@openeventkit/event-site 2.0.122 → 2.0.123-beta.2
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/package.json +6 -2
- package/src/actions/event-actions.js +1 -10
- package/src/components/AvatarEditorModal/index.js +251 -0
- package/src/components/Navbar/index.js +12 -22
- package/src/components/Navbar/template.js +64 -84
- package/src/components/SyncWordsPlayer.js +58 -0
- package/src/components/VideoComponent.js +12 -3
- package/src/components/summit-my-orders-tickets/components/TicketPopup/TicketPopupEditDetailsForm/TicketPopupEditDetailsForm.js +5 -0
- package/src/components/ui/Button/index.js +41 -0
- package/src/components/ui/IconButton/index.js +32 -0
- package/src/components/ui/index.js +7 -0
- package/src/content/site-settings/index.json +1 -50
- package/src/content/sponsors.json +1 -1
- package/src/styles/colors.scss +0 -6
- package/src/styles/full-profile.module.scss +3 -0
- package/src/styles/video.module.scss +21 -1
- package/src/templates/full-profile-page.js +24 -18
- package/src/utils/videoUtils.js +18 -0
- package/src/components/ProfilePopupComponent.js +0 -369
package/package.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openeventkit/event-site",
|
|
3
3
|
"description": "Event Site",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.123-beta.2",
|
|
5
5
|
"author": "Tipit LLC",
|
|
6
6
|
"dependencies": {
|
|
7
|
+
"@emotion/cache": "^11.13.1",
|
|
7
8
|
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
|
8
9
|
"@fortawesome/free-brands-svg-icons": "^6.5.2",
|
|
9
10
|
"@fortawesome/react-fontawesome": "^0.2.2",
|
|
10
11
|
"@mdx-js/react": "^3.0.1",
|
|
11
12
|
"@mdx-js/runtime": "^1.6.22",
|
|
12
13
|
"@mui/base": "^5.0.0-beta.40",
|
|
14
|
+
"@mui/icons-material": "^5.16.7",
|
|
15
|
+
"@mui/material": "^5.16.7",
|
|
16
|
+
"@mui/system": "^5.16.7",
|
|
13
17
|
"@mux/mux-player-react": "^1.14.1",
|
|
14
18
|
"@ncwidgets/file-relation": "^0.8.0",
|
|
15
19
|
"@ncwidgets/id": "^0.8.1",
|
|
@@ -28,7 +32,7 @@
|
|
|
28
32
|
"@vimeo/player": "^2.16.3",
|
|
29
33
|
"ably": "^1.2.34",
|
|
30
34
|
"assert": "^2.1.0",
|
|
31
|
-
"attendee-to-attendee-widget": "3.1.1-beta.
|
|
35
|
+
"attendee-to-attendee-widget": "3.1.1-beta.32",
|
|
32
36
|
"autoprefixer": "10.4.14",
|
|
33
37
|
"awesome-bootstrap-checkbox": "^1.0.1",
|
|
34
38
|
"axios": "^0.19.2",
|
|
@@ -29,23 +29,14 @@ export const setEventLastUpdate = (lastUpdate) => (dispatch) => {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* @param eventId
|
|
32
|
-
* @param checkLocal
|
|
33
32
|
* @returns {(function(*, *): Promise<*>)|*}
|
|
34
33
|
*/
|
|
35
34
|
export const getEventById = (
|
|
36
35
|
eventId
|
|
37
|
-
) => async (dispatch
|
|
36
|
+
) => async (dispatch) => {
|
|
38
37
|
|
|
39
38
|
dispatch(startLoading());
|
|
40
|
-
// if we have it on the reducer , provide that first
|
|
41
|
-
let {allSchedulesState: {allEvents}} = getState();
|
|
42
|
-
const event = allEvents.find(ev => ev.id === parseInt(eventId));
|
|
43
|
-
|
|
44
|
-
if (event) {
|
|
45
|
-
dispatch(createAction(GET_EVENT_DATA)({event}));
|
|
46
|
-
}
|
|
47
39
|
|
|
48
|
-
// then refresh from api
|
|
49
40
|
let accessToken;
|
|
50
41
|
try {
|
|
51
42
|
accessToken = await getAccessToken();
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect } from "react";
|
|
2
|
+
import AvatarEditor from "react-avatar-editor";
|
|
3
|
+
import { Box, Typography, Slider, Modal } from "@mui/material";
|
|
4
|
+
import { Button, IconButton } from "../ui";
|
|
5
|
+
import { styled } from "@mui/system";
|
|
6
|
+
import {
|
|
7
|
+
//Close as CloseIcon,
|
|
8
|
+
CameraAlt as CameraAltIcon,
|
|
9
|
+
RotateLeft as RotateLeftIcon,
|
|
10
|
+
RotateRight as RotateRightIcon,
|
|
11
|
+
} from "@mui/icons-material";
|
|
12
|
+
import { create_UUID } from "@utils/uuidGenerator";
|
|
13
|
+
|
|
14
|
+
const CustomSlider = styled(Slider)(({ theme }) => ({
|
|
15
|
+
color: "var(--color-primary)"
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
const AvatarEditorModal = ({
|
|
19
|
+
userProfile,
|
|
20
|
+
open,
|
|
21
|
+
changePicture,
|
|
22
|
+
handleClose
|
|
23
|
+
}) => {
|
|
24
|
+
const editorRef = useRef(null);
|
|
25
|
+
const fileInputRef = useRef(null);
|
|
26
|
+
|
|
27
|
+
const [image, setImage] = useState(userProfile.picture || null);
|
|
28
|
+
const [position, setPosition] = useState({ x: 0.5, y: 0.5 });
|
|
29
|
+
const [scale, setScale] = useState(1);
|
|
30
|
+
const [rotate, setRotate] = useState(0);
|
|
31
|
+
const [newImage, setNewImage] = useState(false);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setImage(userProfile.picture);
|
|
35
|
+
}, [userProfile.picture]);
|
|
36
|
+
|
|
37
|
+
const handleNewImage = (e) => {
|
|
38
|
+
setImage(e.target.files[0]);
|
|
39
|
+
setNewImage(true);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const handleScale = (e, newValue) => {
|
|
43
|
+
setScale(newValue);
|
|
44
|
+
setNewImage(true);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handlePositionChange = (newPosition) => {
|
|
48
|
+
setPosition(newPosition);
|
|
49
|
+
setNewImage(true);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const rotateLeft = () => {
|
|
53
|
+
setRotate((prev) => prev - 22.5);
|
|
54
|
+
setNewImage(true);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const rotateRight = () => {
|
|
58
|
+
setRotate((prev) => prev + 22.5);
|
|
59
|
+
setNewImage(true);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const handleSave = () => {
|
|
63
|
+
if (editorRef.current && newImage) {
|
|
64
|
+
const canvas = editorRef.current.getImage().toDataURL();
|
|
65
|
+
fetch(canvas)
|
|
66
|
+
.then((res) => res.blob())
|
|
67
|
+
.then((blob) => {
|
|
68
|
+
const file = new File([blob], `${create_UUID()}.png`, { type: blob.type });
|
|
69
|
+
changePicture(file);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<Modal
|
|
76
|
+
open={open}
|
|
77
|
+
onClose={handleClose}
|
|
78
|
+
aria-labelledby="avatar-modal-title"
|
|
79
|
+
sx={{
|
|
80
|
+
display: "flex",
|
|
81
|
+
alignItems: "center",
|
|
82
|
+
justifyContent: "center"
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
<Box
|
|
86
|
+
sx={{
|
|
87
|
+
width: { xs: "100%", sm: 400 },
|
|
88
|
+
bgcolor: "var(--color_background_light)",
|
|
89
|
+
color: "var(--color_text_dark)",
|
|
90
|
+
display: "flex",
|
|
91
|
+
flexDirection: "column",
|
|
92
|
+
position: "relative",
|
|
93
|
+
border: "1px solid #dbdbdb"
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<Box
|
|
97
|
+
sx={{
|
|
98
|
+
padding: "7.5px 15px",
|
|
99
|
+
display: "flex",
|
|
100
|
+
alignItems: "center",
|
|
101
|
+
borderBottom: "1px solid #dbdbdb"
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
<Typography
|
|
105
|
+
id="avatar-modal-title"
|
|
106
|
+
component="h2"
|
|
107
|
+
sx={{
|
|
108
|
+
fontWeight: "bold",
|
|
109
|
+
color: "var(--color_text_dark)",
|
|
110
|
+
fontFamily: "var(--font_family)",
|
|
111
|
+
fontSize: "18px"
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
Edit Profile Picture
|
|
115
|
+
</Typography>
|
|
116
|
+
<IconButton
|
|
117
|
+
onClick={handleClose}
|
|
118
|
+
sx={{
|
|
119
|
+
ml: "auto",
|
|
120
|
+
fontSize: "16px",
|
|
121
|
+
padding: 0
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
<i className="fa fa-times" />
|
|
125
|
+
</IconButton>
|
|
126
|
+
</Box>
|
|
127
|
+
<Box
|
|
128
|
+
sx={{
|
|
129
|
+
padding: "20px",
|
|
130
|
+
textAlign: "center",
|
|
131
|
+
position: "relative"
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
<AvatarEditor
|
|
135
|
+
ref={editorRef}
|
|
136
|
+
image={image}
|
|
137
|
+
width={200}
|
|
138
|
+
height={200}
|
|
139
|
+
border={50}
|
|
140
|
+
color={[0, 0, 0, 0.8]}
|
|
141
|
+
position={position}
|
|
142
|
+
onPositionChange={handlePositionChange}
|
|
143
|
+
scale={scale}
|
|
144
|
+
rotate={rotate}
|
|
145
|
+
crossOrigin={"anonymous"}
|
|
146
|
+
/>
|
|
147
|
+
<IconButton
|
|
148
|
+
onClick={() => fileInputRef.current.click()}
|
|
149
|
+
sx={{
|
|
150
|
+
position: "absolute",
|
|
151
|
+
top: "79.5%",
|
|
152
|
+
right: "44%",
|
|
153
|
+
color: "#fff"
|
|
154
|
+
}}
|
|
155
|
+
>
|
|
156
|
+
<CameraAltIcon fontSize="inherit" />
|
|
157
|
+
</IconButton>
|
|
158
|
+
<input
|
|
159
|
+
ref={fileInputRef}
|
|
160
|
+
type="file"
|
|
161
|
+
accept=".jpg,.jpeg,.png"
|
|
162
|
+
style={{ display: "none" }}
|
|
163
|
+
onChange={handleNewImage}
|
|
164
|
+
/>
|
|
165
|
+
</Box>
|
|
166
|
+
<Box
|
|
167
|
+
sx={{
|
|
168
|
+
px: "20px",
|
|
169
|
+
display: "flex",
|
|
170
|
+
flexDirection: "column",
|
|
171
|
+
gap: "20px"
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
<Box
|
|
175
|
+
sx={{
|
|
176
|
+
display: "flex",
|
|
177
|
+
alignItems: "center",
|
|
178
|
+
gap: "20px",
|
|
179
|
+
justifyContent: "center"
|
|
180
|
+
}}
|
|
181
|
+
>
|
|
182
|
+
<Typography
|
|
183
|
+
sx={{
|
|
184
|
+
fontSize: "1.5rem",
|
|
185
|
+
fontFamily: "var(--font_family)"
|
|
186
|
+
}
|
|
187
|
+
}>
|
|
188
|
+
Zoom
|
|
189
|
+
</Typography>
|
|
190
|
+
<CustomSlider
|
|
191
|
+
value={scale}
|
|
192
|
+
min={0}
|
|
193
|
+
max={2}
|
|
194
|
+
step={0.01}
|
|
195
|
+
onChange={handleScale}
|
|
196
|
+
sx={{ flex: 1, mx: 2 }}
|
|
197
|
+
/>
|
|
198
|
+
</Box>
|
|
199
|
+
<Box
|
|
200
|
+
sx={{
|
|
201
|
+
display: "flex",
|
|
202
|
+
alignItems: "center"
|
|
203
|
+
}}
|
|
204
|
+
>
|
|
205
|
+
<Typography
|
|
206
|
+
sx={{
|
|
207
|
+
fontSize: "1.5rem",
|
|
208
|
+
fontFamily: "var(--font_family)"
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
Rotate
|
|
212
|
+
</Typography>
|
|
213
|
+
<Box
|
|
214
|
+
sx={{
|
|
215
|
+
display: "flex",
|
|
216
|
+
flex: 1,
|
|
217
|
+
justifyContent: "center",
|
|
218
|
+
gap: "20px"
|
|
219
|
+
}}
|
|
220
|
+
>
|
|
221
|
+
<IconButton onClick={rotateLeft}>
|
|
222
|
+
<RotateLeftIcon fontSize="inherit" />
|
|
223
|
+
</IconButton>
|
|
224
|
+
<IconButton onClick={rotateRight}>
|
|
225
|
+
<RotateRightIcon fontSize="inherit" />
|
|
226
|
+
</IconButton>
|
|
227
|
+
</Box>
|
|
228
|
+
</Box>
|
|
229
|
+
</Box>
|
|
230
|
+
<Box
|
|
231
|
+
sx={{
|
|
232
|
+
backgroundColor: "var(--color_background_light)",
|
|
233
|
+
display: "flex",
|
|
234
|
+
justifyContent: "space-between",
|
|
235
|
+
padding: "20px",
|
|
236
|
+
gap: "20px"
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
<Button onClick={handleClose}>
|
|
240
|
+
Discard
|
|
241
|
+
</Button>
|
|
242
|
+
<Button onClick={handleSave} disabled={!newImage}>
|
|
243
|
+
Update
|
|
244
|
+
</Button>
|
|
245
|
+
</Box>
|
|
246
|
+
</Box>
|
|
247
|
+
</Modal>
|
|
248
|
+
);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
export default AvatarEditorModal;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
|
+
import { navigate } from "gatsby";
|
|
4
5
|
import NavbarTemplate from "./template";
|
|
5
6
|
|
|
6
|
-
import {
|
|
7
|
-
updateProfile,
|
|
8
|
-
updateProfilePicture
|
|
9
|
-
} from "../../actions/user-actions";
|
|
10
|
-
|
|
11
7
|
import { userHasAccessLevel, VirtualAccessLevel } from "@utils/authorizedGroups";
|
|
12
8
|
import { getDefaultLocation } from "@utils/loginUtils";
|
|
13
9
|
|
|
@@ -21,11 +17,8 @@ const Navbar = ({
|
|
|
21
17
|
summitPhase,
|
|
22
18
|
summit,
|
|
23
19
|
isLoggedUser,
|
|
24
|
-
idpLoading,
|
|
25
20
|
idpProfile,
|
|
26
21
|
userProfile,
|
|
27
|
-
updateProfile,
|
|
28
|
-
updateProfilePicture,
|
|
29
22
|
eventRedirect
|
|
30
23
|
}) => {
|
|
31
24
|
|
|
@@ -105,20 +98,21 @@ const Navbar = ({
|
|
|
105
98
|
passPageRestriction;
|
|
106
99
|
};
|
|
107
100
|
|
|
101
|
+
const handleLogoClick = () => navigate(isLoggedUser ? defaultPath : "/");
|
|
102
|
+
|
|
103
|
+
const handleProfileIconClick = () => navigate("/a/profile");
|
|
104
|
+
|
|
108
105
|
return (
|
|
109
106
|
<NavbarTemplate
|
|
110
|
-
|
|
107
|
+
items={navbarContent.items.filter(showItem)}
|
|
111
108
|
summit={summit}
|
|
109
|
+
logo={summit?.logo}
|
|
110
|
+
onLogoClick={handleLogoClick}
|
|
112
111
|
isLoggedUser={isLoggedUser}
|
|
113
|
-
idpLoading={idpLoading}
|
|
114
112
|
idpProfile={idpProfile}
|
|
115
|
-
|
|
116
|
-
updateProfile={updateProfile}
|
|
117
|
-
updateProfilePicture={updateProfilePicture}
|
|
118
|
-
defaultPath={defaultPath}
|
|
119
|
-
logo={summit?.logo}
|
|
113
|
+
onProfileIconClick={handleProfileIconClick}
|
|
120
114
|
/>
|
|
121
|
-
)
|
|
115
|
+
);
|
|
122
116
|
};
|
|
123
117
|
|
|
124
118
|
|
|
@@ -129,17 +123,13 @@ const mapStateToProps = ({
|
|
|
129
123
|
loggedUserState,
|
|
130
124
|
userState
|
|
131
125
|
}) => ({
|
|
132
|
-
summitPhase: clockState.summit_phase,
|
|
133
126
|
summit: summitState.summit,
|
|
127
|
+
summitPhase: clockState.summit_phase,
|
|
134
128
|
isLoggedUser: loggedUserState.isLoggedUser,
|
|
135
129
|
idpProfile: userState.idpProfile,
|
|
136
|
-
idpLoading: userState.loadingIDP,
|
|
137
130
|
userProfile: userState.userProfile,
|
|
138
131
|
// TODO: move to site settings i/o marketing page settings
|
|
139
132
|
eventRedirect: settingState.marketingPageSettings.eventRedirect
|
|
140
133
|
});
|
|
141
134
|
|
|
142
|
-
export default connect(mapStateToProps, {
|
|
143
|
-
updateProfile,
|
|
144
|
-
updateProfilePicture
|
|
145
|
-
})(Navbar);
|
|
135
|
+
export default connect(mapStateToProps, {})(Navbar);
|
|
@@ -1,108 +1,88 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
|
|
3
2
|
import Link from "../Link";
|
|
4
|
-
import ProfilePopupComponent from "../ProfilePopupComponent";
|
|
5
3
|
import LogoutButton from "../LogoutButton";
|
|
6
4
|
|
|
7
5
|
import styles from "../../styles/navbar.module.scss";
|
|
8
6
|
|
|
9
7
|
const NavbarTemplate = ({
|
|
10
|
-
|
|
8
|
+
items,
|
|
9
|
+
logo,
|
|
11
10
|
summit,
|
|
12
11
|
isLoggedUser,
|
|
13
|
-
idpLoading,
|
|
14
12
|
idpProfile,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
defaultPath,
|
|
18
|
-
logo
|
|
13
|
+
onLogoClick,
|
|
14
|
+
onProfileIconClick
|
|
19
15
|
}) => {
|
|
20
16
|
const [active, setActive] = useState(false);
|
|
21
|
-
const [showProfile, setShowProfile] = useState(false);
|
|
22
17
|
|
|
23
|
-
const toggleHamburger = () =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
const toggleHamburger = () => setActive(!active);
|
|
19
|
+
|
|
20
|
+
const navBarActiveClass = active ? styles.isActive : "";
|
|
21
|
+
|
|
22
|
+
const renderLogo = () => {
|
|
23
|
+
if (!logo && !summit?.name) return null;
|
|
24
|
+
|
|
25
|
+
const logoContent = logo ? <img src={logo} alt={summit?.name || "Logo"} /> : <h4>{summit.name}</h4>;
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
return onLogoClick ? (
|
|
28
|
+
<button className={`link ${styles.navbarItem}`} onClick={onLogoClick}>
|
|
29
|
+
{logoContent}
|
|
30
|
+
</button>
|
|
31
|
+
) : (
|
|
32
|
+
<div className={styles.navbarItem}>{logoContent}</div>
|
|
33
|
+
);
|
|
35
34
|
};
|
|
36
35
|
|
|
37
|
-
const
|
|
36
|
+
const renderProfileIcon = () => {
|
|
37
|
+
if (!isLoggedUser || !idpProfile?.picture) return null;
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
className={`${styles.navbar}`}
|
|
43
|
-
role="navigation"
|
|
44
|
-
aria-label="main navigation"
|
|
45
|
-
>
|
|
46
|
-
<div className={styles.navbarBrand}>
|
|
47
|
-
<Link
|
|
48
|
-
to={isLoggedUser ? defaultPath : "/"}
|
|
49
|
-
className={styles.navbarItem}
|
|
50
|
-
>
|
|
51
|
-
{logo && <img src={logo} alt={summit.name} />}
|
|
52
|
-
</Link>
|
|
39
|
+
const profilePic = (
|
|
40
|
+
<img alt={idpProfile?.name} className={styles.profilePic} src={idpProfile.picture} />
|
|
41
|
+
);
|
|
53
42
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
</button>
|
|
65
|
-
</div>
|
|
43
|
+
return onProfileIconClick ? (
|
|
44
|
+
<div className={styles.navbarItem}>
|
|
45
|
+
<button className="link" onClick={onProfileIconClick}>
|
|
46
|
+
{profilePic}
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
) : (
|
|
50
|
+
<div className={styles.navbarItem}>{profilePic}</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
66
53
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
54
|
+
return (
|
|
55
|
+
<nav className={styles.navbar} role="navigation" aria-label="main navigation">
|
|
56
|
+
<div className={styles.navbarBrand}>
|
|
57
|
+
{renderLogo()}
|
|
58
|
+
<button
|
|
59
|
+
className={`link ${styles.navbarBurger} ${styles.burger} ${navBarActiveClass}`}
|
|
60
|
+
aria-label="menu"
|
|
61
|
+
aria-expanded="false"
|
|
62
|
+
data-target="navbar"
|
|
63
|
+
onClick={toggleHamburger}
|
|
70
64
|
>
|
|
71
|
-
<
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{showProfile && (
|
|
90
|
-
<ProfilePopupComponent
|
|
91
|
-
userProfile={idpProfile}
|
|
92
|
-
showProfile={showProfile}
|
|
93
|
-
idpLoading={idpLoading}
|
|
94
|
-
changePicture={updateProfilePicture}
|
|
95
|
-
changeProfile={updateProfile}
|
|
96
|
-
closePopup={() => handleTogglePopup()}
|
|
97
|
-
/>
|
|
98
|
-
)}
|
|
99
|
-
</div>
|
|
100
|
-
)}
|
|
101
|
-
<LogoutButton styles={styles} isLoggedUser={isLoggedUser} />
|
|
102
|
-
</div>
|
|
65
|
+
<span aria-hidden="true" />
|
|
66
|
+
<span aria-hidden="true" />
|
|
67
|
+
<span aria-hidden="true" />
|
|
68
|
+
</button>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div id="navbar" className={`${styles.navbarMenu} ${navBarActiveClass}`}>
|
|
72
|
+
<div className={styles.navbarStart} />
|
|
73
|
+
<div className={styles.navbarEnd}>
|
|
74
|
+
{items?.map((item, index) => (
|
|
75
|
+
<div className={styles.navbarItem} key={index}>
|
|
76
|
+
<Link to={item.link} className={styles.link}>
|
|
77
|
+
<span>{item.title}</span>
|
|
78
|
+
</Link>
|
|
79
|
+
</div>
|
|
80
|
+
))}
|
|
81
|
+
{renderProfileIcon()}
|
|
82
|
+
<LogoutButton styles={styles} isLoggedUser={isLoggedUser} />
|
|
103
83
|
</div>
|
|
104
|
-
</
|
|
105
|
-
</
|
|
84
|
+
</div>
|
|
85
|
+
</nav>
|
|
106
86
|
);
|
|
107
87
|
};
|
|
108
88
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import {getSynchWordsVideoFrameDdFromSrc} from "../utils/videoUtils";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SynchWordsPlayer extends React.Component {
|
|
7
|
+
|
|
8
|
+
constructor(props) {
|
|
9
|
+
super(props);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
componentDidMount() {
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
componentWillUnmount() {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
render() {
|
|
19
|
+
const { video, className, autoplay } = this.props;
|
|
20
|
+
const id = getSynchWordsVideoFrameDdFromSrc(video);
|
|
21
|
+
console.log(`SynchWordsPlayer::render with id ${id}`);
|
|
22
|
+
let allow = "encrypted-media";
|
|
23
|
+
if(autoplay) allow = allow +';autoplay'
|
|
24
|
+
return (
|
|
25
|
+
<div className={className}>
|
|
26
|
+
<iframe id={id}
|
|
27
|
+
src={video}
|
|
28
|
+
frameBorder="0"
|
|
29
|
+
scrolling="no"
|
|
30
|
+
allow={allow}
|
|
31
|
+
allowFullScreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen
|
|
32
|
+
>
|
|
33
|
+
</iframe>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
SynchWordsPlayer.propTypes = {
|
|
40
|
+
/**
|
|
41
|
+
* a video URL.
|
|
42
|
+
*/
|
|
43
|
+
video: PropTypes.oneOfType([
|
|
44
|
+
PropTypes.number,
|
|
45
|
+
PropTypes.string,
|
|
46
|
+
]),
|
|
47
|
+
/**
|
|
48
|
+
* CSS className for the player element.
|
|
49
|
+
*/
|
|
50
|
+
className: PropTypes.string,
|
|
51
|
+
/**
|
|
52
|
+
* Automatically start playback of the video. Note that this won’t work on
|
|
53
|
+
* some devices.
|
|
54
|
+
*/
|
|
55
|
+
autoplay: PropTypes.bool,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default SynchWordsPlayer;
|
|
@@ -4,7 +4,8 @@ import VideoJSPlayer from './VideoJSPlayer';
|
|
|
4
4
|
import VimeoPlayer from "./VimeoPlayer";
|
|
5
5
|
import VideoMUXPlayer from './VideoMUXPlayer';
|
|
6
6
|
import styles from '../styles/video.module.scss';
|
|
7
|
-
import { isMuxVideo, isVimeoVideo, isYouTubeVideo } from '../utils/videoUtils';
|
|
7
|
+
import { isMuxVideo, isVimeoVideo, isYouTubeVideo, isSynchWordsVideo } from '../utils/videoUtils';
|
|
8
|
+
import SynchWordsPlayer from "./SyncWordsPlayer";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @param url
|
|
@@ -48,6 +49,14 @@ const VideoComponent = ({ url, title, namespace, isLive, firstHalf, autoPlay, st
|
|
|
48
49
|
/>
|
|
49
50
|
);
|
|
50
51
|
};
|
|
52
|
+
// synch words player
|
|
53
|
+
if(isSynchWordsVideo(url)){
|
|
54
|
+
return (<SynchWordsPlayer
|
|
55
|
+
video={url}
|
|
56
|
+
autoplay={autoPlay}
|
|
57
|
+
className={styles.synchWordsPlayer}
|
|
58
|
+
/>);
|
|
59
|
+
}
|
|
51
60
|
|
|
52
61
|
const defaultVideoJsOptions = isYouTubeVideo(url) ? {
|
|
53
62
|
techOrder: ["youtube"],
|
|
@@ -99,7 +108,7 @@ VideoComponent.propTypes = {
|
|
|
99
108
|
isLive: PropTypes.bool,
|
|
100
109
|
firstHalf: PropTypes.bool,
|
|
101
110
|
autoPlay: PropTypes.bool,
|
|
102
|
-
start: PropTypes.number,
|
|
111
|
+
start: PropTypes.number,
|
|
103
112
|
tokens: PropTypes.object,
|
|
104
113
|
onError: PropTypes.func,
|
|
105
114
|
};
|
|
@@ -108,7 +117,7 @@ VideoComponent.defaultProps = {
|
|
|
108
117
|
title: '',
|
|
109
118
|
namespace: '',
|
|
110
119
|
firstHalf: true,
|
|
111
|
-
autoPlay: false,
|
|
120
|
+
autoPlay: false,
|
|
112
121
|
tokens: null,
|
|
113
122
|
};
|
|
114
123
|
|
|
@@ -319,6 +319,11 @@ export const TicketPopupEditDetailsForm = ({
|
|
|
319
319
|
onBlur={formik.handleBlur}
|
|
320
320
|
onChange={!!initialValues[TicketKeys.company].name ? noop : formik.handleChange}
|
|
321
321
|
disabled={!!initialValues[TicketKeys.company].name}
|
|
322
|
+
menuPortalTarget={document.body}
|
|
323
|
+
menuPosition="fixed"
|
|
324
|
+
styles={{
|
|
325
|
+
menuPortal: (base) => ({ ...base, zIndex: 9999 }),
|
|
326
|
+
}}
|
|
322
327
|
tabSelectsValue={false}
|
|
323
328
|
/>
|
|
324
329
|
{(formik.touched[TicketKeys.company] || triedSubmitting) && formik.errors[TicketKeys.company] &&
|