fix: lazy load embedded files in super editor (#2043)

This commit is contained in:
Aman Harwara
2022-11-23 00:55:20 +05:30
committed by GitHub
parent 8c8f045b9a
commit 096d82f7af
4 changed files with 62 additions and 12 deletions

View File

@@ -6,7 +6,8 @@ import Spinner from '@/Components/Spinner/Spinner'
import FilePreviewError from './FilePreviewError' import FilePreviewError from './FilePreviewError'
import { isFileTypePreviewable } from './isFilePreviewable' import { isFileTypePreviewable } from './isFilePreviewable'
import PreviewComponent from './PreviewComponent' import PreviewComponent from './PreviewComponent'
import ProtectedItemOverlay from '../ProtectedItemOverlay/ProtectedItemOverlay' import Button from '../Button/Button'
import { ProtectedIllustration } from '@standardnotes/icons'
type Props = { type Props = {
application: WebApplication application: WebApplication
@@ -77,13 +78,28 @@ const FilePreview = ({ file, application }: Props) => {
}, [application.files, downloadedBytes, file, isFilePreviewable, isAuthorized]) }, [application.files, downloadedBytes, file, isFilePreviewable, isAuthorized])
if (!isAuthorized) { if (!isAuthorized) {
const hasProtectionSources = application.hasProtectionSources()
return ( return (
<ProtectedItemOverlay <div className="flex flex-grow flex-col items-center justify-center">
showAccountMenu={application.showAccountMenu} <ProtectedIllustration className="mb-4 h-30 w-30" />
itemType={'file'} <div className="mb-2 text-base font-bold">This file is protected.</div>
onViewItem={() => application.protections.authorizeItemAccess(file)} <p className="max-w-[35ch] text-center text-sm text-passive-0">
hasProtectionSources={application.hasProtectionSources()} {hasProtectionSources
/> ? 'Authenticate to view this file.'
: 'Add a passcode or create an account to require authentication to view this file.'}
</p>
<div className="mt-3 flex gap-3">
{!hasProtectionSources && (
<Button primary small onClick={() => application.showAccountMenu()}>
Open account menu
</Button>
)}
<Button primary onClick={() => application.protections.authorizeItemAccess(file)}>
{hasProtectionSources ? 'Authenticate' : 'View file'}
</Button>
</div>
</div>
) )
} }

View File

@@ -17,7 +17,7 @@ const FilePreviewError = ({ file, filesController, isFilePreviewable, tryAgainCa
<div className="mb-2 text-base font-bold">This file can't be previewed.</div> <div className="mb-2 text-base font-bold">This file can't be previewed.</div>
{isFilePreviewable ? ( {isFilePreviewable ? (
<> <>
<div className="max-w-35ch mb-4 text-center text-sm text-passive-0"> <div className="mb-4 max-w-[35ch] text-center text-sm text-passive-0">
There was an error loading the file. Try again, or download the file and open it using another application. There was an error loading the file. Try again, or download the file and open it using another application.
</div> </div>
<div className="flex items-center"> <div className="flex items-center">
@@ -41,7 +41,7 @@ const FilePreviewError = ({ file, filesController, isFilePreviewable, tryAgainCa
</> </>
) : ( ) : (
<> <>
<div className="max-w-35ch mb-4 text-center text-sm text-passive-0"> <div className="mb-4 max-w-[35ch] text-center text-sm text-passive-0">
To view this file, download it and open it using another application. To view this file, download it and open it using another application.
</div> </div>
<Button <Button

View File

@@ -953,7 +953,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
)} )}
{editorMode === 'super' && ( {editorMode === 'super' && (
<div className={classNames('blocks-editor w-full flex-grow overflow-hidden overflow-y-scroll')}> <div className={classNames('blocks-editor w-full flex-grow overflow-hidden overflow-y-auto')}>
<SuperEditor <SuperEditor
key={this.note.uuid} key={this.note.uuid}
application={this.application} application={this.application}

View File

@@ -1,5 +1,5 @@
import { BlockWithAlignableContents } from '@lexical/react/LexicalBlockWithAlignableContents' import { BlockWithAlignableContents } from '@lexical/react/LexicalBlockWithAlignableContents'
import { useMemo } from 'react' import { useEffect, useMemo, useRef, useState } from 'react'
import { ElementFormatType, NodeKey } from 'lexical' import { ElementFormatType, NodeKey } from 'lexical'
import { useApplication } from '@/Components/ApplicationView/ApplicationProvider' import { useApplication } from '@/Components/ApplicationView/ApplicationProvider'
import FilePreview from '@/Components/FilePreview/FilePreview' import FilePreview from '@/Components/FilePreview/FilePreview'
@@ -19,13 +19,47 @@ export function FileComponent({ className, format, nodeKey, fileUuid }: FileComp
const application = useApplication() const application = useApplication()
const file = useMemo(() => application.items.findItem<FileItem>(fileUuid), [application, fileUuid]) const file = useMemo(() => application.items.findItem<FileItem>(fileUuid), [application, fileUuid])
const [canLoad, setCanLoad] = useState(false)
const blockWrapperRef = useRef<HTMLDivElement>(null)
const blockObserver = useMemo(
() =>
new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setCanLoad(true)
}
})
},
{
threshold: 0.25,
},
),
[],
)
useEffect(() => {
const wrapper = blockWrapperRef.current
if (!wrapper) {
return
}
blockObserver.observe(wrapper)
return () => {
blockObserver.unobserve(wrapper)
}
}, [blockObserver])
if (!file) { if (!file) {
return <div>Unable to find file {fileUuid}</div> return <div>Unable to find file {fileUuid}</div>
} }
return ( return (
<BlockWithAlignableContents className={className} format={format} nodeKey={nodeKey}> <BlockWithAlignableContents className={className} format={format} nodeKey={nodeKey}>
<FilePreview file={file} application={application} /> <div ref={blockWrapperRef}>{canLoad && <FilePreview file={file} application={application} />}</div>
</BlockWithAlignableContents> </BlockWithAlignableContents>
) )
} }