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

Fixed video skeleton not loading bug.

Deleted videos are not filtered out. They are now visible and show an image on the Home, Channel, and VideoContent pages that says "This video has been removed by the user".

Fixed minification bug caused by store.ts

titleFormatter and titleFormatterOnSave redone, only characters not allowed by Operating Systems are filtered out when saving as file.
This commit is contained in:
Qortal Dev 2024-07-08 17:09:18 -06:00
parent 7bd0946976
commit 6412417891
8 changed files with 77 additions and 68 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,14 +1,14 @@
import React, { useState, useEffect, CSSProperties } from 'react'
import Skeleton from '@mui/material/Skeleton'
import { Box } from '@mui/material'
import React, { useState, useEffect, CSSProperties } from "react";
import Skeleton from "@mui/material/Skeleton";
import { Box } from "@mui/material";
import DeletedVideo from "../assets/img/DeletedVideo.jpg";
interface ResponsiveImageProps {
src: string
width: number
height: number
alt?: string
className?: string
style?: CSSProperties
src: string;
width: number;
height: number;
alt?: string;
className?: string;
style?: CSSProperties;
}
const ResponsiveImage: React.FC<ResponsiveImageProps> = ({
@ -17,49 +17,55 @@ const ResponsiveImage: React.FC<ResponsiveImageProps> = ({
height,
alt,
className,
style
style,
}) => {
const [loading, setLoading] = useState(true)
const [loading, setLoading] = useState(true);
const endLoading = (endTimeSeconds: number) => {
const endTimeMilliSeconds = endTimeSeconds * 1000;
setTimeout(() => {
if (loading) setLoading(false);
}, endTimeMilliSeconds);
};
useEffect(() => endLoading(5), []);
return (
<Box
sx={{
padding: '2px',
height: '100%',
...style
padding: "2px",
height: "100%",
...style,
}}
>
{loading && (
<Skeleton
variant="rectangular"
style={{
width: '100%',
width: "100%",
height: 0,
paddingBottom: `${(height / width) * 100}%`,
objectFit: 'contain',
visibility: loading ? 'visible' : 'hidden',
borderRadius: '8px'
objectFit: "contain",
visibility: loading ? "visible" : "hidden",
borderRadius: "8px",
}}
/>
)}
<img
onLoad={() => setLoading(false)}
src={src}
src={!src && !loading ? DeletedVideo : src}
style={{
width: '100%',
height: '100%',
borderRadius: '8px',
visibility: loading ? 'hidden' : 'visible',
position: loading ? 'absolute' : 'unset',
objectFit: 'contain'
width: "100%",
height: "100%",
borderRadius: "8px",
visibility: loading ? "hidden" : "visible",
position: loading ? "absolute" : "unset",
objectFit: "contain",
}}
/>
</Box>
)
}
);
};
export default ResponsiveImage
export default ResponsiveImage;

View File

@ -181,18 +181,17 @@ export const CommentEditor = ({
notificationInformation: comment.notificationInformation,
about: comment.about,
};
const superLikeToFile = await objectToFile(superObj);
const superLikeToFile = objectToFile(superObj);
dataFile = superLikeToFile;
}
if (isSuperLike && !dataFile)
throw new Error("unable to edit Super like");
const stringFile = stringToFile(value);
const resourceResponse = await qortalRequest({
action: "PUBLISH_QDN_RESOURCE",
name: name,
service: "BLOG_COMMENT",
file: isSuperLike ? dataFile : stringFile,
file: isSuperLike ? dataFile : stringToFile(value),
identifier: identifier,
description,
tag1,

View File

@ -1,6 +1,7 @@
export const minPriceSuperlike = 1;
export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.;:|—~@#$%^*+=<>]/g;
export const titleFormatterOnSave = /[^a-zA-Z0-9\s-_!()&',.;—~@#$%^+=]/g;
export const titleFormatter = /[\r\n]+/g;
export const titleFormatterOnSave = /[\r\n/<>:"'\\*|?]+/g;
export const videoMaxSize = 400; // Size in Megabytes (decimal)
export const maxSize = videoMaxSize *1024*1024
export const maxSize = videoMaxSize * 1024 * 1024;

View File

@ -7,6 +7,7 @@ import React, {
} from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
import ResponsiveImage from "../../../components/ResponsiveImage.tsx";
import { setIsLoadingGlobal } from "../../../state/features/globalSlice.ts";
import { Avatar, Box, Typography, useTheme } from "@mui/material";
import {
@ -17,6 +18,7 @@ import { RootState } from "../../../state/store.ts";
import { addToHashMap } from "../../../state/features/videoSlice.ts";
import AttachFileIcon from "@mui/icons-material/AttachFile";
import DownloadIcon from "@mui/icons-material/Download";
import DeletedVideo from "../../../assets/img/DeletedVideo.jpg";
import mockImg from "../../../test/mockimg.jpg";
import {
@ -403,7 +405,7 @@ export const VideoContent = () => {
width: "70vw",
}}
>
{videoReference && (
{videoReference ? (
<VideoPlayer
name={videoReference?.name}
service={videoReference?.service}
@ -414,6 +416,8 @@ export const VideoContent = () => {
customStyle={{ aspectRatio: "16/9" }}
ref={containerRef}
/>
) : (
<img src={DeletedVideo} width={"100%"} height={"100%"} />
)}
<Box
sx={{
@ -630,6 +634,7 @@ export const VideoContent = () => {
</Box>
</VideoPlayerContainer>
<SuperLikesSection
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
getMore={() => {}}
loadingSuperLikes={loadingSuperLikes}
superlikes={superlikeList}

View File

@ -6,7 +6,12 @@ import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { PlaylistSVG } from "../../assets/svgs/PlaylistSVG.tsx";
import ResponsiveImage from "../../components/ResponsiveImage.tsx";
import { blockUser, setEditPlaylist, setEditVideo, Video } from "../../state/features/videoSlice.ts";
import {
blockUser,
setEditPlaylist,
setEditVideo,
Video,
} from "../../state/features/videoSlice.ts";
import { RootState } from "../../state/store.ts";
import { formatDate } from "../../utils/time.ts";
import { VideoCardImageContainer } from "./VideoCardImageContainer.tsx";
@ -55,16 +60,14 @@ export const VideoList = ({ videos }: VideoListProps) => {
if (response === true) {
dispatch(blockUser(user));
}
} catch (error) {console.log(error)}
} catch (error) {
console.log(error);
}
};
const filteredVideos = useMemo(() => {
return videos.filter((video: Video) => hashMapVideos[`${video.id}-${video.user}`]?.isValid);
}, [videos, hashMapVideos]);
return (
<VideoCardContainer>
{filteredVideos.map((video: any) => {
{videos.map((video: any) => {
const fullId = video ? `${video.id}-${video.user}` : undefined;
const existingVideo = hashMapVideos[fullId];
let hasHash = false;
@ -244,11 +247,6 @@ export const VideoList = ({ videos }: VideoListProps) => {
videoImage={videoObj.videoImage}
frameImages={videoObj?.extracts || []}
/>
{/* <ResponsiveImage
src={videoObj.videoImage}
width={266}
height={150}
/> */}
<VideoCardTitle>{videoObj.title}</VideoCardTitle>
<BottomParent>
<NameContainer

View File

@ -1,3 +1,4 @@
/* eslint-disable */
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import notificationsReducer from "./features/notificationsSlice";
import authReducer from "./features/authSlice";

View File

@ -1,36 +1,35 @@
import { checkStructure } from './checkStructure'
import { checkStructure } from "./checkStructure";
export const fetchAndEvaluateVideos = async (data: any) => {
const getVideo = async () => {
const { user, videoId, content } = data
const { user, videoId, content } = data;
let obj: any = {
...content,
isValid: false
}
};
if (!user || !videoId) return obj
if (!user || !videoId) return obj;
try {
const responseData = await qortalRequest({
action: 'FETCH_QDN_RESOURCE',
action: "FETCH_QDN_RESOURCE",
name: user,
service: content?.service || 'DOCUMENT',
identifier: videoId
})
service: content?.service || "DOCUMENT",
identifier: videoId,
});
if (responseData) {
obj = {
...content,
...responseData,
isValid: true
}
isValid: true,
isDeleted: false,
};
}
return obj
return obj;
} catch (error: any) {
throw new Error(error?.message || 'error')
throw new Error(error?.message || "error");
}
}
};
const res = await getVideo()
return res
}
const res = await getVideo();
return res;
};