Extend lookupMap to contain artist to album mapping

This commit is contained in:
RandyTheSilly committed 2026-10-10 18:19:07 -04:00
1 parent f7b4805ba1
commit 198f18e5a2
2 files changed
+37 -23

No files matched your search

+12 -8
View File
@@ -2,22 +2,26 @@
Control Jellyfin music playback from your Pebble with an iPod-like interface. Control Jellyfin music playback from your Pebble with an iPod-like interface.
# Supported Phone Clients # Supported Phone Clients
jellyPod requires a Jellyfin client to be running on your phone to handle playback. Not all clients support all features of jellyPod. Tested clients are detailed below. `jellyPod` requires a Jellyfin client to be running on your phone to handle playback. Not all clients support all features of `jellyPod`. Tested clients are detailed below.
## Legend ## Legend
- ✅ = verified (supports all features of jellyPod and prefers offline playback of local media over online streaming) - ✅ = verified (supports all features of `jellyPod` and prefers offline playback of local media over online streaming)
- ⚠️ = usable (functional with missing features/bugs detailed below) - ⚠️ = usable (functional with missing features/bugs detailed below)
- ⛔ = unsupported (does not work well or at all with jellyPod) - ⛔ = unsupported (does not work well or at all with `jellyPod`)
## iOS ## iOS
- ✅ [Finamp Beta/Redesign](https://github.com/finamp-app/finamp/tree/redesign) (last tested release: 1.0.1) - ✅ [Finamp Beta/Redesign](https://github.com/finamp-app/finamp/tree/redesign) (last tested release: 1.0.1)
# Special Features # Opinionated Design Philosophy
I made `jellyPod` to suite my tastes. Everything listed below is non-negotiable and will not be changed.
- No playlist support
- Playlists encourage poor listening habits that lead to portions of your library being ignored while others are overplayed
- True sequential playback - True sequential playback
- Your music continues to play in order even after you exhaust the tracks on the selected album and by the current artist - Your music continues to play in order even after you exhaust the tracks on the selected album and by the current artist
- The next album is chosen by release date and the next artist is chosen alphanumerically - The next album is chosen by release date and the next artist is chosen alphanumerically
- Shuffle at every scope
- You can easily shuffle artists, albums (from a given artist), or all tracks
- Multi-client/device support - Multi-client/device support
- jellyPod is not just a remote for your phone - `jellyPod` is not just a remote for your phone
- Determines which client to control based on the most recently active session under your Jellyfin user - The client to control is determined by your most recently active session under your Jellyfin user
- Classic design - Classic design
- Inspired by the 4th generation iPod - Inspired by the 4th generation iPod
- Support for ALL Pebbles - NONE of this application, nor any art/assets used in its creation, was generated by AI
- Absolutely NO AI was used in the creation of this application
+25 -15
View File
@@ -21,7 +21,7 @@ Pebble.addEventListener("ready", function () {
// get library response from Jellyfin // get library response from Jellyfin
callAPI("GET", cfg.PRIV_BASE_URL + "/Items?userId=" + userId + "&recursive=true&includeItemTypes=Audio&sortBy=AlbumArtist,Artist,ProductionYear,Album,IndexNumber,Name", function (libResp) { callAPI("GET", cfg.PRIV_BASE_URL + "/Items?userId=" + userId + "&recursive=true&includeItemTypes=Audio&sortBy=AlbumArtist,Artist,ProductionYear,Album,IndexNumber,Name", function (libResp) {
if (libResp === null) { return; } if (libResp === null) return;
const libObj = JSON.parse(libResp); const libObj = JSON.parse(libResp);
// format response for jellyPod // format response for jellyPod
@@ -30,31 +30,41 @@ Pebble.addEventListener("ready", function () {
const lookupMap = new Map(); const lookupMap = new Map();
let lastAlbumInfo = {AlbumArtist: "", AlbumName: "", AlbumYear: 0}; let lastAlbumInfo = {AlbumArtist: "", AlbumName: "", AlbumYear: 0};
for (const track of libObj.Items) { for (const track of libObj.Items) {
if (!track.Name) { if (!track.Name) continue;
continue;
}
let albumArtist = "unknown artist"; let albumArtist = "unknown artist";
if (track.AlbumArtist) { if (track.AlbumArtist) {
albumArtist = track.AlbumArtist; albumArtist = track.AlbumArtist;
} else if (track.Artists.length > 0) { } else if (track.Artists.length > 0) {
albumArtist = track.Artists[0] albumArtist = track.Artists[0];
} }
const albumName = track.Album ? track.Album : "unknown album"; const albumName = track.Album ? track.Album : "unknown album";
if (lastAlbumInfo.AlbumArtist != albumArtist) {
firstChar = Array.from(albumArtist)[0].toUpperCase(); // register album in lookupMap whenever the album changes (new artist OR new album)
if (lastAlbumInfo.AlbumArtist !== albumArtist || lastAlbumInfo.AlbumName !== albumName) {
const firstChar = Array.from(albumArtist)[0].toUpperCase();
if (!lookupMap.has(firstChar)) { if (!lookupMap.has(firstChar)) {
lookupMap.set(firstChar, [albumArtist]); lookupMap.set(firstChar, new Map());
} else { }
lookupMap.get(firstChar).push(albumArtist); const artistMap = lookupMap.get(firstChar);
}; if (!artistMap.has(albumArtist)) {
if (lastAlbumInfo.AlbumName != albumName) { artistMap.set(albumArtist, []);
}
const albums = artistMap.get(albumArtist);
if (!albums.includes(albumName)) {
albums.push(albumName);
}
}
// keep lastAlbumInfo in sync for every album change
if (lastAlbumInfo.AlbumArtist !== albumArtist || lastAlbumInfo.AlbumName !== albumName) {
lastAlbumInfo = { lastAlbumInfo = {
AlbumArtist: albumArtist, AlbumArtist: albumArtist,
AlbumName: track.Album ? track.Album : "unknown album", AlbumName: albumName,
AlbumYear: track.ProductionYear ? track.ProductionYear : 1970 AlbumYear: track.ProductionYear ? track.ProductionYear : 1970
}; };
} }
}
jpTracksArr.push({ jpTracksArr.push({
TrackName: track.Name, TrackName: track.Name,
JfId: track.Id, JfId: track.Id,
@@ -64,7 +74,7 @@ Pebble.addEventListener("ready", function () {
//console.log(jpTracksArr); //console.log(jpTracksArr);
//console.log("Items:", libObj.Items.length, "Tracks:", jpTracksArr.length); //console.log("Items:", libObj.Items.length, "Tracks:", jpTracksArr.length);
//console.log(...lookupMap); console.log(JSON.stringify([...lookupMap].map(([ch, m]) => [ch, [...m]])));
Pebble.sendAppMessage({ PKJS_READY: 1 }); Pebble.sendAppMessage({ PKJS_READY: 1 });
}); });