options dialog refactoring into more standard widget structure

This commit is contained in:
zadam 2022-11-20 18:29:15 +01:00
parent 02d908df1e
commit a3783b0113
16 changed files with 226 additions and 195 deletions

View File

@ -81,6 +81,18 @@ import MermaidExportButton from "../widgets/floating_buttons/mermaid_export_butt
import EditableCodeButtonsWidget from "../widgets/type_widgets/editable_code_buttons.js";
import ApiLogWidget from "../widgets/api_log.js";
import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js";
import AppearanceOptions from "../widgets/dialogs/options/appearance.js";
import KeyboardShortcutsOptions from "../widgets/dialogs/options/shortcuts.js";
import TextNotesOptions from "../widgets/dialogs/options/text_notes.js";
import CodeNotesOptions from "../widgets/dialogs/options/code_notes.js";
import ImageOptions from "../widgets/dialogs/options/images.js";
import SpellcheckOptions from "../widgets/dialogs/options/spellcheck.js";
import PasswordOptions from "../widgets/dialogs/options/password.js";
import EtapiOptions from "../widgets/dialogs/options/etapi.js";
import BackupOptions from "../widgets/dialogs/options/backup.js";
import SyncOptions from "../widgets/dialogs/options/sync.js";
import OtherOptions from "../widgets/dialogs/options/other.js";
import AdvancedOptions from "../widgets/dialogs/options/advanced.js";
export default class DesktopLayout {
constructor(customWidgets) {
@ -241,6 +253,19 @@ export default class DesktopLayout {
.child(new InfoDialog())
.child(new ConfirmDialog())
.child(new PromptDialog())
.child(new OptionsDialog());
.child(new OptionsDialog()
.child(new AppearanceOptions())
.child(new KeyboardShortcutsOptions())
.child(new TextNotesOptions())
.child(new CodeNotesOptions())
.child(new ImageOptions())
.child(new SpellcheckOptions())
.child(new PasswordOptions())
.child(new EtapiOptions())
.child(new BackupOptions())
.child(new SyncOptions())
.child(new OtherOptions())
.child(new AdvancedOptions())
);
}
}

View File

@ -27,59 +27,9 @@ const TPL = `
</div>
<div class="modal-body">
<div style="display: flex">
<ul class="nav nav-tabs flex-column">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#options-appearance">Appearance</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-shortcuts">Shortcuts</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-text-notes">Text notes</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-code-notes">Code notes</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-images">Images</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-spellcheck">Spellcheck</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-password">Password</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-etapi">ETAPI</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-backup">Backup</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-sync-setup">Sync</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-other">Other</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#options-advanced">Advanced</a>
</li>
</ul>
<ul class="nav nav-tabs flex-column"></ul>
<br/>
<div class="tab-content">
<div id="options-appearance" class="tab-pane active"></div>
<div id="options-shortcuts" class="tab-pane"></div>
<div id="options-text-notes" class="tab-pane"></div>
<div id="options-code-notes" class="tab-pane"></div>
<div id="options-images" class="tab-pane"></div>
<div id="options-spellcheck" class="tab-pane"></div>
<div id="options-password" class="tab-pane"></div>
<div id="options-etapi" class="tab-pane"></div>
<div id="options-backup" class="tab-pane"></div>
<div id="options-sync-setup" class="tab-pane"></div>
<div id="options-other" class="tab-pane"></div>
<div id="options-advanced" class="tab-pane"></div>
</div>
<div class="tab-content"></div>
</div>
</div>
</div>
@ -90,36 +40,51 @@ const TPL = `
export default class OptionsDialog extends BasicWidget {
doRender() {
this.$widget = $(TPL);
this.$navTabs = this.$widget.find(".nav-tabs");
this.$tabContent = this.$widget.find(".tab-content");
for (const child of this.children) {
this.$navTabs.append(
$('<li class="nav-item">')
.append(
$('<a class="nav-link" data-toggle="tab">')
.attr("href", '#options-' + child.constructor.name)
.text(child.tabTitle)
)
);
this.$tabContent.append(
$('<div class="tab-pane">')
.attr("id", "options-" + child.constructor.name)
);
}
}
async showOptionsEvent({openTab}) {
const options = await server.get('options');
const optionPromise = server.get('options');
utils.openDialog(this.$widget);
for (const child of this.children) {
child.lazyRender();
(await Promise.all([
import('./options/appearance.js'),
import('./options/shortcuts.js'),
import('./options/text_notes.js'),
import('./options/code_notes.js'),
import('./options/images.js'),
import('./options/spellcheck.js'),
import('./options/password.js'),
import('./options/etapi.js'),
import('./options/backup.js'),
import('./options/sync.js'),
import('./options/other.js'),
import('./options/advanced.js')
]))
.map(m => new m.default)
.forEach(tab => {
if (tab.optionsLoaded) {
tab.optionsLoaded(options)
this.$widget.find("#options-" + child.constructor.name)
.empty()
.append(child.$widget);
}
});
if (openTab) {
$(`.nav-link[href='#options-${openTab}']`).trigger("click");
const options = await optionPromise;
for (const child of this.children) {
if (child.optionsLoaded) {
child.optionsLoaded(options)
}
}
await utils.openDialog(this.$widget);
if (!openTab) {
openTab = "AppearanceOptions";
}
this.$widget.find(`.nav-link[href='#options-${openTab}']`).trigger("click");
}
}

View File

@ -1,5 +1,6 @@
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<h4 style="margin-top: 0;">Sync</h4>
@ -46,17 +47,19 @@ const TPL = `
<button id="vacuum-database-button" class="btn">Vacuum database</button>`;
export default class AdvancedOptions {
constructor() {
$("#options-advanced").html(TPL);
export default class AdvancedOptions extends OptionsTab {
get tabTitle() { return "Advanced" }
this.$forceFullSyncButton = $("#force-full-sync-button");
this.$fillEntityChangesButton = $("#fill-entity-changes-button");
this.$anonymizeFullButton = $("#anonymize-full-button");
this.$anonymizeLightButton = $("#anonymize-light-button");
this.$vacuumDatabaseButton = $("#vacuum-database-button");
this.$findAndFixConsistencyIssuesButton = $("#find-and-fix-consistency-issues-button");
this.$checkIntegrityButton = $("#check-integrity-button");
lazyRender() {
this.$widget = $(TPL);
this.$forceFullSyncButton = this.$widget.find("#force-full-sync-button");
this.$fillEntityChangesButton = this.$widget.find("#fill-entity-changes-button");
this.$anonymizeFullButton = this.$widget.find("#anonymize-full-button");
this.$anonymizeLightButton = this.$widget.find("#anonymize-light-button");
this.$vacuumDatabaseButton = this.$widget.find("#vacuum-database-button");
this.$findAndFixConsistencyIssuesButton = this.$widget.find("#find-and-fix-consistency-issues-button");
this.$checkIntegrityButton = this.$widget.find("#check-integrity-button");
this.$forceFullSyncButton.on('click', async () => {
await server.post('sync/force-full-sync');

View File

@ -1,6 +1,7 @@
import server from "../../../services/server.js";
import utils from "../../../services/utils.js";
import appContext from "../../../services/app_context.js";
import OptionsTab from "./options_tab.js";
const FONT_FAMILIES = [
{ value: "theme", label: "Theme defined" },
@ -174,33 +175,35 @@ const TPL = `
</p>
</form>`;
export default class ApperanceOptions {
constructor() {
$("#options-appearance").html(TPL);
export default class AppearanceOptions extends OptionsTab {
get tabTitle() { return "Appearance" }
this.$zoomFactorSelect = $("#zoom-factor-select");
this.$nativeTitleBarSelect = $("#native-title-bar-select");
lazyRender() {
this.$widget = $(TPL);
this.$themeSelect = $("#theme-select");
this.$overrideThemeFonts = $("#override-theme-fonts");
this.$zoomFactorSelect = this.$widget.find("#zoom-factor-select");
this.$nativeTitleBarSelect = this.$widget.find("#native-title-bar-select");
this.$overridenFontSettings = $("#overriden-font-settings");
this.$themeSelect = this.$widget.find("#theme-select");
this.$overrideThemeFonts = this.$widget.find("#override-theme-fonts");
this.$mainFontSize = $("#main-font-size");
this.$mainFontFamily = $("#main-font-family");
this.$overridenFontSettings = this.$widget.find("#overriden-font-settings");
this.$treeFontSize = $("#tree-font-size");
this.$treeFontFamily = $("#tree-font-family");
this.$mainFontSize = this.$widget.find("#main-font-size");
this.$mainFontFamily = this.$widget.find("#main-font-family");
this.$detailFontSize = $("#detail-font-size");
this.$detailFontFamily = $("#detail-font-family");
this.$treeFontSize = this.$widget.find("#tree-font-size");
this.$treeFontFamily = this.$widget.find("#tree-font-family");
this.$monospaceFontSize = $("#monospace-font-size");
this.$monospaceFontFamily = $("#monospace-font-family");
this.$detailFontSize = this.$widget.find("#detail-font-size");
this.$detailFontFamily = this.$widget.find("#detail-font-family");
$(".reload-frontend-button").on("click", () => utils.reloadFrontendApp("changes from appearance options"));
this.$monospaceFontSize = this.$widget.find("#monospace-font-size");
this.$monospaceFontFamily = this.$widget.find("#monospace-font-family");
this.$body = $("body");
this.$widget.find(".reload-frontend-button").on("click", () => utils.reloadFrontendApp("changes from appearance options"));
this.$body = this.$widget.find("body");
this.$themeSelect.on('change', async () => {
const newTheme = this.$themeSelect.val();
@ -237,7 +240,7 @@ export default class ApperanceOptions {
this['$' + optionName].on('change', () => server.put(`options/${optionName}/${this['$' + optionName].val()}`));
}
this.$maxContentWidth = $("#max-content-width");
this.$maxContentWidth = this.$widget.find("#max-content-width");
this.$maxContentWidth.on('change', async () => {
const maxContentWidth = this.$maxContentWidth.val();

View File

@ -1,5 +1,6 @@
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<h4>Automatic backup</h4>
@ -32,11 +33,13 @@ const TPL = `
<button id="backup-database-button" class="btn">Backup database now</button><br/><br/>
`;
export default class BackupOptions {
constructor() {
$("#options-backup").html(TPL);
export default class BackupOptions extends OptionsTab {
get tabTitle() { return "Backup" }
this.$backupDatabaseButton = $("#backup-database-button");
lazyRender() {
this.$widget = $(TPL);
this.$backupDatabaseButton = this.$widget.find("#backup-database-button");
this.$backupDatabaseButton.on('click', async () => {
const {backupFile} = await server.post('database/backup-database');
@ -44,9 +47,9 @@ export default class BackupOptions {
toastService.showMessage("Database has been backed up to " + backupFile, 10000);
});
this.$dailyBackupEnabled = $("#daily-backup-enabled");
this.$weeklyBackupEnabled = $("#weekly-backup-enabled");
this.$monthlyBackupEnabled = $("#monthly-backup-enabled");
this.$dailyBackupEnabled = this.$widget.find("#daily-backup-enabled");
this.$weeklyBackupEnabled = this.$widget.find("#weekly-backup-enabled");
this.$monthlyBackupEnabled = this.$widget.find("#monthly-backup-enabled");
this.$dailyBackupEnabled.on('change', () => {
const opts = { 'dailyBackupEnabled': this.$dailyBackupEnabled.is(":checked") ? "true" : "false" };

View File

@ -2,6 +2,7 @@ import mimeTypesService from "../../../services/mime_types.js";
import options from "../../../services/options.js";
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<div>
@ -39,26 +40,28 @@ const TPL = `
<ul id="options-mime-types" style="max-height: 500px; overflow: auto; list-style-type: none;"></ul>
</div>`;
export default class CodeNotesOptions {
constructor() {
$("#options-code-notes").html(TPL);
export default class CodeNotesOptions extends OptionsTab {
get tabTitle() { return "Code notes" }
this.$vimKeymapEnabled = $("#vim-keymap-enabled");
lazyRender() {
this.$widget = $(TPL);
this.$vimKeymapEnabled = this.$widget.find("#vim-keymap-enabled");
this.$vimKeymapEnabled.on('change', () => {
const opts = { 'vimKeymapEnabled': this.$vimKeymapEnabled.is(":checked") ? "true" : "false" };
server.put('options', opts).then(() => toastService.showMessage("Options change have been saved."));
return false;
});
this.$codeLineWrapEnabled = $("#line-wrap-enabled");
this.$codeLineWrapEnabled = this.$widget.find("#line-wrap-enabled");
this.$codeLineWrapEnabled.on('change', () => {
const opts = { 'codeLineWrapEnabled': this.$codeLineWrapEnabled.is(":checked") ? "true" : "false" };
server.put('options', opts).then(() => toastService.showMessage("Options change have been saved."));
return false;
});
this.$mimeTypes = $("#options-mime-types");
this.$mimeTypes = this.$widget.find("#options-mime-types");
this.$autoReadonlySizeCode = $("#auto-readonly-size-code");
this.$autoReadonlySizeCode = this.$widget.find("#auto-readonly-size-code");
this.$autoReadonlySizeCode.on('change', () => {
const opts = { 'autoReadonlySizeCode': this.$autoReadonlySizeCode.val() };
server.put('options', opts).then(() => toastService.showMessage("Options change have been saved."));
@ -96,7 +99,7 @@ export default class CodeNotesOptions {
const enabledMimeTypes = [];
this.$mimeTypes.find("input:checked").each(
(i, el) => enabledMimeTypes.push($(el).attr("data-mime-type")));
(i, el) => enabledMimeTypes.push(this.$widget.find(el).attr("data-mime-type")));
await options.save('codeNotesMimeTypes', JSON.stringify(enabledMimeTypes));

View File

@ -1,6 +1,7 @@
import server from "../../../services/server.js";
import dialogService from "../../dialog.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<h4>ETAPI</h4>
@ -45,11 +46,13 @@ const TPL = `
}
</style>`;
export default class EtapiOptions {
constructor() {
$("#options-etapi").html(TPL);
export default class EtapiOptions extends OptionsTab {
get tabTitle() { return "ETAPI" }
$("#create-etapi-token").on("click", async () => {
lazyRender() {
this.$widget = $(TPL);
this.$widget.find("#create-etapi-token").on("click", async () => {
const tokenName = await dialogService.prompt({
title: "New ETAPI token",
message: "Please enter new token's name",
@ -76,8 +79,8 @@ export default class EtapiOptions {
}
async refreshTokens() {
const $noTokensYet = $("#no-tokens-yet");
const $tokensTable = $("#tokens-table");
const $noTokensYet = this.$widget.find("#no-tokens-yet");
const $tokensTable = this.$widget.find("#tokens-table");
const tokens = await server.get('etapi-tokens');

View File

@ -1,5 +1,6 @@
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<div>
@ -30,12 +31,14 @@ const TPL = `
</div>
`;
export default class ImageOptions {
constructor() {
$("#options-images").html(TPL);
export default class ImageOptions extends OptionsTab {
get tabTitle() { return "Images" }
this.$imageMaxWidthHeight = $("#image-max-width-height");
this.$imageJpegQuality = $("#image-jpeg-quality");
lazyRender() {
this.$widget = $(TPL);
this.$imageMaxWidthHeight = this.$widget.find("#image-max-width-height");
this.$imageJpegQuality = this.$widget.find("#image-jpeg-quality");
this.$imageMaxWidthHeight.on('change', () => {
const opts = { 'imageMaxWidthHeight': this.$imageMaxWidthHeight.val() };
@ -51,7 +54,7 @@ export default class ImageOptions {
return false;
});
this.$downloadImagesAutomatically = $("#download-images-automatically");
this.$downloadImagesAutomatically = this.$widget.find("#download-images-automatically");
this.$downloadImagesAutomatically.on("change", () => {
const isChecked = this.$downloadImagesAutomatically.prop("checked");
@ -60,8 +63,8 @@ export default class ImageOptions {
server.put('options', opts).then(() => toastService.showMessage("Options change have been saved."));
});
this.$enableImageCompression = $("#image-compresion-enabled");
this.$imageCompressionWrapper = $("#image-compression-enabled-wraper");
this.$enableImageCompression = this.$widget.find("#image-compresion-enabled");
this.$imageCompressionWrapper = this.$widget.find("#image-compression-enabled-wraper");
this.setImageCompression = (isChecked) => {
if (isChecked) {

View File

@ -0,0 +1,5 @@
import BasicWidget from "../../basic_widget.js";
export default class OptionsTab extends BasicWidget {
}

View File

@ -1,5 +1,6 @@
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<div>
@ -52,11 +53,13 @@ const TPL = `
</div>
</div>`;
export default class OtherOptions {
constructor() {
$("#options-other").html(TPL);
export default class OtherOptions extends OptionsTab {
get tabTitle() { return "Other" }
this.$trayEnabled = $("#tray-enabled");
lazyRender() {
this.$widget = $(TPL);
this.$trayEnabled = this.$widget.find("#tray-enabled");
this.$trayEnabled.on('change', () => {
const opts = { 'disableTray': !this.$trayEnabled.is(":checked") ? "true" : "false" };
server.put('options', opts).then(() => toastService.showMessage("Options change have been saved."));
@ -64,7 +67,7 @@ export default class OtherOptions {
return false;
});
this.$eraseEntitiesAfterTimeInSeconds = $("#erase-entities-after-time-in-seconds");
this.$eraseEntitiesAfterTimeInSeconds = this.$widget.find("#erase-entities-after-time-in-seconds");
this.$eraseEntitiesAfterTimeInSeconds.on('change', () => {
const eraseEntitiesAfterTimeInSeconds = this.$eraseEntitiesAfterTimeInSeconds.val();
@ -76,14 +79,14 @@ export default class OtherOptions {
return false;
});
this.$eraseDeletedNotesButton = $("#erase-deleted-notes-now-button");
this.$eraseDeletedNotesButton = this.$widget.find("#erase-deleted-notes-now-button");
this.$eraseDeletedNotesButton.on('click', () => {
server.post('notes/erase-deleted-notes-now').then(() => {
toastService.showMessage("Deleted notes have been erased.");
});
});
this.$noteRevisionsTimeInterval = $("#note-revision-snapshot-time-interval-in-seconds");
this.$noteRevisionsTimeInterval = this.$widget.find("#note-revision-snapshot-time-interval-in-seconds");
this.$noteRevisionsTimeInterval.on('change', () => {
const opts = { 'noteRevisionSnapshotTimeInterval': this.$noteRevisionsTimeInterval.val() };
@ -92,7 +95,7 @@ export default class OtherOptions {
return false;
});
this.$checkForUpdates = $("#check-for-updates");
this.$checkForUpdates = this.$widget.find("#check-for-updates");
this.$checkForUpdates.on("change", () => {
const isChecked = this.$checkForUpdates.prop("checked");
const opts = { 'checkForUpdates': isChecked ? 'true' : 'false' };

View File

@ -1,6 +1,7 @@
import server from "../../../services/server.js";
import protectedSessionHolder from "../../../services/protected_session_holder.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<div>
@ -46,17 +47,19 @@ const TPL = `
</div>
</div>`;
export default class PasswordOptions {
constructor() {
$("#options-password").html(TPL);
export default class PasswordOptions extends OptionsTab {
get tabTitle() { return "Password" }
this.$passwordHeading = $("#password-heading");
this.$changePasswordForm = $("#change-password-form");
this.$oldPassword = $("#old-password");
this.$newPassword1 = $("#new-password1");
this.$newPassword2 = $("#new-password2");
this.$savePasswordButton = $("#save-password-button");
this.$resetPasswordButton = $("#reset-password-button");
lazyRender() {
this.$widget = $(TPL);
this.$passwordHeading = this.$widget.find("#password-heading");
this.$changePasswordForm = this.$widget.find("#change-password-form");
this.$oldPassword = this.$widget.find("#old-password");
this.$newPassword1 = this.$widget.find("#new-password1");
this.$newPassword2 = this.$widget.find("#new-password2");
this.$savePasswordButton = this.$widget.find("#save-password-button");
this.$resetPasswordButton = this.$widget.find("#reset-password-button");
this.$resetPasswordButton.on("click", async () => {
if (confirm("By resetting the password you will forever lose access to all your existing protected notes. Do you really want to reset the password?")) {
@ -71,7 +74,7 @@ export default class PasswordOptions {
this.$changePasswordForm.on('submit', () => this.save());
this.$protectedSessionTimeout = $("#protected-session-timeout-in-seconds");
this.$protectedSessionTimeout = this.$widget.find("#protected-session-timeout-in-seconds");
this.$protectedSessionTimeout.on('change', () => {
const protectedSessionTimeout = this.$protectedSessionTimeout.val();
@ -87,7 +90,7 @@ export default class PasswordOptions {
optionsLoaded(options) {
const isPasswordSet = options.isPasswordSet === 'true';
$("#old-password-form-group").toggle(isPasswordSet);
this.$widget.find("#old-password-form-group").toggle(isPasswordSet);
this.$passwordHeading.text(isPasswordSet ? 'Change password' : 'Set password');
this.$savePasswordButton.text(isPasswordSet ? 'Change password' : 'Set password');
this.$protectedSessionTimeout.val(options['protectedSessionTimeout']);

View File

@ -1,6 +1,7 @@
import server from "../../../services/server.js";
import utils from "../../../services/utils.js";
import dialogService from "../../dialog.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<h4>Keyboard shortcuts</h4>
@ -34,13 +35,15 @@ const TPL = `
let globActions;
export default class KeyboardShortcutsOptions {
constructor() {
$("#options-shortcuts").html(TPL);
export default class KeyboardShortcutsOptions extends OptionsTab {
get tabTitle() { return "Shortcuts" }
$("#options-keyboard-shortcuts-reload-app").on("click", () => utils.reloadFrontendApp());
lazyRender() {
this.$widget = $(TPL);
const $table = $("#keyboard-shortcut-table tbody");
this.$widget.find("#options-keyboard-shortcuts-reload-app").on("click", () => utils.reloadFrontendApp());
const $table = this.$widget.find("#keyboard-shortcut-table tbody");
server.get('keyboard-actions').then(actions => {
globActions = actions;
@ -73,7 +76,7 @@ export default class KeyboardShortcutsOptions {
});
$table.on('change', 'input.form-control', e => {
const $input = $(e.target);
const $input = this.$widget.find(e.target);
const actionName = $input.attr('data-keyboard-action-name');
const shortcuts = $input.val()
.replace('+,', "+Comma")
@ -87,48 +90,48 @@ export default class KeyboardShortcutsOptions {
server.put('options', opts);
});
$("#options-keyboard-shortcuts-set-all-to-default").on('click', async () => {
this.$widget.find("#options-keyboard-shortcuts-set-all-to-default").on('click', async () => {
if (!await dialogService.confirm("Do you really want to reset all keyboard shortcuts to the default?")) {
return;
}
$table.find('input.form-control').each(function() {
const defaultShortcuts = $(this).attr('data-default-keyboard-shortcuts');
const defaultShortcuts = this.$widget.find(this).attr('data-default-keyboard-shortcuts');
if ($(this).val() !== defaultShortcuts) {
$(this)
if (this.$widget.find(this).val() !== defaultShortcuts) {
this.$widget.find(this)
.val(defaultShortcuts)
.trigger('change');
}
});
});
const $filter = $("#keyboard-shortcut-filter");
const $filter = this.$widget.find("#keyboard-shortcut-filter");
$filter.on('keyup', () => {
const filter = $filter.val().trim().toLowerCase();
$table.find("tr").each((i, el) => {
if (!filter) {
$(el).show();
this.$widget.find(el).show();
return;
}
const actionName = $(el).find('input').attr('data-keyboard-action-name');
const actionName = this.$widget.find(el).find('input').attr('data-keyboard-action-name');
if (!actionName) {
$(el).hide();
this.$widget.find(el).hide();
return;
}
const action = globActions.find(act => act.actionName === actionName);
if (!action) {
$(el).hide();
this.$widget.find(el).hide();
return;
}
$(el).toggle(!!( // !! to avoid toggle overloads with different behavior
this.$widget.find(el).toggle(!!( // !! to avoid toggle overloads with different behavior
action.actionName.toLowerCase().includes(filter)
|| action.defaultShortcuts.some(shortcut => shortcut.toLowerCase().includes(filter))
|| action.effectiveShortcuts.some(shortcut => shortcut.toLowerCase().includes(filter))

View File

@ -1,6 +1,7 @@
import utils from "../../../services/utils.js";
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<style>
@ -32,12 +33,14 @@ const TPL = `
<p><strong>Available language codes: </strong> <span id="available-language-codes"></span></p>
</div>`;
export default class SpellcheckOptions {
constructor() {
$("#options-spellcheck").html(TPL);
export default class SpellcheckOptions extends OptionsTab {
get tabTitle() { return "Spellcheck" }
this.$spellCheckEnabled = $("#spell-check-enabled");
this.$spellCheckLanguageCode = $("#spell-check-language-code");
lazyRender() {
this.$widget = $(TPL);
this.$spellCheckEnabled = this.$widget.find("#spell-check-enabled");
this.$spellCheckLanguageCode = this.$widget.find("#spell-check-language-code");
this.$spellCheckEnabled.on('change', () => {
const opts = { 'spellCheckEnabled': this.$spellCheckEnabled.is(":checked") ? "true" : "false" };
@ -53,7 +56,7 @@ export default class SpellcheckOptions {
return false;
});
this.$availableLanguageCodes = $("#available-language-codes");
this.$availableLanguageCodes = this.$widget.find("#available-language-codes");
if (utils.isElectron()) {
const { webContents } = utils.dynamicRequire('@electron/remote').getCurrentWindow();

View File

@ -1,5 +1,6 @@
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<h4 style="margin-top: 0px;">Sync configuration</h4>
@ -37,15 +38,17 @@ const TPL = `
<button id="test-sync-button" class="btn">Test sync</button>`;
export default class SyncOptions {
constructor() {
$("#options-sync-setup").html(TPL);
export default class SyncOptions extends OptionsTab {
get tabTitle() { return "Sync" }
this.$form = $("#sync-setup-form");
this.$syncServerHost = $("#sync-server-host");
this.$syncServerTimeout = $("#sync-server-timeout");
this.$syncProxy = $("#sync-proxy");
this.$testSyncButton = $("#test-sync-button");
lazyRender() {
this.$widget = $(TPL);
this.$form = this.$widget.find("#sync-setup-form");
this.$syncServerHost = this.$widget.find("#sync-server-host");
this.$syncServerTimeout = this.$widget.find("#sync-server-timeout");
this.$syncProxy = this.$widget.find("#sync-proxy");
this.$testSyncButton = this.$widget.find("#test-sync-button");
this.$form.on('submit', () => this.save());

View File

@ -1,5 +1,6 @@
import server from "../../../services/server.js";
import toastService from "../../../services/toast.js";
import OptionsTab from "./options_tab.js";
const TPL = `
<p><strong>Settings on this options tab are saved automatically after each change.</strong></p>
@ -36,13 +37,15 @@ const TPL = `
</div>
</form>`;
export default class TextNotesOptions {
constructor() {
$("#options-text-notes").html(TPL);
export default class TextNotesOptions extends OptionsTab {
get tabTitle() { return "Text notes" }
this.$body = $("body");
lazyRender() {
this.$widget = $(TPL);
this.$headingStyle = $("#heading-style");
this.$body = this.$widget.find("body");
this.$headingStyle = this.$widget.find("#heading-style");
this.$headingStyle.on('change', () => {
const newHeadingStyle = this.$headingStyle.val();
@ -51,14 +54,14 @@ export default class TextNotesOptions {
server.put('options/headingStyle/' + newHeadingStyle);
});
this.$minTocHeadings = $("#min-toc-headings");
this.$minTocHeadings = this.$widget.find("#min-toc-headings");
this.$minTocHeadings.on('change', () => {
const minTocHeadings = this.$minTocHeadings.val();
server.put('options/minTocHeadings/' + minTocHeadings);
});
this.$autoReadonlySizeText = $("#auto-readonly-size-text");
this.$autoReadonlySizeText = this.$widget.find("#auto-readonly-size-text");
this.$autoReadonlySizeText.on('change', () => {
const opts = { 'autoReadonlySizeText': this.$autoReadonlySizeText.val() };
@ -78,7 +81,7 @@ export default class TextNotesOptions {
this.$body.addClass(prefix + value);
}
async optionsLoaded(options) {
optionsLoaded(options) {
this.$headingStyle.val(options.headingStyle);
this.$minTocHeadings.val(options.minTocHeadings);
this.$autoReadonlySizeText.val(options.autoReadonlySizeText);

View File

@ -28,7 +28,7 @@ export default class PasswordNoteSetDialog extends BasicWidget {
this.$widget = $(TPL);
this.$openPasswordOptionsButton = this.$widget.find(".open-password-options-button");
this.$openPasswordOptionsButton.on("click", () => {
this.triggerCommand("showOptions", { openTab: 'password' });
this.triggerCommand("showOptions", { openTab: 'PasswordOptions' });
});
}