Skip to content

Commit 8129edc

Browse files
Added the ability to add a clip to a collection
1 parent 17c976d commit 8129edc

File tree

9 files changed

+117
-36
lines changed

9 files changed

+117
-36
lines changed

src/api/CollectionAPI.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const getCollections = async (game) => {
2+
return await window.api.send("getCollections", game);
3+
}
4+
5+
const createNewCollection = async (collectionId, game) => {
6+
return await window.api.send("createCollection", { game, collectionId });
7+
}
8+
9+
const deleteCollection = async (collectionId, game, deleteFiles = false) => {
10+
return await window.api.send("deleteCollection", { game, collectionId, deleteFiles });
11+
}
12+
13+
const removeFromCollection = async (collectionId, game, videoId) => {
14+
return collectionMap = await window.api.send("removeFromCollection", { game, collectionId, videoId });
15+
}
16+
17+
const addToCollection = async (collectionId, game, videoId) => {
18+
return collectionMap = await window.api.send("addToCollection", { game, collectionId, videoId });
19+
}
20+
21+
export default {
22+
getCollections,
23+
createNewCollection,
24+
deleteCollection,
25+
removeFromCollection,
26+
addToCollection
27+
}

src/main/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ ipcMain.handle('storeVideo', (event, { base64ByteStream, subtitles, title, clipN
501501

502502
fs.writeFileSync(videoFilePath, Buffer.from(base64ByteStream, "base64"));
503503
fs.writeFileSync(subFilePath, subtitles);
504+
505+
return baseFileName;
504506
});
505507

506508
ipcMain.handle('deleteVideo', (event, { id, game }) => {

src/renderer/App.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, {useEffect, useState} from 'react';
33
import {Routes, Route, NavLink as Link, Navigate, useNavigate, useLocation} from 'react-router-dom';
44
import {ToastContainer} from 'react-toastify';
55

6-
import AdvancedEditor from './routes/AdvancedEditor';
6+
import AdvancedEditor from './routes/editor/AdvancedEditor';
77
import VideoList from './routes/VideoList';
88
import VideoView from './routes/VideoView';
99
import Launcher from './routes/Launcher';
@@ -12,10 +12,10 @@ import Config from './routes/Config';
1212
import About from './routes/About';
1313

1414
import 'react-toastify/dist/ReactToastify.css';
15-
import ClipEditor from './routes/ClipEditor';
16-
import SimpleEditor from './routes/SimpleEditor';
15+
import ClipEditor from './routes/editor/ClipEditor';
16+
import SimpleEditor from './routes/editor/SimpleEditor';
1717

18-
const VERSION = "v1.2.2-beta";
18+
const VERSION = "v1.2.3-beta";
1919

2020
let App = (props) => {
2121
const navigate = useNavigate();

src/renderer/components/SubtitleList.jsx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import CollectionAPI from 'api/CollectionAPI';
12
import { useEffect, useState } from 'react';
23
import { Link } from 'react-router-dom';
34

@@ -12,8 +13,19 @@ let convertMillisecondsToTimestamp = (milliseconds) => {
1213
}
1314

1415
export default ({ subs, currentSub, currentSliderPosition, game, onSubsChange, onSelectSub, onRemoveSub, onSave }) => {
15-
let [clipTitle, setClipTitle] = useState("");
16-
let [clipNumber, setClipNumber] = useState(1);
16+
const [clipTitle, setClipTitle] = useState("");
17+
const [clipNumber, setClipNumber] = useState(1);
18+
const [collections, setCollections] = useState([]);
19+
const [selectedCollection, setSelectedCollection] = useState("_none");
20+
21+
useEffect(() => {
22+
getCollections();
23+
}, []);
24+
25+
const getCollections = async () => {
26+
let collections = await CollectionAPI.getCollections(game);
27+
setCollections(collections);
28+
}
1729

1830
console.log("CURRENT SUB: " + currentSub);
1931

@@ -31,8 +43,19 @@ export default ({ subs, currentSub, currentSliderPosition, game, onSubsChange, o
3143
<td>Clip Number</td>
3244
<td><input type="number" value={clipNumber} onChange={({ target: { value } }) => { setClipNumber(value) }} /></td>
3345
</tr>
46+
<tr>
47+
<td>Collection</td>
48+
<td>
49+
<select value={selectedCollection} onChange={({target: {value}}) => {setSelectedCollection(value)}}>
50+
<option key="_none">None</option>
51+
{Object.keys(collections).map((collectionId) => (
52+
<option>{collectionId}</option>
53+
))}
54+
</select>
55+
</td>
56+
</tr>
3457
</table>
35-
<button onClick={() => { onSave(clipTitle, clipNumber) }}>Finalize Clip</button><br />
58+
<button onClick={() => { onSave(clipTitle, clipNumber, selectedCollection) }}>Finalize Clip</button><br />
3659
<Link to="/"><button>Cancel</button></Link>
3760
</div>
3861
<h3>Subtitles</h3>

src/renderer/routes/CollectionManager.jsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import CollectionAPI from 'api/CollectionAPI';
12
import React, { useState, useEffect } from 'react';
23
import { useParams } from 'react-router';
34
import { toast } from 'react-toastify';
@@ -21,25 +22,25 @@ export default () => {
2122
}
2223

2324
const createNewCollection = async () => {
24-
const collectionMap = await window.api.send("createCollection", {game, collectionId: newCollectionName});
25+
const collectionMap = await CollectionAPI.createNewCollection(newCollectionName, game);
2526
setCollections(collectionMap);
2627
setNewCollectionName("");
2728
toast("Created new clip pack!", {type: "info"});
2829
}
2930

3031
const deleteCollection = async (collectionId, deleteFiles = false) => {
31-
const collectionMap = await window.api.send("deleteCollection", {game, collectionId, deleteFiles});
32+
const collectionMap = await CollectionAPI.deleteCollection(collectionId, game, deleteFiles);
3233
setCollections(collectionMap);
3334
toast("Deleted clip pack!", {type: "info"});
3435
}
3536

3637
const removeFromCollection = async (collectionId, videoId) => {
37-
const collectionMap = await window.api.send("removeFromCollection", {game, collectionId, videoId});
38+
const collectionMap = await CollectionAPI.removeFromCollection(collectionId, game, videoId);
3839
setCollections(collectionMap);
3940
}
4041

4142
const addToCollection = async (collectionId, videoId) => {
42-
const collectionMap = await window.api.send("addToCollection", {game, collectionId, videoId});
43+
const collectionMap = await CollectionAPI.addToCollection(collectionId, game, videoId);
4344
setCollections(collectionMap);
4445
}
4546

src/renderer/routes/AdvancedEditor.jsx renamed to src/renderer/routes/editor/AdvancedEditor.jsx

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
import React, {useState} from 'react';
2-
import {useParams, useNavigate} from 'react-router';
1+
import React, { useState } from 'react';
2+
import { useParams, useNavigate } from 'react-router';
33
import { Link } from 'react-router-dom';
4-
import {toast} from 'react-toastify';
5-
import {addVideo} from '../util/VideoTools';
4+
import { toast } from 'react-toastify';
5+
import { addVideo } from '../../util/VideoTools';
66

7-
import {api} from '../util/Api';
7+
import { api } from '../../util/Api';
88

9-
import WhatTheDubPlayer from '../components/WhatTheDubPlayer';
10-
import TimeLine from '../components/TimeLine';
11-
import SubtitleList from '../components/SubtitleList';
9+
import WhatTheDubPlayer from '../../components/WhatTheDubPlayer';
10+
import TimeLine from '../../components/TimeLine';
11+
import SubtitleList from '../../components/SubtitleList';
12+
import CollectionAPI from 'api/CollectionAPI';
1213

1314
let AdvancedEditor = () => {
1415
const params = useParams();
1516
const navigate = useNavigate();
1617

17-
const [windowSize, setWindowSize] = useState({width: window.innerWidth, height: window.innerHeight});
18+
const [windowSize, setWindowSize] = useState({ width: window.innerWidth, height: window.innerHeight });
1819

1920
const [error, setError] = useState(null);
2021
const [videoSource, setVideoSource] = useState("");
@@ -37,7 +38,7 @@ let AdvancedEditor = () => {
3738
}
3839

3940
window.onresize = () => {
40-
setWindowSize({width: window.innerWidth, height: window.innerHeight})
41+
setWindowSize({ width: window.innerWidth, height: window.innerHeight })
4142
}
4243

4344
let onFileOpen = (e) => {
@@ -65,12 +66,12 @@ let AdvancedEditor = () => {
6566
} else if (seconds > videoLength * 1000) {
6667
seconds = videoLength * 1000;
6768
}
68-
setCurrentPosition(seconds/1000);
69+
setCurrentPosition(seconds / 1000);
6970
setCurrentSliderPosition(seconds);
7071
setIsPlaying(false);
7172
}
7273

73-
let addVideoToGame = async (videoName, clipNumber) => {
74+
let addVideoToGame = async (videoName, clipNumber, collectionId) => {
7475
if (await checkClipExists(videoName, clipNumber)) {
7576
setError("Clip with this name and number already exists");
7677
return;
@@ -80,19 +81,22 @@ let AdvancedEditor = () => {
8081

8182
try {
8283
setButtonsDisabled(true);
83-
await addVideo(videoSource.substring(videoSource.indexOf(',') + 1), subs, videoName, clipNumber, params.type);
84+
let videoId = await addVideo(videoSource.substring(videoSource.indexOf(',') + 1), subs, videoName, clipNumber, params.type);
85+
if (!collectionId.startsWith("_")) {
86+
await CollectionAPI.addToCollection(collectionId, params.type, videoId);
87+
}
8488
setButtonsDisabled(false);
8589

86-
toast(`Clip added successfully!`, {type: "info"});
90+
toast(`Clip added successfully!`, { type: "info" });
8791
navigate('/');
8892
} catch (error) {
8993
console.error(error);
90-
toast(`Clip add failed!`, {type: "error"});
94+
toast(`Clip add failed!`, { type: "error" });
9195
}
9296
}
9397

9498
let checkClipExists = async (title, clipNumber) => {
95-
return await api.send("clipExists", {title, clipNumber, game: params.type});
99+
return await api.send("clipExists", { title, clipNumber, game: params.type });
96100
}
97101

98102
const subChangeHandler = (mode, sub) => {
@@ -152,8 +156,8 @@ let AdvancedEditor = () => {
152156

153157
return (
154158
<div>
155-
<div style={{color: "red"}}>{error}</div>
156-
{ videoSource ?
159+
<div style={{ color: "red" }}>{error}</div>
160+
{videoSource ?
157161
<div className="editor-container">
158162
<div className="top-pane">
159163
<WhatTheDubPlayer
@@ -181,7 +185,7 @@ let AdvancedEditor = () => {
181185
subs={subs}
182186
onSubsChange={subChangeHandler}
183187
onSelectSub={setCurrentSub}
184-
onSave={(title, number) => {addVideoToGame(title, number)}} />
188+
onSave={(title, number, collectionId) => { addVideoToGame(title, number, collectionId) }} />
185189
</div>
186190
<TimeLine
187191
timelineWidth={windowSize.width * 0.9}
File renamed without changes.

src/renderer/routes/SimpleEditor.jsx renamed to src/renderer/routes/editor/SimpleEditor.jsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import React, { useState } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import { toast } from 'react-toastify';
3-
import WhatTheDubPlayer from '../components/WhatTheDubPlayer';
4-
import { addVideo } from '../util/VideoTools';
3+
import WhatTheDubPlayer from '../../components/WhatTheDubPlayer';
4+
import { addVideo } from '../../util/VideoTools';
55
import { useParams, useNavigate } from 'react-router';
66
import { Link } from 'react-router-dom';
7+
import CollectionAPI from 'api/CollectionAPI';
78

89
let SimpleEditor = () => {
910
const params = useParams();
@@ -17,6 +18,8 @@ let SimpleEditor = () => {
1718
const [currentSub, setCurrentSub] = useState(null);
1819
const [substitution, setSubstitution] = useState("");
1920
const [buttonsDisabled, setButtonsDisabled] = useState(false);
21+
const [collections, setCollections] = useState([]);
22+
const [selectedCollection, setSelectedCollection] = useState("_none");
2023

2124
const [isPlaying, setIsPlaying] = useState(false);
2225
const [currentPosition, setCurrentPosition] = useState(0);
@@ -100,7 +103,8 @@ let SimpleEditor = () => {
100103
let addVideoToGame = async () => {
101104
try {
102105
setButtonsDisabled(true);
103-
await addVideo(videoSource.substring(videoSource.indexOf(',') + 1), subs, videoName, clipNumber, params.type);
106+
let videoId = await addVideo(videoSource.substring(videoSource.indexOf(',') + 1), subs, videoName, clipNumber, params.type);
107+
CollectionAPI.addToCollection(selectedCollection, params.type, videoId);
104108
setButtonsDisabled(false);
105109

106110
toast(`Clip added successfully!`, { type: "info" });
@@ -135,6 +139,15 @@ let SimpleEditor = () => {
135139
setError(null);
136140
}
137141

142+
useEffect(() => {
143+
getCollections();
144+
}, []);
145+
146+
const getCollections = async () => {
147+
let collections = await CollectionAPI.getCollections(params.type);
148+
setCollections(collections);
149+
}
150+
138151
return (
139152
<div>
140153
<h3>{game} Clip Editor</h3>
@@ -209,6 +222,17 @@ let SimpleEditor = () => {
209222
<tr>
210223
<td>Clip Number</td><td><input type="number" min={1} max={999} maxLength={3} value={clipNumber} onChange={(e) => { updateClipNumber(Math.min(e.target.value, 999)) }} /></td>
211224
</tr>
225+
<tr>
226+
<td>Collection</td>
227+
<td>
228+
<select value={selectedCollection} onChange={({ target: { value } }) => { setSelectedCollection(value) }}>
229+
<option key="_none">None</option>
230+
{Object.keys(collections).map((collectionId) => (
231+
<option>{collectionId}</option>
232+
))}
233+
</select>
234+
</td>
235+
</tr>
212236
</table>
213237
</div>
214238
<div>

src/renderer/util/VideoTools.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,5 @@ export let createWebVttDataUri = (subtitles, substitution) => {
110110
}
111111

112112
export let addVideo = async (base64ByteStream, subtitles, title, clipNumber = 1, type) => {
113-
await window.api.send("storeVideo", {base64ByteStream, subtitles: convertSubtitlesToSrt(subtitles, type), title, clipNumber, game: type});
114-
}
113+
return await window.api.send("storeVideo", {base64ByteStream, subtitles: convertSubtitlesToSrt(subtitles, type), title, clipNumber, game: type});
114+
}

0 commit comments

Comments
 (0)