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:
parent
7bd0946976
commit
6412417891
BIN
src/assets/img/DeletedVideo.jpg
Normal file
BIN
src/assets/img/DeletedVideo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable */
|
||||
import { combineReducers, configureStore } from "@reduxjs/toolkit";
|
||||
import notificationsReducer from "./features/notificationsSlice";
|
||||
import authReducer from "./features/authSlice";
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user