283 lines
7.1 KiB
JavaScript
283 lines
7.1 KiB
JavaScript
import { CustomHTMLElement } from "./lib/custom_html_element.mjs"
|
|
import { API } from './api.mjs'
|
|
|
|
export class N2PagePreferences extends CustomHTMLElement {
|
|
static {// {{{
|
|
this.tmpl = document.createElement('template')
|
|
this.tmpl.innerHTML = `
|
|
<style>
|
|
.el-sets {
|
|
display: grid;
|
|
grid-template-columns: min-content;
|
|
grid-gap: 32px;
|
|
}
|
|
|
|
:host > div {
|
|
margin-bottom: 32px;
|
|
}
|
|
|
|
.dev-pref-set {
|
|
display: grid;
|
|
grid-template-columns: min-content min-content;
|
|
grid-gap: 16px;
|
|
align-items: center;
|
|
white-space: nowrap;
|
|
}
|
|
</style>
|
|
<h1>Preferences</h1>
|
|
|
|
<div>Changes preferences to not download images or files on the device doesn't remove the already downloaded data.</div>
|
|
|
|
<div class="dev-pref-set">
|
|
<div>Device preference set</div>
|
|
<select data-el="dev-preference-set"></select>
|
|
</div>
|
|
|
|
<div data-el="sets"></div>
|
|
|
|
<button data-el="new-set">New set</button>
|
|
<button data-el="save" disabled>Save</button>
|
|
`
|
|
}// }}}
|
|
constructor() {// {{{
|
|
super(true)
|
|
this.sets = []
|
|
|
|
this.elNewSet.addEventListener('click', () => this.newSet())
|
|
this.elSave.addEventListener('click', () => this.save())
|
|
this.elDevPreferenceSet.addEventListener('change', event=>this.changePreferenceSet(event))
|
|
|
|
window._mbus.subscribe('SHOW_PAGE', async event => {
|
|
if (event.detail.data?.page == 'preferences') {
|
|
this.sets = await this.getPreferenceSets()
|
|
this.render()
|
|
}
|
|
})
|
|
|
|
window._mbus.subscribe('PREFERENCE_SET_MODIFIED', () => this.preferencesModified())
|
|
window._mbus.subscribe('PREFERENCE_SET_DELETE', event => this.preferencesDelete(event.detail.data.set))
|
|
}// }}}
|
|
sortSets(a, b) {// {{{
|
|
if (a.name == 'default') return -1
|
|
if (b.name == 'default') return 1
|
|
|
|
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1
|
|
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1
|
|
|
|
return 0
|
|
}// }}}
|
|
async render() {// {{{
|
|
try {
|
|
this.sets.sort(this.sortSets)
|
|
this.elSets.replaceChildren(...this.sets)
|
|
|
|
const setNames = this.sets.entries().map(([i, set]) => {
|
|
const optn = document.createElement('option')
|
|
optn.innerText = set.name
|
|
return optn
|
|
})
|
|
this.elDevPreferenceSet.replaceChildren(...setNames)
|
|
} catch (e) {
|
|
console.error(e)
|
|
alert(e.message)
|
|
}
|
|
}// }}}
|
|
async getPreferenceSets() {// {{{
|
|
const userData = localStorage.getItem('user')
|
|
if (userData === null)
|
|
throw new Error('Could not find user in localStorage')
|
|
|
|
const user = JSON.parse(userData)
|
|
const prefsData = user.Preferences
|
|
|
|
if (prefsData === undefined)
|
|
throw new Error('User object is missing preferences')
|
|
|
|
if (!prefsData.hasOwnProperty('default'))
|
|
throw new Error('The "default" preferences set is missing')
|
|
|
|
return Object.keys(prefsData).map(name => new N2PreferenceSet(name, prefsData[name]))
|
|
}// }}}
|
|
async retrieveServerPreferences() {// {{{
|
|
try {
|
|
API.query('GET', '/user/preferences')
|
|
} catch (e) {
|
|
console.error(e)
|
|
alert(`Error retrieving preferences: ${e.message}`)
|
|
}
|
|
}// }}}
|
|
changePreferenceSet(event) {// {{{
|
|
this.preferencesModified()
|
|
}// }}}
|
|
newSet() {// {{{
|
|
let name = prompt("Name for new preference set")
|
|
if (!name)
|
|
return
|
|
|
|
name = name.trim()
|
|
if (name === '')
|
|
return
|
|
|
|
if (name == 'default') {
|
|
alert(`Name can't be "default".`)
|
|
return
|
|
}
|
|
|
|
const exists = this.sets.some(s => s.name.toLowerCase() == name.toLowerCase())
|
|
if (exists) {
|
|
alert(`Set with name "${name}" already exist.`)
|
|
return
|
|
}
|
|
|
|
this.sets.push(new N2PreferenceSet(name, {}))
|
|
this.preferencesModified()
|
|
this.render()
|
|
}// }}}
|
|
preferencesModified() {// {{{
|
|
this.elSave.removeAttribute('disabled')
|
|
}// }}}
|
|
preferencesDelete(deleteSet) {// {{{
|
|
if (deleteSet.name == 'default') {
|
|
alert("Can't delete the default set.")
|
|
return
|
|
}
|
|
|
|
if (!confirm(`Confirm deleting "${deleteSet.name}"`))
|
|
return
|
|
|
|
this.sets = this.sets.filter(set => {
|
|
return !(set.name === deleteSet.name)
|
|
})
|
|
|
|
this.preferencesModified()
|
|
this.render()
|
|
}// }}}
|
|
async save() {// {{{
|
|
try {
|
|
let newPrefs = {}
|
|
this.sets.forEach(s => {
|
|
const setState = s.getState()
|
|
newPrefs[setState.name] = setState.state
|
|
})
|
|
|
|
// Throws exception on both HTTP and application errors.
|
|
await API.query('POST', '/user/preferences', newPrefs)
|
|
|
|
const userData = localStorage.getItem('user')
|
|
const user = JSON.parse(userData)
|
|
user.Preferences = newPrefs
|
|
localStorage.setItem('user', JSON.stringify(user))
|
|
localStorage.setItem('device_preference_set', this.elDevPreferenceSet.value)
|
|
_mbus.dispatch('DEVICE_PREFERENCE_SET_UPDATED')
|
|
} catch (e) {
|
|
console.error(e)
|
|
alert(e.message)
|
|
} finally {
|
|
this.elSave.setAttribute('disabled', true)
|
|
}
|
|
|
|
}// }}}
|
|
}
|
|
customElements.define('n2-pagepreferences', N2PagePreferences)
|
|
|
|
// Preferences is a set of preferences, of which there can be many named.
|
|
export class N2PreferenceSet extends CustomHTMLElement {
|
|
static {// {{{
|
|
this.tmpl = document.createElement('template')
|
|
this.tmpl.innerHTML = `
|
|
<style>
|
|
:host {
|
|
border: 1px solid var(--line-color);
|
|
padding: 16px;
|
|
|
|
display: grid;
|
|
grid-template-columns: min-content 1fr;
|
|
justify-items: start;
|
|
align-items: center;
|
|
grid-gap: 8px 16px;
|
|
white-space: nowrap;
|
|
user-select: none;
|
|
|
|
.header {
|
|
grid-column: 1 / -1;
|
|
width: 100%;
|
|
|
|
display: grid;
|
|
grid-template-columns: 1fr min-content;
|
|
|
|
.el-name {
|
|
font-weight: bold;
|
|
margin-bottom: 32px;
|
|
cursor: pointer;
|
|
color: var(--color1);
|
|
}
|
|
|
|
.el-delete {
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|
|
|
|
<div class="header">
|
|
<div data-el="name"></div>
|
|
<div data-el="delete">✘</div>
|
|
</div>
|
|
|
|
<div><label for="download-images">Download images on device</label></div>
|
|
<input data-field="download-images" type="checkbox" id="download-images">
|
|
|
|
<div><label for="download-files">Download files on device</label></div>
|
|
<input data-field="download-files" type="checkbox" id="download-files">
|
|
`
|
|
}// }}}
|
|
constructor(name, data) {// {{{
|
|
super(true)
|
|
this.name = name
|
|
this.data = data
|
|
this.render()
|
|
|
|
// Enable the save button when settings are modified.
|
|
this.allFields().forEach(f =>
|
|
f.addEventListener('input', () => _mbus.dispatch('PREFERENCE_SET_MODIFIED'))
|
|
)
|
|
|
|
this.elName.addEventListener('click', () => this.updateName())
|
|
this.elDelete.addEventListener('click', () => this.deleteSet())
|
|
}// }}}
|
|
updateName() {// {{{
|
|
if (this.name == 'default') {
|
|
alert('Can not change name of the default profile.')
|
|
return
|
|
}
|
|
|
|
const name = prompt("Change name", this.name)
|
|
if (!name)
|
|
return
|
|
|
|
this.name = name
|
|
this.render()
|
|
_mbus.dispatch('PREFERENCE_SET_MODIFIED')
|
|
}// }}}
|
|
deleteSet() {// {{{
|
|
_mbus.dispatch('PREFERENCE_SET_DELETE', { set: this })
|
|
}// }}}
|
|
render() {// {{{
|
|
this.elName.innerText = this.name
|
|
|
|
this.fieldDownloadImages.checked = this.data.DownloadImages
|
|
this.fieldDownloadFiles.checked = this.data.DownloadFiles
|
|
}// }}}
|
|
getState() {// {{{
|
|
const name = this.name.trim()
|
|
if (name === '')
|
|
throw new Error('Name can not be empty.')
|
|
|
|
return {
|
|
name: this.name.trim(),
|
|
state: this.fieldValues(),
|
|
}
|
|
}// }}}
|
|
}
|
|
customElements.define('n2-preferenceset', N2PreferenceSet)
|