mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-07 10:31:46 +00:00
bookmarks tab
This commit is contained in:
1 parent
0bb5a07ef4
commit
9a105d7ee2
7 files changed
+140
-33
No files matched your search
@@ -10,7 +10,7 @@ import Button from "components/common/Button";
|
||||
|
||||
interface AudioCardProps {
|
||||
data: any;
|
||||
type: "media" | "weights" | "favorites";
|
||||
type: "media" | "weights";
|
||||
}
|
||||
|
||||
export default function AudioCard({ data, type }: AudioCardProps) {
|
||||
@@ -28,6 +28,12 @@ export default function AudioCard({ data, type }: AudioCardProps) {
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
const handleUseModel = () => {
|
||||
if (type === "weights") {
|
||||
history.push(`/weights/${data.token}`);
|
||||
}
|
||||
};
|
||||
|
||||
const timeAgo = useTimeAgo(data.created_at);
|
||||
|
||||
const handleLike = async (data: any) => {
|
||||
@@ -84,7 +90,7 @@ export default function AudioCard({ data, type }: AudioCardProps) {
|
||||
<p className="fs-7 opacity-75">{timeAgo}</p>
|
||||
</div>
|
||||
<div onClick={handleInnerClick}>
|
||||
<Button label="Use" small={true} />
|
||||
<Button label="Use" small={true} onClick={handleUseModel} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@ import FavoriteButton from "components/common/FavoriteButton";
|
||||
|
||||
interface ImageCardProps {
|
||||
data: any;
|
||||
type: "media" | "weights" | "favorites";
|
||||
type: "media" | "weights";
|
||||
}
|
||||
|
||||
export default function ImageCard({ data, type }: ImageCardProps) {
|
||||
|
||||
@@ -9,9 +9,10 @@ import LikeButton from "components/common/LikeButton";
|
||||
|
||||
interface VideoCardProps {
|
||||
data: any;
|
||||
type: "media" | "weights";
|
||||
}
|
||||
|
||||
export default function VideoCard({ data }: VideoCardProps) {
|
||||
export default function VideoCard({ data, type }: VideoCardProps) {
|
||||
const history = useHistory();
|
||||
|
||||
const handleCardClick = () => {
|
||||
@@ -30,34 +31,75 @@ export default function VideoCard({ data }: VideoCardProps) {
|
||||
|
||||
return (
|
||||
<Card padding={false} onClick={handleCardClick}>
|
||||
<img
|
||||
src={data.public_bucket_path}
|
||||
alt={data.weight_name}
|
||||
className="card-video"
|
||||
/>
|
||||
<div className="card-img-overlay">
|
||||
<div className="card-img-gradient" />
|
||||
{type === "media" && (
|
||||
<>
|
||||
<img
|
||||
src={data.public_bucket_path}
|
||||
alt={data.weight_name}
|
||||
className="card-video"
|
||||
/>
|
||||
<div className="card-img-overlay">
|
||||
<div className="card-img-gradient" />
|
||||
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="flex-grow-1">
|
||||
<Badge label="Video" color="purple" overlay={true} />
|
||||
</div>
|
||||
</div>
|
||||
<FontAwesomeIcon icon={faPlayCircle} className="card-video-play" />
|
||||
<div className="card-img-overlay-text">
|
||||
<div>
|
||||
<h6 className="fw-semibold text-white mb-1">{data.weight_name}</h6>
|
||||
<p className="fs-7 opacity-75">{timeAgo}</p>
|
||||
<div className="mt-2" onClick={handleInnerClick}>
|
||||
<LikeButton
|
||||
onToggle={handleLike}
|
||||
likeCount={data.likes}
|
||||
overlay={true}
|
||||
/>
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="flex-grow-1">
|
||||
<Badge label="Video" color="purple" overlay={true} />
|
||||
</div>
|
||||
</div>
|
||||
<FontAwesomeIcon icon={faPlayCircle} className="card-video-play" />
|
||||
<div className="card-img-overlay-text">
|
||||
<div>
|
||||
<h6 className="fw-semibold text-white mb-1">
|
||||
{data.weight_name}
|
||||
</h6>
|
||||
<p className="fs-7 opacity-75">{timeAgo}</p>
|
||||
<div className="mt-2" onClick={handleInnerClick}>
|
||||
<LikeButton
|
||||
onToggle={handleLike}
|
||||
likeCount={data.likes}
|
||||
overlay={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{type === "weights" && (
|
||||
<>
|
||||
<img
|
||||
src={data.public_bucket_path}
|
||||
alt={data.weight_name}
|
||||
className="card-video"
|
||||
/>
|
||||
<div className="card-img-overlay">
|
||||
<div className="card-img-gradient" />
|
||||
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="flex-grow-1">
|
||||
<Badge label="Video" color="purple" overlay={true} />
|
||||
</div>
|
||||
</div>
|
||||
<FontAwesomeIcon icon={faPlayCircle} className="card-video-play" />
|
||||
<div className="card-img-overlay-text">
|
||||
<div>
|
||||
<h6 className="fw-semibold text-white mb-1">
|
||||
{data.weight_name}
|
||||
</h6>
|
||||
<p className="fs-7 opacity-75">{timeAgo}</p>
|
||||
<div className="mt-2" onClick={handleInnerClick}>
|
||||
<LikeButton
|
||||
onToggle={handleLike}
|
||||
likeCount={data.likes}
|
||||
overlay={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import Container from "components/common/Container";
|
||||
import Tabs from "components/common/Tabs";
|
||||
import MediaTab from "./tabs/MediaTab";
|
||||
import WeightsTab from "./tabs/WeightsTab";
|
||||
import BookmarksTab from "./tabs/BookmarksTab";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper;
|
||||
@@ -368,7 +369,7 @@ function NewProfilePage(this: any, props: Props) {
|
||||
{
|
||||
to: `/profile/${username}/bookmarks`,
|
||||
label: "Bookmarks",
|
||||
content: <div>Bookmarks</div>,
|
||||
content: <BookmarksTab />,
|
||||
icon: faBookmark,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
import MasonryGrid from "components/common/MasonryGrid/MasonryGrid";
|
||||
import AudioCard from "components/common/Card/AudioCard";
|
||||
import ImageCard from "components/common/Card/ImageCard";
|
||||
import VideoCard from "components/common/Card/VideoCard";
|
||||
import Panel from "components/common/Panel";
|
||||
import AudioPlayerProvider from "components/common/AudioPlayer/AudioPlayerContext";
|
||||
import SkeletonCard from "components/common/Card/SkeletonCard";
|
||||
import mockWeightsData from "./mockWeightsData";
|
||||
|
||||
export default function BookmarksTab() {
|
||||
const [data, setData] = useState(mockWeightsData);
|
||||
const [hasMore, setHasMore] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const gridContainerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
return (
|
||||
<Panel clear={true} padding={true}>
|
||||
<AudioPlayerProvider>
|
||||
{isLoading ? (
|
||||
<div className="row gx-3 gy-3">
|
||||
{Array.from({ length: 6 }).map((_, index) => (
|
||||
<SkeletonCard key={index} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<MasonryGrid
|
||||
gridRef={gridContainerRef}
|
||||
onLayoutComplete={() => console.log("Layout complete!")}
|
||||
>
|
||||
{data.map((data, index) => {
|
||||
let card;
|
||||
switch (data.media_type) {
|
||||
case "audio":
|
||||
card = <AudioCard key={index} data={data} type="weights" />;
|
||||
break;
|
||||
case "image":
|
||||
card = <ImageCard key={index} data={data} type="weights" />;
|
||||
break;
|
||||
case "video":
|
||||
card = <VideoCard key={index} data={data} type="weights" />;
|
||||
break;
|
||||
default:
|
||||
card = <div key={index}>Unsupported media type</div>;
|
||||
}
|
||||
return (
|
||||
<div key={index} className="col-12 col-sm-6 col-xl-4 grid-item">
|
||||
{card}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</MasonryGrid>
|
||||
)}
|
||||
</AudioPlayerProvider>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ export default function MediaTab() {
|
||||
card = <ImageCard key={index} data={data} type="media" />;
|
||||
break;
|
||||
case "video":
|
||||
card = <VideoCard key={index} data={data} />;
|
||||
card = <VideoCard key={index} data={data} type="media" />;
|
||||
break;
|
||||
default:
|
||||
card = <div key={index}>Unsupported media type</div>;
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import SkeletonCard from "components/common/Card/SkeletonCard";
|
||||
|
||||
export default function MediaTab() {
|
||||
export default function WeightsTab() {
|
||||
const [data, setData] = useState(mockWeightsData);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@@ -68,7 +68,7 @@ export default function MediaTab() {
|
||||
card = <ImageCard key={index} data={data} type="weights" />;
|
||||
break;
|
||||
case "video":
|
||||
card = <VideoCard key={index} data={data} />;
|
||||
card = <VideoCard key={index} data={data} type="weights" />;
|
||||
break;
|
||||
default:
|
||||
card = <div key={index}>Unsupported media type</div>;
|
||||
|
||||
Reference in new issue
Block a user