settings import + export

This commit is contained in:
edidealt 2026-03-02 23:32:51 +00:00
parent be67f79968
commit 9054016ff2
3 changed files with 91 additions and 5 deletions

View file

@ -5076,6 +5076,24 @@
/>
</div>
</div>
<div class="setting-item">
<div class="info">
<span class="label">Export All Settings</span>
<span class="description"
>Export all app settings as JSON</span
>
</div>
<div style="display: flex; gap: 0.5rem">
<button id="export-settings-btn" class="btn-secondary">Export</button>
<button id="import-settings-btn" class="btn-secondary">Import</button>
<input
type="file"
id="import-settings-input"
style="display: none"
accept=".json"
/>
</div>
</div>
<div class="setting-item">
<div class="info">
<span class="label">ADVANCED: Custom Database/Auth</span>

View file

@ -2562,12 +2562,27 @@ document.addEventListener('DOMContentLoaded', async () => {
const headerAccountImg = document.getElementById('header-account-img');
const headerAccountIcon = document.getElementById('header-account-icon');
// Temporarily disable accounts - show popup
const isAccountsDisabled = true;
if (headerAccountBtn && headerAccountDropdown) {
headerAccountBtn.addEventListener('click', (e) => {
e.stopPropagation();
headerAccountDropdown.classList.toggle('active');
updateAccountDropdown();
});
if (isAccountsDisabled) {
headerAccountBtn.style.opacity = '0.5';
headerAccountBtn.style.cursor = 'not-allowed';
headerAccountBtn.title = 'Accounts temporarily unavailable';
headerAccountBtn.addEventListener('click', (e) => {
e.stopPropagation();
alert(
"We're moving authentication and data storing systems.\n\nAccounts, profiles, playlists, and community themes will not work during this period (approximately 2 days).\n\nYou will need to re-login after the migration is complete."
);
});
} else {
headerAccountBtn.addEventListener('click', (e) => {
e.stopPropagation();
headerAccountDropdown.classList.toggle('active');
updateAccountDropdown();
});
}
document.addEventListener('click', (e) => {
if (!headerAccountBtn.contains(e.target) && !headerAccountDropdown.contains(e.target)) {

View file

@ -2750,6 +2750,59 @@ export function initializeSettings(scrobbler, player, api, ui) {
reader.readAsText(file);
});
// Export All Settings
document.getElementById('export-settings-btn')?.addEventListener('click', () => {
const settingsToExport = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && key.startsWith('monochrome-')) {
try {
settingsToExport[key] = JSON.parse(localStorage.getItem(key));
} catch {
settingsToExport[key] = localStorage.getItem(key);
}
}
}
const blob = new Blob([JSON.stringify(settingsToExport, null, 2)], {
type: 'application/json',
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `monochrome-settings-${new Date().toISOString().split('T')[0]}.json`;
a.click();
URL.revokeObjectURL(url);
});
// Import All Settings
const settingsImportInput = document.getElementById('import-settings-input');
document.getElementById('import-settings-btn')?.addEventListener('click', () => {
settingsImportInput.click();
});
settingsImportInput?.addEventListener('change', async (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = async (event) => {
try {
const settingsToImport = JSON.parse(event.target.result);
for (const [key, value] of Object.entries(settingsToImport)) {
if (key.startsWith('monochrome-')) {
localStorage.setItem(key, typeof value === 'string' ? value : JSON.stringify(value));
}
}
alert('Settings imported successfully! Please reload the app.');
window.location.reload();
} catch (err) {
console.error('Import failed:', err);
alert('Failed to import settings. Please check the file format.');
}
};
reader.readAsText(file);
});
const customDbBtn = document.getElementById('custom-db-btn');
const customDbModal = document.getElementById('custom-db-modal');
const customPbUrlInput = document.getElementById('custom-pb-url');