diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx index a7de4eca23..f67ad07187 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx @@ -1128,7 +1128,6 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: Ref) => { const allAssetsOptions: NoteStyleOptions = { contentMaxWidthTarget: '.mce-content-body', contentWrapperSelector: '.mce-content-body', - scrollbarSize: props.scrollbarSize, themeId: props.contentMarkupLanguage === MarkupLanguage.Html ? 1 : null, whiteBackgroundNoteRendering: props.whiteBackgroundNoteRendering, }; @@ -1145,7 +1144,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: Ref) => { cancelled = true; }; // eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied - }, [editor, props.noteId, props.themeId, props.scrollbarSize, props.markupToHtml, props.allAssets, props.content, props.resourceInfos, props.contentKey, props.contentMarkupLanguage, props.whiteBackgroundNoteRendering]); + }, [editor, props.noteId, props.themeId, props.markupToHtml, props.allAssets, props.content, props.resourceInfos, props.contentKey, props.contentMarkupLanguage, props.whiteBackgroundNoteRendering]); useEffect(() => { if (!editor) return () => {}; diff --git a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx index 9a0cb63ba8..7a1fe6906b 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteEditor.tsx @@ -157,6 +157,7 @@ function NoteEditorContent(props: NoteEditorProps) { customCss: props.customCss, plugins: props.plugins, scrollbarSize: props.scrollbarSize, + baseFontFamily: props.viewerFontFamily, }); const allAssets = useCallback(async (markupLanguage: number, options: AllAssetsOptions = null) => { @@ -176,9 +177,10 @@ function NoteEditorContent(props: NoteEditorProps) { contentMaxWidth: props.contentMaxWidth, contentMaxWidthTarget: options.contentMaxWidthTarget, scrollbarSize: props.scrollbarSize, + baseFontFamily: props.viewerFontFamily, whiteBackgroundNoteRendering: options.whiteBackgroundNoteRendering, }); - }, [props.plugins, props.themeId, props.scrollbarSize, props.customCss, props.contentMaxWidth]); + }, [props.plugins, props.themeId, props.scrollbarSize, props.viewerFontFamily, props.customCss, props.contentMaxWidth]); const handleProvisionalFlag = useCallback(() => { if (props.isProvisional) { @@ -457,6 +459,7 @@ function NoteEditorContent(props: NoteEditorProps) { fontSize: Setting.value('style.editor.fontSize'), contentMaxWidth: props.contentMaxWidth, scrollbarSize: props.scrollbarSize, + baseFontFamily: props.viewerFontFamily, isSafeMode: props.isSafeMode, useCustomPdfViewer: props.useCustomPdfViewer, // We need it to identify the context for which media is rendered. @@ -712,6 +715,7 @@ const mapStateToProps = (state: AppState, ownProps: ConnectProps) => { ], whenClauseContext)[0] as ToolbarButtonInfo, contentMaxWidth: state.settings['style.editor.contentMaxWidth'], scrollbarSize: state.settings['style.scrollbarSize'], + viewerFontFamily: state.settings['style.viewer.fontFamily'], tabMovesFocus: state.settings['editor.tabMovesFocus'], isSafeMode: state.settings.isSafeMode, useCustomPdfViewer: false, diff --git a/packages/app-desktop/gui/NoteEditor/utils/types.ts b/packages/app-desktop/gui/NoteEditor/utils/types.ts index a58efea9be..2a880bd4bd 100644 --- a/packages/app-desktop/gui/NoteEditor/utils/types.ts +++ b/packages/app-desktop/gui/NoteEditor/utils/types.ts @@ -57,6 +57,7 @@ export interface NoteEditorProps { setTagsToolbarButtonInfo: ToolbarButtonInfo; contentMaxWidth: number; scrollbarSize: ScrollbarSize; + viewerFontFamily: string; isSafeMode: boolean; useCustomPdfViewer: boolean; shareCacheSetting: string; @@ -131,6 +132,7 @@ export interface NoteBodyEditorProps { plugins: PluginStates; mathEnabled: boolean; fontSize: number; + baseFontFamily: string; contentMaxWidth: number; isSafeMode: boolean; noteId: string; diff --git a/packages/app-desktop/gui/NoteRevisionViewer.tsx b/packages/app-desktop/gui/NoteRevisionViewer.tsx index 24f5292fb2..1aa5f33bd9 100644 --- a/packages/app-desktop/gui/NoteRevisionViewer.tsx +++ b/packages/app-desktop/gui/NoteRevisionViewer.tsx @@ -31,6 +31,7 @@ interface Props { onBack: ()=> void; customCss: string; scrollbarSize: ScrollbarSize; + fontFamily: string; } const useNoteContent = ( @@ -40,6 +41,7 @@ const useNoteContent = ( themeId: number, customCss: string, scrollbarSize: ScrollbarSize, + fontFamily: string, ) => { const [note, setNote] = useState(null); @@ -49,6 +51,7 @@ const useNoteContent = ( plugins: {}, whiteBackgroundNoteRendering: false, scrollbarSize, + baseFontFamily: fontFamily, }); useAsyncEffect(async (event) => { @@ -78,7 +81,7 @@ const useNoteContent = ( return note; }; -const NoteRevisionViewerComponent: React.FC = ({ themeId, noteId, onBack, customCss, scrollbarSize }) => { +const NoteRevisionViewerComponent: React.FC = ({ themeId, noteId, onBack, customCss, scrollbarSize, fontFamily }) => { const helpButton_onClick = useCallback(() => {}, []); const viewerRef = useRef(null); const revisionListRef = useRef(null); @@ -87,7 +90,9 @@ const NoteRevisionViewerComponent: React.FC = ({ themeId, noteId, onBack, const [currentRevId, setCurrentRevId] = useState(''); const [restoring, setRestoring] = useState(false); - const note = useNoteContent(viewerRef, currentRevId, revisions, themeId, customCss, scrollbarSize); + const note = useNoteContent( + viewerRef, currentRevId, revisions, themeId, customCss, scrollbarSize, fontFamily, + ); const viewer_domReady = useCallback(async () => { // this.viewerRef_.current.openDevTools(); @@ -203,6 +208,7 @@ const mapStateToProps = (state: AppState) => { return { themeId: state.settings.theme, scrollbarSize: state.settings['style.scrollbarSize'], + fontFamily: state.settings['style.viewer.fontFamily'], }; }; diff --git a/packages/app-desktop/gui/hooks/useMarkupToHtml.ts b/packages/app-desktop/gui/hooks/useMarkupToHtml.ts index 8f4d38d388..db5da91919 100644 --- a/packages/app-desktop/gui/hooks/useMarkupToHtml.ts +++ b/packages/app-desktop/gui/hooks/useMarkupToHtml.ts @@ -23,10 +23,11 @@ interface HookDependencies { plugins: PluginStates; whiteBackgroundNoteRendering: boolean; scrollbarSize: ScrollbarSize; + baseFontFamily: string; } export default function useMarkupToHtml(deps: HookDependencies) { - const { themeId, customCss, plugins, whiteBackgroundNoteRendering, scrollbarSize } = deps; + const { themeId, customCss, plugins, whiteBackgroundNoteRendering, scrollbarSize, baseFontFamily } = deps; const resourceBaseUrl = useMemo(() => { return `joplin-content://note-viewer/${Setting.value('resourceDir')}/`; @@ -70,6 +71,7 @@ export default function useMarkupToHtml(deps: HookDependencies) { settingValue: getPluginSettingValue, whiteBackgroundNoteRendering, scrollbarSize: scrollbarSize, + baseFontFamily, itemIdToUrl: (id: string, urlParameters = '') => { if (!(id in resources) || !resources[id]) { return null; @@ -81,5 +83,5 @@ export default function useMarkupToHtml(deps: HookDependencies) { }); return result; - }, [themeId, markupToHtml, whiteBackgroundNoteRendering, scrollbarSize, resourceBaseUrl]); + }, [themeId, markupToHtml, baseFontFamily, whiteBackgroundNoteRendering, scrollbarSize, resourceBaseUrl]); } diff --git a/packages/lib/models/settings/builtInMetadata.ts b/packages/lib/models/settings/builtInMetadata.ts index c397e9dab7..b1c7b25640 100644 --- a/packages/lib/models/settings/builtInMetadata.ts +++ b/packages/lib/models/settings/builtInMetadata.ts @@ -1184,6 +1184,17 @@ const builtInMetadata = (Setting: typeof SettingType) => { isGlobal: true, subType: SettingItemSubType.MonospaceFontFamily, }, + 'style.viewer.fontFamily': { + value: '', + type: SettingItemType.String, + public: true, + appTypes: [AppType.Desktop], + section: 'appearance', + label: () => _('Viewer and Rich Text Editor font family'), + storage: SettingStorage.File, + isGlobal: true, + subType: SettingItemSubType.FontFamily, + }, 'style.editor.contentMaxWidth': { value: 0, type: SettingItemType.Int, public: true, storage: SettingStorage.File, isGlobal: true, appTypes: [AppType.Desktop], section: 'appearance', label: () => _('Editor maximum width'), description: () => _('Set it to 0 to make it take the complete available space. Recommended width is 600.') }, diff --git a/packages/renderer/MdToHtml.ts b/packages/renderer/MdToHtml.ts index b0031ea9da..931973d4f3 100644 --- a/packages/renderer/MdToHtml.ts +++ b/packages/renderer/MdToHtml.ts @@ -644,6 +644,7 @@ export default class MdToHtml implements MarkupRenderer { let cssStrings = noteStyle(options.theme, { scrollbarSize: options.scrollbarSize, + baseFontFamily: options.baseFontFamily, contentMaxWidth: options.contentMaxWidth, }); diff --git a/packages/renderer/noteStyle.ts b/packages/renderer/noteStyle.ts index b2d1493519..7686913b93 100644 --- a/packages/renderer/noteStyle.ts +++ b/packages/renderer/noteStyle.ts @@ -13,6 +13,7 @@ export interface Options { contentMaxWidthTarget?: string; contentWrapperSelector?: string; scrollbarSize?: number; + baseFontFamily?: string; themeId?: number; whiteBackgroundNoteRendering?: boolean; } @@ -83,7 +84,7 @@ export default function(theme: any, options: Options = null) { theme = theme ? theme : {}; - const fontFamily = '\'Avenir Next\', \'Avenir\', \'Arial\', sans-serif'; + const fontFamily = options.baseFontFamily || '\'Avenir Next\', \'Avenir\', \'Arial\', sans-serif'; const contentWrapperTarget = options.contentWrapperSelector ?? '#rendered-md'; const maxWidthTarget = options.contentMaxWidthTarget ? options.contentMaxWidthTarget : contentWrapperTarget; diff --git a/packages/renderer/types.ts b/packages/renderer/types.ts index f2bfd9be87..42480a7865 100644 --- a/packages/renderer/types.ts +++ b/packages/renderer/types.ts @@ -35,6 +35,7 @@ export interface FsDriver { export interface RenderOptions { contentMaxWidth?: number; scrollbarSize?: number; + baseFontFamily?: string; bodyOnly?: boolean; splitted?: boolean; enableLongPress?: boolean;