Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/utils/SettingsExportImport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const STORAGE_PREFIXES = ["SpicyLyrics-", "spicy-lyrics-settings.", "spicy-lyrics-dev-settings.", "spicy-lyrics-health."];

export function exportSettings(): void {
const data: Record<string, string> = {};

for (let i = 0; i < window.localStorage.length; i++) {
const key = window.localStorage.key(i);
if (!key) continue;
if (STORAGE_PREFIXES.some((p) => key.startsWith(p))) {
data[key] = window.localStorage.getItem(key) ?? "";
}
}

const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `spicy-lyrics-settings-${new Date().toISOString().slice(0, 10)}.json`;
a.click();
URL.revokeObjectURL(url);
}

export function importSettings(): void {
const input = document.createElement("input");
input.type = "file";
input.accept = ".json";
input.onchange = (e: Event) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (ev) => {
try {
const raw = ev.target?.result;
if (typeof raw !== "string") throw new Error("empty");
const data = JSON.parse(raw) as Record<string, unknown>;
for (const [key, value] of Object.entries(data)) {
if (typeof value === "string") {
window.localStorage.setItem(key, value);
}
}
(Spicetify as any).showNotification?.("Settings imported! Reloading in 2s…", false, 2000);
setTimeout(() => window.location.reload(), 2200);
} catch {
(Spicetify as any).showNotification?.("Failed to import: invalid settings file.", true);
}
};
reader.readAsText(file);
};
input.click();
}
37 changes: 37 additions & 0 deletions src/utils/settings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Defaults from "../components/Global/Defaults.ts";
import storage from "./storage.ts";
import { RemoveCurrentLyrics_AllCaches, RemoveCurrentLyrics_StateCache, RemoveLyricsCache } from "./LyricsCacheTools.ts";
import { exportSettings, importSettings } from "./SettingsExportImport.ts";
import { ProjectVersion } from "../../project/config.ts";

export async function setSettingsMenu() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
Expand All @@ -11,6 +13,7 @@ export async function setSettingsMenu() {

generalSettings(SettingsSection);
devSettings(SettingsSection);
healthSettings(SettingsSection);
//infos(SettingsSection);
}

Expand Down Expand Up @@ -207,6 +210,40 @@ function generalSettings(SettingsSection: any) {
settings.pushSettings();
}

function healthSettings(SettingsSection: any) {
const settings = new SettingsSection(
"Spicy Lyrics - Info & Health",
"spicy-lyrics-health"
);

settings.addButton(
"version-info",
`Extension version: ${ProjectVersion} | API: ${Defaults.lyrics.api.url}`,
"Copy Debug Info",
() => {
const info = `Spicy Lyrics v${ProjectVersion} | API: ${Defaults.lyrics.api.url}`;
navigator.clipboard?.writeText(info).catch(() => {});
(Spicetify as any).showNotification?.("Debug info copied to clipboard", false, 2000);
}
);

settings.addButton(
"export-settings",
"Download all Spicy Lyrics settings as a JSON file for backup or sharing",
"Export Settings",
() => exportSettings()
);

settings.addButton(
"import-settings",
"Restore settings from a previously exported JSON file (reloads Spotify)",
"Import Settings",
() => importSettings()
);

settings.pushSettings();
}

/* function infos(SettingsSection: any) {
const settings = new SettingsSection("Spicy Lyrics - Info", "spicy-lyrics-settings-info");

Expand Down