mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	appearance tab in hidden subtree
This commit is contained in:
		| @@ -218,20 +218,20 @@ export default class DesktopLayout { | |||||||
|             .child(new DeleteNotesDialog()) |             .child(new DeleteNotesDialog()) | ||||||
|             .child(new InfoDialog()) |             .child(new InfoDialog()) | ||||||
|             .child(new ConfirmDialog()) |             .child(new ConfirmDialog()) | ||||||
|             .child(new PromptDialog()) |             .child(new PromptDialog()); | ||||||
|             .child(new OptionsDialog() |             // .child(new OptionsDialog() | ||||||
|                 .child(new AppearanceOptions()) |             //     .child(new AppearanceOptions()) | ||||||
|                 .child(new KeyboardShortcutsOptions()) |             //     .child(new KeyboardShortcutsOptions()) | ||||||
|                 .child(new TextNotesOptions()) |             //     .child(new TextNotesOptions()) | ||||||
|                 .child(new CodeNotesOptions()) |             //     .child(new CodeNotesOptions()) | ||||||
|                 .child(new ImageOptions()) |             //     .child(new ImageOptions()) | ||||||
|                 .child(new SpellcheckOptions()) |             //     .child(new SpellcheckOptions()) | ||||||
|                 .child(new PasswordOptions()) |             //     .child(new PasswordOptions()) | ||||||
|                 .child(new EtapiOptions()) |             //     .child(new EtapiOptions()) | ||||||
|                 .child(new BackupOptions()) |             //     .child(new BackupOptions()) | ||||||
|                 .child(new SyncOptions()) |             //     .child(new SyncOptions()) | ||||||
|                 .child(new OtherOptions()) |             //     .child(new OtherOptions()) | ||||||
|                 .child(new AdvancedOptions()) |             //     .child(new AdvancedOptions()) | ||||||
|             ); |             // ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import BasicWidget from "../../basic_widget.js"; |  | ||||||
| import server from "../../../services/server.js"; | import server from "../../../services/server.js"; | ||||||
| import toastService from "../../../services/toast.js"; | import toastService from "../../../services/toast.js"; | ||||||
|  | import NoteContextAwareWidget from "../../note_context_aware_widget.js"; | ||||||
|  |  | ||||||
| export default class OptionsTab extends BasicWidget { | export default class OptionsTab extends NoteContextAwareWidget { | ||||||
|     async updateOption(name, value) { |     async updateOption(name, value) { | ||||||
|         const opts = { [name]: value }; |         const opts = { [name]: value }; | ||||||
|  |  | ||||||
| @@ -34,4 +34,10 @@ export default class OptionsTab extends BasicWidget { | |||||||
|     setCheckboxState($checkbox, optionValue) { |     setCheckboxState($checkbox, optionValue) { | ||||||
|         $checkbox.prop('checked', optionValue === 'true'); |         $checkbox.prop('checked', optionValue === 'true'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async refreshWithNote(note) { | ||||||
|  |         const options = await server.get('options'); | ||||||
|  |  | ||||||
|  |         this.optionsLoaded(options); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,12 +1,22 @@ | |||||||
| import TypeWidget from "./type_widget.js"; | import TypeWidget from "./type_widget.js"; | ||||||
|  | import AppearanceOptions from "./options/appearance.js"; | ||||||
|  |  | ||||||
| const TPL = `<div class="note-detail-widget note-detail-printable"></div>`; | const TPL = `<div class="note-detail-content-widget note-detail-printable"> | ||||||
|  |     <style> | ||||||
|  |         .note-detail-content-widget-content { | ||||||
|  |             padding: 15px; | ||||||
|  |         } | ||||||
|  |     </style> | ||||||
|  |  | ||||||
|  |     <div class="note-detail-content-widget-content"></div> | ||||||
|  | </div>`; | ||||||
|  |  | ||||||
| export default class ContentWidgetTypeWidget extends TypeWidget { | export default class ContentWidgetTypeWidget extends TypeWidget { | ||||||
|     static getType() { return "content-widget"; } |     static getType() { return "content-widget"; } | ||||||
|  |  | ||||||
|     doRender() { |     doRender() { | ||||||
|         this.$widget = $(TPL); |         this.$widget = $(TPL); | ||||||
|  |         this.$content = this.$widget.find(".note-detail-content-widget-content"); | ||||||
|  |  | ||||||
|         super.doRender(); |         super.doRender(); | ||||||
|     } |     } | ||||||
| @@ -14,10 +24,19 @@ export default class ContentWidgetTypeWidget extends TypeWidget { | |||||||
|     async doRefresh(note) { |     async doRefresh(note) { | ||||||
|         const contentWidget = note.getLabelValue('contentWidget'); |         const contentWidget = note.getLabelValue('contentWidget'); | ||||||
|  |  | ||||||
|  |         this.$content.empty(); | ||||||
|  |         this.children = []; | ||||||
|  |  | ||||||
|         if (contentWidget === 'optionsAppearance') { |         if (contentWidget === 'optionsAppearance') { | ||||||
|             this.$widget.empty().append("HI!"); |             const widget = new AppearanceOptions(); | ||||||
|  |  | ||||||
|  |             await widget.handleEvent('setNoteContext', { noteContext: this.noteContext }); | ||||||
|  |             this.child(widget); | ||||||
|  |  | ||||||
|  |             this.$content.append(widget.render()); | ||||||
|  |             await widget.refresh(); | ||||||
|         } else { |         } else { | ||||||
|             this.$widget.empty().append(`Unknown widget of type "${contentWidget}"`); |             this.$content.append(`Unknown widget of type "${contentWidget}"`); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										326
									
								
								src/public/app/widgets/type_widgets/options/appearance.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								src/public/app/widgets/type_widgets/options/appearance.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,326 @@ | |||||||
|  | import server from "../../../services/server.js"; | ||||||
|  | import utils from "../../../services/utils.js"; | ||||||
|  | import appContext from "../../../components/app_context.js"; | ||||||
|  | import OptionsTab from "../../dialogs/options/options_tab.js"; | ||||||
|  |  | ||||||
|  | const FONT_FAMILIES = [ | ||||||
|  |     { value: "theme", label: "Theme defined" }, | ||||||
|  |     { value: "serif", label: "Serif" }, | ||||||
|  |     { value: "sans-serif", label: "Sans Serif" }, | ||||||
|  |     { value: "monospace", label: "Monospace" }, | ||||||
|  |     { value: "Arial", label: "Arial" }, | ||||||
|  |     { value: "Verdana", label: "Verdana" }, | ||||||
|  |     { value: "Helvetica", label: "Helvetica" }, | ||||||
|  |     { value: "Tahoma", label: "Tahoma" }, | ||||||
|  |     { value: "Trebuchet MS", label: "Trebuchet MS" }, | ||||||
|  |     { value: "Times New Roman", label: "Times New Roman" }, | ||||||
|  |     { value: "Georgia", label: "Georgia" }, | ||||||
|  |     { value: "Garamond", label: "Garamond" }, | ||||||
|  |     { value: "Courier New", label: "Courier New" }, | ||||||
|  |     { value: "Brush Script MT", label: "Brush Script MT" }, | ||||||
|  |     { value: "Impact", label: "Impact" }, | ||||||
|  |     { value: "American Typewriter", label: "American Typewriter" }, | ||||||
|  |     { value: "Andalé Mono", label: "Andalé Mono" }, | ||||||
|  |     { value: "Lucida Console", label: "Lucida Console" }, | ||||||
|  |     { value: "Monaco", label: "Monaco" }, | ||||||
|  |     { value: "Bradley Hand", label: "Bradley Hand" }, | ||||||
|  |     { value: "Luminari", label: "Luminari" }, | ||||||
|  |     { value: "Comic Sans MS", label: "Comic Sans MS" }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | const TPL = ` | ||||||
|  | <div> | ||||||
|  | <p><strong>Settings on this options tab are saved automatically after each change.</strong></p> | ||||||
|  |  | ||||||
|  | <style> | ||||||
|  |     .options-section .row { | ||||||
|  |         /* rows otherwise overflow horizontally and force a scrollbar */ | ||||||
|  |         margin-left: auto; | ||||||
|  |         margin-right: auto; | ||||||
|  |     } | ||||||
|  | </style> | ||||||
|  |  | ||||||
|  | <div class="options-section"> | ||||||
|  |     <div class="form-group row"> | ||||||
|  |         <div class="col-6"> | ||||||
|  |             <label>Zoom factor (desktop build only)</label> | ||||||
|  |      | ||||||
|  |             <input type="number" class="zoom-factor-select form-control" min="0.3" max="2.0" step="0.1"/> | ||||||
|  |         </div> | ||||||
|  |          | ||||||
|  |         <div class="col-6"> | ||||||
|  |             <label>Native title bar (requires app restart)</label> | ||||||
|  |      | ||||||
|  |             <select class="native-title-bar-select form-control"> | ||||||
|  |                 <option value="show">enabled</option> | ||||||
|  |                 <option value="hide">disabled</option> | ||||||
|  |             </select> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |          | ||||||
|  |     <p>Zooming can be controlled with CTRL+- and CTRL+= shortcuts as well.</p> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <div class="options-section"> | ||||||
|  |     <h4>Theme</h4> | ||||||
|  |      | ||||||
|  |     <div class="form-group row"> | ||||||
|  |         <div class="col-6"> | ||||||
|  |             <label>Theme</label> | ||||||
|  |             <select class="theme-select form-control"></select> | ||||||
|  |         </div> | ||||||
|  |          | ||||||
|  |         <div class="col-6"> | ||||||
|  |             <label>Override theme fonts</label> | ||||||
|  |             <input type="checkbox" class="override-theme-fonts form-control"> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <div class="overriden-font-settings options-section"> | ||||||
|  |     <h4>Fonts</h4> | ||||||
|  |      | ||||||
|  |     <h5>Main font</h5> | ||||||
|  |      | ||||||
|  |     <div class="form-group row"> | ||||||
|  |         <div class="col-6"> | ||||||
|  |             <label>Font family</label> | ||||||
|  |             <select class="main-font-family form-control"></select> | ||||||
|  |         </div> | ||||||
|  |      | ||||||
|  |         <div class="col-6"> | ||||||
|  |             <label>Size</label> | ||||||
|  |  | ||||||
|  |             <div class="input-group"> | ||||||
|  |                 <input type="number" class="main-font-size form-control" min="50" max="200" step="10"/> | ||||||
|  |                 <div class="input-group-append"> | ||||||
|  |                     <span class="input-group-text">%</span> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <h5>Note tree font</h5> | ||||||
|  |  | ||||||
|  |     <div class="form-group row"> | ||||||
|  |         <div class="col-4"> | ||||||
|  |             <label>Font family</label> | ||||||
|  |             <select class="tree-font-family form-control"></select> | ||||||
|  |         </div> | ||||||
|  |      | ||||||
|  |         <div class="col-4"> | ||||||
|  |             <label>Size</label> | ||||||
|  |  | ||||||
|  |             <div class="input-group"> | ||||||
|  |                 <input type="number" class="tree-font-size form-control" min="50" max="200" step="10"/> | ||||||
|  |                 <div class="input-group-append"> | ||||||
|  |                     <span class="input-group-text">%</span> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |      | ||||||
|  |     <h5>Note detail font</h5> | ||||||
|  |      | ||||||
|  |     <div class="form-group row"> | ||||||
|  |         <div class="col-4"> | ||||||
|  |             <label>Font family</label> | ||||||
|  |             <select class="detail-font-family form-control"></select> | ||||||
|  |         </div> | ||||||
|  |          | ||||||
|  |         <div class="col-4"> | ||||||
|  |             <label>Size</label> | ||||||
|  |  | ||||||
|  |             <div class="input-group"> | ||||||
|  |                 <input type="number" class="detail-font-size form-control" min="50" max="200" step="10"/> | ||||||
|  |                 <div class="input-group-append"> | ||||||
|  |                     <span class="input-group-text">%</span> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |      | ||||||
|  |     <h5>Monospace (code) font</h5> | ||||||
|  |      | ||||||
|  |     <div class="form-group row"> | ||||||
|  |         <div class="col-4"> | ||||||
|  |             <label>Font family</label> | ||||||
|  |             <select class="monospace-font-family form-control"></select> | ||||||
|  |         </div> | ||||||
|  |      | ||||||
|  |         <div class="col-4"> | ||||||
|  |             <label>Size</label> | ||||||
|  |  | ||||||
|  |             <div class="input-group"> | ||||||
|  |                 <input type="number" class="monospace-font-size form-control" min="50" max="200" step="10"/> | ||||||
|  |                 <div class="input-group-append"> | ||||||
|  |                     <span class="input-group-text">%</span> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <p>Note that tree and detail font sizing is relative to the main font size setting.</p> | ||||||
|  |  | ||||||
|  |     <p>Not all listed fonts may be available on your system.</p> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <p> | ||||||
|  |     To apply font changes, click on  | ||||||
|  |     <button class="btn btn-micro reload-frontend-button">reload frontend</button> | ||||||
|  | </p> | ||||||
|  |  | ||||||
|  | <div class="options-section"> | ||||||
|  |     <h4>Content width</h4> | ||||||
|  |      | ||||||
|  |     <p>Trilium by default limits max content width to improve readability for maximized screens on wide screens.</p> | ||||||
|  |      | ||||||
|  |     <div class="form-group row"> | ||||||
|  |         <div class="col-4"> | ||||||
|  |             <label>Max content width in pixels</label> | ||||||
|  |             <input type="number" min="200" step="10" class="max-content-width form-control"> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |      | ||||||
|  |     <p> | ||||||
|  |         To content width changes, click on  | ||||||
|  |         <button class="btn btn-micro reload-frontend-button">reload frontend</button> | ||||||
|  |     </p> | ||||||
|  | </div> | ||||||
|  | </div>`; | ||||||
|  |  | ||||||
|  | export default class AppearanceOptions extends OptionsTab { | ||||||
|  |     get tabTitle() { return "Appearance" } | ||||||
|  |  | ||||||
|  |     doRender() { | ||||||
|  |         this.$widget = $(TPL); | ||||||
|  |  | ||||||
|  |         this.$zoomFactorSelect = this.$widget.find(".zoom-factor-select"); | ||||||
|  |         this.$nativeTitleBarSelect = this.$widget.find(".native-title-bar-select"); | ||||||
|  |  | ||||||
|  |         this.$themeSelect = this.$widget.find(".theme-select"); | ||||||
|  |         this.$overrideThemeFonts = this.$widget.find(".override-theme-fonts"); | ||||||
|  |  | ||||||
|  |         this.$overridenFontSettings = this.$widget.find(".overriden-font-settings"); | ||||||
|  |  | ||||||
|  |         this.$mainFontSize = this.$widget.find(".main-font-size"); | ||||||
|  |         this.$mainFontFamily = this.$widget.find(".main-font-family"); | ||||||
|  |  | ||||||
|  |         this.$treeFontSize = this.$widget.find(".tree-font-size"); | ||||||
|  |         this.$treeFontFamily = this.$widget.find(".tree-font-family"); | ||||||
|  |  | ||||||
|  |         this.$detailFontSize = this.$widget.find(".detail-font-size"); | ||||||
|  |         this.$detailFontFamily = this.$widget.find(".detail-font-family"); | ||||||
|  |  | ||||||
|  |         this.$monospaceFontSize = this.$widget.find(".monospace-font-size"); | ||||||
|  |         this.$monospaceFontFamily = this.$widget.find(".monospace-font-family"); | ||||||
|  |  | ||||||
|  |         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(); | ||||||
|  |  | ||||||
|  |             await server.put('options/theme/' + newTheme); | ||||||
|  |  | ||||||
|  |             utils.reloadFrontendApp("theme change"); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         this.$overrideThemeFonts.on('change', async () => { | ||||||
|  |             this.updateCheckboxOption('overrideThemeFonts', this.$overrideThemeFonts); | ||||||
|  |  | ||||||
|  |             this.$overridenFontSettings.toggle(this.$overrideThemeFonts.is(":checked")); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         this.$zoomFactorSelect.on('change', () => { appContext.triggerCommand('setZoomFactorAndSave', {zoomFactor: this.$zoomFactorSelect.val()}); }); | ||||||
|  |  | ||||||
|  |         this.$nativeTitleBarSelect.on('change', () => { | ||||||
|  |             const nativeTitleBarVisible = this.$nativeTitleBarSelect.val() === 'show' ? 'true' : 'false'; | ||||||
|  |  | ||||||
|  |             this.updateOption('nativeTitleBarVisible', nativeTitleBarVisible); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         const optionsToSave = [ | ||||||
|  |             'mainFontFamily', 'mainFontSize', | ||||||
|  |             'treeFontFamily', 'treeFontSize', | ||||||
|  |             'detailFontFamily', 'detailFontSize', | ||||||
|  |             'monospaceFontFamily', 'monospaceFontSize' | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         for (const optionName of optionsToSave) { | ||||||
|  |             this['$' + optionName].on('change', () => | ||||||
|  |                 this.updateOption(optionName, this['$' + optionName].val())); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.$maxContentWidth = this.$widget.find(".max-content-width"); | ||||||
|  |  | ||||||
|  |         this.$maxContentWidth.on('change', async () => | ||||||
|  |             this.updateOption('maxContentWidth', this.$maxContentWidth.val())) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     toggleBodyClass(prefix, value) { | ||||||
|  |         for (const clazz of Array.from(this.$body[0].classList)) { // create copy to safely iterate over while removing classes | ||||||
|  |             if (clazz.startsWith(prefix)) { | ||||||
|  |                 this.$body.removeClass(clazz); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.$body.addClass(prefix + value); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async optionsLoaded(options) { | ||||||
|  |         if (utils.isElectron()) { | ||||||
|  |             this.$zoomFactorSelect.val(options.zoomFactor); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             this.$zoomFactorSelect.prop('disabled', true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.$nativeTitleBarSelect.val(options.nativeTitleBarVisible === 'true' ? 'show' : 'hide'); | ||||||
|  |  | ||||||
|  |         const themes = [ | ||||||
|  |             { val: 'light', title: 'Light' }, | ||||||
|  |             { val: 'dark', title: 'Dark' } | ||||||
|  |         ].concat(await server.get('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.val(options.theme); | ||||||
|  |  | ||||||
|  |         this.setCheckboxState(this.$overrideThemeFonts, options.overrideThemeFonts); | ||||||
|  |         this.$overridenFontSettings.toggle(options.overrideThemeFonts === 'true'); | ||||||
|  |  | ||||||
|  |         this.$mainFontSize.val(options.mainFontSize); | ||||||
|  |         this.fillFontFamilyOptions(this.$mainFontFamily, options.mainFontFamily); | ||||||
|  |  | ||||||
|  |         this.$treeFontSize.val(options.treeFontSize); | ||||||
|  |         this.fillFontFamilyOptions(this.$treeFontFamily, options.treeFontFamily); | ||||||
|  |  | ||||||
|  |         this.$detailFontSize.val(options.detailFontSize); | ||||||
|  |         this.fillFontFamilyOptions(this.$detailFontFamily, options.detailFontFamily); | ||||||
|  |  | ||||||
|  |         this.$monospaceFontSize.val(options.monospaceFontSize); | ||||||
|  |         this.fillFontFamilyOptions(this.$monospaceFontFamily, options.monospaceFontFamily); | ||||||
|  |  | ||||||
|  |         this.$maxContentWidth.val(options.maxContentWidth); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fillFontFamilyOptions($select, currentValue) { | ||||||
|  |         $select.empty(); | ||||||
|  |  | ||||||
|  |         for (const {value, label} of FONT_FAMILIES) { | ||||||
|  |             $select.append($("<option>") | ||||||
|  |                 .attr("value", value) | ||||||
|  |                 .prop("selected", value === currentValue) | ||||||
|  |                 .text(label)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -582,7 +582,7 @@ function createOptionNotes() { | |||||||
|             branchId: OPTIONS_ROOT, |             branchId: OPTIONS_ROOT, | ||||||
|             noteId: OPTIONS_ROOT, |             noteId: OPTIONS_ROOT, | ||||||
|             title: 'Options', |             title: 'Options', | ||||||
|             type: 'doc', |             type: 'book', | ||||||
|             content: '', |             content: '', | ||||||
|             parentNoteId: getHiddenRoot().noteId |             parentNoteId: getHiddenRoot().noteId | ||||||
|         }); |         }); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user