Baseline: full tree snapshot after git repository loss

The previous .git directory was found gutted (only info/ remained), so
history is unrecoverable locally. This commit restores version control
with the tree exactly as it stands: the working app, the preview-tracks
launcher on the artist hero, the scrollable-track-previews design bundle
(docs + approved mockups), and the Phase 0 validation artifacts.
This commit is contained in:
KeelrLeek committed 2026-07-22 17:57:00 -05:00
commit a667b4b28e
161 files changed
+53170

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
// Dev-only mock library data, for exercising the Library UI on a machine
// without a populated music library. Inert unless explicitly enabled by
// setting localStorage.mockLibrary = "1" in the webview (then reload);
// remove the key to go back to real backend data.
const ARTISTS = ["Aphex Twin","Boards of Canada","Caribou","Daft Punk","Eno Brian","Four Tet","Grimes","Holly Herndon","Jon Hopkins","Kraftwerk","LCD Soundsystem","Moderat","Nils Frahm","Oneohtrix","Portishead","Radiohead","Squarepusher","Tycho","Underworld","Vangelis","Wilco","Yello","Zero 7","Air","Bonobo","Burial","Clark","Deadmau5","Emancipator","Floating Points","Gold Panda","Helios","Kiasmos","Lorn","Moby","Nujabes","Ott","Plaid","Rival Consoles","Shpongle"];
const albums = [];
let aid = 1;
for (let i = 0; i < ARTISTS.length; i++) {
const n = 2 + (i % 3); // 2-4 albums per artist
for (let j = 0; j < n; j++) {
albums.push({
id: aid,
artist: ARTISTS[i],
title: `Album ${j + 1} of ${ARTISTS[i]}`,
year: 1995 + ((i + j) % 30),
track_count: 10,
art_path: `mock://art/${aid}`,
artist_art_path: `mock://artist/${i}`,
path: `C:\\mock\\${i}\\${j}`,
});
aid++;
}
}
function svgArt(hue, label) {
const s =
`<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">` +
`<rect width="256" height="256" fill="hsl(${hue},45%,35%)"/>` +
`<text x="128" y="140" font-size="90" text-anchor="middle" fill="rgba(255,255,255,.75)" font-family="sans-serif">${label}</text></svg>`;
return "data:image/svg+xml;base64," + btoa(s);
}
function tracksFor(albumId) {
const artist = albums.find((a) => a.id === albumId)?.artist ?? "?";
return Array.from({ length: 10 }, (_, k) => ({
id: albumId * 100 + k,
title: `Track ${k + 1}`,
artist,
track_no: k + 1,
duration_secs: 120 + k * 17,
bitrate_kbps: 320,
path: `C:\\mock\\t${albumId}-${k}.mp3`,
}));
}
const enabled = (() => {
try {
return localStorage.getItem("mockLibrary") === "1";
} catch {
return false;
}
})();
/** Returns a Promise for mocked commands, or undefined to pass through. */
export function mockInvoke(cmd, args) {
if (!enabled) return undefined;
if (cmd === "library_albums") return Promise.resolve(albums);
if (cmd === "album_tracks")
return new Promise((r) => setTimeout(() => r(tracksFor(args.albumId)), 60));
if (cmd === "album_art") {
const m = /(\d+)$/.exec(args.path || "");
const num = m ? +m[1] : 0;
return Promise.resolve(svgArt((num * 47) % 360, String.fromCharCode(65 + (num % 26))));
}
if (cmd === "list_playlists") return Promise.resolve([]);
return undefined;
}