refactor: component viewer use state for timeout so timeout isnt set if no render eventually occurs
This commit is contained in:
@@ -54,10 +54,6 @@ export abstract class PureComponent<P = PureComponentProps, S = PureComponentSta
|
||||
this.deinit()
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>Must override</div>
|
||||
}
|
||||
|
||||
public get appState(): AppState {
|
||||
return this.application.getAppState()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from '@standardnotes/snjs'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { FunctionalComponent } from 'preact'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks'
|
||||
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { OfflineRestricted } from '@/Components/ComponentView/OfflineRestricted'
|
||||
import { UrlMissing } from '@/Components/ComponentView/UrlMissing'
|
||||
@@ -25,7 +25,6 @@ interface IProps {
|
||||
componentViewer: ComponentViewer
|
||||
requestReload?: (viewer: ComponentViewer, force?: boolean) => void
|
||||
onLoad?: (component: SNComponent) => void
|
||||
manualDealloc?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +38,7 @@ const MSToWaitAfterIframeLoadToAvoidFlicker = 35
|
||||
export const ComponentView: FunctionalComponent<IProps> = observer(
|
||||
({ application, onLoad, componentViewer, requestReload }) => {
|
||||
const iframeRef = useRef<HTMLIFrameElement>(null)
|
||||
const excessiveLoadingTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
|
||||
const [loadTimeout, setLoadTimeout] = useState<ReturnType<typeof setTimeout> | undefined>(undefined)
|
||||
|
||||
const [hasIssueLoading, setHasIssueLoading] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
@@ -88,34 +87,36 @@ export const ComponentView: FunctionalComponent<IProps> = observer(
|
||||
}
|
||||
}, [hasIssueLoading, componentViewer, requestReload])
|
||||
|
||||
const handleIframeTakingTooLongToLoad = useCallback(async () => {
|
||||
setIsLoading(false)
|
||||
setHasIssueLoading(true)
|
||||
|
||||
if (!didAttemptReload) {
|
||||
setDidAttemptReload(true)
|
||||
requestReload?.(componentViewer)
|
||||
} else {
|
||||
document.addEventListener(VisibilityChangeKey, onVisibilityChange)
|
||||
}
|
||||
}, [didAttemptReload, onVisibilityChange, componentViewer, requestReload])
|
||||
|
||||
useMemo(() => {
|
||||
useEffect(() => {
|
||||
const loadTimeout = setTimeout(() => {
|
||||
handleIframeTakingTooLongToLoad().catch(console.error)
|
||||
setIsLoading(false)
|
||||
setHasIssueLoading(true)
|
||||
|
||||
if (!didAttemptReload) {
|
||||
setDidAttemptReload(true)
|
||||
requestReload?.(componentViewer)
|
||||
} else {
|
||||
document.addEventListener(VisibilityChangeKey, onVisibilityChange)
|
||||
}
|
||||
}, MaxLoadThreshold)
|
||||
|
||||
excessiveLoadingTimeout.current = loadTimeout
|
||||
setLoadTimeout(loadTimeout)
|
||||
|
||||
return () => {
|
||||
excessiveLoadingTimeout.current && clearTimeout(excessiveLoadingTimeout.current)
|
||||
if (loadTimeout) {
|
||||
clearTimeout(loadTimeout)
|
||||
}
|
||||
}
|
||||
}, [handleIframeTakingTooLongToLoad])
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [componentViewer])
|
||||
|
||||
const onIframeLoad = useCallback(() => {
|
||||
const iframe = iframeRef.current as HTMLIFrameElement
|
||||
const contentWindow = iframe.contentWindow as Window
|
||||
excessiveLoadingTimeout.current && clearTimeout(excessiveLoadingTimeout.current)
|
||||
|
||||
if (loadTimeout) {
|
||||
clearTimeout(loadTimeout)
|
||||
}
|
||||
|
||||
try {
|
||||
componentViewer.setWindow(contentWindow)
|
||||
@@ -128,7 +129,7 @@ export const ComponentView: FunctionalComponent<IProps> = observer(
|
||||
setHasIssueLoading(false)
|
||||
onLoad?.(component)
|
||||
}, MSToWaitAfterIframeLoadToAvoidFlicker)
|
||||
}, [componentViewer, onLoad, component, excessiveLoadingTimeout])
|
||||
}, [componentViewer, onLoad, component, loadTimeout])
|
||||
|
||||
useEffect(() => {
|
||||
const removeFeaturesChangedObserver = componentViewer.addEventObserver((event) => {
|
||||
|
||||
@@ -264,21 +264,26 @@ export class NoteView extends PureComponent<Props, State> {
|
||||
|
||||
let title = this.state.editorTitle,
|
||||
text = this.state.editorText
|
||||
|
||||
if (isPayloadSourceRetrieved(source)) {
|
||||
title = note.title
|
||||
text = note.text
|
||||
}
|
||||
|
||||
if (!this.state.editorTitle) {
|
||||
title = note.title
|
||||
}
|
||||
|
||||
if (!this.state.editorText) {
|
||||
text = note.text
|
||||
}
|
||||
|
||||
if (title !== this.state.editorTitle) {
|
||||
this.setState({
|
||||
editorTitle: title,
|
||||
})
|
||||
}
|
||||
|
||||
if (text !== this.state.editorText) {
|
||||
this.setState({
|
||||
editorText: text,
|
||||
@@ -317,6 +322,7 @@ export class NoteView extends PureComponent<Props, State> {
|
||||
if (this.state.editorComponentViewer) {
|
||||
this.application.componentManager?.destroyComponentViewer(this.state.editorComponentViewer)
|
||||
}
|
||||
|
||||
super.componentWillUnmount()
|
||||
}
|
||||
|
||||
@@ -401,12 +407,15 @@ export class NoteView extends PureComponent<Props, State> {
|
||||
|
||||
dismissProtectedWarning = async () => {
|
||||
let showNoteContents = true
|
||||
|
||||
if (this.application.hasProtectionSources()) {
|
||||
showNoteContents = await this.application.authorizeNoteAccess(this.note)
|
||||
}
|
||||
|
||||
if (!showNoteContents) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setShowProtectedOverlay(false)
|
||||
this.focusTitle()
|
||||
}
|
||||
@@ -1021,6 +1030,7 @@ export class NoteView extends PureComponent<Props, State> {
|
||||
{this.state.editorComponentViewer && (
|
||||
<div className="component-view">
|
||||
<ComponentView
|
||||
key={this.state.editorComponentViewer.identifier}
|
||||
componentViewer={this.state.editorComponentViewer}
|
||||
onLoad={this.onEditorComponentLoad}
|
||||
requestReload={this.editorComponentViewerRequestsReload}
|
||||
@@ -1099,7 +1109,6 @@ export class NoteView extends PureComponent<Props, State> {
|
||||
<ComponentView
|
||||
key={viewer.identifier}
|
||||
componentViewer={viewer}
|
||||
manualDealloc={true}
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user