mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 01:38:44 +00:00
Merge branch 'feature/mvp' of https://github.com/storytold/storyteller-frontend into feature/mvp
This commit is contained in:
commit
0ecf276742
20 files changed
+477
-186
No files matched your search
@@ -30,7 +30,7 @@ class BucketConfig {
|
||||
const basePath = this.isLocalDev
|
||||
? "https://dev-cdn.fakeyou.com"
|
||||
: "https://cdn.fakeyou.com";
|
||||
let path = bucketRelativePath.startsWith("/")
|
||||
let path = bucketRelativePath?.startsWith("/")
|
||||
? bucketRelativePath
|
||||
: "/" + bucketRelativePath;
|
||||
let resizeParams = "";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
export enum MediaFileType {
|
||||
Audio = "audio",
|
||||
Video = "video",
|
||||
Image = "image",
|
||||
None = "none",
|
||||
}
|
||||
@@ -1,19 +1,25 @@
|
||||
import MakeRequest from "../MakeRequest";
|
||||
import { Pagination } from "../_common/SharedFetchTypes";
|
||||
import { Weight } from "../weights/GetWeight";
|
||||
|
||||
export interface UserBookmarksListRequest {}
|
||||
|
||||
export interface UserBookmarksListResponse {
|
||||
// pagination: Pagination,
|
||||
success: boolean,
|
||||
// weights: any
|
||||
success: boolean;
|
||||
results: Weight[];
|
||||
}
|
||||
|
||||
export interface UserBookmarksListQueries {
|
||||
page_index: number,
|
||||
page_index: number;
|
||||
}
|
||||
|
||||
export const GetBookmarksByUser = MakeRequest<string, UserBookmarksListRequest, UserBookmarksListResponse, UserBookmarksListQueries>({
|
||||
export const GetBookmarksByUser = MakeRequest<
|
||||
string,
|
||||
UserBookmarksListRequest,
|
||||
UserBookmarksListResponse,
|
||||
UserBookmarksListQueries
|
||||
>({
|
||||
method: "GET",
|
||||
routingFunction: (userToken: string) => `/v1/user_bookmarks/list/user/${userToken}`,
|
||||
});
|
||||
routingFunction: (userToken: string) =>
|
||||
`/v1/user_bookmarks/list/user/${userToken}`,
|
||||
});
|
||||
@@ -1,15 +1,26 @@
|
||||
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;
|
||||
maybe_cover_image_public_bucket_path: string;
|
||||
};
|
||||
}
|
||||
|
||||
export enum MediaFileLookupError {
|
||||
@@ -19,34 +30,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 };
|
||||
});
|
||||
}
|
||||
@@ -5,8 +5,8 @@ import { WeightType } from "../_common/enums/WeightType";
|
||||
|
||||
export interface Weight {
|
||||
weight_token: string;
|
||||
weights_type: WeightType;
|
||||
weights_category: WeightCategory;
|
||||
weight_type: WeightType;
|
||||
weight_category: WeightCategory;
|
||||
title: string;
|
||||
public_bucket_path: string;
|
||||
creator_set_visibility: string;
|
||||
|
||||
@@ -11,6 +11,7 @@ import { faArrowRight } from "@fortawesome/pro-solid-svg-icons";
|
||||
import Button from "components/common/Button";
|
||||
import useWeightTypeInfo from "hooks/useWeightTypeInfo/useWeightTypeInfo";
|
||||
import WeightCoverImage from "components/common/WeightCoverImage";
|
||||
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
|
||||
|
||||
interface AudioCardProps {
|
||||
bookmarks: any;
|
||||
@@ -30,7 +31,11 @@ export default function AudioCard({
|
||||
showCover,
|
||||
}: AudioCardProps) {
|
||||
const linkUrl =
|
||||
type === "media" ? `/media/${data.token}` : `/weight/${data.weight_token}${origin ? "?origin=" + origin + "&ehhh=mehh" : "" }`;
|
||||
type === "media"
|
||||
? `/media/${data.token}`
|
||||
: `/weight/${data.weight_token || data.details.entity_token}${
|
||||
origin ? "?origin=" + origin + "&ehhh=mehh" : ""
|
||||
}`;
|
||||
|
||||
const handleInnerClick = (event: any) => {
|
||||
event.stopPropagation();
|
||||
@@ -44,10 +49,40 @@ export default function AudioCard({
|
||||
};
|
||||
|
||||
const { label: weightBadgeLabel, color: weightBadgeColor } =
|
||||
useWeightTypeInfo(data.weights_type);
|
||||
useWeightTypeInfo(
|
||||
data.weight_type || data.details?.maybe_weight_data?.weight_type
|
||||
);
|
||||
|
||||
const bucketConfig = new BucketConfig();
|
||||
let coverImage = "/images/avatars/default-pfp.png";
|
||||
|
||||
if (type === "media") {
|
||||
coverImage = bucketConfig.getCdnUrl(data.public_bucket_path, 400, 100);
|
||||
} else if (type === "weights") {
|
||||
if (data.maybe_cover_image_public_bucket_path) {
|
||||
coverImage = bucketConfig.getCdnUrl(
|
||||
data.maybe_cover_image_public_bucket_path,
|
||||
100,
|
||||
100
|
||||
);
|
||||
}
|
||||
if (data.details?.maybe_weight_data?.maybe_cover_image_public_bucket_path) {
|
||||
coverImage = bucketConfig.getCdnUrl(
|
||||
data.details?.maybe_weight_data?.maybe_cover_image_public_bucket_path,
|
||||
100,
|
||||
100
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Link {...{ to: linkUrl, state: { origin }, onClick: () => console.log("🌠 AUDIO CARD") }}>
|
||||
<Link
|
||||
{...{
|
||||
to: linkUrl,
|
||||
state: { origin },
|
||||
onClick: () => console.log("🌠 AUDIO CARD"),
|
||||
}}
|
||||
>
|
||||
<Card padding={true} canHover={true}>
|
||||
{type === "media" && (
|
||||
<>
|
||||
@@ -100,9 +135,7 @@ export default function AudioCard({
|
||||
{type === "weights" && (
|
||||
<>
|
||||
<div className="d-flex">
|
||||
{showCover && (
|
||||
<WeightCoverImage src="/images/avatars/default-pfp.png" />
|
||||
)}
|
||||
{showCover && <WeightCoverImage src={coverImage} />}
|
||||
|
||||
<div className="flex-grow-1">
|
||||
<div className="d-flex align-items-center">
|
||||
@@ -122,7 +155,7 @@ export default function AudioCard({
|
||||
<div className="d-flex align-items-center mt-3">
|
||||
<div className="flex-grow-1">
|
||||
<h6 className="fw-semibold text-white mb-1">
|
||||
{data.title}
|
||||
{data.title || data.details.maybe_weight_data.title}
|
||||
</h6>
|
||||
<p className="fs-7 opacity-75">{timeAgo}</p>
|
||||
</div>
|
||||
@@ -153,12 +186,13 @@ export default function AudioCard({
|
||||
<div>
|
||||
<LikeButton onToggle={handleLike} likeCount={data.likes} />
|
||||
</div>
|
||||
<BookmarkButton {...{
|
||||
entityToken: data.weight_token,
|
||||
entityType: "model_weight",
|
||||
onToggle: bookmarks.toggle,
|
||||
large: true,
|
||||
}} />
|
||||
<BookmarkButton
|
||||
{...{
|
||||
entityToken: data.weight_token,
|
||||
entityType: "model_weight",
|
||||
onToggle: bookmarks.toggle,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -12,16 +12,26 @@ import useWeightTypeInfo from "hooks/useWeightTypeInfo/useWeightTypeInfo";
|
||||
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
|
||||
|
||||
interface ImageCardProps {
|
||||
bookmarks: any,
|
||||
bookmarks: any;
|
||||
data: any;
|
||||
origin?: string;
|
||||
type: "media" | "weights";
|
||||
showCreator?: boolean;
|
||||
}
|
||||
|
||||
export default function ImageCard({ bookmarks, data, origin = "", type, showCreator }: ImageCardProps) {
|
||||
export default function ImageCard({
|
||||
bookmarks,
|
||||
data,
|
||||
origin = "",
|
||||
type,
|
||||
showCreator,
|
||||
}: ImageCardProps) {
|
||||
const linkUrl =
|
||||
type === "media" ? `/media/${data.token}` : `/weight/${data.weight_token}`;
|
||||
type === "media"
|
||||
? `/media/${data.token}`
|
||||
: `/weight/${data.weight_token || data.details.entity_token}${
|
||||
origin ? "?origin=" + origin + "&ehhh=mehh" : ""
|
||||
}`;
|
||||
|
||||
const handleInnerClick = (event: any) => {
|
||||
event.stopPropagation();
|
||||
@@ -35,18 +45,46 @@ export default function ImageCard({ bookmarks, data, origin = "", type, showCrea
|
||||
};
|
||||
|
||||
const { label: weightBadgeLabel, color: weightBadgeColor } =
|
||||
useWeightTypeInfo(data.weights_type);
|
||||
|
||||
const imageLink = new BucketConfig().getGcsUrl(data.public_bucket_path);
|
||||
useWeightTypeInfo(
|
||||
data.weight_type || data.details?.maybe_weight_data?.weight_type
|
||||
);
|
||||
|
||||
console.log("🌇", origin);
|
||||
|
||||
const bucketConfig = new BucketConfig();
|
||||
let coverImage = "/images/avatars/default-pfp.png";
|
||||
|
||||
if (type === "media") {
|
||||
coverImage = bucketConfig.getCdnUrl(data.public_bucket_path, 400, 100);
|
||||
} else if (type === "weights") {
|
||||
if (data.maybe_cover_image_public_bucket_path) {
|
||||
coverImage = bucketConfig.getCdnUrl(
|
||||
data.maybe_cover_image_public_bucket_path,
|
||||
400,
|
||||
100
|
||||
);
|
||||
}
|
||||
if (data.details?.maybe_weight_data?.maybe_cover_image_public_bucket_path) {
|
||||
coverImage = bucketConfig.getCdnUrl(
|
||||
data.details?.maybe_weight_data?.maybe_cover_image_public_bucket_path,
|
||||
400,
|
||||
100
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Link {...{ to: linkUrl, state: { origin }, onClick: () => console.log("🌠 IMG CARD") }}>
|
||||
<Link
|
||||
{...{
|
||||
to: linkUrl,
|
||||
state: { origin },
|
||||
onClick: () => console.log("🌠 IMG CARD"),
|
||||
}}
|
||||
>
|
||||
<Card padding={false} canHover={true}>
|
||||
{type === "media" && (
|
||||
<>
|
||||
<img src={imageLink} alt={data.weight_name} className="card-img" />
|
||||
<img src={coverImage} alt={data.weight_name} className="card-img" />
|
||||
<div className="card-img-overlay">
|
||||
<div className="card-img-gradient" />
|
||||
|
||||
@@ -96,14 +134,7 @@ export default function ImageCard({ bookmarks, data, origin = "", type, showCrea
|
||||
|
||||
{type === "weights" && (
|
||||
<>
|
||||
<img
|
||||
src={
|
||||
data.maybe_cover_image_public_bucket_path ||
|
||||
"/images/avatars/default-pfp.png"
|
||||
}
|
||||
alt={data.title}
|
||||
className="card-img"
|
||||
/>
|
||||
<img src={coverImage} alt={data.title} className="card-img" />
|
||||
<div className="card-img-overlay">
|
||||
<div className="card-img-gradient" />
|
||||
<div className="d-flex align-items-center">
|
||||
@@ -128,7 +159,7 @@ export default function ImageCard({ bookmarks, data, origin = "", type, showCrea
|
||||
<div className="d-flex align-items-center mt-3">
|
||||
<div className="flex-grow-1">
|
||||
<h6 className="fw-semibold text-white mb-1">
|
||||
{data.title}
|
||||
{data.title || data.details?.maybe_weight_data?.title}
|
||||
</h6>
|
||||
<p className="fs-7 opacity-75 mb-0">{timeAgo}</p>
|
||||
</div>
|
||||
@@ -159,11 +190,13 @@ export default function ImageCard({ bookmarks, data, origin = "", type, showCrea
|
||||
<div>
|
||||
<LikeButton onToggle={handleLike} likeCount={data.likes} />
|
||||
</div>
|
||||
<BookmarkButton {...{
|
||||
entityToken: data.weight_token,
|
||||
entityType: "model_weight",
|
||||
onToggle: bookmarks.toggle,
|
||||
}}/>
|
||||
<BookmarkButton
|
||||
{...{
|
||||
entityToken: data.weight_token,
|
||||
entityType: "model_weight",
|
||||
onToggle: bookmarks.toggle,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useEffect, useState } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { FetchStatus } from "@storyteller/components/src/api/_common/SharedFetchTypes";
|
||||
import { GetWeight, Weight } from "@storyteller/components/src/api/weights/GetWeight";
|
||||
import {
|
||||
GetWeight,
|
||||
Weight,
|
||||
} from "@storyteller/components/src/api/weights/GetWeight";
|
||||
import { UpdateWeight } from "@storyteller/components/src/api/weights/UpdateWeight";
|
||||
import { DeleteWeight } from "@storyteller/components/src/api/weights/DeleteWeight";
|
||||
import { UploadMedia, UploadMediaResponse } from "@storyteller/components/src/api/media_files/UploadMedia";
|
||||
@@ -28,7 +31,11 @@ export default function useWeightFetch({ onRemove = () => {}, token }: Props) {
|
||||
const history = useHistory();
|
||||
|
||||
const onChange = ({ target }: { target: { name: string; value: any } }) => {
|
||||
const todo: { [key: string]: (x: any) => void } = { descriptionMDSet, titleSet, visibilitySet };
|
||||
const todo: { [key: string]: (x: any) => void } = {
|
||||
descriptionMDSet,
|
||||
titleSet,
|
||||
visibilitySet,
|
||||
};
|
||||
todo[target.name + "Set"](target.value);
|
||||
};
|
||||
|
||||
@@ -40,35 +47,30 @@ export default function useWeightFetch({ onRemove = () => {}, token }: Props) {
|
||||
description_rendered_html: data?.description_rendered_html || "",
|
||||
title,
|
||||
visibility,
|
||||
weight_category: data?.weights_category || "",
|
||||
weight_type: data?.weights_type || ""
|
||||
weight_category: data?.weight_category || "",
|
||||
weight_type: data?.weight_type || "",
|
||||
})
|
||||
.then((res: any) => {
|
||||
console.log("📝",res);
|
||||
writeStatusSet(FetchStatus.success);
|
||||
history.replace(`/weight/${ token }`);
|
||||
})
|
||||
.catch(err => {
|
||||
writeStatusSet(FetchStatus.error);
|
||||
});
|
||||
.then((res: any) => {
|
||||
writeStatusSet(FetchStatus.success);
|
||||
history.replace(`/weight/${token}`);
|
||||
})
|
||||
.catch(err => {
|
||||
writeStatusSet(FetchStatus.error);
|
||||
});
|
||||
};
|
||||
|
||||
const remove = () => {
|
||||
writeStatusSet(FetchStatus.in_progress);
|
||||
DeleteWeight(token,{
|
||||
DeleteWeight(token, {
|
||||
as_mod: true,
|
||||
set_delete: true
|
||||
})
|
||||
.then((res: any) => {
|
||||
set_delete: true,
|
||||
}).then((res: any) => {
|
||||
writeStatusSet(FetchStatus.success);
|
||||
console.log("✂️",res);
|
||||
onRemove(res);
|
||||
});
|
||||
};
|
||||
|
||||
const uploadCoverImg = (e: any) => {
|
||||
console.log("🧲",!!imageProps.file, imgUploadStatus);
|
||||
// e.stopPropigation();
|
||||
if (imageProps.file && imgUploadStatus < 2) {
|
||||
imgUploadStatusSet(FetchStatus.in_progress);
|
||||
UploadMedia({
|
||||
@@ -89,20 +91,23 @@ export default function useWeightFetch({ onRemove = () => {}, token }: Props) {
|
||||
if (token && !data && status === FetchStatus.ready) {
|
||||
statusSet(FetchStatus.in_progress);
|
||||
GetWeight(token, {})
|
||||
.then((res: any) => {
|
||||
let { creator_set_visibility, description_markdown, title: resTitle, ...response } = res;
|
||||
console.log("🏋️", res, status);
|
||||
statusSet(FetchStatus.success);
|
||||
titleSet(resTitle);
|
||||
descriptionMDSet(description_markdown);
|
||||
visibilitySet(creator_set_visibility);
|
||||
setData(response);
|
||||
})
|
||||
.catch(err => {
|
||||
statusSet(FetchStatus.error);
|
||||
});
|
||||
.then((res: any) => {
|
||||
let {
|
||||
creator_set_visibility,
|
||||
description_markdown,
|
||||
title: resTitle,
|
||||
} = res;
|
||||
statusSet(FetchStatus.success);
|
||||
titleSet(resTitle);
|
||||
descriptionMDSet(description_markdown);
|
||||
visibilitySet(creator_set_visibility);
|
||||
setData(res);
|
||||
})
|
||||
.catch(err => {
|
||||
statusSet(FetchStatus.error);
|
||||
});
|
||||
}
|
||||
}, [status, token, data]);
|
||||
|
||||
return { data, fetchError, imgMediaFile, imgMediaFileSet, imageProps, imgUploadStatus, isLoading, descriptionMD, onChange, remove, status, title, update, uploadCoverImg, visibility, writeStatus };
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./useWeightTypeInfo";
|
||||
@@ -9,6 +9,8 @@ import { MediaFile } from "@storyteller/components/src/api/media_files/GetMedia"
|
||||
import { useBookmarks, useLazyLists } from "hooks";
|
||||
import { ListFeaturedMediaFiles } from "@storyteller/components/src/api/media_files/ListFeaturedMediaFiles";
|
||||
import SkeletonCard from "components/common/Card/SkeletonCard";
|
||||
import ImageCard from "components/common/Card/ImageCard";
|
||||
import VideoCard from "components/common/Card/VideoCard";
|
||||
|
||||
export default function FeaturedTab() {
|
||||
const bookmarks = useBookmarks();
|
||||
@@ -23,7 +25,7 @@ export default function FeaturedTab() {
|
||||
onInputChange: () => setShowMasonryGrid(false),
|
||||
onSuccess: () => setShowMasonryGrid(true),
|
||||
requestList: true,
|
||||
addQueries: { page_size: 12 },
|
||||
debug: "featured media",
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -55,22 +57,52 @@ export default function FeaturedTab() {
|
||||
gridRef={gridContainerRef}
|
||||
onLayoutComplete={() => console.log("Layout complete!")}
|
||||
>
|
||||
{media.list.map((data, index) => {
|
||||
let card = (
|
||||
<AudioCard
|
||||
{...{
|
||||
bookmarks,
|
||||
data,
|
||||
type: "media",
|
||||
showCreator: true,
|
||||
showCover: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
{media.list.map((data: any, index: number) => {
|
||||
let card;
|
||||
switch (data.media_type) {
|
||||
case "audio":
|
||||
card = (
|
||||
<AudioCard
|
||||
{...{
|
||||
bookmarks,
|
||||
data,
|
||||
type: "media",
|
||||
showCreator: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "image":
|
||||
card = (
|
||||
<ImageCard
|
||||
{...{
|
||||
bookmarks,
|
||||
data,
|
||||
type: "media",
|
||||
showCreator: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "video":
|
||||
card = (
|
||||
<VideoCard
|
||||
{...{
|
||||
bookmarks,
|
||||
data,
|
||||
type: "media",
|
||||
showCreator: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
card = <div>Unsupported media type</div>;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="col-12 col-lg-6 col-xxl-4 grid-item"
|
||||
className="col-12 col-sm-6 col-xl-4 grid-item"
|
||||
>
|
||||
{card}
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function MediaTab() {
|
||||
|
||||
const filterOptions = [
|
||||
{ value: "all", label: "All Media" },
|
||||
{ value: "images", label: "Images" },
|
||||
{ value: "image", label: "Images" },
|
||||
{ value: "audio", label: "Audio" },
|
||||
{ value: "video", label: "Video" },
|
||||
];
|
||||
@@ -81,11 +81,14 @@ export default function MediaTab() {
|
||||
next={media.getMore}
|
||||
hasMore={!media.list.length || !!media.next}
|
||||
loader={
|
||||
<div className="mt-4 d-flex justify-content-center">
|
||||
<div className="spinner-border text-light" role="status">
|
||||
<span className="visually-hidden">Loading...</span>
|
||||
media.list.length !== 0 &&
|
||||
media.isLoading && (
|
||||
<div className="mt-4 d-flex justify-content-center">
|
||||
<div className="spinner-border text-light" role="status">
|
||||
<span className="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
endMessage={
|
||||
<p className="text-center mt-4 opacity-75">No more results.</p>
|
||||
|
||||
@@ -117,11 +117,14 @@ export default function WeightsTab() {
|
||||
next={weights.getMore}
|
||||
hasMore={!weights.list.length || !!weights.next}
|
||||
loader={
|
||||
<div className="mt-4 d-flex justify-content-center">
|
||||
<div className="spinner-border text-light" role="status">
|
||||
<span className="visually-hidden">Loading...</span>
|
||||
weights.list.length !== 0 &&
|
||||
weights.isLoading && (
|
||||
<div className="mt-4 d-flex justify-content-center">
|
||||
<div className="spinner-border text-light" role="status">
|
||||
<span className="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
endMessage={
|
||||
<p className="text-center mt-4 opacity-75">No more results.</p>
|
||||
@@ -155,7 +158,7 @@ export default function WeightsTab() {
|
||||
}}
|
||||
>
|
||||
<WeightsCards
|
||||
{...{ type: data.weights_category, props }}
|
||||
{...{ type: data.weight_category, props }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,17 +9,10 @@ interface MediaImageComponentProps {
|
||||
export default function MediaImageComponent({
|
||||
mediaFile,
|
||||
}: MediaImageComponentProps) {
|
||||
const imagePath = new BucketConfig().getGcsUrl(
|
||||
mediaFile.public_bucket_path
|
||||
);
|
||||
const imagePath = new BucketConfig().getGcsUrl(mediaFile.public_bucket_path);
|
||||
return (
|
||||
<div>
|
||||
<img
|
||||
src={imagePath}
|
||||
alt="test"
|
||||
width="400"
|
||||
height="300"
|
||||
/>
|
||||
<img src={imagePath} alt="test" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import MediaAudioComponent from "./MediaAudioComponent";
|
||||
import MediaVideoComponent from "./MediaVideoComponent";
|
||||
import MediaImageComponent from "./MediaImageComponent";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import {
|
||||
GetMediaFile,
|
||||
@@ -18,8 +17,6 @@ import {
|
||||
faCircleExclamation,
|
||||
faFaceViewfinder,
|
||||
faArrowDownToLine,
|
||||
// faCirclePlay,
|
||||
// faShare,
|
||||
faSquareQuote,
|
||||
faShare,
|
||||
faLink,
|
||||
@@ -35,6 +32,11 @@ 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";
|
||||
import SdCoverImagePanel from "../weight/cover_image_panels/SdCoverImagePanel";
|
||||
|
||||
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:
|
||||
@@ -107,12 +111,28 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) {
|
||||
);
|
||||
|
||||
case MediaFileType.Image:
|
||||
return <MediaImageComponent mediaFile={mediaFile} />;
|
||||
let sdMediaImage = "/images/avatars/default-pfp.png";
|
||||
if (
|
||||
mediaFile.maybe_model_weight_info &&
|
||||
mediaFile.maybe_model_weight_info
|
||||
.maybe_cover_image_public_bucket_path !== null
|
||||
) {
|
||||
sdMediaImage = bucketConfig.getGcsUrl(
|
||||
mediaFile.maybe_model_weight_info
|
||||
.maybe_cover_image_public_bucket_path
|
||||
);
|
||||
}
|
||||
return <SdCoverImagePanel src={sdMediaImage} />;
|
||||
default:
|
||||
return <div>Unsupported media type</div>;
|
||||
}
|
||||
}
|
||||
|
||||
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 +306,72 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) {
|
||||
setTimeout(() => setButtonLabel("Copy"), 1000);
|
||||
};
|
||||
|
||||
const subtitleDivider = <span className="opacity-25 fs-5 fw-light">|</span>;
|
||||
|
||||
const bucketConfig = new BucketConfig();
|
||||
|
||||
let weightUsedCoverImage = "/images/avatars/default-pfp.png";
|
||||
if (mediaFile.maybe_model_weight_info !== null) {
|
||||
weightUsedCoverImage = bucketConfig.getCdnUrl(
|
||||
mediaFile.maybe_model_weight_info.maybe_cover_image_public_bucket_path,
|
||||
60,
|
||||
100
|
||||
);
|
||||
}
|
||||
|
||||
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 +457,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={weightUsedCoverImage}
|
||||
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}>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useLocation } from "react-router-dom";
|
||||
import MasonryGrid from "components/common/MasonryGrid/MasonryGrid";
|
||||
import MediaCards from "components/common/Card/MediaCards";
|
||||
import SkeletonCard from "components/common/Card/SkeletonCard";
|
||||
import { TempSelect } from "components/common";
|
||||
import {
|
||||
@@ -12,6 +11,7 @@ import Pagination from "components/common/Pagination";
|
||||
|
||||
import { useBookmarks, useListContent } from "hooks";
|
||||
import { GetBookmarksByUser } from "@storyteller/components/src/api/bookmarks/GetBookmarksByUser";
|
||||
import WeightsCards from "components/common/Card/WeightsCards";
|
||||
|
||||
export default function BookmarksTab({ username }: { username: string }) {
|
||||
const { pathname: origin } = useLocation();
|
||||
@@ -164,7 +164,21 @@ export default function BookmarksTab({ username }: { username: string }) {
|
||||
onLayoutComplete={() => console.log("Layout complete!")}
|
||||
>
|
||||
{dataList.map((data: any, key: number) => {
|
||||
let props = { bookmarks, data, origin, type: "weights" };
|
||||
let weightProps = {
|
||||
bookmarks,
|
||||
data,
|
||||
origin,
|
||||
type: "weights",
|
||||
showCreator: true,
|
||||
};
|
||||
|
||||
// let mediaProps = {
|
||||
// bookmarks,
|
||||
// data,
|
||||
// origin,
|
||||
// type: "media",
|
||||
// showCreator: true,
|
||||
// };
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -173,7 +187,15 @@ export default function BookmarksTab({ username }: { username: string }) {
|
||||
key,
|
||||
}}
|
||||
>
|
||||
<MediaCards {...{ type: data.media_type, props }} />
|
||||
<WeightsCards
|
||||
{...{
|
||||
type: data.details.maybe_weight_data.weight_category,
|
||||
props: weightProps,
|
||||
}}
|
||||
/>
|
||||
{/* <MediaCards
|
||||
{...{ type: data.media_type, props: mediaProps }}
|
||||
/> */}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function WeightsTab({ username }: { username: string }) {
|
||||
addQueries: { page_size: 24 },
|
||||
});
|
||||
|
||||
console.log("💎",origin);
|
||||
console.log("💎", origin);
|
||||
|
||||
const handlePageClick = (selectedItem: { selected: number }) => {
|
||||
weights.pageChange(selectedItem.selected);
|
||||
@@ -178,7 +178,7 @@ export default function WeightsTab({ username }: { username: string }) {
|
||||
}}
|
||||
>
|
||||
<WeightsCards
|
||||
{...{ type: data.weights_category, props }}
|
||||
{...{ type: data.weight_category, props }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -67,9 +67,18 @@ export default function WeightPage({
|
||||
const { weight_token } = useParams<{ weight_token: string }>();
|
||||
const origin = search ? new URLSearchParams(search).get("origin") : "";
|
||||
const history = useHistory();
|
||||
const { data: weight, descriptionMD, fetchError, isLoading, title, remove } = useWeightFetch({
|
||||
onRemove: () => { history.push(origin || ""); },
|
||||
token: weight_token
|
||||
const {
|
||||
data: weight,
|
||||
descriptionMD,
|
||||
fetchError,
|
||||
isLoading,
|
||||
title,
|
||||
remove,
|
||||
} = useWeightFetch({
|
||||
onRemove: () => {
|
||||
history.push(origin || "");
|
||||
},
|
||||
token: weight_token,
|
||||
});
|
||||
|
||||
const timeUpdated = moment(weight?.updated_at || "").fromNow();
|
||||
@@ -84,7 +93,7 @@ export default function WeightPage({
|
||||
const bucketConfig = new BucketConfig();
|
||||
|
||||
const weightTypeInfo = useWeightTypeInfo(
|
||||
weight?.weights_type || WeightType.NONE
|
||||
weight?.weight_type || WeightType.NONE
|
||||
);
|
||||
const {
|
||||
label: weightType,
|
||||
@@ -93,7 +102,7 @@ export default function WeightPage({
|
||||
} = weightTypeInfo;
|
||||
|
||||
function renderWeightComponent(weight: Weight) {
|
||||
switch (weight.weights_category) {
|
||||
switch (weight.weight_category) {
|
||||
case WeightCategory.TTS:
|
||||
return (
|
||||
<TtsInferencePanel
|
||||
@@ -221,7 +230,7 @@ export default function WeightPage({
|
||||
[WeightCategory.VOCODER]: { weightCategory: "Vocoder" },
|
||||
};
|
||||
|
||||
let { weightCategory } = weightCategoryMap[weight.weights_category] || {
|
||||
let { weightCategory } = weightCategoryMap[weight.weight_category] || {
|
||||
weightCategory: "none",
|
||||
};
|
||||
|
||||
@@ -230,7 +239,7 @@ export default function WeightPage({
|
||||
{ property: "Category", value: weightCategory },
|
||||
{
|
||||
property: "Visibility",
|
||||
value: weight.creator_set_visibility?.toString() || "",
|
||||
value: weight.creator_set_visibility,
|
||||
},
|
||||
{ property: "Created at", value: weight.created_at?.toString() || "" },
|
||||
{ property: "Updated at", value: weight.updated_at?.toString() || "" },
|
||||
@@ -241,7 +250,7 @@ export default function WeightPage({
|
||||
{ property: "Category", value: weightCategory },
|
||||
{
|
||||
property: "Visibility",
|
||||
value: weight.creator_set_visibility?.toString() || "",
|
||||
value: weight.creator_set_visibility,
|
||||
},
|
||||
{ property: "Created at", value: dateCreated || "" },
|
||||
{ property: "Updated at", value: dateUpdated || "" },
|
||||
@@ -251,7 +260,7 @@ export default function WeightPage({
|
||||
|
||||
let weightDetails = undefined;
|
||||
|
||||
switch (weight.weights_category) {
|
||||
switch (weight.weight_category) {
|
||||
case WeightCategory.TTS:
|
||||
weightDetails = <DataTable data={voiceDetails} />;
|
||||
break;
|
||||
@@ -347,8 +356,8 @@ export default function WeightPage({
|
||||
<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">
|
||||
{(weight.weights_category === WeightCategory.VC ||
|
||||
weight.weights_category === WeightCategory.TTS) && (
|
||||
{(weight.weight_category === WeightCategory.VC ||
|
||||
weight.weight_category === WeightCategory.TTS) && (
|
||||
<WeightCoverImage src={audioWeightCoverImage} />
|
||||
)}
|
||||
<div>
|
||||
|
||||
Reference in new issue
Block a user