// "Save & settings" dialog: export (file or text), import (file or pasted text), reset. import { downloadText, ImportError, readFileText } from '../services/saveio.js'; import { t } from '../services/i18n.js'; import { $ } from './dom.js'; import { showToast } from './toast.js'; /** * @param hooks.getExport () => { text, name } current save as text + file base name * @param hooks.importText (text) => void throws ImportError on bad input * @param hooks.reset () => void */ export function createSettings(hooks) { const dialog = $('#settings'); const exportBox = $('#export-text'); const importBox = $('#import-text'); const fileInput = $('#import-file'); function open() { exportBox.value = hooks.getExport().text; importBox.value = ''; if (typeof dialog.showModal === 'function') dialog.showModal(); else dialog.setAttribute('open', ''); } function download(extension, mime) { const { text, name } = hooks.getExport(); downloadText(`${name}.${extension}`, text, mime); } async function copy() { exportBox.value = hooks.getExport().text; try { await navigator.clipboard.writeText(exportBox.value); } catch { exportBox.select(); if (!document.execCommand?.('copy')) return showToast(t('toast.copyFailed'), { error: true }); } showToast(t('toast.copied')); } async function runImport(text) { try { await hooks.importText(text); dialog.close?.(); showToast(t('toast.imported')); } catch (error) { const code = error instanceof ImportError ? error.code : 'invalid'; showToast(t(`error.import.${code}`), { error: true }); } } $('#open-settings').addEventListener('click', open); $('#export-json').addEventListener('click', () => download('json', 'application/json')); $('#export-txt').addEventListener('click', () => download('txt', 'text/plain')); $('#export-copy').addEventListener('click', copy); $('#import-paste').addEventListener('click', () => runImport(importBox.value)); fileInput.addEventListener('change', async () => { const file = fileInput.files?.[0]; fileInput.value = ''; // allow picking the same file again if (file) await runImport(await readFileText(file)); }); $('#reset-game').addEventListener('click', () => { if (!confirm(t('settings.resetConfirm'))) return; hooks.reset(); dialog.close?.(); showToast(t('toast.reset')); }); return { open }; }