feat: First iteration, multi themes, I18N
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
// "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 };
|
||||
}
|
||||
Reference in New Issue
Block a user