From 2bb453451c14f99aff6bc10723c5acdc2b3c2c12 Mon Sep 17 00:00:00 2001 From: Philip Molares Date: Wed, 27 Nov 2024 20:17:47 +0100 Subject: [PATCH] feat(redux): add print-mode Signed-off-by: Philip Molares --- .../editor-page/utils/print-iframe.ts | 39 ++++++++++++++----- .../render-page/render-page-content.tsx | 8 ++++ .../rendering-message.ts | 10 ++++- .../hooks/dark-mode/use-dark-mode-state.ts | 10 +++++ frontend/src/redux/index.ts | 4 +- .../src/redux/print-mode/initial-state.ts | 10 +++++ frontend/src/redux/print-mode/methods.ts | 12 ++++++ frontend/src/redux/print-mode/slice.ts | 22 +++++++++++ frontend/src/redux/print-mode/types.ts | 8 ++++ 9 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 frontend/src/redux/print-mode/initial-state.ts create mode 100644 frontend/src/redux/print-mode/methods.ts create mode 100644 frontend/src/redux/print-mode/slice.ts create mode 100644 frontend/src/redux/print-mode/types.ts diff --git a/frontend/src/components/editor-page/utils/print-iframe.ts b/frontend/src/components/editor-page/utils/print-iframe.ts index ae7012aef..a4cf76676 100644 --- a/frontend/src/components/editor-page/utils/print-iframe.ts +++ b/frontend/src/components/editor-page/utils/print-iframe.ts @@ -4,17 +4,36 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { useIsRendererReady } from '../../render-page/window-post-message-communicator/hooks/use-is-renderer-ready' +import { useCallback } from 'react' +import { CommunicationMessageType } from '../../render-page/window-post-message-communicator/rendering-message' +import { useEditorToRendererCommunicator } from '../render-context/editor-to-renderer-communicator-context-provider' + /** * Prints the content of the renderer iframe. */ -export const printIframe = (): void => { - const iframe = document.getElementById('editor-renderer-iframe') as HTMLIFrameElement -<<<<<<< HEAD - if (!iframe) { -======= - if (!iframe || !iframe.contentWindow) { ->>>>>>> 279f6cd89 (feat(frontend): add basic print functionality) - return - } - iframe.contentWindow.print() +export const usePrintIframe = (): (() => void) => { + const iframeCommunicator = useEditorToRendererCommunicator() + const rendererReady = useIsRendererReady() + + return useCallback(() => { + if (!rendererReady) { + return + } + const iframe = document.getElementById('editor-renderer-iframe') as HTMLIFrameElement + if (!iframe || !iframe.contentWindow) { + return + } + iframeCommunicator.sendMessageToOtherSide({ + type: CommunicationMessageType.SET_PRINT_MODE, + printMode: true + }) + setTimeout(() => { + iframe.contentWindow?.print() + iframeCommunicator.sendMessageToOtherSide({ + type: CommunicationMessageType.SET_PRINT_MODE, + printMode: false + }) + }, 50) + }, [rendererReady, iframeCommunicator]) } diff --git a/frontend/src/components/render-page/render-page-content.tsx b/frontend/src/components/render-page/render-page-content.tsx index b9789840f..995168ed0 100644 --- a/frontend/src/components/render-page/render-page-content.tsx +++ b/frontend/src/components/render-page/render-page-content.tsx @@ -17,6 +17,7 @@ import { countWords } from './word-counter' import type { SlideOptions } from '@hedgedoc/commons' import { EventEmitter2 } from 'eventemitter2' import React, { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react' +import { setPrintMode } from '../../redux/print-mode/methods' /** * Wraps the markdown rendering in an iframe. @@ -78,6 +79,13 @@ export const RenderPageContent: React.FC = () => { }, [communicator]) ) + useRendererReceiveHandler( + CommunicationMessageType.SET_PRINT_MODE, + useCallback(({ printMode }) => { + setPrintMode(printMode) + }, []) + ) + const onMakeScrollSource = useCallback(() => { sendScrolling.current = true communicator.sendMessageToOtherSide({ diff --git a/frontend/src/components/render-page/window-post-message-communicator/rendering-message.ts b/frontend/src/components/render-page/window-post-message-communicator/rendering-message.ts index 919989266..a06fd3ae1 100644 --- a/frontend/src/components/render-page/window-post-message-communicator/rendering-message.ts +++ b/frontend/src/components/render-page/window-post-message-communicator/rendering-message.ts @@ -20,13 +20,19 @@ export enum CommunicationMessageType { ON_WORD_COUNT_CALCULATED = 'ON_WORD_COUNT_CALCULATED', SET_SLIDE_OPTIONS = 'SET_SLIDE_OPTIONS', IMAGE_UPLOAD = 'IMAGE_UPLOAD', - EXTENSION_EVENT = 'EXTENSION_EVENT' + EXTENSION_EVENT = 'EXTENSION_EVENT', + SET_PRINT_MODE = 'SET_PRINT_MODE' } export interface NoPayloadMessage { type: TYPE } +export interface SetPrintModeConfigurationMessage { + type: CommunicationMessageType.SET_PRINT_MODE + printMode: boolean +} + export interface SetAdditionalConfigurationMessage { type: CommunicationMessageType.SET_ADDITIONAL_CONFIGURATION darkModePreference: DarkModePreference @@ -101,6 +107,7 @@ export type CommunicationMessages = | OnWordCountCalculatedMessage | ImageUploadMessage | ExtensionEvent + | SetPrintModeConfigurationMessage export type EditorToRendererMessageType = | CommunicationMessageType.SET_MARKDOWN_CONTENT @@ -110,6 +117,7 @@ export type EditorToRendererMessageType = | CommunicationMessageType.GET_WORD_COUNT | CommunicationMessageType.SET_SLIDE_OPTIONS | CommunicationMessageType.DISABLE_RENDERER_SCROLL_SOURCE + | CommunicationMessageType.SET_PRINT_MODE export type RendererToEditorMessageType = | CommunicationMessageType.RENDERER_READY diff --git a/frontend/src/hooks/dark-mode/use-dark-mode-state.ts b/frontend/src/hooks/dark-mode/use-dark-mode-state.ts index 88c7e69b2..d8cb8985e 100644 --- a/frontend/src/hooks/dark-mode/use-dark-mode-state.ts +++ b/frontend/src/hooks/dark-mode/use-dark-mode-state.ts @@ -6,6 +6,9 @@ import { DarkModePreference } from '../../redux/dark-mode/types' import { useApplicationState } from '../common/use-application-state' import useMediaQuery from '@restart/hooks/useMediaQuery' +import { Logger } from '../../utils/logger' + +const logger = new Logger('useDarkModeState') /** * Uses the user settings and the browser preference to determine if dark mode should be used. @@ -14,7 +17,14 @@ import useMediaQuery from '@restart/hooks/useMediaQuery' */ export const useDarkModeState = (): boolean => { const preference = useApplicationState((state) => state.darkMode.darkModePreference) + const printModeEnabled = useApplicationState((state) => state.printMode.printModeEnabled) const isBrowserPreferringDark = useMediaQuery('(prefers-color-scheme: dark)') + logger.info(`SET_PRINT_MODE ${printModeEnabled}`) + + if (printModeEnabled) { + return false + } + return preference === DarkModePreference.DARK || (preference === DarkModePreference.AUTO && isBrowserPreferringDark) } diff --git a/frontend/src/redux/index.ts b/frontend/src/redux/index.ts index ad9bed194..1a7f332e3 100644 --- a/frontend/src/redux/index.ts +++ b/frontend/src/redux/index.ts @@ -12,6 +12,7 @@ import { rendererStatusReducer } from './renderer-status/slice' import { realtimeStatusReducer } from './realtime/slice' import { historyReducer } from './history/slice' import { noteDetailsReducer } from './note-details/slice' +import { printModeReducer } from './print-mode/slice' export const store = configureStore({ reducer: { @@ -21,7 +22,8 @@ export const store = configureStore({ rendererStatus: rendererStatusReducer, realtimeStatus: realtimeStatusReducer, history: historyReducer, - noteDetails: noteDetailsReducer + noteDetails: noteDetailsReducer, + printMode: printModeReducer }, devTools: isDevMode }) diff --git a/frontend/src/redux/print-mode/initial-state.ts b/frontend/src/redux/print-mode/initial-state.ts new file mode 100644 index 000000000..30c8bd826 --- /dev/null +++ b/frontend/src/redux/print-mode/initial-state.ts @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import type { PrintModeConfig } from './types' + +export const initialState: PrintModeConfig = { + printModeEnabled: false +} diff --git a/frontend/src/redux/print-mode/methods.ts b/frontend/src/redux/print-mode/methods.ts new file mode 100644 index 000000000..3b595982d --- /dev/null +++ b/frontend/src/redux/print-mode/methods.ts @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { store } from '..' +import { printModeActionsCreator } from './slice' + +export const setPrintMode = (printMode: boolean): void => { + const action = printModeActionsCreator.setPrintMode(printMode) + store.dispatch(action) +} diff --git a/frontend/src/redux/print-mode/slice.ts b/frontend/src/redux/print-mode/slice.ts new file mode 100644 index 000000000..8bf9505bb --- /dev/null +++ b/frontend/src/redux/print-mode/slice.ts @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import type { PayloadAction } from '@reduxjs/toolkit' +import { createSlice } from '@reduxjs/toolkit' +import { initialState } from './initial-state' +import type { PrintModeConfig } from './types' + +const printModeSlice = createSlice({ + name: 'printMode', + initialState, + reducers: { + setPrintMode: (state, action: PayloadAction) => { + state.printModeEnabled = action.payload + } + } +}) + +export const printModeActionsCreator = printModeSlice.actions +export const printModeReducer = printModeSlice.reducer diff --git a/frontend/src/redux/print-mode/types.ts b/frontend/src/redux/print-mode/types.ts new file mode 100644 index 000000000..81986e89b --- /dev/null +++ b/frontend/src/redux/print-mode/types.ts @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +export interface PrintModeConfig { + printModeEnabled: boolean +}