style: auto-fix linting issues
This commit is contained in:
parent
1cb17680f3
commit
3e212a7e5b
4 changed files with 190 additions and 181 deletions
|
|
@ -1493,10 +1493,12 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<p style="padding-top: 50px; text-align: center; color: #8b8b93">
|
<p style="padding-top: 50px; text-align: center; color: #8b8b93">
|
||||||
We only store music data and a randomized ID to find out which Google/Email account is which.
|
We only store music data and a randomized ID to find out which Google/Email account is
|
||||||
|
which.
|
||||||
<br />
|
<br />
|
||||||
All data is anonymous. We do not store anything like emails, usernames, or anything
|
All data is anonymous. We do not store anything like emails, usernames, or anything
|
||||||
sensitive. <br />
|
sensitive. <br />
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="page-donate" class="page">
|
<div id="page-donate" class="page">
|
||||||
|
|
|
||||||
|
|
@ -19,22 +19,22 @@ const syncManager = {
|
||||||
if (this._userRecordCache && this._userRecordCache.firebase_id === uid) {
|
if (this._userRecordCache && this._userRecordCache.firebase_id === uid) {
|
||||||
return this._userRecordCache;
|
return this._userRecordCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const record = await this.pb.collection('DB_users').getFirstListItem(
|
const record = await this.pb.collection('DB_users').getFirstListItem(`firebase_id="${uid}"`, { f_id: uid });
|
||||||
`firebase_id="${uid}"`,
|
|
||||||
{ f_id: uid }
|
|
||||||
);
|
|
||||||
this._userRecordCache = record;
|
this._userRecordCache = record;
|
||||||
return record;
|
return record;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.status === 404) {
|
if (error.status === 404) {
|
||||||
try {
|
try {
|
||||||
const newRecord = await this.pb.collection('DB_users').create({
|
const newRecord = await this.pb.collection('DB_users').create(
|
||||||
firebase_id: uid,
|
{
|
||||||
library: {},
|
firebase_id: uid,
|
||||||
history: [],
|
library: {},
|
||||||
}, { f_id: uid });
|
history: [],
|
||||||
|
},
|
||||||
|
{ f_id: uid }
|
||||||
|
);
|
||||||
this._userRecordCache = newRecord;
|
this._userRecordCache = newRecord;
|
||||||
return newRecord;
|
return newRecord;
|
||||||
} catch (createError) {
|
} catch (createError) {
|
||||||
|
|
@ -95,11 +95,7 @@ const syncManager = {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const updated = await this.pb.collection('DB_users').update(
|
const updated = await this.pb.collection('DB_users').update(record.id, { [field]: data }, { f_id: uid });
|
||||||
record.id,
|
|
||||||
{ [field]: data },
|
|
||||||
{ f_id: uid }
|
|
||||||
);
|
|
||||||
this._userRecordCache = updated;
|
this._userRecordCache = updated;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to sync ${field} to PocketBase:`, error);
|
console.error(`Failed to sync ${field} to PocketBase:`, error);
|
||||||
|
|
@ -114,13 +110,13 @@ const syncManager = {
|
||||||
if (!record) return;
|
if (!record) return;
|
||||||
|
|
||||||
let library = record.library || {};
|
let library = record.library || {};
|
||||||
|
|
||||||
if (typeof library === 'string') {
|
if (typeof library === 'string') {
|
||||||
try {
|
try {
|
||||||
library = JSON.parse(library);
|
library = JSON.parse(library);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Library field is not valid JSON', e);
|
console.error('Library field is not valid JSON', e);
|
||||||
library = {};
|
library = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,7 +251,7 @@ const syncManager = {
|
||||||
if (!record) return;
|
if (!record) return;
|
||||||
|
|
||||||
let userPlaylists = record.user_playlists || {};
|
let userPlaylists = record.user_playlists || {};
|
||||||
|
|
||||||
if (typeof userPlaylists === 'string') {
|
if (typeof userPlaylists === 'string') {
|
||||||
try {
|
try {
|
||||||
userPlaylists = JSON.parse(userPlaylists);
|
userPlaylists = JSON.parse(userPlaylists);
|
||||||
|
|
@ -272,7 +268,7 @@ const syncManager = {
|
||||||
id: playlist.id,
|
id: playlist.id,
|
||||||
name: playlist.name,
|
name: playlist.name,
|
||||||
cover: playlist.cover || null,
|
cover: playlist.cover || null,
|
||||||
tracks: playlist.tracks ? playlist.tracks.map(t => this._minifyItem('track', t)) : [],
|
tracks: playlist.tracks ? playlist.tracks.map((t) => this._minifyItem('track', t)) : [],
|
||||||
createdAt: playlist.createdAt || Date.now(),
|
createdAt: playlist.createdAt || Date.now(),
|
||||||
updatedAt: playlist.updatedAt || Date.now(),
|
updatedAt: playlist.updatedAt || Date.now(),
|
||||||
numberOfTracks: playlist.tracks ? playlist.tracks.length : 0,
|
numberOfTracks: playlist.tracks ? playlist.tracks.length : 0,
|
||||||
|
|
@ -286,18 +282,19 @@ const syncManager = {
|
||||||
|
|
||||||
async getPublicPlaylist(uuid) {
|
async getPublicPlaylist(uuid) {
|
||||||
try {
|
try {
|
||||||
const record = await this.pb.collection(PUBLIC_COLLECTION).getFirstListItem(
|
const record = await this.pb
|
||||||
`uuid="${uuid}"`,
|
.collection(PUBLIC_COLLECTION)
|
||||||
{ p_id: uuid }
|
.getFirstListItem(`uuid="${uuid}"`, { p_id: uuid });
|
||||||
);
|
|
||||||
|
|
||||||
let rawCover = record.image || record.cover || record.playlist_cover || '';
|
let rawCover = record.image || record.cover || record.playlist_cover || '';
|
||||||
let extraData = record.data;
|
let extraData = record.data;
|
||||||
|
|
||||||
if (typeof extraData === 'string') {
|
if (typeof extraData === 'string') {
|
||||||
try { extraData = JSON.parse(extraData); } catch(e) {}
|
try {
|
||||||
|
extraData = JSON.parse(extraData);
|
||||||
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rawCover && extraData && typeof extraData === 'object') {
|
if (!rawCover && extraData && typeof extraData === 'object') {
|
||||||
rawCover = extraData.cover || extraData.image || '';
|
rawCover = extraData.cover || extraData.image || '';
|
||||||
}
|
}
|
||||||
|
|
@ -309,7 +306,7 @@ const syncManager = {
|
||||||
|
|
||||||
let images = [];
|
let images = [];
|
||||||
let tracks = record.tracks || [];
|
let tracks = record.tracks || [];
|
||||||
|
|
||||||
if (typeof tracks === 'string') {
|
if (typeof tracks === 'string') {
|
||||||
try {
|
try {
|
||||||
tracks = JSON.parse(tracks);
|
tracks = JSON.parse(tracks);
|
||||||
|
|
@ -338,7 +335,6 @@ const syncManager = {
|
||||||
finalTitle = extraData.title || extraData.name;
|
finalTitle = extraData.title || extraData.name;
|
||||||
}
|
}
|
||||||
if (!finalTitle) finalTitle = 'Untitled Playlist';
|
if (!finalTitle) finalTitle = 'Untitled Playlist';
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...record,
|
...record,
|
||||||
|
|
@ -352,7 +348,7 @@ const syncManager = {
|
||||||
numberOfTracks: tracks.length,
|
numberOfTracks: tracks.length,
|
||||||
type: 'user-playlist',
|
type: 'user-playlist',
|
||||||
isPublic: true,
|
isPublic: true,
|
||||||
user: { name: 'Community Playlist' }
|
user: { name: 'Community Playlist' },
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.status === 404) return null;
|
if (error.status === 404) return null;
|
||||||
|
|
@ -379,14 +375,14 @@ const syncManager = {
|
||||||
isPublic: true,
|
isPublic: true,
|
||||||
data: {
|
data: {
|
||||||
title: playlist.name,
|
title: playlist.name,
|
||||||
cover: playlist.cover
|
cover: playlist.cover,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const existing = await this.pb.collection(PUBLIC_COLLECTION).getList(1, 1, {
|
const existing = await this.pb.collection(PUBLIC_COLLECTION).getList(1, 1, {
|
||||||
filter: `uuid="${playlist.id}"`,
|
filter: `uuid="${playlist.id}"`,
|
||||||
p_id: playlist.id
|
p_id: playlist.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existing.items.length > 0) {
|
if (existing.items.length > 0) {
|
||||||
|
|
@ -406,7 +402,7 @@ const syncManager = {
|
||||||
try {
|
try {
|
||||||
const existing = await this.pb.collection('public_playlists').getList(1, 1, {
|
const existing = await this.pb.collection('public_playlists').getList(1, 1, {
|
||||||
filter: `uuid="${uuid}"`,
|
filter: `uuid="${uuid}"`,
|
||||||
p_id: uuid
|
p_id: uuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existing.items && existing.items.length > 0) {
|
if (existing.items && existing.items.length > 0) {
|
||||||
|
|
@ -439,24 +435,36 @@ const syncManager = {
|
||||||
if (this._isSyncing) return;
|
if (this._isSyncing) return;
|
||||||
|
|
||||||
this._isSyncing = true;
|
this._isSyncing = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await this.getUserData();
|
const data = await this.getUserData();
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
const convertedData = {
|
const convertedData = {
|
||||||
favorites_tracks: data.library.tracks ? Object.values(data.library.tracks).filter(t => t && typeof t === 'object') : [],
|
favorites_tracks: data.library.tracks
|
||||||
favorites_albums: data.library.albums ? Object.values(data.library.albums).filter(a => a && typeof a === 'object') : [],
|
? Object.values(data.library.tracks).filter((t) => t && typeof t === 'object')
|
||||||
favorites_artists: data.library.artists ? Object.values(data.library.artists).filter(a => a && typeof a === 'object') : [],
|
: [],
|
||||||
favorites_playlists: data.library.playlists ? Object.values(data.library.playlists).filter(p => p && typeof p === 'object') : [],
|
favorites_albums: data.library.albums
|
||||||
favorites_mixes: data.library.mixes ? Object.values(data.library.mixes).filter(m => m && typeof m === 'object') : [],
|
? Object.values(data.library.albums).filter((a) => a && typeof a === 'object')
|
||||||
|
: [],
|
||||||
|
favorites_artists: data.library.artists
|
||||||
|
? Object.values(data.library.artists).filter((a) => a && typeof a === 'object')
|
||||||
|
: [],
|
||||||
|
favorites_playlists: data.library.playlists
|
||||||
|
? Object.values(data.library.playlists).filter((p) => p && typeof p === 'object')
|
||||||
|
: [],
|
||||||
|
favorites_mixes: data.library.mixes
|
||||||
|
? Object.values(data.library.mixes).filter((m) => m && typeof m === 'object')
|
||||||
|
: [],
|
||||||
history_tracks: data.history || [],
|
history_tracks: data.history || [],
|
||||||
user_playlists: data.userPlaylists ? Object.values(data.userPlaylists).filter(p => p && typeof p === 'object') : [],
|
user_playlists: data.userPlaylists
|
||||||
|
? Object.values(data.userPlaylists).filter((p) => p && typeof p === 'object')
|
||||||
|
: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
await db.importData(convertedData);
|
await db.importData(convertedData);
|
||||||
await new Promise(resolve => setTimeout(resolve, 300));
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||||
|
|
||||||
window.dispatchEvent(new CustomEvent('library-changed'));
|
window.dispatchEvent(new CustomEvent('library-changed'));
|
||||||
window.dispatchEvent(new CustomEvent('history-changed'));
|
window.dispatchEvent(new CustomEvent('history-changed'));
|
||||||
window.dispatchEvent(new HashChangeEvent('hashchange'));
|
window.dispatchEvent(new HashChangeEvent('hashchange'));
|
||||||
|
|
@ -477,4 +485,4 @@ if (pb) {
|
||||||
authManager.onAuthStateChanged(syncManager.onAuthStateChanged.bind(syncManager));
|
authManager.onAuthStateChanged(syncManager.onAuthStateChanged.bind(syncManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
export { pb, syncManager };
|
export { pb, syncManager };
|
||||||
|
|
|
||||||
261
js/db.js
261
js/db.js
|
|
@ -141,28 +141,28 @@ export class MusicDatabase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFavorites(type) {
|
async getFavorites(type) {
|
||||||
const plural = type === 'mix' ? 'mixes' : `${type}s`;
|
const plural = type === 'mix' ? 'mixes' : `${type}s`;
|
||||||
const storeName = `favorites_${plural}`;
|
const storeName = `favorites_${plural}`;
|
||||||
const db = await this.open();
|
const db = await this.open();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const transaction = db.transaction(storeName, 'readonly');
|
const transaction = db.transaction(storeName, 'readonly');
|
||||||
const store = transaction.objectStore(storeName);
|
const store = transaction.objectStore(storeName);
|
||||||
|
|
||||||
const request = store.getAll();
|
const request = store.getAll();
|
||||||
|
|
||||||
request.onsuccess = () => {
|
request.onsuccess = () => {
|
||||||
const results = request.result;
|
const results = request.result;
|
||||||
results.sort((a, b) => {
|
results.sort((a, b) => {
|
||||||
const aTime = a.addedAt || 0;
|
const aTime = a.addedAt || 0;
|
||||||
const bTime = b.addedAt || 0;
|
const bTime = b.addedAt || 0;
|
||||||
return bTime - aTime; // Newest first
|
return bTime - aTime; // Newest first
|
||||||
});
|
});
|
||||||
resolve(results);
|
resolve(results);
|
||||||
};
|
};
|
||||||
request.onerror = () => reject(request.error);
|
request.onerror = () => reject(request.error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_minifyItem(type, item) {
|
_minifyItem(type, item) {
|
||||||
if (!item) return item;
|
if (!item) return item;
|
||||||
|
|
@ -281,105 +281,102 @@ export class MusicDatabase {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async importData(data, clear = false) {
|
async importData(data, clear = false) {
|
||||||
const db = await this.open();
|
const db = await this.open();
|
||||||
|
|
||||||
const importStore = async (storeName, items) => {
|
|
||||||
if (items === undefined) return false;
|
|
||||||
|
|
||||||
let itemsArray = Array.isArray(items) ? items : Object.values(items || {});
|
|
||||||
|
|
||||||
console.log(`Importing to ${storeName}: ${itemsArray.length} items`);
|
|
||||||
|
|
||||||
if (itemsArray.length === 0) {
|
|
||||||
if (clear) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readwrite');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
|
|
||||||
const countReq = store.count();
|
|
||||||
countReq.onsuccess = () => {
|
|
||||||
if (countReq.result > 0) {
|
|
||||||
store.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
transaction.oncomplete = () => {
|
|
||||||
resolve(countReq.result > 0);
|
|
||||||
};
|
|
||||||
transaction.onerror = () => reject(transaction.error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = db.transaction(storeName, 'readwrite');
|
|
||||||
const store = transaction.objectStore(storeName);
|
|
||||||
let hasChanges = false;
|
|
||||||
|
|
||||||
// force clear on first sync
|
|
||||||
console.log(`Clearing ${storeName} to Make Sure Everythings Good`);
|
|
||||||
store.clear();
|
|
||||||
hasChanges = true;
|
|
||||||
|
|
||||||
itemsArray.forEach((item) => {
|
|
||||||
if (item.id && typeof item.id === 'string' && !isNaN(item.id)) {
|
|
||||||
item.id = parseInt(item.id, 10);
|
|
||||||
}
|
|
||||||
if (item.album?.id && typeof item.album.id === 'string' && !isNaN(item.album.id)) {
|
|
||||||
item.album.id = parseInt(item.album.id, 10);
|
|
||||||
}
|
|
||||||
if (item.artists) {
|
|
||||||
item.artists.forEach(artist => {
|
|
||||||
if (artist.id && typeof artist.id === 'string' && !isNaN(artist.id)) {
|
|
||||||
artist.id = parseInt(artist.id, 10);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`${storeName}: Adding item with ID ${item.id || item.uuid || item.timestamp}`);
|
|
||||||
store.put(item);
|
|
||||||
});
|
|
||||||
|
|
||||||
transaction.oncomplete = () => {
|
|
||||||
console.log(`${storeName}: Imported ${itemsArray.length} items`);
|
|
||||||
resolve(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
transaction.onerror = (event) => {
|
|
||||||
console.error(`${storeName}: Transaction error:`, event.target.error);
|
|
||||||
reject(transaction.error);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('Starting import with data:', {
|
|
||||||
tracks: data.favorites_tracks?.length || 0,
|
|
||||||
albums: data.favorites_albums?.length || 0,
|
|
||||||
artists: data.favorites_artists?.length || 0,
|
|
||||||
playlists: data.favorites_playlists?.length || 0,
|
|
||||||
mixes: data.favorites_mixes?.length || 0,
|
|
||||||
history: data.history_tracks?.length || 0,
|
|
||||||
userPlaylists: data.user_playlists?.length || 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = await Promise.all([
|
|
||||||
importStore('favorites_tracks', data.favorites_tracks),
|
|
||||||
importStore('favorites_albums', data.favorites_albums),
|
|
||||||
importStore('favorites_artists', data.favorites_artists),
|
|
||||||
importStore('favorites_playlists', data.favorites_playlists),
|
|
||||||
importStore('favorites_mixes', data.favorites_mixes),
|
|
||||||
importStore('history_tracks', data.history_tracks),
|
|
||||||
data.user_playlists ? importStore('user_playlists', data.user_playlists) : Promise.resolve(false),
|
|
||||||
]);
|
|
||||||
|
|
||||||
console.log('Import results:', results);
|
|
||||||
return results.some((r) => r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const importStore = async (storeName, items) => {
|
||||||
|
if (items === undefined) return false;
|
||||||
|
|
||||||
|
let itemsArray = Array.isArray(items) ? items : Object.values(items || {});
|
||||||
|
|
||||||
|
console.log(`Importing to ${storeName}: ${itemsArray.length} items`);
|
||||||
|
|
||||||
|
if (itemsArray.length === 0) {
|
||||||
|
if (clear) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const transaction = db.transaction(storeName, 'readwrite');
|
||||||
|
const store = transaction.objectStore(storeName);
|
||||||
|
|
||||||
|
const countReq = store.count();
|
||||||
|
countReq.onsuccess = () => {
|
||||||
|
if (countReq.result > 0) {
|
||||||
|
store.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction.oncomplete = () => {
|
||||||
|
resolve(countReq.result > 0);
|
||||||
|
};
|
||||||
|
transaction.onerror = () => reject(transaction.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const transaction = db.transaction(storeName, 'readwrite');
|
||||||
|
const store = transaction.objectStore(storeName);
|
||||||
|
let hasChanges = false;
|
||||||
|
|
||||||
|
// force clear on first sync
|
||||||
|
console.log(`Clearing ${storeName} to Make Sure Everythings Good`);
|
||||||
|
store.clear();
|
||||||
|
hasChanges = true;
|
||||||
|
|
||||||
|
itemsArray.forEach((item) => {
|
||||||
|
if (item.id && typeof item.id === 'string' && !isNaN(item.id)) {
|
||||||
|
item.id = parseInt(item.id, 10);
|
||||||
|
}
|
||||||
|
if (item.album?.id && typeof item.album.id === 'string' && !isNaN(item.album.id)) {
|
||||||
|
item.album.id = parseInt(item.album.id, 10);
|
||||||
|
}
|
||||||
|
if (item.artists) {
|
||||||
|
item.artists.forEach((artist) => {
|
||||||
|
if (artist.id && typeof artist.id === 'string' && !isNaN(artist.id)) {
|
||||||
|
artist.id = parseInt(artist.id, 10);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`${storeName}: Adding item with ID ${item.id || item.uuid || item.timestamp}`);
|
||||||
|
store.put(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
transaction.oncomplete = () => {
|
||||||
|
console.log(`${storeName}: Imported ${itemsArray.length} items`);
|
||||||
|
resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction.onerror = (event) => {
|
||||||
|
console.error(`${storeName}: Transaction error:`, event.target.error);
|
||||||
|
reject(transaction.error);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('Starting import with data:', {
|
||||||
|
tracks: data.favorites_tracks?.length || 0,
|
||||||
|
albums: data.favorites_albums?.length || 0,
|
||||||
|
artists: data.favorites_artists?.length || 0,
|
||||||
|
playlists: data.favorites_playlists?.length || 0,
|
||||||
|
mixes: data.favorites_mixes?.length || 0,
|
||||||
|
history: data.history_tracks?.length || 0,
|
||||||
|
userPlaylists: data.user_playlists?.length || 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await Promise.all([
|
||||||
|
importStore('favorites_tracks', data.favorites_tracks),
|
||||||
|
importStore('favorites_albums', data.favorites_albums),
|
||||||
|
importStore('favorites_artists', data.favorites_artists),
|
||||||
|
importStore('favorites_playlists', data.favorites_playlists),
|
||||||
|
importStore('favorites_mixes', data.favorites_mixes),
|
||||||
|
importStore('history_tracks', data.history_tracks),
|
||||||
|
data.user_playlists ? importStore('user_playlists', data.user_playlists) : Promise.resolve(false),
|
||||||
|
]);
|
||||||
|
|
||||||
|
console.log('Import results:', results);
|
||||||
|
return results.some((r) => r);
|
||||||
|
}
|
||||||
|
|
||||||
_updatePlaylistMetadata(playlist) {
|
_updatePlaylistMetadata(playlist) {
|
||||||
playlist.numberOfTracks = playlist.tracks ? playlist.tracks.length : 0;
|
playlist.numberOfTracks = playlist.tracks ? playlist.tracks.length : 0;
|
||||||
|
|
@ -402,9 +399,11 @@ export class MusicDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
_dispatchPlaylistSync(action, playlist) {
|
_dispatchPlaylistSync(action, playlist) {
|
||||||
window.dispatchEvent(new CustomEvent('sync-playlist-change', {
|
window.dispatchEvent(
|
||||||
detail: { action, playlist }
|
new CustomEvent('sync-playlist-change', {
|
||||||
}));
|
detail: { action, playlist },
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// User Playlists API
|
// User Playlists API
|
||||||
|
|
@ -418,14 +417,14 @@ export class MusicDatabase {
|
||||||
createdAt: Date.now(),
|
createdAt: Date.now(),
|
||||||
updatedAt: Date.now(),
|
updatedAt: Date.now(),
|
||||||
numberOfTracks: tracks.length,
|
numberOfTracks: tracks.length,
|
||||||
images: [] // Initialize images
|
images: [], // Initialize images
|
||||||
};
|
};
|
||||||
this._updatePlaylistMetadata(playlist);
|
this._updatePlaylistMetadata(playlist);
|
||||||
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
||||||
|
|
||||||
// TRIGGER SYNC
|
// TRIGGER SYNC
|
||||||
this._dispatchPlaylistSync('create', playlist);
|
this._dispatchPlaylistSync('create', playlist);
|
||||||
|
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,9 +438,9 @@ export class MusicDatabase {
|
||||||
playlist.updatedAt = Date.now();
|
playlist.updatedAt = Date.now();
|
||||||
this._updatePlaylistMetadata(playlist);
|
this._updatePlaylistMetadata(playlist);
|
||||||
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
||||||
|
|
||||||
this._dispatchPlaylistSync('update', playlist);
|
this._dispatchPlaylistSync('update', playlist);
|
||||||
|
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -453,15 +452,15 @@ export class MusicDatabase {
|
||||||
playlist.updatedAt = Date.now();
|
playlist.updatedAt = Date.now();
|
||||||
this._updatePlaylistMetadata(playlist);
|
this._updatePlaylistMetadata(playlist);
|
||||||
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
||||||
|
|
||||||
this._dispatchPlaylistSync('update', playlist);
|
this._dispatchPlaylistSync('update', playlist);
|
||||||
|
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
async deletePlaylist(playlistId) {
|
async deletePlaylist(playlistId) {
|
||||||
await this.performTransaction('user_playlists', 'readwrite', (store) => store.delete(playlistId));
|
await this.performTransaction('user_playlists', 'readwrite', (store) => store.delete(playlistId));
|
||||||
|
|
||||||
// TRIGGER SYNC (but for deleting)
|
// TRIGGER SYNC (but for deleting)
|
||||||
this._dispatchPlaylistSync('delete', { id: playlistId });
|
this._dispatchPlaylistSync('delete', { id: playlistId });
|
||||||
}
|
}
|
||||||
|
|
@ -474,9 +473,9 @@ export class MusicDatabase {
|
||||||
playlist.updatedAt = Date.now();
|
playlist.updatedAt = Date.now();
|
||||||
this._updatePlaylistMetadata(playlist);
|
this._updatePlaylistMetadata(playlist);
|
||||||
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
await this.performTransaction('user_playlists', 'readwrite', (store) => store.put(playlist));
|
||||||
|
|
||||||
this._dispatchPlaylistSync('update', playlist);
|
this._dispatchPlaylistSync('update', playlist);
|
||||||
|
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,8 @@ export function initializeUIInteractions(player, api) {
|
||||||
const likeBtn = container.querySelector('#like-queue-btn');
|
const likeBtn = container.querySelector('#like-queue-btn');
|
||||||
if (likeBtn) {
|
if (likeBtn) {
|
||||||
likeBtn.addEventListener('click', async () => {
|
likeBtn.addEventListener('click', async () => {
|
||||||
const { db } = await import('./db.js'); // Already imported
|
const { db } = await import('./db.js'); // Already imported
|
||||||
const { syncManager } = await import('./accounts/pocketbase.js');
|
const { syncManager } = await import('./accounts/pocketbase.js');
|
||||||
const { showNotification } = await import('./downloads.js');
|
const { showNotification } = await import('./downloads.js');
|
||||||
|
|
||||||
let addedCount = 0;
|
let addedCount = 0;
|
||||||
|
|
@ -107,8 +107,8 @@ export function initializeUIInteractions(player, api) {
|
||||||
const addToPlaylistBtn = container.querySelector('#add-queue-to-playlist-btn');
|
const addToPlaylistBtn = container.querySelector('#add-queue-to-playlist-btn');
|
||||||
if (addToPlaylistBtn) {
|
if (addToPlaylistBtn) {
|
||||||
addToPlaylistBtn.addEventListener('click', async () => {
|
addToPlaylistBtn.addEventListener('click', async () => {
|
||||||
const { db } = await import('./db.js'); // Already imported
|
const { db } = await import('./db.js'); // Already imported
|
||||||
const { syncManager } = await import('./accounts/pocketbase.js');
|
const { syncManager } = await import('./accounts/pocketbase.js');
|
||||||
const { showNotification } = await import('./downloads.js');
|
const { showNotification } = await import('./downloads.js');
|
||||||
|
|
||||||
const playlists = await db.getPlaylists();
|
const playlists = await db.getPlaylists();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue