yet another preventative fix
This commit is contained in:
parent
134cd05113
commit
52b1bb946a
4 changed files with 60 additions and 5 deletions
|
|
@ -677,7 +677,35 @@ const syncManager = {
|
||||||
user_folders: Object.values(userFolders).filter((f) => f && typeof f === 'object'),
|
user_folders: Object.values(userFolders).filter((f) => f && typeof f === 'object'),
|
||||||
};
|
};
|
||||||
|
|
||||||
await database.importData(convertedData);
|
// Safety check: if we had local data but merged result is completely empty, something went wrong.
|
||||||
|
// Do NOT call importData as it would wipe the user's local stores.
|
||||||
|
const hadLocalData =
|
||||||
|
localData.tracks.length > 0 ||
|
||||||
|
localData.albums.length > 0 ||
|
||||||
|
localData.artists.length > 0 ||
|
||||||
|
localData.playlists.length > 0 ||
|
||||||
|
localData.mixes.length > 0 ||
|
||||||
|
localData.history.length > 0 ||
|
||||||
|
localData.userPlaylists.length > 0 ||
|
||||||
|
localData.userFolders.length > 0;
|
||||||
|
|
||||||
|
const isConvertedEmpty =
|
||||||
|
convertedData.favorites_tracks.length === 0 &&
|
||||||
|
convertedData.favorites_albums.length === 0 &&
|
||||||
|
convertedData.favorites_artists.length === 0 &&
|
||||||
|
convertedData.favorites_playlists.length === 0 &&
|
||||||
|
convertedData.favorites_mixes.length === 0 &&
|
||||||
|
convertedData.history_tracks.length === 0 &&
|
||||||
|
convertedData.user_playlists.length === 0 &&
|
||||||
|
convertedData.user_folders.length === 0;
|
||||||
|
|
||||||
|
if (hadLocalData && isConvertedEmpty) {
|
||||||
|
console.warn(
|
||||||
|
'[PocketBase] Sync aborted: local data exists but merged result is empty. Preserving local data to prevent accidental wipe.'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await database.importData(convertedData, true);
|
||||||
|
}
|
||||||
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'));
|
||||||
|
|
|
||||||
|
|
@ -412,6 +412,13 @@ async function uploadCoverImage(file) {
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
await modernSettings.waitPending();
|
await modernSettings.waitPending();
|
||||||
|
|
||||||
|
// Request persistent storage to reduce risk of browser wiping data on updates or cleanup
|
||||||
|
if (navigator.storage && navigator.storage.persist) {
|
||||||
|
navigator.storage.persist().catch(() => {
|
||||||
|
// Ignore errors; persistence is a best-effort request
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
window.monochrome = {
|
window.monochrome = {
|
||||||
HiFiClient,
|
HiFiClient,
|
||||||
|
|
|
||||||
24
js/db.js
24
js/db.js
|
|
@ -455,6 +455,25 @@ export class MusicDatabase {
|
||||||
async importData(data, clear = false) {
|
async importData(data, clear = false) {
|
||||||
const db = await this.open();
|
const db = await this.open();
|
||||||
|
|
||||||
|
// Safety check: if clear=true but all data is empty, skip to avoid wiping existing data
|
||||||
|
if (clear) {
|
||||||
|
const allEmpty = [
|
||||||
|
data.favorites_tracks,
|
||||||
|
data.favorites_albums,
|
||||||
|
data.favorites_artists,
|
||||||
|
data.favorites_playlists,
|
||||||
|
data.favorites_mixes,
|
||||||
|
data.history_tracks,
|
||||||
|
data.user_playlists,
|
||||||
|
data.user_folders,
|
||||||
|
].every((arr) => !arr || (Array.isArray(arr) ? arr.length === 0 : Object.keys(arr).length === 0));
|
||||||
|
|
||||||
|
if (allEmpty) {
|
||||||
|
console.warn('[importData] Aborting: clear=true but all import data is empty. Existing data preserved.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const importStore = async (storeName, items) => {
|
const importStore = async (storeName, items) => {
|
||||||
if (items === undefined) return false;
|
if (items === undefined) return false;
|
||||||
|
|
||||||
|
|
@ -488,9 +507,10 @@ export class MusicDatabase {
|
||||||
const transaction = db.transaction(storeName, 'readwrite');
|
const transaction = db.transaction(storeName, 'readwrite');
|
||||||
const store = transaction.objectStore(storeName);
|
const store = transaction.objectStore(storeName);
|
||||||
|
|
||||||
// force clear on first sync
|
if (clear) {
|
||||||
console.log(`Clearing ${storeName} to Make Sure Everythings Good`);
|
console.log(`[importData] Clearing ${storeName} before import`);
|
||||||
store.clear();
|
store.clear();
|
||||||
|
}
|
||||||
|
|
||||||
itemsArray.forEach((item) => {
|
itemsArray.forEach((item) => {
|
||||||
if (item.id && typeof item.id === 'string' && !isNaN(item.id)) {
|
if (item.id && typeof item.id === 'string' && !isNaN(item.id)) {
|
||||||
|
|
|
||||||
|
|
@ -6573,7 +6573,7 @@ export async function initializeSettings(scrobbler, player, api, ui) {
|
||||||
reader.onload = async (event) => {
|
reader.onload = async (event) => {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(event.target.result);
|
const data = JSON.parse(event.target.result);
|
||||||
await db.importData(data);
|
await db.importData(data, true);
|
||||||
alert('Library imported successfully!');
|
alert('Library imported successfully!');
|
||||||
window.location.reload(); // Simple way to refresh all state
|
window.location.reload(); // Simple way to refresh all state
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue