media page weight used data binding

This commit is contained in:
BFlat committed 2023-12-29 11:31:11 +07:00
1 parent c3dab52908
commit ee0df1c59a
7 files changed
+183 -55

No files matched your search

@@ -1,6 +1,6 @@
export enum MediaFileType {
Audio = "audio",
Video = "video",
Image = "image",
None = "none",
}
@@ -1,15 +1,25 @@
import { ApiConfig } from "../ApiConfig";
import { UserDetailsLight } from "../_common/UserDetailsLight";
import { MediaFileType } from "../_common/enums/MediaFileType";
import { WeightCategory } from "../_common/enums/WeightCategory";
import { WeightType } from "../_common/enums/WeightType";
// import { Weight } from "../weights/GetWeight";
export interface MediaFile {
token: string,
media_type: MediaFileType,
public_bucket_path: string,
maybe_creator_user: UserDetailsLight | null,
creator_set_visibility: string,
created_at: Date,
updated_at: Date,
token: string;
media_type: MediaFileType;
public_bucket_path: string;
maybe_creator_user?: UserDetailsLight | null;
creator_set_visibility: string;
created_at: Date;
updated_at: Date;
maybe_model_weight_info?: {
title: string;
weight_token: string;
weight_category: WeightCategory;
weight_type: WeightType;
maybe_weight_creator: UserDetailsLight;
};
}
export enum MediaFileLookupError {
@@ -19,34 +29,40 @@ export enum MediaFileLookupError {
}
export interface GetMediaFileResponse {
success: boolean,
media_file?: MediaFile,
success: boolean;
media_file?: MediaFile;
}
export async function GetMediaFile(mediaFileToken: string) : Promise<GetMediaFileResponse> {
export async function GetMediaFile(
mediaFileToken: string
): Promise<GetMediaFileResponse> {
const endpoint = new ApiConfig().getMediaFile(mediaFileToken);
return await fetch(endpoint, {
method: 'GET',
headers: {
'Accept': 'application/json',
},
credentials: 'include',
})
.then(res => res.json())
.then(res => {
const response : GetMediaFileResponse = res;
if (response && response.success && response.media_file) {
// NB: Timestamps aren't converted to Date objects on their own!
response.media_file.created_at = new Date(response.media_file.created_at);
response.media_file.updated_at = new Date(response.media_file.updated_at);
return response;
} else {
return { success : false };
}
return await fetch(endpoint, {
method: "GET",
headers: {
Accept: "application/json",
},
credentials: "include",
})
.catch(e => {
return { success : false };
});
.then(res => res.json())
.then(res => {
const response: GetMediaFileResponse = res;
if (response && response.success && response.media_file) {
// NB: Timestamps aren't converted to Date objects on their own!
response.media_file.created_at = new Date(
response.media_file.created_at
);
response.media_file.updated_at = new Date(
response.media_file.updated_at
);
return response;
} else {
return { success: false };
}
})
.catch(e => {
return { success: false };
});
}
@@ -26,7 +26,7 @@ export default function ShareButton(props: ShareButtonProps) {
<div className="d-flex">
<Tippy
content={tippyContent}
hideOnClick={false}
hideOnClick={true}
placement="bottom"
theme="fakeyou"
arrow={false}
@@ -0,0 +1 @@
export { default } from "./useMediaFileTypeInfo";
@@ -0,0 +1,33 @@
import { MediaFileType } from "@storyteller/components/src/api/_common/enums/MediaFileType";
type MediaFileTypeInfo = {
[key in MediaFileType]: { label: string; color: string };
};
const mediaFileTypeInfo: MediaFileTypeInfo = {
[MediaFileType.Audio]: {
label: "Audio",
color: "teal",
},
[MediaFileType.Image]: {
label: "Image",
color: "ultramarine",
},
[MediaFileType.Video]: {
label: "Video",
color: "purple",
},
[MediaFileType.None]: {
label: "None",
color: "gray",
},
};
export default function useMediaFileTypeInfo(mediaFileType: MediaFileType) {
return (
mediaFileTypeInfo[mediaFileType] || {
label: "None",
color: "gray",
}
);
}
@@ -0,0 +1 @@
export { default } from "./useWeightTypeInfo";
@@ -18,8 +18,6 @@ import {
faCircleExclamation,
faFaceViewfinder,
faArrowDownToLine,
// faCirclePlay,
// faShare,
faSquareQuote,
faShare,
faLink,
@@ -35,6 +33,10 @@ import WeightCoverImage from "components/common/WeightCoverImage";
import SocialButton from "components/common/SocialButton";
import Modal from "components/common/Modal";
import { Input } from "components/common";
import LikeButton from "components/common/LikeButton";
import Badge from "components/common/Badge";
import useMediaFileTypeInfo from "hooks/useMediaFileTypeInfo";
import { useBookmarks } from "hooks";
interface MediaPageProps {
sessionWrapper: SessionWrapper;
@@ -67,6 +69,8 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) {
getMediaFile(token);
}, [token, getMediaFile]);
const bookmarks = useBookmarks();
function renderMediaComponent(mediaFile: MediaFile) {
switch (mediaFile.media_type) {
case MediaFileType.Audio:
@@ -113,6 +117,11 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) {
}
}
const weightTypeInfo = useMediaFileTypeInfo(
mediaFile?.media_type || MediaFileType.None
);
const { label: mediaType, color: mediaTagColor } = weightTypeInfo;
let audioLink = new BucketConfig().getGcsUrl(mediaFile?.public_bucket_path);
const shareUrl = `https://fakeyou.com/media/${mediaFile?.token || ""}`;
@@ -286,9 +295,61 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) {
setTimeout(() => setButtonLabel("Copy"), 1000);
};
const subtitleDivider = <span className="opacity-25 fs-5 fw-light">|</span>;
return (
<div>
<Container type="panel" className="pt-4 pt-lg-5">
<Container type="panel" className="mb-5">
<Panel clear={true} className="py-4">
<div className="d-flex flex-column flex-lg-row gap-3 gap-lg-2">
<div>
<div className="d-flex gap-2 align-items-center flex-wrap">
<h1 className="fw-bold mb-2">
{mediaFile.maybe_model_weight_info?.title ||
`Media ${mediaType}`}
</h1>
</div>
<div className="d-flex gap-3 flex-wrap align-items-center">
<div className="d-flex gap-2 align-items-center flex-wrap">
<div>
<Badge label={mediaType} color={mediaTagColor} />
</div>
{subtitleDivider}
{mediaFile.maybe_model_weight_info && (
<>
<p>
{mediaFile.maybe_model_weight_info?.weight_category}
</p>
{subtitleDivider}
</>
)}
<div className="d-flex align-items-center gap-2">
<LikeButton
{...{
entityToken: token,
entityType: "media_file",
likeCount: 1200,
onToggle: bookmarks.toggle,
large: true,
}}
/>
{/* <BookmarkButton
{...{
entityToken: weight_token,
entityType: "model_weight",
onToggle: bookmarks.toggle,
large: true,
}}
/> */}
</div>
</div>
</div>
</div>
</div>
</Panel>
<div className="row g-4">
<div className="col-12 col-xl-8">
<div className="media-wrapper">
@@ -374,30 +435,46 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) {
<p className="fw-medium text-white">Anonymous</p>
)}
<p className="fs-7">Created: {timeCreated}</p>
<p className="fs-7">Created {timeCreated}</p>
</div>
</div>
</Panel>
<Panel className="rounded">
<div className="d-flex flex-column gap-2 p-3">
<h6 className="fw-medium mb-0">Weight Used</h6>
<hr className="my-1" />
<div className="d-flex align-items-center">
<WeightCoverImage
src="/images/dummy-image.jpg"
height={60}
width={60}
/>
<div className="d-flex flex-column">
<Link to="/">
<h6 className="mb-1">Weight Name</h6>
</Link>
<p className="fs-7">by hanashi</p>
{mediaFile.maybe_model_weight_info && (
<Panel className="rounded">
<div className="d-flex flex-column gap-2 p-3">
<h6 className="fw-medium mb-0">Weight Used</h6>
<hr className="my-1" />
<div className="d-flex align-items-center">
<WeightCoverImage
src="/images/dummy-image.jpg"
height={60}
width={60}
/>
<div className="d-flex flex-column">
<Link
to={`/weight/${mediaFile.maybe_model_weight_info.weight_token}`}
>
<h6 className="mb-1">
{mediaFile.maybe_model_weight_info.title}
</h6>
</Link>
<p className="fs-7">
by{" "}
<Link
to={`/profile/${mediaFile.maybe_model_weight_info.maybe_weight_creator.username}`}
>
{
mediaFile.maybe_model_weight_info
.maybe_weight_creator.display_name
}
</Link>
</p>
</div>
</div>
</div>
</div>
</Panel>
</Panel>
)}
<Accordion>
<Accordion.Item title="Media Details" defaultOpen={true}>