3
0
mirror of https://github.com/Qortal/q-tube.git synced 2025-02-11 17:55:51 +00:00

Merge pull request #7 from QortalSeth/main

Updates to Video Player, Playlists, and VideoContent/PlaylistContent pages
This commit is contained in:
Qortal Dev 2024-01-24 08:02:32 -07:00 committed by GitHub
commit 3f79339e6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 1038 additions and 856 deletions

22
package-lock.json generated
View File

@ -39,6 +39,7 @@
"eslint": "^8.38.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
"prettier": "^2.8.6",
"typescript": "^5.0.2",
"vite": "^5.0.5"
}
@ -3661,6 +3662,21 @@
"node": ">= 0.8.0"
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@ -6972,6 +6988,12 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true
},
"prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",

View File

@ -41,6 +41,7 @@
"eslint": "^8.38.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
"prettier": "^2.8.6",
"typescript": "^5.0.2",
"vite": "^5.0.5"
}

View File

@ -1,13 +1,30 @@
import { IconTypes } from './IconTypes'
import { IconTypes } from "./IconTypes";
export const DownloadingLight: React.FC<IconTypes> = ({
color,
height,
width,
className,
onClickFunc
onClickFunc,
}) => {
return (
<svg className={className} xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height={height} viewBox="0 0 24 24" width={width} fill="#FFFFFF"><g><rect fill="none" /></g><g><g><path d="M18.32,4.26C16.84,3.05,15.01,2.25,13,2.05v2.02c1.46,0.18,2.79,0.76,3.9,1.62L18.32,4.26z M19.93,11h2.02 c-0.2-2.01-1-3.84-2.21-5.32L18.31,7.1C19.17,8.21,19.75,9.54,19.93,11z M18.31,16.9l1.43,1.43c1.21-1.48,2.01-3.32,2.21-5.32 h-2.02C19.75,14.46,19.17,15.79,18.31,16.9z M13,19.93v2.02c2.01-0.2,3.84-1,5.32-2.21l-1.43-1.43 C15.79,19.17,14.46,19.75,13,19.93z M13,12V7h-2v5H7l5,5l5-5H13z M11,19.93v2.02c-5.05-0.5-9-4.76-9-9.95s3.95-9.45,9-9.95v2.02 C7.05,4.56,4,7.92,4,12S7.05,19.44,11,19.93z"/></g></g></svg>
)
}
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
enableBackground="new 0 0 24 24"
height={height}
viewBox="0 0 24 24"
width={width}
fill="#FFFFFF"
>
<g>
<rect fill="none" />
</g>
<g>
<g>
<path d="M18.32,4.26C16.84,3.05,15.01,2.25,13,2.05v2.02c1.46,0.18,2.79,0.76,3.9,1.62L18.32,4.26z M19.93,11h2.02 c-0.2-2.01-1-3.84-2.21-5.32L18.31,7.1C19.17,8.21,19.75,9.54,19.93,11z M18.31,16.9l1.43,1.43c1.21-1.48,2.01-3.32,2.21-5.32 h-2.02C19.75,14.46,19.17,15.79,18.31,16.9z M13,19.93v2.02c2.01-0.2,3.84-1,5.32-2.21l-1.43-1.43 C15.79,19.17,14.46,19.75,13,19.93z M13,12V7h-2v5H7l5,5l5-5H13z M11,19.93v2.02c-5.05-0.5-9-4.76-9-9.95s3.95-9.45,9-9.95v2.02 C7.05,4.56,4,7.92,4,12S7.05,19.44,11,19.93z" />
</g>
</g>
</svg>
);
};

View File

@ -20,18 +20,15 @@ export const Playlists = ({
sx={{
display: "flex",
flexDirection: "column",
maxWidth: "400px",
width: "100%",
maxWidth: "25vw",
maxHeight: "70vh",
}}
>
<CrowdfundSubTitleRow>
<CrowdfundSubTitle>Playlist</CrowdfundSubTitle>
</CrowdfundSubTitleRow>
<CardContentContainerComment
sx={{
marginTop: "25px",
height: "450px",
marginTop: "0px",
height: "100%",
overflow: "auto",
}}
>
@ -61,7 +58,8 @@ export const Playlists = ({
>
<Typography
sx={{
fontSize: "14px",
fontSize: "18px",
fontWeight: "bold",
}}
>
{index + 1}

View File

@ -1,19 +0,0 @@
import { Box, Typography } from '@mui/material'
import React from 'react'
import ListSuperLikes from './ListSuperLikes'
import { useSelector } from 'react-redux'
import { RootState } from '../../../state/store'
export const LiskSuperLikeContainer = () => {
const superlikelist = useSelector((state: RootState) => state.global.superlikelistAll);
return (
<Box>
<Typography sx={{
fontSize: '18px',
color: 'gold'
}}>Recent Super likes</Typography>
<ListSuperLikes superlikes={superlikelist} />
</Box>
)
}

View File

@ -0,0 +1,25 @@
import { Box, Typography } from "@mui/material";
import React from "react";
import ListSuperLikes from "./ListSuperLikes";
import { useSelector } from "react-redux";
import { RootState } from "../../../state/store";
export const ListSuperLikeContainer = () => {
const superlikelist = useSelector(
(state: RootState) => state.global.superlikelistAll
);
return (
<Box>
<Typography
sx={{
fontSize: "18px",
color: "gold",
}}
>
Recent Super likes
</Typography>
<ListSuperLikes superlikes={superlikelist} />
</Box>
);
};

View File

@ -49,9 +49,8 @@ export default function ListSuperLikes({ superlikes }) {
amount = parseFloat(superlike?.amount).toFixed(2);
}
return (
<>
<React.Fragment key={superlike?.identifier}>
<ListItem
key={superlike?.identifier}
alignItems="flex-start"
sx={{
cursor: url ? "pointer" : "default",
@ -68,66 +67,64 @@ export default function ListSuperLikes({ superlikes }) {
width: "100%",
}}
>
<ListItem
sx={{
padding: "0px",
}}
alignItems="flex-start"
>
<ListItemAvatar>
<Avatar
alt="Remy Sharp"
src={`/arbitrary/THUMBNAIL/${superlike?.name}/qortal_avatar`}
/>
</ListItemAvatar>
<ListItemText
primary={
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "5px",
fontSize: "16px",
}}
>
<ThumbUpIcon
style={{
color: "gold",
}}
/>
<Typography
<List sx={{ padding: "0px" }}>
<ListItem
sx={{
padding: "0px",
}}
alignItems="flex-start"
>
<ListItemAvatar>
<Avatar
alt="Remy Sharp"
src={`/arbitrary/THUMBNAIL/${superlike?.name}/qortal_avatar`}
/>
</ListItemAvatar>
<ListItemText
primary={
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "5px",
fontSize: "18px",
}}
>
{amount ? amount : ""} QORT
</Typography>
</Box>
}
secondary={
<Box
sx={{
fontSize: "15px",
}}
>
<Typography
sx={{
display: "inline",
wordBreak: "break-word",
fontSize: "16px",
}}
component="span"
variant="body2"
color="text.primary"
>
{superlike?.name}
</Typography>
<ThumbUpIcon
style={{
color: "gold",
}}
/>
<Typography
sx={{
fontSize: "18px",
}}
>
{amount ? amount : ""} QORT
</Typography>
</Box>
}
secondary={
<>
<Typography
sx={{
display: "inline",
wordBreak: "break-word",
fontSize: "15px",
}}
component="span"
variant="body2"
color="text.primary"
>
{superlike?.name}
</Typography>
{` - ${truncateMessage(message)}`}
</Box>
}
/>
</ListItem>
{` - ${truncateMessage(message)}`}
</>
}
/>
</ListItem>
</List>
{forName && (
<Box
sx={{
@ -151,7 +148,7 @@ export default function ListSuperLikes({ superlikes }) {
>
{superlikes.length === index + 1 ? null : <Divider />}
</Box>
</>
</React.Fragment>
);
})}
</List>

View File

@ -0,0 +1,39 @@
import { Button, ButtonProps } from "@mui/material";
import { MouseEvent } from "react";
interface SubscribeButtonProps extends ButtonProps {
name: string;
}
const isSubscribed = false;
export const SubscribeButton = ({ name, ...props }: SubscribeButtonProps) => {
const manageSubscription = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
e.stopPropagation();
console.log("subscribed to: ", name);
};
const verticalPadding = "3px";
const horizontalPadding = "8px";
const buttonStyle = {
...props.sx,
fontSize: "15px",
fontWeight: "700",
paddingTop: verticalPadding,
paddingBottom: verticalPadding,
paddingLeft: horizontalPadding,
paddingRight: horizontalPadding,
borderRadius: 28,
display: "none",
};
return (
<Button
{...props}
variant={"contained"}
color="error"
sx={buttonStyle}
onClick={e => manageSubscription(e)}
>
{isSubscribed ? "Unsubscribe" : "Subscribe"}
</Button>
);
};

View File

@ -239,28 +239,19 @@ export const SuperLike = ({
flexShrink: 0,
}}
>
{numberOfSuperlikes === 0 ? null : (
<p
style={{
fontSize: "16px",
userSelect: "none",
margin: "0px",
padding: "0px",
}}
>
{totalAmount} QORT from {numberOfSuperlikes} Super Likes
</p>
)}
<Tooltip title="Super Like" placement="top">
<Box
sx={{
padding: "5px",
borderRadius: "7px",
gap: "10px",
gap: "5px",
display: "flex",
alignItems: "center",
outline: "1px gold solid",
marginRight:'10px',
height: '53px',
}}
>
<ThumbUpIcon
@ -268,14 +259,25 @@ export const SuperLike = ({
color: "gold",
}}
/>
<p
style={{
fontSize: "16px",
margin: "0px",
}}
>
Super Like
</p>
{numberOfSuperlikes === 0 ? null : (
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center', userSelect: "none"}}>
<span style={{marginRight:'10px', paddingBottom:'4px'}}>{numberOfSuperlikes}</span>
<img
style={{
height: "25px",
width: "25px",
marginRight:'5px',
}}
src={qortImg}
alt={"Qort Icon"}
/>
{truncateNumber(totalAmount,0)}
</div>
)}
</Box>
</Tooltip>
</Box>

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,4 @@
export const minPriceSuperlike = 10;
export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.;:|—~@#$%^*+=]/g;
export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.;:|—~@#$%^*+=<>]/g;
export const titleSaveFormatter = /[^a-zA-Z0-9\s-_!()&',.;—~@#$%^+=]/g;

View File

@ -1,5 +1,13 @@
import { styled } from "@mui/system";
import { Box, Grid, Typography, Checkbox, TextField, InputLabel, Autocomplete } from "@mui/material";
import {
Box,
Grid,
Typography,
Checkbox,
TextField,
InputLabel,
Autocomplete,
} from "@mui/material";
export const VideoContainer = styled(Grid)(({ theme }) => ({
position: "relative",
@ -9,7 +17,7 @@ export const VideoContainer = styled(Grid)(({ theme }) => ({
gap: "20px",
flexWrap: "wrap",
justifyContent: "flex-start",
width: '100%'
width: "100%",
}));
// export const VideoCardContainer = styled(Grid)({
@ -31,18 +39,18 @@ export const VideoContainer = styled(Grid)(({ theme }) => ({
// },
// }));
export const VideoCardContainer = styled('div')(({ theme }) => ({
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',
export const VideoCardContainer = styled("div")(({ theme }) => ({
display: "grid",
gridTemplateColumns: "repeat(auto-fill, minmax(250px, 1fr))",
gap: theme.spacing(2),
padding: '10px',
width: '100%'
padding: "10px",
width: "100%",
}));
export const VideoCardCol = styled('div')({
position: 'relative',
minWidth: '250px', // Minimum width of each item
maxWidth: '1fr', // Maximum width, allowing the item to fill the column
export const VideoCardCol = styled("div")({
position: "relative",
minWidth: "250px", // Minimum width of each item
maxWidth: "1fr", // Maximum width, allowing the item to fill the column
// ... other styles
});
@ -55,8 +63,8 @@ export const StoresRow = styled(Grid)(({ theme }) => ({
width: "auto",
position: "relative",
"@media (max-width: 450px)": {
width: "100%"
}
width: "100%",
},
}));
export const VideoCard = styled(Grid)(({ theme }) => ({
@ -83,8 +91,8 @@ export const VideoCard = styled(Grid)(({ theme }) => ({
boxShadow:
theme.palette.mode === "dark"
? "0px 8px 10px 1px hsla(0,0%,0%,0.14), 0px 3px 14px 2px hsla(0,0%,0%,0.12), 0px 5px 5px -3px hsla(0,0%,0%,0.2)"
: "rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;"
}
: "rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;",
},
}));
export const StoreCardInfo = styled(Grid)(({ theme }) => ({
@ -92,7 +100,7 @@ export const StoreCardInfo = styled(Grid)(({ theme }) => ({
flexDirection: "column",
gap: "10px",
padding: "5px",
marginTop: "15px"
marginTop: "15px",
}));
export const VideoImageContainer = styled(Grid)(({ theme }) => ({}));
@ -101,9 +109,9 @@ export const VideoCardImage = styled("img")(({ theme }) => ({
maxWidth: "300px",
minWidth: "150px",
borderRadius: "5px",
height: '150px',
objectFit: 'fill',
width: '266px',
height: "150px",
objectFit: "fill",
width: "266px",
}));
const DoubleLine = styled(Typography)`
@ -111,7 +119,7 @@ const DoubleLine = styled(Typography)`
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
`
`;
export const VideoCardTitle = styled(DoubleLine)(({ theme }) => ({
fontFamily: "Cairo",
@ -119,37 +127,36 @@ export const VideoCardTitle = styled(DoubleLine)(({ theme }) => ({
letterSpacing: "0.4px",
color: theme.palette.text.primary,
userSelect: "none",
marginBottom: 'auto'
marginBottom: "auto",
}));
export const VideoCardName = styled(Typography)(({ theme }) => ({
fontFamily: "Cairo",
fontSize: "14px",
letterSpacing: "0.4px",
color: theme.palette.text.primary,
userSelect: "none",
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
width: "100%",
}));
export const VideoUploadDate = styled(Typography)(({ theme }) => ({
fontFamily: "Cairo",
fontSize: "12px",
letterSpacing: "0.4px",
color: theme.palette.text.primary,
userSelect: "none"
}));
fontFamily: "Cairo",
fontSize: "18px",
letterSpacing: "0.4px",
color: theme.palette.text.primary,
userSelect: "none",
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
}));
export const VideoUploadDate = styled(Typography)(({ theme }) => ({
fontFamily: "Cairo",
fontSize: "18px",
letterSpacing: "0.4px",
color: theme.palette.text.primary,
userSelect: "none",
}));
export const BottomParent = styled(Box)(({ theme }) => ({
display: 'flex',
alignItems: 'flex-start',
flexDirection: 'column'
display: "flex",
alignItems: "flex-start",
flexDirection: "column",
}));
export const VideoCardDescription = styled(Typography)(({ theme }) => ({
fontFamily: "Karla",
fontSize: "20px",
letterSpacing: "0px",
color: theme.palette.text.primary,
userSelect: "none"
userSelect: "none",
}));
export const StoreCardOwner = styled(Typography)(({ theme }) => ({
@ -159,7 +166,7 @@ export const StoreCardOwner = styled(Typography)(({ theme }) => ({
position: "absolute",
bottom: "5px",
right: "10px",
userSelect: "none"
userSelect: "none",
}));
export const StoreCardYouOwn = styled(Box)(({ theme }) => ({
@ -171,7 +178,7 @@ export const StoreCardYouOwn = styled(Box)(({ theme }) => ({
gap: "5px",
fontFamily: "Livvic",
fontSize: "15px",
color: theme.palette.text.primary
color: theme.palette.text.primary,
}));
export const MyStoresRow = styled(Grid)(({ theme }) => ({
@ -179,16 +186,16 @@ export const MyStoresRow = styled(Grid)(({ theme }) => ({
flexDirection: "row",
justifyContent: "flex-end",
padding: "5px",
width: "100%"
width: "100%",
}));
export const NameContainer = styled(Box)(({ theme }) => ({
display: "flex",
flexDirection: "row",
justifyContent: "flex-start",
alignItems: 'center',
gap: '10px',
marginBottom: '10px'
alignItems: "center",
gap: "10px",
marginBottom: "10px",
}));
export const MyStoresCard = styled(Box)(({ theme }) => ({
@ -201,14 +208,14 @@ export const MyStoresCard = styled(Box)(({ theme }) => ({
padding: "5px 10px",
fontFamily: "Raleway",
fontSize: "18px",
color: theme.palette.text.primary
color: theme.palette.text.primary,
}));
export const MyStoresCheckbox = styled(Checkbox)(({ theme }) => ({
color: "#c0d4ff",
"&.Mui-checked": {
color: "#6596ff"
}
color: "#6596ff",
},
}));
export const ProductManagerRow = styled(Box)(({ theme }) => ({
@ -219,8 +226,6 @@ export const ProductManagerRow = styled(Box)(({ theme }) => ({
width: "100%",
}));
export const FiltersCol = styled(Grid)(({ theme }) => ({
display: "flex",
flexDirection: "column",
@ -228,13 +233,13 @@ export const FiltersCol = styled(Grid)(({ theme }) => ({
padding: "20px 15px",
backgroundColor: theme.palette.background.default,
borderTop: `1px solid ${theme.palette.background.paper}`,
borderRight: `1px solid ${theme.palette.background.paper}`
borderRight: `1px solid ${theme.palette.background.paper}`,
}));
export const FiltersContainer = styled(Box)(({ theme }) => ({
display: "flex",
flexDirection: "column",
justifyContent: "space-between"
justifyContent: "space-between",
}));
export const FiltersRow = styled(Box)(({ theme }) => ({
@ -244,7 +249,7 @@ export const FiltersRow = styled(Box)(({ theme }) => ({
width: "100%",
padding: "0 15px",
fontSize: "16px",
userSelect: "none"
userSelect: "none",
}));
export const FiltersTitle = styled(Typography)(({ theme }) => ({
@ -255,74 +260,73 @@ export const FiltersTitle = styled(Typography)(({ theme }) => ({
fontFamily: "Raleway",
fontSize: "17px",
color: theme.palette.text.primary,
userSelect: "none"
userSelect: "none",
}));
export const FiltersCheckbox = styled(Checkbox)(({ theme }) => ({
color: "#c0d4ff",
"&.Mui-checked": {
color: "#6596ff"
}
color: "#6596ff",
},
}));
export const FilterSelect = styled(Autocomplete)(({ theme }) => ({
"& #categories-select": {
padding: "7px"
padding: "7px",
},
"& .MuiSelect-placeholder": {
fontFamily: "Raleway",
fontSize: "17px",
color: theme.palette.text.primary,
userSelect: "none"
userSelect: "none",
},
"& MuiFormLabel-root": {
fontFamily: "Raleway",
fontSize: "17px",
color: theme.palette.text.primary,
userSelect: "none"
}
userSelect: "none",
},
}));
export const FilterSelectMenuItems = styled(TextField)(({ theme }) => ({
fontFamily: "Raleway",
fontSize: "17px",
color: theme.palette.text.primary,
userSelect: "none"
userSelect: "none",
}));
export const FiltersSubContainer = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
flexDirection: "column",
gap: "5px"
gap: "5px",
}));
export const FilterDropdownLabel = styled(InputLabel)(({ theme }) => ({
fontFamily: "Raleway",
fontSize: "16px",
color: theme.palette.text.primary
color: theme.palette.text.primary,
}));
export const IconsBox = styled(Box)({
display: 'flex',
display: "flex",
gap: "3px",
position: 'absolute',
top: '12px',
right: '5px',
transition: 'all 0.3s ease-in-out',
position: "absolute",
top: "12px",
right: "5px",
transition: "all 0.3s ease-in-out",
});
export const BlockIconContainer = styled(Box)({
display: 'flex',
display: "flex",
boxShadow: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;",
backgroundColor: '#fbfbfb',
backgroundColor: "#fbfbfb",
color: "#c25252",
padding: '5px',
borderRadius: '3px',
transition: 'all 0.3s ease-in-out',
padding: "5px",
borderRadius: "3px",
transition: "all 0.3s ease-in-out",
"&:hover": {
cursor: 'pointer',
cursor: "pointer",
transform: "scale(1.1)",
}
})
},
});

View File

@ -63,8 +63,9 @@ import { Playlists } from "../../components/Playlists/Playlists";
import { PlaylistSVG } from "../../assets/svgs/PlaylistSVG";
import BlockIcon from "@mui/icons-material/Block";
import EditIcon from "@mui/icons-material/Edit";
import { LiskSuperLikeContainer } from "../../components/common/ListSuperLikes/LiskSuperLikeContainer";
import { ListSuperLikeContainer } from "../../components/common/ListSuperLikes/ListSuperLikeContainer.tsx";
import { VideoCardImageContainer } from "./VideoCardImageContainer";
import { SubscribeButton } from "../../components/common/SubscribeButton.tsx";
interface VideoListProps {
mode?: string;
@ -634,13 +635,13 @@ export const VideoList = ({ mode }: VideoListProps) => {
>
{videoObj?.user}
</VideoCardName>
</NameContainer>
{videoObj?.created && (
<VideoUploadDate>
{formatDate(videoObj.created)}
</VideoUploadDate>
)}
{videoObj?.created && (
<VideoUploadDate>
{formatDate(videoObj.created)}
</VideoUploadDate>
)}
</NameContainer>
<Box
sx={{
display: "flex",
@ -733,8 +734,8 @@ export const VideoList = ({ mode }: VideoListProps) => {
>
{videoObj?.user}
</VideoCardName>
<SubscribeButton name={videoObj?.user} />
</NameContainer>
{videoObj?.created && (
<VideoUploadDate>
{formatDate(videoObj.created)}
@ -755,7 +756,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
</ProductManagerRow>
</Grid>
<FiltersCol item xs={0} lg={3} xl={2}>
<LiskSuperLikeContainer />
<ListSuperLikeContainer />
</FiltersCol>
</Grid>
);

View File

@ -7,6 +7,7 @@ import { useParams } from 'react-router-dom'
import { useSelector } from 'react-redux'
import { setUserAvatarHash } from '../../state/features/globalSlice'
import { RootState } from '../../state/store'
import { SubscribeButton } from "../../components/common/SubscribeButton.tsx";
export const IndividualProfile = () => {
const { name: paramName } = useParams()
@ -53,7 +54,7 @@ export const IndividualProfile = () => {
{paramName}
</AuthorTextComment>
</StyledCardColComment>
<SubscribeButton name={paramName} sx={{marginLeft:'10px'}}/>
</StyledCardHeaderComment>
</Box>
</HeaderContainer>

View File

@ -2,11 +2,10 @@ import { styled } from "@mui/system";
import { Box, Grid, Typography, Checkbox } from "@mui/material";
export const VideoPlayerContainer = styled(Box)(({ theme }) => ({
maxWidth: '95%',
width: '1000px',
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
maxWidth: "95%",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
}));
export const VideoTitle = styled(Typography)(({ theme }) => ({
@ -14,7 +13,7 @@ export const VideoTitle = styled(Typography)(({ theme }) => ({
fontSize: "20px",
color: theme.palette.text.primary,
userSelect: "none",
wordBreak: "break-word"
wordBreak: "break-word",
}));
export const VideoDescription = styled(Typography)(({ theme }) => ({
@ -22,60 +21,65 @@ export const VideoDescription = styled(Typography)(({ theme }) => ({
fontSize: "16px",
color: theme.palette.text.primary,
userSelect: "none",
wordBreak: "break-word"
wordBreak: "break-word",
}));
export const Spacer = ({height}: any)=> {
return <Box sx={{
height: height
}} />
}
export const Spacer = ({ height }: any) => {
return (
<Box
sx={{
height: height,
}}
/>
);
};
export const StyledCardHeaderComment = styled(Box)({
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-start',
gap: '5px',
padding: '7px 0px'
})
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
gap: "5px",
padding: "7px 0px",
});
export const StyledCardCol = styled(Box)({
display: 'flex',
overflow: 'hidden',
flexDirection: 'column',
gap: '2px',
alignItems: 'flex-start',
width: '100%'
})
display: "flex",
overflow: "hidden",
flexDirection: "column",
gap: "2px",
alignItems: "flex-start",
width: "100%",
});
export const StyledCardColComment = styled(Box)({
display: 'flex',
overflow: 'hidden',
flexDirection: 'column',
gap: '2px',
alignItems: 'flex-start',
width: '100%'
})
display: "flex",
overflow: "hidden",
flexDirection: "column",
gap: "2px",
alignItems: "flex-start",
width: "100%",
});
export const AuthorTextComment = styled(Typography)({
fontFamily: 'Raleway, sans-serif',
fontSize: '16px',
lineHeight: '1.2'
})
fontFamily: "Raleway, sans-serif",
fontSize: "20px",
lineHeight: "1.2",
});
export const FileAttachmentContainer = styled(Box)(({ theme }) =>({
export const FileAttachmentContainer = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
gap: "20px",
padding: "5px 10px",
border: `1px solid ${theme.palette.text.primary}`,
width: "350px",
}));
export const FileAttachmentFont = styled(Typography)(({ theme }) => ({
fontFamily: "Mulish",
color: theme.palette.text.primary,
fontSize: "16px",
fontSize: "20px",
letterSpacing: 0,
fontWeight: 400,
userSelect: "none",
whiteSpace: 'nowrap'
}));
whiteSpace: "nowrap",
}));

View File

@ -55,6 +55,7 @@ import {
SUPER_LIKE_BASE,
} from "../../constants/Identifiers.ts";
import { minPriceSuperlike } from "../../constants/Misc.ts";
import { SubscribeButton } from "../../components/common/SubscribeButton.tsx";
export const PlaylistContent = () => {
const { name, id } = useParams();
@ -414,7 +415,6 @@ export const PlaylistContent = () => {
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
}}
>
<Typography>This playlist is empty</Typography>
@ -422,48 +422,128 @@ export const PlaylistContent = () => {
</>
) : (
<>
{videoReference && (
<VideoPlayer
name={videoReference?.name}
service={videoReference?.service}
identifier={videoReference?.identifier}
user={name}
jsonId={id}
poster={videoCover || ""}
nextVideo={nextVideo}
onEnd={onEndVideo}
autoPlay={doAutoPlay}
/>
)}
<Box
sx={{
display: "grid",
gridTemplateColumns: "70vw 30vw",
width: "100vw",
}}
>
{videoReference && (
<VideoPlayer
name={videoReference?.name}
service={videoReference?.service}
identifier={videoReference?.identifier}
user={name}
jsonId={id}
poster={videoCover || ""}
nextVideo={nextVideo}
onEnd={onEndVideo}
autoPlay={doAutoPlay}
/>
)}
{playlistData && (
<Playlists
playlistData={playlistData}
currentVideoIdentifier={videoData?.id}
onClick={getVideoData}
/>
)}
</Box>
<Spacer height="15px" />
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "flex-end",
display: "grid",
gridTemplateColumns: "1fr 1fr",
}}
>
<FileAttachmentContainer>
<FileAttachmentFont>save to disk</FileAttachmentFont>
<FileElement
fileInfo={{
...videoReference,
filename:
videoData?.filename ||
videoData?.title?.slice(0, 20) + ".mp4",
mimeType: videoData?.videoType || '"video/mp4',
}}
title={videoData?.filename || videoData?.title?.slice(0, 20)}
customStyles={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
{" "}
<Box>
<StyledCardHeaderComment
sx={{
"& .MuiCardHeader-content": {
overflow: "hidden",
},
}}
>
<DownloadIcon />
</FileElement>
</FileAttachmentContainer>
<Box
sx={{
cursor: "pointer",
}}
onClick={() => {
navigate(`/channel/${name}`);
}}
>
<Avatar
src={`/arbitrary/THUMBNAIL/${name}/qortal_avatar`}
alt={`${name}'s avatar`}
/>
</Box>
<StyledCardColComment>
<AuthorTextComment
color={
theme.palette.mode === "light"
? theme.palette.text.secondary
: "#d6e8ff"
}
sx={{
cursor: "pointer",
}}
onClick={() => {
navigate(`/channel/${name}`);
}}
>
{name}
<SubscribeButton
name={name}
sx={{ marginLeft: "20px" }}
/>
</AuthorTextComment>
</StyledCardColComment>
</StyledCardHeaderComment>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "row",
}}
>
{videoData && (
<SuperLike
numberOfSuperlikes={numberOfSuperlikes}
totalAmount={calculateAmountSuperlike}
name={videoData?.user}
service={videoData?.service}
identifier={videoData?.id}
onSuccess={val => {
setSuperlikelist(prev => [val, ...prev]);
}}
/>
)}
<FileAttachmentContainer>
<FileAttachmentFont>Save to Disk</FileAttachmentFont>
<FileElement
fileInfo={{
...videoReference,
filename:
videoData?.filename ||
videoData?.title?.slice(0, 20) + ".mp4",
mimeType: videoData?.videoType || '"video/mp4',
}}
title={
videoData?.filename || videoData?.title?.slice(0, 20)
}
customStyles={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
}}
>
<DownloadIcon />
</FileElement>
</FileAttachmentContainer>
</Box>
</Box>
<Box
sx={{
@ -484,25 +564,13 @@ export const PlaylistContent = () => {
>
{videoData?.title}
</VideoTitle>
{videoData && (
<SuperLike
numberOfSuperlikes={numberOfSuperlikes}
totalAmount={calculateAmountSuperlike}
name={videoData?.user}
service={videoData?.service}
identifier={videoData?.id}
onSuccess={val => {
setSuperlikelist(prev => [val, ...prev]);
}}
/>
)}
</Box>
{videoData?.created && (
<Typography
variant="h6"
sx={{
fontSize: "12px",
fontSize: "16px",
}}
color={theme.palette.text.primary}
>
@ -510,42 +578,7 @@ export const PlaylistContent = () => {
</Typography>
)}
<Spacer height="15px" />
<Box
sx={{
cursor: "pointer",
}}
onClick={() => {
navigate(`/channel/${name}`);
}}
>
<StyledCardHeaderComment
sx={{
"& .MuiCardHeader-content": {
overflow: "hidden",
},
}}
>
<Box>
<Avatar
src={`/arbitrary/THUMBNAIL/${name}/qortal_avatar`}
alt={`${name}'s avatar`}
/>
</Box>
<StyledCardColComment>
<AuthorTextComment
color={
theme.palette.mode === "light"
? theme.palette.text.secondary
: "#d6e8ff"
}
>
{name}
</AuthorTextComment>
</StyledCardColComment>
</StyledCardHeaderComment>
</Box>
<Spacer height="15px" />
<Spacer height="30px" />
<Box
sx={{
background: "#333333",
@ -555,16 +588,16 @@ export const PlaylistContent = () => {
cursor: !descriptionHeight
? "default"
: isExpandedDescription
? "default"
: "pointer",
? "default"
: "pointer",
position: "relative",
}}
className={
!descriptionHeight
? ""
: isExpandedDescription
? ""
: "hover-click"
? ""
: "hover-click"
}
>
{descriptionHeight && !isExpandedDescription && (
@ -589,8 +622,8 @@ export const PlaylistContent = () => {
height: !descriptionHeight
? "auto"
: isExpandedDescription
? "auto"
: "100px",
? "auto"
: "100px",
overflow: "hidden",
}}
>
@ -644,13 +677,6 @@ export const PlaylistContent = () => {
}}
>
<CommentSection postId={videoData?.id || ""} postName={name || ""} />
{playlistData && (
<Playlists
playlistData={playlistData}
currentVideoIdentifier={videoData?.id}
onClick={getVideoData}
/>
)}
</Box>
</Box>
);

View File

@ -2,19 +2,18 @@ import { styled } from "@mui/system";
import { Box, Grid, Typography, Checkbox } from "@mui/material";
export const VideoPlayerContainer = styled(Box)(({ theme }) => ({
maxWidth: '95%',
width: '1000px',
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
maxWidth: "95%",
width: "1000px",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
}));
export const VideoTitle = styled(Typography)(({ theme }) => ({
fontFamily: "Raleway",
fontSize: "20px",
color: theme.palette.text.primary,
userSelect: "none",
wordBreak: "break-word"
wordBreak: "break-word",
}));
export const VideoDescription = styled(Typography)(({ theme }) => ({
@ -22,60 +21,63 @@ export const VideoDescription = styled(Typography)(({ theme }) => ({
fontSize: "16px",
color: theme.palette.text.primary,
userSelect: "none",
wordBreak: "break-word"
wordBreak: "break-word",
}));
export const Spacer = ({height}: any)=> {
return <Box sx={{
height: height
}} />
}
export const Spacer = ({ height }: any) => {
return (
<Box
sx={{
height: height,
}}
/>
);
};
export const StyledCardHeaderComment = styled(Box)({
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-start',
gap: '5px',
padding: '7px 0px'
})
export const StyledCardCol = styled(Box)({
display: 'flex',
overflow: 'hidden',
flexDirection: 'column',
gap: '2px',
alignItems: 'flex-start',
width: '100%'
})
export const StyledCardColComment = styled(Box)({
display: 'flex',
overflow: 'hidden',
flexDirection: 'column',
gap: '2px',
alignItems: 'flex-start',
width: '100%'
})
export const AuthorTextComment = styled(Typography)({
fontFamily: 'Raleway, sans-serif',
fontSize: '16px',
lineHeight: '1.2'
})
export const FileAttachmentContainer = styled(Box)(({ theme }) =>({
display: "flex",
alignItems: "center",
gap: "20px",
justifyContent: "flex-start",
gap: "5px",
padding: "7px 0px",
});
export const StyledCardCol = styled(Box)({
display: "flex",
overflow: "hidden",
flexDirection: "column",
gap: "2px",
alignItems: "flex-start",
width: "100%",
});
export const StyledCardColComment = styled(Box)({
display: "flex",
overflow: "hidden",
flexDirection: "column",
gap: "2px",
alignItems: "flex-start",
});
export const AuthorTextComment = styled(Typography)({
fontFamily: "Raleway, sans-serif",
fontSize: "20px",
lineHeight: "1.2",
});
export const FileAttachmentContainer = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
padding: "5px 10px",
border: `1px solid ${theme.palette.text.primary}`,
width: "350px",
}));
export const FileAttachmentFont = styled(Typography)(({ theme }) => ({
fontFamily: "Mulish",
color: theme.palette.text.primary,
fontSize: "16px",
fontSize: "20px",
letterSpacing: 0,
fontWeight: 400,
userSelect: "none",
whiteSpace: 'nowrap'
}));
whiteSpace: "nowrap",
}));

View File

@ -53,6 +53,7 @@ import {
SUPER_LIKE_BASE,
} from "../../constants/Identifiers.ts";
import { minPriceSuperlike } from "../../constants/Misc.ts";
import { SubscribeButton } from "../../components/common/SubscribeButton.tsx";
export function isTimestampWithinRange(resTimestamp, resCreated) {
// Calculate the absolute difference in milliseconds
@ -171,11 +172,9 @@ export const VideoContent = () => {
const [videoData, setVideoData] = useState<any>(null);
const saveAsFilename = useMemo(() => {
// nb. we prefer to construct the local filename to use for
// saving, from the video "title" when possible
if (videoData?.title) {
// figure out filename extension
let ext = ".mp4";
if (videoData?.filename) {
@ -197,9 +196,7 @@ export const VideoContent = () => {
// TODO: this was the previous value, leaving here as the
// fallback for now even though it probably is not needed..?
return videoData?.filename ||
videoData?.title?.slice(0, 20) + ".mp4";
return videoData?.filename || videoData?.title?.slice(0, 20) + ".mp4";
}, [videoData]);
const hashMapVideos = useSelector(
@ -280,7 +277,7 @@ export const VideoContent = () => {
React.useEffect(() => {
if (name && id) {
const existingVideo = hashMapVideos[id + '-' + name];
const existingVideo = hashMapVideos[id + "-" + name];
if (existingVideo) {
setVideoData(existingVideo);
@ -376,6 +373,8 @@ export const VideoContent = () => {
<VideoPlayerContainer
sx={{
marginBottom: "30px",
width: "70vw",
height: "70vw",
}}
>
{videoReference && (
@ -393,30 +392,89 @@ export const VideoContent = () => {
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "flex-end",
display: "grid",
gridTemplateColumns: "1fr 1fr",
}}
>
<FileAttachmentContainer>
<FileAttachmentFont>save to disk</FileAttachmentFont>
<FileElement
fileInfo={{
...videoReference,
filename: saveAsFilename,
mimeType: videoData?.videoType || '"video/mp4',
}}
title={videoData?.filename || videoData?.title?.slice(0, 20)}
customStyles={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
<Box>
<StyledCardHeaderComment
sx={{
"& .MuiCardHeader-content": {
overflow: "hidden",
},
}}
>
<DownloadIcon />
</FileElement>
</FileAttachmentContainer>
<Box
sx={{
cursor: "pointer",
}}
onClick={() => {
navigate(`/channel/${name}`);
}}
>
<Avatar
src={`/arbitrary/THUMBNAIL/${name}/qortal_avatar`}
alt={`${name}'s avatar`}
/>
</Box>
<StyledCardColComment>
<AuthorTextComment
color={
theme.palette.mode === "light"
? theme.palette.text.secondary
: "#d6e8ff"
}
sx={{
cursor: "pointer",
}}
onClick={() => {
navigate(`/channel/${name}`);
}}
>
{name}
<SubscribeButton name={name} sx={{ marginLeft: "20px" }} />
</AuthorTextComment>
</StyledCardColComment>
</StyledCardHeaderComment>
</Box>
<Box
sx={{
display: "flex",
flexDirection: "row",
}}
>
{videoData && (
<SuperLike
numberOfSuperlikes={numberOfSuperlikes}
totalAmount={calculateAmountSuperlike}
name={videoData?.user}
service={videoData?.service}
identifier={videoData?.id}
onSuccess={val => {
setSuperlikelist(prev => [val, ...prev]);
}}
/>
)}
<FileAttachmentContainer>
<FileAttachmentFont>Save to Disk</FileAttachmentFont>
<FileElement
fileInfo={{
...videoReference,
filename: saveAsFilename,
mimeType: videoData?.videoType || '"video/mp4',
}}
title={videoData?.filename || videoData?.title?.slice(0, 20)}
customStyles={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
}}
>
<DownloadIcon />
</FileElement>
</FileAttachmentContainer>
</Box>
</Box>
<Box
sx={{
display: "flex",
@ -436,25 +494,13 @@ export const VideoContent = () => {
>
{videoData?.title}
</VideoTitle>
{videoData && (
<SuperLike
numberOfSuperlikes={numberOfSuperlikes}
totalAmount={calculateAmountSuperlike}
name={videoData?.user}
service={videoData?.service}
identifier={videoData?.id}
onSuccess={val => {
setSuperlikelist(prev => [val, ...prev]);
}}
/>
)}
</Box>
{videoData?.created && (
<Typography
variant="h6"
sx={{
fontSize: "12px",
fontSize: "16px",
}}
color={theme.palette.text.primary}
>
@ -462,42 +508,7 @@ export const VideoContent = () => {
</Typography>
)}
<Spacer height="15px" />
<Box
sx={{
cursor: "pointer",
}}
onClick={() => {
navigate(`/channel/${name}`);
}}
>
<StyledCardHeaderComment
sx={{
"& .MuiCardHeader-content": {
overflow: "hidden",
},
}}
>
<Box>
<Avatar
src={`/arbitrary/THUMBNAIL/${name}/qortal_avatar`}
alt={`${name}'s avatar`}
/>
</Box>
<StyledCardColComment>
<AuthorTextComment
color={
theme.palette.mode === "light"
? theme.palette.text.secondary
: "#d6e8ff"
}
>
{name}
</AuthorTextComment>
</StyledCardColComment>
</StyledCardHeaderComment>
</Box>
<Spacer height="15px" />
<Spacer height="30px" />
<Box
sx={{
background: "#333333",
@ -507,8 +518,8 @@ export const VideoContent = () => {
cursor: !descriptionHeight
? "default"
: isExpandedDescription
? "default"
: "pointer",
? "default"
: "pointer",
position: "relative",
}}
className={
@ -537,8 +548,8 @@ export const VideoContent = () => {
height: !descriptionHeight
? "auto"
: isExpandedDescription
? "auto"
: "100px",
? "auto"
: "100px",
overflow: "hidden",
}}
>