Files

72 lines
2.4 KiB
JavaScript

// "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 };
}