feat: use native preview for pdf in mobile webview (#1728)

This commit is contained in:
Aman Harwara
2022-10-02 23:10:44 +05:30
committed by GitHub
parent 65818ac1cd
commit a90e4a50e8
15 changed files with 91 additions and 22 deletions

View File

@@ -66,7 +66,7 @@ const FilePreview = ({ file, application }: Props) => {
<span className="mt-3">Loading file...</span>
</div>
) : downloadedBytes ? (
<PreviewComponent file={file} bytes={downloadedBytes} />
<PreviewComponent application={application} file={file} bytes={downloadedBytes} />
) : (
<FilePreviewError
file={file}

View File

@@ -1,16 +1,24 @@
import { WebApplication } from '@/Application/Application'
import { getBase64FromBlob } from '@/Utils'
import { FileItem } from '@standardnotes/snjs'
import { FunctionComponent, useEffect, useMemo, useRef } from 'react'
import { FunctionComponent, useCallback, useEffect, useMemo, useRef } from 'react'
import Button from '../Button/Button'
import { AppPaneId } from '../ResponsivePane/AppPaneMetadata'
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
import { createObjectURLWithRef } from './CreateObjectURLWithRef'
import ImagePreview from './ImagePreview'
import { PreviewableTextFileTypes } from './isFilePreviewable'
import { PreviewableTextFileTypes, RequiresNativeFilePreview } from './isFilePreviewable'
import TextPreview from './TextPreview'
type Props = {
application: WebApplication
file: FileItem
bytes: Uint8Array
}
const PreviewComponent: FunctionComponent<Props> = ({ file, bytes }) => {
const PreviewComponent: FunctionComponent<Props> = ({ application, file, bytes }) => {
const { selectedPane } = useResponsiveAppPane()
const objectUrlRef = useRef<string>()
const objectUrl = useMemo(() => {
@@ -28,6 +36,42 @@ const PreviewComponent: FunctionComponent<Props> = ({ file, bytes }) => {
}
}, [])
const isNativeMobileWeb = application.isNativeMobileWeb()
const requiresNativePreview = RequiresNativeFilePreview.includes(file.mimeType)
const openNativeFilePreview = useCallback(async () => {
if (!isNativeMobileWeb) {
throw new Error('Native file preview cannot be used on non-native platform')
}
const fileBase64 = await getBase64FromBlob(
new Blob([bytes], {
type: file.mimeType,
}),
)
application.mobileDevice().previewFile(fileBase64, file.name)
}, [application, bytes, file.mimeType, file.name, isNativeMobileWeb])
useEffect(() => {
const shouldOpenNativePreviewOnLoad =
isNativeMobileWeb && selectedPane === AppPaneId.Editor && requiresNativePreview
if (shouldOpenNativePreviewOnLoad) {
void openNativeFilePreview()
}
}, [isNativeMobileWeb, openNativeFilePreview, requiresNativePreview, selectedPane])
if (isNativeMobileWeb && requiresNativePreview) {
return (
<div className="flex flex-grow flex-col items-center justify-center">
<div className="text-base font-bold">Previewing file...</div>
<Button className="mt-3" primary onClick={openNativeFilePreview}>
Re-open file preview
</Button>
</div>
)
}
if (file.mimeType.startsWith('image/')) {
return <ImagePreview objectUrl={objectUrl} />
}

View File

@@ -1,5 +1,7 @@
export const PreviewableTextFileTypes = ['text/plain', 'text/csv', 'application/json']
export const RequiresNativeFilePreview = ['application/pdf']
export const isFileTypePreviewable = (fileType: string) => {
const isImage = fileType.startsWith('image/')
const isVideo = fileType.startsWith('video/')