mirror of
https://github.com/Qortal/q-tube.git
synced 2025-12-12 15:52:59 +00:00
update playlist content
This commit is contained in:
8
package-lock.json
generated
8
package-lock.json
generated
@@ -21,7 +21,7 @@
|
||||
"localforage": "^1.10.0",
|
||||
"mediainfo.js": "^0.3.5",
|
||||
"moment": "^2.30.1",
|
||||
"qapp-core": "^1.0.41",
|
||||
"qapp-core": "^1.0.43",
|
||||
"quill": "^2.0.2",
|
||||
"quill-image-resize-module-react": "^3.0.0",
|
||||
"react": "^19.0.0",
|
||||
@@ -5062,9 +5062,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/qapp-core": {
|
||||
"version": "1.0.41",
|
||||
"resolved": "https://registry.npmjs.org/qapp-core/-/qapp-core-1.0.41.tgz",
|
||||
"integrity": "sha512-3j10QXhLIRVg7T6RF67B4b29q+C6wnBkPSILdveCOjZeGI4gsrE6Olf8RO3kytNCdgbj4/EuXiE6kC2D5oi9KA==",
|
||||
"version": "1.0.43",
|
||||
"resolved": "https://registry.npmjs.org/qapp-core/-/qapp-core-1.0.43.tgz",
|
||||
"integrity": "sha512-Ts5E5+PGnKp1jybxxtDA3zq8FVl3Dr2vRSs7xZHG9DW0bXtb57/qc9joERlXyJzcDowLzmaEraisMtehgwn/GA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/react-virtual": "^3.13.2",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"localforage": "^1.10.0",
|
||||
"mediainfo.js": "^0.3.5",
|
||||
"moment": "^2.30.1",
|
||||
"qapp-core": "^1.0.41",
|
||||
"qapp-core": "^1.0.43",
|
||||
"quill": "^2.0.2",
|
||||
"quill-image-resize-module-react": "^3.0.0",
|
||||
"react": "^19.0.0",
|
||||
|
||||
@@ -54,12 +54,15 @@ const Layout = () => {
|
||||
},
|
||||
|
||||
'::-webkit-scrollbar-thumb': {
|
||||
backgroundColor: '#90CAF9',
|
||||
backgroundColor: 'rgba(63, 67, 80, 0.24)',
|
||||
borderRadius: '8px',
|
||||
backgroundClip: 'content-box',
|
||||
border: '4px solid transparent',
|
||||
transition: '0.3s background-color',
|
||||
},
|
||||
'::-webkit-scrollbar-thumb:hover': {
|
||||
backgroundColor: 'rgba(63, 67, 80, 0.50)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Outlet />
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import React from "react";
|
||||
import { CardContentContainerComment } from "../common/Comments/Comments-styles";
|
||||
} from '@mui/material';
|
||||
import React from 'react';
|
||||
import { CardContentContainerComment } from '../common/Comments/Comments-styles';
|
||||
|
||||
interface PlaylistsProps {
|
||||
playlistData;
|
||||
@@ -23,23 +23,25 @@ export const Playlists = ({
|
||||
}: PlaylistsProps) => {
|
||||
const theme = useTheme();
|
||||
const isScreenSmall = !useMediaQuery(`(min-width:700px)`);
|
||||
const PlaylistsHeight = "36vw"; // This is videoplayer width * 9/16 (inverse of aspect ratio)
|
||||
const PlaylistsHeight = '36vw'; // This is videoplayer width * 9/16 (inverse of aspect ratio)
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: isScreenSmall ? "200px" : PlaylistsHeight,
|
||||
// width: "100%",
|
||||
...sx,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<CardContentContainerComment
|
||||
sx={{
|
||||
marginTop: "0px",
|
||||
height: "100%",
|
||||
overflow: "auto",
|
||||
marginTop: '0px',
|
||||
height: '100%',
|
||||
gap: '3px',
|
||||
padding: '3px',
|
||||
}}
|
||||
>
|
||||
{playlistData?.videos?.map((vid, index) => {
|
||||
@@ -50,15 +52,18 @@ export const Playlists = ({
|
||||
<Box
|
||||
key={vid?.identifier}
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
width: "100%",
|
||||
display: 'flex',
|
||||
gap: '10px',
|
||||
width: '100%',
|
||||
background: isCurrentVidPlaying && theme.palette.primary.main,
|
||||
alignItems: "center",
|
||||
padding: "10px",
|
||||
borderRadius: "5px",
|
||||
cursor: isCurrentVidPlaying ? "default" : "pointer",
|
||||
userSelect: "none",
|
||||
color:
|
||||
isCurrentVidPlaying && theme.palette.primary.contrastText,
|
||||
alignItems: 'center',
|
||||
padding: '10px',
|
||||
borderRadius: '5px',
|
||||
cursor: isCurrentVidPlaying ? 'default' : 'pointer',
|
||||
userSelect: 'none',
|
||||
border: '1px solid rgba(255, 255, 255, 0.23)',
|
||||
}}
|
||||
onClick={() => {
|
||||
if (isCurrentVidPlaying) return;
|
||||
@@ -68,16 +73,16 @@ export const Playlists = ({
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
fontWeight: "bold",
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{index + 1}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
wordBreak: "break-word",
|
||||
fontSize: '18px',
|
||||
wordBreak: 'break-word',
|
||||
}}
|
||||
>
|
||||
{vid?.metadata?.title}
|
||||
|
||||
@@ -9,6 +9,7 @@ interface ResponsiveImageProps {
|
||||
alt?: string;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
fill?: boolean;
|
||||
}
|
||||
|
||||
const ResponsiveImage: React.FC<ResponsiveImageProps> = ({
|
||||
@@ -18,6 +19,7 @@ const ResponsiveImage: React.FC<ResponsiveImageProps> = ({
|
||||
alt,
|
||||
className,
|
||||
style,
|
||||
fill,
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -46,8 +48,7 @@ const ResponsiveImage: React.FC<ResponsiveImageProps> = ({
|
||||
variant="rectangular"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 0,
|
||||
paddingBottom: `${(height / width) * 100}%`,
|
||||
height: '100%',
|
||||
objectFit: 'contain',
|
||||
visibility: loading ? 'visible' : 'hidden',
|
||||
borderRadius: '8px',
|
||||
@@ -57,13 +58,13 @@ const ResponsiveImage: React.FC<ResponsiveImageProps> = ({
|
||||
|
||||
<img
|
||||
onLoad={() => setLoading(false)}
|
||||
src={!src && !loading ? DeletedVideo : src || null}
|
||||
src={!src && !loading ? DeletedVideo : src || ''}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
borderRadius: '8px',
|
||||
display: loading ? 'none' : 'unset',
|
||||
objectFit: 'contain',
|
||||
objectFit: fill ? 'fill' : 'contain',
|
||||
maskImage: 'radial-gradient(circle, black 95%, transparent 100%)',
|
||||
maskMode: 'alpha',
|
||||
}}
|
||||
|
||||
@@ -2,6 +2,8 @@ import {
|
||||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
ButtonBase,
|
||||
Collapse,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
@@ -15,12 +17,15 @@ import {
|
||||
CardContentContainerComment,
|
||||
CommentActionButtonRow,
|
||||
CommentDateText,
|
||||
CreatedTextComment,
|
||||
EditReplyButton,
|
||||
StyledCardComment,
|
||||
} from './Comments-styles';
|
||||
import { StyledCardHeaderComment } from './Comments-styles';
|
||||
import { StyledCardColComment } from './Comments-styles';
|
||||
import { AuthorTextComment } from './Comments-styles';
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
|
||||
import {
|
||||
StyledCardContentComment,
|
||||
LoadMoreCommentsButton as CommentActionButton,
|
||||
@@ -28,7 +33,7 @@ import {
|
||||
|
||||
import Portal from '../Portal';
|
||||
import { formatDate } from '../../../utils/time';
|
||||
import { createAvatarLink, useAuth } from 'qapp-core';
|
||||
import { createAvatarLink, Spacer, useAuth } from 'qapp-core';
|
||||
interface CommentProps {
|
||||
comment: any;
|
||||
postId: string;
|
||||
@@ -46,7 +51,7 @@ export const Comment = ({
|
||||
const { name } = useAuth();
|
||||
const [currentEdit, setCurrentEdit] = useState<any>(null);
|
||||
const theme = useTheme();
|
||||
|
||||
const [isOpenReplies, setIsOpenReplies] = useState(false);
|
||||
const handleSubmit = useCallback((comment: any, isEdit?: boolean) => {
|
||||
onSubmit(comment, isEdit);
|
||||
setCurrentEdit(null);
|
||||
@@ -97,12 +102,37 @@ export const Comment = ({
|
||||
</Dialog>
|
||||
</Portal>
|
||||
)}
|
||||
|
||||
<CommentCard
|
||||
name={comment?.name}
|
||||
message={comment?.message}
|
||||
replies={comment?.replies || []}
|
||||
setCurrentEdit={setCurrentEdit}
|
||||
created={comment?.created}
|
||||
isOpenReplies={isOpenReplies}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start',
|
||||
}}
|
||||
>
|
||||
{isReplying && (
|
||||
<CommentEditor
|
||||
onSubmit={handleSubmit}
|
||||
postId={postId}
|
||||
postName={postName}
|
||||
isReply
|
||||
commentId={comment.identifier}
|
||||
onCloseReply={() => {
|
||||
setIsReplying(false);
|
||||
setIsEditing(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
@@ -112,36 +142,23 @@ export const Comment = ({
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
{comment?.created && (
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{
|
||||
fontSize: '12px',
|
||||
marginLeft: '5px',
|
||||
}}
|
||||
color={theme.palette.text.primary}
|
||||
>
|
||||
{formatDate(+comment?.created)}
|
||||
</Typography>
|
||||
)}
|
||||
<CommentActionButtonRow>
|
||||
<CommentActionButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setIsReplying(true)}
|
||||
>
|
||||
reply
|
||||
</CommentActionButton>
|
||||
{name === comment?.name && (
|
||||
<CommentActionButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setCurrentEdit(comment)}
|
||||
>
|
||||
edit
|
||||
</CommentActionButton>
|
||||
<CommentActionButtonRow
|
||||
sx={{
|
||||
gap: '20px',
|
||||
}}
|
||||
>
|
||||
{!isReplying && (
|
||||
<ButtonBase onClick={() => setIsReplying(true)}>
|
||||
<Typography>Reply</Typography>
|
||||
</ButtonBase>
|
||||
)}
|
||||
{isReplying && (
|
||||
|
||||
{/* {name === comment?.name && (
|
||||
<ButtonBase onClick={() => setCurrentEdit(comment)}>
|
||||
<Typography>Edit</Typography>
|
||||
</ButtonBase>
|
||||
)} */}
|
||||
{/* {isReplying && (
|
||||
<CommentActionButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
@@ -152,29 +169,33 @@ export const Comment = ({
|
||||
>
|
||||
close
|
||||
</CommentActionButton>
|
||||
)} */}
|
||||
{comment?.replies && comment?.replies?.length > 0 && (
|
||||
<ButtonBase onClick={() => setIsOpenReplies((prev) => !prev)}>
|
||||
{isOpenReplies ? (
|
||||
<ExpandLessIcon
|
||||
sx={{
|
||||
color: 'primary.dark',
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<ExpandMoreIcon
|
||||
sx={{
|
||||
color: 'primary.dark',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Typography color="primary.dark">
|
||||
{isOpenReplies
|
||||
? ` Hide all replies (${comment?.replies?.length})`
|
||||
: ` View all replies (${comment?.replies?.length})`}
|
||||
</Typography>
|
||||
</ButtonBase>
|
||||
)}
|
||||
</CommentActionButtonRow>
|
||||
</Box>
|
||||
</CommentCard>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{isReplying && (
|
||||
<CommentEditor
|
||||
onSubmit={handleSubmit}
|
||||
postId={postId}
|
||||
postName={postName}
|
||||
isReply
|
||||
commentId={comment.identifier}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -186,9 +207,11 @@ export const CommentCard = ({
|
||||
replies,
|
||||
children,
|
||||
setCurrentEdit,
|
||||
isOpenReplies,
|
||||
isReply,
|
||||
}: any) => {
|
||||
const { name: username } = useAuth();
|
||||
const avatarUrl = createAvatarLink(username);
|
||||
const avatarUrl = createAvatarLink(name);
|
||||
|
||||
return (
|
||||
<CardContentContainerComment>
|
||||
@@ -203,72 +226,91 @@ export const CommentCard = ({
|
||||
<Avatar
|
||||
src={avatarUrl}
|
||||
alt={`${name}'s avatar`}
|
||||
sx={{ width: '35px', height: '35px' }}
|
||||
sx={{
|
||||
width: isReply ? '30px' : '40px',
|
||||
height: isReply ? '30px' : '40px',
|
||||
marginRight: '5px',
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<StyledCardColComment>
|
||||
<AuthorTextComment>{name}</AuthorTextComment>
|
||||
</StyledCardColComment>
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<StyledCardColComment
|
||||
sx={{
|
||||
flexDirection: 'row',
|
||||
gap: '10px',
|
||||
}}
|
||||
>
|
||||
<AuthorTextComment>{name}</AuthorTextComment>
|
||||
<CreatedTextComment>{formatDate(+created)}</CreatedTextComment>
|
||||
</StyledCardColComment>
|
||||
<Spacer height="10px" />
|
||||
<StyledCardContentComment>
|
||||
<StyledCardComment>{message}</StyledCardComment>
|
||||
</StyledCardContentComment>
|
||||
{children}
|
||||
</Box>
|
||||
</StyledCardHeaderComment>
|
||||
<StyledCardContentComment>
|
||||
<StyledCardComment>{message}</StyledCardComment>
|
||||
</StyledCardContentComment>
|
||||
<Box
|
||||
sx={{
|
||||
paddingLeft: '15px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
{replies?.map((reply: any) => {
|
||||
return (
|
||||
<Box
|
||||
key={reply?.identifier}
|
||||
id={reply?.identifier}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
border: '1px solid grey',
|
||||
borderRadius: '10px',
|
||||
marginTop: '8px',
|
||||
}}
|
||||
>
|
||||
<CommentCard
|
||||
name={reply?.name}
|
||||
message={reply?.message}
|
||||
setCurrentEdit={setCurrentEdit}
|
||||
<Collapse in={isOpenReplies} timeout="auto" unmountOnExit>
|
||||
<Box
|
||||
sx={{
|
||||
paddingLeft: '50px',
|
||||
paddingTop: '10px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
{replies?.map((reply: any) => {
|
||||
return (
|
||||
<Box
|
||||
key={reply?.identifier}
|
||||
id={reply?.identifier}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
// border: '1px solid grey',
|
||||
borderRadius: '10px',
|
||||
marginTop: '8px',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '5px',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
<CommentCard
|
||||
name={reply?.name}
|
||||
message={reply?.message}
|
||||
setCurrentEdit={setCurrentEdit}
|
||||
created={reply?.created}
|
||||
isReply
|
||||
>
|
||||
{reply?.created && (
|
||||
<CommentDateText>
|
||||
{formatDate(+reply?.created)}
|
||||
</CommentDateText>
|
||||
)}
|
||||
{username === reply?.name ? (
|
||||
<EditReplyButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setCurrentEdit(reply)}
|
||||
sx={{}}
|
||||
>
|
||||
edit
|
||||
</EditReplyButton>
|
||||
) : (
|
||||
<Box />
|
||||
)}
|
||||
</Box>
|
||||
</CommentCard>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
{children}
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '5px',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
{/* {username === reply?.name ? (
|
||||
<EditReplyButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setCurrentEdit(reply)}
|
||||
sx={{}}
|
||||
>
|
||||
edit
|
||||
</EditReplyButton>
|
||||
) : (
|
||||
<Box />
|
||||
)} */}
|
||||
</Box>
|
||||
</CommentCard>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</Collapse>
|
||||
</CardContentContainerComment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -89,6 +89,7 @@ interface CommentEditorProps {
|
||||
commentId?: string;
|
||||
isEdit?: boolean;
|
||||
commentMessage?: string;
|
||||
onCloseReply?: () => void;
|
||||
}
|
||||
|
||||
function utf8ToBase64(inputString: string): string {
|
||||
@@ -111,6 +112,7 @@ export const CommentEditor = ({
|
||||
commentId,
|
||||
isEdit,
|
||||
commentMessage,
|
||||
onCloseReply,
|
||||
}: CommentEditorProps) => {
|
||||
const [value, setValue] = useState<string>('');
|
||||
const { name, address } = useAuth();
|
||||
@@ -215,6 +217,8 @@ export const CommentEditor = ({
|
||||
}
|
||||
};
|
||||
|
||||
console.log('onCloseReply', onCloseReply);
|
||||
|
||||
return (
|
||||
<CommentInputContainer>
|
||||
<CommentInput
|
||||
@@ -239,10 +243,21 @@ export const CommentEditor = ({
|
||||
justifyContent: 'flex-end',
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
visibility: value || isFocused ? 'visible' : 'hidden',
|
||||
visibility: isReply
|
||||
? 'visible'
|
||||
: value || isFocused
|
||||
? 'visible'
|
||||
: 'hidden',
|
||||
}}
|
||||
>
|
||||
<Button onClick={() => setValue('')} variant="text">
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
setValue('');
|
||||
if (!onCloseReply) return;
|
||||
onCloseReply();
|
||||
}}
|
||||
variant="text"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<SubmitCommentButton
|
||||
|
||||
@@ -25,10 +25,10 @@ export const CardContentContainer = styled(Box)(({ theme }) => ({
|
||||
}));
|
||||
|
||||
export const CardContentContainerComment = styled(Box)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.mode === 'light' ? '#a9d9d038' : '#c3abe414',
|
||||
border: `1px solid ${theme.palette.primary.main}`,
|
||||
// backgroundColor: theme.palette.mode === 'light' ? '#a9d9d038' : '#c3abe414',
|
||||
// border: `1px solid ${theme.palette.primary.main}`,
|
||||
margin: '0px',
|
||||
padding: '8px 15px',
|
||||
// padding: '8px 15px',
|
||||
borderRadius: '8px',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
@@ -45,10 +45,10 @@ export const StyledCardHeader = styled(Box)({
|
||||
|
||||
export const StyledCardHeaderComment = styled(Box)({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'flex-start',
|
||||
gap: '7px',
|
||||
padding: '9px 7px',
|
||||
padding: '0px 7px 9px 0px',
|
||||
});
|
||||
|
||||
export const StyledCardCol = styled(Box)({
|
||||
@@ -83,13 +83,13 @@ export const StyledCardContentComment = styled(Box)({
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'flex-start',
|
||||
padding: '5px 10px',
|
||||
// padding: '5px 10px',
|
||||
gap: '10px',
|
||||
});
|
||||
|
||||
export const StyledCardComment = styled(Typography)(({ theme }) => ({
|
||||
letterSpacing: 0,
|
||||
fontWeight: 400,
|
||||
fontWeight: 300,
|
||||
color: theme.palette.text.primary,
|
||||
fontSize: '19px',
|
||||
wordBreak: 'break-word',
|
||||
@@ -112,7 +112,14 @@ export const AuthorText = styled(Typography)({
|
||||
export const AuthorTextComment = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '17px',
|
||||
letterSpacing: '0.3px',
|
||||
fontWeight: 400,
|
||||
fontWeight: 500,
|
||||
color: theme.palette.text.primary,
|
||||
userSelect: 'none',
|
||||
}));
|
||||
export const CreatedTextComment = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '17px',
|
||||
letterSpacing: '0.3px',
|
||||
fontWeight: 300,
|
||||
color: theme.palette.text.primary,
|
||||
userSelect: 'none',
|
||||
}));
|
||||
@@ -231,7 +238,7 @@ export const CommentInputContainer = styled(Box)({
|
||||
maxWidth: '1000px',
|
||||
borderRadius: '8px',
|
||||
gap: '10px',
|
||||
alignItems: 'center',
|
||||
alignItems: 'flex-start',
|
||||
});
|
||||
|
||||
export const CommentInput = styled(TextField)(({ theme }) => ({
|
||||
|
||||
@@ -203,7 +203,11 @@ export const SuperLike = ({
|
||||
}}
|
||||
>
|
||||
<CustomTooltip title="Super Like" placement="top">
|
||||
<Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
}}
|
||||
>
|
||||
<ThumbUpIcon
|
||||
style={{
|
||||
color: 'gold',
|
||||
@@ -217,6 +221,7 @@ export const SuperLike = ({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
userSelect: 'none',
|
||||
marginLeft: '5px',
|
||||
}}
|
||||
>
|
||||
<span style={{ marginRight: '10px', paddingBottom: '4px' }}>
|
||||
|
||||
@@ -142,15 +142,19 @@ export const Comment = ({
|
||||
</Typography>
|
||||
)}
|
||||
<CommentActionButtonRow>
|
||||
<CommentActionButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setIsReplying(true)}
|
||||
>
|
||||
reply
|
||||
</CommentActionButton>
|
||||
{!isReplying && (
|
||||
<CommentActionButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setIsReplying(true)}
|
||||
>
|
||||
reply
|
||||
</CommentActionButton>
|
||||
)}
|
||||
|
||||
{username === comment?.name && hasHash && (
|
||||
<CommentActionButton
|
||||
color="info"
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setCurrentEdit(comment)}
|
||||
@@ -161,7 +165,8 @@ export const Comment = ({
|
||||
{isReplying && (
|
||||
<CommentActionButton
|
||||
size="small"
|
||||
variant="contained"
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={() => {
|
||||
setIsReplying(false);
|
||||
setIsEditing(false);
|
||||
@@ -328,6 +333,7 @@ export const CommentCard = ({
|
||||
{username === reply?.name ? (
|
||||
<EditReplyButton
|
||||
size="small"
|
||||
color="info"
|
||||
variant="contained"
|
||||
onClick={() => setCurrentEdit(reply)}
|
||||
sx={{}}
|
||||
|
||||
@@ -277,7 +277,11 @@ export const CommentEditor = ({
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
/>
|
||||
|
||||
<SubmitCommentButton variant="contained" onClick={handleSubmit}>
|
||||
<SubmitCommentButton
|
||||
color="info"
|
||||
variant="contained"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
{isReply ? 'Submit reply' : isEdit ? 'Edit' : 'Submit comment'}
|
||||
</SubmitCommentButton>
|
||||
</CommentInputContainer>
|
||||
|
||||
@@ -191,16 +191,12 @@ export const LoadMoreCommentsButtonRow = styled(Box)({
|
||||
export const EditReplyButton = styled(Button)(({ theme }) => ({
|
||||
width: '30px',
|
||||
alignSelf: 'flex-end',
|
||||
background: theme.palette.primary.light,
|
||||
color: '#ffffff',
|
||||
}));
|
||||
|
||||
export const LoadMoreCommentsButton = styled(Button)(({ theme }) => ({
|
||||
fontWeight: 400,
|
||||
letterSpacing: '0.2px',
|
||||
fontSize: '15px',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: '#ffffff',
|
||||
}));
|
||||
|
||||
export const CommentActionButtonRow = styled(Box)({
|
||||
@@ -266,7 +262,5 @@ export const SubmitCommentButton = styled(Button)(({ theme }) => ({
|
||||
fontWeight: 400,
|
||||
letterSpacing: '0.2px',
|
||||
fontSize: '15px',
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: '#ffffff',
|
||||
width: '75%',
|
||||
}));
|
||||
|
||||
@@ -26,6 +26,7 @@ export interface VideoPlayerProps {
|
||||
style?: CSS.Properties;
|
||||
duration?: number;
|
||||
filename: string;
|
||||
parentStyles?: CSS.Properties;
|
||||
}
|
||||
|
||||
export const VideoPlayer = ({ ...props }: VideoPlayerProps) => {
|
||||
@@ -34,9 +35,13 @@ export const VideoPlayer = ({ ...props }: VideoPlayerProps) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
// width: '100%',
|
||||
height: '70vh',
|
||||
background: 'black',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
...(props?.parentStyles || {}),
|
||||
}}
|
||||
>
|
||||
<QappVideoPlayer
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
export const useTestIdentifiers = false;
|
||||
export const QTUBE_VIDEO_BASE = useTestIdentifiers
|
||||
? 'MYTEST2_vid_'
|
||||
? '2MYTEST_vid_'
|
||||
: 'qtube_vid_';
|
||||
export const QTUBE_PLAYLIST_BASE = useTestIdentifiers
|
||||
? 'MYTEST2_playlist_'
|
||||
? '2MYTEST_playlist_'
|
||||
: 'qtube_playlist_';
|
||||
export const SUPER_LIKE_BASE = useTestIdentifiers
|
||||
? 'MYTEST2_superlike_'
|
||||
? '2MYTEST_superlike_'
|
||||
: 'qtube_superlike_';
|
||||
|
||||
export const LIKE_BASE = useTestIdentifiers ? 'MYTEST2_like_' : 'qtube_like_';
|
||||
export const LIKE_BASE = useTestIdentifiers ? '2MYTEST_like_' : 'qtube_like_';
|
||||
|
||||
export const COMMENT_BASE = useTestIdentifiers
|
||||
? 'qc_v1_MYTEST2_'
|
||||
? '2qc_v1_MYTEST_'
|
||||
: 'qc_v1_qtube_';
|
||||
export const FOR = useTestIdentifiers ? 'FORTEST52' : 'FOR0962';
|
||||
export const FOR_SUPER_LIKE = useTestIdentifiers ? 'MYTEST2_sl' : `qtube_sl`;
|
||||
export const FOR_LIKE = useTestIdentifiers ? 'MYTEST2_like' : `qtube_like`;
|
||||
export const FOR = useTestIdentifiers ? '2FORTEST5' : 'FOR096';
|
||||
export const FOR_SUPER_LIKE = useTestIdentifiers ? '2MYTEST_sl' : `qtube_sl`;
|
||||
export const FOR_LIKE = useTestIdentifiers ? '2MYTEST_like' : `qtube_like`;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Roboto Thin 100 */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: url('.styles/fonts/Roboto-Thin.ttf') format('truetype');
|
||||
src: url('./styles/fonts/Roboto-Thin.ttf') format('truetype');
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@@ -61,49 +61,88 @@ export const PlaylistContent = () => {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column',
|
||||
padding: '0px',
|
||||
marginLeft: '2%',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<VideoPlayerContainer
|
||||
sx={{
|
||||
width: isScreenSmall ? '100%' : '60%',
|
||||
alignSelf: 'start',
|
||||
paddingRight: isScreenSmall ? '10px' : '0px',
|
||||
marginBottom: '20px',
|
||||
height: '70vh',
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
gap: '10px',
|
||||
}}
|
||||
>
|
||||
{videoReference && (
|
||||
<VideoPlayer
|
||||
name={videoReference?.name}
|
||||
service={videoReference?.service}
|
||||
identifier={videoReference?.identifier}
|
||||
user={channelName}
|
||||
jsonId={id}
|
||||
poster={videoCover || ''}
|
||||
nextVideo={nextVideo}
|
||||
onEnd={onEndVideo}
|
||||
autoPlay={doAutoPlay}
|
||||
videoStyles={{
|
||||
video: { aspectRatio: '16 / 9' },
|
||||
}}
|
||||
duration={videoData?.duration}
|
||||
filename={videoData?.filename}
|
||||
/>
|
||||
)}
|
||||
{playlistData && (
|
||||
<Playlists
|
||||
playlistData={playlistData}
|
||||
currentVideoIdentifier={videoData?.id}
|
||||
onClick={(name, identifier) => {
|
||||
setVideoMetadataResource({
|
||||
name,
|
||||
identifier,
|
||||
service: 'DOCUMENT',
|
||||
});
|
||||
}}
|
||||
sx={playlistsSX}
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexGrow: 1,
|
||||
flexBasis: '75%',
|
||||
}}
|
||||
>
|
||||
{videoReference && (
|
||||
<VideoPlayer
|
||||
name={videoReference?.name}
|
||||
service={videoReference?.service}
|
||||
identifier={videoReference?.identifier}
|
||||
user={channelName}
|
||||
jsonId={id}
|
||||
poster={videoCover || ''}
|
||||
nextVideo={nextVideo}
|
||||
onEnd={onEndVideo}
|
||||
autoPlay={doAutoPlay}
|
||||
videoStyles={{
|
||||
video: { aspectRatio: '16 / 9' },
|
||||
}}
|
||||
duration={videoData?.duration}
|
||||
filename={videoData?.filename}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexGrow: 1,
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
'::-webkit-scrollbar-track': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
|
||||
'::-webkit-scrollbar': {
|
||||
width: '16px',
|
||||
height: '10px',
|
||||
},
|
||||
|
||||
'::-webkit-scrollbar-thumb': {
|
||||
backgroundColor: 'rgba(63, 67, 80, 0.24)',
|
||||
borderRadius: '8px',
|
||||
backgroundClip: 'content-box',
|
||||
border: '4px solid transparent',
|
||||
transition: '0.3s background-color',
|
||||
},
|
||||
'::-webkit-scrollbar-thumb:hover': {
|
||||
backgroundColor: 'rgba(63, 67, 80, 0.50)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{playlistData && (
|
||||
<Playlists
|
||||
playlistData={playlistData}
|
||||
currentVideoIdentifier={videoData?.id}
|
||||
onClick={(name, identifier) => {
|
||||
setVideoMetadataResource({
|
||||
name,
|
||||
identifier,
|
||||
service: 'DOCUMENT',
|
||||
});
|
||||
}}
|
||||
// sx={playlistsSX}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</VideoPlayerContainer>
|
||||
<VideoActionsBar
|
||||
channelName={channelName}
|
||||
|
||||
@@ -16,19 +16,16 @@ export const useVideoContentState = () => {
|
||||
const { name: channelName, id } = useParams();
|
||||
const [videoMetadataResource, setVideoMetadataResource] =
|
||||
useState<null | QortalGetMetadata>(null);
|
||||
const { resource } = usePublish(
|
||||
2,
|
||||
'JSON',
|
||||
videoMetadataResource
|
||||
? videoMetadataResource
|
||||
: !id
|
||||
? null
|
||||
: {
|
||||
identifier: id,
|
||||
name: channelName,
|
||||
service: 'DOCUMENT',
|
||||
}
|
||||
);
|
||||
const metadata: QortalGetMetadata = videoMetadataResource
|
||||
? videoMetadataResource
|
||||
: {
|
||||
identifier: id || '',
|
||||
name: channelName || '',
|
||||
service: 'DOCUMENT',
|
||||
};
|
||||
|
||||
const { resource } = usePublish(2, 'JSON', metadata);
|
||||
|
||||
const [superLikeversion, setSuperLikeVersion] = useState<null | number>(null);
|
||||
const [isExpandedDescription, setIsExpandedDescription] =
|
||||
useState<boolean>(false);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Box, Button, Divider, Typography, useMediaQuery } from '@mui/material';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { CommentSection } from '../../../components/common/Comments/CommentSection.tsx';
|
||||
import { SuperLikesSection } from '../../../components/common/SuperLikesList/SuperLikesSection.tsx';
|
||||
import { DisplayHtml } from '../../../components/common/TextEditor/DisplayHtml.tsx';
|
||||
import { VideoPlayer } from '../../../components/common/VideoPlayer/VideoPlayer.tsx';
|
||||
import {
|
||||
fontSizeSmall,
|
||||
@@ -19,19 +18,17 @@ import DOMPurify from 'dompurify';
|
||||
import {
|
||||
Spacer,
|
||||
VideoContentContainer,
|
||||
VideoDescription,
|
||||
VideoPlayerContainer,
|
||||
VideoTitle,
|
||||
} from './VideoContent-styles.tsx';
|
||||
import { useScrollToTop } from '../../../hooks/useScrollToTop.tsx';
|
||||
import { CrowdfundInlineContent } from '../../../components/Publish/EditPlaylist/Upload-styles.tsx';
|
||||
import { convertQortalLinks } from '../../../components/common/TextEditor/utils.ts';
|
||||
import { processText } from 'qapp-core';
|
||||
|
||||
function flattenHtml(html: string): string {
|
||||
const sanitize: string = DOMPurify.sanitize(html, {
|
||||
USE_PROFILES: { html: true },
|
||||
});
|
||||
const res = convertQortalLinks(sanitize);
|
||||
const res = processText(sanitize);
|
||||
return res
|
||||
.replace(/<\/p>/gi, ' ') // replace end of paragraph with space
|
||||
.replace(/<p[^>]*>/gi, '') // remove opening <p> tags
|
||||
@@ -48,15 +45,38 @@ const CollapsibleDescription = ({
|
||||
html?: any;
|
||||
}) => {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const [showMore, setShowMore] = useState(false);
|
||||
const textRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (textRef.current) {
|
||||
const el = textRef.current;
|
||||
|
||||
// Clone the element to measure full height
|
||||
const clone = el.cloneNode(true) as HTMLElement;
|
||||
clone.style.visibility = 'hidden';
|
||||
clone.style.position = 'absolute';
|
||||
clone.style.pointerEvents = 'none';
|
||||
clone.style.WebkitLineClamp = 'none';
|
||||
clone.style.display = 'block';
|
||||
|
||||
document.body.appendChild(clone);
|
||||
const fullHeight = clone.offsetHeight;
|
||||
document.body.removeChild(clone);
|
||||
|
||||
const clampedHeight = el.offsetHeight;
|
||||
|
||||
if (fullHeight > clampedHeight + 2) {
|
||||
setShowMore(true);
|
||||
}
|
||||
}
|
||||
}, [text, html]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
maxWidth: '1200px',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ maxWidth: '1200px' }}>
|
||||
{text && (
|
||||
<Typography
|
||||
ref={textRef}
|
||||
sx={{
|
||||
display: '-webkit-box',
|
||||
WebkitLineClamp: expanded ? 'none' : 2,
|
||||
@@ -70,6 +90,7 @@ const CollapsibleDescription = ({
|
||||
)}
|
||||
{html && (
|
||||
<Box
|
||||
ref={textRef}
|
||||
sx={{
|
||||
display: '-webkit-box',
|
||||
WebkitLineClamp: expanded ? 'none' : 2,
|
||||
@@ -81,13 +102,15 @@ const CollapsibleDescription = ({
|
||||
dangerouslySetInnerHTML={{ __html: flattenHtml(html) }}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
size="small"
|
||||
sx={{ mt: 1, textTransform: 'none' }}
|
||||
>
|
||||
{expanded ? 'Show less' : 'Show more'}
|
||||
</Button>
|
||||
{showMore && (
|
||||
<Button
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
size="small"
|
||||
sx={{ mt: 1, textTransform: 'none' }}
|
||||
>
|
||||
{expanded ? 'Show less' : 'Show more'}
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -133,8 +156,6 @@ export const VideoContent = () => {
|
||||
setScreenWidth(window.innerWidth + 120);
|
||||
});
|
||||
}, []);
|
||||
console.log('videoData', videoData);
|
||||
console.log('videoData?.fullDescription', videoData?.fullDescription);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -233,88 +254,6 @@ export const VideoContent = () => {
|
||||
) : (
|
||||
<CollapsibleDescription text={videoData?.fullDescription} />
|
||||
)}
|
||||
{/* {videoData?.fullDescription && (
|
||||
<Box
|
||||
sx={{
|
||||
background: '#333333',
|
||||
borderRadius: '5px',
|
||||
padding: '5px',
|
||||
width: '95%',
|
||||
cursor: !descriptionHeight
|
||||
? 'default'
|
||||
: isExpandedDescription
|
||||
? 'default'
|
||||
: 'pointer',
|
||||
position: 'relative',
|
||||
marginBottom: '30px',
|
||||
}}
|
||||
className={
|
||||
!descriptionHeight
|
||||
? ''
|
||||
: isExpandedDescription
|
||||
? ''
|
||||
: 'hover-click'
|
||||
}
|
||||
>
|
||||
{descriptionHeight && !isExpandedDescription && (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: '0px',
|
||||
right: '0px',
|
||||
left: '0px',
|
||||
bottom: '0px',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
if (isExpandedDescription) return;
|
||||
setIsExpandedDescription(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
ref={contentRef}
|
||||
sx={{
|
||||
height: !descriptionHeight
|
||||
? 'auto'
|
||||
: isExpandedDescription
|
||||
? 'auto'
|
||||
: '200px',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
{videoData?.htmlDescription ? (
|
||||
<DisplayHtml html={videoData?.htmlDescription} />
|
||||
) : (
|
||||
<VideoDescription
|
||||
variant="body1"
|
||||
color="textPrimary"
|
||||
sx={{
|
||||
cursor: 'default',
|
||||
}}
|
||||
>
|
||||
{videoData?.fullDescription}
|
||||
</VideoDescription>
|
||||
)}
|
||||
</Box>
|
||||
{descriptionHeight >= descriptionThreshold && (
|
||||
<Typography
|
||||
onClick={() => {
|
||||
setIsExpandedDescription((prev) => !prev);
|
||||
}}
|
||||
sx={{
|
||||
fontWeight: 'bold',
|
||||
fontSize: '16px',
|
||||
cursor: 'pointer',
|
||||
paddingLeft: '15px',
|
||||
paddingTop: '15px',
|
||||
}}
|
||||
>
|
||||
{isExpandedDescription ? 'Show less' : '...more'}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
)} */}
|
||||
|
||||
{id && channelName && (
|
||||
<>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { RefObject, useCallback, useRef } from 'react';
|
||||
|
||||
import { VideoCardContainer } from './VideoList-styles.tsx';
|
||||
import {
|
||||
|
||||
@@ -100,14 +100,31 @@ export const VideoListItem = ({
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ResponsiveImage
|
||||
src={video?.image}
|
||||
width={320}
|
||||
height={180}
|
||||
<div
|
||||
style={{
|
||||
maxHeight: '50%',
|
||||
height: 480,
|
||||
width: 320,
|
||||
maxHeight: '50vh',
|
||||
maxWidth: '100%',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<ResponsiveImage
|
||||
src={video?.image}
|
||||
width={320}
|
||||
height={180}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
zIndex: 1,
|
||||
}}
|
||||
fill={true}
|
||||
/>
|
||||
</div>
|
||||
<VideoCardTitle>{video?.title}</VideoCardTitle>
|
||||
<BottomParent>
|
||||
<NameContainer
|
||||
|
||||
@@ -15,8 +15,7 @@ export const VideoLoaderItem = ({ status }) => {
|
||||
style={{
|
||||
width: 320,
|
||||
height: 180,
|
||||
borderRadius: '8px',
|
||||
marginTop: 10,
|
||||
// borderRadius: '8px',
|
||||
alignSelf: 'center',
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
@@ -24,12 +23,18 @@ export const VideoLoaderItem = ({ status }) => {
|
||||
|
||||
<BottomParent>
|
||||
<NameContainer>
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{
|
||||
width: 24,
|
||||
height: 24,
|
||||
}}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rectangular"
|
||||
style={{
|
||||
width: 200,
|
||||
height: 50,
|
||||
marginTop: 12,
|
||||
height: 34,
|
||||
alignSelf: 'center',
|
||||
maxWidth: '100%',
|
||||
}}
|
||||
@@ -39,18 +44,8 @@ export const VideoLoaderItem = ({ status }) => {
|
||||
variant="rectangular"
|
||||
style={{
|
||||
width: 200,
|
||||
height: 24,
|
||||
marginTop: 15,
|
||||
alignSelf: 'center',
|
||||
}}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rectangular"
|
||||
style={{
|
||||
width: 200,
|
||||
height: 24,
|
||||
marginTop: 15,
|
||||
alignSelf: 'center',
|
||||
height: 15,
|
||||
marginTop: '5px',
|
||||
}}
|
||||
/>
|
||||
</BottomParent>
|
||||
|
||||
@@ -105,7 +105,7 @@ const darkTheme = createTheme({
|
||||
primary: {
|
||||
// main: '#101115',
|
||||
main: '#90CAF9',
|
||||
dark: 'rgb(45, 92, 201)',
|
||||
dark: 'rgba(66, 165, 245, 1)',
|
||||
light: 'rgb(130, 185, 255)',
|
||||
contrastText: 'rgba(0, 0, 0, 0.87)',
|
||||
},
|
||||
|
||||
@@ -1,33 +1,12 @@
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
|
||||
// const __filename = fileURLToPath(import.meta.url);
|
||||
// const __dirname = path.dirname(__filename);
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react(), viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
src: path.join(
|
||||
__dirname,
|
||||
'node_modules',
|
||||
'mediainfo.js',
|
||||
'dist',
|
||||
'MediaInfoModule.wasm'
|
||||
),
|
||||
dest: '', // copies to root of /dist → served at /MediaInfoModule.wasm
|
||||
},
|
||||
],
|
||||
}),],
|
||||
plugins: [react()],
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 5174
|
||||
port: 5174,
|
||||
},
|
||||
base: "",
|
||||
base: '',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user