PluginProbe ʕ •ᴥ•ʔ
Presto Player / 2.2.2
Presto Player v2.2.2
4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / src / admin / blocks / shared / tracks / TracksEditor.js
presto-player / src / admin / blocks / shared / tracks Last commit date
TracksEditor.js 5 years ago
TracksEditor.js
293 lines
1 /**
2 * WordPress dependencies
3 */
4 // import { __, sprintf } from '@wordpress/i18n';
5 const { __, sprintf } = wp.i18n;
6 const {
7 NavigableMenu,
8 MenuItem,
9 FormFileUpload,
10 MenuGroup,
11 ToolbarGroup,
12 ToolbarButton,
13 Dropdown,
14 SVG,
15 Rect,
16 Path,
17 Button,
18 TextControl,
19 SelectControl,
20 } = wp.components;
21 const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
22 const { useSelect } = wp.data;
23 const { useState } = wp.element;
24
25 const ALLOWED_TYPES = ["text/vtt"];
26
27 const DEFAULT_KIND = "subtitles";
28
29 // const KIND_OPTIONS = [
30 // { label: __("Subtitles"), value: "subtitles" },
31 // { label: __("Captions"), value: "captions" },
32 // { label: __("Descriptions"), value: "descriptions" },
33 // { label: __("Chapters"), value: "chapters" },
34 // { label: __("Metadata"), value: "metadata" },
35 // ];
36
37 const captionIcon = (
38 <svg viewBox="0 0 29 25" fill="none" xmlns="http://www.w3.org/2000/svg">
39 <path
40 fillRule="evenodd"
41 clipRule="evenodd"
42 d="M17.5014 20.2854H28.6316V0.764648H0.110825V20.2854H11.241L14.3712 24.2854L17.5014 20.2854ZM14.3712 21.0401L16.5269 18.2854H26.6316V2.76465H2.11082V18.2854H12.2155L14.3712 21.0401Z"
43 />
44 <path d="M10.4503 14.9446C9.56226 14.9446 8.76226 14.7606 8.05026 14.3926C7.33826 14.0166 6.77826 13.4966 6.37026 12.8326C5.97026 12.1606 5.77026 11.4006 5.77026 10.5526C5.77026 9.70464 5.97026 8.94864 6.37026 8.28464C6.77826 7.61264 7.33826 7.09264 8.05026 6.72464C8.76226 6.34864 9.56226 6.16064 10.4503 6.16064C11.2663 6.16064 11.9943 6.30464 12.6343 6.59264C13.2743 6.88064 13.8023 7.29664 14.2183 7.84064L12.4303 9.43664C11.9103 8.78064 11.2983 8.45264 10.5943 8.45264C10.0023 8.45264 9.52626 8.64464 9.16626 9.02864C8.80626 9.40464 8.62626 9.91264 8.62626 10.5526C8.62626 11.1926 8.80626 11.7046 9.16626 12.0886C9.52626 12.4646 10.0023 12.6526 10.5943 12.6526C11.2983 12.6526 11.9103 12.3246 12.4303 11.6686L14.2183 13.2646C13.8023 13.8086 13.2743 14.2246 12.6343 14.5126C11.9943 14.8006 11.2663 14.9446 10.4503 14.9446Z" />
45 <path d="M19.2042 14.9446C18.3162 14.9446 17.5162 14.7606 16.8042 14.3926C16.0922 14.0166 15.5322 13.4966 15.1242 12.8326C14.7242 12.1606 14.5242 11.4006 14.5242 10.5526C14.5242 9.70464 14.7242 8.94864 15.1242 8.28464C15.5322 7.61264 16.0922 7.09264 16.8042 6.72464C17.5162 6.34864 18.3162 6.16064 19.2042 6.16064C20.0202 6.16064 20.7482 6.30464 21.3882 6.59264C22.0282 6.88064 22.5562 7.29664 22.9722 7.84064L21.1842 9.43664C20.6642 8.78064 20.0522 8.45264 19.3482 8.45264C18.7562 8.45264 18.2802 8.64464 17.9202 9.02864C17.5602 9.40464 17.3802 9.91264 17.3802 10.5526C17.3802 11.1926 17.5602 11.7046 17.9202 12.0886C18.2802 12.4646 18.7562 12.6526 19.3482 12.6526C20.0522 12.6526 20.6642 12.3246 21.1842 11.6686L22.9722 13.2646C22.5562 13.8086 22.0282 14.2246 21.3882 14.5126C20.7482 14.8006 20.0202 14.9446 19.2042 14.9446Z" />
46 </svg>
47 );
48
49 function TrackList({ tracks, onEditPress }) {
50 let content;
51 if (tracks.length === 0) {
52 content = (
53 <p className="block-library-video-tracks-editor__tracks-informative-message">
54 {__(
55 "Captions are .vtt files that help make your content more accesible to a wider range of users.",
56 "presto-player"
57 )}
58 </p>
59 );
60 } else {
61 content = tracks.map((track, index) => {
62 return (
63 <div
64 key={index}
65 className="block-library-video-tracks-editor__track-list-track"
66 >
67 <span>{track.label} </span>
68 <Button
69 isTertiary
70 onClick={() => onEditPress(index)}
71 aria-label={sprintf(
72 /* translators: %s: Label of the video text track e.g: "French subtitles" */
73 __("Edit %s", "presto-player"),
74 track.label
75 )}
76 >
77 {__("Edit", "presto-player")}
78 </Button>
79 </div>
80 );
81 });
82 }
83 return (
84 <MenuGroup
85 label={__("Captions", "presto-player")}
86 className="block-library-video-tracks-editor__track-list"
87 >
88 {content}
89 </MenuGroup>
90 );
91 }
92
93 function SingleTrackEditor({ track, onChange, onClose, onRemove }) {
94 const { src = "", label = "", srcLang = "", kind = DEFAULT_KIND } = track;
95 const fileName = src.startsWith("blob:")
96 ? ""
97 : src.substring(src.lastIndexOf("/") + 1);
98 return (
99 <NavigableMenu>
100 <div className="block-library-video-tracks-editor__single-track-editor">
101 <span className="block-library-video-tracks-editor__single-track-editor-edit-track-label">
102 {__("Edit caption track", "presto-player")}
103 </span>
104 <span>
105 {__("File", "presto-player")}: <b>{fileName}</b>
106 </span>
107 <div className="block-library-video-tracks-editor__single-track-editor-label-language">
108 <TextControl
109 /* eslint-disable jsx-a11y/no-autofocus */
110 autoFocus
111 /* eslint-enable jsx-a11y/no-autofocus */
112 onChange={(newLabel) =>
113 onChange({
114 ...track,
115 label: newLabel,
116 })
117 }
118 label={__("Label", "presto-player")}
119 value={label}
120 help={__("Title of track", "presto-player")}
121 />
122 <TextControl
123 onChange={(newSrcLang) =>
124 onChange({
125 ...track,
126 srcLang: newSrcLang,
127 })
128 }
129 label={__("Source language", "presto-player")}
130 value={srcLang}
131 help={__("Language tag (en, fr, etc.)", "presto-player")}
132 />
133 </div>
134 {/* <SelectControl
135 className="block-library-video-tracks-editor__single-track-editor-kind-select"
136 options={KIND_OPTIONS}
137 value={kind}
138 label={__("Kind")}
139 onChange={(newKind) => {
140 if (newKind === DEFAULT_KIND) {
141 newKind = undefined;
142 }
143 onChange({
144 ...track,
145 kind: newKind,
146 });
147 }}
148 /> */}
149 <div className="block-library-video-tracks-editor__single-track-editor-buttons-container">
150 <Button
151 isSecondary
152 onClick={() => {
153 const changes = {};
154 let hasChanges = false;
155 if (label === "") {
156 changes.label = __("English", "presto-player");
157 hasChanges = true;
158 }
159 if (srcLang === "") {
160 changes.srcLang = "en";
161 hasChanges = true;
162 }
163 if (hasChanges) {
164 onChange({
165 ...track,
166 ...changes,
167 });
168 }
169 onClose();
170 }}
171 >
172 {__("Close", "presto-player")}
173 </Button>
174 <Button isDestructive isLink onClick={onRemove}>
175 {__("Remove track", "presto-player")}
176 </Button>
177 </div>
178 </div>
179 </NavigableMenu>
180 );
181 }
182
183 export default function TracksEditor({ tracks = [], onChange }) {
184 const mediaUpload = useSelect((select) => {
185 return select("core/block-editor").getSettings().mediaUpload;
186 }, []);
187 const [trackBeingEdited, setTrackBeingEdited] = useState(null);
188
189 if (!mediaUpload) {
190 return null;
191 }
192 return (
193 <Dropdown
194 contentClassName="block-library-video-tracks-editor"
195 renderToggle={({ isOpen, onToggle }) => (
196 <ToolbarGroup>
197 <ToolbarButton
198 label={__("Captions", "presto-player")}
199 showTooltip
200 aria-expanded={isOpen}
201 aria-haspopup="true"
202 onClick={onToggle}
203 icon={captionIcon}
204 />
205 </ToolbarGroup>
206 )}
207 renderContent={({}) => {
208 if (trackBeingEdited !== null) {
209 return (
210 <SingleTrackEditor
211 track={tracks[trackBeingEdited]}
212 onChange={(newTrack) => {
213 const newTracks = [...tracks];
214 newTracks[trackBeingEdited] = newTrack;
215 onChange(newTracks);
216 }}
217 onClose={() => setTrackBeingEdited(null)}
218 onRemove={() => {
219 onChange(
220 tracks.filter((_track, index) => index !== trackBeingEdited)
221 );
222 setTrackBeingEdited(null);
223 }}
224 />
225 );
226 }
227 return (
228 <>
229 <NavigableMenu>
230 <TrackList tracks={tracks} onEditPress={setTrackBeingEdited} />
231 <MenuGroup
232 className="block-library-video-tracks-editor__add-tracks-container"
233 label={__("Add caption languages", "presto-player")}
234 >
235 <MediaUpload
236 onSelect={({ url }) => {
237 const trackIndex = tracks.length;
238 onChange([...tracks, { src: url }]);
239 setTrackBeingEdited(trackIndex);
240 }}
241 allowedTypes={ALLOWED_TYPES}
242 render={({ open }) => (
243 <MenuItem icon={"media"} onClick={open}>
244 {__("Open Media Library", "presto-player")}
245 </MenuItem>
246 )}
247 />
248 <MediaUploadCheck>
249 <FormFileUpload
250 onChange={(event) => {
251 const files = event.target.files;
252 const trackIndex = tracks.length;
253 mediaUpload({
254 allowedTypes: ALLOWED_TYPES,
255 filesList: files,
256 onFileChange: ([{ url }]) => {
257 const newTracks = [...tracks];
258 if (!newTracks[trackIndex]) {
259 newTracks[trackIndex] = {};
260 }
261 newTracks[trackIndex] = {
262 ...tracks[trackIndex],
263 src: url,
264 };
265 onChange(newTracks);
266 setTrackBeingEdited(trackIndex);
267 },
268 });
269 }}
270 accept=".vtt,text/vtt"
271 render={({ openFileDialog }) => {
272 return (
273 <MenuItem
274 icon={"upload"}
275 onClick={() => {
276 openFileDialog();
277 }}
278 >
279 {__("Upload", "presto-player")}
280 </MenuItem>
281 );
282 }}
283 />
284 </MediaUploadCheck>
285 </MenuGroup>
286 </NavigableMenu>
287 </>
288 );
289 }}
290 />
291 );
292 }
293