@performant-software/semantic-components 0.5.16-beta.0 → 0.5.16-beta.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/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/main.css +8 -0
- package/package.json +4 -6
- package/src/components/AudioPlayer.js +40 -22
- package/src/components/LazyAudio.js +21 -4
- package/src/components/LazyDocument.js +20 -3
- package/src/components/LazyImage.js +22 -5
- package/src/components/LazyLoader.css +7 -0
- package/src/components/LazyLoader.js +28 -0
- package/src/components/LazyVideo.js +30 -5
- package/src/components/PhotoViewer.js +38 -25
- package/src/components/VideoPlayer.js +23 -2
- package/src/i18n/en.json +24 -0
- package/types/components/AudioPlayer.js.flow +40 -22
- package/types/components/LazyAudio.js.flow +21 -4
- package/types/components/LazyDocument.js.flow +20 -3
- package/types/components/LazyImage.js.flow +22 -5
- package/types/components/LazyLoader.js.flow +28 -0
- package/types/components/LazyVideo.js.flow +30 -5
- package/types/components/PhotoViewer.js.flow +38 -25
- package/types/components/VideoPlayer.js.flow +23 -2
package/build/main.css
CHANGED
|
@@ -422,6 +422,14 @@ div.react-calendar {
|
|
|
422
422
|
left: 4px;
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
+
.lazy-loader {
|
|
426
|
+
background-color: #f9fafb;
|
|
427
|
+
box-shadow: 0 1px 3px 0 #d4d4d5, 0 0 0 1px #d4d4d5;
|
|
428
|
+
padding-top: 20%;
|
|
429
|
+
padding-bottom: 20%;
|
|
430
|
+
text-align: center;
|
|
431
|
+
}
|
|
432
|
+
|
|
425
433
|
.lazy-audio.ui.segment {
|
|
426
434
|
display: inline-block !important;
|
|
427
435
|
max-width: 100%;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@performant-software/semantic-components",
|
|
3
|
-
"version": "0.5.16-beta.
|
|
3
|
+
"version": "0.5.16-beta.1",
|
|
4
4
|
"description": "A package of shared components based on the Semantic UI Framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -9,12 +9,10 @@
|
|
|
9
9
|
"./build/semantic-ui.css"
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "webpack --mode production && flow-copy-source -v src types"
|
|
13
|
-
"publish": "npm publish",
|
|
14
|
-
"publish-beta": "npm publish --tag beta"
|
|
12
|
+
"build": "webpack --mode production && flow-copy-source -v src types"
|
|
15
13
|
},
|
|
16
14
|
"dependencies": {
|
|
17
|
-
"@performant-software/shared-components": "^0.5.16-beta.
|
|
15
|
+
"@performant-software/shared-components": "^0.5.16-beta.1",
|
|
18
16
|
"@react-google-maps/api": "^2.8.1",
|
|
19
17
|
"axios": "^0.26.1",
|
|
20
18
|
"i18next": "^19.4.4",
|
|
@@ -35,7 +33,7 @@
|
|
|
35
33
|
"react-dom": ">= 16.13.1 < 18.0.0"
|
|
36
34
|
},
|
|
37
35
|
"devDependencies": {
|
|
38
|
-
"@performant-software/webpack-config": "^0.5.16-beta.
|
|
36
|
+
"@performant-software/webpack-config": "^0.5.16-beta.1",
|
|
39
37
|
"flow-copy-source": "^2.0.9",
|
|
40
38
|
"less": "^4.1.2",
|
|
41
39
|
"less-loader": "^11.0.0",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { Button, Modal } from 'semantic-ui-react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Button, Message, Modal } from 'semantic-ui-react';
|
|
5
5
|
import i18n from '../i18n/i18n';
|
|
6
|
+
import ModalContext from '../context/ModalContext';
|
|
6
7
|
import './AudioPlayer.css';
|
|
7
8
|
|
|
8
9
|
type Props = {
|
|
@@ -12,25 +13,42 @@ type Props = {
|
|
|
12
13
|
src: string
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
const AudioPlayer = (props: Props) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
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
|
+
};
|
|
35
53
|
|
|
36
54
|
export default AudioPlayer;
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
14
|
import i18n from '../i18n/i18n';
|
|
15
15
|
import AudioPlayer from './AudioPlayer';
|
|
16
|
+
import LazyLoader from './LazyLoader';
|
|
16
17
|
import './LazyAudio.css';
|
|
17
18
|
|
|
18
19
|
type Props = {
|
|
@@ -26,9 +27,11 @@ type Props = {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
const LazyAudio = (props: Props) => {
|
|
29
|
-
const [visible, setVisible] = useState(false);
|
|
30
|
-
const [modal, setModal] = useState(false);
|
|
31
30
|
const [dimmer, setDimmer] = useState(false);
|
|
31
|
+
const [error, setError] = useState(false);
|
|
32
|
+
const [loaded, setLoaded] = useState(!props.preview);
|
|
33
|
+
const [modal, setModal] = useState(false);
|
|
34
|
+
const [visible, setVisible] = useState(false);
|
|
32
35
|
|
|
33
36
|
if (!visible) {
|
|
34
37
|
return (
|
|
@@ -60,14 +63,28 @@ const LazyAudio = (props: Props) => {
|
|
|
60
63
|
onMouseEnter={() => setDimmer(true)}
|
|
61
64
|
onMouseLeave={() => setDimmer(false)}
|
|
62
65
|
>
|
|
63
|
-
{
|
|
66
|
+
{ !loaded && (
|
|
67
|
+
<LazyLoader
|
|
68
|
+
active
|
|
69
|
+
size={props.size}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
{ !error && props.preview && (
|
|
64
73
|
<Image
|
|
65
74
|
{...props.image}
|
|
75
|
+
onError={() => {
|
|
76
|
+
setError(true);
|
|
77
|
+
setLoaded(true);
|
|
78
|
+
}}
|
|
79
|
+
onLoad={() => {
|
|
80
|
+
setError(false);
|
|
81
|
+
setLoaded(true);
|
|
82
|
+
}}
|
|
66
83
|
size={props.size}
|
|
67
84
|
src={props.preview}
|
|
68
85
|
/>
|
|
69
86
|
)}
|
|
70
|
-
{ !props.preview && (
|
|
87
|
+
{ (error || !props.preview) && (
|
|
71
88
|
<Image
|
|
72
89
|
{...props.image}
|
|
73
90
|
className='placeholder-image'
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
14
|
import i18n from '../i18n/i18n';
|
|
15
15
|
import DownloadButton from './DownloadButton';
|
|
16
|
+
import LazyLoader from './LazyLoader';
|
|
16
17
|
import './LazyDocument.css';
|
|
17
18
|
|
|
18
19
|
type Props = {
|
|
@@ -27,8 +28,10 @@ type Props = {
|
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
const LazyDocument = (props: Props) => {
|
|
30
|
-
const [visible, setVisible] = useState(false);
|
|
31
31
|
const [dimmer, setDimmer] = useState(false);
|
|
32
|
+
const [error, setError] = useState(false);
|
|
33
|
+
const [loaded, setLoaded] = useState(!props.preview);
|
|
34
|
+
const [visible, setVisible] = useState(false);
|
|
32
35
|
|
|
33
36
|
if (!visible) {
|
|
34
37
|
return (
|
|
@@ -60,9 +63,23 @@ const LazyDocument = (props: Props) => {
|
|
|
60
63
|
onMouseEnter={() => setDimmer(true)}
|
|
61
64
|
onMouseLeave={() => setDimmer(false)}
|
|
62
65
|
>
|
|
63
|
-
{
|
|
66
|
+
{ !loaded && (
|
|
67
|
+
<LazyLoader
|
|
68
|
+
active
|
|
69
|
+
size={props.size}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
{ !error && props.preview && (
|
|
64
73
|
<Image
|
|
65
74
|
{...props.image}
|
|
75
|
+
onError={() => {
|
|
76
|
+
setError(true);
|
|
77
|
+
setLoaded(true);
|
|
78
|
+
}}
|
|
79
|
+
onLoad={() => {
|
|
80
|
+
setError(false);
|
|
81
|
+
setLoaded(true);
|
|
82
|
+
}}
|
|
66
83
|
src={props.preview}
|
|
67
84
|
size={props.size}
|
|
68
85
|
/>
|
|
@@ -81,7 +98,7 @@ const LazyDocument = (props: Props) => {
|
|
|
81
98
|
</Document>
|
|
82
99
|
</Image>
|
|
83
100
|
)}
|
|
84
|
-
{ !props.preview && !(props.src && props.pdf) && (
|
|
101
|
+
{ (error || (!props.preview && !(props.src && props.pdf))) && (
|
|
85
102
|
<Image
|
|
86
103
|
{...props.image}
|
|
87
104
|
className='placeholder-image'
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
Visibility
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
14
|
import i18n from '../i18n/i18n';
|
|
15
|
+
import LazyLoader from './LazyLoader';
|
|
15
16
|
import PhotoViewer from './PhotoViewer';
|
|
16
17
|
import './LazyImage.css';
|
|
17
18
|
|
|
@@ -26,9 +27,11 @@ type Props = {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
const LazyImage = (props: Props) => {
|
|
29
|
-
const [visible, setVisible] = useState(false);
|
|
30
|
-
const [modal, setModal] = useState(false);
|
|
31
30
|
const [dimmer, setDimmer] = useState(false);
|
|
31
|
+
const [error, setError] = useState(false);
|
|
32
|
+
const [loaded, setLoaded] = useState(!(props.src || props.preview));
|
|
33
|
+
const [modal, setModal] = useState(false);
|
|
34
|
+
const [visible, setVisible] = useState(false);
|
|
32
35
|
|
|
33
36
|
if (!visible) {
|
|
34
37
|
return (
|
|
@@ -60,14 +63,28 @@ const LazyImage = (props: Props) => {
|
|
|
60
63
|
onMouseEnter={() => setDimmer(true)}
|
|
61
64
|
onMouseLeave={() => setDimmer(false)}
|
|
62
65
|
>
|
|
63
|
-
{
|
|
66
|
+
{ !loaded && (
|
|
67
|
+
<LazyLoader
|
|
68
|
+
active
|
|
69
|
+
size={props.size}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
{ !error && (props.preview || props.src) && (
|
|
64
73
|
<Image
|
|
65
74
|
{...props.image}
|
|
75
|
+
onError={() => {
|
|
76
|
+
setError(true);
|
|
77
|
+
setLoaded(true);
|
|
78
|
+
}}
|
|
79
|
+
onLoad={() => {
|
|
80
|
+
setError(false);
|
|
81
|
+
setLoaded(true);
|
|
82
|
+
}}
|
|
66
83
|
size={props.size}
|
|
67
84
|
src={props.preview || props.src}
|
|
68
85
|
/>
|
|
69
86
|
)}
|
|
70
|
-
{ !(props.preview || props.src) && (
|
|
87
|
+
{ (error || !(props.preview || props.src)) && (
|
|
71
88
|
<Image
|
|
72
89
|
{...props.image}
|
|
73
90
|
className='placeholder-image'
|
|
@@ -79,7 +96,7 @@ const LazyImage = (props: Props) => {
|
|
|
79
96
|
/>
|
|
80
97
|
</Image>
|
|
81
98
|
)}
|
|
82
|
-
{ (props.src || props.children) && props.dimmable && (
|
|
99
|
+
{ !error && (props.src || props.children) && props.dimmable && (
|
|
83
100
|
<Dimmer
|
|
84
101
|
active={dimmer}
|
|
85
102
|
>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Image, Loader } from 'semantic-ui-react';
|
|
5
|
+
import './LazyLoader.css';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
active: boolean,
|
|
9
|
+
size: string
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const LazyLoader = (props: Props) => (
|
|
13
|
+
<Image
|
|
14
|
+
className='lazy-loader'
|
|
15
|
+
size={props.size}
|
|
16
|
+
>
|
|
17
|
+
<Loader
|
|
18
|
+
active={props.active}
|
|
19
|
+
/>
|
|
20
|
+
</Image>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
LazyLoader.defaultProps = {
|
|
24
|
+
active: false,
|
|
25
|
+
size: 'small'
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default LazyLoader;
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
Visibility
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
14
|
import i18n from '../i18n/i18n';
|
|
15
|
+
import LazyLoader from './LazyLoader';
|
|
15
16
|
import VideoPlayer from './VideoPlayer';
|
|
16
17
|
import './LazyVideo.css';
|
|
17
18
|
|
|
@@ -29,9 +30,11 @@ type Props = {
|
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
const LazyVideo = (props: Props) => {
|
|
32
|
-
const [visible, setVisible] = useState(false);
|
|
33
|
-
const [modal, setModal] = useState(false);
|
|
34
33
|
const [dimmer, setDimmer] = useState(false);
|
|
34
|
+
const [error, setError] = useState(false);
|
|
35
|
+
const [loaded, setLoaded] = useState(!(props.preview || props.src));
|
|
36
|
+
const [modal, setModal] = useState(false);
|
|
37
|
+
const [visible, setVisible] = useState(false);
|
|
35
38
|
|
|
36
39
|
if (!visible) {
|
|
37
40
|
return (
|
|
@@ -63,24 +66,46 @@ const LazyVideo = (props: Props) => {
|
|
|
63
66
|
onMouseEnter={() => setDimmer(true)}
|
|
64
67
|
onMouseLeave={() => setDimmer(false)}
|
|
65
68
|
>
|
|
66
|
-
{
|
|
69
|
+
{ !loaded && (
|
|
70
|
+
<LazyLoader
|
|
71
|
+
active
|
|
72
|
+
size={props.size}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
{ !error && props.preview && (
|
|
67
76
|
<Image
|
|
68
77
|
{...props.image}
|
|
78
|
+
onError={() => {
|
|
79
|
+
setError(true);
|
|
80
|
+
setLoaded(true);
|
|
81
|
+
}}
|
|
82
|
+
onLoad={() => {
|
|
83
|
+
setError(false);
|
|
84
|
+
setLoaded(true);
|
|
85
|
+
}}
|
|
69
86
|
src={props.preview}
|
|
70
87
|
size={props.size}
|
|
71
88
|
/>
|
|
72
89
|
)}
|
|
73
|
-
{ !props.preview && props.src && (
|
|
90
|
+
{ !error && !props.preview && props.src && (
|
|
74
91
|
<Image
|
|
75
92
|
{...props.image}
|
|
76
93
|
size={props.size}
|
|
77
94
|
>
|
|
78
95
|
<video
|
|
96
|
+
onError={() => {
|
|
97
|
+
setError(true);
|
|
98
|
+
setLoaded(true);
|
|
99
|
+
}}
|
|
100
|
+
onLoadedData={() => {
|
|
101
|
+
setError(false);
|
|
102
|
+
setLoaded(true);
|
|
103
|
+
}}
|
|
79
104
|
src={props.src}
|
|
80
105
|
/>
|
|
81
106
|
</Image>
|
|
82
107
|
)}
|
|
83
|
-
{ !props.preview && !props.src && (
|
|
108
|
+
{ (error || (!props.preview && !props.src)) && (
|
|
84
109
|
<Image
|
|
85
110
|
{...props.image}
|
|
86
111
|
className='placeholder-image'
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { Image, Modal } from 'semantic-ui-react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Image, Message, Modal } from 'semantic-ui-react';
|
|
5
5
|
import ModalContext from '../context/ModalContext';
|
|
6
6
|
import './PhotoViewer.css';
|
|
7
|
+
import i18n from '../i18n/i18n';
|
|
7
8
|
|
|
8
9
|
type Props = {
|
|
9
10
|
alt?: string,
|
|
@@ -13,29 +14,41 @@ type Props = {
|
|
|
13
14
|
size?: string
|
|
14
15
|
};
|
|
15
16
|
|
|
16
|
-
const PhotoViewer = (props: Props) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
17
|
+
const PhotoViewer = (props: Props) => {
|
|
18
|
+
const [error, setError] = useState(false);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<ModalContext.Consumer>
|
|
22
|
+
{(mountNode) => (
|
|
23
|
+
<Modal
|
|
24
|
+
centered={false}
|
|
25
|
+
className='photo-viewer'
|
|
26
|
+
closeIcon
|
|
27
|
+
mountNode={mountNode}
|
|
28
|
+
onClose={props.onClose.bind(this)}
|
|
29
|
+
open={props.open}
|
|
30
|
+
size={props.size}
|
|
31
|
+
>
|
|
32
|
+
<Modal.Content>
|
|
33
|
+
{ error && (
|
|
34
|
+
<Message
|
|
35
|
+
content={i18n.t('PhotoViewer.errors.path.content', { path: props.image })}
|
|
36
|
+
header={i18n.t('PhotoViewer.errors.path.header')}
|
|
37
|
+
icon='exclamation circle'
|
|
38
|
+
/>
|
|
39
|
+
)}
|
|
40
|
+
<Image
|
|
41
|
+
alt={props.alt}
|
|
42
|
+
fluid
|
|
43
|
+
onError={() => setError(true)}
|
|
44
|
+
src={props.image}
|
|
45
|
+
/>
|
|
46
|
+
</Modal.Content>
|
|
47
|
+
</Modal>
|
|
48
|
+
)}
|
|
49
|
+
</ModalContext.Consumer>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
39
52
|
|
|
40
53
|
PhotoViewer.defaultProps = {
|
|
41
54
|
size: 'small'
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, {
|
|
4
|
-
|
|
3
|
+
import React, {
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
type Element
|
|
8
|
+
} from 'react';
|
|
9
|
+
import {
|
|
10
|
+
Embed,
|
|
11
|
+
Message,
|
|
12
|
+
Modal,
|
|
13
|
+
Ref
|
|
14
|
+
} from 'semantic-ui-react';
|
|
5
15
|
import ModalContext from '../context/ModalContext';
|
|
6
16
|
import './VideoPlayer.css';
|
|
17
|
+
import i18n from '../i18n/i18n';
|
|
7
18
|
|
|
8
19
|
type Props = {
|
|
9
20
|
autoPlay?: boolean,
|
|
@@ -18,6 +29,8 @@ type Props = {
|
|
|
18
29
|
};
|
|
19
30
|
|
|
20
31
|
const VideoPlayer = (props: Props) => {
|
|
32
|
+
const [error, setError] = useState(false);
|
|
33
|
+
|
|
21
34
|
const embedRef = useRef();
|
|
22
35
|
|
|
23
36
|
/**
|
|
@@ -46,6 +59,13 @@ const VideoPlayer = (props: Props) => {
|
|
|
46
59
|
size={props.size}
|
|
47
60
|
>
|
|
48
61
|
<Modal.Content>
|
|
62
|
+
{ error && (
|
|
63
|
+
<Message
|
|
64
|
+
content={i18n.t('VideoPlayer.errors.path.content', { path: props.video })}
|
|
65
|
+
header={i18n.t('VideoPlayer.errors.path.header')}
|
|
66
|
+
icon='exclamation circle'
|
|
67
|
+
/>
|
|
68
|
+
)}
|
|
49
69
|
{ props.embedded && (
|
|
50
70
|
<Ref
|
|
51
71
|
innerRef={embedRef}
|
|
@@ -63,6 +83,7 @@ const VideoPlayer = (props: Props) => {
|
|
|
63
83
|
<video
|
|
64
84
|
autoPlay={props.autoPlay}
|
|
65
85
|
controls
|
|
86
|
+
onError={() => setError(true)}
|
|
66
87
|
src={props.video}
|
|
67
88
|
/>
|
|
68
89
|
)}
|
package/src/i18n/en.json
CHANGED
|
@@ -8,6 +8,14 @@
|
|
|
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",
|
|
@@ -198,6 +206,14 @@
|
|
|
198
206
|
"loginErrorHeader": "Invalid Credentials",
|
|
199
207
|
"password": "Password"
|
|
200
208
|
},
|
|
209
|
+
"PhotoViewer": {
|
|
210
|
+
"errors": {
|
|
211
|
+
"path": {
|
|
212
|
+
"content": "Please check the image path: {{path}}",
|
|
213
|
+
"header": "There was a problem loading the image"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
},
|
|
201
217
|
"ReferenceCodeFormLabel": {
|
|
202
218
|
"content": "The values in this list can be edited via the {{name}} reference table."
|
|
203
219
|
},
|
|
@@ -245,6 +261,14 @@
|
|
|
245
261
|
},
|
|
246
262
|
"title": "Select Frame"
|
|
247
263
|
},
|
|
264
|
+
"VideoPlayer": {
|
|
265
|
+
"errors": {
|
|
266
|
+
"path": {
|
|
267
|
+
"content": "Please check the video path: {{path}}",
|
|
268
|
+
"header": "There was a problem loading the video"
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
},
|
|
248
272
|
"ViewXML": {
|
|
249
273
|
"buttons": {
|
|
250
274
|
"view": "View XML"
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { Button, Modal } from 'semantic-ui-react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Button, Message, Modal } from 'semantic-ui-react';
|
|
5
5
|
import i18n from '../i18n/i18n';
|
|
6
|
+
import ModalContext from '../context/ModalContext';
|
|
6
7
|
import './AudioPlayer.css';
|
|
7
8
|
|
|
8
9
|
type Props = {
|
|
@@ -12,25 +13,42 @@ type Props = {
|
|
|
12
13
|
src: string
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
const AudioPlayer = (props: Props) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
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
|
+
};
|
|
35
53
|
|
|
36
54
|
export default AudioPlayer;
|