import { html, useState, useEffect } from './vendor/htm-preact.js'; import { t } from './i18n.js'; import { ToggleSwitch, useSaver } from './settings-ui.js'; import { FolderPickerField } from './folder-tree.js'; /** * Chat's operator settings. * * Every app's settings pane takes the same props (see `apps.js`): the group's * roots and known folders, the node's current answers, a `saveDirectories` * bound to this app, and the transport for anything the app alone needs. It * owns its drafts and its own busy state, and the page renders it without * naming it. * * The directory here is unlike every other app's. Videos, Music and Photos * point at folders they *read*; this is where attachments get *written*, so it * has to be on a read-write root. The picker greys out the rest rather than * letting the node's refusal arrive after the fact. */ function ChatSettings({ roots, dirs, settings, saveDirectories, transport, signFn }) { const { busy, msg, run } = useSaver(); const [directory, setDirectory] = useState(settings.chatDirectory || ''); const [linkPreview, setLinkPreview] = useState(settings.chatLinkPreview !== false); // Re-seeded from the node's answer: another operator may be editing the // same group, and their change arrives here as a prop. useEffect(() => { setDirectory(settings.chatDirectory || ''); }, [settings.chatDirectory]); useEffect(() => { setLinkPreview(settings.chatLinkPreview !== false); }, [settings.chatLinkPreview]); const noWritable = !(roots || []).some((r) => r.writable); const dirty = directory !== (settings.chatDirectory || ''); return html`
${noWritable && html`

${t('settings_app.chat_no_writable_root')}

`} <${FolderPickerField} label=${t('settings_app.chat_directory_label')} hint=${t('settings_app.chat_directory_hint')} roots=${roots} dirs=${dirs} mode="single" requireWritable=${true} value=${directory} disabled=${busy || noWritable} onChange=${setDirectory} />
<${ToggleSwitch} checked=${linkPreview} disabled=${busy} onChange=${(v) => { setLinkPreview(v); run(() => transport.setChatLinkPreview(v, signFn)); }} label=${t('settings_app.chat_link_preview_label')} />

${t('settings_app.chat_link_preview_hint')}

${/* Not a toggle: chat is always encrypted (MNP 2.0), so there is nothing here to turn on. What an operator may want is to move the key on deliberately — the removals that matter already do it by themselves. Stated rather than left invisible, because "is my chat encrypted?" is a question people ask of a settings pane. */ ''}

${t('settings_app.chat_encrypted_always')}

${t('settings_app.chat_rotate_epoch_hint')}

${msg && html`

${msg}

`}
`; } export { ChatSettings };