cozy-viewer 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/Readme.md +44 -0
- package/babel.config.js +23 -0
- package/dist/Footer/BottomSheetContent.d.ts +12 -0
- package/dist/Footer/BottomSheetContent.js +45 -0
- package/dist/Footer/DownloadButton.d.ts +16 -0
- package/dist/Footer/DownloadButton.js +113 -0
- package/dist/Footer/FooterActionButtons.d.ts +13 -0
- package/dist/Footer/FooterActionButtons.js +33 -0
- package/dist/Footer/FooterActionButtons.spec.d.ts +1 -0
- package/dist/Footer/FooterContent.d.ts +16 -0
- package/dist/Footer/FooterContent.js +120 -0
- package/dist/Footer/ForwardButton.d.ts +20 -0
- package/dist/Footer/ForwardButton.js +177 -0
- package/dist/Footer/ForwardButton.spec.d.ts +1 -0
- package/dist/Footer/ForwardOrDownloadButton.d.ts +11 -0
- package/dist/Footer/ForwardOrDownloadButton.js +42 -0
- package/dist/Footer/Sharing.d.ts +16 -0
- package/dist/Footer/Sharing.js +79 -0
- package/dist/Footer/helpers.d.ts +8 -0
- package/dist/Footer/helpers.js +179 -0
- package/dist/Footer/helpers.spec.d.ts +1 -0
- package/dist/NoViewer/DownloadButton.d.ts +2 -0
- package/dist/NoViewer/DownloadButton.js +52 -0
- package/dist/NoViewer/FileIcon.d.ts +4 -0
- package/dist/NoViewer/FileIcon.js +76 -0
- package/dist/NoViewer/NoViewer.d.ts +18 -0
- package/dist/NoViewer/NoViewer.js +64 -0
- package/dist/NoViewer/NoViewer.spec.d.ts +1 -0
- package/dist/NoViewer/index.d.ts +1 -0
- package/dist/NoViewer/index.js +15 -0
- package/dist/Panel/ActionMenuDesktop.d.ts +3 -0
- package/dist/Panel/ActionMenuDesktop.js +91 -0
- package/dist/Panel/ActionMenuMobile.d.ts +20 -0
- package/dist/Panel/ActionMenuMobile.js +95 -0
- package/dist/Panel/ActionMenuWrapper.d.ts +3 -0
- package/dist/Panel/ActionMenuWrapper.js +155 -0
- package/dist/Panel/Certifications.d.ts +2 -0
- package/dist/Panel/Certifications.js +80 -0
- package/dist/Panel/PanelContent.d.ts +2 -0
- package/dist/Panel/PanelContent.js +71 -0
- package/dist/Panel/Qualification.d.ts +2 -0
- package/dist/Panel/Qualification.js +148 -0
- package/dist/Panel/QualificationListItemContact.d.ts +10 -0
- package/dist/Panel/QualificationListItemContact.js +123 -0
- package/dist/Panel/QualificationListItemDate.d.ts +3 -0
- package/dist/Panel/QualificationListItemDate.js +90 -0
- package/dist/Panel/QualificationListItemInformation.d.ts +3 -0
- package/dist/Panel/QualificationListItemInformation.js +84 -0
- package/dist/Panel/QualificationListItemInformation.spec.d.ts +1 -0
- package/dist/Panel/QualificationListItemOther.d.ts +3 -0
- package/dist/Panel/QualificationListItemOther.js +78 -0
- package/dist/Panel/QualificationListItemText.d.ts +13 -0
- package/dist/Panel/QualificationListItemText.js +42 -0
- package/dist/Panel/getPanelBlocks.d.ts +26 -0
- package/dist/Panel/getPanelBlocks.js +79 -0
- package/dist/Panel/getPanelBlocks.spec.d.ts +1 -0
- package/dist/Viewer.d.ts +39 -0
- package/dist/Viewer.js +191 -0
- package/dist/ViewerContainer.d.ts +22 -0
- package/dist/ViewerContainer.js +221 -0
- package/dist/ViewerExposer.d.ts +2 -0
- package/dist/ViewerExposer.js +13 -0
- package/dist/ViewerInformationsWrapper.d.ts +20 -0
- package/dist/ViewerInformationsWrapper.js +68 -0
- package/dist/ViewerInformationsWrapper.spec.d.ts +1 -0
- package/dist/ViewerWithCustomPanelAndFooter.d.ts +2 -0
- package/dist/ViewerWithCustomPanelAndFooter.js +78 -0
- package/dist/ViewersByFile/AudioViewer.d.ts +74 -0
- package/dist/ViewersByFile/AudioViewer.js +57 -0
- package/dist/ViewersByFile/AudioViewer.spec.d.ts +1 -0
- package/dist/ViewersByFile/BlankPaperViewer.d.ts +2 -0
- package/dist/ViewersByFile/BlankPaperViewer.js +97 -0
- package/dist/ViewersByFile/ImageViewer.d.ts +31 -0
- package/dist/ViewersByFile/ImageViewer.js +385 -0
- package/dist/ViewersByFile/ImageViewer.spec.d.ts +1 -0
- package/dist/ViewersByFile/NoNetworkViewer.d.ts +2 -0
- package/dist/ViewersByFile/NoNetworkViewer.js +54 -0
- package/dist/ViewersByFile/OnlyOfficeViewer.d.ts +2 -0
- package/dist/ViewersByFile/OnlyOfficeViewer.js +46 -0
- package/dist/ViewersByFile/PdfJsViewer.d.ts +31 -0
- package/dist/ViewersByFile/PdfJsViewer.js +283 -0
- package/dist/ViewersByFile/PdfJsViewer.spec.d.ts +1 -0
- package/dist/ViewersByFile/PdfMobileViewer.d.ts +4 -0
- package/dist/ViewersByFile/PdfMobileViewer.js +185 -0
- package/dist/ViewersByFile/PdfMobileViewer.spec.d.ts +1 -0
- package/dist/ViewersByFile/ShortcutViewer.d.ts +2 -0
- package/dist/ViewersByFile/ShortcutViewer.js +61 -0
- package/dist/ViewersByFile/ShortcutViewer.spec.d.ts +4 -0
- package/dist/ViewersByFile/TextViewer.d.ts +90 -0
- package/dist/ViewersByFile/TextViewer.js +250 -0
- package/dist/ViewersByFile/TextViewer.spec.d.ts +1 -0
- package/dist/ViewersByFile/VideoViewer.d.ts +74 -0
- package/dist/ViewersByFile/VideoViewer.js +46 -0
- package/dist/ViewersByFile/VideoViewer.spec.d.ts +1 -0
- package/dist/assets/IlluGenericNewPage.svg +10 -0
- package/dist/components/ExpirationAlert.d.ts +2 -0
- package/dist/components/ExpirationAlert.js +129 -0
- package/dist/components/ExpirationAnnotation.d.ts +10 -0
- package/dist/components/ExpirationAnnotation.js +56 -0
- package/dist/components/Footer.d.ts +4 -0
- package/dist/components/Footer.js +41 -0
- package/dist/components/InformationPanel.d.ts +12 -0
- package/dist/components/InformationPanel.js +36 -0
- package/dist/components/Navigation.d.ts +18 -0
- package/dist/components/Navigation.js +63 -0
- package/dist/components/PdfToolbarButton.d.ts +16 -0
- package/dist/components/PdfToolbarButton.js +40 -0
- package/dist/components/PrintButton.d.ts +16 -0
- package/dist/components/PrintButton.js +163 -0
- package/dist/components/Toolbar.d.ts +2 -0
- package/dist/components/Toolbar.js +146 -0
- package/dist/components/ToolbarButtons.d.ts +5 -0
- package/dist/components/ToolbarButtons.js +20 -0
- package/dist/components/ToolbarFilePath.d.ts +3 -0
- package/dist/components/ToolbarFilePath.js +92 -0
- package/dist/components/ViewerByFile.d.ts +7 -0
- package/dist/components/ViewerByFile.js +137 -0
- package/dist/components/ViewerByFile.spec.d.ts +1 -0
- package/dist/components/ViewerControls.d.ts +9 -0
- package/dist/components/ViewerControls.js +251 -0
- package/dist/components/ViewerControls.spec.d.ts +1 -0
- package/dist/components/ViewerSpinner.d.ts +2 -0
- package/dist/components/ViewerSpinner.js +31 -0
- package/dist/docs/DemoProvider.d.ts +6 -0
- package/dist/docs/DemoProvider.js +159 -0
- package/dist/helpers.d.ts +37 -0
- package/dist/helpers.js +190 -0
- package/dist/helpers.spec.d.ts +1 -0
- package/dist/hoc/withFileUrl.d.ts +75 -0
- package/dist/hoc/withFileUrl.js +231 -0
- package/dist/hoc/withViewerLocales.d.ts +1 -0
- package/dist/hoc/withViewerLocales.js +15 -0
- package/dist/hooks/useReferencedContactName.d.ts +5 -0
- package/dist/hooks/useReferencedContactName.js +45 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +75 -0
- package/dist/locales/index.d.ts +6 -0
- package/dist/locales/index.js +18 -0
- package/dist/proptypes.d.ts +7 -0
- package/dist/proptypes.js +25 -0
- package/dist/providers/ActionMenuProvider.d.ts +13 -0
- package/dist/providers/ActionMenuProvider.js +47 -0
- package/dist/providers/EncryptedProvider.d.ts +8 -0
- package/dist/providers/EncryptedProvider.js +43 -0
- package/dist/queries.d.ts +15 -0
- package/dist/queries.js +40 -0
- package/dist/stylesheet.css +218 -0
- package/jest.config.js +23 -0
- package/package.json +62 -0
- package/preprocess.js +16 -0
- package/src/Footer/BottomSheetContent.jsx +30 -0
- package/src/Footer/DownloadButton.jsx +66 -0
- package/src/Footer/FooterActionButtons.jsx +22 -0
- package/src/Footer/FooterActionButtons.spec.jsx +30 -0
- package/src/Footer/FooterContent.jsx +102 -0
- package/src/Footer/ForwardButton.jsx +95 -0
- package/src/Footer/ForwardButton.spec.jsx +87 -0
- package/src/Footer/ForwardOrDownloadButton.jsx +24 -0
- package/src/Footer/Sharing.jsx +59 -0
- package/src/Footer/helpers.js +106 -0
- package/src/Footer/helpers.spec.js +77 -0
- package/src/NoViewer/DownloadButton.jsx +28 -0
- package/src/NoViewer/FileIcon.jsx +46 -0
- package/src/NoViewer/NoViewer.jsx +30 -0
- package/src/NoViewer/NoViewer.spec.jsx +44 -0
- package/src/NoViewer/__snapshots__/NoViewer.spec.jsx.snap +82 -0
- package/src/NoViewer/index.jsx +1 -0
- package/src/Panel/ActionMenuDesktop.jsx +69 -0
- package/src/Panel/ActionMenuMobile.jsx +76 -0
- package/src/Panel/ActionMenuWrapper.jsx +104 -0
- package/src/Panel/Certifications.jsx +63 -0
- package/src/Panel/PanelContent.jsx +50 -0
- package/src/Panel/Qualification.jsx +114 -0
- package/src/Panel/QualificationListItemContact.jsx +85 -0
- package/src/Panel/QualificationListItemDate.jsx +78 -0
- package/src/Panel/QualificationListItemInformation.jsx +68 -0
- package/src/Panel/QualificationListItemInformation.spec.jsx +73 -0
- package/src/Panel/QualificationListItemOther.jsx +61 -0
- package/src/Panel/QualificationListItemText.jsx +30 -0
- package/src/Panel/getPanelBlocks.jsx +56 -0
- package/src/Panel/getPanelBlocks.spec.jsx +79 -0
- package/src/Panel/styles.styl +13 -0
- package/src/Readme.md +352 -0
- package/src/Viewer.jsx +135 -0
- package/src/ViewerContainer.jsx +170 -0
- package/src/ViewerExposer.js +3 -0
- package/src/ViewerInformationsWrapper.jsx +70 -0
- package/src/ViewerInformationsWrapper.spec.jsx +63 -0
- package/src/ViewerWithCustomPanelAndFooter.jsx +57 -0
- package/src/ViewersByFile/AudioViewer.jsx +22 -0
- package/src/ViewersByFile/AudioViewer.spec.jsx +40 -0
- package/src/ViewersByFile/BlankPaperViewer.jsx +47 -0
- package/src/ViewersByFile/ImageViewer.jsx +331 -0
- package/src/ViewersByFile/ImageViewer.spec.jsx +73 -0
- package/src/ViewersByFile/NoNetworkViewer.jsx +18 -0
- package/src/ViewersByFile/OnlyOfficeViewer.jsx +29 -0
- package/src/ViewersByFile/PdfJsViewer.jsx +210 -0
- package/src/ViewersByFile/PdfJsViewer.spec.jsx +161 -0
- package/src/ViewersByFile/PdfMobileViewer.jsx +106 -0
- package/src/ViewersByFile/PdfMobileViewer.spec.jsx +76 -0
- package/src/ViewersByFile/ShortcutViewer.jsx +38 -0
- package/src/ViewersByFile/ShortcutViewer.spec.jsx +32 -0
- package/src/ViewersByFile/TextViewer.jsx +126 -0
- package/src/ViewersByFile/TextViewer.spec.jsx +118 -0
- package/src/ViewersByFile/VideoViewer.jsx +13 -0
- package/src/ViewersByFile/VideoViewer.spec.jsx +40 -0
- package/src/ViewersByFile/__snapshots__/AudioViewer.spec.jsx.snap +43 -0
- package/src/ViewersByFile/__snapshots__/ShortcutViewer.spec.jsx.snap +57 -0
- package/src/ViewersByFile/__snapshots__/TextViewer.spec.jsx.snap +100 -0
- package/src/ViewersByFile/__snapshots__/VideoViewer.spec.jsx.snap +19 -0
- package/src/ViewersByFile/styles.styl +87 -0
- package/src/assets/IlluGenericNewPage.svg +10 -0
- package/src/components/ExpirationAlert.jsx +86 -0
- package/src/components/ExpirationAnnotation.jsx +39 -0
- package/src/components/Footer.jsx +14 -0
- package/src/components/InformationPanel.jsx +26 -0
- package/src/components/Navigation.jsx +40 -0
- package/src/components/PdfToolbarButton.jsx +26 -0
- package/src/components/PrintButton.jsx +89 -0
- package/src/components/Toolbar.jsx +111 -0
- package/src/components/ToolbarButtons.jsx +11 -0
- package/src/components/ToolbarFilePath.jsx +61 -0
- package/src/components/ViewerByFile.jsx +112 -0
- package/src/components/ViewerByFile.spec.jsx +100 -0
- package/src/components/ViewerControls.jsx +191 -0
- package/src/components/ViewerControls.spec.jsx +54 -0
- package/src/components/ViewerSpinner.jsx +17 -0
- package/src/components/styles.styl +93 -0
- package/src/docs/DemoProvider.jsx +90 -0
- package/src/helpers.js +131 -0
- package/src/helpers.spec.js +136 -0
- package/src/hoc/withFileUrl.jsx +93 -0
- package/src/hoc/withViewerLocales.jsx +5 -0
- package/src/hooks/useReferencedContactName.jsx +26 -0
- package/src/index.jsx +12 -0
- package/src/locales/en.json +66 -0
- package/src/locales/fr.json +66 -0
- package/src/locales/index.js +4 -0
- package/src/proptypes.js +12 -0
- package/src/providers/ActionMenuProvider.jsx +35 -0
- package/src/providers/EncryptedProvider.jsx +25 -0
- package/src/queries.js +20 -0
- package/src/styles.styl +22 -0
- package/src/vars.styl +6 -0
- package/test/__mocks__/fileMock.js +3 -0
- package/test/jestLib/setup.js +5 -0
- package/tsconfig-build.json +13 -0
- package/tsconfig.json +34 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import get from 'lodash/get'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import { useClient, useFetchShortcut } from 'cozy-client'
|
|
5
|
+
import OpenwithIcon from 'cozy-ui/transpiled/react/Icons/Openwith'
|
|
6
|
+
import { ButtonLink } from 'cozy-ui/transpiled/react/deprecated/Button'
|
|
7
|
+
import { FileDoctype } from 'cozy-ui/transpiled/react/proptypes'
|
|
8
|
+
|
|
9
|
+
import NoViewer from '../NoViewer'
|
|
10
|
+
import { withViewerLocales } from '../hoc/withViewerLocales'
|
|
11
|
+
|
|
12
|
+
const ShortcutViewer = ({ t, file }) => {
|
|
13
|
+
const client = useClient()
|
|
14
|
+
const { shortcutInfos } = useFetchShortcut(client, file.id)
|
|
15
|
+
let url = ''
|
|
16
|
+
if (shortcutInfos) {
|
|
17
|
+
url = new URL(get(shortcutInfos, 'data.attributes.url'))
|
|
18
|
+
}
|
|
19
|
+
return (
|
|
20
|
+
<NoViewer
|
|
21
|
+
file={file}
|
|
22
|
+
renderFallbackExtraContent={() => (
|
|
23
|
+
<ButtonLink
|
|
24
|
+
label={`${t('Viewer.goto', { url: get(url, 'origin', '') })}`}
|
|
25
|
+
icon={OpenwithIcon}
|
|
26
|
+
href={`${get(url, 'origin', '')}`}
|
|
27
|
+
target="_blank"
|
|
28
|
+
/>
|
|
29
|
+
)}
|
|
30
|
+
/>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
ShortcutViewer.propTypes = {
|
|
35
|
+
file: FileDoctype.isRequired
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default withViewerLocales(ShortcutViewer)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { render, waitFor } from '@testing-library/react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import CozyClient, { CozyProvider } from 'cozy-client'
|
|
5
|
+
import I18n from 'cozy-ui/transpiled/react/providers/I18n'
|
|
6
|
+
|
|
7
|
+
import ShortcutViewer from './ShortcutViewer'
|
|
8
|
+
import en from '../locales/en.json'
|
|
9
|
+
|
|
10
|
+
export const locales = {
|
|
11
|
+
en
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const setup = () => {
|
|
15
|
+
const client = new CozyClient({})
|
|
16
|
+
return (
|
|
17
|
+
<CozyProvider client={client}>
|
|
18
|
+
<I18n lang="en" dictRequire={() => locales['en']}>
|
|
19
|
+
<ShortcutViewer file={{ id: '1' }} />
|
|
20
|
+
</I18n>
|
|
21
|
+
</CozyProvider>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('Shortcutviewer', () => {
|
|
26
|
+
it('renders the component', async () => {
|
|
27
|
+
const { container } = render(setup())
|
|
28
|
+
await waitFor(() => {
|
|
29
|
+
expect(container).toMatchSnapshot()
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import cx from 'classnames'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import ReactMarkdown from 'react-markdown'
|
|
5
|
+
|
|
6
|
+
import { withClient, models } from 'cozy-client'
|
|
7
|
+
import { FileDoctype } from 'cozy-ui/transpiled/react/proptypes'
|
|
8
|
+
|
|
9
|
+
import styles from './styles.styl'
|
|
10
|
+
import NoViewer from '../NoViewer'
|
|
11
|
+
import ViewerSpinner from '../components/ViewerSpinner'
|
|
12
|
+
import { isFileEncrypted } from '../helpers'
|
|
13
|
+
import withFileUrl from '../hoc/withFileUrl'
|
|
14
|
+
|
|
15
|
+
const MarkdownRenderer = ({ text }) => (
|
|
16
|
+
<ReactMarkdown
|
|
17
|
+
className={cx(styles['viewer-textviewer-content'], 'u-p-1')}
|
|
18
|
+
source={text}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const PlainTextRenderer = ({ text }) => (
|
|
23
|
+
<pre
|
|
24
|
+
className={cx(styles['viewer-textviewer-content'], 'u-mh-auto', 'u-mv-2')}
|
|
25
|
+
>
|
|
26
|
+
{text}
|
|
27
|
+
</pre>
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
const Loader = () => {
|
|
31
|
+
return (
|
|
32
|
+
<div className={styles['viewer-textviewer']}>
|
|
33
|
+
<ViewerSpinner />
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const isMarkdown = file =>
|
|
39
|
+
file.mime === 'text/markdown' ||
|
|
40
|
+
/.md$/.test(file.name) ||
|
|
41
|
+
models.file.isNote(file)
|
|
42
|
+
export class TextViewer extends React.Component {
|
|
43
|
+
state = {
|
|
44
|
+
text: '',
|
|
45
|
+
isMarkdown: false,
|
|
46
|
+
loading: true,
|
|
47
|
+
error: null
|
|
48
|
+
}
|
|
49
|
+
_mounted = false
|
|
50
|
+
|
|
51
|
+
componentDidMount() {
|
|
52
|
+
this._mounted = true
|
|
53
|
+
this.loadFile()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
componentWillUnmount() {
|
|
57
|
+
this._mounted = false
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async loadFile() {
|
|
61
|
+
const { url, file } = this.props
|
|
62
|
+
try {
|
|
63
|
+
let response
|
|
64
|
+
if (isFileEncrypted(file)) {
|
|
65
|
+
response = await fetch(url)
|
|
66
|
+
} else {
|
|
67
|
+
const { pathname } = new URL(url)
|
|
68
|
+
const client = this.props.client.getStackClient()
|
|
69
|
+
response = await client.fetch('GET', pathname)
|
|
70
|
+
}
|
|
71
|
+
const text = await response.text()
|
|
72
|
+
|
|
73
|
+
if (this._mounted) {
|
|
74
|
+
this.setState({
|
|
75
|
+
text,
|
|
76
|
+
isMarkdown: isMarkdown(file),
|
|
77
|
+
loading: false
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
// eslint-disable-next-line no-console
|
|
82
|
+
console.warn(error)
|
|
83
|
+
if (this._mounted) {
|
|
84
|
+
this.setState({
|
|
85
|
+
loading: false,
|
|
86
|
+
error
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
render() {
|
|
93
|
+
const { loading, error, text, isMarkdown } = this.state
|
|
94
|
+
const { file, renderFallbackExtraContent } = this.props
|
|
95
|
+
if (loading) return <Loader />
|
|
96
|
+
else if (error)
|
|
97
|
+
return (
|
|
98
|
+
<NoViewer
|
|
99
|
+
file={file}
|
|
100
|
+
renderFallbackExtraContent={renderFallbackExtraContent}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
else
|
|
104
|
+
return (
|
|
105
|
+
<div className={styles['viewer-textviewer']}>
|
|
106
|
+
<h2 className={cx(styles['viewer-filename'], 'u-mt-3', 'u-mb-1')}>
|
|
107
|
+
{file.name}
|
|
108
|
+
</h2>
|
|
109
|
+
{isMarkdown ? (
|
|
110
|
+
<MarkdownRenderer text={text} />
|
|
111
|
+
) : (
|
|
112
|
+
<PlainTextRenderer text={text} />
|
|
113
|
+
)}
|
|
114
|
+
</div>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
TextViewer.propTypes = {
|
|
120
|
+
client: PropTypes.object.isRequired,
|
|
121
|
+
url: PropTypes.string.isRequired,
|
|
122
|
+
file: FileDoctype.isRequired,
|
|
123
|
+
renderFallbackExtraContent: PropTypes.func
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export default withFileUrl(withClient(TextViewer))
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { shallow } from 'enzyme'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import renderer from 'react-test-renderer'
|
|
4
|
+
|
|
5
|
+
import { createMockClient } from 'cozy-client'
|
|
6
|
+
import { BreakpointsProvider } from 'cozy-ui/transpiled/react/providers/Breakpoints'
|
|
7
|
+
|
|
8
|
+
import { TextViewer, isMarkdown } from './TextViewer'
|
|
9
|
+
|
|
10
|
+
const client = createMockClient({})
|
|
11
|
+
|
|
12
|
+
const mockText = jest.fn()
|
|
13
|
+
const mockFetch = responseText => async () => ({
|
|
14
|
+
text: mockText.mockResolvedValue(responseText)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
client.stackClient.fetch = mockFetch('Text')
|
|
18
|
+
|
|
19
|
+
const props = {
|
|
20
|
+
client,
|
|
21
|
+
url: 'https://foo.mycozy.cloud',
|
|
22
|
+
file: {
|
|
23
|
+
_id: '1',
|
|
24
|
+
_type: 'io.cozy.files',
|
|
25
|
+
name: 'My File'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('isMarkdown function', () => {
|
|
30
|
+
it('test markdown function', () => {
|
|
31
|
+
const note = {
|
|
32
|
+
name: 'My Note.cozy-note',
|
|
33
|
+
type: 'file',
|
|
34
|
+
metadata: {
|
|
35
|
+
content: 'my prosemirror content',
|
|
36
|
+
schema: '1',
|
|
37
|
+
title: 'prosemirror title',
|
|
38
|
+
version: '3'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
expect(isMarkdown({ mime: 'text/markdown' })).toBe(true)
|
|
42
|
+
expect(isMarkdown({ name: 'text.md' })).toBe(true)
|
|
43
|
+
expect(isMarkdown(note)).toBe(true)
|
|
44
|
+
expect(isMarkdown({ name: 'text.txt' })).toBe(false)
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
describe('TextViewer Component', () => {
|
|
48
|
+
it('should display the loader ', () => {
|
|
49
|
+
const comp = shallow(<TextViewer {...props} />)
|
|
50
|
+
expect(comp).toMatchSnapshot()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should display the error component and render with renderFallback', () => {
|
|
54
|
+
const comp = renderer.create(
|
|
55
|
+
<BreakpointsProvider>
|
|
56
|
+
<TextViewer
|
|
57
|
+
{...props}
|
|
58
|
+
renderFallbackExtraContent={file => <span>{file.name}</span>}
|
|
59
|
+
/>
|
|
60
|
+
</BreakpointsProvider>
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
const inst = comp.root.children[0].instance
|
|
64
|
+
inst.setState({ error: true, loading: false })
|
|
65
|
+
expect(comp.toJSON()).toMatchSnapshot()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('should display the text viewer', () => {
|
|
69
|
+
const comp = renderer.create(
|
|
70
|
+
<BreakpointsProvider>
|
|
71
|
+
<TextViewer {...props} />
|
|
72
|
+
</BreakpointsProvider>
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
const inst = comp.root.children[0].instance
|
|
76
|
+
inst.setState({
|
|
77
|
+
loading: false,
|
|
78
|
+
isMarkdown: false,
|
|
79
|
+
text: 'The content of my file'
|
|
80
|
+
})
|
|
81
|
+
expect(comp.toJSON()).toMatchSnapshot()
|
|
82
|
+
expect(mockText).toHaveBeenCalled()
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('should display the markdown viewer', () => {
|
|
86
|
+
const comp = renderer.create(
|
|
87
|
+
<BreakpointsProvider>
|
|
88
|
+
<TextViewer {...props} />
|
|
89
|
+
</BreakpointsProvider>
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const inst = comp.root.children[0].instance
|
|
93
|
+
inst.setState({
|
|
94
|
+
loading: false,
|
|
95
|
+
isMarkdown: true,
|
|
96
|
+
text: "It's very easy to make some words **bold** and other words *italic* with Markdown"
|
|
97
|
+
})
|
|
98
|
+
expect(comp.toJSON()).toMatchSnapshot()
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should display the text viewer when an URL is given', () => {
|
|
102
|
+
const url = 'blob:http://foo.mycozy.cloud'
|
|
103
|
+
const comp = renderer.create(
|
|
104
|
+
<BreakpointsProvider>
|
|
105
|
+
<TextViewer {...props} url={url} />
|
|
106
|
+
</BreakpointsProvider>
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
const inst = comp.root.children[0].instance
|
|
110
|
+
inst.setState({
|
|
111
|
+
loading: false,
|
|
112
|
+
isMarkdown: false,
|
|
113
|
+
text: 'The content of my file'
|
|
114
|
+
})
|
|
115
|
+
expect(comp.toJSON()).toMatchSnapshot()
|
|
116
|
+
expect(mockText).toHaveBeenCalled()
|
|
117
|
+
})
|
|
118
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import styles from './styles.styl'
|
|
4
|
+
import withFileUrl from '../hoc/withFileUrl'
|
|
5
|
+
|
|
6
|
+
const VideoViewer = ({ file, url }) => (
|
|
7
|
+
<div className={styles['viewer-videoviewer']}>
|
|
8
|
+
<video src={url} controls="controls" />
|
|
9
|
+
<p className={styles['viewer-filename']}>{file.name}</p>
|
|
10
|
+
</div>
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
export default withFileUrl(VideoViewer)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { render, waitFor } from '@testing-library/react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
import { BreakpointsProvider } from 'cozy-ui/transpiled/react/providers/Breakpoints'
|
|
5
|
+
|
|
6
|
+
import VideoViewer from './VideoViewer'
|
|
7
|
+
import DemoProvider from '../docs/DemoProvider'
|
|
8
|
+
|
|
9
|
+
const file = {
|
|
10
|
+
_id: 'video',
|
|
11
|
+
class: 'video',
|
|
12
|
+
mime: 'video/mp4',
|
|
13
|
+
name: 'sample.mp4'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const setup = () => {
|
|
17
|
+
const root = render(
|
|
18
|
+
<DemoProvider>
|
|
19
|
+
<BreakpointsProvider>
|
|
20
|
+
<VideoViewer file={file} />
|
|
21
|
+
</BreakpointsProvider>
|
|
22
|
+
</DemoProvider>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
return { root }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('VideoViewer', () => {
|
|
29
|
+
it('should render a spinner then the video viewer', async () => {
|
|
30
|
+
const { root } = setup()
|
|
31
|
+
const { container, queryByRole } = root
|
|
32
|
+
|
|
33
|
+
expect(queryByRole('progressbar')).toBeTruthy()
|
|
34
|
+
|
|
35
|
+
await waitFor(() => {
|
|
36
|
+
expect(queryByRole('progressbar')).toBeFalsy()
|
|
37
|
+
expect(container).toMatchSnapshot()
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`AudioViewer should render a spinner then the audio viewer 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="viewer-audioviewer"
|
|
7
|
+
>
|
|
8
|
+
<svg
|
|
9
|
+
class="styles__icon___23x3R"
|
|
10
|
+
height="140"
|
|
11
|
+
viewBox="0 0 32 32"
|
|
12
|
+
width="160"
|
|
13
|
+
>
|
|
14
|
+
<g
|
|
15
|
+
fill="none"
|
|
16
|
+
fill-rule="evenodd"
|
|
17
|
+
transform="translate(1 1)"
|
|
18
|
+
>
|
|
19
|
+
<rect
|
|
20
|
+
fill="#ACF6F7"
|
|
21
|
+
height="30"
|
|
22
|
+
rx="2"
|
|
23
|
+
width="30"
|
|
24
|
+
/>
|
|
25
|
+
<path
|
|
26
|
+
d="M8 19.998a2 2 0 00-.002 4H9c1.657 0 3-1.35 3-2.997v-7.679a.63.63 0 01.492-.601l6.016-1.129c.272-.05.492.124.492.418v5.478c0 .282-.215.51-.49.51H17c-1.105 0-2 .904-2 1.997v-.179a2 2 0 001.998 1.997H18c1.657 0 3-1.349 3-2.993V7c0-.554-.445-.921-.976-.825L10.976 7.82C10.437 7.918 10 8.454 10 9v10.498c0 .276-.215.5-.49.5H8z"
|
|
27
|
+
fill="#0CCBD0"
|
|
28
|
+
/>
|
|
29
|
+
</g>
|
|
30
|
+
</svg>
|
|
31
|
+
<p
|
|
32
|
+
class="viewer-filename"
|
|
33
|
+
>
|
|
34
|
+
sample.mp3
|
|
35
|
+
</p>
|
|
36
|
+
<audio
|
|
37
|
+
controls=""
|
|
38
|
+
preload="auto"
|
|
39
|
+
src="https://viewerdemo.cozycloud.cc/Z.mp3"
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
`;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Shortcutviewer renders the component 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="viewer-noviewer"
|
|
7
|
+
>
|
|
8
|
+
<svg
|
|
9
|
+
class="styles__icon___23x3R"
|
|
10
|
+
height="140"
|
|
11
|
+
viewBox="0 0 32 32"
|
|
12
|
+
width="160"
|
|
13
|
+
>
|
|
14
|
+
<g
|
|
15
|
+
fill="none"
|
|
16
|
+
fill-rule="evenodd"
|
|
17
|
+
>
|
|
18
|
+
<path
|
|
19
|
+
d="M3 2.002C3 .896 3.89 0 4.997 0H22l7 7v22.996A2 2 0 0127.003 32H4.997A1.995 1.995 0 013 29.998V2.002z"
|
|
20
|
+
fill="#D1D5DB"
|
|
21
|
+
/>
|
|
22
|
+
<path
|
|
23
|
+
d="M21.5 0c-.276 0-.5.23-.5.5V8h7.5c.276 0 .5-.232.5-.5V7l-7-7h-.5z"
|
|
24
|
+
fill="#A3ACB8"
|
|
25
|
+
/>
|
|
26
|
+
</g>
|
|
27
|
+
</svg>
|
|
28
|
+
<p
|
|
29
|
+
class="viewer-filename"
|
|
30
|
+
/>
|
|
31
|
+
<a
|
|
32
|
+
class="styles__c-btn___3kXsk"
|
|
33
|
+
href=""
|
|
34
|
+
target="_blank"
|
|
35
|
+
>
|
|
36
|
+
<span>
|
|
37
|
+
<svg
|
|
38
|
+
aria-hidden="true"
|
|
39
|
+
class="styles__icon___23x3R"
|
|
40
|
+
focusable="false"
|
|
41
|
+
height="16"
|
|
42
|
+
viewBox="0 0 16 16"
|
|
43
|
+
width="16"
|
|
44
|
+
>
|
|
45
|
+
<path
|
|
46
|
+
d="M9 0v2h3.5L6 8.5 7.5 10 14 3.5V7h2V1.003A.996.996 0 0014.997 0H9zM7 2V0H1.003A1 1 0 000 1v14c0 .552.445 1 1 1h14c.552 0 1-.438 1-1.003V9h-2v5H2V2h5z"
|
|
47
|
+
fill-rule="evenodd"
|
|
48
|
+
/>
|
|
49
|
+
</svg>
|
|
50
|
+
<span>
|
|
51
|
+
Go to
|
|
52
|
+
</span>
|
|
53
|
+
</span>
|
|
54
|
+
</a>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
`;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`TextViewer Component should display the error component and render with renderFallback 1`] = `
|
|
4
|
+
<div
|
|
5
|
+
className="viewer-noviewer"
|
|
6
|
+
>
|
|
7
|
+
<svg
|
|
8
|
+
className="styles__icon___23x3R"
|
|
9
|
+
height={140}
|
|
10
|
+
style={Object {}}
|
|
11
|
+
viewBox="0 0 32 32"
|
|
12
|
+
width={160}
|
|
13
|
+
>
|
|
14
|
+
<g
|
|
15
|
+
fill="none"
|
|
16
|
+
fillRule="evenodd"
|
|
17
|
+
>
|
|
18
|
+
<path
|
|
19
|
+
d="M3 2.002C3 .896 3.89 0 4.997 0H22l7 7v22.996A2 2 0 0127.003 32H4.997A1.995 1.995 0 013 29.998V2.002z"
|
|
20
|
+
fill="#D1D5DB"
|
|
21
|
+
/>
|
|
22
|
+
<path
|
|
23
|
+
d="M21.5 0c-.276 0-.5.23-.5.5V8h7.5c.276 0 .5-.232.5-.5V7l-7-7h-.5z"
|
|
24
|
+
fill="#A3ACB8"
|
|
25
|
+
/>
|
|
26
|
+
</g>
|
|
27
|
+
</svg>
|
|
28
|
+
<p
|
|
29
|
+
className="viewer-filename"
|
|
30
|
+
>
|
|
31
|
+
My File
|
|
32
|
+
</p>
|
|
33
|
+
<span>
|
|
34
|
+
My File
|
|
35
|
+
</span>
|
|
36
|
+
</div>
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
exports[`TextViewer Component should display the loader 1`] = `<Loader />`;
|
|
40
|
+
|
|
41
|
+
exports[`TextViewer Component should display the markdown viewer 1`] = `
|
|
42
|
+
<div
|
|
43
|
+
className="viewer-textviewer"
|
|
44
|
+
>
|
|
45
|
+
<h2
|
|
46
|
+
className="viewer-filename u-mt-3 u-mb-1"
|
|
47
|
+
>
|
|
48
|
+
My File
|
|
49
|
+
</h2>
|
|
50
|
+
<div
|
|
51
|
+
className="viewer-textviewer-content u-p-1"
|
|
52
|
+
>
|
|
53
|
+
<p>
|
|
54
|
+
It's very easy to make some words
|
|
55
|
+
<strong>
|
|
56
|
+
bold
|
|
57
|
+
</strong>
|
|
58
|
+
and other words
|
|
59
|
+
<em>
|
|
60
|
+
italic
|
|
61
|
+
</em>
|
|
62
|
+
with Markdown
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
exports[`TextViewer Component should display the text viewer 1`] = `
|
|
69
|
+
<div
|
|
70
|
+
className="viewer-textviewer"
|
|
71
|
+
>
|
|
72
|
+
<h2
|
|
73
|
+
className="viewer-filename u-mt-3 u-mb-1"
|
|
74
|
+
>
|
|
75
|
+
My File
|
|
76
|
+
</h2>
|
|
77
|
+
<pre
|
|
78
|
+
className="viewer-textviewer-content u-mh-auto u-mv-2"
|
|
79
|
+
>
|
|
80
|
+
The content of my file
|
|
81
|
+
</pre>
|
|
82
|
+
</div>
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
exports[`TextViewer Component should display the text viewer when an URL is given 1`] = `
|
|
86
|
+
<div
|
|
87
|
+
className="viewer-textviewer"
|
|
88
|
+
>
|
|
89
|
+
<h2
|
|
90
|
+
className="viewer-filename u-mt-3 u-mb-1"
|
|
91
|
+
>
|
|
92
|
+
My File
|
|
93
|
+
</h2>
|
|
94
|
+
<pre
|
|
95
|
+
className="viewer-textviewer-content u-mh-auto u-mv-2"
|
|
96
|
+
>
|
|
97
|
+
The content of my file
|
|
98
|
+
</pre>
|
|
99
|
+
</div>
|
|
100
|
+
`;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`VideoViewer should render a spinner then the video viewer 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="viewer-videoviewer"
|
|
7
|
+
>
|
|
8
|
+
<video
|
|
9
|
+
controls=""
|
|
10
|
+
src="https://viewerdemo.cozycloud.cc/Nextcloud.mp4"
|
|
11
|
+
/>
|
|
12
|
+
<p
|
|
13
|
+
class="viewer-filename"
|
|
14
|
+
>
|
|
15
|
+
sample.mp4
|
|
16
|
+
</p>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
@require 'settings/breakpoints.styl'
|
|
2
|
+
@require '../vars.styl'
|
|
3
|
+
|
|
4
|
+
.viewer-imageviewer
|
|
5
|
+
.viewer-noviewer
|
|
6
|
+
.viewer-audioviewer
|
|
7
|
+
.viewer-videoviewer
|
|
8
|
+
.viewer-pdfviewer
|
|
9
|
+
.viewer-textviewer
|
|
10
|
+
.viewer-canceled
|
|
11
|
+
position relative
|
|
12
|
+
display flex
|
|
13
|
+
width 60%
|
|
14
|
+
max-height 'calc(100% - %s)' % $toolbarHeight
|
|
15
|
+
justify-content center
|
|
16
|
+
align-items center
|
|
17
|
+
flex-direction column
|
|
18
|
+
margin-top $toolbarHeight
|
|
19
|
+
|
|
20
|
+
h2
|
|
21
|
+
max-width 90%
|
|
22
|
+
|
|
23
|
+
+medium-screen()
|
|
24
|
+
margin-left 0
|
|
25
|
+
width 100%
|
|
26
|
+
max-height 'calc(100% - %s)' % $viewerHeightMedium
|
|
27
|
+
margin-top $viewerMarginTopMedium
|
|
28
|
+
|
|
29
|
+
// rules for specific viewers below
|
|
30
|
+
|
|
31
|
+
.viewer-videoviewer
|
|
32
|
+
video
|
|
33
|
+
width 100%
|
|
34
|
+
max-width 31.25rem
|
|
35
|
+
height auto
|
|
36
|
+
|
|
37
|
+
.viewer-textviewer
|
|
38
|
+
.viewer-textviewer-content
|
|
39
|
+
white-space pre-line
|
|
40
|
+
width 100%
|
|
41
|
+
max-height 70%
|
|
42
|
+
overflow auto
|
|
43
|
+
|
|
44
|
+
a
|
|
45
|
+
color var(--azure)
|
|
46
|
+
|
|
47
|
+
+medium-screen()
|
|
48
|
+
width 90%
|
|
49
|
+
margin-left 5%
|
|
50
|
+
|
|
51
|
+
.viewer-filename
|
|
52
|
+
max-width 90%
|
|
53
|
+
text-overflow ellipsis
|
|
54
|
+
overflow hidden
|
|
55
|
+
|
|
56
|
+
.viewer-pdfviewer-pdf
|
|
57
|
+
overflow auto
|
|
58
|
+
width 100%
|
|
59
|
+
|
|
60
|
+
.viewer-pdfviewer-page > *
|
|
61
|
+
margin auto
|
|
62
|
+
|
|
63
|
+
.viewer-pdfviewer-toolbar
|
|
64
|
+
position absolute
|
|
65
|
+
bottom 2rem
|
|
66
|
+
background var(--charcoalGrey)
|
|
67
|
+
color var(--white)
|
|
68
|
+
border-radius .5rem
|
|
69
|
+
|
|
70
|
+
.viewer-imageviewer
|
|
71
|
+
flex 1 1 100%
|
|
72
|
+
width auto
|
|
73
|
+
max-width 100%
|
|
74
|
+
|
|
75
|
+
img
|
|
76
|
+
display block
|
|
77
|
+
max-width 100%
|
|
78
|
+
max-height 100%
|
|
79
|
+
box-shadow 0 .375rem 1.5rem 0 rgba(0, 0, 0, .5)
|
|
80
|
+
|
|
81
|
+
.viewer-pdfMobile
|
|
82
|
+
width 100%
|
|
83
|
+
height 'calc(100% - %s - var(--flagship-top-height))' % $viewerHeightMedium
|
|
84
|
+
margin-top 'calc(var(--flagship-top-height, 0rem) + %s)' % $viewerMarginTopMedium
|
|
85
|
+
|
|
86
|
+
&--image
|
|
87
|
+
width 100%
|