cozy-ui 57.9.2 → 58.1.1

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 CHANGED
@@ -1,3 +1,45 @@
1
+ ## [58.1.1](https://github.com/cozy/cozy-ui/compare/v58.1.0...v58.1.1) (2021-12-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Replace jest function in documentation ([cdbc01f](https://github.com/cozy/cozy-ui/commit/cdbc01f))
7
+
8
+ # [58.1.0](https://github.com/cozy/cozy-ui/compare/v58.0.0...v58.1.0) (2021-12-06)
9
+
10
+
11
+ ### Features
12
+
13
+ * Add realtime to FileImageLoader component ([621fe47](https://github.com/cozy/cozy-ui/commit/621fe47))
14
+
15
+ # [58.0.0](https://github.com/cozy/cozy-ui/compare/v57.10.0...v58.0.0) (2021-12-03)
16
+
17
+
18
+ ### Features
19
+
20
+ * Renamed ImageLoader & Exposed it directly ([2ca789b](https://github.com/cozy/cozy-ui/commit/2ca789b))
21
+
22
+
23
+ ### BREAKING CHANGES
24
+
25
+ * `ImageLoader` is rename `FileImageLoader`.
26
+ If you were previously importing `ImageLoader`
27
+ via the `Viewer`like this
28
+ `import ImageLoader from 'cozy-ui/transpiled/react/Viewer/ImageLoader'`
29
+ this no longer works, there is a more direct path:
30
+ `import ImageLoader from 'cozy-ui/transpiled/react/ImageLoader`.
31
+ The method `checkImageSource` has been moved also
32
+ from `Viewer` folder to `ImageLoader` folder.
33
+
34
+ Co-authored-by: JF-Cozy
35
+
36
+ # [57.10.0](https://github.com/cozy/cozy-ui/compare/v57.9.2...v57.10.0) (2021-11-29)
37
+
38
+
39
+ ### Features
40
+
41
+ * Forward remaining props to AppIcon ([ed86adf](https://github.com/cozy/cozy-ui/commit/ed86adf))
42
+
1
43
  ## [57.9.2](https://github.com/cozy/cozy-ui/compare/v57.9.1...v57.9.2) (2021-11-23)
2
44
 
3
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "57.9.2",
3
+ "version": "58.1.1",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -140,7 +140,7 @@
140
140
  "stylus": "0.54.7",
141
141
  "stylus-loader": "3.0.2",
142
142
  "svg-sprite-loader": "4.1.6",
143
- "svgstore-cli": "1.3.1",
143
+ "svgstore-cli": "1.3.2",
144
144
  "url-loader": "1.1.2",
145
145
  "webpack": "4.39.3"
146
146
  },
@@ -0,0 +1,48 @@
1
+ ### FileImageLoader
2
+
3
+ A component to get the image in `links` prop of a file, according to its class (could be `image` or `pdf`).
4
+
5
+ ```jsx
6
+ import DemoProvider from '../Viewer/docs/DemoProvider'
7
+
8
+ import FileImageLoader from 'cozy-ui/transpiled/react/FileImageLoader'
9
+ import Icon from 'cozy-ui/transpiled/react/Icon'
10
+ import FileDuotoneIcon from "cozy-ui/transpiled/react/Icons/FileDuotone"
11
+ import BankIcon from "cozy-ui/transpiled/react/Icons/Bank"
12
+
13
+ const file = {
14
+ _id: 'image',
15
+ class: 'image',
16
+ name: 'Demo.img',
17
+ mime: 'application/jpeg',
18
+ links: {
19
+ large: 'https://viewerdemo.cozycloud.cc/IMG_0062.PNG'
20
+ }
21
+ }
22
+
23
+ const onImageError = () => console.info('image errored')
24
+ const onImageLoad = () => console.info('image loaded!')
25
+ const FallbackComp = () => {
26
+ return (
27
+ <div>fallback component</div>
28
+ )
29
+ }
30
+
31
+ ;
32
+
33
+ <DemoProvider>
34
+ <FileImageLoader
35
+ file={file}
36
+ linkType="large"
37
+ onError={onImageError}
38
+ render={src => (
39
+ <img
40
+ src={src}
41
+ height={300}
42
+ onLoad={onImageLoad}
43
+ />
44
+ )}
45
+ renderFallback={() => <FallbackComp />}
46
+ />
47
+ </DemoProvider>
48
+ ```
@@ -1,8 +1,12 @@
1
- const TTL = 10000
2
-
3
- export const checkImageSource = src => {
1
+ /**
2
+ * @param {string} src - Image source
3
+ * @returns {Promise<void>}
4
+ */
5
+ export const checkImageSource = async src => {
6
+ const TTL = 10000
4
7
  let timeout = null
5
8
  let img = null
9
+
6
10
  const cleanImageLoader = () => {
7
11
  clearTimeout(timeout)
8
12
  img.onload = img.onerror = null
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import { Component } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { withClient } from 'cozy-client'
4
4
  import logger from 'cozy-logger'
@@ -11,7 +11,8 @@ const FAILED = 'FAILED'
11
11
  const GET_LINK = 'GET_LINK'
12
12
 
13
13
  import { checkImageSource } from './checkImageSource'
14
- export class ImageLoader extends React.Component {
14
+
15
+ export class FileImageLoader extends Component {
15
16
  state = {
16
17
  src: null
17
18
  }
@@ -19,9 +20,13 @@ export class ImageLoader extends React.Component {
19
20
  _mounted = false
20
21
 
21
22
  componentDidMount() {
23
+ const { client } = this.props
22
24
  this._mounted = true
23
25
  this.status = PENDING
24
26
  this.loadNextSrc()
27
+ this.realtime = client.plugins.realtime
28
+ this.type = 'io.cozy.files.thumbnails'
29
+ this.realtime.subscribe('created', this.type, this.handleCreate)
25
30
  }
26
31
 
27
32
  componentWillUnmount() {
@@ -30,6 +35,19 @@ export class ImageLoader extends React.Component {
30
35
  this.img.onload = this.img.onerror = null
31
36
  this.img.src = ''
32
37
  }
38
+ this.realtime &&
39
+ this.realtime.unsubscribe('created', this.type, this.handleCreate)
40
+ }
41
+
42
+ /**
43
+ * Reload the link when realtime tell us that the
44
+ * thumbnail is created. By default linkType === small
45
+ */
46
+ handleCreate = doc => {
47
+ const { file, linkType } = this.props
48
+ if (file._id === doc._id && doc.format === linkType) {
49
+ this.loadLink()
50
+ }
33
51
  }
34
52
 
35
53
  getFileId(file) {
@@ -51,6 +69,7 @@ export class ImageLoader extends React.Component {
51
69
  const response = await this.props.client
52
70
  .collection('io.cozy.files')
53
71
  .get(this.getFileId(file))
72
+
54
73
  if (!response.data.links) throw new Error('Could not fetch file links')
55
74
  return response.data.links
56
75
  }
@@ -63,6 +82,7 @@ export class ImageLoader extends React.Component {
63
82
  const link = file.links ? file.links[linkType] : false
64
83
 
65
84
  if (!link) throw new Error(`${linkType} link is not available`)
85
+
66
86
  const src = client.getStackClient().uri + link
67
87
  await checkImageSource(src)
68
88
  if (this._mounted) {
@@ -72,10 +92,10 @@ export class ImageLoader extends React.Component {
72
92
  })
73
93
  }
74
94
  } catch (e) {
75
- logger.error(e)
76
95
  this.loadNextSrc(e)
77
96
  }
78
97
  }
98
+
79
99
  async loadLink() {
80
100
  this.status = LOADING_LINK
81
101
  const { file, linkType, client } = this.props
@@ -105,7 +125,7 @@ export class ImageLoader extends React.Component {
105
125
  const { file, client } = this.props
106
126
 
107
127
  try {
108
- // ImageLoader can also be used for pdf files, because on mobile a preview image is
128
+ // FileImageLoader can also be used for pdf files, because on mobile a preview image is
109
129
  // generated and the pdf is therefore treated as an image.
110
130
  // But the fallback allows to display the original file as an image if there is an error
111
131
  // during the preview recovery. This principle is not possible with a pdf file.
@@ -137,17 +157,17 @@ export class ImageLoader extends React.Component {
137
157
  }
138
158
  }
139
159
 
140
- ImageLoader.propTypes = {
160
+ FileImageLoader.propTypes = {
141
161
  file: PropTypes.object.isRequired,
142
162
  render: PropTypes.func.isRequired,
143
- linkType: PropTypes.oneOf(['small', 'medium', 'large', 'preview']),
163
+ linkType: PropTypes.oneOf(['small', 'medium', 'large', 'preview', 'icon']),
144
164
  onError: PropTypes.func,
145
165
  renderFallback: PropTypes.func
146
166
  }
147
167
 
148
- ImageLoader.defaultProps = {
168
+ FileImageLoader.defaultProps = {
149
169
  linkType: 'small',
150
170
  onError: () => {}
151
171
  }
152
172
 
153
- export default withClient(ImageLoader)
173
+ export default withClient(FileImageLoader)
@@ -4,7 +4,7 @@ import { render, waitFor } from '@testing-library/react'
4
4
  import { createMockClient } from 'cozy-client'
5
5
  import logger from 'cozy-logger'
6
6
 
7
- import { ImageLoader } from './ImageLoader'
7
+ import { FileImageLoader } from '.'
8
8
  import { checkImageSource } from './checkImageSource'
9
9
 
10
10
  jest.mock('./checkImageSource', () => ({
@@ -21,6 +21,11 @@ client.collection = jest.fn(() => ({
21
21
  getDownloadLinkById: getDownloadLinkByIdMock,
22
22
  get: getMock
23
23
  }))
24
+ client.plugins.realtime = {
25
+ subscribe: jest.fn(),
26
+ unsubscribe: jest.fn(),
27
+ unsubscribeAll: jest.fn()
28
+ }
24
29
 
25
30
  const file = {
26
31
  _id: 'image',
@@ -34,11 +39,18 @@ const file = {
34
39
 
35
40
  const setup = ({ file }) => {
36
41
  const root = render(
37
- <ImageLoader
42
+ <FileImageLoader
38
43
  file={file}
39
44
  linkType="large"
40
45
  key={file.id}
41
46
  render={src => <img alt={file.name} src={src} data-testid="img_image" />}
47
+ renderFallback={() => (
48
+ <img
49
+ alt="render fallback"
50
+ src="http://url.img_image_render_fallback/"
51
+ data-testid="img_image_renderFallback"
52
+ />
53
+ )}
42
54
  client={client}
43
55
  />
44
56
  )
@@ -46,10 +58,11 @@ const setup = ({ file }) => {
46
58
  return { root }
47
59
  }
48
60
 
49
- describe('ImageLoader', () => {
61
+ describe('FileImageLoader', () => {
50
62
  afterEach(() => {
51
63
  jest.restoreAllMocks()
52
64
  })
65
+
53
66
  it('should set the source of image to links.large if no error', async () => {
54
67
  const { root } = setup({ file })
55
68
  const { getByTestId } = root
@@ -115,4 +128,30 @@ describe('ImageLoader', () => {
115
128
  const img = getByTestId('img_image')
116
129
  expect(img.src).toEqual('http://valid/')
117
130
  })
131
+
132
+ it('should render fallback component if other request failed & file is a PDF', async () => {
133
+ const file = {
134
+ _id: 'pdf',
135
+ class: 'pdf',
136
+ name: 'Demo.pdf',
137
+ mime: 'application/pdf',
138
+ links: {
139
+ icon: 'https://url.not.valid.anymore'
140
+ }
141
+ }
142
+ checkImageSource.mockRejectedValueOnce('KO')
143
+ const { root } = setup({ file })
144
+ const { getByTestId } = root
145
+ getMock.mockResolvedValue({
146
+ data: {
147
+ links: {
148
+ icon: 'http://urlnotvalidneither'
149
+ }
150
+ }
151
+ })
152
+ await waitFor(() => getByTestId('img_image_renderFallback'))
153
+
154
+ const img = getByTestId('img_image_renderFallback')
155
+ expect(img.src).toEqual('http://url.img_image_render_fallback/')
156
+ })
118
157
  })
@@ -10,6 +10,7 @@ import { useCozyTheme } from 'cozy-ui/transpiled/react/CozyTheme'
10
10
  import cloudWallpaper from '../../docs/cloud-wallpaper.jpg'
11
11
 
12
12
  const theme = useCozyTheme()
13
+ const app = { name: "Test App", slug: "testapp", type: "app" }
13
14
 
14
15
  ;
15
16
 
@@ -17,13 +18,13 @@ const theme = useCozyTheme()
17
18
  <Grid container spacing={1} style={{ background: `center / cover no-repeat url(${cloudWallpaper})` }}
18
19
  >
19
20
  <Grid item>
20
- <SquareAppIcon app="testapp" name="Normal" />
21
+ <SquareAppIcon app={app} name="Normal" />
21
22
  </Grid>
22
23
  <Grid item>
23
- <SquareAppIcon app="testapp" name="Maintenance" variant="maintenance" />
24
+ <SquareAppIcon app={app} name="Maintenance" variant="maintenance" />
24
25
  </Grid>
25
26
  <Grid item>
26
- <SquareAppIcon app="testapp" name="Error" variant="error" />
27
+ <SquareAppIcon app={app} name="Error" variant="error" />
27
28
  </Grid>
28
29
  <Grid item>
29
30
  <SquareAppIcon name="Add" variant="add" />
@@ -2,13 +2,13 @@ import React from 'react'
2
2
  import cx from 'classnames'
3
3
  import PropTypes from 'prop-types'
4
4
  import { makeStyles } from '@material-ui/styles'
5
+ import get from 'lodash/get'
5
6
 
6
7
  import AppIcon from '../AppIcon'
7
8
  import Badge from '../Badge'
8
9
  import InfosBadge from '../InfosBadge'
9
10
  import { nameToColor } from '../Avatar'
10
11
  import Typography from '../Typography'
11
- import { AppDoctype } from '../proptypes'
12
12
  import Icon from '../Icon'
13
13
  import iconPlus from '../Icons/Plus'
14
14
  import iconWarning from '../Icons/WarningCircle'
@@ -61,9 +61,15 @@ const useStyles = makeStyles(theme => ({
61
61
  }
62
62
  }))
63
63
 
64
- export const SquareAppIcon = ({ app, type, name, variant, IconContent }) => {
64
+ export const SquareAppIcon = ({
65
+ name,
66
+ variant,
67
+ IconContent,
68
+ ...appIconProps
69
+ }) => {
65
70
  const classes = useStyles()
66
- const appName = name || (app && app.name) || app || ''
71
+ const appName =
72
+ name || get(appIconProps, 'app.name') || get(appIconProps, 'app') || ''
67
73
  const letter = appName[0] || ''
68
74
 
69
75
  return (
@@ -119,7 +125,7 @@ export const SquareAppIcon = ({ app, type, name, variant, IconContent }) => {
119
125
  ) : IconContent ? (
120
126
  IconContent
121
127
  ) : (
122
- <AppIcon app={app} type={type} />
128
+ <AppIcon {...appIconProps} />
123
129
  )}
124
130
  </div>
125
131
  )}
@@ -137,7 +143,6 @@ export const SquareAppIcon = ({ app, type, name, variant, IconContent }) => {
137
143
  }
138
144
 
139
145
  SquareAppIcon.propTypes = {
140
- app: PropTypes.oneOfType([AppDoctype, PropTypes.string]),
141
146
  name: PropTypes.string,
142
147
  variant: PropTypes.oneOf([
143
148
  'ghost',
@@ -146,8 +151,7 @@ SquareAppIcon.propTypes = {
146
151
  'add',
147
152
  'shortcut'
148
153
  ]),
149
- IconContent: PropTypes.node,
150
- type: PropTypes.oneOf(['app', 'konnector'])
154
+ IconContent: PropTypes.node
151
155
  }
152
156
 
153
157
  export default SquareAppIcon
@@ -1,8 +1,9 @@
1
1
  import React, { Component } from 'react'
2
2
  import Hammer from 'hammerjs'
3
3
 
4
+ import FileImageLoader from '../FileImageLoader'
5
+
4
6
  import ViewerSpinner from './ViewerSpinner'
5
- import ImageLoader from './ImageLoader'
6
7
  import NoNetworkViewer from './NoNetworkViewer'
7
8
 
8
9
  import styles from './styles.styl'
@@ -222,7 +223,7 @@ class ImageViewer extends Component {
222
223
  <div className={styles['viewer-imageviewer']}>
223
224
  {loading && <ViewerSpinner />}
224
225
  {file && (
225
- <ImageLoader
226
+ <FileImageLoader
226
227
  file={file}
227
228
  linkType="large"
228
229
  onError={this.onImageError}
@@ -4,11 +4,11 @@ import { render, waitFor } from '@testing-library/react'
4
4
  import { BreakpointsProvider } from '../hooks/useBreakpoints'
5
5
 
6
6
  import DemoProvider from './docs/DemoProvider'
7
- import { checkImageSource } from './checkImageSource'
7
+ import { checkImageSource } from '../FileImageLoader/checkImageSource'
8
8
  import ImageViewer from './ImageViewer'
9
9
 
10
- jest.mock('./checkImageSource', () => ({
11
- ...jest.requireActual('./checkImageSource'),
10
+ jest.mock('../FileImageLoader/checkImageSource', () => ({
11
+ ...jest.requireActual('../FileImageLoader/checkImageSource'),
12
12
  checkImageSource: jest.fn()
13
13
  }))
14
14
 
@@ -7,10 +7,10 @@ import { isMobileApp } from 'cozy-device-helper'
7
7
  import Alerter from '../Alerter'
8
8
  import Spinner from '../Spinner'
9
9
  import Button from '../Button'
10
+ import FileImageLoader from '../FileImageLoader'
10
11
 
11
12
  import { withViewerLocales } from './withViewerLocales'
12
13
  import DownloadButton from './NoViewer/DownloadButton'
13
- import ImageLoader from './ImageLoader'
14
14
  import NoViewer from './NoViewer'
15
15
 
16
16
  import styles from './styles.styl'
@@ -80,7 +80,7 @@ export const PdfMobileViewer = ({ file, t, gestures }) => {
80
80
  <div className={styles['viewer-pdfMobile']}>
81
81
  {loading && <Spinner size="xxlarge" middle noMargin />}
82
82
  {file && (
83
- <ImageLoader
83
+ <FileImageLoader
84
84
  file={file}
85
85
  linkType="preview"
86
86
  onError={onImageError}
@@ -20,6 +20,11 @@ const client = createMockClient({})
20
20
  client.collection = jest.fn(() => ({
21
21
  getDownloadLinkById: jest.fn()
22
22
  }))
23
+ client.plugins.realtime = {
24
+ subscribe: jest.fn(),
25
+ unsubscribe: jest.fn(),
26
+ unsubscribeAll: jest.fn()
27
+ }
23
28
 
24
29
  const file = {
25
30
  _id: 'pdf',
package/react/index.js CHANGED
@@ -97,3 +97,4 @@ export { default as Paper } from './Paper'
97
97
  export { default as ProgressionBanner } from './ProgressionBanner'
98
98
  export { default as Fab } from './Fab'
99
99
  export { default as SquareAppIcon } from './SquareAppIcon'
100
+ export { default as FileImageLoader } from './FileImageLoader'
@@ -0,0 +1,49 @@
1
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+
4
+ /**
5
+ * @param {string} src - Image source
6
+ * @returns {Promise<void>}
7
+ */
8
+ export var checkImageSource = /*#__PURE__*/function () {
9
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(src) {
10
+ var TTL, timeout, img, cleanImageLoader;
11
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
12
+ while (1) {
13
+ switch (_context.prev = _context.next) {
14
+ case 0:
15
+ TTL = 10000;
16
+ timeout = null;
17
+ img = null;
18
+
19
+ cleanImageLoader = function cleanImageLoader() {
20
+ clearTimeout(timeout);
21
+ img.onload = img.onerror = null;
22
+ img.src = '';
23
+ img = null;
24
+ };
25
+
26
+ return _context.abrupt("return", new Promise(function (resolve, reject) {
27
+ img = new Image();
28
+ img.onload = resolve;
29
+ img.onerror = reject;
30
+ img.src = src;
31
+ timeout = setTimeout(function () {
32
+ return reject(new Error('Loading image took too long'));
33
+ }, TTL);
34
+ }).then(function () {
35
+ return cleanImageLoader();
36
+ }));
37
+
38
+ case 5:
39
+ case "end":
40
+ return _context.stop();
41
+ }
42
+ }
43
+ }, _callee);
44
+ }));
45
+
46
+ return function checkImageSource(_x) {
47
+ return _ref.apply(this, arguments);
48
+ };
49
+ }();
@@ -7,7 +7,7 @@ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
7
7
  import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
8
8
  import _inherits from "@babel/runtime/helpers/inherits";
9
9
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
10
- import React from 'react';
10
+ import { Component } from 'react';
11
11
  import PropTypes from 'prop-types';
12
12
  import { withClient } from 'cozy-client';
13
13
  import logger from 'cozy-logger';
@@ -17,22 +17,22 @@ var LOADING_FALLBACK = 'LOADING_FALLBACK';
17
17
  var LOADED = 'LOADED';
18
18
  var FAILED = 'FAILED';
19
19
  var GET_LINK = 'GET_LINK';
20
- import { checkImageSource } from "cozy-ui/transpiled/react/Viewer/checkImageSource";
21
- export var ImageLoader = /*#__PURE__*/function (_React$Component) {
22
- _inherits(ImageLoader, _React$Component);
20
+ import { checkImageSource } from "cozy-ui/transpiled/react/FileImageLoader/checkImageSource";
21
+ export var FileImageLoader = /*#__PURE__*/function (_Component) {
22
+ _inherits(FileImageLoader, _Component);
23
23
 
24
- function ImageLoader() {
24
+ function FileImageLoader() {
25
25
  var _getPrototypeOf2;
26
26
 
27
27
  var _this;
28
28
 
29
- _classCallCheck(this, ImageLoader);
29
+ _classCallCheck(this, FileImageLoader);
30
30
 
31
31
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
32
32
  args[_key] = arguments[_key];
33
33
  }
34
34
 
35
- _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(ImageLoader)).call.apply(_getPrototypeOf2, [this].concat(args)));
35
+ _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(FileImageLoader)).call.apply(_getPrototypeOf2, [this].concat(args)));
36
36
 
37
37
  _defineProperty(_assertThisInitialized(_this), "state", {
38
38
  src: null
@@ -40,15 +40,29 @@ export var ImageLoader = /*#__PURE__*/function (_React$Component) {
40
40
 
41
41
  _defineProperty(_assertThisInitialized(_this), "_mounted", false);
42
42
 
43
+ _defineProperty(_assertThisInitialized(_this), "handleCreate", function (doc) {
44
+ var _this$props = _this.props,
45
+ file = _this$props.file,
46
+ linkType = _this$props.linkType;
47
+
48
+ if (file._id === doc._id && doc.format === linkType) {
49
+ _this.loadLink();
50
+ }
51
+ });
52
+
43
53
  return _this;
44
54
  }
45
55
 
46
- _createClass(ImageLoader, [{
56
+ _createClass(FileImageLoader, [{
47
57
  key: "componentDidMount",
48
58
  value: function componentDidMount() {
59
+ var client = this.props.client;
49
60
  this._mounted = true;
50
61
  this.status = PENDING;
51
62
  this.loadNextSrc();
63
+ this.realtime = client.plugins.realtime;
64
+ this.type = 'io.cozy.files.thumbnails';
65
+ this.realtime.subscribe('created', this.type, this.handleCreate);
52
66
  }
53
67
  }, {
54
68
  key: "componentWillUnmount",
@@ -59,7 +73,14 @@ export var ImageLoader = /*#__PURE__*/function (_React$Component) {
59
73
  this.img.onload = this.img.onerror = null;
60
74
  this.img.src = '';
61
75
  }
76
+
77
+ this.realtime && this.realtime.unsubscribe('created', this.type, this.handleCreate);
62
78
  }
79
+ /**
80
+ * Reload the link when realtime tell us that the
81
+ * thumbnail is created. By default linkType === small
82
+ */
83
+
63
84
  }, {
64
85
  key: "getFileId",
65
86
  value: function getFileId(file) {
@@ -120,14 +141,14 @@ export var ImageLoader = /*#__PURE__*/function (_React$Component) {
120
141
  key: "getLink",
121
142
  value: function () {
122
143
  var _getLink = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
123
- var _this$props, file, linkType, client, link, src;
144
+ var _this$props2, file, linkType, client, link, src;
124
145
 
125
146
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
126
147
  while (1) {
127
148
  switch (_context2.prev = _context2.next) {
128
149
  case 0:
129
150
  this.status = GET_LINK;
130
- _this$props = this.props, file = _this$props.file, linkType = _this$props.linkType, client = _this$props.client;
151
+ _this$props2 = this.props, file = _this$props2.file, linkType = _this$props2.linkType, client = _this$props2.client;
131
152
  _context2.prev = 2;
132
153
  link = file.links ? file.links[linkType] : false;
133
154
 
@@ -151,16 +172,15 @@ export var ImageLoader = /*#__PURE__*/function (_React$Component) {
151
172
  });
152
173
  }
153
174
 
154
- _context2.next = 16;
175
+ _context2.next = 15;
155
176
  break;
156
177
 
157
178
  case 12:
158
179
  _context2.prev = 12;
159
180
  _context2.t0 = _context2["catch"](2);
160
- logger.error(_context2.t0);
161
181
  this.loadNextSrc(_context2.t0);
162
182
 
163
- case 16:
183
+ case 15:
164
184
  case "end":
165
185
  return _context2.stop();
166
186
  }
@@ -178,14 +198,14 @@ export var ImageLoader = /*#__PURE__*/function (_React$Component) {
178
198
  key: "loadLink",
179
199
  value: function () {
180
200
  var _loadLink = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
181
- var _this$props2, file, linkType, client, links, link, src;
201
+ var _this$props3, file, linkType, client, links, link, src;
182
202
 
183
203
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
184
204
  while (1) {
185
205
  switch (_context3.prev = _context3.next) {
186
206
  case 0:
187
207
  this.status = LOADING_LINK;
188
- _this$props2 = this.props, file = _this$props2.file, linkType = _this$props2.linkType, client = _this$props2.client;
208
+ _this$props3 = this.props, file = _this$props3.file, linkType = _this$props3.linkType, client = _this$props3.client;
189
209
  _context3.prev = 2;
190
210
  _context3.next = 5;
191
211
  return this.fetchFileLinks(file);
@@ -241,14 +261,14 @@ export var ImageLoader = /*#__PURE__*/function (_React$Component) {
241
261
  key: "loadFallback",
242
262
  value: function () {
243
263
  var _loadFallback = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
244
- var _this$props3, file, client, src;
264
+ var _this$props4, file, client, src;
245
265
 
246
266
  return _regeneratorRuntime.wrap(function _callee4$(_context4) {
247
267
  while (1) {
248
268
  switch (_context4.prev = _context4.next) {
249
269
  case 0:
250
270
  this.status = LOADING_FALLBACK;
251
- _this$props3 = this.props, file = _this$props3.file, client = _this$props3.client;
271
+ _this$props4 = this.props, file = _this$props4.file, client = _this$props4.client;
252
272
  _context4.prev = 2;
253
273
 
254
274
  if (!(file.class === 'pdf')) {
@@ -301,24 +321,24 @@ export var ImageLoader = /*#__PURE__*/function (_React$Component) {
301
321
  key: "render",
302
322
  value: function render() {
303
323
  var src = this.state.src;
304
- var _this$props4 = this.props,
305
- render = _this$props4.render,
306
- renderFallback = _this$props4.renderFallback;
324
+ var _this$props5 = this.props,
325
+ render = _this$props5.render,
326
+ renderFallback = _this$props5.renderFallback;
307
327
  if (src) return render(src);else if (renderFallback) return renderFallback();else return null;
308
328
  }
309
329
  }]);
310
330
 
311
- return ImageLoader;
312
- }(React.Component);
313
- ImageLoader.propTypes = {
331
+ return FileImageLoader;
332
+ }(Component);
333
+ FileImageLoader.propTypes = {
314
334
  file: PropTypes.object.isRequired,
315
335
  render: PropTypes.func.isRequired,
316
- linkType: PropTypes.oneOf(['small', 'medium', 'large', 'preview']),
336
+ linkType: PropTypes.oneOf(['small', 'medium', 'large', 'preview', 'icon']),
317
337
  onError: PropTypes.func,
318
338
  renderFallback: PropTypes.func
319
339
  };
320
- ImageLoader.defaultProps = {
340
+ FileImageLoader.defaultProps = {
321
341
  linkType: 'small',
322
342
  onError: function onError() {}
323
343
  };
324
- export default withClient(ImageLoader);
344
+ export default withClient(FileImageLoader);
@@ -1,14 +1,15 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
1
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  import React from 'react';
3
4
  import cx from 'classnames';
4
5
  import PropTypes from 'prop-types';
5
6
  import { makeStyles } from '@material-ui/styles';
7
+ import get from 'lodash/get';
6
8
  import AppIcon from "cozy-ui/transpiled/react/AppIcon";
7
9
  import Badge from "cozy-ui/transpiled/react/Badge";
8
10
  import InfosBadge from "cozy-ui/transpiled/react/InfosBadge";
9
11
  import { nameToColor } from "cozy-ui/transpiled/react/Avatar";
10
12
  import Typography from "cozy-ui/transpiled/react/Typography";
11
- import { AppDoctype } from "cozy-ui/transpiled/react/proptypes";
12
13
  import Icon from "cozy-ui/transpiled/react/Icon";
13
14
  import iconPlus from "cozy-ui/transpiled/react/Icons/Plus";
14
15
  import iconWarning from "cozy-ui/transpiled/react/Icons/WarningCircle";
@@ -74,13 +75,13 @@ var useStyles = makeStyles(function (theme) {
74
75
  export var SquareAppIcon = function SquareAppIcon(_ref) {
75
76
  var _cx;
76
77
 
77
- var app = _ref.app,
78
- type = _ref.type,
79
- name = _ref.name,
78
+ var name = _ref.name,
80
79
  variant = _ref.variant,
81
- IconContent = _ref.IconContent;
80
+ IconContent = _ref.IconContent,
81
+ appIconProps = _objectWithoutProperties(_ref, ["name", "variant", "IconContent"]);
82
+
82
83
  var classes = useStyles();
83
- var appName = name || app && app.name || app || '';
84
+ var appName = name || get(appIconProps, 'app.name') || get(appIconProps, 'app') || '';
84
85
  var letter = appName[0] || '';
85
86
  return React.createElement("div", {
86
87
  "data-testid": "square-app-icon",
@@ -115,20 +116,15 @@ export var SquareAppIcon = function SquareAppIcon(_ref) {
115
116
  }, variant === 'add' ? React.createElement(Icon, {
116
117
  icon: iconPlus,
117
118
  color: color
118
- }) : IconContent ? IconContent : React.createElement(AppIcon, {
119
- app: app,
120
- type: type
121
- })))), React.createElement(Typography, {
119
+ }) : IconContent ? IconContent : React.createElement(AppIcon, appIconProps)))), React.createElement(Typography, {
122
120
  className: cx(classes.name, 'u-spacellipsis'),
123
121
  variant: "h6",
124
122
  align: "center"
125
123
  }, appName));
126
124
  };
127
125
  SquareAppIcon.propTypes = {
128
- app: PropTypes.oneOfType([AppDoctype, PropTypes.string]),
129
126
  name: PropTypes.string,
130
127
  variant: PropTypes.oneOf(['ghost', 'maintenance', 'error', 'add', 'shortcut']),
131
- IconContent: PropTypes.node,
132
- type: PropTypes.oneOf(['app', 'konnector'])
128
+ IconContent: PropTypes.node
133
129
  };
134
130
  export default SquareAppIcon;
@@ -8,8 +8,8 @@ import _inherits from "@babel/runtime/helpers/inherits";
8
8
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
9
9
  import React, { Component } from 'react';
10
10
  import Hammer from 'hammerjs';
11
+ import FileImageLoader from "cozy-ui/transpiled/react/FileImageLoader";
11
12
  import ViewerSpinner from "cozy-ui/transpiled/react/Viewer/ViewerSpinner";
12
- import ImageLoader from "cozy-ui/transpiled/react/Viewer/ImageLoader";
13
13
  import NoNetworkViewer from "cozy-ui/transpiled/react/Viewer/NoNetworkViewer";
14
14
  var styles = {
15
15
  "CozyTheme--inverted": "styles__CozyTheme--inverted___1II8o",
@@ -269,7 +269,7 @@ var ImageViewer = /*#__PURE__*/function (_Component) {
269
269
  };
270
270
  return React.createElement("div", {
271
271
  className: styles['viewer-imageviewer']
272
- }, loading && React.createElement(ViewerSpinner, null), file && React.createElement(ImageLoader, {
272
+ }, loading && React.createElement(ViewerSpinner, null), file && React.createElement(FileImageLoader, {
273
273
  file: file,
274
274
  linkType: "large",
275
275
  onError: this.onImageError,
@@ -8,9 +8,9 @@ import { isMobileApp } from 'cozy-device-helper';
8
8
  import Alerter from "cozy-ui/transpiled/react/Alerter";
9
9
  import Spinner from "cozy-ui/transpiled/react/Spinner";
10
10
  import Button from "cozy-ui/transpiled/react/Button";
11
+ import FileImageLoader from "cozy-ui/transpiled/react/FileImageLoader";
11
12
  import { withViewerLocales } from "cozy-ui/transpiled/react/Viewer/withViewerLocales";
12
13
  import DownloadButton from "cozy-ui/transpiled/react/Viewer/NoViewer/DownloadButton";
13
- import ImageLoader from "cozy-ui/transpiled/react/Viewer/ImageLoader";
14
14
  import NoViewer from "cozy-ui/transpiled/react/Viewer/NoViewer";
15
15
  var styles = {
16
16
  "CozyTheme--inverted": "styles__CozyTheme--inverted___1II8o",
@@ -146,7 +146,7 @@ export var PdfMobileViewer = function PdfMobileViewer(_ref) {
146
146
  size: "xxlarge",
147
147
  middle: true,
148
148
  noMargin: true
149
- }), file && React.createElement(ImageLoader, {
149
+ }), file && React.createElement(FileImageLoader, {
150
150
  file: file,
151
151
  linkType: "preview",
152
152
  onError: onImageError,
@@ -74,4 +74,5 @@ export { default as CozyTheme } from './CozyTheme';
74
74
  export { default as Paper } from './Paper';
75
75
  export { default as ProgressionBanner } from './ProgressionBanner';
76
76
  export { default as Fab } from './Fab';
77
- export { default as SquareAppIcon } from './SquareAppIcon';
77
+ export { default as SquareAppIcon } from './SquareAppIcon';
78
+ export { default as FileImageLoader } from './FileImageLoader';
@@ -1,24 +0,0 @@
1
- var TTL = 10000;
2
- export var checkImageSource = function checkImageSource(src) {
3
- var timeout = null;
4
- var img = null;
5
-
6
- var cleanImageLoader = function cleanImageLoader() {
7
- clearTimeout(timeout);
8
- img.onload = img.onerror = null;
9
- img.src = '';
10
- img = null;
11
- };
12
-
13
- return new Promise(function (resolve, reject) {
14
- img = new Image();
15
- img.onload = resolve;
16
- img.onerror = reject;
17
- img.src = src;
18
- timeout = setTimeout(function () {
19
- return reject(new Error('Loading image took too long'));
20
- }, TTL);
21
- }).then(function () {
22
- return cleanImageLoader();
23
- });
24
- };