diff --git a/frontend/src/components/common/renderer-iframe/hooks/use-send-note-id.ts b/frontend/src/components/common/renderer-iframe/hooks/use-send-note-id.ts new file mode 100644 index 000000000..481ebcad5 --- /dev/null +++ b/frontend/src/components/common/renderer-iframe/hooks/use-send-note-id.ts @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { useSendToRenderer } from '../../../render-page/window-post-message-communicator/hooks/use-send-to-renderer' +import { CommunicationMessageType } from '../../../render-page/window-post-message-communicator/rendering-message' +import { useMemo } from 'react' +import { useApplicationState } from '../../../../hooks/common/use-application-state' + +/** + * Sends the id of the current note to the renderer. + * + * @param rendererReady Defines if the target renderer is ready + */ +export const useSendNoteId = (rendererReady: boolean): void => { + const noteId = useApplicationState((state) => state.noteDetails.id) + + return useSendToRenderer( + useMemo( + () => ({ + type: CommunicationMessageType.SET_NOTE_ID, + noteId + }), + [noteId] + ), + rendererReady + ) +} diff --git a/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx b/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx index 77ee1a7ef..a04fced35 100644 --- a/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx +++ b/frontend/src/components/common/renderer-iframe/renderer-iframe.tsx @@ -27,6 +27,7 @@ import { useSendMarkdownToRenderer } from './hooks/use-send-markdown-to-renderer import { useSendScrollState } from './hooks/use-send-scroll-state' import styles from './style.module.scss' import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { useSendNoteId } from './hooks/use-send-note-id' export interface RendererIframeProps extends Omit { rendererType: RendererType @@ -157,6 +158,7 @@ export const RendererIframe: React.FC = ({ useEffectOnRenderTypeChange(rendererType, onIframeLoad) useSendAdditionalConfigurationToRenderer(rendererReady) useSendMarkdownToRenderer(markdownContentLines, rendererReady) + useSendNoteId(rendererReady) useSendScrollState(scrollState ?? null, rendererReady) useEditorReceiveHandler( diff --git a/frontend/src/components/render-page/fullscreen-button/fullscreen-button.tsx b/frontend/src/components/render-page/fullscreen-button/fullscreen-button.tsx index 699caa8da..5ad445225 100644 --- a/frontend/src/components/render-page/fullscreen-button/fullscreen-button.tsx +++ b/frontend/src/components/render-page/fullscreen-button/fullscreen-button.tsx @@ -25,26 +25,26 @@ import { NoteType } from '@hedgedoc/commons' export const FullscreenButton: React.FC = () => { const noteLinks = useNoteLinks() const pageType = useGetNotePageType() - const noteFrontmatter = useApplicationState((state) => state.noteDetails.frontmatter) + const noteType = useApplicationState((state) => state.noteDetails.frontmatter.type) const { correctLink, icon } = useMemo(() => { - if (!noteFrontmatter) { + if (!noteType) { return {} } switch (pageType) { case NotePageType.EDITOR: - switch (noteFrontmatter.type) { - case NoteType.DOCUMENT: - return { - correctLink: noteLinks[NotePageType.READ_ONLY], - icon: IconArrowsFullscreen - } + switch (noteType) { case NoteType.SLIDE: - default: return { correctLink: noteLinks[NotePageType.PRESENTATION], icon: IconCollectionPlay } + case NoteType.DOCUMENT: + default: + return { + correctLink: noteLinks[NotePageType.READ_ONLY], + icon: IconArrowsFullscreen + } } case NotePageType.READ_ONLY: default: @@ -53,7 +53,7 @@ export const FullscreenButton: React.FC = () => { icon: IconPencil } } - }, [noteLinks, pageType, noteFrontmatter]) + }, [noteLinks, pageType, noteType]) if (pageType === NotePageType.PRESENTATION || !correctLink || !icon) { return null diff --git a/frontend/src/components/render-page/render-page-content.tsx b/frontend/src/components/render-page/render-page-content.tsx index ae8e88969..70f89da42 100644 --- a/frontend/src/components/render-page/render-page-content.tsx +++ b/frontend/src/components/render-page/render-page-content.tsx @@ -20,6 +20,10 @@ import React, { useCallback, useDeferredValue, useEffect, useMemo, useRef, useSt import { setPrintMode } from '../../redux/print-mode/methods' import { usePrintKeyboardShortcut } from '../editor-page/hooks/use-print-keyboard-shortcut' import { FullscreenButton } from './fullscreen-button/fullscreen-button' +import { updateMetadata } from '../../redux/note-details/methods' +import { Logger } from '../../utils/logger' + +const logger = new Logger('RenderPageContent') /** * Wraps the markdown rendering in an iframe. @@ -88,6 +92,18 @@ export const RenderPageContent: React.FC = () => { }, []) ) + useRendererReceiveHandler( + CommunicationMessageType.SET_NOTE_ID, + useCallback(({ noteId }) => { + if (!noteId) { + return + } + updateMetadata(noteId).catch((error) => { + logger.error('Failed to update metadata for note id', noteId, error) + }) + }, []) + ) + usePrintKeyboardShortcut() const onMakeScrollSource = useCallback(() => { 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 a06fd3ae1..5945c2709 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 @@ -21,7 +21,8 @@ export enum CommunicationMessageType { SET_SLIDE_OPTIONS = 'SET_SLIDE_OPTIONS', IMAGE_UPLOAD = 'IMAGE_UPLOAD', EXTENSION_EVENT = 'EXTENSION_EVENT', - SET_PRINT_MODE = 'SET_PRINT_MODE' + SET_PRINT_MODE = 'SET_PRINT_MODE', + SET_NOTE_ID = 'SET_NOTE_ID' } export interface NoPayloadMessage { @@ -83,6 +84,11 @@ export interface SetSlideOptionsMessage { slideOptions: SlideOptions } +export interface SetNoteMetadataMessage { + type: CommunicationMessageType.SET_NOTE_ID + noteId: string +} + export interface OnHeightChangeMessage { type: CommunicationMessageType.ON_HEIGHT_CHANGE height: number @@ -108,6 +114,7 @@ export type CommunicationMessages = | ImageUploadMessage | ExtensionEvent | SetPrintModeConfigurationMessage + | SetNoteMetadataMessage export type EditorToRendererMessageType = | CommunicationMessageType.SET_MARKDOWN_CONTENT @@ -118,6 +125,7 @@ export type EditorToRendererMessageType = | CommunicationMessageType.SET_SLIDE_OPTIONS | CommunicationMessageType.DISABLE_RENDERER_SCROLL_SOURCE | CommunicationMessageType.SET_PRINT_MODE + | CommunicationMessageType.SET_NOTE_ID export type RendererToEditorMessageType = | CommunicationMessageType.RENDERER_READY diff --git a/frontend/src/redux/note-details/methods.ts b/frontend/src/redux/note-details/methods.ts index 6469216cf..c3786061f 100644 --- a/frontend/src/redux/note-details/methods.ts +++ b/frontend/src/redux/note-details/methods.ts @@ -52,13 +52,17 @@ export const updateCursorPositions = (selection: CursorSelection): void => { /** * Updates the current note's metadata from the server. + * If no noteId is provided, the noteId from the current note is used. + * + * @param noteId Optional: The noteId of the note to update the metadata for. */ -export const updateMetadata = async (): Promise => { +export const updateMetadata = async (noteId?: string): Promise => { const noteDetails = store.getState().noteDetails - if (!noteDetails) { + if (!noteDetails && !noteId) { return } - const updatedMetadata = await getNoteMetadata(noteDetails.id) + const updatedMetadata = await getNoteMetadata(noteId || noteDetails.id) + console.debug('Updated metadata:', updatedMetadata) const action = noteDetailsActionsCreator.updateMetadata(updatedMetadata) store.dispatch(action) }