-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1754 from cozy/feat/viewer-mobile
Add PdfMobileViewer on Viewer
- Loading branch information
Showing
20 changed files
with
427 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import React, { useState, useEffect, useRef } from 'react' | ||
import has from 'lodash/get' | ||
|
||
import { useClient } from 'cozy-client' | ||
import { openFileWith } from 'cozy-client/dist/models/fsnative' | ||
import { isMobileApp } from 'cozy-device-helper' | ||
|
||
import Alerter from '../Alerter' | ||
import Spinner from '../Spinner' | ||
import Button from '../Button' | ||
|
||
import { withViewerLocales } from './withViewerLocales' | ||
import DownloadButton from './NoViewer/DownloadButton' | ||
import ImageLoader from './ImageLoader' | ||
import NoViewer from './NoViewer' | ||
import NoNetworkViewer from './NoNetworkViewer' | ||
|
||
import styles from './styles.styl' | ||
|
||
export const PdfMobileViewer = ({ file, t, gestures }) => { | ||
const [loading, setLoading] = useState(true) | ||
const [error, setError] = useState(false) | ||
const imgRef = useRef(null) | ||
|
||
const client = useClient() | ||
|
||
const reload = () => { | ||
setLoading(true) | ||
setError(false) | ||
} | ||
|
||
const onImageError = () => { | ||
setLoading(false) | ||
setError(true) | ||
} | ||
|
||
const onImageLoad = () => { | ||
setLoading(false) | ||
} | ||
|
||
const onFileOpen = async file => { | ||
try { | ||
await openFileWith(client, file) | ||
} catch (error) { | ||
Alerter.info(`Viewer.error.${error}`, { fileMime: file.mime }) | ||
} | ||
} | ||
|
||
const handleOnClick = file => { | ||
!isMobileApp() && client.collection('io.cozy.files').download(file) | ||
} | ||
|
||
useEffect(() => { | ||
if (gestures && isMobileApp()) { | ||
gestures.get('pinch').set({ enable: true }) | ||
gestures.on('tap doubletap pinchend', e => { | ||
if (e.target === imgRef.current) { | ||
onFileOpen(file) | ||
} | ||
}) | ||
|
||
return () => { | ||
gestures.off('tap doubletap pinchend') | ||
} | ||
} | ||
}, [gestures]) | ||
|
||
if (error) { | ||
return <NoNetworkViewer onReload={reload} /> | ||
} | ||
|
||
if (!has(file, 'links.preview')) { | ||
return ( | ||
<NoViewer | ||
file={file} | ||
renderFallbackExtraContent={ | ||
isMobileApp() | ||
? file => ( | ||
<Button | ||
className={styles['viewer-noviewer-download']} | ||
onClick={() => onFileOpen(file)} | ||
label={t('Viewer.openWith')} | ||
/> | ||
) | ||
: file => <DownloadButton file={file} /> | ||
} | ||
/> | ||
) | ||
} | ||
|
||
return ( | ||
<div className={styles['viewer-pdfMobile']}> | ||
{loading && <Spinner size="xxlarge" middle noMargin />} | ||
{file && ( | ||
<ImageLoader | ||
file={file} | ||
linkType="preview" | ||
onError={onImageError} | ||
key={file.id} | ||
render={src => ( | ||
<img | ||
ref={imgRef} | ||
className={styles['viewer-pdfMobile--image']} | ||
alt={file.name} | ||
src={src} | ||
onLoad={onImageLoad} | ||
onClick={() => handleOnClick(file)} | ||
/> | ||
)} | ||
/> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export default withViewerLocales(PdfMobileViewer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import React from 'react' | ||
import { render, wait } from '@testing-library/react' | ||
|
||
import { CozyProvider, createMockClient } from 'cozy-client' | ||
import { isMobileApp } from 'cozy-device-helper' | ||
|
||
import { I18n } from '../I18n' | ||
|
||
import { PdfMobileViewer } from './PdfMobileViewer' | ||
import { ImageLoader } from './ImageLoader' | ||
|
||
jest.mock('cozy-device-helper', () => ({ | ||
...jest.requireActual('cozy-device-helper'), | ||
isMobileApp: jest.fn() | ||
})) | ||
|
||
const client = createMockClient({}) | ||
client.collection = jest.fn(() => ({ | ||
getDownloadLinkById: jest.fn() | ||
})) | ||
|
||
const file = { | ||
_id: 'pdf', | ||
class: 'pdf', | ||
name: 'Demo.pdf', | ||
mime: 'application/pdf', | ||
links: { | ||
preview: 'https://viewerdemo.cozycloud.cc/IMG_0062.PNG' | ||
} | ||
} | ||
|
||
const setup = ({ file }) => { | ||
const root = render( | ||
<CozyProvider client={client}> | ||
<I18n lang="en" dictRequire={() => ''}> | ||
<PdfMobileViewer file={file} t={x => x} /> | ||
</I18n> | ||
</CozyProvider> | ||
) | ||
|
||
return { root } | ||
} | ||
|
||
describe('PdfMobileViewer', () => { | ||
it('should show a spinner if image is not loaded', () => { | ||
const { root } = setup({ file }) | ||
const { getByRole } = root | ||
|
||
expect(getByRole('progressbar')) | ||
}) | ||
|
||
describe('error when downloading file', () => { | ||
it('should show network error message on native app and browser', async () => { | ||
ImageLoader.prototype.checkImageSource = jest.fn().mockRejectedValue() // fail to load image | ||
|
||
const { root } = setup({ file }) | ||
const { queryByRole, getByText } = root | ||
|
||
const isMobileAppValues = [true, false] | ||
|
||
for (const isMobileAppValue of isMobileAppValues) { | ||
isMobileApp.mockReturnValue(isMobileAppValue) | ||
|
||
await wait() | ||
|
||
expect(queryByRole('progressbar')).toBeFalsy() | ||
expect( | ||
getByText( | ||
'This file could not be loaded. Do you have a working internet connection right now?' | ||
) | ||
) | ||
} | ||
}) | ||
}) | ||
|
||
describe('error if file as no preview', () => { | ||
let fileWithoutLinks = file | ||
|
||
beforeAll(() => { | ||
fileWithoutLinks.links = {} | ||
}) | ||
|
||
it('should show "download" button on browser', () => { | ||
isMobileApp.mockReturnValue(false) | ||
|
||
const { root } = setup({ file: fileWithoutLinks }) | ||
const { getByText, queryByRole } = root | ||
|
||
expect(queryByRole('progressbar')).toBeFalsy() | ||
expect(getByText('Download')) | ||
expect(getByText(file.name)) | ||
}) | ||
|
||
it('should show "open with" button on native app', () => { | ||
isMobileApp.mockReturnValue(true) | ||
|
||
const { root } = setup({ file: fileWithoutLinks }) | ||
const { getByText, queryByRole } = root | ||
|
||
expect(queryByRole('progressbar')).toBeFalsy() | ||
expect(getByText('Viewer.openWith')) | ||
expect(getByText(file.name)) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.