refactor: migrate remaining angular components to react (#833)

* refactor: menuRow directive to MenuRow component

* refactor: migrate footer to react

* refactor: migrate actions menu to react

* refactor: migrate history menu to react

* fix: click outside handler use capture to trigger event before re-render occurs which would otherwise cause node.contains to return incorrect result (specifically for the account menu)

* refactor: migrate revision preview modal to react

* refactor: migrate permissions modal to react

* refactor: migrate password wizard to react

* refactor: remove unused input modal directive

* refactor: remove unused delay hide component

* refactor: remove unused filechange directive

* refactor: remove unused elemReady directive

* refactor: remove unused sn-enter directive

* refactor: remove unused lowercase directive

* refactor: remove unused autofocus directive

* refactor(wip): note view to react

* refactor: use mutation observer to deinit textarea listeners

* refactor: migrate challenge modal to react

* refactor: migrate note group view to react

* refactor(wip): migrate remaining classes

* fix: navigation parent ref

* refactor: fully remove angular assets

* fix: account switcher

* fix: application view state

* refactor: remove unused password wizard type

* fix: revision preview and permissions modal

* fix: remove angular comment

* refactor: react panel resizers for editor

* feat: simple panel resizer

* fix: use simple panel resizer everywhere

* fix: simplify panel resizer state

* chore: rename simple panel resizer to panel resizer

* refactor: simplify column layout

* fix: editor mount safety check

* fix: use inline onLoad callback for iframe, as setting onload after it loads will never call it

* chore: fix note view test

* chore(deps): upgrade snjs
This commit is contained in:
Mo
2022-01-30 19:01:30 -06:00
committed by GitHub
parent 0ecbde6bac
commit 50c92619ce
117 changed files with 4715 additions and 5309 deletions

View File

@@ -9,8 +9,13 @@ import {
} from '@standardnotes/snjs';
import { WebApplication } from '@/ui_models/application';
import { FunctionalComponent } from 'preact';
import { toDirective } from '@/components/utils';
import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
import {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'preact/hooks';
import { observer } from 'mobx-react-lite';
import { OfflineRestricted } from '@/components/ComponentView/OfflineRestricted';
import { UrlMissing } from '@/components/ComponentView/UrlMissing';
@@ -66,20 +71,6 @@ export const ComponentView: FunctionalComponent<IProps> = observer(
openSubscriptionDashboard(application);
}, [application]);
useEffect(() => {
const loadTimeout = setTimeout(() => {
handleIframeTakingTooLongToLoad();
}, MaxLoadThreshold);
excessiveLoadingTimeout.current = loadTimeout;
return () => {
excessiveLoadingTimeout.current &&
clearTimeout(excessiveLoadingTimeout.current);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const reloadValidityStatus = useCallback(() => {
setFeatureStatus(componentViewer.getFeatureStatus());
if (!componentViewer.lockReadonly) {
@@ -128,28 +119,35 @@ export const ComponentView: FunctionalComponent<IProps> = observer(
} else {
document.addEventListener(VisibilityChangeKey, onVisibilityChange);
}
}, [componentViewer, didAttemptReload, onVisibilityChange, requestReload]);
}, [didAttemptReload, onVisibilityChange, componentViewer, requestReload]);
useEffect(() => {
if (!iframeRef.current) {
return;
}
useMemo(() => {
const loadTimeout = setTimeout(() => {
handleIframeTakingTooLongToLoad();
}, MaxLoadThreshold);
const iframe = iframeRef.current as HTMLIFrameElement;
iframe.onload = () => {
const contentWindow = iframe.contentWindow as Window;
excessiveLoadingTimeout.current = loadTimeout;
return () => {
excessiveLoadingTimeout.current &&
clearTimeout(excessiveLoadingTimeout.current);
componentViewer.setWindow(contentWindow);
setTimeout(() => {
setIsLoading(false);
setHasIssueLoading(false);
onLoad?.(component);
}, MSToWaitAfterIframeLoadToAvoidFlicker);
};
}, [onLoad, component, componentViewer]);
}, [handleIframeTakingTooLongToLoad]);
const onIframeLoad = useCallback(() => {
const iframe = iframeRef.current as HTMLIFrameElement;
const contentWindow = iframe.contentWindow as Window;
excessiveLoadingTimeout.current &&
clearTimeout(excessiveLoadingTimeout.current);
componentViewer.setWindow(contentWindow);
setTimeout(() => {
setIsLoading(false);
setHasIssueLoading(false);
onLoad?.(component);
}, MSToWaitAfterIframeLoadToAvoidFlicker);
}, [componentViewer, onLoad, component, excessiveLoadingTimeout]);
useEffect(() => {
const removeFeaturesChangedObserver = componentViewer.addEventObserver(
@@ -236,6 +234,7 @@ export const ComponentView: FunctionalComponent<IProps> = observer(
{component.uuid && isComponentValid && (
<iframe
ref={iframeRef}
onLoad={onIframeLoad}
data-component-viewer-id={componentViewer.identifier}
frameBorder={0}
src={componentViewer.url || ''}
@@ -249,10 +248,3 @@ export const ComponentView: FunctionalComponent<IProps> = observer(
);
}
);
export const ComponentViewDirective = toDirective<IProps>(ComponentView, {
onLoad: '=',
componentViewer: '=',
requestReload: '=',
manualDealloc: '=',
});