refactoring of access to options in frontend

This commit is contained in:
zadam 2019-08-22 23:31:02 +02:00
parent b84542064c
commit f9abea83f3
13 changed files with 93 additions and 62 deletions

View File

@ -1,2 +1,2 @@
INSERT INTO options (name, value, utcDateCreated, utcDateModified, isSynced)
VALUES ('showSidebarInNewTab', '1', '2018-07-29T18:31:00.874Z', '2018-07-29T18:31:00.874Z', 0);
VALUES ('showSidebarInNewTab', 'true', '2018-07-29T18:31:00.874Z', '2018-07-29T18:31:00.874Z', 0);

View File

@ -45,7 +45,7 @@ export default class ApperanceOptions {
const hideTabRowForOneTab = this.$oneTabDisplaySelect.val() === 'hide' ? 'true' : 'false';
server.put('options/hideTabRowForOneTab/' + hideTabRowForOneTab)
.then(optionsInit.loadOptions);
.then(optionsInit.reloadOptions);
});
this.$leftPaneMinWidth.change(async () => {

View File

@ -18,7 +18,7 @@ export default class ProtectedSessionOptions {
const protectedSessionTimeout = this.$protectedSessionTimeout.val();
server.put('options', { 'protectedSessionTimeout': protectedSessionTimeout }).then(() => {
optionsInit.loadOptions();
optionsInit.reloadOptions();
infoService.showMessage("Options change have been saved.");
});

View File

@ -24,11 +24,11 @@ export default class SidebarOptions {
});
this.$showSidebarInNewTab.change(async () => {
const flag = this.$showSidebarInNewTab.is(":checked") ? 1 : 0;
const flag = this.$showSidebarInNewTab.is(":checked") ? 'true' : 'false';
await server.put('options/showSidebarInNewTab/' + flag);
optionsInit.loadOptions();
optionsInit.reloadOptions();
});
}
@ -116,6 +116,8 @@ export default class SidebarOptions {
});
await server.put('options', opts);
optionsInit.reloadOptions();
}
parseJsonSafely(str) {

View File

@ -5,12 +5,12 @@ import noteDetailService from "./note_detail.js";
let hoistedNoteId;
optionsInit.optionsReady.then(options => {
hoistedNoteId = options['hoistedNoteId'];
optionsInit.waitForOptions().then(options => {
hoistedNoteId = options.get('hoistedNoteId');
});
async function getHoistedNoteId() {
await optionsInit.optionsReady;
await optionsInit.waitForOptions();
return hoistedNoteId;
}

View File

@ -4,9 +4,42 @@ let optionsReady;
const loadListeners = [];
function loadOptions() {
class Options {
constructor(arr) {
this.arr = arr;
}
get(key) {
return this.arr[key];
}
getJson(key) {
try {
return JSON.parse(this.arr[key]);
}
catch (e) {
return null;
}
}
getInt(key) {
return parseInt(this.arr[key]);
}
getFloat(key) {
return parseFloat(this.arr[key]);
}
is(key) {
return this.arr[key] === 'true';
}
}
function reloadOptions() {
optionsReady = new Promise((resolve, reject) => {
server.get('options').then(options => {
server.get('options').then(optionArr => {
const options = new Options(optionArr);
resolve(options);
for (const listener of loadListeners) {
@ -14,9 +47,16 @@ function loadOptions() {
}
});
});
return optionsReady;
}
loadOptions(); // initial load
/** just waits for some options without triggering reload */
async function waitForOptions() {
return await optionsReady;
}
reloadOptions(); // initial load
function addLoadListener(listener) {
loadListeners.push(listener);
@ -26,28 +66,8 @@ function addLoadListener(listener) {
optionsReady.then(listener);
}
async function getOption(name) {
const options = await optionsReady;
return options[name];
}
async function getJsonOption(name) {
const option = await getOption(name);
try {
return JSON.parse(option);
}
catch (e) {
return null;
}
}
export default {
// use addLoadListener() which will be called also on refreshes
optionsReady,
addLoadListener,
loadOptions,
getOption,
getJsonOption
reloadOptions,
waitForOptions
}

View File

@ -6,7 +6,7 @@ const PROTECTED_SESSION_ID_KEY = 'protectedSessionId';
let lastProtectedSessionOperationDate = null;
let protectedSessionTimeout = null;
optionsInitService.addLoadListener(options => setProtectedSessionTimeout(options.protectedSessionTimeout));
optionsInitService.addLoadListener(options => setProtectedSessionTimeout(options.getInt('protectedSessionTimeout')));
setInterval(() => {
if (lastProtectedSessionOperationDate !== null && Date.now() - lastProtectedSessionOperationDate.getTime() > protectedSessionTimeout * 1000) {

View File

@ -74,10 +74,13 @@ class Sidebar {
try {
const widget = new widgetClass(this.ctx, state);
await widget.renderBody();
if (await widget.isEnabled()) {
const $el = await widget.render();
this.widgets.push(widget);
this.$widgetContainer.append(widget.getWidgetElement());
this.$widgetContainer.append($el);
}
}
catch (e) {
messagingService.logError(`Error while loading widget ${widgetClass.name}: ${e.message}`);

View File

@ -38,7 +38,7 @@ const componentClasses = {
let showSidebarInNewTab = true;
optionsInitService.addLoadListener(options => {
showSidebarInNewTab = options.showSidebarInNewTab === '1';
showSidebarInNewTab = options.is('showSidebarInNewTab');
});
class TabContext {

View File

@ -410,6 +410,6 @@ class TabRow {
const noteTabRowEl = document.querySelector('.note-tab-row');
const tabRow = new TabRow(noteTabRowEl);
optionsInit.addLoadListener(options => tabRow.setHideTabRowForOneTab(options.hideTabRowForOneTab === 'true'));
optionsInit.addLoadListener(options => tabRow.setHideTabRowForOneTab(options.is('hideTabRowForOneTab')));
export default tabRow;

View File

@ -331,16 +331,9 @@ async function treeInitialized() {
return;
}
let openTabs = [];
const options = await optionsInit.waitForOptions();
try {
const options = await optionsInit.optionsReady;
openTabs = JSON.parse(options.openTabs);
}
catch (e) {
messagingService.logError("Cannot retrieve open tabs: " + e.stack);
}
const openTabs = options.getJson('openTabs') || [];
// if there's notePath in the URL, make sure it's open and active
// (useful, among others, for opening clipped notes from clipper)

View File

@ -40,7 +40,7 @@ function getCurrentZoom() {
}
if (utils.isElectron()) {
optionsInitService.addLoadListener(options => setZoomFactor(options.zoomFactor))
optionsInitService.addLoadListener(options => setZoomFactor(options.getFloat('zoomFactor')))
}
export default {

View File

@ -1,3 +1,5 @@
import optionsInit from "../services/options_init.js";
const WIDGET_TPL = `
<div class="card widget">
<div class="card-header">
@ -21,9 +23,20 @@ class StandardWidget {
*/
constructor(ctx, state) {
this.ctx = ctx;
this.widgetName = this.constructor.name;
this.state = state;
// construct in camelCase
this.widgetName = this.constructor.name.substr(0, 1).toLowerCase() + this.constructor.name.substr(1);
const widgetId = `tab-${ctx.tabId}-widget-${this.widgetName}`;
}
getWidgetTitle() { return "Untitled widget"; }
getHeaderActions() { return []; }
getMaxHeight() { return null; }
async render() {
const widgetId = `tab-${this.ctx.tabId}-widget-${this.widgetName}`;
this.$widget = $(WIDGET_TPL);
this.$widget.find('[data-target]').attr('data-target', "#" + widgetId);
@ -31,7 +44,7 @@ class StandardWidget {
this.$bodyWrapper = this.$widget.find('.body-wrapper');
this.$bodyWrapper.attr('id', widgetId);
if (state && state.expanded) {
if (this.state && this.state.expanded) {
this.$bodyWrapper.collapse("show");
}
@ -51,14 +64,12 @@ class StandardWidget {
this.$title.text(this.getWidgetTitle());
this.$headerActions = this.$widget.find('.widget-header-actions');
this.$headerActions.append(...this.getHeaderActions());
await this.renderBody();
return this.$widget;
}
getWidgetTitle() { return "Untitled widget"; }
getHeaderActions() { return []; }
getMaxHeight() { return null; }
async renderBody() {
if (!this.isExpanded() || this.rendered) {
return;
@ -72,6 +83,12 @@ class StandardWidget {
/** for overriding */
async doRenderBody() {}
async isEnabled() {
const option = await optionsInit.getJsonOption(this.widgetName + 'Widget');
return option ? option.enabled : true;
}
isExpanded() {
return this.$bodyWrapper.hasClass("show");
}
@ -83,10 +100,6 @@ class StandardWidget {
};
}
getWidgetElement() {
return this.$widget;
}
syncDataReceived(syncData) {}
}