feat: 동영상 게시글 상세 작업
This commit is contained in:
@@ -52,7 +52,15 @@ export class AttachmentApiService implements AttachmentService {
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
public async getMovieThumbnailUrl(atflId: string): Promise<string> {
|
||||
public async getStreamVideoUrlByAtflId(atflId: string): Promise<string> {
|
||||
const response = await fetch(
|
||||
`${ENDPOINT.ATTACH_SERVICE.STREAM_VIDEO}/${atflId}`,
|
||||
);
|
||||
const blob = await response.blob();
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
public async getMovieThumbnailUrlByAtflId(atflId: string): Promise<string> {
|
||||
const response = await fetch(
|
||||
`${ENDPOINT.ATTACH_SERVICE.MOVIE_THUMBNAIL}/${atflId}`,
|
||||
);
|
||||
@@ -60,6 +68,14 @@ export class AttachmentApiService implements AttachmentService {
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
public async getMovieThumbnailUrlByAtflCd(atflCd: string): Promise<string> {
|
||||
const response = await fetch(
|
||||
`${ENDPOINT.ATTACH_SERVICE.MOVIE_THUMBNAIL}/atflCd/${atflCd}`,
|
||||
);
|
||||
const blob = await response.blob();
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
public async downloadAttachmentByAtflCd(
|
||||
atflCd: string,
|
||||
): Promise<AxiosResponse> {
|
||||
|
||||
@@ -40,6 +40,8 @@ export interface AttachmentService {
|
||||
deleteAttachmentByAtflCd: (atflCd: string) => Promise<void>;
|
||||
getImageUrlByAtflId: (atflId: string) => Promise<string>;
|
||||
getImageUrlByAtflCd: (atflCd: string) => Promise<string>;
|
||||
getMovieThumbnailUrl: (atflId: string) => Promise<string>;
|
||||
getStreamVideoUrlByAtflId: (atflId: string) => Promise<string>;
|
||||
getMovieThumbnailUrlByAtflId: (atflId: string) => Promise<string>;
|
||||
getMovieThumbnailUrlByAtflCd: (atflCd: string) => Promise<string>;
|
||||
downloadAttachmentByAtflCd: (atflCd: string) => Promise<AxiosResponse>;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ export const ENDPOINT = {
|
||||
MOVIE_THUMBNAIL: "/attach-service/api/v1/movie/thumbnail",
|
||||
ATTACHMENTS: "/attach-service/api/v1/atfl/attachments",
|
||||
DOWNLOAD: "/attach-service/api/v1/atflcd/download",
|
||||
STREAM_VIDEO: "/attach-service/api/v1/stream/video",
|
||||
},
|
||||
USER_SERVICE: {
|
||||
LOGIN: "/user-service/login",
|
||||
|
||||
@@ -2,10 +2,11 @@ import dayjs from "dayjs";
|
||||
import Image from "next/image";
|
||||
import type { ColumnDef } from "@tanstack/react-table";
|
||||
import { Badge, Checkbox, Skeleton } from "@common/components";
|
||||
import { AttachmentApi } from "@/entities/attachment";
|
||||
import type { Post } from "@/entities/post";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { AttachmentApi } from "@/entities/attachment";
|
||||
import { useMenuStore } from "@/shared/lib";
|
||||
|
||||
export const createColumns = (
|
||||
thumbRefs: React.MutableRefObject<Map<number, string>>,
|
||||
@@ -81,9 +82,17 @@ type ThumbImageProps = {
|
||||
const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => {
|
||||
const prevImage = thumbRefs.current.get(pstNo);
|
||||
|
||||
const { bbsInfo } = useMenuStore((state) => state);
|
||||
|
||||
const { data: imageUrl, isLoading } = useQuery({
|
||||
queryKey: [ENDPOINT.ATTACH_SERVICE.IMAGES, atflCd],
|
||||
queryFn: () => AttachmentApi.getImageUrlByAtflCd(atflCd),
|
||||
queryFn: () => {
|
||||
if (bbsInfo?.bbsTypeCd === "BBSIMAGE") {
|
||||
return AttachmentApi.getImageUrlByAtflCd(atflCd);
|
||||
} else if (bbsInfo?.bbsTypeCd === "BBSMOVIE") {
|
||||
return AttachmentApi.getMovieThumbnailUrlByAtflCd(atflCd);
|
||||
}
|
||||
},
|
||||
select: (url) => {
|
||||
if (url) thumbRefs.current.set(pstNo, url);
|
||||
return url;
|
||||
|
||||
@@ -23,12 +23,11 @@ import {
|
||||
Skeleton,
|
||||
} from "@common/components";
|
||||
import { PostApi, type Post, type PostParams } from "@/entities/post";
|
||||
import type { BoardType } from "@/entities/board";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { useMenuStore, useUserStore } from "@/shared/lib";
|
||||
import { GridViewDataTable } from "@/shared/ui/grid-view-data-table";
|
||||
import { columns } from "../model/post-table-columns";
|
||||
import { createColumns } from "../model/grid-view-table-columns";
|
||||
import { columns as tableColumns } from "../model/post-table-columns";
|
||||
import { createColumns as createGridViewColumns } from "../model/grid-view-table-columns";
|
||||
|
||||
function PostPage({ bbsId }: { bbsId: string }) {
|
||||
const router = useRouter();
|
||||
@@ -36,7 +35,7 @@ function PostPage({ bbsId }: { bbsId: string }) {
|
||||
const { confirm } = useConfirm();
|
||||
const { userInfo } = useUserStore((state) => state);
|
||||
const { bbsInfo, pageMenuAuthority } = useMenuStore((state) => state);
|
||||
const bbsType = bbsInfo?.bbsTypeCd as BoardType;
|
||||
const thumbRefs = useRef<Map<number, string>>(new Map());
|
||||
|
||||
const [postParams, setPostParams] = useState<PostParams>({
|
||||
keywordType: "title",
|
||||
@@ -48,8 +47,6 @@ function PostPage({ bbsId }: { bbsId: string }) {
|
||||
});
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||
|
||||
const thumbRefs = useRef<Map<number, string>>(new Map());
|
||||
|
||||
const { data: upndFixPostList } = useQuery({
|
||||
queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, bbsInfo],
|
||||
queryFn: () =>
|
||||
@@ -62,10 +59,7 @@ function PostPage({ bbsId }: { bbsId: string }) {
|
||||
...post,
|
||||
isUpndFixPost: post.upndFixYn === "Y",
|
||||
}));
|
||||
return {
|
||||
...data,
|
||||
content: newContent,
|
||||
};
|
||||
return { ...data, content: newContent };
|
||||
},
|
||||
enabled: bbsInfo?.upndFixUseYn === "Y",
|
||||
});
|
||||
@@ -85,9 +79,14 @@ function PostPage({ bbsId }: { bbsId: string }) {
|
||||
enabled: false,
|
||||
});
|
||||
|
||||
const isGridViewPage =
|
||||
bbsInfo?.bbsTypeCd === "BBSIMAGE" || bbsInfo?.bbsTypeCd === "BBSMOVIE";
|
||||
|
||||
const table = useReactTable({
|
||||
data: [...(upndFixPostList?.content ?? []), ...(postList?.content ?? [])],
|
||||
columns,
|
||||
data: isGridViewPage
|
||||
? (postList?.content ?? [])
|
||||
: [...(upndFixPostList?.content ?? []), ...(postList?.content ?? [])],
|
||||
columns: isGridViewPage ? createGridViewColumns(thumbRefs) : tableColumns,
|
||||
state: { pagination, rowSelection },
|
||||
rowCount: postList?.totalElements ?? 0,
|
||||
manualPagination: true,
|
||||
@@ -97,17 +96,7 @@ function PostPage({ bbsId }: { bbsId: string }) {
|
||||
onRowSelectionChange: setRowSelection,
|
||||
});
|
||||
|
||||
const gridViewTable = useReactTable({
|
||||
data: postList?.content ?? [],
|
||||
columns: createColumns(thumbRefs),
|
||||
state: { pagination, rowSelection },
|
||||
rowCount: postList?.totalElements ?? 0,
|
||||
manualPagination: true,
|
||||
enableMultiRowSelection: true,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
onPaginationChange: setPagination,
|
||||
onRowSelectionChange: setRowSelection,
|
||||
});
|
||||
const DataTableComponent = isGridViewPage ? GridViewDataTable : DataTable;
|
||||
|
||||
const onPostDelete = async () => {
|
||||
const selectedPosts = table
|
||||
@@ -211,19 +200,11 @@ function PostPage({ bbsId }: { bbsId: string }) {
|
||||
</div>
|
||||
<div className="card !m-[1.2rem] h-full overflow-auto !p-0">
|
||||
{isFetched ? (
|
||||
bbsType === "BBSIMAGE" || bbsType === "BBSMOVIE" ? (
|
||||
<GridViewDataTable
|
||||
table={gridViewTable}
|
||||
onRowClick={handleRowClick}
|
||||
viewPagination
|
||||
/>
|
||||
) : (
|
||||
<DataTable
|
||||
table={table}
|
||||
onRowClick={handleRowClick}
|
||||
viewPagination
|
||||
/>
|
||||
)
|
||||
<DataTableComponent
|
||||
table={table}
|
||||
onRowClick={handleRowClick}
|
||||
viewPagination
|
||||
/>
|
||||
) : (
|
||||
<Skeleton className="h-[36rem] w-full" />
|
||||
)}
|
||||
|
||||
@@ -36,7 +36,10 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) {
|
||||
queryKey: [ENDPOINT.ATTACH_SERVICE.DOWNLOAD, postData?.atflCd],
|
||||
queryFn: () =>
|
||||
AttachmentApi.downloadAttachmentByAtflCd(postData?.atflCd as string),
|
||||
enabled: !!postData?.atflCd && bbsInfo?.bbsTypeCd !== "BBSIMAGE",
|
||||
enabled:
|
||||
!!postData?.atflCd &&
|
||||
bbsInfo?.bbsTypeCd !== "BBSIMAGE" &&
|
||||
bbsInfo?.bbsTypeCd !== "BBSMOVIE",
|
||||
});
|
||||
|
||||
const { data: imageUrl, isLoading } = useQuery({
|
||||
@@ -46,6 +49,22 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) {
|
||||
enabled: !!postData?.atflCd,
|
||||
});
|
||||
|
||||
const { data: videoAttachment } = useQuery({
|
||||
queryKey: [ENDPOINT.ATTACH_SERVICE.ATTACHMENTS, postData?.atflCd],
|
||||
queryFn: () => AttachmentApi.getAttachmentsInfo(postData?.atflCd as string),
|
||||
select: (data) => data[0],
|
||||
enabled: !!postData?.atflCd && bbsInfo?.bbsTypeCd === "BBSMOVIE",
|
||||
});
|
||||
|
||||
const { data: videoUrl } = useQuery({
|
||||
queryKey: [ENDPOINT.ATTACH_SERVICE.STREAM_VIDEO, videoAttachment?.atflId],
|
||||
queryFn: () =>
|
||||
AttachmentApi.getStreamVideoUrlByAtflId(
|
||||
videoAttachment?.atflId as string,
|
||||
),
|
||||
enabled: !!videoAttachment?.atflId,
|
||||
});
|
||||
|
||||
const { mutate: deletePost } = useMutation({
|
||||
mutationFn: (pstPswd: string) => PostApi.deletePost(bbsId, pstNo, pstPswd),
|
||||
onSuccess: () => {
|
||||
@@ -142,6 +161,11 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{bbsInfo?.bbsTypeCd === "BBSMOVIE" && (
|
||||
<div className="relative my-6 flex h-[56.25rem] w-[100rem]">
|
||||
<video src={videoUrl} controls className="object-contain" />
|
||||
</div>
|
||||
)}
|
||||
<pre className="font-noto min-h-[40rem] whitespace-pre-wrap p-8 text-2xl tracking-tighter text-foreground">
|
||||
{postData?.pstCn ?? ""}
|
||||
</pre>
|
||||
|
||||
@@ -50,7 +50,7 @@ function WithPreviewFileUploader<T extends PostFormData | PostUpdateFormData>({
|
||||
imageUrl = await AttachmentApi.getImageUrlByAtflId(atflId);
|
||||
}
|
||||
if (bbsInfo?.bbsTypeCd === "BBSMOVIE") {
|
||||
imageUrl = await AttachmentApi.getMovieThumbnailUrl(atflId);
|
||||
imageUrl = await AttachmentApi.getMovieThumbnailUrlByAtflId(atflId);
|
||||
}
|
||||
setThumbnailUrl(imageUrl);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user