Browse Source

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
pull/7/head
Qortal Dev 8 months ago
parent
commit
6b1c18fd7d
  1. 22
      package-lock.json
  2. 1
      package.json
  3. 27
      src/assets/svgs/DownloadingLight.tsx
  4. 14
      src/components/Playlists/Playlists.tsx
  5. 19
      src/components/common/ListSuperLikes/LiskSuperLikeContainer.tsx
  6. 25
      src/components/common/ListSuperLikes/ListSuperLikeContainer.tsx
  7. 113
      src/components/common/ListSuperLikes/ListSuperLikes.tsx
  8. 39
      src/components/common/SubscribeButton.tsx
  9. 44
      src/components/common/SuperLike/SuperLike.tsx
  10. 855
      src/components/common/VideoPlayer.tsx
  11. 4
      src/constants/Misc.ts
  12. 164
      src/pages/Home/VideoList-styles.tsx
  13. 19
      src/pages/Home/VideoList.tsx
  14. 3
      src/pages/IndividualProfile/IndividualProfile.tsx
  15. 84
      src/pages/PlaylistContent/PlaylistContent-styles.tsx
  16. 220
      src/pages/PlaylistContent/PlaylistContent.tsx
  17. 86
      src/pages/VideoContent/VideoContent-styles.tsx
  18. 167
      src/pages/VideoContent/VideoContent.tsx

22
package-lock.json generated

@ -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",

1
package.json

@ -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"
}

27
src/assets/svgs/DownloadingLight.tsx

@ -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>
);
};

14
src/components/Playlists/Playlists.tsx

@ -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}

19
src/components/common/ListSuperLikes/LiskSuperLikeContainer.tsx

@ -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>
)
}

25
src/components/common/ListSuperLikes/ListSuperLikeContainer.tsx

@ -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>
);
};

113
src/components/common/ListSuperLikes/ListSuperLikes.tsx

@ -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>

39
src/components/common/SubscribeButton.tsx

@ -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>
);
};

44
src/components/common/SuperLike/SuperLike.tsx

@ -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>

855
src/components/common/VideoPlayer.tsx

File diff suppressed because it is too large Load Diff

4
src/constants/Misc.ts

@ -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;

164
src/pages/Home/VideoList-styles.tsx

@ -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)",
}
})
},
});

19
src/pages/Home/VideoList.tsx

@ -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>
);

3
src/pages/IndividualProfile/IndividualProfile.tsx

@ -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>

84
src/pages/PlaylistContent/PlaylistContent-styles.tsx

@ -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",
}));

220
src/pages/PlaylistContent/PlaylistContent.tsx

@ -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>
);

86
src/pages/VideoContent/VideoContent-styles.tsx

@ -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'
})
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",
});
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",
}));

167
src/pages/VideoContent/VideoContent.tsx

@ -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",
}}
>

Loading…
Cancel
Save