@performant-software/semantic-components 0.5.15 → 0.5.16-beta.10
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/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/main.css +43 -0
- package/package.json +3 -3
- package/src/components/AudioPlayer.css +3 -0
- package/src/components/AudioPlayer.js +54 -0
- package/src/components/DownloadButton.js +63 -12
- package/src/components/IIIFModal.js +26 -0
- package/src/components/LazyAudio.css +23 -0
- package/src/components/LazyAudio.js +150 -0
- package/src/components/LazyDocument.css +2 -0
- package/src/components/LazyDocument.js +29 -20
- package/src/components/LazyIIIF.js +44 -0
- package/src/components/LazyImage.css +3 -1
- package/src/components/LazyImage.js +40 -11
- package/src/components/LazyLoader.css +7 -0
- package/src/components/LazyLoader.js +28 -0
- package/src/components/LazyMedia.js +244 -0
- package/src/components/LazyVideo.css +8 -1
- package/src/components/LazyVideo.js +40 -5
- package/src/components/PhotoViewer.js +38 -25
- package/src/components/VideoPlayer.js +23 -2
- package/src/i18n/en.json +35 -3
- package/src/index.js +5 -0
- package/types/components/AudioPlayer.js.flow +54 -0
- package/types/components/DownloadButton.js.flow +63 -12
- package/types/components/IIIFModal.js.flow +26 -0
- package/types/components/LazyAudio.js.flow +150 -0
- package/types/components/LazyDocument.js.flow +29 -20
- package/types/components/LazyIIIF.js.flow +44 -0
- package/types/components/LazyImage.js.flow +40 -11
- package/types/components/LazyLoader.js.flow +28 -0
- package/types/components/LazyMedia.js.flow +244 -0
- package/types/components/LazyVideo.js.flow +40 -5
- package/types/components/PhotoViewer.js.flow +38 -25
- package/types/components/VideoPlayer.js.flow +23 -2
- package/types/index.js.flow +5 -0
package/src/i18n/en.json
CHANGED
|
@@ -8,15 +8,26 @@
|
|
|
8
8
|
"AccordionSelector": {
|
|
9
9
|
"title": "Select Items"
|
|
10
10
|
},
|
|
11
|
+
"AudioPlayer": {
|
|
12
|
+
"errors": {
|
|
13
|
+
"path": {
|
|
14
|
+
"content": "Please check the audio path: {{path}}",
|
|
15
|
+
"header": "There was a problem loading the audio"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
11
19
|
"Common": {
|
|
12
20
|
"buttons": {
|
|
13
21
|
"add": "Add",
|
|
14
22
|
"cancel": "Cancel",
|
|
15
23
|
"clear": "Clear",
|
|
16
24
|
"close": "Close",
|
|
25
|
+
"download": "Download",
|
|
17
26
|
"edit": "Edit",
|
|
18
27
|
"ok": "OK",
|
|
19
|
-
"
|
|
28
|
+
"open": "Open",
|
|
29
|
+
"save": "Save",
|
|
30
|
+
"upload": "Upload"
|
|
20
31
|
},
|
|
21
32
|
"errors": {
|
|
22
33
|
"title": "Oops!"
|
|
@@ -135,9 +146,9 @@
|
|
|
135
146
|
"value": "Value"
|
|
136
147
|
}
|
|
137
148
|
},
|
|
138
|
-
"
|
|
149
|
+
"LazyAudio": {
|
|
139
150
|
"buttons": {
|
|
140
|
-
"
|
|
151
|
+
"play": "Play"
|
|
141
152
|
}
|
|
142
153
|
},
|
|
143
154
|
"LazyImage": {
|
|
@@ -145,6 +156,11 @@
|
|
|
145
156
|
"view": "View image"
|
|
146
157
|
}
|
|
147
158
|
},
|
|
159
|
+
"LazyMedia": {
|
|
160
|
+
"messages": {
|
|
161
|
+
"uploaded": "Your <bold>{{type}}</bold> has been received"
|
|
162
|
+
}
|
|
163
|
+
},
|
|
148
164
|
"LazyVideo": {
|
|
149
165
|
"buttons": {
|
|
150
166
|
"play": "Play video"
|
|
@@ -193,6 +209,14 @@
|
|
|
193
209
|
"loginErrorHeader": "Invalid Credentials",
|
|
194
210
|
"password": "Password"
|
|
195
211
|
},
|
|
212
|
+
"PhotoViewer": {
|
|
213
|
+
"errors": {
|
|
214
|
+
"path": {
|
|
215
|
+
"content": "Please check the image path: {{path}}",
|
|
216
|
+
"header": "There was a problem loading the image"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
},
|
|
196
220
|
"ReferenceCodeFormLabel": {
|
|
197
221
|
"content": "The values in this list can be edited via the {{name}} reference table."
|
|
198
222
|
},
|
|
@@ -240,6 +264,14 @@
|
|
|
240
264
|
},
|
|
241
265
|
"title": "Select Frame"
|
|
242
266
|
},
|
|
267
|
+
"VideoPlayer": {
|
|
268
|
+
"errors": {
|
|
269
|
+
"path": {
|
|
270
|
+
"content": "Please check the video path: {{path}}",
|
|
271
|
+
"header": "There was a problem loading the video"
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
},
|
|
243
275
|
"ViewXML": {
|
|
244
276
|
"buttons": {
|
|
245
277
|
"view": "View XML"
|
package/src/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { default as AccordionList } from './components/AccordionList';
|
|
|
9
9
|
export { default as AccordionSelector } from './components/AccordionSelector';
|
|
10
10
|
export { default as ArrowButtons } from './components/ArrowButtons';
|
|
11
11
|
export { default as AssociatedDropdown } from './components/AssociatedDropdown';
|
|
12
|
+
export { default as AudioPlayer } from './components/AudioPlayer';
|
|
12
13
|
export { default as BooleanIcon } from './components/BooleanIcon';
|
|
13
14
|
export { default as CancelButton } from './components/CancelButton';
|
|
14
15
|
export { default as ColorButton } from './components/ColorButton';
|
|
@@ -34,13 +35,17 @@ export { default as FuzzyDate } from './components/FuzzyDate';
|
|
|
34
35
|
export { default as GoogleMap } from './components/GoogleMap';
|
|
35
36
|
export { default as GooglePlacesSearch } from './components/GooglePlacesSearch';
|
|
36
37
|
export { default as HorizontalCards } from './components/HorizontalCards';
|
|
38
|
+
export { default as IIIFModal } from './components/IIIFModal';
|
|
37
39
|
export { default as ItemCollection } from './components/ItemCollection';
|
|
38
40
|
export { default as ItemList } from './components/ItemList';
|
|
39
41
|
export { default as Items } from './components/Items';
|
|
40
42
|
export { default as KeyboardField } from './components/KeyboardField';
|
|
41
43
|
export { default as KeyValuePairs } from './components/KeyValuePairs';
|
|
44
|
+
export { default as LazyAudio } from './components/LazyAudio';
|
|
42
45
|
export { default as LazyDocument } from './components/LazyDocument';
|
|
46
|
+
export { default as LazyIIIF } from './components/LazyIIIF';
|
|
43
47
|
export { default as LazyImage } from './components/LazyImage';
|
|
48
|
+
export { default as LazyMedia } from './components/LazyMedia';
|
|
44
49
|
export { default as LazyVideo } from './components/LazyVideo';
|
|
45
50
|
export { default as LinkButton } from './components/LinkButton';
|
|
46
51
|
export { default as ListFilters } from './components/ListFilters';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Button, Message, Modal } from 'semantic-ui-react';
|
|
5
|
+
import i18n from '../i18n/i18n';
|
|
6
|
+
import ModalContext from '../context/ModalContext';
|
|
7
|
+
import './AudioPlayer.css';
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
centered?: boolean,
|
|
11
|
+
onClose: () => void,
|
|
12
|
+
open: boolean,
|
|
13
|
+
src: string
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const AudioPlayer = (props: Props) => {
|
|
17
|
+
const [error, setError] = useState(false);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<ModalContext.Consumer>
|
|
21
|
+
{(mountNode) => (
|
|
22
|
+
<Modal
|
|
23
|
+
centered={props.centered}
|
|
24
|
+
className='audio-player'
|
|
25
|
+
mountNode={mountNode}
|
|
26
|
+
open={props.open}
|
|
27
|
+
>
|
|
28
|
+
<Modal.Content>
|
|
29
|
+
{ error && (
|
|
30
|
+
<Message
|
|
31
|
+
content={i18n.t('AudioPlayer.errors.path.content', { path: props.src })}
|
|
32
|
+
header={i18n.t('AudioPlayer.errors.path.header')}
|
|
33
|
+
icon='exclamation circle'
|
|
34
|
+
/>
|
|
35
|
+
)}
|
|
36
|
+
<audio
|
|
37
|
+
controls
|
|
38
|
+
onError={() => setError(true)}
|
|
39
|
+
src={props.src}
|
|
40
|
+
/>
|
|
41
|
+
</Modal.Content>
|
|
42
|
+
<Modal.Actions>
|
|
43
|
+
<Button
|
|
44
|
+
content={i18n.t('Common.buttons.close')}
|
|
45
|
+
onClick={props.onClose}
|
|
46
|
+
/>
|
|
47
|
+
</Modal.Actions>
|
|
48
|
+
</Modal>
|
|
49
|
+
)}
|
|
50
|
+
</ModalContext.Consumer>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default AudioPlayer;
|
|
@@ -1,23 +1,74 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
4
|
import uuid from 'react-uuid';
|
|
5
|
-
import {
|
|
5
|
+
import { Icon } from 'semantic-ui-react';
|
|
6
|
+
import i18n from '../i18n/i18n';
|
|
6
7
|
|
|
7
8
|
type Props = {
|
|
9
|
+
basic?: boolean,
|
|
10
|
+
className?: string,
|
|
11
|
+
color?: string,
|
|
12
|
+
compact?: boolean,
|
|
8
13
|
filename?: string,
|
|
14
|
+
primary?: boolean,
|
|
15
|
+
size?: string,
|
|
16
|
+
secondary?: boolean,
|
|
9
17
|
url: string
|
|
10
18
|
};
|
|
11
19
|
|
|
12
|
-
const DownloadButton = (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
20
|
+
const DownloadButton = (props: Props) => {
|
|
21
|
+
/**
|
|
22
|
+
* Sets the appropriate class names based on the formatting props.
|
|
23
|
+
*
|
|
24
|
+
* @type {string}
|
|
25
|
+
*/
|
|
26
|
+
const className = useMemo(() => {
|
|
27
|
+
const classNames = ['ui', 'button'];
|
|
28
|
+
|
|
29
|
+
if (props.basic) {
|
|
30
|
+
classNames.push('basic');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (props.className) {
|
|
34
|
+
classNames.push(...props.className.split(' '));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (props.color) {
|
|
38
|
+
classNames.push(props.color);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (props.compact) {
|
|
42
|
+
classNames.push('compact');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (props.primary) {
|
|
46
|
+
classNames.push('primary');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (props.secondary) {
|
|
50
|
+
classNames.push('secondary');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (props.size) {
|
|
54
|
+
classNames.push(props.size);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return classNames.join(' ');
|
|
58
|
+
}, [props.basic, props.color]);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<a
|
|
62
|
+
className={className}
|
|
63
|
+
download={props.filename || uuid()}
|
|
64
|
+
href={props.url}
|
|
65
|
+
>
|
|
66
|
+
<Icon
|
|
67
|
+
name='cloud download'
|
|
68
|
+
/>
|
|
69
|
+
{ i18n.t('Common.buttons.download') }
|
|
70
|
+
</a>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
22
73
|
|
|
23
74
|
export default DownloadButton;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Modal } from 'semantic-ui-react';
|
|
5
|
+
import { IIIFViewer } from '@performant-software/shared-components';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
onClose: () => void
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const IIIFModal = ({ onClose, ...props }: Props) => (
|
|
12
|
+
<Modal
|
|
13
|
+
centered={false}
|
|
14
|
+
closeIcon
|
|
15
|
+
onClose={onClose}
|
|
16
|
+
open
|
|
17
|
+
>
|
|
18
|
+
<Modal.Content>
|
|
19
|
+
<IIIFViewer
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
</Modal.Content>
|
|
23
|
+
</Modal>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export default IIIFModal;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useState, type Node } from 'react';
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
Dimmer,
|
|
7
|
+
Icon,
|
|
8
|
+
Image,
|
|
9
|
+
Loader,
|
|
10
|
+
Segment,
|
|
11
|
+
Transition,
|
|
12
|
+
Visibility
|
|
13
|
+
} from 'semantic-ui-react';
|
|
14
|
+
import i18n from '../i18n/i18n';
|
|
15
|
+
import AudioPlayer from './AudioPlayer';
|
|
16
|
+
import DownloadButton from './DownloadButton';
|
|
17
|
+
import LazyLoader from './LazyLoader';
|
|
18
|
+
import './LazyAudio.css';
|
|
19
|
+
|
|
20
|
+
type Props = {
|
|
21
|
+
children?: Node,
|
|
22
|
+
dimmable: boolean,
|
|
23
|
+
download?: string,
|
|
24
|
+
duration?: number,
|
|
25
|
+
image?: any,
|
|
26
|
+
name?: string,
|
|
27
|
+
preview?: string,
|
|
28
|
+
size?: string,
|
|
29
|
+
src?: string
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const LazyAudio = (props: Props) => {
|
|
33
|
+
const [dimmer, setDimmer] = useState(false);
|
|
34
|
+
const [error, setError] = useState(false);
|
|
35
|
+
const [loaded, setLoaded] = useState(!props.preview);
|
|
36
|
+
const [modal, setModal] = useState(false);
|
|
37
|
+
const [visible, setVisible] = useState(false);
|
|
38
|
+
|
|
39
|
+
if (!visible) {
|
|
40
|
+
return (
|
|
41
|
+
<Visibility
|
|
42
|
+
as='span'
|
|
43
|
+
fireOnMount
|
|
44
|
+
onTopVisible={() => setVisible(true)}
|
|
45
|
+
>
|
|
46
|
+
<Loader
|
|
47
|
+
active
|
|
48
|
+
inline='centered'
|
|
49
|
+
size={props.size}
|
|
50
|
+
/>
|
|
51
|
+
</Visibility>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<>
|
|
57
|
+
<Transition
|
|
58
|
+
duration={props.duration}
|
|
59
|
+
visible
|
|
60
|
+
>
|
|
61
|
+
<Dimmer.Dimmable
|
|
62
|
+
as={Segment}
|
|
63
|
+
className='lazy-audio'
|
|
64
|
+
compact
|
|
65
|
+
onBlur={() => setDimmer(false)}
|
|
66
|
+
onMouseEnter={() => setDimmer(true)}
|
|
67
|
+
onMouseLeave={() => setDimmer(false)}
|
|
68
|
+
>
|
|
69
|
+
{ !loaded && (
|
|
70
|
+
<LazyLoader
|
|
71
|
+
active
|
|
72
|
+
size={props.size}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
{ !error && props.preview && (
|
|
76
|
+
<Image
|
|
77
|
+
{...props.image}
|
|
78
|
+
onError={() => {
|
|
79
|
+
setError(true);
|
|
80
|
+
setLoaded(true);
|
|
81
|
+
}}
|
|
82
|
+
onLoad={() => {
|
|
83
|
+
setError(false);
|
|
84
|
+
setLoaded(true);
|
|
85
|
+
}}
|
|
86
|
+
size={props.size}
|
|
87
|
+
src={props.preview}
|
|
88
|
+
/>
|
|
89
|
+
)}
|
|
90
|
+
{ (error || !props.preview) && (
|
|
91
|
+
<Image
|
|
92
|
+
{...props.image}
|
|
93
|
+
className='placeholder-image'
|
|
94
|
+
size={props.size}
|
|
95
|
+
>
|
|
96
|
+
<Icon
|
|
97
|
+
name='file audio outline'
|
|
98
|
+
size='big'
|
|
99
|
+
/>
|
|
100
|
+
</Image>
|
|
101
|
+
)}
|
|
102
|
+
{ (props.src || props.children) && props.dimmable && (
|
|
103
|
+
<Dimmer
|
|
104
|
+
active={dimmer}
|
|
105
|
+
>
|
|
106
|
+
<div
|
|
107
|
+
className='buttons'
|
|
108
|
+
>
|
|
109
|
+
{ props.src && (
|
|
110
|
+
<Button
|
|
111
|
+
content={i18n.t('LazyAudio.buttons.play')}
|
|
112
|
+
icon='play circle outline'
|
|
113
|
+
onClick={() => setModal(true)}
|
|
114
|
+
primary
|
|
115
|
+
/>
|
|
116
|
+
)}
|
|
117
|
+
{ props.download && (
|
|
118
|
+
<DownloadButton
|
|
119
|
+
color='green'
|
|
120
|
+
filename={props.name}
|
|
121
|
+
url={props.download}
|
|
122
|
+
/>
|
|
123
|
+
)}
|
|
124
|
+
{ props.children }
|
|
125
|
+
</div>
|
|
126
|
+
</Dimmer>
|
|
127
|
+
)}
|
|
128
|
+
</Dimmer.Dimmable>
|
|
129
|
+
</Transition>
|
|
130
|
+
{ props.src && (
|
|
131
|
+
<AudioPlayer
|
|
132
|
+
onClose={() => setModal(false)}
|
|
133
|
+
open={modal}
|
|
134
|
+
size='large'
|
|
135
|
+
src={props.src}
|
|
136
|
+
/>
|
|
137
|
+
)}
|
|
138
|
+
</>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
LazyAudio.defaultProps = {
|
|
143
|
+
dimmable: true,
|
|
144
|
+
duration: 1000,
|
|
145
|
+
preview: undefined,
|
|
146
|
+
size: 'medium',
|
|
147
|
+
src: undefined
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export default LazyAudio;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, { useState,
|
|
3
|
+
import React, { useState, type Node } from 'react';
|
|
4
4
|
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack';
|
|
5
5
|
import {
|
|
6
6
|
Dimmer,
|
|
@@ -11,32 +11,27 @@ import {
|
|
|
11
11
|
Transition,
|
|
12
12
|
Visibility
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
|
-
import i18n from '../i18n/i18n';
|
|
15
14
|
import DownloadButton from './DownloadButton';
|
|
15
|
+
import LazyLoader from './LazyLoader';
|
|
16
16
|
import './LazyDocument.css';
|
|
17
17
|
|
|
18
18
|
type Props = {
|
|
19
19
|
children?: Node,
|
|
20
20
|
dimmable?: boolean,
|
|
21
|
+
download?: string,
|
|
21
22
|
duration?: number,
|
|
22
23
|
image?: any,
|
|
24
|
+
pdf?: boolean,
|
|
23
25
|
preview?: ?string,
|
|
24
26
|
size?: string,
|
|
25
27
|
src?: string
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
const LazyDocument = (props: Props) => {
|
|
29
|
-
const [visible, setVisible] = useState(false);
|
|
30
31
|
const [dimmer, setDimmer] = useState(false);
|
|
31
|
-
const [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (props.src && !props.preview) {
|
|
35
|
-
fetch(props.src)
|
|
36
|
-
.then((response) => response.blob())
|
|
37
|
-
.then((blob) => setContentType(blob.type));
|
|
38
|
-
}
|
|
39
|
-
}, [props.preview, props.src]);
|
|
32
|
+
const [error, setError] = useState(false);
|
|
33
|
+
const [loaded, setLoaded] = useState(!props.preview);
|
|
34
|
+
const [visible, setVisible] = useState(false);
|
|
40
35
|
|
|
41
36
|
if (!visible) {
|
|
42
37
|
return (
|
|
@@ -68,20 +63,35 @@ const LazyDocument = (props: Props) => {
|
|
|
68
63
|
onMouseEnter={() => setDimmer(true)}
|
|
69
64
|
onMouseLeave={() => setDimmer(false)}
|
|
70
65
|
>
|
|
71
|
-
{
|
|
66
|
+
{ !loaded && (
|
|
67
|
+
<LazyLoader
|
|
68
|
+
active
|
|
69
|
+
size={props.size}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
{ !error && props.preview && (
|
|
72
73
|
<Image
|
|
73
74
|
{...props.image}
|
|
75
|
+
onError={() => {
|
|
76
|
+
setError(true);
|
|
77
|
+
setLoaded(true);
|
|
78
|
+
}}
|
|
79
|
+
onLoad={() => {
|
|
80
|
+
setError(false);
|
|
81
|
+
setLoaded(true);
|
|
82
|
+
}}
|
|
74
83
|
src={props.preview}
|
|
75
84
|
size={props.size}
|
|
76
85
|
/>
|
|
77
86
|
)}
|
|
78
|
-
{ !props.preview && props.src &&
|
|
87
|
+
{ !error && loaded && !props.preview && props.src && props.pdf && (
|
|
79
88
|
<Image
|
|
80
89
|
{...props.image}
|
|
81
90
|
size={props.size}
|
|
82
91
|
>
|
|
83
92
|
<Document
|
|
84
93
|
file={props.src}
|
|
94
|
+
onLoadError={(e) => console.log(e.message)}
|
|
85
95
|
>
|
|
86
96
|
<Page
|
|
87
97
|
pageNumber={1}
|
|
@@ -89,7 +99,7 @@ const LazyDocument = (props: Props) => {
|
|
|
89
99
|
</Document>
|
|
90
100
|
</Image>
|
|
91
101
|
)}
|
|
92
|
-
{ !props.preview && (
|
|
102
|
+
{ (error || (!props.preview && !(props.src && props.pdf))) && (
|
|
93
103
|
<Image
|
|
94
104
|
{...props.image}
|
|
95
105
|
className='placeholder-image'
|
|
@@ -101,19 +111,17 @@ const LazyDocument = (props: Props) => {
|
|
|
101
111
|
/>
|
|
102
112
|
</Image>
|
|
103
113
|
)}
|
|
104
|
-
{ (props.src || props.children) && props.dimmable && (
|
|
114
|
+
{ (props.download || props.src || props.children) && props.dimmable && (
|
|
105
115
|
<Dimmer
|
|
106
116
|
active={dimmer}
|
|
107
117
|
>
|
|
108
118
|
<div
|
|
109
119
|
className='buttons'
|
|
110
120
|
>
|
|
111
|
-
{ props.
|
|
121
|
+
{ props.download && (
|
|
112
122
|
<DownloadButton
|
|
113
|
-
content={i18n.t('LazyDocument.buttons.download')}
|
|
114
|
-
icon='cloud download'
|
|
115
123
|
primary
|
|
116
|
-
url={props.
|
|
124
|
+
url={props.download || props.src}
|
|
117
125
|
/>
|
|
118
126
|
)}
|
|
119
127
|
{ props.children }
|
|
@@ -129,6 +137,7 @@ const LazyDocument = (props: Props) => {
|
|
|
129
137
|
LazyDocument.defaultProps = {
|
|
130
138
|
dimmable: true,
|
|
131
139
|
duration: 1000,
|
|
140
|
+
pdf: false,
|
|
132
141
|
preview: undefined,
|
|
133
142
|
size: 'medium',
|
|
134
143
|
src: undefined
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useState, type Node } from 'react';
|
|
4
|
+
import { Button } from 'semantic-ui-react';
|
|
5
|
+
import _ from 'underscore';
|
|
6
|
+
import i18n from '../i18n/i18n';
|
|
7
|
+
import IIIFModal from './IIIFModal';
|
|
8
|
+
import LazyMedia from './LazyMedia';
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
children?: Node,
|
|
12
|
+
manifest?: string,
|
|
13
|
+
options?: any
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const LazyIIIF = ({ manifest, options = {}, ...props }: Props) => {
|
|
17
|
+
const [modal, setModal] = useState(false);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
<LazyMedia
|
|
22
|
+
{...props}
|
|
23
|
+
>
|
|
24
|
+
{ manifest && (
|
|
25
|
+
<Button
|
|
26
|
+
content={i18n.t('Common.buttons.open')}
|
|
27
|
+
icon='images outline'
|
|
28
|
+
onClick={() => setModal(true)}
|
|
29
|
+
/>
|
|
30
|
+
)}
|
|
31
|
+
{ props.children }
|
|
32
|
+
</LazyMedia>
|
|
33
|
+
{ modal && (
|
|
34
|
+
<IIIFModal
|
|
35
|
+
manifestId={manifest}
|
|
36
|
+
onClose={() => setModal(false)}
|
|
37
|
+
options={_.defaults(options, { showIIIFBadge: false })}
|
|
38
|
+
/>
|
|
39
|
+
)}
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default LazyIIIF;
|
|
@@ -12,23 +12,29 @@ import {
|
|
|
12
12
|
Visibility
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
14
|
import i18n from '../i18n/i18n';
|
|
15
|
+
import DownloadButton from './DownloadButton';
|
|
16
|
+
import LazyLoader from './LazyLoader';
|
|
15
17
|
import PhotoViewer from './PhotoViewer';
|
|
16
18
|
import './LazyImage.css';
|
|
17
19
|
|
|
18
20
|
type Props = {
|
|
19
21
|
children?: Node,
|
|
20
22
|
dimmable: boolean,
|
|
23
|
+
download?: string,
|
|
21
24
|
duration?: number,
|
|
22
25
|
image?: any,
|
|
26
|
+
name?: string,
|
|
23
27
|
preview?: string,
|
|
24
28
|
size?: string,
|
|
25
29
|
src?: string
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
const LazyImage = (props: Props) => {
|
|
29
|
-
const [visible, setVisible] = useState(false);
|
|
30
|
-
const [modal, setModal] = useState(false);
|
|
31
33
|
const [dimmer, setDimmer] = useState(false);
|
|
34
|
+
const [error, setError] = useState(false);
|
|
35
|
+
const [loaded, setLoaded] = useState(!(props.src || props.preview));
|
|
36
|
+
const [modal, setModal] = useState(false);
|
|
37
|
+
const [visible, setVisible] = useState(false);
|
|
32
38
|
|
|
33
39
|
if (!visible) {
|
|
34
40
|
return (
|
|
@@ -60,14 +66,28 @@ const LazyImage = (props: Props) => {
|
|
|
60
66
|
onMouseEnter={() => setDimmer(true)}
|
|
61
67
|
onMouseLeave={() => setDimmer(false)}
|
|
62
68
|
>
|
|
63
|
-
{
|
|
69
|
+
{ !loaded && (
|
|
70
|
+
<LazyLoader
|
|
71
|
+
active
|
|
72
|
+
size={props.size}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
{ !error && (props.preview || props.src) && (
|
|
64
76
|
<Image
|
|
65
77
|
{...props.image}
|
|
78
|
+
onError={() => {
|
|
79
|
+
setError(true);
|
|
80
|
+
setLoaded(true);
|
|
81
|
+
}}
|
|
82
|
+
onLoad={() => {
|
|
83
|
+
setError(false);
|
|
84
|
+
setLoaded(true);
|
|
85
|
+
}}
|
|
66
86
|
size={props.size}
|
|
67
87
|
src={props.preview || props.src}
|
|
68
88
|
/>
|
|
69
89
|
)}
|
|
70
|
-
{ !props.src && (
|
|
90
|
+
{ (error || !(props.preview || props.src)) && (
|
|
71
91
|
<Image
|
|
72
92
|
{...props.image}
|
|
73
93
|
className='placeholder-image'
|
|
@@ -79,7 +99,7 @@ const LazyImage = (props: Props) => {
|
|
|
79
99
|
/>
|
|
80
100
|
</Image>
|
|
81
101
|
)}
|
|
82
|
-
{ (props.src || props.children) && props.dimmable && (
|
|
102
|
+
{ !error && (props.src || props.children) && props.dimmable && (
|
|
83
103
|
<Dimmer
|
|
84
104
|
active={dimmer}
|
|
85
105
|
>
|
|
@@ -94,18 +114,27 @@ const LazyImage = (props: Props) => {
|
|
|
94
114
|
primary
|
|
95
115
|
/>
|
|
96
116
|
)}
|
|
117
|
+
{ props.download && (
|
|
118
|
+
<DownloadButton
|
|
119
|
+
color='green'
|
|
120
|
+
filename={props.name}
|
|
121
|
+
url={props.download}
|
|
122
|
+
/>
|
|
123
|
+
)}
|
|
97
124
|
{ props.children }
|
|
98
125
|
</div>
|
|
99
126
|
</Dimmer>
|
|
100
127
|
)}
|
|
101
128
|
</Dimmer.Dimmable>
|
|
102
129
|
</Transition>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
130
|
+
{ props.src && (
|
|
131
|
+
<PhotoViewer
|
|
132
|
+
image={props.src}
|
|
133
|
+
onClose={() => setModal(false)}
|
|
134
|
+
open={modal}
|
|
135
|
+
size='large'
|
|
136
|
+
/>
|
|
137
|
+
)}
|
|
109
138
|
</>
|
|
110
139
|
);
|
|
111
140
|
};
|