diff --git a/docker-compose.yml b/docker-compose.yml index d7f6363..4687484 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,4 +5,12 @@ services: build: . ports: - "7481:3000" + restart: unless-stopped + + sync-service: + build: ./sync-server + ports: + - "7482:3001" + volumes: + - ./data:/app/data restart: unless-stopped \ No newline at end of file diff --git a/index.html b/index.html index 049df05..30a9121 100644 --- a/index.html +++ b/index.html @@ -139,6 +139,9 @@ const { useState, useEffect, useRef, useMemo, useCallback } = React; const API_BASE = "https://music-dl.sayqz.com"; + // Use relative path for sync service, assuming Nginx proxy is configured to forward /api/kv to the sync service + const SYNC_API_BASE = "/api"; + const SOURCES = [ { id: 'netease', name: '网易云' }, { id: 'kuwo', name: '酷我' }, @@ -245,6 +248,34 @@ } }; + // --- Sync Service --- + const syncService = { + get: async (key, token) => { + if (!token) return null; + try { + const res = await fetch(`${SYNC_API_BASE}/kv/${key}?token=${encodeURIComponent(token)}`); + if (res.ok) { + return await res.json(); + } + } catch (e) { + console.error("Sync get failed", e); + } + return null; + }, + set: async (key, data, token) => { + if (!token) return; + try { + await fetch(`${SYNC_API_BASE}/kv/${key}?token=${encodeURIComponent(token)}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data) + }); + } catch (e) { + console.error("Sync set failed", e); + } + } + }; + // --- Components --- const Icon = ({ name, size = "", className = "", onClick }) => ( @@ -319,7 +350,7 @@ ); - const SideDrawer = ({ isOpen, onClose, view, setView, quality, setQuality, onClearCache }) => { + const SideDrawer = ({ isOpen, onClose, view, setView, quality, setQuality, onClearCache, syncToken, setSyncToken, onSyncNow }) => { if (!isOpen) return null; return ( @@ -366,6 +397,26 @@ +
+ +
+ setSyncToken(e.target.value)} + placeholder="输入任意密钥以同步" + className="bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-sm text-white w-full focus:outline-none focus:border-primary" + /> + +
+

使用相同的密钥在多端同步收藏列表

+
+