Skip to content

Commit

Permalink
feat: add video listing (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
sirily11 authored Dec 11, 2022
1 parent af3ce0c commit 1e85a31
Show file tree
Hide file tree
Showing 11 changed files with 406 additions and 38 deletions.
2 changes: 1 addition & 1 deletion components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface Props {
export default function Layout({ children, menus, actions }: Props) {
return (
<>
<AppBar position="static" elevation={0}>
<AppBar position="sticky" elevation={0}>
<Toolbar>
<Stack direction={"row"} alignItems={"center"} mr={5} spacing={2}>
<Image
Expand Down
38 changes: 38 additions & 0 deletions components/Video/VideoCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @flow
import * as React from "react";
import { GetVideoResponse } from "../../src/services/VideoService";
import { CardMedia, Stack, Typography } from "@mui/material";
import Image from "next/image";

type Props = {
video: GetVideoResponse;
};

export function VideoCard(props: Props) {
return (
<Stack spacing={0.5} sx={{ cursor: "pointer" }}>
<CardMedia
component={"img"}
image={
props.video.thumbnail ??
"https://helpx.adobe.com/content/dam/help/en/photoshop/using/convert-color-image-black-white/jcr_content/main-pars/before_and_after/image-before/Landscape-Color.jpg"
}
sx={{
height: 240,
borderRadius: 6,
}}
/>
<Typography fontSize={14}>{props.video.title}</Typography>
{/*User name*/}
<Stack direction={"row"} spacing={1}>
<Image
src={"/images/user.icon.svg"}
alt={"user"}
width={20}
height={20}
/>
<Typography fontSize={14}>{props.video.title}</Typography>
</Stack>
</Stack>
);
}
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
"@mui/lab": "5.0.0-alpha.110",
"@mui/material": "^5.10.16",
"@mui/system": "^5.10.17",
"@tanstack/react-virtual": "3.0.0-beta.30",
"@types/node": "18.11.11",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",
"axios": "^1.2.1",
"editor": "workspace:editor",
"eslint": "8.29.0",
"eslint-config-next": "13.0.6",
"formik": "^2.2.9",
Expand All @@ -34,8 +36,8 @@
"react-dom": "18.2.0",
"react-dropzone": "^14.2.3",
"react-qr-code": "^2.0.8",
"typescript": "4.9.3",
"editor": "workspace:editor"
"react-query": "^3.39.2",
"typescript": "4.9.3"
},
"devDependencies": {
"autoprefixer": "^10.4.13",
Expand Down
42 changes: 29 additions & 13 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ import { SnackbarProvider } from "notistack";
import { UIContext, UIContextProvider } from "../src/models/UIModel";
import "editor/src/style.css";
import "../styles/globals.css";
import { QueryClient, QueryClientProvider } from "react-query";
import React from "react";
import { ReactQueryDevtools } from "react-query/devtools";

const theme = createTheme({
components: {
MuiAppBar: {
styleOverrides: {
root: {
color: "white",
backgroundColor: "rgb(255, 255, 255, 0.8)",
backgroundColor: "rgb(255, 255, 255, 1)",
boxShadow: "none",
height: 64,
transition:
Expand Down Expand Up @@ -48,21 +51,34 @@ const theme = createTheme({
},
},
},
MuiChip: {
styleOverrides: {
root: {
borderRadius: 8,
},
},
},
},
});

const queryClient = new QueryClient();

export default function App({ Component, pageProps }: AppProps) {
return (
<SnackbarProvider>
<SessionProvider session={(pageProps as any).session}>
<UIContextProvider>
<ThemeProvider theme={theme}>
<Layout menus={menus} actions={actions}>
<Component {...pageProps} />
<CssBaseline />
</Layout>
</ThemeProvider>
</UIContextProvider>
</SessionProvider>
</SnackbarProvider>
<QueryClientProvider client={queryClient}>
<SnackbarProvider>
<SessionProvider session={(pageProps as any).session}>
<UIContextProvider>
<ThemeProvider theme={theme}>
<Layout menus={menus} actions={actions}>
<Component {...pageProps} />
<CssBaseline />
<ReactQueryDevtools initialIsOpen={false} />
</Layout>
</ThemeProvider>
</UIContextProvider>
</SessionProvider>
</SnackbarProvider>
</QueryClientProvider>
);
}
17 changes: 12 additions & 5 deletions pages/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ export function UploadStep(props: UploadStepProps) {
}
);
setPreSignedUrl(video.preSignedURL);
upload(video.preSignedURL, file);
upload(
(session.data as any).accessToken,
video.video.id,
video.preSignedURL,
file
);
await router.push(`/create?video=${video.video.id}&step=2`);
} catch (e: any) {
notifyError(e);
Expand Down Expand Up @@ -188,16 +193,15 @@ function CreateVideoStep(props: CreateVideoStep) {
},
onSubmit: async (values) => {
try {
console.log("values", values);
await VideoService.updateVideo(
await VideoService.publishVideo(
(session.data! as any).accessToken,
props.video.id,
{
...values,
SalesInfo: isForSale ? values.SalesInfo : undefined,
}
);
router.push(`/create?video=${props.video.id}&step=3`);
await router.push(`/create?video=${props.video.id}&step=3`);
} catch (e: any) {
notifyError(e);
}
Expand Down Expand Up @@ -326,12 +330,15 @@ function FinishStep() {
export const getServerSideProps: GetServerSideProps<Props> = async (context) =>
requireAuthentication(context, async (accessToken, user) => {
const uploadType = context.query.uploadType ?? "video";
const step = parseInt((context.query.step as any) ?? "1");
let step = parseInt((context.query.step as any) ?? "1");
const videoId = (context.query.video as any) ?? null;
let video: GetVideoResponse | null = null;

if (videoId) {
video = await VideoService.getVideo(videoId);
if (video.status !== "UPLOADING") {
step = 3;
}
}

return {
Expand Down
95 changes: 92 additions & 3 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,95 @@
import Head from "next/head";
import Image from "next/image";
import { useGetVideos } from "../src/hooks/useGetVideos";
import { useVirtualizer } from "@tanstack/react-virtual";
import { useEffect, useRef } from "react";
import {
Box,
Chip,
CircularProgress,
Container,
Grid,
Paper,
Stack,
useTheme,
} from "@mui/material";
import { debug } from "util";
import { VideoCard } from "../components/Video/VideoCard";

export default function Home() {
return <></>;
const {
status,
data,
error,
isFetching,
isFetchingNextPage,
fetchNextPage,
hasNextPage,
} = useGetVideos();

const parentRef = useRef(null);

const rows = data ? data.pages.flatMap((page) => page.items) : [];

const rowVirtualizer = useVirtualizer({
count: hasNextPage ? rows.length + 1 : rows.length,
getScrollElement: () => parentRef.current!,
estimateSize: () => 100,
overscan: 10,
});

useEffect(() => {
const [lastItem] = [...rowVirtualizer.getVirtualItems()].reverse();
if (!lastItem) {
return;
}

if (
lastItem.index >= rows.length - 1 &&
hasNextPage &&
!isFetchingNextPage
) {
fetchNextPage();
}
}, [
hasNextPage,
fetchNextPage,
rows.length,
isFetchingNextPage,
rowVirtualizer.getVirtualItems(),
]);
const theme = useTheme();

return (
<Stack spacing={2} ref={parentRef}>
<Box position={"sticky"} top={64}>
<Paper
elevation={0}
sx={{
background: (
theme.components?.MuiAppBar?.styleOverrides?.root as any
)?.backgroundColor,
}}
>
<Stack
width={"100%"}
direction={"row"}
justifyContent={"center"}
alignItems={"center"}
p={1}
>
<Chip label={"All"} />
</Stack>
</Paper>
</Box>
<Grid container spacing={2} columns={{ lg: 15 }} px={10}>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
const row = rows[virtualRow.index];
return (
<Grid item lg={3} key={virtualRow.index}>
{row ? <VideoCard video={row} /> : <CircularProgress />}
</Grid>
);
})}
</Grid>
</Stack>
);
}
Loading

1 comment on commit 1e85a31

@vercel
Copy link

@vercel vercel bot commented on 1e85a31 Dec 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.