fix: lazy load embedded files in super editor (#2043)
This commit is contained in:
@@ -6,7 +6,8 @@ import Spinner from '@/Components/Spinner/Spinner'
|
||||
import FilePreviewError from './FilePreviewError'
|
||||
import { isFileTypePreviewable } from './isFilePreviewable'
|
||||
import PreviewComponent from './PreviewComponent'
|
||||
import ProtectedItemOverlay from '../ProtectedItemOverlay/ProtectedItemOverlay'
|
||||
import Button from '../Button/Button'
|
||||
import { ProtectedIllustration } from '@standardnotes/icons'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
@@ -77,13 +78,28 @@ const FilePreview = ({ file, application }: Props) => {
|
||||
}, [application.files, downloadedBytes, file, isFilePreviewable, isAuthorized])
|
||||
|
||||
if (!isAuthorized) {
|
||||
const hasProtectionSources = application.hasProtectionSources()
|
||||
|
||||
return (
|
||||
<ProtectedItemOverlay
|
||||
showAccountMenu={application.showAccountMenu}
|
||||
itemType={'file'}
|
||||
onViewItem={() => application.protections.authorizeItemAccess(file)}
|
||||
hasProtectionSources={application.hasProtectionSources()}
|
||||
/>
|
||||
<div className="flex flex-grow flex-col items-center justify-center">
|
||||
<ProtectedIllustration className="mb-4 h-30 w-30" />
|
||||
<div className="mb-2 text-base font-bold">This file is protected.</div>
|
||||
<p className="max-w-[35ch] text-center text-sm text-passive-0">
|
||||
{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>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
{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.
|
||||
</div>
|
||||
<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.
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@@ -953,7 +953,7 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
|
||||
)}
|
||||
|
||||
{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
|
||||
key={this.note.uuid}
|
||||
application={this.application}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { BlockWithAlignableContents } from '@lexical/react/LexicalBlockWithAlignableContents'
|
||||
import { useMemo } from 'react'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { ElementFormatType, NodeKey } from 'lexical'
|
||||
import { useApplication } from '@/Components/ApplicationView/ApplicationProvider'
|
||||
import FilePreview from '@/Components/FilePreview/FilePreview'
|
||||
@@ -19,13 +19,47 @@ export function FileComponent({ className, format, nodeKey, fileUuid }: FileComp
|
||||
const application = useApplication()
|
||||
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) {
|
||||
return <div>Unable to find file {fileUuid}</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<BlockWithAlignableContents className={className} format={format} nodeKey={nodeKey}>
|
||||
<FilePreview file={file} application={application} />
|
||||
<div ref={blockWrapperRef}>{canLoad && <FilePreview file={file} application={application} />}</div>
|
||||
</BlockWithAlignableContents>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user