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

Superlike Icon button is less verbose, shows more info with icons instead of words

Videoplayer is much bigger, playlist is next to it instead of below

Video publisher name, icon, etc. moved to same row as superlike, file downloader

Titles can be selected/copied

Changed structure of ListSuperLikes.tsx slightly to fix undesirable warnings involving list keys and <div> being descendent of <p>

SubscribeButton.tsx created, but not fully implemented
This commit is contained in:
Qortal Dev 2024-01-23 17:31:50 -07:00
parent 55535d7c86
commit 6b1c18fd7d
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",
}}
>