Skip to content

Commit

Permalink
swaps between an idle playing video element and an answer playing vid…
Browse files Browse the repository at this point in the history
…eo element
  • Loading branch information
aaronshiel committed May 15, 2022
1 parent 17ad0d8 commit 917463f
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 88 deletions.
220 changes: 148 additions & 72 deletions client/src/components/video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ function Video(args: {
});
const curMentor = useSelector<State, string>((state) => state.curMentor);

const idleVideo = useSelector<State, VideoData | null>((state) => {
const m = state.mentorsById[state.curMentor];
if (!m) {
return null;
}
return {
src: idleUrl(m.mentor),
subtitles: "",
};
});

const video = useSelector<State, VideoData | null>((state) => {
if (state.chat.replay) {
const videoMedia = state.chat.messages.find((m) => {
Expand All @@ -69,11 +80,8 @@ function Video(args: {
return null;
}
return {
src: state.isIdle ? idleUrl(m.mentor) : videoUrl(m.answer_media || []),
subtitles:
subtitlesSupported && !state.isIdle
? subtitleUrl(m.answer_media || [])
: "",
src: videoUrl(m.answer_media || []),
subtitles: subtitlesSupported ? subtitleUrl(m.answer_media || []) : "",
};
});

Expand Down Expand Up @@ -168,6 +176,7 @@ function Video(args: {
}

function onEnded() {
setVideoFinishedBuffering(false);
setHideLinkLabel(true);
dispatch(playIdleAfterReplay(false));
dispatch(answerFinished());
Expand All @@ -185,7 +194,6 @@ function Video(args: {
if (isIdle) {
setHideLinkLabel(true);
dispatch(answerFinished());

return;
}
dispatch(
Expand All @@ -202,6 +210,8 @@ function Video(args: {
};

const [disclaimerOpen, setDisclaimerOpen] = useState<boolean>(false);
const [videoFinishedBuffering, setVideoFinishedBuffering] =
useState<boolean>(true);
const disclaimerDisplayed = getLocalStorage("viewedDisclaimer");
useEffect(() => {
if (!disclaimerDisplayed || disclaimerDisplayed !== "true") {
Expand All @@ -216,81 +226,144 @@ function Video(args: {
}
}

return (
<div
data-cy="video-container"
data-test-playing={Boolean(playing)}
data-video-type={isIdle ? "idle" : "answer"}
className="video-container"
data-test-replay={video.src}
>
<MemoVideoPlayer
isIdle={Boolean(isIdle)}
onEnded={onEnded}
onPlay={onPlay}
playing={Boolean(playing)}
setDuration={setDuration}
subtitlesOn={Boolean(subtitlesSupported) && Boolean(video.subtitles)}
subtitlesUrl={video.subtitles}
videoUrl={video.src}
webLinks={webLinks}
hideLinkLabel={hideLinkLabel}
mentorName={mentorData ? mentorData.name : ""}
numberMentors={numberMentors}
/>
<LoadingSpinner mentor={curMentor} />
<MessageStatus mentor={curMentor} />
{mentorData?.name && args.configEmailMentorAddress ? (
<Tooltip
data-cy="email-disclaimer"
open={disclaimerOpen}
onClose={onCloseDisclaimer}
onOpen={() => setDisclaimerOpen(true)}
title={
<div
style={{
fontSize: "15px",
pointerEvents: "auto",
cursor: !disclaimerDisplayed ? "pointer" : "none",
}}
onClick={() => onCloseDisclaimer()}
>
Please only contact mentors through the provided contact email.
Messages sent directly to other mentor emails found online may be
ignored.
{!disclaimerDisplayed ? (
<>
<br /> <br /> Click here to close
</>
) : (
""
)}
</div>
}
arrow
function onProgressAnswerVideo(state: {
played: number;
playedSeconds: number;
loaded: number;
loadedSeconds: number;
}) {
if (state.playedSeconds > 0.1 && !videoFinishedBuffering && !isIdle) {
setVideoFinishedBuffering(true);
}
}

function onProgressIdleVideo() {
return;
}

function PlayVideo() {
if (!idleVideo || !video) {
return <div></div>;
}
return (
<div
data-cy="video-container"
data-test-playing={true}
className="video-container"
style={{ display: "block" }}
data-test-replay={idleVideo.src}
>
<div
data-cy="answer-idle-video-container"
style={{ position: "relative", textAlign: "left" }}
>
<div
data-cy="email-mentor-icon"
className="email-mentor-button"
onClick={() =>
sendMail(
args.configEmailMentorAddress,
`Contacting ${mentorData.name} for more information`
)
{/* Answer Video Player, once its onPlay is triggered */}
<span
className="video-player-wrapper"
style={{ zIndex: !isIdle && videoFinishedBuffering ? 2 : 0 }}
>
<MemoVideoPlayer
isIdle={Boolean(isIdle)}
onEnded={onEnded}
onPlay={onPlay}
onProgress={onProgressAnswerVideo}
playing={Boolean(playing)}
setDuration={setDuration}
subtitlesOn={
Boolean(subtitlesSupported) && Boolean(video.subtitles)
}
subtitlesUrl={video.subtitles}
videoUrl={isIdle ? "" : video.src}
webLinks={webLinks}
hideLinkLabel={hideLinkLabel}
mentorName={mentorData ? mentorData.name : ""}
numberMentors={numberMentors}
/>
</span>
{/* Idle video player, always activate, but sits behind answer video player */}
<span
className="video-player-wrapper"
style={{ position: "absolute", top: 0, left: 0, zIndex: 1 }}
>
<MemoVideoPlayer
isIdle={true}
onEnded={onEnded}
onPlay={onPlay}
playing={true}
onProgress={onProgressIdleVideo}
setDuration={setDuration}
subtitlesOn={false}
subtitlesUrl={""}
videoUrl={idleVideo.src}
webLinks={webLinks}
hideLinkLabel={hideLinkLabel}
mentorName={mentorData ? mentorData.name : ""}
numberMentors={numberMentors}
/>
</span>
</div>
<LoadingSpinner mentor={curMentor} />
<MessageStatus mentor={curMentor} />
{mentorData?.name && args.configEmailMentorAddress ? (
<Tooltip
data-cy="email-disclaimer"
open={disclaimerOpen}
onClose={onCloseDisclaimer}
onOpen={() => setDisclaimerOpen(true)}
title={
<div
style={{
fontSize: "15px",
pointerEvents: "auto",
cursor: !disclaimerDisplayed ? "pointer" : "none",
}}
onClick={() => onCloseDisclaimer()}
>
Please only contact mentors through the provided contact email.
Messages sent directly to other mentor emails found online may
be ignored.
{!disclaimerDisplayed ? (
<>
<br /> <br /> Click here to close
</>
) : (
""
)}
</div>
}
arrow
>
Email Mentor <MailIcon />
</div>
</Tooltip>
) : undefined}
</div>
);
<div
data-cy="email-mentor-icon"
className="email-mentor-button"
onClick={() =>
sendMail(
args.configEmailMentorAddress,
`Contacting ${mentorData.name} for more information`
)
}
>
Email Mentor <MailIcon />
</div>
</Tooltip>
) : undefined}
</div>
);
}

return PlayVideo();
}

interface VideoPlayerParams {
isIdle: boolean;
onEnded: () => void;
onPlay: () => void;
onProgress: (state: {
played: number;
playedSeconds: number;
loaded: number;
loadedSeconds: number;
}) => void;
playing?: boolean;
setDuration: (d: number) => void;
subtitlesOn: boolean;
Expand All @@ -307,6 +380,7 @@ function VideoPlayer(args: VideoPlayerParams) {
isIdle,
onEnded,
onPlay,
onProgress,
playing,
setDuration,
subtitlesOn,
Expand Down Expand Up @@ -381,8 +455,10 @@ function VideoPlayer(args: VideoPlayerParams) {
onDuration={setDuration}
onEnded={onEnded}
onPlay={onPlay}
onProgress={onProgress}
loop={isIdle}
controls={!isIdle}
progressInterval={100}
playing={Boolean(playing)}
playsinline
webkit-playsinline="true"
Expand Down
2 changes: 1 addition & 1 deletion cypress/cypress/fixtures/clint.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"webMedia": {
"type": "video",
"tag": "web",
"url": "http://videos.org/answer_id.mp4"
"url": "http://videos.org/idle.mp4"
},
"mobileMedia": {
"type": "video",
Expand Down
18 changes: 3 additions & 15 deletions cypress/cypress/integration/video.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,12 @@ describe("Video Mentor", () => {
it("plays a mentor response and displays subtitles", () => {
mockDefaultSetup(cy, { mentorData: clint });
cy.visit("/?mentor=clint");

cy.get("[data-cy=input-field]").type("is the food good");
// have to wait until the intro video is done to send a question
// to truly check if we are recieving a response to the question
cy.get("[data-cy=video-container]", { timeout: 8000 }).should(
"have.attr",
"data-video-type",
"idle"
);
cy.wait(8000);
cy.get("[data-cy=input-send]").trigger("mouseover").click();
cy.get("[data-cy=video-container]").should(
"have.attr",
"data-video-type",
"answer"
);
cy.get("[data-cy=video-container]").within(($vc) => {
cy.get("video").should("exist");
cy.get("video")
Expand Down Expand Up @@ -253,11 +245,7 @@ describe("Video Mentor", () => {
cy.get("[data-cy=input-field]").type("is the food good");
// have to wait until the intro video is done to send a question
// to truly check if we are recieving a response to the question
cy.get("[data-cy=video-container]", { timeout: 8000 }).should(
"have.attr",
"data-video-type",
"idle"
);
cy.wait(8000);
cy.get("[data-cy=input-send]").trigger("mouseover").click();
cy.get("[data-cy=video-container]").within(($vc) => {
cy.get("video").should("exist");
Expand Down
1 change: 1 addition & 0 deletions cypress/cypress/support/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export function cyMockConfig(config: Partial<Config>) {
}

export function mockMentorVideos(cy) {
cy.intercept("**/idle.mp4", { fixture: "3.mp4" });
cy.intercept("**/*.mp4", { fixture: "video_response.mp4" });
}

Expand Down

0 comments on commit 917463f

Please sign in to comment.