new: added default firebase instance, reworked settings layout
This commit is contained in:
parent
2a98654e54
commit
060d4762cc
6 changed files with 338 additions and 188 deletions
384
index.html
384
index.html
|
|
@ -282,190 +282,212 @@
|
|||
<div id="page-settings" class="page">
|
||||
<h2 class="section-title">Settings</h2>
|
||||
<div class="settings-list">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Theme</span>
|
||||
<span class="description">Choose your preferred color scheme</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme-picker" id="theme-picker">
|
||||
<div class="theme-option" data-theme="system">System</div>
|
||||
<div class="theme-option" data-theme="light">Light</div>
|
||||
<div class="theme-option" data-theme="dark">Dark</div>
|
||||
<div class="theme-option" data-theme="monochrome">Black</div>
|
||||
<div class="theme-option" data-theme="ocean">Ocean</div>
|
||||
<div class="theme-option" data-theme="purple">Purple</div>
|
||||
<div class="theme-option" data-theme="forest">Forest</div>
|
||||
<div class="theme-option" data-theme="custom">Custom</div>
|
||||
</div>
|
||||
<div class="custom-theme-editor" id="custom-theme-editor">
|
||||
<h4>Custom Theme</h4>
|
||||
<div class="theme-color-grid" id="theme-color-grid"></div>
|
||||
<div class="theme-actions">
|
||||
<button class="btn-secondary" id="apply-custom-theme">Apply Theme</button>
|
||||
<button class="btn-secondary" id="reset-custom-theme">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Album Cover Background</span>
|
||||
<span class="description">Use the album cover as a blurred background on album pages and as primary color</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="album-background-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Last.fm Scrobbling</span>
|
||||
<span class="description" id="lastfm-status">Connect your Last.fm account to scrobble tracks</span>
|
||||
</div>
|
||||
<div id="lastfm-controls">
|
||||
<button id="lastfm-connect-btn" class="btn-secondary">Connect Last.fm</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-item" id="lastfm-toggle-setting" style="display: none;">
|
||||
<div class="info">
|
||||
<span class="label">Enable Scrobbling</span>
|
||||
<span class="description">Automatically scrobble played tracks</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="lastfm-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Firebase Configuration</span>
|
||||
<span class="description">Paste your Firebase Config JSON here to enable sync.</span>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 0.5rem; width: 100%; max-width: 400px;">
|
||||
<textarea id="firebase-config-input" class="template-input" rows="5" placeholder='{ "apiKey": "...", "authDomain": "...", ... }'></textarea>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<button id="save-firebase-config-btn" class="btn-secondary">Save & Reload</button>
|
||||
<button id="share-firebase-config-btn" class="btn-secondary">Share</button>
|
||||
<button id="clear-firebase-config-btn" class="btn-secondary danger">Clear Config</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Sync & Backup (Beta)</span>
|
||||
<span class="description" id="firebase-status">Sync your library across devices</span>
|
||||
<div style="display: flex; gap: 0.5rem; margin-top: 0.5rem; align-items: center;">
|
||||
<img id="firebase-user-avatar" src="" style="width: 24px; height: 24px; border-radius: 50%; display: none;" onerror="this.style.display='none'" onload="this.style.display='block'">
|
||||
<span id="firebase-user-name" style="font-size: 0.85rem; color: var(--foreground);"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="firebase-controls">
|
||||
<button id="firebase-connect-btn" class="btn-secondary">Connect with Google</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Audio Quality</span>
|
||||
<span class="description">Quality for streaming and downloads</span>
|
||||
</div>
|
||||
<select id="quality-setting">
|
||||
<option value="LOSSLESS">FLAC (Lossless)</option>
|
||||
<option value="HIGH">AAC 320kbps</option>
|
||||
<option value="LOW">AAC 96kbps</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Now Playing View Mode</span>
|
||||
<span class="description">Choose what shows when you click the album art</span>
|
||||
</div>
|
||||
<select id="now-playing-mode">
|
||||
<option value="album">Show Album</option>
|
||||
<option value="cover">Enlarged Cover</option>
|
||||
<option value="lyrics">Lyrics Panel</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Track List Actions</span>
|
||||
<span class="description">Choose between a dropdown menu or inline buttons for track actions</span>
|
||||
</div>
|
||||
<select id="track-list-actions-mode">
|
||||
<option value="dropdown">Dropdown Menu</option>
|
||||
<option value="inline">Inline Buttons</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Download Lyrics</span>
|
||||
<span class="description">Include .lrc files when downloading tracks/albums</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="download-lyrics-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Gapless Playback</span>
|
||||
<span class="description">Play audio without interruption between tracks</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Filename Template</span>
|
||||
<span class="description">Customize download filenames. Available: {trackNumber}, {artist}, {title}, {album}</span>
|
||||
</div>
|
||||
<input type="text" id="filename-template" class="template-input" placeholder="{trackNumber} - {artist} - {title}">
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">ZIP Folder Template</span>
|
||||
<span class="description">Customize album folder names. Available: {albumTitle}, {albumArtist}, {year}</span>
|
||||
</div>
|
||||
<input type="text" id="zip-folder-template" class="template-input" placeholder="{albumTitle} - {albumArtist} - monochrome.tf">
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Keyboard Shortcuts</span>
|
||||
<span class="description">View available keyboard shortcuts</span>
|
||||
</div>
|
||||
<button id="show-shortcuts-btn" class="btn-secondary">Show Shortcuts</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Cache</span>
|
||||
<span class="description" id="cache-info">Stores API responses to reduce requests</span>
|
||||
</div>
|
||||
<button id="clear-cache-btn" class="btn-secondary">Clear Cache</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Backup & Restore</span>
|
||||
<span class="description">Export or import your library and history as JSON</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<button id="export-library-btn" class="btn-secondary">Export</button>
|
||||
<button id="import-library-btn" class="btn-secondary">Import</button>
|
||||
<input type="file" id="import-library-input" style="display: none;" accept=".json">
|
||||
</div>
|
||||
</div>
|
||||
<div id="api-instance-manager">
|
||||
<div class="setting-item" style="padding-bottom: 1rem; border: none;">
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">API Instances</span>
|
||||
<span class="description">Manage and prioritize API instances. Automatically sorted by speed.</span>
|
||||
<span class="label">Theme</span>
|
||||
<span class="description">Choose your preferred color scheme</span>
|
||||
</div>
|
||||
<button id="refresh-speed-test-btn" class="btn-secondary">Refresh Speed Test</button>
|
||||
</div>
|
||||
<ul id="api-instance-list"></ul>
|
||||
<div class="theme-picker" id="theme-picker">
|
||||
<div class="theme-option" data-theme="system">System</div>
|
||||
<div class="theme-option" data-theme="light">Light</div>
|
||||
<div class="theme-option" data-theme="dark">Dark</div>
|
||||
<div class="theme-option" data-theme="monochrome">Black</div>
|
||||
<div class="theme-option" data-theme="ocean">Ocean</div>
|
||||
<div class="theme-option" data-theme="purple">Purple</div>
|
||||
<div class="theme-option" data-theme="forest">Forest</div>
|
||||
<div class="theme-option" data-theme="custom">Custom</div>
|
||||
</div>
|
||||
<div class="custom-theme-editor" id="custom-theme-editor">
|
||||
<h4>Custom Theme</h4>
|
||||
<div class="theme-color-grid" id="theme-color-grid"></div>
|
||||
<div class="theme-actions">
|
||||
<button class="btn-secondary" id="apply-custom-theme">Apply Theme</button>
|
||||
<button class="btn-secondary" id="reset-custom-theme">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Album Cover Background</span>
|
||||
<span class="description">Use the album cover as a blurred background on album pages and as primary color</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="album-background-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Last.fm Scrobbling</span>
|
||||
<span class="description" id="lastfm-status">Connect your Last.fm account to scrobble tracks</span>
|
||||
</div>
|
||||
<div id="lastfm-controls">
|
||||
<button id="lastfm-connect-btn" class="btn-secondary">Connect Last.fm</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-item" id="lastfm-toggle-setting" style="display: none;">
|
||||
<div class="info">
|
||||
<span class="label">Enable Scrobbling</span>
|
||||
<span class="description">Automatically scrobble played tracks</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="lastfm-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Firebase Configuration</span>
|
||||
<span class="description">Manage your database connection.</span>
|
||||
</div>
|
||||
<div class="firebase-settings-wrapper">
|
||||
<button id="toggle-firebase-config-btn" class="btn-secondary">Advanced: Custom Configuration</button>
|
||||
<div id="custom-firebase-config-container" class="custom-firebase-config">
|
||||
<p class="config-help-text">Default shared instance is active. <a href="firebase-setup.md" target="_blank" class="text-link">Override below only if needed.</a></p>
|
||||
<textarea id="firebase-config-input" class="template-input" rows="5" placeholder='{ "apiKey": "...", "authDomain": "...", ... }'></textarea>
|
||||
<div class="firebase-controls-container">
|
||||
<button id="save-firebase-config-btn" class="btn-secondary">Save & Reload</button>
|
||||
<button id="share-firebase-config-btn" class="btn-secondary">Share</button>
|
||||
<button id="clear-firebase-config-btn" class="btn-secondary danger">Clear Config</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Sync & Backup (Beta)</span>
|
||||
<span class="description" id="firebase-status">Sync your library across devices</span>
|
||||
<div style="display: flex; gap: 0.5rem; margin-top: 0.5rem; align-items: center;">
|
||||
<img id="firebase-user-avatar" src="" style="width: 24px; height: 24px; border-radius: 50%; display: none;" onerror="this.style.display='none'" onload="this.style.display='block'">
|
||||
<span id="firebase-user-name" style="font-size: 0.85rem; color: var(--foreground);"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="firebase-controls">
|
||||
<button id="firebase-connect-btn" class="btn-secondary">Connect with Google</button>
|
||||
<button id="firebase-clear-cloud-btn" class="btn-secondary danger" style="display: none; margin-top: 0.5rem;">Clear Cloud Data</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Audio Quality</span>
|
||||
<span class="description">Quality for streaming and downloads</span>
|
||||
</div>
|
||||
<select id="quality-setting">
|
||||
<option value="LOSSLESS">FLAC (Lossless)</option>
|
||||
<option value="HIGH">AAC 320kbps</option>
|
||||
<option value="LOW">AAC 96kbps</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Gapless Playback</span>
|
||||
<span class="description">Play audio without interruption between tracks</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Now Playing View Mode</span>
|
||||
<span class="description">Choose what shows when you click the album art</span>
|
||||
</div>
|
||||
<select id="now-playing-mode">
|
||||
<option value="album">Show Album</option>
|
||||
<option value="cover">Enlarged Cover</option>
|
||||
<option value="lyrics">Lyrics Panel</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Track List Actions</span>
|
||||
<span class="description">Choose between a dropdown menu or inline buttons for track actions</span>
|
||||
</div>
|
||||
<select id="track-list-actions-mode">
|
||||
<option value="dropdown">Dropdown Menu</option>
|
||||
<option value="inline">Inline Buttons</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Download Lyrics</span>
|
||||
<span class="description">Include .lrc files when downloading tracks/albums</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="download-lyrics-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Filename Template</span>
|
||||
<span class="description">Customize download filenames. Available: {trackNumber}, {artist}, {title}, {album}</span>
|
||||
</div>
|
||||
<input type="text" id="filename-template" class="template-input" placeholder="{trackNumber} - {artist} - {title}">
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">ZIP Folder Template</span>
|
||||
<span class="description">Customize album folder names. Available: {albumTitle}, {albumArtist}, {year}</span>
|
||||
</div>
|
||||
<input type="text" id="zip-folder-template" class="template-input" placeholder="{albumTitle} - {albumArtist} - monochrome.tf">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Keyboard Shortcuts</span>
|
||||
<span class="description">View available keyboard shortcuts</span>
|
||||
</div>
|
||||
<button id="show-shortcuts-btn" class="btn-secondary">Show Shortcuts</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Cache</span>
|
||||
<span class="description" id="cache-info">Stores API responses to reduce requests</span>
|
||||
</div>
|
||||
<button id="clear-cache-btn" class="btn-secondary">Clear Cache</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Backup & Restore</span>
|
||||
<span class="description">Export or import your library and history as JSON</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<button id="export-library-btn" class="btn-secondary">Export</button>
|
||||
<button id="import-library-btn" class="btn-secondary">Import</button>
|
||||
<input type="file" id="import-library-input" style="display: none;" accept=".json">
|
||||
</div>
|
||||
</div>
|
||||
<div id="api-instance-manager">
|
||||
<div class="setting-item" style="padding-bottom: 1rem; border: none;">
|
||||
<div class="info">
|
||||
<span class="label">API Instances</span>
|
||||
<span class="description">Manage and prioritize API instances. Automatically sorted by speed.</span>
|
||||
</div>
|
||||
<button id="refresh-speed-test-btn" class="btn-secondary">Refresh Speed Test</button>
|
||||
</div>
|
||||
<ul id="api-instance-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ export class AuthManager {
|
|||
|
||||
updateUI(user) {
|
||||
const connectBtn = document.getElementById('firebase-connect-btn');
|
||||
const clearDataBtn = document.getElementById('firebase-clear-cloud-btn');
|
||||
const statusText = document.getElementById('firebase-status');
|
||||
const userAvatar = document.getElementById('firebase-user-avatar');
|
||||
const userName = document.getElementById('firebase-user-name');
|
||||
|
|
@ -70,6 +71,8 @@ export class AuthManager {
|
|||
connectBtn.classList.add('danger');
|
||||
connectBtn.onclick = () => this.signOut();
|
||||
|
||||
if (clearDataBtn) clearDataBtn.style.display = 'block';
|
||||
|
||||
if (statusText) statusText.textContent = `Signed in as ${user.email}`;
|
||||
|
||||
// Optional: Show user info if elements exist
|
||||
|
|
@ -81,6 +84,8 @@ export class AuthManager {
|
|||
connectBtn.classList.remove('danger');
|
||||
connectBtn.onclick = () => this.signInWithGoogle();
|
||||
|
||||
if (clearDataBtn) clearDataBtn.style.display = 'none';
|
||||
|
||||
if (statusText) statusText.textContent = 'Sync your library across devices';
|
||||
|
||||
if (userAvatar) userAvatar.src = ''; // Placeholder or clear
|
||||
|
|
|
|||
|
|
@ -10,6 +10,15 @@ let provider = null;
|
|||
|
||||
const STORAGE_KEY = 'monochrome-firebase-config';
|
||||
|
||||
const DEFAULT_CONFIG = {
|
||||
apiKey: "AIzaSyDPU-unAjuLtQJt4IkGS5faG50UCF7lYyA",
|
||||
authDomain: "monochrome-database.firebaseapp.com",
|
||||
projectId: "monochrome-database",
|
||||
storageBucket: "monochrome-database.firebasestorage.app",
|
||||
messagingSenderId: "895657412760",
|
||||
appId: "1:895657412760:web:e81c5044c7f4e9b799e8ed"
|
||||
};
|
||||
|
||||
function getStoredConfig() {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEY);
|
||||
|
|
@ -21,19 +30,21 @@ function getStoredConfig() {
|
|||
}
|
||||
|
||||
// Attempt to initialize on load
|
||||
const config = getStoredConfig();
|
||||
const storedConfig = getStoredConfig();
|
||||
const config = storedConfig || DEFAULT_CONFIG;
|
||||
|
||||
if (config) {
|
||||
try {
|
||||
app = initializeApp(config);
|
||||
auth = getAuth(app);
|
||||
database = getDatabase(app);
|
||||
provider = new GoogleAuthProvider();
|
||||
console.log("Firebase initialized from saved config");
|
||||
console.log("Firebase initialized from " + (storedConfig ? "saved" : "default") + " config");
|
||||
} catch (error) {
|
||||
console.error("Error initializing Firebase from saved config:", error);
|
||||
console.error("Error initializing Firebase:", error);
|
||||
}
|
||||
} else {
|
||||
console.log("No Firebase config found in local storage.");
|
||||
console.log("No Firebase config found.");
|
||||
}
|
||||
|
||||
export function saveFirebaseConfig(configObj) {
|
||||
|
|
@ -113,6 +124,22 @@ export function initializeFirebaseSettingsUI() {
|
|||
const saveFirebaseConfigBtn = document.getElementById('save-firebase-config-btn');
|
||||
const clearFirebaseConfigBtn = document.getElementById('clear-firebase-config-btn');
|
||||
const shareFirebaseConfigBtn = document.getElementById('share-firebase-config-btn');
|
||||
const toggleFirebaseConfigBtn = document.getElementById('toggle-firebase-config-btn');
|
||||
const customFirebaseConfigContainer = document.getElementById('custom-firebase-config-container');
|
||||
|
||||
// Toggle Button Logic
|
||||
if (toggleFirebaseConfigBtn && customFirebaseConfigContainer) {
|
||||
toggleFirebaseConfigBtn.addEventListener('click', () => {
|
||||
const isVisible = customFirebaseConfigContainer.classList.contains('visible');
|
||||
if (isVisible) {
|
||||
customFirebaseConfigContainer.classList.remove('visible');
|
||||
toggleFirebaseConfigBtn.textContent = 'Advanced: Custom Configuration';
|
||||
} else {
|
||||
customFirebaseConfigContainer.classList.add('visible');
|
||||
toggleFirebaseConfigBtn.textContent = 'Hide Custom Configuration';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Populate current config
|
||||
if (firebaseConfigInput) {
|
||||
|
|
@ -120,6 +147,11 @@ export function initializeFirebaseSettingsUI() {
|
|||
if (currentConfig) {
|
||||
try {
|
||||
firebaseConfigInput.value = JSON.stringify(JSON.parse(currentConfig), null, 2);
|
||||
// If custom config exists, show the container
|
||||
if (customFirebaseConfigContainer && toggleFirebaseConfigBtn) {
|
||||
customFirebaseConfigContainer.classList.add('visible');
|
||||
toggleFirebaseConfigBtn.textContent = 'Hide Custom Configuration';
|
||||
}
|
||||
} catch (e) {
|
||||
firebaseConfigInput.value = currentConfig;
|
||||
}
|
||||
|
|
@ -192,7 +224,7 @@ export function initializeFirebaseSettingsUI() {
|
|||
// Clear Button
|
||||
if (clearFirebaseConfigBtn) {
|
||||
clearFirebaseConfigBtn.addEventListener('click', () => {
|
||||
if (confirm('Are you sure you want to clear the Firebase configuration? Sync will stop.')) {
|
||||
if (confirm('Are you sure you want to remove the custom configuration? The app will revert to the shared default database.')) {
|
||||
clearFirebaseConfig();
|
||||
window.location.reload();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,16 @@ export class SyncManager {
|
|||
const itemRef = child(this.userRef, path);
|
||||
|
||||
if (isAdded) {
|
||||
await set(itemRef, item);
|
||||
// Minify to ensure consistency and reduce bandwidth
|
||||
// We use the db helper to ensure consistent structure
|
||||
const minified = db._minifyItem(type, item);
|
||||
// Ensure addedAt is present. If the passed item didn't have it (e.g. from player),
|
||||
// we add it now. Ideally this matches local DB time, but a small diff is negligible.
|
||||
const entry = {
|
||||
...minified,
|
||||
addedAt: item.addedAt || minified.addedAt || Date.now()
|
||||
};
|
||||
await set(itemRef, entry);
|
||||
} else {
|
||||
await remove(itemRef);
|
||||
}
|
||||
|
|
@ -222,6 +231,13 @@ export class SyncManager {
|
|||
console.error("Failed to sync history item:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async clearCloudData() {
|
||||
if (!this.user || !this.userRef) {
|
||||
throw new Error("Not authenticated");
|
||||
}
|
||||
await remove(this.userRef);
|
||||
}
|
||||
}
|
||||
|
||||
export const syncManager = new SyncManager();
|
||||
|
|
|
|||
|
|
@ -298,6 +298,19 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
}
|
||||
});
|
||||
|
||||
document.getElementById('firebase-clear-cloud-btn')?.addEventListener('click', async () => {
|
||||
if (confirm('Are you sure you want to delete ALL your data from the cloud? This cannot be undone.')) {
|
||||
try {
|
||||
await syncManager.clearCloudData();
|
||||
alert('Cloud data cleared successfully.');
|
||||
authManager.signOut();
|
||||
} catch (error) {
|
||||
console.error('Failed to clear cloud data:', error);
|
||||
alert('Failed to clear cloud data: ' + error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Backup & Restore
|
||||
document.getElementById('export-library-btn')?.addEventListener('click', async () => {
|
||||
const data = await db.exportData();
|
||||
|
|
|
|||
64
styles.css
64
styles.css
|
|
@ -174,6 +174,16 @@ a {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.text-link {
|
||||
color: var(--primary);
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.text-link:hover {
|
||||
color: var(--highlight);
|
||||
}
|
||||
|
||||
kbd {
|
||||
background-color: var(--secondary);
|
||||
border: 1px solid var(--border);
|
||||
|
|
@ -997,10 +1007,22 @@ body.has-page-background .track-item:hover {
|
|||
max-width: 800px;
|
||||
}
|
||||
|
||||
.settings-group {
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: var(--spacing-lg) 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-md);
|
||||
}
|
||||
|
||||
.settings-group .setting-item {
|
||||
border-bottom: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: var(--spacing-lg) 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
gap: var(--spacing-lg);
|
||||
|
|
@ -3200,4 +3222,44 @@ img:not([src]), img[src=''] {
|
|||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* Firebase Settings Styling */
|
||||
.firebase-settings-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.custom-firebase-config {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.custom-firebase-config.visible {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.config-help-text {
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
#firebase-controls {
|
||||
text-align: end;
|
||||
}
|
||||
.firebase-controls-container {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#toggle-firebase-config-btn {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue