Skip to content

Commit

Permalink
Merge pull request #1603 from ecency/feature/3speak-limitation
Browse files Browse the repository at this point in the history
Feature/3speak limitation
  • Loading branch information
feruzm authored May 9, 2024
2 parents 244d305 + ee729ee commit ab80038
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/common/components/video-gallery/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const VideoGallery = ({
<ModalHeader closeButton={true}>
<ModalTitle>{_t("video-gallery.title")}</ModalTitle>
</ModalHeader>
<ModalBody>
<ModalBody className="min-h-[400px]">
<div className="video-status-picker">
{!isEditing ? (
<DropDown
Expand Down
8 changes: 6 additions & 2 deletions src/common/components/video-upload-threespeak/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Modal, ModalBody, ModalHeader, ModalTitle } from "@ui/modal";
import { recordVideoSvg } from "../../img/svg";
import { VideoUploadRecorder } from "./video-upload-recorder";
import useMountedState from "react-use/lib/useMountedState";
import { Alert } from "@ui/alert";

const DEFAULT_THUMBNAIL = require("./assets/thumbnail-play.jpg");

Expand Down Expand Up @@ -120,7 +121,10 @@ export const VideoUpload = (props: Props & React.HTMLAttributes<HTMLDivElement>)
const uploadVideoModal = (
<div className="dialog-content ">
<div className="three-speak-video-uploading position-relative">
<p className="font-weight-bold">Video source</p>
<Alert appearance="primary" className="mb-4">
{_t("video-upload.min-duration-alert")}
</Alert>
<p className="font-weight-bold mb-2">{_t("video-upload.source")}</p>
{showRecorder ? (
<VideoUploadRecorder
setVideoUrl={setVideoUrl}
Expand Down Expand Up @@ -151,7 +155,7 @@ export const VideoUpload = (props: Props & React.HTMLAttributes<HTMLDivElement>)
/>
</div>
)}
<p className="font-weight-bold mt-5">Thumbnail</p>
<p className="font-weight-bold mt-5">{_t("video-upload.thumbnail")}</p>
<VideoUploadItem
label={_t("video-upload.choose-thumbnail")}
onFileChange={handleThumbnailChange}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { circleSvg, rectSvg, switchCameraSvg } from "../../img/svg";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useGetCameraList } from "./utils";
import { useStopwatch } from "../../util/use-stopwatch";

interface Props {
noPermission: boolean;
Expand All @@ -19,59 +20,73 @@ export function VideoUploadRecorderActions({

const [currentCameraIndex, setCurrentCameraIndex] = useState(0);
const [recordStarted, setRecordStarted] = useState(false);
const stopwatch = useStopwatch();

useEffect(() => {
recordStarted ? stopwatch.start() : stopwatch.clear();
}, [recordStarted]);

const getNextCameraIndex = (index: number) => (index + 1) % cameraList.length;

return (
<div className="actions">
<div>
{!recordStarted && cameraList.length > 1 ? (
<div
className="switch-camera"
onClick={() => {
const nextCameraIndex = getNextCameraIndex(currentCameraIndex);
onCameraSelect(cameraList[nextCameraIndex]);
setCurrentCameraIndex(nextCameraIndex);
}}
>
{switchCameraSvg}
</div>
) : (
<></>
)}
</div>
<>
{recordStarted && (
<div className="absolute top-4 right-4 text-white">
{`${stopwatch.hours}`.padStart(2, "0")}:{`${stopwatch.minutes}`.padStart(2, "0")}:
{`${stopwatch.seconds}`.padStart(2, "0")}
</div>
)}

<div className="actions">
<div>
{!recordStarted && cameraList.length > 1 ? (
<div
className="switch-camera"
onClick={() => {
const nextCameraIndex = getNextCameraIndex(currentCameraIndex);
onCameraSelect(cameraList[nextCameraIndex]);
setCurrentCameraIndex(nextCameraIndex);
}}
>
{switchCameraSvg}
</div>
) : (
<></>
)}
</div>

<div>
{recordStarted ? (
<div
aria-disabled={noPermission}
className="record-btn"
onClick={() => {
mediaRecorder?.stop();
setRecordStarted(false);
}}
>
{rectSvg}
</div>
) : (
<></>
)}
{!recordStarted && recordButtonShow ? (
<div
aria-disabled={noPermission}
className="record-btn"
onClick={() => {
mediaRecorder?.start();
setRecordStarted(true);
}}
>
{circleSvg}
</div>
) : (
<></>
)}
<div>
{recordStarted ? (
<div
aria-disabled={noPermission}
className="record-btn"
onClick={() => {
mediaRecorder?.stop();
setRecordStarted(false);
}}
>
{rectSvg}
</div>
) : (
<></>
)}
{!recordStarted && recordButtonShow ? (
<div
aria-disabled={noPermission}
className="record-btn"
onClick={() => {
mediaRecorder?.start();
setRecordStarted(true);
}}
>
{circleSvg}
</div>
) : (
<></>
)}
</div>
<div />
</div>
<div />
</div>
</>
);
}
5 changes: 4 additions & 1 deletion src/common/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1497,7 +1497,10 @@
"confirm-and-upload": "Confirm and upload to 3Speak",
"uploading": "Uploading..{{n}}/{{total}}",
"uploaded": "Uploaded!",
"reset": "Reset"
"reset": "Reset",
"source": "Video source",
"thumbnail": "Thumbnail",
"min-duration-alert": "Video less than 15 seconds in duration will be ignored by 3Speak."
},
"video-gallery": {
"all": "All",
Expand Down
60 changes: 60 additions & 0 deletions src/common/util/use-stopwatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useCallback, useEffect, useRef, useState } from "react";

interface TimeState {
hours: number;
minutes: number;
seconds: number;
}

export function useStopwatch() {
const [time, setTime] = useState<TimeState>({ seconds: 0, minutes: 0, hours: 0 });
const [isActive, setIsActive] = useState(false);
const intervalRef = useRef<any>(null);

const tick = useCallback(() => {
setTime((prevTime) => {
let hours = prevTime.hours;
let minutes = prevTime.minutes;
let seconds = prevTime.seconds;

seconds += 1;

if (seconds >= 60) {
minutes += 1;
seconds = 0;
}

if (minutes >= 60) {
hours += 1;
minutes = 0;
}

return { hours, minutes, seconds };
});
}, []);

const clear = useCallback(() => {
clearInterval(intervalRef.current);
intervalRef.current = null;
setTime({ seconds: 0, minutes: 0, hours: 0 });
}, []);

const start = useCallback(() => {
setIsActive(true);
intervalRef.current = setInterval(tick, 1000);
}, [tick]);

useEffect(() => {
return () => {
clear();
};
}, [clear]);

return {
...time,
isActive,
clear,
start,
setIsActive
};
}

0 comments on commit ab80038

Please sign in to comment.