@ndla/ui 37.1.3 → 38.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/Article/Article.js +2 -2
- package/es/Article/ArticleHeaderWrapper.js +4 -7
- package/es/Article/ArticleNotions.js +16 -17
- package/es/Article/ArticleSideBar.js +4 -5
- package/es/AudioPlayer/Controls.js +173 -255
- package/es/CompetenceGoals/CompetenceGoalsDialog.js +12 -25
- package/es/Filter/FilterButtons.js +12 -14
- package/es/Filter/FilterListPhone.js +2 -4
- package/es/Footer/index.js +1 -2
- package/es/LearningPaths/LearningPathMenuModalWrapper.js +10 -6
- package/es/Masthead/MastheadSearchModal.js +56 -47
- package/es/MyNdla/SettingsMenu.js +6 -6
- package/es/NDLAFilm/AboutNdlaFilm.js +3 -3
- package/es/ResourcesWrapper/ResourcesTopicTitle.js +19 -23
- package/es/SearchTypeResult/PopupFilter.js +14 -20
- package/es/SearchTypeResult/components/ItemContexts.js +10 -21
- package/es/Topic/Topic.js +23 -23
- package/es/User/index.js +1 -3
- package/es/index.js +1 -3
- package/es/locale/messages-en.js +1 -0
- package/es/locale/messages-nb.js +1 -0
- package/es/locale/messages-nn.js +1 -0
- package/es/locale/messages-se.js +1 -0
- package/es/locale/messages-sma.js +1 -0
- package/lib/Article/Article.d.ts +2 -2
- package/lib/Article/Article.js +2 -2
- package/lib/Article/ArticleHeaderWrapper.d.ts +3 -2
- package/lib/Article/ArticleHeaderWrapper.js +4 -7
- package/lib/Article/ArticleNotions.js +17 -21
- package/lib/Article/ArticleSideBar.js +5 -9
- package/lib/AudioPlayer/Controls.d.ts +2 -2
- package/lib/AudioPlayer/Controls.js +173 -255
- package/lib/CompetenceGoals/CompetenceGoalsDialog.d.ts +3 -14
- package/lib/CompetenceGoals/CompetenceGoalsDialog.js +11 -26
- package/lib/Filter/FilterButtons.js +13 -15
- package/lib/Filter/FilterListPhone.js +3 -5
- package/lib/Footer/index.d.ts +1 -2
- package/lib/Footer/index.js +0 -7
- package/lib/LearningPaths/LearningPathMenuModalWrapper.js +9 -8
- package/lib/Masthead/MastheadSearchModal.d.ts +1 -1
- package/lib/Masthead/MastheadSearchModal.js +58 -46
- package/lib/MyNdla/SettingsMenu.js +5 -5
- package/lib/NDLAFilm/AboutNdlaFilm.js +2 -2
- package/lib/ResourcesWrapper/ResourcesTopicTitle.js +20 -27
- package/lib/SearchTypeResult/PopupFilter.js +14 -20
- package/lib/SearchTypeResult/components/ItemContexts.js +10 -21
- package/lib/Topic/Topic.js +22 -22
- package/lib/User/index.d.ts +0 -2
- package/lib/User/index.js +1 -13
- package/lib/index.d.ts +1 -3
- package/lib/index.js +1 -20
- package/lib/locale/messages-en.d.ts +1 -0
- package/lib/locale/messages-en.js +1 -0
- package/lib/locale/messages-nb.d.ts +1 -0
- package/lib/locale/messages-nb.js +1 -0
- package/lib/locale/messages-nn.d.ts +1 -0
- package/lib/locale/messages-nn.js +1 -0
- package/lib/locale/messages-se.d.ts +1 -0
- package/lib/locale/messages-se.js +1 -0
- package/lib/locale/messages-sma.d.ts +1 -0
- package/lib/locale/messages-sma.js +1 -0
- package/package.json +16 -17
- package/src/Article/Article.tsx +4 -4
- package/src/Article/ArticleHeaderWrapper.tsx +12 -18
- package/src/Article/ArticleNotions.tsx +7 -8
- package/src/Article/ArticleSideBar.tsx +3 -3
- package/src/AudioPlayer/Controls.tsx +146 -300
- package/src/CompetenceGoals/CompetenceGoalsDialog.tsx +13 -38
- package/src/Filter/FilterButtons.tsx +4 -5
- package/src/Filter/FilterListPhone.tsx +3 -4
- package/src/Footer/index.ts +1 -2
- package/src/LearningPaths/LearningPathMenuModalWrapper.tsx +10 -6
- package/src/Masthead/MastheadSearchModal.tsx +48 -74
- package/src/MyNdla/SettingsMenu.tsx +3 -3
- package/src/NDLAFilm/AboutNdlaFilm.tsx +3 -3
- package/src/ResourcesWrapper/ResourcesTopicTitle.tsx +4 -8
- package/src/SearchTypeResult/PopupFilter.tsx +6 -11
- package/src/SearchTypeResult/components/ItemContexts.tsx +4 -21
- package/src/Topic/Topic.tsx +7 -7
- package/src/User/index.ts +0 -2
- package/src/index.ts +1 -3
- package/src/locale/messages-en.ts +1 -0
- package/src/locale/messages-nb.ts +1 -0
- package/src/locale/messages-nn.ts +1 -0
- package/src/locale/messages-se.ts +1 -0
- package/src/locale/messages-sma.ts +1 -0
- package/es/Figure/FigureLicenseDialogContent.js +0 -75
- package/es/Footer/FooterAuth.js +0 -110
- package/es/Masthead/MastheadAuthModal.js +0 -50
- package/es/SearchTypeResult/SearchNotionItem.js +0 -208
- package/es/User/AuthModal.js +0 -116
- package/lib/Figure/FigureLicenseDialogContent.d.ts +0 -22
- package/lib/Figure/FigureLicenseDialogContent.js +0 -80
- package/lib/Footer/FooterAuth.d.ts +0 -10
- package/lib/Footer/FooterAuth.js +0 -114
- package/lib/Masthead/MastheadAuthModal.d.ts +0 -13
- package/lib/Masthead/MastheadAuthModal.js +0 -56
- package/lib/SearchTypeResult/SearchNotionItem.d.ts +0 -29
- package/lib/SearchTypeResult/SearchNotionItem.js +0 -215
- package/lib/User/AuthModal.d.ts +0 -22
- package/lib/User/AuthModal.js +0 -124
- package/src/Figure/FigureLicenseDialogContent.tsx +0 -80
- package/src/Footer/FooterAuth.tsx +0 -104
- package/src/Masthead/MastheadAuthModal.tsx +0 -62
- package/src/SearchTypeResult/SearchNotionItem.tsx +0 -228
- package/src/User/AuthModal.tsx +0 -123
|
@@ -8,178 +8,85 @@
|
|
|
8
8
|
|
|
9
9
|
import React, { useEffect, useRef, useState } from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { Root, Trigger, Item, Content, DropdownMenuPortal } from '@radix-ui/react-dropdown-menu';
|
|
12
|
+
import { Root as SliderRoot, Track, Range, SliderThumb } from '@radix-ui/react-slider';
|
|
13
|
+
import { Root as PopoverRoot, PopoverContent, PopoverTrigger, PopoverPortal } from '@radix-ui/react-popover';
|
|
13
14
|
import { Play, Pause, VolumeUp } from '@ndla/icons/common';
|
|
14
15
|
import { breakpoints, colors, fonts, misc, mq, spacing } from '@ndla/core';
|
|
15
16
|
import { useTranslation } from 'react-i18next';
|
|
16
17
|
import { Back15, Forward15 } from '@ndla/icons/action';
|
|
18
|
+
import { ButtonV2, IconButtonV2 } from '@ndla/button';
|
|
17
19
|
|
|
18
20
|
const ControlsWrapper = styled.div`
|
|
19
21
|
border: 1px solid ${colors.brand.lighter};
|
|
20
22
|
display: flex;
|
|
21
23
|
align-items: center;
|
|
22
24
|
justify-content: center;
|
|
23
|
-
background:
|
|
25
|
+
background: ${colors.white};
|
|
24
26
|
font-family: ${fonts.sans};
|
|
27
|
+
gap: ${spacing.xsmall};
|
|
28
|
+
padding: ${spacing.small} ${spacing.normal};
|
|
25
29
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
display: grid;
|
|
31
|
+
padding: ${spacing.small};
|
|
32
|
+
grid-template-columns: 1fr repeat(5, auto) 1fr;
|
|
33
|
+
grid-template-areas:
|
|
34
|
+
'track track track track track track track'
|
|
35
|
+
'. speed backwards play forwards volume .';
|
|
31
36
|
}
|
|
32
37
|
`;
|
|
33
38
|
|
|
34
|
-
const PlayButton = styled
|
|
35
|
-
background: ${colors.brand.lighter};
|
|
36
|
-
border: none;
|
|
37
|
-
display: flex;
|
|
38
|
-
align-items: center;
|
|
39
|
-
justify-content: center;
|
|
40
|
-
padding: 0;
|
|
41
|
-
cursor: pointer;
|
|
42
|
-
color: ${colors.brand.primary};
|
|
43
|
-
width: 55px;
|
|
44
|
-
height: 55px;
|
|
45
|
-
border-radius: 50%;
|
|
46
|
-
transition: ${misc.transition.default};
|
|
47
|
-
margin-right: ${spacing.small};
|
|
39
|
+
const PlayButton = styled(IconButtonV2)`
|
|
48
40
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
49
|
-
|
|
50
|
-
margin-left: ${spacing.small};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
&:hover,
|
|
54
|
-
&:active,
|
|
55
|
-
&:focus {
|
|
56
|
-
background: ${colors.brand.primary};
|
|
57
|
-
color: #ffffff;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.c-icon {
|
|
61
|
-
width: 24px;
|
|
62
|
-
height: 24px;
|
|
41
|
+
grid-area: play;
|
|
63
42
|
}
|
|
64
43
|
`;
|
|
65
44
|
|
|
66
|
-
const
|
|
67
|
-
background-color: inherit;
|
|
68
|
-
background-position: center;
|
|
69
|
-
background-repeat: no-repeat;
|
|
70
|
-
width: 42px;
|
|
71
|
-
height: 42px;
|
|
72
|
-
border: 0;
|
|
73
|
-
border-radius: 50%;
|
|
74
|
-
cursor: pointer;
|
|
75
|
-
font-weight: bold;
|
|
76
|
-
font-size: 9px;
|
|
77
|
-
line-height: 23px;
|
|
78
|
-
color: ${colors.brand.dark};
|
|
79
|
-
font-family: ${fonts.sans};
|
|
80
|
-
transition: ${misc.transition.default};
|
|
81
|
-
|
|
82
|
-
&:hover {
|
|
83
|
-
background-color: ${colors.brand.greyLighter};
|
|
84
|
-
}
|
|
85
|
-
`;
|
|
86
|
-
|
|
87
|
-
const Forward15SecButton = styled(ForwardRewindButton)`
|
|
88
|
-
svg {
|
|
89
|
-
fill: ${colors.brand.primary};
|
|
90
|
-
width: 24px;
|
|
91
|
-
height: 24px;
|
|
92
|
-
}
|
|
45
|
+
const Forward15SecButton = styled(IconButtonV2)`
|
|
93
46
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
94
|
-
|
|
47
|
+
grid-area: forwards;
|
|
95
48
|
}
|
|
96
49
|
`;
|
|
97
|
-
const Back15SecButton = styled(
|
|
98
|
-
svg {
|
|
99
|
-
fill: ${colors.brand.primary};
|
|
100
|
-
width: 24px;
|
|
101
|
-
height: 24px;
|
|
102
|
-
}
|
|
50
|
+
const Back15SecButton = styled(IconButtonV2)`
|
|
103
51
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
104
|
-
|
|
52
|
+
grid-area: backwards;
|
|
105
53
|
}
|
|
106
54
|
`;
|
|
107
55
|
|
|
108
|
-
const
|
|
109
|
-
position: relative;
|
|
110
|
-
display: flex;
|
|
111
|
-
justify-content: center;
|
|
56
|
+
const SpeedButton = styled(ButtonV2)`
|
|
112
57
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
`;
|
|
116
|
-
const SpeedButton = styled(MenuButton)`
|
|
117
|
-
height: 32px;
|
|
118
|
-
border: 0;
|
|
119
|
-
background: none;
|
|
120
|
-
cursor: pointer;
|
|
121
|
-
font-weight: 600;
|
|
122
|
-
font-size: 12px;
|
|
123
|
-
text-align: center;
|
|
124
|
-
width: 52px;
|
|
125
|
-
&:hover,
|
|
126
|
-
&:active,
|
|
127
|
-
&:focus,
|
|
128
|
-
&[aria-expanded='true'] {
|
|
129
|
-
background: ${colors.brand.greyLighter};
|
|
130
|
-
border-radius: 27px;
|
|
131
|
-
color: ${colors.text.primary};
|
|
58
|
+
grid-area: speed;
|
|
132
59
|
}
|
|
133
60
|
`;
|
|
134
61
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
bottom: 36px;
|
|
138
|
-
z-index: 99;
|
|
139
|
-
`;
|
|
140
|
-
|
|
141
|
-
const SpeedList = styled(MenuItems)`
|
|
142
|
-
background: #ffffff;
|
|
62
|
+
const SpeedList = styled(Content)`
|
|
63
|
+
background: ${colors.white};
|
|
143
64
|
border: 1px solid ${colors.brand.lighter};
|
|
144
|
-
border-radius:
|
|
65
|
+
border-radius: ${misc.borderRadius};
|
|
145
66
|
padding: 5px 10px;
|
|
146
67
|
display: flex;
|
|
147
68
|
flex-direction: column;
|
|
148
69
|
justify-content: center;
|
|
149
|
-
align-items: stretch;
|
|
150
70
|
`;
|
|
151
71
|
|
|
152
|
-
|
|
153
|
-
selected?: boolean;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const SpeedValueButton = styled(MenuItem)<SpeedValueButtonProps>`
|
|
72
|
+
const SpeedValueButton = styled(Item)`
|
|
157
73
|
height: 28px;
|
|
158
|
-
position: relative;
|
|
159
|
-
background: none;
|
|
160
|
-
border: 0;
|
|
161
74
|
padding: 0 14px;
|
|
162
75
|
cursor: pointer;
|
|
163
|
-
font-weight:
|
|
164
|
-
|
|
76
|
+
font-weight: ${fonts.weight.semibold};
|
|
77
|
+
${fonts.sizes('14px')};
|
|
165
78
|
color: ${colors.text.light};
|
|
166
79
|
display: flex;
|
|
167
80
|
justify-content: center;
|
|
168
|
-
align-items: center;
|
|
169
81
|
&:hover,
|
|
170
82
|
&:active,
|
|
171
83
|
&:focus,
|
|
172
|
-
&[data-
|
|
84
|
+
&[data-highlighted] {
|
|
173
85
|
background: ${colors.brand.greyLighter};
|
|
174
86
|
border-radius: 5px;
|
|
87
|
+
outline: none;
|
|
175
88
|
color: ${colors.text.primary};
|
|
176
89
|
}
|
|
177
|
-
${(props) =>
|
|
178
|
-
props.selected &&
|
|
179
|
-
`
|
|
180
|
-
color: ${colors.text.primary};
|
|
181
|
-
|
|
182
|
-
`}
|
|
183
90
|
`;
|
|
184
91
|
|
|
185
92
|
const SpeedSelectedMark = styled.span`
|
|
@@ -187,145 +94,105 @@ const SpeedSelectedMark = styled.span`
|
|
|
187
94
|
background: #d1372e;
|
|
188
95
|
width: 6px;
|
|
189
96
|
height: 6px;
|
|
190
|
-
display: inline-block;
|
|
191
|
-
align-self: flex-start;
|
|
192
97
|
margin: 6px 0 0 2px;
|
|
193
98
|
`;
|
|
194
99
|
|
|
195
100
|
const Time = styled.div`
|
|
196
|
-
|
|
101
|
+
${fonts.sizes('16px')};
|
|
197
102
|
`;
|
|
198
103
|
|
|
199
104
|
const ProgressWrapper = styled.div`
|
|
200
|
-
flex: 1
|
|
105
|
+
flex: 1;
|
|
201
106
|
display: flex;
|
|
202
107
|
align-items: center;
|
|
203
|
-
|
|
108
|
+
gap: ${spacing.small};
|
|
204
109
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
205
|
-
|
|
206
|
-
width: 100%;
|
|
207
|
-
margin: 0;
|
|
208
|
-
margin-bottom: ${spacing.normal};
|
|
110
|
+
grid-area: track;
|
|
209
111
|
}
|
|
210
112
|
`;
|
|
211
|
-
|
|
113
|
+
|
|
114
|
+
const SliderWrapper = styled(SliderRoot)`
|
|
212
115
|
cursor: pointer;
|
|
213
|
-
flex: 1
|
|
214
|
-
|
|
116
|
+
flex: 1;
|
|
117
|
+
position: relative;
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
user-select: none;
|
|
121
|
+
touch-action: none;
|
|
215
122
|
`;
|
|
216
123
|
|
|
217
|
-
const
|
|
124
|
+
const StyledTrack = styled(Track)`
|
|
218
125
|
height: 4px;
|
|
219
126
|
width: 100%;
|
|
220
127
|
background: ${colors.brand.lighter};
|
|
221
128
|
border-radius: 7px;
|
|
222
129
|
`;
|
|
223
130
|
|
|
224
|
-
const
|
|
131
|
+
const StyledRange = styled(Range)`
|
|
132
|
+
position: absolute;
|
|
225
133
|
height: 4px;
|
|
226
134
|
background: #5cbc80;
|
|
227
135
|
border-radius: 7px;
|
|
228
136
|
`;
|
|
229
137
|
|
|
230
|
-
const
|
|
138
|
+
const StyledThumb = styled(SliderThumb)`
|
|
139
|
+
display: block;
|
|
231
140
|
width: 20px;
|
|
232
141
|
height: 20px;
|
|
233
142
|
background: #5cbc80;
|
|
234
143
|
border-radius: 50%;
|
|
235
|
-
|
|
236
|
-
`;
|
|
237
|
-
|
|
238
|
-
const VolumeWrapper = styled.div`
|
|
239
|
-
position: relative;
|
|
240
|
-
display: flex;
|
|
241
|
-
justify-content: center;
|
|
242
|
-
${mq.range({ until: breakpoints.tabletWide })} {
|
|
243
|
-
order: 6;
|
|
244
|
-
}
|
|
144
|
+
outline: none;
|
|
245
145
|
`;
|
|
246
146
|
|
|
247
|
-
const
|
|
147
|
+
const VolumeWrapper = styled(PopoverRoot)`
|
|
248
148
|
position: relative;
|
|
249
149
|
display: flex;
|
|
250
150
|
justify-content: center;
|
|
251
151
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
252
|
-
|
|
253
|
-
`
|
|
254
|
-
order: ${props.order};
|
|
255
|
-
`}
|
|
256
|
-
}
|
|
257
|
-
`;
|
|
258
|
-
|
|
259
|
-
const VolumeButton = styled(MenuButton)`
|
|
260
|
-
background-color: inherit;
|
|
261
|
-
width: 48px;
|
|
262
|
-
height: 48px;
|
|
263
|
-
border-radius: 50%;
|
|
264
|
-
border: 0;
|
|
265
|
-
background-position: center;
|
|
266
|
-
background-repeat: no-repeat;
|
|
267
|
-
cursor: pointer;
|
|
268
|
-
|
|
269
|
-
svg {
|
|
270
|
-
fill: ${colors.brand.primary};
|
|
271
|
-
width: 32px;
|
|
272
|
-
height: 32px;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
&:hover,
|
|
276
|
-
&:active,
|
|
277
|
-
&:focus,
|
|
278
|
-
&[aria-expanded='true'] {
|
|
279
|
-
background-color: ${colors.brand.greyLighter};
|
|
152
|
+
grid-area: volume;
|
|
280
153
|
}
|
|
281
154
|
`;
|
|
282
155
|
|
|
283
|
-
const
|
|
284
|
-
position: absolute;
|
|
285
|
-
bottom: 52px;
|
|
286
|
-
z-index: 99;
|
|
287
|
-
`;
|
|
288
|
-
|
|
289
|
-
const VolumeList = styled.div`
|
|
156
|
+
const VolumeList = styled(PopoverContent)`
|
|
290
157
|
box-shadow: 0 14px 20px -5px rgba(32, 88, 143, 0.17);
|
|
291
158
|
border-radius: 60px;
|
|
292
|
-
background:
|
|
159
|
+
background: ${colors.white};
|
|
160
|
+
padding: ${spacing.small};
|
|
293
161
|
border: 1px solid ${colors.brand.lighter};
|
|
294
|
-
display: flex;
|
|
295
|
-
flex-direction: column;
|
|
296
|
-
justify-content: center;
|
|
297
|
-
width: 32px;
|
|
298
162
|
height: 128px;
|
|
299
163
|
`;
|
|
300
164
|
|
|
301
|
-
const VolumeSliderWrapper = styled
|
|
165
|
+
const VolumeSliderWrapper = styled(SliderRoot)`
|
|
302
166
|
cursor: pointer;
|
|
303
|
-
|
|
167
|
+
height: 100%;
|
|
168
|
+
position: relative;
|
|
304
169
|
display: flex;
|
|
305
|
-
|
|
306
|
-
|
|
170
|
+
flex-direction: column;
|
|
171
|
+
align-items: center;
|
|
172
|
+
user-select: none;
|
|
173
|
+
touch-action: none;
|
|
307
174
|
`;
|
|
308
175
|
|
|
309
|
-
const VolumeSliderBackground = styled(
|
|
176
|
+
const VolumeSliderBackground = styled(Track)`
|
|
310
177
|
height: 100%;
|
|
311
178
|
width: 5px;
|
|
312
179
|
background: ${colors.brand.lighter};
|
|
313
180
|
border-radius: 7px;
|
|
314
181
|
`;
|
|
315
182
|
|
|
316
|
-
const VolumeSliderSelected = styled(
|
|
183
|
+
const VolumeSliderSelected = styled(Range)`
|
|
184
|
+
position: absolute;
|
|
317
185
|
width: 5px;
|
|
318
186
|
background: ${colors.brand.secondary};
|
|
319
187
|
border-radius: 7px;
|
|
320
|
-
bottom: 0;
|
|
321
188
|
`;
|
|
322
189
|
|
|
323
|
-
const VolumeSliderHandle = styled(
|
|
190
|
+
const VolumeSliderHandle = styled(SliderThumb)`
|
|
191
|
+
display: block;
|
|
324
192
|
width: 20px;
|
|
325
193
|
height: 20px;
|
|
326
194
|
background: ${colors.brand.primary};
|
|
327
195
|
border-radius: 50%;
|
|
328
|
-
left: -8px;
|
|
329
196
|
`;
|
|
330
197
|
|
|
331
198
|
const formatTime = (seconds: number) => {
|
|
@@ -338,16 +205,15 @@ const formatTime = (seconds: number) => {
|
|
|
338
205
|
|
|
339
206
|
const speedValues = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
|
|
340
207
|
|
|
341
|
-
|
|
208
|
+
interface Props {
|
|
342
209
|
src: string;
|
|
343
210
|
title: string;
|
|
344
|
-
}
|
|
211
|
+
}
|
|
345
212
|
|
|
346
213
|
const Controls = ({ src, title }: Props) => {
|
|
347
214
|
const { t } = useTranslation();
|
|
348
215
|
const [speedValue, setSpeedValue] = useState(1);
|
|
349
216
|
const [volumeValue, setVolumeValue] = useState(100);
|
|
350
|
-
const [sliderValue, setSliderValue] = useState(0);
|
|
351
217
|
const [currentTime, setCurrentTime] = useState(0);
|
|
352
218
|
const [remainingTime, setRemainingTime] = useState(0);
|
|
353
219
|
const [playing, setPlaying] = useState(false);
|
|
@@ -364,8 +230,6 @@ const Controls = ({ src, title }: Props) => {
|
|
|
364
230
|
const audioElement = audioRef.current;
|
|
365
231
|
const handleTimeUpdate = () => {
|
|
366
232
|
const { currentTime, duration } = audioElement;
|
|
367
|
-
const percent = Math.round((currentTime / duration) * 100);
|
|
368
|
-
setSliderValue(percent);
|
|
369
233
|
setCurrentTime(Math.round(currentTime));
|
|
370
234
|
setRemainingTime(Math.round(duration - currentTime));
|
|
371
235
|
};
|
|
@@ -374,7 +238,6 @@ const Controls = ({ src, title }: Props) => {
|
|
|
374
238
|
const { currentTime, duration } = audioElement;
|
|
375
239
|
setCurrentTime(Math.round(currentTime));
|
|
376
240
|
setRemainingTime(Math.round(duration - currentTime));
|
|
377
|
-
setRemainingTime(Math.round(duration - currentTime));
|
|
378
241
|
};
|
|
379
242
|
|
|
380
243
|
const handleTimeEnded = () => {
|
|
@@ -410,16 +273,16 @@ const Controls = ({ src, title }: Props) => {
|
|
|
410
273
|
}
|
|
411
274
|
};
|
|
412
275
|
|
|
413
|
-
const handleSliderChange = (value: number) => {
|
|
276
|
+
const handleSliderChange = (value: number[]) => {
|
|
414
277
|
if (audioRef.current) {
|
|
415
|
-
audioRef.current.currentTime =
|
|
278
|
+
audioRef.current.currentTime = value[0];
|
|
416
279
|
}
|
|
417
280
|
};
|
|
418
281
|
|
|
419
|
-
const handleVolumeSliderChange = (
|
|
282
|
+
const handleVolumeSliderChange = (values: number[]) => {
|
|
420
283
|
if (audioRef.current) {
|
|
421
|
-
audioRef.current.volume =
|
|
422
|
-
setVolumeValue(
|
|
284
|
+
audioRef.current.volume = values[0] / 100;
|
|
285
|
+
setVolumeValue(values[0]);
|
|
423
286
|
}
|
|
424
287
|
};
|
|
425
288
|
|
|
@@ -428,112 +291,95 @@ const Controls = ({ src, title }: Props) => {
|
|
|
428
291
|
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
|
|
429
292
|
<audio ref={audioRef} src={src} title={title} preload="metadata" />
|
|
430
293
|
<ControlsWrapper>
|
|
431
|
-
<PlayButton
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
</span>
|
|
294
|
+
<PlayButton
|
|
295
|
+
aria-label={t(playing ? t('audio.pause') : t('audio.play'))}
|
|
296
|
+
colorTheme="lighter"
|
|
297
|
+
size="normal"
|
|
298
|
+
onClick={togglePlay}
|
|
299
|
+
>
|
|
300
|
+
{playing ? <Pause /> : <Play />}
|
|
439
301
|
</PlayButton>
|
|
440
|
-
<
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
<SpeedWrapper>
|
|
454
|
-
<Menu>
|
|
302
|
+
<Back15SecButton
|
|
303
|
+
variant="ghost"
|
|
304
|
+
colorTheme="greyLighter"
|
|
305
|
+
title={t('audio.controls.rewind15sec')}
|
|
306
|
+
aria-label={t('audio.controls.rewind15sec')}
|
|
307
|
+
onClick={() => onSeekSeconds(-15)}
|
|
308
|
+
>
|
|
309
|
+
<Back15 />
|
|
310
|
+
</Back15SecButton>
|
|
311
|
+
|
|
312
|
+
<Root>
|
|
313
|
+
<Trigger asChild>
|
|
455
314
|
<SpeedButton
|
|
456
|
-
|
|
457
|
-
|
|
315
|
+
shape="pill"
|
|
316
|
+
variant="ghost"
|
|
317
|
+
size="normal"
|
|
318
|
+
colorTheme="greyLighter"
|
|
458
319
|
title={t('audio.controls.selectSpeed')}
|
|
459
320
|
aria-label={t('audio.controls.selectSpeed')}
|
|
460
321
|
>
|
|
461
322
|
{speedValue}x
|
|
462
323
|
</SpeedButton>
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
</Menu>
|
|
484
|
-
</SpeedWrapper>
|
|
485
|
-
<WardButtonWrapper order={5}>
|
|
486
|
-
<Forward15SecButton
|
|
487
|
-
type="button"
|
|
488
|
-
title={t('audio.controls.forward15sec')}
|
|
489
|
-
aria-label={t('audio.controls.forward15sec')}
|
|
490
|
-
onClick={() => {
|
|
491
|
-
onSeekSeconds(15);
|
|
492
|
-
}}
|
|
493
|
-
>
|
|
494
|
-
<Forward15 />
|
|
495
|
-
</Forward15SecButton>
|
|
496
|
-
</WardButtonWrapper>
|
|
324
|
+
</Trigger>
|
|
325
|
+
<DropdownMenuPortal>
|
|
326
|
+
<SpeedList side="top">
|
|
327
|
+
{speedValues.map((speed) => (
|
|
328
|
+
<SpeedValueButton key={speed} onSelect={() => setSpeedValue(speed)}>
|
|
329
|
+
{speed}x{speed === speedValue && <SpeedSelectedMark />}
|
|
330
|
+
</SpeedValueButton>
|
|
331
|
+
))}
|
|
332
|
+
</SpeedList>
|
|
333
|
+
</DropdownMenuPortal>
|
|
334
|
+
</Root>
|
|
335
|
+
<Forward15SecButton
|
|
336
|
+
colorTheme="greyLighter"
|
|
337
|
+
variant="ghost"
|
|
338
|
+
title={t('audio.controls.forward15sec')}
|
|
339
|
+
aria-label={t('audio.controls.forward15sec')}
|
|
340
|
+
onClick={() => onSeekSeconds(15)}
|
|
341
|
+
>
|
|
342
|
+
<Forward15 />
|
|
343
|
+
</Forward15SecButton>
|
|
497
344
|
<ProgressWrapper>
|
|
498
345
|
<Time>{formatTime(currentTime)}</Time>
|
|
499
|
-
<SliderWrapper
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
346
|
+
<SliderWrapper
|
|
347
|
+
value={[audioRef.current?.currentTime ?? 0]}
|
|
348
|
+
defaultValue={[0]}
|
|
349
|
+
step={1}
|
|
350
|
+
max={audioRef.current?.duration ?? 0}
|
|
351
|
+
onValueChange={handleSliderChange}
|
|
352
|
+
>
|
|
353
|
+
<StyledTrack>
|
|
354
|
+
<StyledRange />
|
|
355
|
+
</StyledTrack>
|
|
356
|
+
<StyledThumb />
|
|
506
357
|
</SliderWrapper>
|
|
507
358
|
<Time>-{formatTime(remainingTime)}</Time>
|
|
508
359
|
</ProgressWrapper>
|
|
509
360
|
<VolumeWrapper>
|
|
510
|
-
<
|
|
511
|
-
|
|
512
|
-
<VolumeButton
|
|
513
|
-
type="button"
|
|
514
|
-
as="button"
|
|
515
|
-
title={t('audio.controls.adjustVolume')}
|
|
516
|
-
aria-label={t('audio.controls.adjustVolume')}
|
|
517
|
-
>
|
|
361
|
+
<PopoverTrigger asChild>
|
|
362
|
+
<IconButtonV2 variant="ghost" colorTheme="greyLighter" aria-label={t('audio.controls.adjustVolume')}>
|
|
518
363
|
<VolumeUp />
|
|
519
|
-
</
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
</
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
364
|
+
</IconButtonV2>
|
|
365
|
+
</PopoverTrigger>
|
|
366
|
+
<PopoverPortal>
|
|
367
|
+
<VolumeList side="top">
|
|
368
|
+
<VolumeSliderWrapper
|
|
369
|
+
orientation="vertical"
|
|
370
|
+
value={[volumeValue]}
|
|
371
|
+
min={0}
|
|
372
|
+
defaultValue={[100]}
|
|
373
|
+
step={1}
|
|
374
|
+
onValueChange={handleVolumeSliderChange}
|
|
375
|
+
>
|
|
376
|
+
<VolumeSliderBackground>
|
|
377
|
+
<VolumeSliderSelected />
|
|
378
|
+
</VolumeSliderBackground>
|
|
379
|
+
<VolumeSliderHandle />
|
|
380
|
+
</VolumeSliderWrapper>
|
|
381
|
+
</VolumeList>
|
|
382
|
+
</PopoverPortal>
|
|
537
383
|
</VolumeWrapper>
|
|
538
384
|
</ControlsWrapper>
|
|
539
385
|
</div>
|