/** * 移动端同步模块 */ import { App } from './state.js'; import { ensureSession } from './utils.js'; import { addFileMessage } from './chat.js'; import { checkAutoStart, promptMissingConfig } from './config.js'; export async function generateQr() { await ensureSession(); const mobileUrl = window.location.origin + '/mobile/' + App.sessionId; const box = document.getElementById('qrcode'); box.innerHTML = ''; new QRCode(box, { text: mobileUrl, width: 120, height: 120, colorDark: '#333', colorLight: '#fff', }); } export async function startSync() { if (App.syncTimer) return; await syncFiles(); App.syncTimer = setInterval(syncFiles, 3000); } export function stopSync() { if (App.syncTimer) { clearInterval(App.syncTimer); App.syncTimer = null; } } async function syncFiles() { if (!App.sessionId) return; try { const r = await fetch(`/api/files/${App.sessionId}`); const d = await r.json(); const serverFiles = d.files || []; const serverNames = new Set(serverFiles.map(f => f.name)); const localNames = new Set(App.allFiles.map(f => f.name)); const addedFiles = []; for (const serverFile of serverFiles) { if (!localNames.has(serverFile.name)) { const resp = await fetch(`/api/download/${App.sessionId}/${encodeURIComponent(serverFile.name)}`); const blob = await resp.blob(); const file = new File([blob], serverFile.name, { type: blob.type }); file.__source = 'server'; App.allFiles.push(file); addedFiles.push(serverFile.name); } } for (const f of [...App.allFiles]) { if (!serverNames.has(f.name) && f.__source !== 'local') { const idx = App.allFiles.indexOf(f); if (idx > -1) App.allFiles.splice(idx, 1); } } if (addedFiles.length) { addedFiles.forEach(name => addFileMessage(name)); if (App.processState === 'done') { App.processState = 'idle'; App.newFilenames = addedFiles; } else if (App.processState === 'awaiting_supplement') { App.processState = 'idle'; App.newFilenames = addedFiles; } } if (App.allFiles.length) { document.getElementById('file-zone').classList.add('active'); } else { document.getElementById('file-zone').classList.remove('active'); } checkAutoStart(); } catch (e) { /* ignore */ } }