fix(frontend): migrate type changes

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-10-20 08:49:46 +02:00 committed by renovate[bot]
parent 2f5dadb981
commit 61362f9175
37 changed files with 80 additions and 79 deletions

View file

@ -42,6 +42,8 @@ export const ApplicationLoader: React.FC<PropsWithChildren> = ({ children }) =>
For further information look into the browser console.
</Fragment>
)
} else {
return null
}
}, [error])

View file

@ -11,7 +11,7 @@ import React from 'react'
import { Alert } from 'react-bootstrap'
export interface LoadingScreenProps {
errorMessage?: string | ReactElement
errorMessage?: string | ReactElement | null
}
/**

View file

@ -14,13 +14,12 @@ import { Fragment, useMemo } from 'react'
* @param lines The elements to wrap
* @param startLineNumber The line number to start with. Will default to 1 if omitted.
*/
export const useAttachLineNumbers = (
lines: undefined | ReactElement[],
startLineNumber = 1
): undefined | ReactElement[] =>
useMemo(
() =>
lines?.map((line, index) => (
export const useAttachLineNumbers = (lines: ReactElement[] | null, startLineNumber = 1): ReactElement | null => {
return useMemo(() => {
if (lines === null) {
return null
}
const adjustedLines = lines.map((line, index) => (
<Fragment key={index}>
<span {...cypressId('linenumber')} className={styles['linenumber']}>
{startLineNumber + index}
@ -29,6 +28,7 @@ export const useAttachLineNumbers = (
{line}
</div>
</Fragment>
)),
[startLineNumber, lines]
)
))
return <Fragment>{adjustedLines}</Fragment>
}, [startLineNumber, lines])
}

View file

@ -3,7 +3,7 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { HtmlToReact } from '../../../../components/common/html-to-react/html-to-react'
import { HtmlToReact } from '../../html-to-react/html-to-react'
import type { HLJSApi } from 'highlight.js'
import type { ReactElement } from 'react'
import React, { useMemo } from 'react'
@ -16,10 +16,10 @@ import React, { useMemo } from 'react'
* @param language The language of the code to use for highlighting
* @return The react elements that represent the highlighted code
*/
export const useCodeDom = (code: string, hljs: HLJSApi | undefined, language?: string): ReactElement[] | undefined => {
export const useCodeDom = (code: string, hljs: HLJSApi | undefined, language?: string): ReactElement[] | null => {
return useMemo(() => {
if (!hljs) {
return
return null
}
if (!!language && hljs.listLanguages().includes(language)) {
const highlightedHtml = hljs.highlight(code, { language }).value

View file

@ -20,7 +20,7 @@ export const useSendAdditionalConfigurationToRenderer = (rendererReady: boolean)
useSendToRenderer(
useMemo(() => {
return newlinesAreBreaks === undefined
? undefined
? null
: {
type: CommunicationMessageType.SET_ADDITIONAL_CONFIGURATION,
darkModePreference: darkModePreference,

View file

@ -15,13 +15,13 @@ import { useMemo, useRef } from 'react'
* @param scrollState The scroll state to send
* @param rendererReady Defines if the target renderer is ready
*/
export const useSendScrollState = (scrollState: ScrollState | undefined, rendererReady: boolean): void => {
export const useSendScrollState = (scrollState: ScrollState | null, rendererReady: boolean): void => {
const oldScrollState = useRef<ScrollState | undefined>(undefined)
useSendToRenderer(
useMemo(() => {
if (!scrollState || equal(scrollState, oldScrollState.current)) {
return
return null
}
oldScrollState.current = scrollState
return { type: CommunicationMessageType.SET_SCROLL_STATE, scrollState }

View file

@ -112,7 +112,7 @@ export const RendererIframe: React.FC<RendererIframeProps> = ({
CommunicationMessageType.EXTENSION_EVENT,
useMemo(() => {
return eventEmitter === undefined
? undefined
? null
: (values: ExtensionEvent) => eventEmitter.emit(values.eventName, values.payload)
}, [eventEmitter])
)
@ -159,7 +159,7 @@ export const RendererIframe: React.FC<RendererIframeProps> = ({
useSendAdditionalConfigurationToRenderer(rendererReady)
useSendMarkdownToRenderer(markdownContentLines, rendererReady)
useSendScrollState(scrollState, rendererReady)
useSendScrollState(scrollState ?? null, rendererReady)
useEditorReceiveHandler(
CommunicationMessageType.SET_SCROLL_STATE,
useCallback((values: SetScrollStateMessage) => onScroll?.(values.scrollState), [onScroll])

View file

@ -40,9 +40,7 @@ export const changeEditorContent = (view: EditorView, formatter: ContentFormatte
export const useChangeEditorContentCallback = () => {
const [codeMirrorRef] = useCodemirrorReferenceContext()
return useMemo(() => {
if (codeMirrorRef) {
return (callback: ContentFormatter) => changeEditorContent(codeMirrorRef, callback)
}
return !codeMirrorRef ? null : (callback: ContentFormatter) => changeEditorContent(codeMirrorRef, callback)
}, [codeMirrorRef])
}

View file

@ -59,14 +59,14 @@ export type EditorPaneProps = ScrollProps
*/
export const EditorPane: React.FC<EditorPaneProps> = ({ scrollState, onScroll, onMakeScrollSource }) => {
const { dispatchUiNotification } = useUiNotifications()
useApplyScrollState(scrollState)
useApplyScrollState(scrollState ?? null)
const messageTransporter = useRealtimeConnection()
useDisconnectOnUserLoginStatusChange(messageTransporter)
const realtimeDoc = useRealtimeDoc()
const editorScrollExtension = useCodeMirrorScrollWatchExtension(onScroll)
const editorScrollExtension = useCodeMirrorScrollWatchExtension(onScroll ?? null)
const tablePasteExtensions = useCodeMirrorTablePasteExtension()
const fileInsertExtension = useCodeMirrorFileInsertExtension()
const spellCheckExtension = useCodeMirrorSpellCheckExtension()

View file

@ -35,7 +35,7 @@ export const extractScrollState = (view: EditorView): ScrollState => {
* @param onScroll The callback that is used to post {@link ScrollState scroll states} when the editor view is scrolling.
* @return The extensions that watches the scrolling in the editor.
*/
export const useCodeMirrorScrollWatchExtension = (onScroll: OnScrollCallback): Extension => {
export const useCodeMirrorScrollWatchExtension = (onScroll: OnScrollCallback | null): Extension => {
const onEditorScroll = useCallback(
(view: EditorView) => {
if (!onScroll || !view) {

View file

@ -35,7 +35,7 @@ const applyScrollState = (view: EditorView, scrollState: ScrollState): void => {
*
* @param scrollState The scroll state that should be monitored
*/
export const useApplyScrollState = (scrollState?: ScrollState): void => {
export const useApplyScrollState = (scrollState: ScrollState | null): void => {
const lastScrollPosition = useRef<ScrollState>()
const [codeMirrorRef] = useCodemirrorReferenceContext()

View file

@ -23,13 +23,13 @@ const calculateLineBasedPosition = (absolutePosition: number, lineStartIndexes:
/**
* Returns the line+character based position of the to-cursor, if available.
*/
export const useLineBasedToPosition = (): LineBasedPosition | undefined => {
export const useLineBasedToPosition = (): LineBasedPosition | null => {
const lineStartIndexes = useApplicationState((state) => state.noteDetails?.markdownContent.lineStartIndexes ?? [])
const selectionTo = useApplicationState((state) => state.noteDetails?.selection.to)
return useMemo(() => {
if (selectionTo === undefined) {
return undefined
return null
}
return calculateLineBasedPosition(selectionTo, lineStartIndexes)
}, [selectionTo, lineStartIndexes])

View file

@ -13,7 +13,7 @@ const LOCAL_FALLBACK_URL = 'ws://localhost:8080/realtime/'
/**
* Provides the URL for the realtime endpoint.
*/
export const useWebsocketUrl = (): URL | undefined => {
export const useWebsocketUrl = (): URL | null => {
const noteId = useApplicationState((state) => state.noteDetails?.id)
const baseUrl = useBaseUrl()
@ -34,7 +34,7 @@ export const useWebsocketUrl = (): URL | undefined => {
return useMemo(() => {
if (noteId === '' || noteId === undefined) {
return
return null
}
const url = new URL(websocketUrl)
url.search = `?noteId=${noteId}`

View file

@ -16,7 +16,7 @@ export const SelectedCharacters: React.FC = () => {
const selection = useApplicationState((state) => state.noteDetails?.selection)
const count = useMemo(
() => (selection === undefined || selection.to === undefined ? undefined : selection.to - selection.from),
() => (selection === undefined || selection.to === undefined ? null : selection.to - selection.from),
[selection]
)
const countTranslationOptions = useMemo(() => ({ count }), [count])

View file

@ -20,7 +20,7 @@ export const TableSizeText: React.FC<TableSizeProps> = ({ tableSize }) => {
useTranslation()
const translationValues = useMemo(() => {
return tableSize ? { cols: tableSize.columns, rows: tableSize.rows } : undefined
return tableSize ? { cols: tableSize.columns, rows: tableSize.rows } : null
}, [tableSize])
if (!translationValues) {

View file

@ -13,15 +13,15 @@ import { useMemo } from 'react'
* @param onScroll The callback that posts a scroll state
* @return the modified callback that posts the same scroll state but with line offset
*/
export const useOnScrollWithLineOffset = (onScroll: ScrollCallback | undefined): ScrollCallback | undefined => {
export const useOnScrollWithLineOffset = (onScroll: ScrollCallback | null): ScrollCallback | null => {
return useMemo(() => {
if (onScroll === undefined) {
return undefined
if (onScroll === null) {
return null
} else {
return (scrollState: ScrollState) => {
const noteDetails = getGlobalState().noteDetails
if (noteDetails === null) {
return undefined
return null
}
onScroll({
firstLineInView: scrollState.firstLineInView + noteDetails.startOfContentLineOffset,

View file

@ -13,11 +13,11 @@ import { useMemo } from 'react'
* @param scrollState The original scroll state with the line offset
* @return the adjusted scroll state without the line offset
*/
export const useScrollStateWithoutLineOffset = (scrollState: ScrollState | undefined): ScrollState | undefined => {
export const useScrollStateWithoutLineOffset = (scrollState: ScrollState | null): ScrollState | null => {
const lineOffset = useApplicationState((state) => state.noteDetails?.startOfContentLineOffset)
return useMemo(() => {
return scrollState === undefined || lineOffset === undefined
? undefined
return scrollState === null || lineOffset === undefined
? null
: {
firstLineInView: scrollState.firstLineInView - lineOffset,
scrolledPercentage: scrollState.scrolledPercentage

View file

@ -29,8 +29,8 @@ export type RendererPaneProps = Omit<
export const RendererPane: React.FC<RendererPaneProps> = ({ scrollState, onScroll, ...props }) => {
const trimmedContentLines = useTrimmedNoteMarkdownContentWithoutFrontmatter()
const noteType = useApplicationState((state) => state.noteDetails?.frontmatter.type)
const adjustedOnScroll = useOnScrollWithLineOffset(onScroll)
const adjustedScrollState = useScrollStateWithoutLineOffset(scrollState)
const adjustedOnScroll = useOnScrollWithLineOffset(onScroll ?? null)
const adjustedScrollState = useScrollStateWithoutLineOffset(scrollState ?? null)
if (!noteType) {
return null

View file

@ -18,7 +18,7 @@ export const NoteInfoLineCreatedAt: React.FC = () => {
useTranslation()
const noteCreateTime = useApplicationState((state) => state.noteDetails?.createdAt)
const noteCreateDateTime = useMemo(
() => (noteCreateTime === undefined ? undefined : DateTime.fromSeconds(noteCreateTime)),
() => (noteCreateTime === undefined ? null : DateTime.fromSeconds(noteCreateTime)),
[noteCreateTime]
)

View file

@ -18,7 +18,7 @@ export const NoteInfoLineUpdatedAt: React.FC = () => {
useTranslation()
const noteUpdateTime = useApplicationState((state) => state.noteDetails?.updatedAt)
const noteUpdateDateTime = useMemo(
() => (noteUpdateTime === undefined ? undefined : DateTime.fromSeconds(noteUpdateTime)),
() => (noteUpdateTime === undefined ? null : DateTime.fromSeconds(noteUpdateTime)),
[noteUpdateTime]
)

View file

@ -40,8 +40,8 @@ export const PermissionEntryUser: React.FC<PermissionEntryUserProps & Permission
const permissionInconsistent = useMemo(
() =>
(everyonePermission && everyonePermission.canEdit && !entry.canEdit) ||
(loggedInPermission && loggedInPermission.canEdit && !entry.canEdit),
(!!everyonePermission && everyonePermission.canEdit && !entry.canEdit) ||
(!!loggedInPermission && loggedInPermission.canEdit && !entry.canEdit),
[everyonePermission, loggedInPermission, entry]
)

View file

@ -28,7 +28,7 @@ export const NoteUrlField: React.FC<LinkFieldProps> = ({ type }) => {
const url = useMemo(() => {
if (noteId === undefined) {
return undefined
return null
}
const url = new URL(baseUrl)
url.pathname += `${type}/${noteId}`

View file

@ -7,8 +7,8 @@
export type ScrollCallback = (scrollState: ScrollState) => void
export interface ScrollProps {
scrollState?: ScrollState
onScroll?: ScrollCallback
scrollState?: ScrollState | null
onScroll?: ScrollCallback | null
onMakeScrollSource?: () => void
}

View file

@ -30,7 +30,7 @@ export const MotdModal: React.FC = () => {
const { error, loading, value } = useAsync(fetchMotd)
const [dismissed, setDismissed] = useState(false)
const lines = useMemo(() => value?.motdText.split('\n'), [value?.motdText])
const lines = useMemo(() => value?.motdText.split('\n') ?? [], [value?.motdText])
const dismiss = useCallback(() => {
if (value?.lastModified) {
@ -51,7 +51,7 @@ export const MotdModal: React.FC = () => {
return (
<CommonModal
show={!!lines && !loading && !error && !dismissed}
show={lines.length > 0 && !loading && !error && !dismissed}
titleI18nKey={'motd.title'}
{...cypressId('motd-modal')}>
<Modal.Body>
@ -59,7 +59,7 @@ export const MotdModal: React.FC = () => {
<RendererIframe
frameClasses={'w-100'}
rendererType={RendererType.SIMPLE}
markdownContentLines={lines as string[]}
markdownContentLines={lines}
adaptFrameHeightToContent={true}
showWaitSpinner={true}
/>

View file

@ -17,7 +17,7 @@ interface LanguageOptionProps {
*/
export const LanguageOption: React.FC<LanguageOptionProps> = ({ languageCode }) => {
const displayName = useMemo(
() => new Intl.DisplayNames([languageCode], { type: 'language' }).of(languageCode),
() => new Intl.DisplayNames([languageCode], { type: 'language' }).of(languageCode) ?? null,
[languageCode]
)

View file

@ -41,12 +41,14 @@ export const MarkdownToReact: React.FC<MarkdownToReactProps> = ({
useMemo(() => {
nodeToReactTransformer.setReplacers(markdownRenderExtensions.flatMap((extension) => extension.buildReplacers()))
return null //todo: replace usememo hack
}, [nodeToReactTransformer, markdownRenderExtensions])
useMemo(() => {
measurePerformance('markdown-to-react: update-line-mapping', () => {
nodeToReactTransformer.setLineIds(lineNumberMapper.updateLineMapping(markdownContentLines))
})
return null
}, [nodeToReactTransformer, lineNumberMapper, markdownContentLines])
const nodePreProcessor = useCombinedNodePreprocessor(markdownRenderExtensions)

View file

@ -17,7 +17,7 @@ export const RegisterError: React.FC<RegisterErrorProps> = ({ error }) => {
const errorI18nKey = useMemo(() => {
if (!error) {
return undefined
return null
}
return new ErrorToI18nKeyMapper(error, 'login.register.error')
.withHttpCode(409, 'usernameExisting')
@ -28,7 +28,7 @@ export const RegisterError: React.FC<RegisterErrorProps> = ({ error }) => {
return (
<Alert className='small' show={!!errorI18nKey} variant='danger'>
<Trans i18nKey={errorI18nKey} />
<Trans i18nKey={errorI18nKey ?? ''} />
</Alert>
)
}

View file

@ -26,10 +26,10 @@ export const useDocumentSyncScrolling = (
outerContainerRef: React.RefObject<HTMLElement>,
rendererRef: React.RefObject<HTMLElement>,
numberOfLines: number,
scrollState?: ScrollState,
onScroll?: (scrollState: ScrollState) => void
scrollState: ScrollState | null,
onScroll: null | ((scrollState: ScrollState) => void)
): [(lineMarkers: LineMarkerPosition[]) => void, React.UIEventHandler<HTMLElement>] => {
const [lineMarks, setLineMarks] = useState<LineMarkerPosition[]>()
const [lineMarks, setLineMarks] = useState<LineMarkerPosition[]>([])
const recalculateLineMarkerPositions = useCallback(
(linkMarkerPositions: LineMarkerPosition[]) => {

View file

@ -19,7 +19,7 @@ import { useCallback } from 'react'
export const useOnUserScroll = (
lineMarks: LineMarkerPosition[] | undefined,
scrollContainer: React.RefObject<HTMLElement>,
onScroll: ((newScrollState: ScrollState) => void) | undefined
onScroll: ((newScrollState: ScrollState) => void) | null
): React.UIEventHandler<HTMLElement> => {
return useCallback(() => {
if (!scrollContainer.current || !lineMarks || lineMarks.length === 0 || !onScroll) {

View file

@ -18,8 +18,8 @@ import { useCallback, useEffect, useRef } from 'react'
* @param scrollContainer The container to scroll in
*/
export const useScrollToLineMark = (
scrollState: ScrollState | undefined,
lineMarks: LineMarkerPosition[] | undefined,
scrollState: ScrollState | null,
lineMarks: LineMarkerPosition[],
contentLineCount: number,
scrollContainer: RefObject<HTMLElement>
): void => {

View file

@ -57,8 +57,8 @@ export const DocumentMarkdownRenderer: React.FC<DocumentMarkdownRendererProps> =
internalDocumentRenderPaneRef,
rendererRef,
contentLineCount,
scrollState,
onScroll
scrollState ?? null,
onScroll ?? null
)
const markdownBodyRef = useRef<HTMLDivElement>(null)

View file

@ -16,7 +16,7 @@ import { useEffect } from 'react'
*/
export const useEditorReceiveHandler = <R extends RendererToEditorMessageType>(
messageType: R,
handler?: Handler<CommunicationMessages, R>
handler: Handler<CommunicationMessages, R> | null
): void => {
const editorToRendererCommunicator = useEditorToRendererCommunicator()
useEffect(() => {

View file

@ -15,7 +15,7 @@ import { useEffect } from 'react'
* @param rendererReady Defines if the target renderer is ready
*/
export const useSendToRenderer = (
message: undefined | Extract<CommunicationMessages, MessagePayload<EditorToRendererMessageType>>,
message: null | Extract<CommunicationMessages, MessagePayload<EditorToRendererMessageType>>,
rendererReady: boolean
): void => {
const iframeCommunicator = useEditorToRendererCommunicator()

View file

@ -27,7 +27,7 @@ export const SlideShowPageContent: React.FC = () => {
useSendToRenderer(
useMemo(() => {
return !slideOptions
? undefined
? null
: {
type: CommunicationMessageType.SET_SLIDE_OPTIONS,
slideOptions

View file

@ -38,7 +38,7 @@ export const CsvTable: React.FC<CsvTableProps> = ({
}, [code, delimiter, showHeader])
const renderTableHeader = useMemo(() => {
return headerRow.length === 0 ? undefined : (
return headerRow.length === 0 ? null : (
<thead>
<tr>
{headerRow.map((column, columnNumber) => (

View file

@ -16,7 +16,6 @@ import { useMemo } from 'react'
export const useSingleStringUrlParameter = <T>(parameter: string, fallback: T): string | T => {
const router = useSearchParams()
return useMemo(() => {
return router?.get(parameter) ?? fallback
}, [fallback, parameter, router])
const value = useMemo(() => router?.get(parameter) ?? null, [parameter, router])
return value ?? fallback
}

View file

@ -29,7 +29,7 @@ export const useTrimmedNoteMarkdownContentWithoutFrontmatter = (): string[] => {
const trimmedLines = useMemo(() => {
if (!markdownContent) {
return undefined
return null
}
if (markdownContent.content.length > maxLength) {
return markdownContent.content.slice(0, maxLength).split('\n')
@ -39,6 +39,6 @@ export const useTrimmedNoteMarkdownContentWithoutFrontmatter = (): string[] => {
}, [markdownContent, maxLength])
return useMemo(() => {
return trimmedLines === undefined || lineOffset === undefined ? [] : trimmedLines.slice(lineOffset)
return trimmedLines === null || lineOffset === undefined ? [] : trimmedLines.slice(lineOffset)
}, [lineOffset, trimmedLines])
}