mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	chore(client/ts): port options/appearance
This commit is contained in:
		
							parent
							
								
									5bfcf88acd
								
							
						
					
					
						commit
						552cc2753f
					
				| @ -188,6 +188,9 @@ export type CommandMappings = { | ||||
|     copyTabToNewWindow: CommandData; | ||||
|     closeActiveTab: CommandData & { | ||||
|         $el: JQuery<HTMLElement> | ||||
|     }, | ||||
|     setZoomFactorAndSave: { | ||||
|         zoomFactor: string; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| import type { OptionMap } from "../../../../../../services/options_interface.js"; | ||||
| import { t } from "../../../../services/i18n.js"; | ||||
| import library_loader from "../../../../services/library_loader.js"; | ||||
| import server from "../../../../services/server.js"; | ||||
| @ -54,15 +55,27 @@ const TPL = ` | ||||
| </div> | ||||
| `;
 | ||||
| 
 | ||||
| interface Theme { | ||||
|     title: string; | ||||
|     val: string; | ||||
| } | ||||
| 
 | ||||
| type Response = Record<string, Theme[]> | ||||
| 
 | ||||
| /** | ||||
|  * Contains appearance settings for code blocks within text notes, such as the theme for the syntax highlighter. | ||||
|  */ | ||||
| export default class CodeBlockOptions extends OptionsWidget { | ||||
| 
 | ||||
|     private $themeSelect!: JQuery<HTMLElement>; | ||||
|     private $wordWrap!: JQuery<HTMLElement>; | ||||
|     private $sampleEl!: JQuery<HTMLElement>; | ||||
| 
 | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
|         this.$themeSelect = this.$widget.find(".theme-select"); | ||||
|         this.$themeSelect.on("change", async () => { | ||||
|             const newTheme = this.$themeSelect.val(); | ||||
|             const newTheme = String(this.$themeSelect.val()); | ||||
|             library_loader.loadHighlightingTheme(newTheme); | ||||
|             await server.put(`options/codeBlockTheme/${newTheme}`); | ||||
|         }); | ||||
| @ -74,7 +87,7 @@ export default class CodeBlockOptions extends OptionsWidget { | ||||
|         this.$sampleEl = this.$widget.find(".code-sample"); | ||||
|     } | ||||
| 
 | ||||
|     #setupPreview(shouldEnableSyntaxHighlight) { | ||||
|     #setupPreview(shouldEnableSyntaxHighlight: boolean) { | ||||
|         const text = SAMPLE_CODE; | ||||
|         if (shouldEnableSyntaxHighlight) { | ||||
|             library_loader.requireLibrary(library_loader.HIGHLIGHT_JS).then(() => { | ||||
| @ -88,8 +101,8 @@ export default class CodeBlockOptions extends OptionsWidget { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async optionsLoaded(options) { | ||||
|         const themeGroups = await server.get("options/codeblock-themes"); | ||||
|     async optionsLoaded(options: OptionMap) { | ||||
|         const themeGroups = await server.get<Response>("options/codeblock-themes"); | ||||
|         this.$themeSelect.empty(); | ||||
| 
 | ||||
|         for (const [key, themes] of Object.entries(themeGroups)) { | ||||
| @ -104,8 +117,10 @@ export default class CodeBlockOptions extends OptionsWidget { | ||||
|                     this.$themeSelect.append(option); | ||||
|                 } | ||||
|             } | ||||
|             if ($group) { | ||||
|                 this.$themeSelect.append($group); | ||||
|             } | ||||
|         } | ||||
|         this.$themeSelect.val(options.codeBlockTheme); | ||||
|         this.setCheckboxState(this.$wordWrap, options.codeBlockWordWrap); | ||||
|         this.$widget.closest(".note-detail-printable").toggleClass("word-wrap", options.codeBlockWordWrap === "true"); | ||||
| @ -1,6 +1,7 @@ | ||||
| import OptionsWidget from "../options_widget.js"; | ||||
| import { t } from "../../../../services/i18n.js"; | ||||
| import utils from "../../../../services/utils.js"; | ||||
| import type { OptionMap } from "../../../../../../services/options_interface.js"; | ||||
| 
 | ||||
| const TPL = ` | ||||
| <div class="options-section"> | ||||
| @ -36,12 +37,17 @@ const TPL = ` | ||||
| `;
 | ||||
| 
 | ||||
| export default class ElectronIntegrationOptions extends OptionsWidget { | ||||
| 
 | ||||
|     private $zoomFactorSelect!: JQuery<HTMLElement>; | ||||
|     private $nativeTitleBar!: JQuery<HTMLElement>; | ||||
|     private $backgroundEffects!: JQuery<HTMLElement>; | ||||
| 
 | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
| 
 | ||||
|         this.$zoomFactorSelect = this.$widget.find(".zoom-factor-select"); | ||||
|         this.$zoomFactorSelect.on("change", () => { | ||||
|             appContext.triggerCommand("setZoomFactorAndSave", { zoomFactor: this.$zoomFactorSelect.val() }); | ||||
|             this.triggerCommand("setZoomFactorAndSave", { zoomFactor: String(this.$zoomFactorSelect.val()) }); | ||||
|         }); | ||||
| 
 | ||||
|         this.$nativeTitleBar = this.$widget.find("input.native-title-bar"); | ||||
| @ -62,7 +68,7 @@ export default class ElectronIntegrationOptions extends OptionsWidget { | ||||
|         return utils.isElectron(); | ||||
|     } | ||||
| 
 | ||||
|     async optionsLoaded(options) { | ||||
|     async optionsLoaded(options: OptionMap) { | ||||
|         this.$zoomFactorSelect.val(options.zoomFactor); | ||||
|         this.setCheckboxState(this.$nativeTitleBar, options.nativeTitleBarVisible); | ||||
|         this.setCheckboxState(this.$backgroundEffects, options.backgroundEffects); | ||||
| @ -2,6 +2,7 @@ import OptionsWidget from "../options_widget.js"; | ||||
| import server from "../../../../services/server.js"; | ||||
| import utils from "../../../../services/utils.js"; | ||||
| import { t } from "../../../../services/i18n.js"; | ||||
| import type { OptionMap } from "../../../../../../services/options_interface.js"; | ||||
| 
 | ||||
| const TPL = ` | ||||
| <div class="options-section"> | ||||
| @ -24,7 +25,17 @@ const TPL = ` | ||||
| </div> | ||||
| `;
 | ||||
| 
 | ||||
| // TODO: Deduplicate with server.
 | ||||
| interface Locale { | ||||
|     id: string; | ||||
|     name: string; | ||||
| } | ||||
| 
 | ||||
| export default class LocalizationOptions extends OptionsWidget { | ||||
| 
 | ||||
|     private $localeSelect!: JQuery<HTMLElement>; | ||||
|     private $firstDayOfWeek!: JQuery<HTMLElement>; | ||||
| 
 | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
| 
 | ||||
| @ -37,12 +48,12 @@ export default class LocalizationOptions extends OptionsWidget { | ||||
| 
 | ||||
|         this.$firstDayOfWeek = this.$widget.find(".first-day-of-week-select"); | ||||
|         this.$firstDayOfWeek.on("change", () => { | ||||
|             this.updateOption("firstDayOfWeek", this.$firstDayOfWeek.val()); | ||||
|             this.updateOption("firstDayOfWeek", String(this.$firstDayOfWeek.val())); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     async optionsLoaded(options) { | ||||
|         const availableLocales = await server.get("options/locales"); | ||||
|     async optionsLoaded(options: OptionMap) { | ||||
|         const availableLocales = await server.get<Locale[]>("options/locales"); | ||||
|         this.$localeSelect.empty(); | ||||
| 
 | ||||
|         for (const locale of availableLocales) { | ||||
| @ -1,6 +1,7 @@ | ||||
| import OptionsWidget from "../options_widget.js"; | ||||
| import utils from "../../../../services/utils.js"; | ||||
| import { t } from "../../../../services/i18n.js"; | ||||
| import type { OptionMap } from "../../../../../../services/options_interface.js"; | ||||
| 
 | ||||
| const MIN_VALUE = 640; | ||||
| 
 | ||||
| @ -24,17 +25,20 @@ const TPL = ` | ||||
| </div>`;
 | ||||
| 
 | ||||
| export default class MaxContentWidthOptions extends OptionsWidget { | ||||
| 
 | ||||
|     private $maxContentWidth!: JQuery<HTMLElement>; | ||||
| 
 | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
| 
 | ||||
|         this.$maxContentWidth = this.$widget.find(".max-content-width"); | ||||
| 
 | ||||
|         this.$maxContentWidth.on("change", async () => this.updateOption("maxContentWidth", this.$maxContentWidth.val())); | ||||
|         this.$maxContentWidth.on("change", async () => this.updateOption("maxContentWidth", String(this.$maxContentWidth.val()))); | ||||
| 
 | ||||
|         this.$widget.find(".reload-frontend-button").on("click", () => utils.reloadFrontendApp(t("max_content_width.reload_description"))); | ||||
|     } | ||||
| 
 | ||||
|     async optionsLoaded(options) { | ||||
|         this.$maxContentWidth.val(Math.max(MIN_VALUE, options.maxContentWidth)); | ||||
|     async optionsLoaded(options: OptionMap) { | ||||
|         this.$maxContentWidth.val(Math.max(MIN_VALUE, parseInt(options.maxContentWidth, 10))); | ||||
|     } | ||||
| } | ||||
| @ -1,3 +1,4 @@ | ||||
| import type { OptionMap } from "../../../../../../services/options_interface.js"; | ||||
| import { t } from "../../../../services/i18n.js"; | ||||
| import OptionsWidget from "../options_widget.js"; | ||||
| 
 | ||||
| @ -16,6 +17,10 @@ const TPL = ` | ||||
| </div>`;
 | ||||
| 
 | ||||
| export default class RibbonOptions extends OptionsWidget { | ||||
| 
 | ||||
|     private $promotedAttributesOpenInRibbon!: JQuery<HTMLElement>; | ||||
|     private $editedNotesOpenInRibbon!: JQuery<HTMLElement>; | ||||
| 
 | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
| 
 | ||||
| @ -26,7 +31,7 @@ export default class RibbonOptions extends OptionsWidget { | ||||
|         this.$editedNotesOpenInRibbon.on("change", () => this.updateCheckboxOption("editedNotesOpenInRibbon", this.$editedNotesOpenInRibbon)); | ||||
|     } | ||||
| 
 | ||||
|     async optionsLoaded(options) { | ||||
|     async optionsLoaded(options: OptionMap) { | ||||
|         this.setCheckboxState(this.$promotedAttributesOpenInRibbon, options.promotedAttributesOpenInRibbon); | ||||
|         this.setCheckboxState(this.$editedNotesOpenInRibbon, options.editedNotesOpenInRibbon); | ||||
|     } | ||||
| @ -2,6 +2,7 @@ import OptionsWidget from "../options_widget.js"; | ||||
| import server from "../../../../services/server.js"; | ||||
| import utils from "../../../../services/utils.js"; | ||||
| import { t } from "../../../../services/i18n.js"; | ||||
| import type { OptionMap } from "../../../../../../services/options_interface.js"; | ||||
| 
 | ||||
| const TPL = ` | ||||
| <div class="options-section"> | ||||
| @ -44,13 +45,24 @@ const TPL = ` | ||||
|     </div> | ||||
| </div>`;
 | ||||
| 
 | ||||
| interface Theme { | ||||
|     val: string; | ||||
|     title: string; | ||||
|     noteId?: string; | ||||
| } | ||||
| 
 | ||||
| export default class ThemeOptions extends OptionsWidget { | ||||
| 
 | ||||
|     private $themeSelect!: JQuery<HTMLElement>; | ||||
|     private $overrideThemeFonts!: JQuery<HTMLElement>; | ||||
|     private $layoutOrientation!: JQuery<HTMLElement>; | ||||
| 
 | ||||
|     doRender() { | ||||
|         this.$widget = $(TPL); | ||||
|         this.$themeSelect = this.$widget.find(".theme-select"); | ||||
|         this.$overrideThemeFonts = this.$widget.find(".override-theme-fonts"); | ||||
|         this.$layoutOrientation = this.$widget.find(`input[name="layout-orientation"]`).on("change", async () => { | ||||
|             const newLayoutOrientation = this.$widget.find(`input[name="layout-orientation"]:checked`).val(); | ||||
|             const newLayoutOrientation = String(this.$widget.find(`input[name="layout-orientation"]:checked`).val()); | ||||
|             await this.updateOption("layoutOrientation", newLayoutOrientation); | ||||
|             utils.reloadFrontendApp("layout orientation change"); | ||||
|         }); | ||||
| @ -66,20 +78,23 @@ export default class ThemeOptions extends OptionsWidget { | ||||
|         this.$overrideThemeFonts.on("change", () => this.updateCheckboxOption("overrideThemeFonts", this.$overrideThemeFonts)); | ||||
|     } | ||||
| 
 | ||||
|     async optionsLoaded(options) { | ||||
|         const themes = [ | ||||
|     async optionsLoaded(options: OptionMap) { | ||||
|         const themes: Theme[] = [ | ||||
|             { val: "next", title: t("theme.triliumnext") }, | ||||
|             { val: "next-light", title: t("theme.triliumnext-light") }, | ||||
|             { val: "next-dark", title: t("theme.triliumnext-dark") }, | ||||
|             { val: "auto", title: t("theme.auto_theme") }, | ||||
|             { val: "light", title: t("theme.light_theme") }, | ||||
|             { val: "dark", title: t("theme.dark_theme") } | ||||
|         ].concat(await server.get("options/user-themes")); | ||||
|         ].concat(await server.get<Theme[]>("options/user-themes")); | ||||
| 
 | ||||
|         this.$themeSelect.empty(); | ||||
| 
 | ||||
|         for (const theme of themes) { | ||||
|             this.$themeSelect.append($("<option>").attr("value", theme.val).attr("data-note-id", theme.noteId).text(theme.title)); | ||||
|             this.$themeSelect.append($("<option>") | ||||
|                 .attr("value", theme.val) | ||||
|                 .attr("data-note-id", theme.noteId || "") | ||||
|                 .text(theme.title)); | ||||
|         } | ||||
| 
 | ||||
|         this.$themeSelect.val(options.theme); | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran