From c0e92631db07a86529d56283be52e0806d3c9cdc Mon Sep 17 00:00:00 2001 From: BFlat Date: Sat, 23 Jul 2022 01:50:30 +0100 Subject: [PATCH 1/6] w2l template view --- .../w2l_template_view/W2lTemplateViewFc.tsx | 567 ++++++++++-------- 1 file changed, 325 insertions(+), 242 deletions(-) diff --git a/packages/fakeyou/src/v2/view/w2l/w2l_template_view/W2lTemplateViewFc.tsx b/packages/fakeyou/src/v2/view/w2l/w2l_template_view/W2lTemplateViewFc.tsx index 35a3287070..3fb56125a6 100644 --- a/packages/fakeyou/src/v2/view/w2l/w2l_template_view/W2lTemplateViewFc.tsx +++ b/packages/fakeyou/src/v2/view/w2l/w2l_template_view/W2lTemplateViewFc.tsx @@ -1,73 +1,86 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import axios from 'axios'; -import { ApiConfig } from '@storyteller/components'; -import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper'; -import { Gravatar } from '@storyteller/components/src/elements/Gravatar'; -import { W2lInferenceJob } from '../../../../App'; -import { useParams, Link } from 'react-router-dom'; -import { v4 as uuidv4 } from 'uuid'; -import { SessionW2lInferenceResultListFc } from '../../_common/SessionW2lInferenceResultsListFc'; -import { ReportDiscordLinkFc } from '../../_common/DiscordReportLinkFc'; -import { BucketConfig } from '@storyteller/components/src/api/BucketConfig'; -import { UploadIcon } from '../../_icons/UploadIcon'; -import { VisibleIconFc } from '../../_icons/VisibleIcon'; -import { HiddenIconFc } from '../../_icons/HiddenIcon'; -import { FrontendUrlConfig } from '../../../../common/FrontendUrlConfig'; -import { GetW2lTemplate, GetW2lTemplateIsErr, GetW2lTemplateIsOk, W2lTemplate, W2lTemplateLookupError } from '../../../api/w2l/GetW2lTemplate'; -import { GetW2lTemplateUseCount } from '../../../api/w2l/GetW2lTemplateUseCount'; -import { BackLink } from '../../_common/BackLink'; +import React, { useState, useEffect, useCallback } from "react"; +import axios from "axios"; +import { ApiConfig } from "@storyteller/components"; +import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper"; +import { Gravatar } from "@storyteller/components/src/elements/Gravatar"; +import { W2lInferenceJob } from "../../../../App"; +import { useParams, Link } from "react-router-dom"; +import { v4 as uuidv4 } from "uuid"; +import { SessionW2lInferenceResultListFc } from "../../_common/SessionW2lInferenceResultsListFc"; +import { ReportDiscordLinkFc } from "../../_common/DiscordReportLinkFc"; +import { BucketConfig } from "@storyteller/components/src/api/BucketConfig"; +import { UploadIcon } from "../../_icons/UploadIcon"; +import { VisibleIconFc } from "../../_icons/VisibleIcon"; +import { HiddenIconFc } from "../../_icons/HiddenIcon"; +import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig"; +import { + GetW2lTemplate, + GetW2lTemplateIsErr, + GetW2lTemplateIsOk, + W2lTemplate, + W2lTemplateLookupError, +} from "../../../api/w2l/GetW2lTemplate"; +import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount"; +import { BackLink } from "../../_common/BackLink"; interface EnqueueJobResponsePayload { - success: boolean, - inference_job_token?: string, + success: boolean; + inference_job_token?: string; } interface Props { - sessionWrapper: SessionWrapper, - enqueueW2lJob: (jobToken: string) => void, - w2lInferenceJobs: Array, + sessionWrapper: SessionWrapper; + enqueueW2lJob: (jobToken: string) => void; + w2lInferenceJobs: Array; } function W2lTemplateViewFc(props: Props) { - let { templateSlug } : { templateSlug : string } = useParams(); + let { templateSlug }: { templateSlug: string } = useParams(); // Ajax - const [w2lTemplate, setW2lTemplate] = useState(undefined); - const [w2lTemplateUseCount, setW2lTemplateUseCount] = useState(undefined); + const [w2lTemplate, setW2lTemplate] = useState( + undefined + ); + const [w2lTemplateUseCount, setW2lTemplateUseCount] = useState< + number | undefined + >(undefined); const [notFoundState, setNotFoundState] = useState(false); // Inference - const [audioFile, setAudioFile] = useState(undefined); + const [audioFile, setAudioFile] = useState(undefined); // Moderation - const [modApprovedFormValue, setModApprovedFormValue] = useState(true); + const [modApprovedFormValue, setModApprovedFormValue] = + useState(true); - const getTemplate = useCallback(async (templateSlug: string) => { - const templateResponse = await GetW2lTemplate(templateSlug); + const getTemplate = useCallback( + async (templateSlug: string) => { + const templateResponse = await GetW2lTemplate(templateSlug); - if (GetW2lTemplateIsOk(templateResponse)) { - setW2lTemplate(templateResponse) + if (GetW2lTemplateIsOk(templateResponse)) { + setW2lTemplate(templateResponse); - let modApprovalState = templateResponse?.is_public_listing_approved; + let modApprovalState = templateResponse?.is_public_listing_approved; - if (modApprovedFormValue === undefined || modApprovalState === null) { - modApprovalState = true; + if (modApprovedFormValue === undefined || modApprovalState === null) { + modApprovalState = true; + } + + setModApprovedFormValue(modApprovalState); + } else if (GetW2lTemplateIsErr(templateResponse)) { + switch (templateResponse) { + case W2lTemplateLookupError.NotFound: + setNotFoundState(true); + break; + } } - - setModApprovedFormValue(modApprovalState); - - } else if (GetW2lTemplateIsErr(templateResponse)) { - switch(templateResponse) { - case W2lTemplateLookupError.NotFound: - setNotFoundState(true); - break; - } - } - }, [modApprovedFormValue]); + }, + [modApprovedFormValue] + ); const getTemplateUseCount = useCallback(async (templateToken) => { const count = await GetW2lTemplateUseCount(templateToken); - setW2lTemplateUseCount(count || 0) + setW2lTemplateUseCount(count || 0); }, []); useEffect(() => { @@ -76,19 +89,15 @@ function W2lTemplateViewFc(props: Props) { }, [templateSlug, getTemplate, getTemplateUseCount]); if (notFoundState) { - return ( -

Template not found

- ); + return

Template not found

; } if (!w2lTemplate) { - return
+ return
; } - const handleAudioFileChange = (fileList: FileList|null) => { - if (fileList === null - || fileList === undefined - || fileList.length < 1) { + const handleAudioFileChange = (fileList: FileList | null) => { + if (fileList === null || fileList === undefined || fileList.length < 1) { setAudioFile(undefined); } @@ -96,7 +105,9 @@ function W2lTemplateViewFc(props: Props) { setAudioFile(file); }; - const handleInferenceFormSubmit = (ev: React.FormEvent) : boolean => { + const handleInferenceFormSubmit = ( + ev: React.FormEvent + ): boolean => { ev.preventDefault(); if (audioFile === undefined) { @@ -110,43 +121,49 @@ function W2lTemplateViewFc(props: Props) { const templateToken = w2lTemplate!.template_token; let formData = new FormData(); - formData.append('audio', audioFile!); - formData.append('template_token', templateToken); - formData.append('uuid_idempotency_token', uuidv4()!); + formData.append("audio", audioFile!); + formData.append("template_token", templateToken); + formData.append("uuid_idempotency_token", uuidv4()!); const api = new ApiConfig(); const endpointUrl = api.inferW2l(); // NB: Using 'axios' because 'fetch' was having problems with form-multipart // and then interpreting the resultant JSON. Maybe I didn't try hard enough? - axios.post(endpointUrl, formData, { withCredentials: true }) - .then(res => res.data) - .then(res => { - console.log('w2l submitted'); - let response : EnqueueJobResponsePayload = res; + axios + .post(endpointUrl, formData, { withCredentials: true }) + .then((res) => res.data) + .then((res) => { + console.log("w2l submitted"); + let response: EnqueueJobResponsePayload = res; if (!response.success || response.inference_job_token === undefined) { return; } - console.log('w2l enqueueing'); + console.log("w2l enqueueing"); props.enqueueW2lJob(response.inference_job_token); }); - return false; }; - let object : string|undefined = undefined; - - if (w2lTemplate?.maybe_image_object_name !== undefined && w2lTemplate?.maybe_image_object_name !== null) { + let object: string | undefined = undefined; + + if ( + w2lTemplate?.maybe_image_object_name !== undefined && + w2lTemplate?.maybe_image_object_name !== null + ) { object = w2lTemplate!.maybe_image_object_name; - } else if (w2lTemplate?.maybe_video_object_name !== undefined && w2lTemplate?.maybe_video_object_name !== null) { + } else if ( + w2lTemplate?.maybe_video_object_name !== undefined && + w2lTemplate?.maybe_video_object_name !== null + ) { object = w2lTemplate!.maybe_video_object_name; } else { } let url = new BucketConfig().getGcsUrl(object); - let audioFilename = '(select a file)'; + let audioFilename = "(select a file)"; if (audioFile !== undefined) { audioFilename = audioFile?.name; } @@ -157,8 +174,15 @@ function W2lTemplateViewFc(props: Props) { case null: modApprovalStatus = ( - Not yet (ask for approval in our Discord) + Not yet (ask for approval in our  + + Discord + + ) ); break; @@ -172,34 +196,47 @@ function W2lTemplateViewFc(props: Props) { let moderatorRows = null; - if (props.sessionWrapper.canDeleteOtherUsersW2lResults() || props.sessionWrapper.canDeleteOtherUsersW2lTemplates()) { + if ( + props.sessionWrapper.canDeleteOtherUsersW2lResults() || + props.sessionWrapper.canDeleteOtherUsersW2lTemplates() + ) { moderatorRows = ( <> - -
-

Moderator Details

+ Creator is banned + + {w2lTemplate?.maybe_moderator_fields?.creator_is_banned + ? "banned" + : "good standing"} - - Creator is banned - {w2lTemplate?.maybe_moderator_fields?.creator_is_banned ? "banned" : "good standing" } - Create IP address - {w2lTemplate?.maybe_moderator_fields?.creator_ip_address_creation || "server error"} + + {w2lTemplate?.maybe_moderator_fields?.creator_ip_address_creation || + "server error"} + Update IP address - {w2lTemplate?.maybe_moderator_fields?.creator_ip_address_last_update || "server error"} + + {w2lTemplate?.maybe_moderator_fields + ?.creator_ip_address_last_update || "server error"} + Mod deleted at (UTC) - {w2lTemplate?.maybe_moderator_fields?.mod_deleted_at || "not deleted"} + + {w2lTemplate?.maybe_moderator_fields?.mod_deleted_at || + "not deleted"} + User deleted at (UTC) - {w2lTemplate?.maybe_moderator_fields?.user_deleted_at || "not deleted"} + + {w2lTemplate?.maybe_moderator_fields?.user_deleted_at || + "not deleted"} + ); @@ -208,21 +245,23 @@ function W2lTemplateViewFc(props: Props) { let creatorLink = ; if (!!w2lTemplate?.creator_display_name) { - const creatorUrl = FrontendUrlConfig.userProfilePage(w2lTemplate?.creator_username); + const creatorUrl = FrontendUrlConfig.userProfilePage( + w2lTemplate?.creator_username + ); creatorLink = ( + username={w2lTemplate.creator_display_name || ""} + email_hash={w2lTemplate.creator_gravatar_hash || ""} + />   {w2lTemplate.creator_display_name} ); } - let humanUseCount : string | number = 'Fetching...'; + let humanUseCount: string | number = "Fetching..."; if (w2lTemplateUseCount !== undefined && w2lTemplateUseCount !== null) { humanUseCount = w2lTemplateUseCount; @@ -230,14 +269,19 @@ function W2lTemplateViewFc(props: Props) { let editButton = ; - if (props.sessionWrapper.canEditTtsModelByUserToken(w2lTemplate?.creator_user_token)) { + if ( + props.sessionWrapper.canEditTtsModelByUserToken( + w2lTemplate?.creator_user_token + ) + ) { editButton = ( <> -
- Edit Template Details + > + Edit Template Details + ); } @@ -247,43 +291,53 @@ function W2lTemplateViewFc(props: Props) { if (props.sessionWrapper.canApproveW2lTemplates()) { const currentlyApproved = w2lTemplate?.is_public_listing_approved; - const approveButtonTitle = currentlyApproved? "Unapprove Template?" : "Approve Template?"; + const approveButtonTitle = currentlyApproved + ? "Unapprove Template?" + : "Approve Template?"; - const approveButtonCss = currentlyApproved? - "button is-danger is-light is-large is-fullwidth" : - "button is-info is-light is-large is-fullwidth"; + const approveButtonCss = currentlyApproved + ? "btn btn-primary w-100" + : "btn btn-primary w-100"; approveButton = ( <> -
- {approveButtonTitle} + > + {approveButtonTitle} + ); } let deleteButton = ; - if (props.sessionWrapper.canDeleteTtsModelByUserToken(w2lTemplate?.creator_user_token)) { + if ( + props.sessionWrapper.canDeleteTtsModelByUserToken( + w2lTemplate?.creator_user_token + ) + ) { + const currentlyDeleted = + !!w2lTemplate?.maybe_moderator_fields?.mod_deleted_at || + !!w2lTemplate?.maybe_moderator_fields?.user_deleted_at; - const currentlyDeleted = !!w2lTemplate?.maybe_moderator_fields?.mod_deleted_at || - !!w2lTemplate?.maybe_moderator_fields?.user_deleted_at; + const deleteButtonTitle = currentlyDeleted + ? "Undelete Template?" + : "Delete Template?"; - const deleteButtonTitle = currentlyDeleted ? "Undelete Template?" : "Delete Template?"; - - const deleteButtonCss = currentlyDeleted ? - "button is-warning is-large is-fullwidth" : - "button is-danger is-large is-fullwidth"; + const deleteButtonCss = currentlyDeleted + ? "btn btn-secondary w-100" + : "btn btn-destructive w-100"; deleteButton = ( <> -
- {deleteButtonTitle} + > + {deleteButtonTitle} + ); } @@ -293,154 +347,183 @@ function W2lTemplateViewFc(props: Props) { if (!!w2lTemplate?.description_rendered_html) { templateDescription = ( <> -

Model Description

-
+
+
+

Model Description

+
+
+
+
+
); } - const resultVisibility = w2lTemplate?.creator_set_visibility === 'hidden' ? - Hidden : - Public ; + const resultVisibility = + w2lTemplate?.creator_set_visibility === "hidden" ? ( + + Hidden + + ) : ( + + Public + + ); return (
-

Video lip sync template

- -
-

- -

-
- -
-

- Upload audio from FakeYou or any other source (eg. music), - then submit. You'll get a beautifully lipsynced video. -

+
+
+

Video Lip Sync Template

+

Template: (Template name)

+
+
+ +
- -
-
- +
+
+

Upload Audio

+
+
+
+

+ Upload audio from FakeYou or any other source (eg. music), + then submit. You'll get a beautifully lipsynced video. +

+
+ + handleAudioFileChange(e.target.files)} + /> +
+ +
+
+
+ template preview +
+
+
+
- - - -
- -
- template preview -
- -
- {templateDescription} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {moderatorRows} - - -
-

Template Details

-
Title{w2lTemplate?.title}
Creator - {creatorLink} -
Use count{humanUseCount}
Visibility{resultVisibility}
Is public listing approved?{modApprovalStatus}
-
-

Media Details

-
Media type{w2lTemplate?.template_type}
Dimensions{w2lTemplate?.frame_width} x {w2lTemplate?.frame_height}
Duration (milliseconds){w2lTemplate?.duration_millis}
Created at (UTC){w2lTemplate?.created_at}
Updated at (UTC){w2lTemplate?.updated_at}
- - {editButton} - - {approveButton} - - {deleteButton} - -
- - -
-

- -

+
+
+

Template Details

+
+ + + + + + + + + + + + + + + + + + + + + + + +
Title{w2lTemplate?.title}
Creator{creatorLink}
Use count{humanUseCount}
Visibility{resultVisibility}
Is public listing approved?{modApprovalStatus}
+
+
-
- +
+
+

Media Details

+
+ + + + + + + + + + + + + + + + + + + + + + + +
Media type{w2lTemplate?.template_type}
Dimensions + {w2lTemplate?.frame_width} x {w2lTemplate?.frame_height} +
Duration (milliseconds){w2lTemplate?.duration_millis}
Created at (UTC){w2lTemplate?.created_at}
Updated at (UTC){w2lTemplate?.updated_at}
+
+
+
+ +
+
+

Moderator Details

+
+ + {moderatorRows} +
+
+
+
+ +
+
+ {editButton} + {approveButton} + {deleteButton} +
+
+ +
+ +
+ +
- ) + ); } export { W2lTemplateViewFc }; From 788fea103655866a0754990d33530d0f33d5494c Mon Sep 17 00:00:00 2001 From: BFlat Date: Sat, 23 Jul 2022 13:36:00 +0100 Subject: [PATCH 2/6] update --- .../W2lTemplateApproveFc.tsx | 207 ++++++++++-------- .../w2l_template_edit/W2lTemplateEditFc.tsx | 193 ++++++++-------- .../w2l_template_view/W2lTemplateViewFc.tsx | 3 +- 3 files changed, 220 insertions(+), 183 deletions(-) diff --git a/packages/fakeyou/src/v2/view/w2l/w2l_template_approve/W2lTemplateApproveFc.tsx b/packages/fakeyou/src/v2/view/w2l/w2l_template_approve/W2lTemplateApproveFc.tsx index 01b73d9f74..bcb5c2f4b9 100644 --- a/packages/fakeyou/src/v2/view/w2l/w2l_template_approve/W2lTemplateApproveFc.tsx +++ b/packages/fakeyou/src/v2/view/w2l/w2l_template_approve/W2lTemplateApproveFc.tsx @@ -1,32 +1,42 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import { ApiConfig } from '@storyteller/components'; -import { FrontendUrlConfig } from '../../../../common/FrontendUrlConfig'; -import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper'; -import { useParams, Link, useHistory } from 'react-router-dom'; -import { GetW2lTemplate, GetW2lTemplateIsOk, W2lTemplate } from '../../../api/w2l/GetW2lTemplate'; -import { GetW2lTemplateUseCount } from '../../../api/w2l/GetW2lTemplateUseCount'; -import { BackLink } from '../../_common/BackLink'; +import React, { useState, useEffect, useCallback } from "react"; +import { ApiConfig } from "@storyteller/components"; +import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig"; +import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper"; +import { useParams, Link, useHistory } from "react-router-dom"; +import { + GetW2lTemplate, + GetW2lTemplateIsOk, + W2lTemplate, +} from "../../../api/w2l/GetW2lTemplate"; +import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount"; +import { BackLink } from "../../_common/BackLink"; const DEFAULT_APPROVED_STATE = true; interface Props { - sessionWrapper: SessionWrapper, + sessionWrapper: SessionWrapper; } function W2lTemplateApproveFc(props: Props) { const history = useHistory(); - let { templateToken } : { templateToken : string } = useParams(); + let { templateToken }: { templateToken: string } = useParams(); - const [w2lTemplate, setW2lTemplate] = useState(undefined); - const [w2lTemplateUseCount, setW2lTemplateUseCount] = useState(undefined); - const [approvedState, setApprovedState] = useState(DEFAULT_APPROVED_STATE); + const [w2lTemplate, setW2lTemplate] = useState( + undefined + ); + const [w2lTemplateUseCount, setW2lTemplateUseCount] = useState< + number | undefined + >(undefined); + const [approvedState, setApprovedState] = useState( + DEFAULT_APPROVED_STATE + ); const getTemplate = useCallback(async (templateToken) => { const template = await GetW2lTemplate(templateToken); if (GetW2lTemplateIsOk(template)) { - setW2lTemplate(template) + setW2lTemplate(template); const currentlyApproved = template?.is_public_listing_approved; setApprovedState(currentlyApproved); } @@ -34,7 +44,7 @@ function W2lTemplateApproveFc(props: Props) { const getTemplateUseCount = useCallback(async (templateToken) => { const count = await GetW2lTemplateUseCount(templateToken); - setW2lTemplateUseCount(count || 0) + setW2lTemplateUseCount(count || 0); }, []); const templateLink = FrontendUrlConfig.w2lTemplatePage(templateToken); @@ -44,45 +54,48 @@ function W2lTemplateApproveFc(props: Props) { getTemplateUseCount(templateToken); }, [templateToken, getTemplate, getTemplateUseCount]); - const handleModApprovalChange= (ev: React.FormEvent) => { + const handleModApprovalChange = (ev: React.FormEvent) => { const value = (ev.target as HTMLSelectElement).value; const updatedValue = value === "true" ? true : false; - setApprovedState(updatedValue) + setApprovedState(updatedValue); }; - const handleApproveFormSubmit = (ev: React.FormEvent) : boolean => { + const handleApproveFormSubmit = ( + ev: React.FormEvent + ): boolean => { ev.preventDefault(); const endpointUri = new ApiConfig().moderateW2l(templateToken); const request = { is_approved: approvedState || false, - } + }; fetch(endpointUri, { - method: 'POST', + method: "POST", headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', + Accept: "application/json", + "Content-Type": "application/json", }, - credentials: 'include', + credentials: "include", body: JSON.stringify(request), }) - .then(res => res.json()) - .then(res => { - if (res.success) { - history.push(templateLink); - } - }) - .catch(e => { - }); + .then((res) => res.json()) + .then((res) => { + if (res.success) { + history.push(templateLink); + } + }) + .catch((e) => {}); return false; - } + }; let creatorLink = ; if (!!w2lTemplate?.creator_display_name) { - const creatorUrl = FrontendUrlConfig.userProfilePage(w2lTemplate?.creator_display_name); + const creatorUrl = FrontendUrlConfig.userProfilePage( + w2lTemplate?.creator_display_name + ); creatorLink = ( {w2lTemplate?.creator_display_name} ); @@ -90,9 +103,11 @@ function W2lTemplateApproveFc(props: Props) { const currentlyApproved = w2lTemplate?.is_public_listing_approved; - const h1Title = currentlyApproved ? "Unapprove Template?" : "Approve Template?"; + const h1Title = currentlyApproved + ? "Unapprove Template?" + : "Approve Template?"; - let humanUseCount : string | number = 'Fetching...'; + let humanUseCount: string | number = "Fetching..."; const approvedFormDefaultState = approvedState ? "true" : "false"; @@ -101,73 +116,79 @@ function W2lTemplateApproveFc(props: Props) { } return ( -
-

{h1Title}

- -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - +
+
+
+

{h1Title}

+
+
+ +
+
-
-
DetailValue
Creator - {creatorLink} -
Use Count{humanUseCount}
Title{w2lTemplate?.title}
Upload Date (UTC){w2lTemplate?.created_at}
- -
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Detail + + Value +
Creator{creatorLink}
Use Count{humanUseCount}
Title{w2lTemplate?.title}
Upload Date (UTC){w2lTemplate?.created_at}
+
+
- +
+
+ -
-
- -
- +
+
+ +
- -

- -

- +
+
+
- -
-
-
- ) + ); } export { W2lTemplateApproveFc }; diff --git a/packages/fakeyou/src/v2/view/w2l/w2l_template_edit/W2lTemplateEditFc.tsx b/packages/fakeyou/src/v2/view/w2l/w2l_template_edit/W2lTemplateEditFc.tsx index 31bf6c806a..baea661ab6 100644 --- a/packages/fakeyou/src/v2/view/w2l/w2l_template_edit/W2lTemplateEditFc.tsx +++ b/packages/fakeyou/src/v2/view/w2l/w2l_template_edit/W2lTemplateEditFc.tsx @@ -1,25 +1,31 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import { ApiConfig } from '@storyteller/components'; -import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper'; -import { useParams, useHistory } from 'react-router-dom'; -import { FrontendUrlConfig } from '../../../../common/FrontendUrlConfig'; -import { VisibleIconFc } from '../../_icons/VisibleIcon'; -import { HiddenIconFc } from '../../_icons/HiddenIcon'; -import { GetW2lTemplate, GetW2lTemplateIsOk, W2lTemplate } from '../../../api/w2l/GetW2lTemplate'; -import { BackLink } from '../../_common/BackLink'; +import React, { useState, useEffect, useCallback } from "react"; +import { ApiConfig } from "@storyteller/components"; +import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper"; +import { useParams, useHistory } from "react-router-dom"; +import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig"; +import { VisibleIconFc } from "../../_icons/VisibleIcon"; +import { HiddenIconFc } from "../../_icons/HiddenIcon"; +import { + GetW2lTemplate, + GetW2lTemplateIsOk, + W2lTemplate, +} from "../../../api/w2l/GetW2lTemplate"; +import { BackLink } from "../../_common/BackLink"; -const DEFAULT_VISIBILITY = 'public'; +const DEFAULT_VISIBILITY = "public"; interface Props { - sessionWrapper: SessionWrapper, + sessionWrapper: SessionWrapper; } function W2lTemplateEditFc(props: Props) { - let { templateToken } : { templateToken : string } = useParams(); + let { templateToken }: { templateToken: string } = useParams(); const history = useHistory(); - const [w2lTemplate, setW2lTemplate] = useState(undefined); + const [w2lTemplate, setW2lTemplate] = useState( + undefined + ); const [title, setTitle] = useState(""); const [descriptionMarkdown, setDescriptionMarkdown] = useState(""); const [visibility, setVisibility] = useState(DEFAULT_VISIBILITY); @@ -28,27 +34,27 @@ function W2lTemplateEditFc(props: Props) { const template = await GetW2lTemplate(token); if (GetW2lTemplateIsOk(template)) { - setTitle(template.title || "") - setDescriptionMarkdown(template.description_markdown || "") + setTitle(template.title || ""); + setDescriptionMarkdown(template.description_markdown || ""); setVisibility(template.creator_set_visibility || DEFAULT_VISIBILITY); - setW2lTemplate(template) + setW2lTemplate(template); } - }, []); - useEffect(() => { getTemplate(templateToken); }, [templateToken, getTemplate]); - const handleTitleChange = (ev: React.FormEvent) => { + const handleTitleChange = (ev: React.FormEvent) => { ev.preventDefault(); const textValue = (ev.target as HTMLInputElement).value; setTitle(textValue); return false; }; - const handleDescriptionMarkdownChange = (ev: React.FormEvent) => { + const handleDescriptionMarkdownChange = ( + ev: React.FormEvent + ) => { ev.preventDefault(); const textValue = (ev.target as HTMLTextAreaElement).value; setDescriptionMarkdown(textValue); @@ -56,12 +62,12 @@ function W2lTemplateEditFc(props: Props) { }; const handleVisibilityChange = (ev: React.FormEvent) => { - setVisibility((ev.target as HTMLSelectElement).value) + setVisibility((ev.target as HTMLSelectElement).value); }; const templateLink = FrontendUrlConfig.w2lTemplatePage(templateToken); - const handleFormSubmit = (ev: React.FormEvent) => { + const handleFormSubmit = (ev: React.FormEvent) => { ev.preventDefault(); if (w2lTemplate === undefined) { @@ -75,103 +81,114 @@ function W2lTemplateEditFc(props: Props) { const templateToken = w2lTemplate!.template_token; const endpointUrl = new ApiConfig().editW2lTemplate(templateToken); - + const request = { title: title, description_markdown: descriptionMarkdown, creator_set_visibility: visibility || DEFAULT_VISIBILITY, - } + }; fetch(endpointUrl, { - method: 'POST', + method: "POST", headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', + Accept: "application/json", + "Content-Type": "application/json", }, - credentials: 'include', + credentials: "include", body: JSON.stringify(request), }) - .then(res => res.json()) - .then(res => { - if (res === undefined || - !res.success) { - return; // Endpoint error? - } + .then((res) => res.json()) + .then((res) => { + if (res === undefined || !res.success) { + return; // Endpoint error? + } - history.push(templateLink); - }) - .catch(e => { - }); + history.push(templateLink); + }) + .catch((e) => {}); return false; }; let isDisabled = w2lTemplate === undefined; - const visibilityIcon = (visibility === 'public') ? : ; + const visibilityIcon = + visibility === "public" ? : ; return ( -
-

Edit Template

- -

- -

+
+
+
+

Edit Template

+
+
+ +
+
+
+
+
+
+ +
+ +
+ {/*

{invalidReason}

*/} +
-
- -
- -
- {/*

{invalidReason}

*/} -
+
+ +
+