refactor: format and lint codebase (#971)

This commit is contained in:
Aman Harwara
2022-04-13 22:02:34 +05:30
committed by GitHub
parent dc9c1ea0fc
commit 8e467f9e6d
367 changed files with 13778 additions and 16093 deletions

View File

@@ -0,0 +1,30 @@
import { FunctionalComponent } from 'preact'
interface IProps {
deprecationMessage: string | undefined
dismissDeprecationMessage: () => void
}
export const IsDeprecated: FunctionalComponent<IProps> = ({
deprecationMessage,
dismissDeprecationMessage,
}) => {
return (
<div className={'sn-component'}>
<div className={'sk-app-bar no-edges no-top-edge dynamic-height'}>
<div className={'left'}>
<div className={'sk-app-bar-item'}>
<div className={'sk-label warning'}>
{deprecationMessage || 'This extension is deprecated.'}
</div>
</div>
</div>
<div className={'right'}>
<div className={'sk-app-bar-item'} onClick={dismissDeprecationMessage}>
<button className={'sn-button small info'}>Dismiss</button>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,54 @@
import { FeatureStatus } from '@standardnotes/snjs'
import { FunctionalComponent } from 'preact'
interface IProps {
expiredDate: string
componentName: string
featureStatus: FeatureStatus
manageSubscription: () => void
}
const statusString = (featureStatus: FeatureStatus, expiredDate: string, componentName: string) => {
switch (featureStatus) {
case FeatureStatus.InCurrentPlanButExpired:
return `Your subscription expired on ${expiredDate}`
case FeatureStatus.NoUserSubscription:
return 'You do not have an active subscription'
case FeatureStatus.NotInCurrentPlan:
return `Please upgrade your plan to access ${componentName}`
default:
return `${componentName} is valid and you should not be seeing this message`
}
}
export const IsExpired: FunctionalComponent<IProps> = ({
expiredDate,
featureStatus,
componentName,
manageSubscription,
}) => {
return (
<div className={'sn-component'}>
<div className={'sk-app-bar no-edges no-top-edge dynamic-height'}>
<div className={'left'}>
<div className={'sk-app-bar-item'}>
<div className={'sk-app-bar-item-column'}>
<div className={'sk-circle danger small'} />
</div>
<div className={'sk-app-bar-item-column'}>
<div>
<strong>{statusString(featureStatus, expiredDate, componentName)}</strong>
<div className={'sk-p'}>{componentName} is in a read-only state.</div>
</div>
</div>
</div>
</div>
<div className={'right'}>
<div className={'sk-app-bar-item'} onClick={() => manageSubscription()}>
<button className={'sn-button small success'}>Manage Subscription</button>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,25 @@
import { FunctionalComponent } from 'preact'
interface IProps {
componentName: string
reloadIframe: () => void
}
export const IssueOnLoading: FunctionalComponent<IProps> = ({ componentName, reloadIframe }) => {
return (
<div className={'sn-component'}>
<div className={'sk-app-bar no-edges no-top-edge dynamic-height'}>
<div className={'left'}>
<div className={'sk-app-bar-item'}>
<div className={'sk-label.warning'}>There was an issue loading {componentName}.</div>
</div>
</div>
<div className={'right'}>
<div className={'sk-app-bar-item'} onClick={reloadIframe}>
<button className={'sn-button small info'}>Reload</button>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,35 @@
import { FunctionalComponent } from 'preact'
export const OfflineRestricted: FunctionalComponent = () => {
return (
<div className={'sn-component'}>
<div className={'sk-panel static'}>
<div className={'sk-panel-content'}>
<div className={'sk-panel-section stretch'}>
<div className={'sk-panel-column'} />
<div className={'sk-h1 sk-bold'}>
You have restricted this component to not use a hosted version.
</div>
<div className={'sk-subtitle'}>
Locally-installed components are not available in the web application.
</div>
<div className={'sk-panel-row'} />
<div className={'sk-panel-row'}>
<div className={'sk-panel-column'}>
<div className={'sk-p'}>To continue, choose from the following options:</div>
<ul>
<li className={'sk-p'}>
Enable the Hosted option for this component by opening the Preferences {'>'}{' '}
General {'>'} Advanced Settings menu and toggling 'Use hosted when local is
unavailable' under this component's options. Then press Reload.
</li>
<li className={'sk-p'}>Use the desktop application.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,27 @@
import { FunctionalComponent } from 'preact'
interface IProps {
componentName: string
}
export const UrlMissing: FunctionalComponent<IProps> = ({ componentName }) => {
return (
<div className={'sn-component'}>
<div className={'sk-panel static'}>
<div className={'sk-panel-content'}>
<div className={'sk-panel-section stretch'}>
<div className={'sk-panel-section-title'}>
This extension is missing its URL property.
</div>
<p>
In order to access your note immediately, please switch from {componentName} to the
Plain Editor.
</p>
<br />
<p>Please contact help@standardnotes.com to remedy this issue.</p>
</div>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,221 @@
import {
ComponentAction,
FeatureStatus,
SNComponent,
dateToLocalizedString,
ComponentViewer,
ComponentViewerEvent,
ComponentViewerError,
} from '@standardnotes/snjs'
import { WebApplication } from '@/UIModels/Application'
import { FunctionalComponent } from 'preact'
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'
import { IsDeprecated } from '@/Components/ComponentView/IsDeprecated'
import { IsExpired } from '@/Components/ComponentView/IsExpired'
import { IssueOnLoading } from '@/Components/ComponentView/IssueOnLoading'
import { AppState } from '@/UIModels/AppState'
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
interface IProps {
application: WebApplication
appState: AppState
componentViewer: ComponentViewer
requestReload?: (viewer: ComponentViewer, force?: boolean) => void
onLoad?: (component: SNComponent) => void
manualDealloc?: boolean
}
/**
* The maximum amount of time we'll wait for a component
* to load before displaying error
*/
const MaxLoadThreshold = 4000
const VisibilityChangeKey = 'visibilitychange'
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 [hasIssueLoading, setHasIssueLoading] = useState(false)
const [isLoading, setIsLoading] = useState(true)
const [featureStatus, setFeatureStatus] = useState<FeatureStatus>(
componentViewer.getFeatureStatus(),
)
const [isComponentValid, setIsComponentValid] = useState(true)
const [error, setError] = useState<ComponentViewerError | undefined>(undefined)
const [deprecationMessage, setDeprecationMessage] = useState<string | undefined>(undefined)
const [isDeprecationMessageDismissed, setIsDeprecationMessageDismissed] = useState(false)
const [didAttemptReload, setDidAttemptReload] = useState(false)
const component = componentViewer.component
const manageSubscription = useCallback(() => {
openSubscriptionDashboard(application)
}, [application])
const reloadValidityStatus = useCallback(() => {
setFeatureStatus(componentViewer.getFeatureStatus())
if (!componentViewer.lockReadonly) {
componentViewer.setReadonly(featureStatus !== FeatureStatus.Entitled)
}
setIsComponentValid(componentViewer.shouldRender())
if (isLoading && !isComponentValid) {
setIsLoading(false)
}
setError(componentViewer.getError())
setDeprecationMessage(component.deprecationMessage)
}, [componentViewer, component.deprecationMessage, featureStatus, isComponentValid, isLoading])
useEffect(() => {
reloadValidityStatus()
}, [reloadValidityStatus])
const dismissDeprecationMessage = () => {
setIsDeprecationMessageDismissed(true)
}
const onVisibilityChange = useCallback(() => {
if (document.visibilityState === 'hidden') {
return
}
if (hasIssueLoading) {
requestReload?.(componentViewer)
}
}, [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(() => {
const loadTimeout = setTimeout(() => {
handleIframeTakingTooLongToLoad().catch(console.error)
}, MaxLoadThreshold)
excessiveLoadingTimeout.current = loadTimeout
return () => {
excessiveLoadingTimeout.current && clearTimeout(excessiveLoadingTimeout.current)
}
}, [handleIframeTakingTooLongToLoad])
const onIframeLoad = useCallback(() => {
const iframe = iframeRef.current as HTMLIFrameElement
const contentWindow = iframe.contentWindow as Window
excessiveLoadingTimeout.current && clearTimeout(excessiveLoadingTimeout.current)
componentViewer.setWindow(contentWindow).catch(console.error)
setTimeout(() => {
setIsLoading(false)
setHasIssueLoading(false)
onLoad?.(component)
}, MSToWaitAfterIframeLoadToAvoidFlicker)
}, [componentViewer, onLoad, component, excessiveLoadingTimeout])
useEffect(() => {
const removeFeaturesChangedObserver = componentViewer.addEventObserver((event) => {
if (event === ComponentViewerEvent.FeatureStatusUpdated) {
setFeatureStatus(componentViewer.getFeatureStatus())
}
})
return () => {
removeFeaturesChangedObserver()
}
}, [componentViewer])
useEffect(() => {
const removeActionObserver = componentViewer.addActionObserver((action, data) => {
switch (action) {
case ComponentAction.KeyDown:
application.io.handleComponentKeyDown(data.keyboardModifier)
break
case ComponentAction.KeyUp:
application.io.handleComponentKeyUp(data.keyboardModifier)
break
case ComponentAction.Click:
application.getAppState().notes.setContextMenuOpen(false)
break
default:
return
}
})
return () => {
removeActionObserver()
}
}, [componentViewer, application])
useEffect(() => {
const unregisterDesktopObserver = application
.getDesktopService()
.registerUpdateObserver((updatedComponent: SNComponent) => {
if (updatedComponent.uuid === component.uuid && updatedComponent.active) {
requestReload?.(componentViewer)
}
})
return () => {
unregisterDesktopObserver()
}
}, [application, requestReload, componentViewer, component.uuid])
return (
<>
{hasIssueLoading && (
<IssueOnLoading
componentName={component.name}
reloadIframe={() => {
reloadValidityStatus(), requestReload?.(componentViewer, true)
}}
/>
)}
{featureStatus !== FeatureStatus.Entitled && (
<IsExpired
expiredDate={dateToLocalizedString(component.valid_until)}
featureStatus={featureStatus}
componentName={component.name}
manageSubscription={manageSubscription}
/>
)}
{deprecationMessage && !isDeprecationMessageDismissed && (
<IsDeprecated
deprecationMessage={deprecationMessage}
dismissDeprecationMessage={dismissDeprecationMessage}
/>
)}
{error === ComponentViewerError.OfflineRestricted && <OfflineRestricted />}
{error === ComponentViewerError.MissingUrl && <UrlMissing componentName={component.name} />}
{component.uuid && isComponentValid && (
<iframe
ref={iframeRef}
onLoad={onIframeLoad}
data-component-viewer-id={componentViewer.identifier}
frameBorder={0}
src={componentViewer.url || ''}
sandbox="allow-scripts allow-top-navigation-by-user-activation allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-modals allow-forms allow-downloads"
>
Loading
</iframe>
)}
{isLoading && <div className={'loading-overlay'} />}
</>
)
},
)