editor pick changes

This commit is contained in:
edideaur 2026-04-02 09:08:39 +00:00 committed by GitHub
parent 62901eef63
commit e71c989319
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 372 additions and 165 deletions

View file

@ -139,7 +139,7 @@ Portainer can deploy directly from your GitHub fork with auto-updates on push.
> **Tip:** `COMPOSE_PROFILES` is a built-in Docker Compose variable. Setting it to `pocketbase` is equivalent to passing `--profile pocketbase` on the command line.
> **Warning:** The `dev` profile is for **local development only**. It uses volume mounts to enable hot-reload, which requires the source code to be present on the host machine. Do **not** include `dev` in `COMPOSE_PROFILES` on Portainer deployments from GitHub it will fail because there's no local source code to mount.
> **Warning:** The `dev` profile is for **local development only**. It uses volume mounts to enable hot-reload, which requires the source code to be present on the host machine. Do **not** include `dev` in `COMPOSE_PROFILES` on Portainer deployments from GitHub - it will fail because there's no local source code to mount.
### Fork Workflow

View file

@ -3187,6 +3187,18 @@
</div>
</div>
<div class="settings-group">
<div class="setting-item">
<div class="info">
<span class="label">Editor's Picks Source</span>
<span class="description">Choose which editor's picks file to display</span>
</div>
<select id="editors-picks-source-select" class="select-dropdown">
<option value="current">Current</option>
</select>
</div>
</div>
<div class="settings-group">
<div class="setting-item">
<div class="info">

View file

@ -550,8 +550,8 @@ document.addEventListener('DOMContentLoaded', async () => {
* having to manually re-scan.
*
* When called with a `blob` and `filename` (single-track download case) it
* performs a cheap partial update reading metadata only from that one file
* and inserting it into the existing cache so the full folder does not need
* performs a cheap partial update - reading metadata only from that one file
* and inserting it into the existing cache - so the full folder does not need
* to be re-walked. When called with no arguments (bulk download case, or when
* `localFilesCache` has never been populated) it falls back to a full rescan.
*/

View file

@ -24,7 +24,7 @@ export class MusicDatabase {
request.onupgradeneeded = (event) => {
const db = event.target.result;
// v10 introduced track_ratings (bad PR) remove it
// v10 introduced track_ratings (bad PR) - remove it
if (db.objectStoreNames.contains('track_ratings')) {
db.deleteObjectStore('track_ratings');
}

View file

@ -5,7 +5,7 @@ let _Haptics = null;
let _ImpactStyle = null;
let _NotificationStyle = null;
// Single stored promise subsequent calls reuse the same one
// Single stored promise - subsequent calls reuse the same one
const _ready = import('@capacitor/haptics')
.then((mod) => {
_Haptics = mod.Haptics;
@ -13,14 +13,14 @@ const _ready = import('@capacitor/haptics')
_NotificationStyle = mod.NotificationStyle;
})
.catch(() => {
// Not in Capacitor or haptics not available fall back to navigator.vibrate
// Not in Capacitor or haptics not available - fall back to navigator.vibrate
});
function vibrateFallback(ms) {
if (navigator.vibrate) navigator.vibrate(ms);
}
/** Light tap for toggles, menu opens */
/** Light tap - for toggles, menu opens */
export async function hapticLight() {
await _ready;
try {
@ -32,7 +32,7 @@ export async function hapticLight() {
vibrateFallback(30);
}
/** Medium impact for play/pause, skip */
/** Medium impact - for play/pause, skip */
export async function hapticMedium() {
await _ready;
try {
@ -44,7 +44,7 @@ export async function hapticMedium() {
vibrateFallback(50);
}
/** Success notification for like/unlike, add to queue */
/** Success notification - for like/unlike, add to queue */
export async function hapticSuccess() {
await _ready;
try {
@ -56,7 +56,7 @@ export async function hapticSuccess() {
vibrateFallback(40);
}
/** Long press replaces navigator.vibrate(50) for track selection */
/** Long press - replaces navigator.vibrate(50) for track selection */
export async function hapticLongPress() {
await _ready;
try {

View file

@ -4917,6 +4917,34 @@ export async function initializeSettings(scrobbler, player, api, ui) {
});
}
const editorsPicksSourceSelect = document.getElementById('editors-picks-source-select');
if (editorsPicksSourceSelect) {
async function populateEditorsPicksSource() {
try {
const response = await fetch('/editors-picks-old/index.json');
if (response.ok) {
const oldPicks = await response.json();
oldPicks.forEach((pick) => {
const option = document.createElement('option');
option.value = pick.file;
option.textContent = pick.label;
editorsPicksSourceSelect.appendChild(option);
});
}
} catch (e) {
console.warn('Could not load editors-picks-old index:', e);
}
const currentSource = homePageSettings.getEditorsPicksSource();
editorsPicksSourceSelect.value = currentSource;
}
populateEditorsPicksSource();
editorsPicksSourceSelect.addEventListener('change', (e) => {
homePageSettings.setEditorsPicksSource(e.target.value);
window.dispatchEvent(new CustomEvent('refresh-home-editors-picks'));
});
}
// Sidebar Section Toggles
const sidebarShowHomeToggle = document.getElementById('sidebar-show-home-toggle');
if (sidebarShowHomeToggle) {

View file

@ -2009,6 +2009,20 @@ export const homePageSettings = {
setShuffleEditorsPicks(enabled) {
localStorage.setItem(this.SHUFFLE_EDITORS_PICKS_KEY, enabled ? 'true' : 'false');
},
EDITORS_PICKS_SOURCE_KEY: 'home-editors-picks-source',
getEditorsPicksSource() {
try {
return localStorage.getItem(this.EDITORS_PICKS_SOURCE_KEY) || 'current';
} catch {
return 'current';
}
},
setEditorsPicksSource(source) {
localStorage.setItem(this.EDITORS_PICKS_SOURCE_KEY, source);
},
};
export const radioSettings = {

View file

@ -135,7 +135,7 @@ export async function addMetadataToAudio(message: _AddMetadataMessage): Promise<
if (explicit !== undefined) {
if (isMp4) {
// rtng is a byte item must be set directly on the Mp4Tag
// rtng is a byte item - must be set directly on the Mp4Tag
const mp4Tag = (underlying as Mp4File).tag() as Mp4Tag;
mp4Tag.setItem('rtng', Mp4Item.fromByte(explicit ? 1 : 0));
} else {

View file

@ -165,6 +165,11 @@ export class UIRenderer {
this.visualizer.updateDimming();
}
});
window.addEventListener('refresh-home-editors-picks', () => {
this.renderHomeEditorsPicks(true, 'home-editors-picks');
this.renderHomeEditorsPicks(true, 'home-editors-picks-empty');
});
}
static async initialize(api, player) {
@ -2510,7 +2515,9 @@ export class UIRenderer {
else if (picksContainer.children.length > 0 && !picksContainer.querySelector('.skeleton')) return;
try {
const response = await fetch('/editors-picks.json');
const source = homePageSettings.getEditorsPicksSource();
const picksPath = source === 'current' ? '/editors-picks.json' : `/editors-picks-old/${source}`;
const response = await fetch(picksPath);
if (!response.ok) throw new Error("Failed to load editor's picks");
let items = await response.json();

View file

@ -0,0 +1,189 @@
[
{
"type": "album",
"id": 510893864,
"title": "BULLY",
"artist": { "id": 25022, "name": "Kanye West" },
"releaseDate": "2026-03-28",
"cover": "cf2f2c9c-ff67-44f6-83aa-a7622f8c6b64",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 403172104,
"title": "From A Man's Perspective",
"artist": { "id": 3561564, "name": "Dax" },
"releaseDate": "2024-12-06",
"cover": "c52a53ea-f021-44bf-8cef-fb31d3b82940",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 341529881,
"title": "FACTS",
"artist": { "id": 5691796, "name": "Tom MacDonald" },
"releaseDate": "2024-01-26",
"cover": "34198718-cc7d-47eb-9bf1-1dc5c26fc8a1",
"explicit": false,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 452163300,
"title": "Tackle Box",
"artist": { "id": 44771714, "name": "JamWayne" },
"releaseDate": "2025-09-01",
"cover": "bf7d2e55-52dc-4e41-9f53-1db31918798e",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 106210035,
"title": "Supermarket (Soundtrack)",
"artist": { "id": 3533999, "name": "LOGIC" },
"releaseDate": "2019-03-26",
"cover": "bdd39738-7177-4836-bd7f-cd4fe4ccf535",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 138458381,
"title": "JOKER",
"artist": { "id": 39109746, "name": "Dax" },
"releaseDate": "2020-05-06",
"cover": "d6a39491-fece-4594-a538-9cfbce7c6c68",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 318467376,
"title": "The Draco Tape 2",
"artist": { "id": 22467779, "name": "60PERCENTHOMO" },
"releaseDate": "2023-09-30",
"cover": "9169e8ab-fdb0-49d1-a14f-82a2b541223c",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 456582219,
"title": "bbno$",
"artist": { "id": 8173944, "name": "bbno$" },
"releaseDate": "2025-10-17",
"cover": "8162c739-4bb2-4218-8915-93cb1f0d9eea",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 506216548,
"title": "Declassified",
"artist": { "id": 5691796, "name": "Tom MacDonald" },
"releaseDate": "2026-03-13",
"cover": "5cf188e5-1660-4a01-bacc-10ca81e7af73",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 486673299,
"title": "Novelty",
"artist": { "id": 3589848, "name": "Goofy" },
"releaseDate": "2026-01-23",
"cover": "dd543595-e604-440e-a24c-e2eaccda3804",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 440469641,
"title": "Tha Carter VI",
"artist": { "id": 27518, "name": "Lil Wayne" },
"releaseDate": "2025-06-06",
"cover": "f2807cfe-6df8-4ea0-ab32-fd0ad9e91072",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 384057608,
"title": "FREE VIPER!",
"artist": { "id": 10285483, "name": "Viper" },
"releaseDate": "2024-08-28",
"cover": "642d73d9-2a45-4598-bec3-033a09181bdf",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 460015533,
"title": "CHARLIE",
"artist": { "id": 5691796, "name": "Tom MacDonald" },
"releaseDate": "2025-09-11",
"cover": "18180e3d-e178-4bd3-aada-e26ca32bc8f4",
"explicit": false,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 123319314,
"title": "BABY G.O.A.T.",
"artist": { "id": 9160626, "name": "Kevo Muney" },
"releaseDate": "2019-12-12",
"cover": "6c87aee6-76da-413e-a639-79b670b3e3d1",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 510493672,
"title": "ADL",
"artist": { "id": 9318056, "name": "Yeat" },
"releaseDate": "2026-03-27",
"cover": "b799025a-7ff6-494c-aa11-5e0461bbca40",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 440096189,
"title": "Rebel",
"artist": { "id": 52081927, "name": "EsDeeKid" },
"releaseDate": "2025-06-20",
"cover": "3433b56c-6386-4e21-90ee-f2369d4bfde7",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 85287313,
"title": "Toilet",
"artist": { "id": 9598562, "name": "Clown Core" },
"releaseDate": "2018-03-03",
"cover": "d6d32464-864e-422f-b8c3-0c30baa563b1",
"explicit": false,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
}
]

View file

@ -0,0 +1,12 @@
[
{
"file": "2026-3-20-before-april-fools.json",
"label": "Before April Fools '26",
"date": "2026-03-20"
},
{
"file": "2026-4-1-april-fools.json",
"label": "April Fools '26",
"date": "2026-04-01"
}
]

View file

@ -8,182 +8,127 @@
"cover": "cf2f2c9c-ff67-44f6-83aa-a7622f8c6b64",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
},
{
"type": "album",
"id": 403172104,
"title": "From A Man's Perspective",
"artist": { "id": 3561564, "name": "Dax" },
"releaseDate": "2024-12-06",
"cover": "c52a53ea-f021-44bf-8cef-fb31d3b82940",
"id": 324660713,
"title": "JOECHILLWORLD",
"artist": { "id": 40978758, "name": "Devon Hendryx" },
"releaseDate": "2010-07-10",
"cover": "25d45544-3e82-4184-b8c2-2c2c6f0f152a",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
},
{
"type": "album",
"id": 15427733,
"title": "Mysterious Phonk: The Chronicles of SpaceGhostPurrp",
"artist": { "id": 4611745, "name": "Spaceghostpurrp" },
"releaseDate": "2012-06-12",
"cover": "c78b7543-1cd8-4921-9155-e81d421353a0",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 341529881,
"title": "FACTS",
"artist": { "id": 5691796, "name": "Tom MacDonald" },
"releaseDate": "2024-01-26",
"cover": "34198718-cc7d-47eb-9bf1-1dc5c26fc8a1",
"id": 464178301,
"title": "Never Forget",
"artist": { "id": 5516508, "name": "Chris Travis" },
"releaseDate": "2014-05-14",
"cover": "4ab11f0d-0768-4cce-8de5-1894134d5994",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 75115890,
"title": "Blood Shore Season 2",
"artist": { "id": 6332342, "name": "Xavier Wulf" },
"releaseDate": "2014-10-30",
"cover": "517303e5-d541-4704-b552-026427e05fcb",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 410197513,
"title": "THE PEAK",
"artist": { "id": 33481052, "name": "smokedope2016" },
"releaseDate": "2025-01-17",
"cover": "ea18084d-36ec-4cea-98a7-fe4684246986",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 418729278,
"title": "I LAY DOWN MY LIFE FOR YOU: DIRECTOR'S CUT",
"artist": { "id": 7958797, "name": "JPEGMAFIA" },
"releaseDate": "2025-02-03",
"cover": "9c84302b-2584-4c0a-9db7-e648542f459f",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
},
{
"type": "album",
"id": 504004321,
"title": "Half Blood (BloodLuxe)",
"artist": { "id": 50799233, "name": "slayr" },
"releaseDate": "2025-11-05",
"cover": "2767cc63-7e92-4a48-aa4b-806a3ea7ec1c",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
},
{
"type": "album",
"id": 325723583,
"title": "Replica",
"artist": { "id": 3715530, "name": "Oneohtrix Point Never" },
"releaseDate": "2011-11-05",
"cover": "95ceeae9-cac7-42dc-ae37-7c93c223f809",
"explicit": false,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 452163300,
"title": "Tackle Box",
"artist": { "id": 44771714, "name": "JamWayne" },
"releaseDate": "2025-09-01",
"cover": "bf7d2e55-52dc-4e41-9f53-1db31918798e",
"id": 336178142,
"title": "Pirate This Album",
"artist": { "id": 8622751, "name": "Shamana" },
"releaseDate": "2023-12-25",
"cover": "a8a647be-0331-4779-9a6e-31645a9abdab",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS", "HIRES_LOSSLESS"] }
},
{
"type": "album",
"id": 106369871,
"title": "Organic Thoughts from the Synthetic Mind",
"artist": { "id": 6436013, "name": "Shinjuku Mad" },
"releaseDate": "2009-07-01",
"cover": "3acc888e-35da-40a8-a4b7-7ffd00576cc9",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 106210035,
"title": "Supermarket (Soundtrack)",
"artist": { "id": 3533999, "name": "LOGIC" },
"releaseDate": "2019-03-26",
"cover": "bdd39738-7177-4836-bd7f-cd4fe4ccf535",
"id": 423471869,
"title": "pain",
"artist": { "id": 44257324, "name": "bleood" },
"releaseDate": "2025-03-11",
"cover": "711b23ba-c473-44e6-a2f0-010fefa9c5b8",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 138458381,
"title": "JOKER",
"artist": { "id": 39109746, "name": "Dax" },
"releaseDate": "2020-05-06",
"cover": "d6a39491-fece-4594-a538-9cfbce7c6c68",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 318467376,
"title": "The Draco Tape 2",
"artist": { "id": 22467779, "name": "60PERCENTHOMO" },
"releaseDate": "2023-09-30",
"cover": "9169e8ab-fdb0-49d1-a14f-82a2b541223c",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 456582219,
"title": "bbno$",
"artist": { "id": 8173944, "name": "bbno$" },
"releaseDate": "2025-10-17",
"cover": "8162c739-4bb2-4218-8915-93cb1f0d9eea",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 506216548,
"title": "Declassified",
"artist": { "id": 5691796, "name": "Tom MacDonald" },
"releaseDate": "2026-03-13",
"cover": "5cf188e5-1660-4a01-bacc-10ca81e7af73",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 486673299,
"title": "Novelty",
"artist": { "id": 3589848, "name": "Goofy" },
"releaseDate": "2026-01-23",
"cover": "dd543595-e604-440e-a24c-e2eaccda3804",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 440469641,
"title": "Tha Carter VI",
"artist": { "id": 27518, "name": "Lil Wayne" },
"releaseDate": "2025-06-06",
"cover": "f2807cfe-6df8-4ea0-ab32-fd0ad9e91072",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 384057608,
"title": "FREE VIPER!",
"artist": { "id": 10285483, "name": "Viper" },
"releaseDate": "2024-08-28",
"cover": "642d73d9-2a45-4598-bec3-033a09181bdf",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 460015533,
"title": "CHARLIE",
"artist": { "id": 5691796, "name": "Tom MacDonald" },
"releaseDate": "2025-09-11",
"cover": "18180e3d-e178-4bd3-aada-e26ca32bc8f4",
"explicit": false,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 123319314,
"title": "BABY G.O.A.T.",
"artist": { "id": 9160626, "name": "Kevo Muney" },
"releaseDate": "2019-12-12",
"cover": "6c87aee6-76da-413e-a639-79b670b3e3d1",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 510493672,
"title": "ADL",
"artist": { "id": 9318056, "name": "Yeat" },
"releaseDate": "2026-03-27",
"cover": "b799025a-7ff6-494c-aa11-5e0461bbca40",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 440096189,
"title": "Rebel",
"artist": { "id": 52081927, "name": "EsDeeKid" },
"releaseDate": "2025-06-20",
"cover": "3433b56c-6386-4e21-90ee-f2369d4bfde7",
"explicit": true,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
},
{
"type": "album",
"id": 85287313,
"title": "Toilet",
"artist": { "id": 9598562, "name": "Clown Core" },
"releaseDate": "2018-03-03",
"cover": "d6d32464-864e-422f-b8c3-0c30baa563b1",
"explicit": false,
"audioQuality": "LOSSLESS",
"mediaMetadata": { "tags": ["LOSSLESS"] }
}
]