import {PluginFile} from "@/file"; import {CONFIG_FILENAME, JSON_MIME, STORAGE_PATH} from "@/const"; import {Plugin} from "siyuan"; import {SettingUtils} from "@/libs/setting-utils"; import {getFirstDefined} from "@/helper"; import {ErrorReporter, InvalidBackgroundColorError} from "@/errors"; export interface Options { dialogOnDesktop: boolean analytics: boolean editorOptions: EditorOptions } export interface EditorOptions { restorePosition: boolean; grid: boolean background: string } export class PluginConfig { private file: PluginFile; options: Options; private firstRun: boolean; getFirstRun() { return this.firstRun } constructor() { this.file = new PluginFile(STORAGE_PATH, CONFIG_FILENAME, JSON_MIME); } async load() { this.firstRun = false; await this.file.loadFromSiYuanFS(); const jsonObj = JSON.parse(this.file.getContent()); if(jsonObj == null) { this.firstRun = true; } // if more than one fallback, the intermediate ones are from a legacy config file version this.options = { dialogOnDesktop: getFirstDefined(jsonObj?.dialogOnDesktop, false), analytics: getFirstDefined(jsonObj?.analytics, true), editorOptions: { restorePosition: getFirstDefined(jsonObj?.editorOptions?.restorePosition, jsonObj?.restorePosition, true), grid: getFirstDefined(jsonObj?.editorOptions?.grid, jsonObj?.grid, true), background: getFirstDefined(jsonObj?.editorOptions?.background, jsonObj?.background, "#00000000") }, }; } async save() { this.file.setContent(JSON.stringify(this.options)); await this.file.save(); } setConfig(config: Options) { this.options = config; } static validateColor(hex: string) { hex = hex.replace('#', ''); return typeof hex === 'string' && (hex.length === 6 || hex.length === 8) && !isNaN(Number('0x' + hex)) } } export class PluginConfigViewer { config: PluginConfig; settingUtils: SettingUtils; plugin: Plugin; private readonly backgroundDropdownOptions; constructor(config: PluginConfig, plugin: Plugin) { this.config = config; this.plugin = plugin; this.backgroundDropdownOptions = { '#00000000': plugin.i18n.settings.suggestedColors.transparent, 'CUSTOM': plugin.i18n.settings.suggestedColors.custom, '#ffffff': plugin.i18n.settings.suggestedColors.white, '#1e2227': plugin.i18n.settings.suggestedColors.darkBlue, '#1e1e1e': plugin.i18n.settings.suggestedColors.darkGray, '#000000': plugin.i18n.settings.suggestedColors.black, } this.populateSettingMenu(); } async configSaveCallback(data) { let color = data.backgroundDropdown === "CUSTOM" ? data.background : data.backgroundDropdown; if(!PluginConfig.validateColor(color)) { ErrorReporter.error(new InvalidBackgroundColorError()); data.background = this.config.options.editorOptions.background; this.settingUtils.set('background', data.background); } this.config.setConfig({ dialogOnDesktop: data.dialogOnDesktop, analytics: data.analytics, editorOptions: { grid: data.grid, background: color, restorePosition: data.restorePosition, } }); await this.config.save(); } populateSettingMenu() { this.settingUtils = new SettingUtils({ plugin: this.plugin, name: 'optionsUI', callback: async (data) => { await this.configSaveCallback(data); } }); this.settingUtils.addItem({ key: "grid", title: this.plugin.i18n.settings.grid.title, description: this.plugin.i18n.settings.grid.description, value: this.config.options.editorOptions.grid, type: 'checkbox' }); this.settingUtils.addItem({ key: 'backgroundDropdown', title: this.plugin.i18n.settings.backgroundDropdown.title, description: this.plugin.i18n.settings.backgroundDropdown.description, type: 'select', value: this.config.options.editorOptions.background in this.backgroundDropdownOptions ? this.config.options.editorOptions.background : 'CUSTOM', options: this.backgroundDropdownOptions, }); this.settingUtils.addItem({ key: "background", title: this.plugin.i18n.settings.background.title, description: this.plugin.i18n.settings.background.description, value: this.config.options.editorOptions.background, type: 'textinput', }); this.settingUtils.addItem({ key: "restorePosition", title: this.plugin.i18n.settings.restorePosition.title, description: this.plugin.i18n.settings.restorePosition.description, value: this.config.options.editorOptions.restorePosition, type: 'checkbox' }); this.settingUtils.addItem({ key: "dialogOnDesktop", title: this.plugin.i18n.settings.dialogOnDesktop.title, description: this.plugin.i18n.settings.dialogOnDesktop.description, value: this.config.options.dialogOnDesktop, type: 'checkbox' }); this.settingUtils.addItem({ key: "analytics", title: this.plugin.i18n.settings.analytics.title, description: this.plugin.i18n.settings.analytics.description, value: this.config.options.analytics, type: 'checkbox' }); } load() { return this.settingUtils.load(); } }