user playlists descriptions
This commit is contained in:
parent
62b83ea9e9
commit
f73c75f668
6 changed files with 58 additions and 12 deletions
|
|
@ -12,23 +12,31 @@ export async function onRequest(context) {
|
|||
|
||||
if (isBot && playlistId) {
|
||||
try {
|
||||
let pbUrl = `https://monodb.samidy.com/api/collections/user_playlists/records/${playlistId}`;
|
||||
// Try public_playlists collection first (for shared playlists)
|
||||
let pbUrl = `https://monodb.samidy.com/api/collections/public_playlists/records?filter=(uuid='${playlistId}')`;
|
||||
let response = await fetch(pbUrl);
|
||||
|
||||
// Fall back to user_playlists for private/owned playlists
|
||||
if (!response.ok) {
|
||||
pbUrl = `https://monodb.samidy.com/api/collections/public_playlists/records?filter=(uuid='${playlistId}')`;
|
||||
pbUrl = `https://monodb.samidy.com/api/collections/user_playlists/records/${playlistId}`;
|
||||
response = await fetch(pbUrl);
|
||||
}
|
||||
|
||||
if (response.ok) {
|
||||
let playlist = await response.json();
|
||||
if (playlist.items && Array.isArray(playlist.items) && playlist.items.length > 0) {
|
||||
playlist = playlist.items[0];
|
||||
|
||||
// Handle public_playlists response (returns { items: [...] })
|
||||
if (playlist.items && Array.isArray(playlist.items)) {
|
||||
if (playlist.items.length > 0) {
|
||||
playlist = playlist.items[0];
|
||||
} else {
|
||||
throw new Error('Playlist not found');
|
||||
}
|
||||
}
|
||||
|
||||
if (!playlist) throw new Error('Playlist not found');
|
||||
|
||||
const title = playlist.name || playlist.title || 'User Playlist';
|
||||
const title = playlist.name || playlist.title || playlist.playlist_name || 'User Playlist';
|
||||
let tracks = [];
|
||||
try {
|
||||
tracks = Array.isArray(playlist.tracks)
|
||||
|
|
@ -41,14 +49,18 @@ export async function onRequest(context) {
|
|||
}
|
||||
|
||||
const trackCount = tracks.length;
|
||||
const description = `User Playlist • ${trackCount} Tracks\nListen on Monochrome`;
|
||||
const playlistDescription = playlist.description || '';
|
||||
const description = playlistDescription
|
||||
? `${playlistDescription}\n${trackCount} Tracks • Listen on Monochrome`
|
||||
: `User Playlist • ${trackCount} Tracks\nListen on Monochrome`;
|
||||
|
||||
let imageUrl = 'https://monochrome.samidy.com/assets/appicon.png';
|
||||
if (playlist.cover) {
|
||||
if (playlist.cover.startsWith('http')) {
|
||||
imageUrl = playlist.cover;
|
||||
const coverUrl = playlist.cover || playlist.image || playlist.playlist_cover || '';
|
||||
if (coverUrl) {
|
||||
if (coverUrl.startsWith('http')) {
|
||||
imageUrl = coverUrl;
|
||||
} else {
|
||||
imageUrl = `https://monodb.samidy.com/api/files/${playlist.collectionId}/${playlist.id}/${playlist.cover}`;
|
||||
imageUrl = `https://monodb.samidy.com/api/files/${playlist.collectionId}/${playlist.id}/${coverUrl}`;
|
||||
}
|
||||
} else if (
|
||||
tracks.length > 0 &&
|
||||
|
|
|
|||
|
|
@ -352,6 +352,12 @@
|
|||
here. (or any other service that allows directly linking to a file, but we recommend catbox due to
|
||||
their long-term storage of your files)
|
||||
</p>
|
||||
<textarea
|
||||
id="playlist-description-input"
|
||||
class="template-input"
|
||||
placeholder="Description (optional)"
|
||||
style="margin: 0.5rem 0; min-height: 80px; resize: vertical"
|
||||
></textarea>
|
||||
<br />
|
||||
<div
|
||||
id="csv-import-section"
|
||||
|
|
|
|||
|
|
@ -348,11 +348,17 @@ const syncManager = {
|
|||
}
|
||||
if (!finalTitle) finalTitle = 'Untitled Playlist';
|
||||
|
||||
let finalDescription = record.description || '';
|
||||
if (!finalDescription && extraData && typeof extraData === 'object') {
|
||||
finalDescription = extraData.description || '';
|
||||
}
|
||||
|
||||
return {
|
||||
...record,
|
||||
id: record.uuid,
|
||||
name: finalTitle,
|
||||
title: finalTitle,
|
||||
description: finalDescription,
|
||||
cover: finalCover,
|
||||
image: finalCover,
|
||||
tracks: tracks,
|
||||
|
|
@ -384,11 +390,13 @@ const syncManager = {
|
|||
image: playlist.cover,
|
||||
cover: playlist.cover,
|
||||
playlist_cover: playlist.cover,
|
||||
description: playlist.description || '',
|
||||
tracks: JSON.stringify(playlist.tracks || []),
|
||||
isPublic: true,
|
||||
data: {
|
||||
title: playlist.name,
|
||||
cover: playlist.cover,
|
||||
description: playlist.description || '',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -649,6 +649,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
document.getElementById('playlist-modal-title').textContent = 'Create Playlist';
|
||||
document.getElementById('playlist-name-input').value = '';
|
||||
document.getElementById('playlist-cover-input').value = '';
|
||||
document.getElementById('playlist-description-input').value = '';
|
||||
modal.dataset.editingId = '';
|
||||
document.getElementById('csv-import-section').style.display = 'block';
|
||||
document.getElementById('csv-file-input').value = '';
|
||||
|
|
@ -696,6 +697,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
|
||||
if (e.target.closest('#playlist-modal-save')) {
|
||||
const name = document.getElementById('playlist-name-input').value.trim();
|
||||
const description = document.getElementById('playlist-description-input').value.trim();
|
||||
const isPublic = document.getElementById('playlist-public-toggle')?.checked;
|
||||
|
||||
if (name) {
|
||||
|
|
@ -728,6 +730,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
if (playlist) {
|
||||
playlist.name = name;
|
||||
playlist.cover = cover;
|
||||
playlist.description = description;
|
||||
await handlePublicStatus(playlist);
|
||||
await db.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
||||
syncManager.syncUserPlaylist(playlist, 'update');
|
||||
|
|
@ -817,7 +820,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
console.log(`Added ${tracks.length} tracks (including pending)`);
|
||||
}
|
||||
|
||||
db.createPlaylist(name, tracks, cover).then(async (playlist) => {
|
||||
db.createPlaylist(name, tracks, cover, description).then(async (playlist) => {
|
||||
await handlePublicStatus(playlist);
|
||||
// Update DB again with isPublic flag
|
||||
await db.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
||||
|
|
@ -842,6 +845,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
document.getElementById('playlist-modal-title').textContent = 'Edit Playlist';
|
||||
document.getElementById('playlist-name-input').value = playlist.name;
|
||||
document.getElementById('playlist-cover-input').value = playlist.cover || '';
|
||||
document.getElementById('playlist-description-input').value = playlist.description || '';
|
||||
|
||||
// Set Public Toggle
|
||||
const publicToggle = document.getElementById('playlist-public-toggle');
|
||||
|
|
@ -886,6 +890,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
document.getElementById('playlist-modal-title').textContent = 'Edit Playlist';
|
||||
document.getElementById('playlist-name-input').value = playlist.name;
|
||||
document.getElementById('playlist-cover-input').value = playlist.cover || '';
|
||||
document.getElementById('playlist-description-input').value = playlist.description || '';
|
||||
|
||||
const publicToggle = document.getElementById('playlist-public-toggle');
|
||||
const shareBtn = document.getElementById('playlist-share-btn');
|
||||
|
|
|
|||
15
js/db.js
15
js/db.js
|
|
@ -466,13 +466,14 @@ export class MusicDatabase {
|
|||
}
|
||||
|
||||
// User Playlists API
|
||||
async createPlaylist(name, tracks = [], cover = '') {
|
||||
async createPlaylist(name, tracks = [], cover = '', description = '') {
|
||||
const id = crypto.randomUUID();
|
||||
const playlist = {
|
||||
id: id,
|
||||
name: name,
|
||||
tracks: tracks.map((t) => this._minifyItem('track', { ...t, addedAt: Date.now() })),
|
||||
cover: cover,
|
||||
description: description,
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
numberOfTracks: tracks.length,
|
||||
|
|
@ -667,6 +668,18 @@ export class MusicDatabase {
|
|||
return playlist;
|
||||
}
|
||||
|
||||
async updatePlaylistDescription(playlistId, newDescription) {
|
||||
const playlist = await this.performTransaction('user_playlists', 'readonly', (store) => store.get(playlistId));
|
||||
if (!playlist) throw new Error('Playlist not found');
|
||||
playlist.description = newDescription;
|
||||
playlist.updatedAt = Date.now();
|
||||
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
||||
|
||||
this._dispatchPlaylistSync('update', playlist);
|
||||
|
||||
return playlist;
|
||||
}
|
||||
|
||||
async updatePlaylistTracks(playlistId, tracks) {
|
||||
const db = await this.open();
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
|
|||
|
|
@ -649,6 +649,7 @@ export async function showAddToPlaylistModal(track) {
|
|||
document.getElementById('playlist-modal-title').textContent = 'Create Playlist';
|
||||
document.getElementById('playlist-name-input').value = '';
|
||||
document.getElementById('playlist-cover-input').value = '';
|
||||
document.getElementById('playlist-description-input').value = '';
|
||||
createModal.dataset.editingId = '';
|
||||
document.getElementById('csv-import-section').style.display = 'none';
|
||||
|
||||
|
|
@ -1005,6 +1006,7 @@ export async function handleTrackAction(
|
|||
document.getElementById('playlist-modal-title').textContent = 'Create Playlist';
|
||||
document.getElementById('playlist-name-input').value = '';
|
||||
document.getElementById('playlist-cover-input').value = '';
|
||||
document.getElementById('playlist-description-input').value = '';
|
||||
createModal.dataset.editingId = '';
|
||||
document.getElementById('csv-import-section').style.display = 'none';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue