mirror of
https://github.com/Qortal/q-share.git
synced 2025-01-30 14:52:20 +00:00
Merge pull request #1 from QortalSeth/main
Publish Title TextField allows more characters are allowed than before
This commit is contained in:
commit
fa0a1dc16a
@ -1,17 +1,10 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {
|
||||
AddCoverImageButton,
|
||||
AddLogoIcon,
|
||||
CoverImagePreview,
|
||||
CrowdfundActionButton,
|
||||
CrowdfundActionButtonRow,
|
||||
CustomInputField,
|
||||
CustomSelect,
|
||||
LogoPreviewRow,
|
||||
ModalBody,
|
||||
NewCrowdfundTitle,
|
||||
StyledButton,
|
||||
TimesIcon,
|
||||
} from "./Upload-styles";
|
||||
import {
|
||||
Box,
|
||||
@ -28,27 +21,19 @@ import {
|
||||
import RemoveIcon from "@mui/icons-material/Remove";
|
||||
|
||||
import ShortUniqueId from "short-unique-id";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import AddBoxIcon from "@mui/icons-material/AddBox";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {useDropzone} from "react-dropzone";
|
||||
|
||||
import { setNotification } from "../../state/features/notificationsSlice";
|
||||
import { objectToBase64, uint8ArrayToBase64 } from "../../utils/toBase64";
|
||||
import { RootState } from "../../state/store";
|
||||
import {
|
||||
upsertVideosBeginning,
|
||||
addToHashMap,
|
||||
upsertVideos,
|
||||
setEditVideo,
|
||||
updateVideo,
|
||||
updateInHashMap,
|
||||
} from "../../state/features/videoSlice";
|
||||
import ImageUploader from "../common/ImageUploader";
|
||||
import { QTUBE_VIDEO_BASE, categories, subCategories, subCategories2,
|
||||
subCategories3, } from "../../constants";
|
||||
import { MultiplePublish } from "../common/MultiplePublish/MultiplePublish";
|
||||
import { TextEditor } from "../common/TextEditor/TextEditor";
|
||||
import { extractTextFromHTML } from "../common/TextEditor/utils";
|
||||
import {setNotification} from "../../state/features/notificationsSlice";
|
||||
import {objectToBase64} from "../../utils/toBase64";
|
||||
import {RootState} from "../../state/store";
|
||||
import {setEditVideo, updateInHashMap, updateVideo,} from "../../state/features/videoSlice";
|
||||
import {QSHARE_FILE_BASE,} from "../../constants/Identifiers.ts";
|
||||
import {MultiplePublish} from "../common/MultiplePublish/MultiplePublishAll";
|
||||
import {TextEditor} from "../common/TextEditor/TextEditor";
|
||||
import {extractTextFromHTML} from "../common/TextEditor/utils";
|
||||
import {categories, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
|
||||
import {titleFormatter} from "../../constants/Misc.ts";
|
||||
|
||||
const uid = new ShortUniqueId();
|
||||
const shortuid = new ShortUniqueId({ length: 5 });
|
||||
@ -70,7 +55,7 @@ interface VideoFile {
|
||||
identifier?:string;
|
||||
filename?:string
|
||||
}
|
||||
export const EditVideo = () => {
|
||||
export const EditFile = () => {
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const username = useSelector((state: RootState) => state.auth?.user?.name);
|
||||
@ -80,7 +65,7 @@ export const EditVideo = () => {
|
||||
const editVideoProperties = useSelector(
|
||||
(state: RootState) => state.video.editVideoProperties
|
||||
);
|
||||
const [publishes, setPublishes] = useState<any[]>([]);
|
||||
const [publishes, setPublishes] = useState<any>(null);
|
||||
const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false);
|
||||
const [videoPropertiesToSetToRedux, setVideoPropertiesToSetToRedux] =
|
||||
useState(null);
|
||||
@ -302,7 +287,7 @@ export const EditVideo = () => {
|
||||
const file = publish.file;
|
||||
const id = uid();
|
||||
|
||||
const identifier = `${QTUBE_VIDEO_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
|
||||
const identifier = `${QSHARE_FILE_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
|
||||
|
||||
|
||||
|
||||
@ -347,7 +332,7 @@ export const EditVideo = () => {
|
||||
description: metadescription,
|
||||
identifier,
|
||||
filename,
|
||||
tag1: QTUBE_VIDEO_BASE,
|
||||
tag1: QSHARE_FILE_BASE,
|
||||
};
|
||||
listOfPublishes.push(requestBodyVideo);
|
||||
fileReferences.push({
|
||||
@ -388,12 +373,16 @@ export const EditVideo = () => {
|
||||
title: title.slice(0, 50),
|
||||
description: metadescription,
|
||||
identifier: editVideoProperties.id,
|
||||
tag1: QTUBE_VIDEO_BASE,
|
||||
tag1: QSHARE_FILE_BASE,
|
||||
filename: `video_metadata.json`,
|
||||
};
|
||||
listOfPublishes.push(requestBodyJson);
|
||||
|
||||
setPublishes(listOfPublishes);
|
||||
const multiplePublish = {
|
||||
action: "PUBLISH_MULTIPLE_QDN_RESOURCES",
|
||||
resources: [...listOfPublishes],
|
||||
};
|
||||
setPublishes(multiplePublish);
|
||||
setIsOpenMultiplePublish(true);
|
||||
setVideoPropertiesToSetToRedux({
|
||||
...editVideoProperties,
|
||||
@ -686,10 +675,7 @@ export const EditVideo = () => {
|
||||
value={title}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
const formattedValue = value.replace(
|
||||
/[^a-zA-Z0-9\s-_!?]/g,
|
||||
""
|
||||
);
|
||||
const formattedValue = value.replace(titleFormatter, "");
|
||||
setTitle(formattedValue);
|
||||
}}
|
||||
inputProps={{ maxLength: 180 }}
|
||||
@ -744,6 +730,18 @@ export const EditVideo = () => {
|
||||
{isOpenMultiplePublish && (
|
||||
<MultiplePublish
|
||||
isOpen={isOpenMultiplePublish}
|
||||
onError={(messageNotification)=> {
|
||||
setIsOpenMultiplePublish(false);
|
||||
setPublishes(null)
|
||||
if(messageNotification){
|
||||
dispatch(
|
||||
setNotification({
|
||||
msg: messageNotification,
|
||||
alertType: 'error'
|
||||
})
|
||||
)
|
||||
}
|
||||
}}
|
||||
onSubmit={() => {
|
||||
setIsOpenMultiplePublish(false);
|
||||
const clonedCopy = structuredClone(videoPropertiesToSetToRedux);
|
@ -12,7 +12,7 @@ import {
|
||||
NewCrowdfundTitle,
|
||||
StyledButton,
|
||||
TimesIcon,
|
||||
} from "./Upload-styles";
|
||||
} from "./Upload-styles.tsx";
|
||||
import {
|
||||
Box,
|
||||
FormControl,
|
||||
@ -43,11 +43,12 @@ import {
|
||||
setEditPlaylist,
|
||||
} from "../../state/features/videoSlice";
|
||||
import ImageUploader from "../common/ImageUploader";
|
||||
import { QTUBE_PLAYLIST_BASE, QTUBE_VIDEO_BASE, categories, subCategories } from "../../constants";
|
||||
import { QSHARE_PLAYLIST_BASE, QSHARE_FILE_BASE } from "../../constants/Identifiers.ts";
|
||||
import { Playlists } from "../Playlists/Playlists";
|
||||
import { PlaylistListEdit } from "../PlaylistListEdit/PlaylistListEdit";
|
||||
import { TextEditor } from "../common/TextEditor/TextEditor";
|
||||
import { extractTextFromHTML } from "../common/TextEditor/utils";
|
||||
import {categories, subCategories} from "../../constants/Categories.ts";
|
||||
|
||||
const uid = new ShortUniqueId();
|
||||
const shortuid = new ShortUniqueId({ length: 5 });
|
||||
@ -289,7 +290,7 @@ export const EditPlaylist = () => {
|
||||
let commentsId = editVideoProperties?.id
|
||||
|
||||
if(isNew){
|
||||
commentsId = `${QTUBE_PLAYLIST_BASE}_cm_${id}`
|
||||
commentsId = `${QSHARE_PLAYLIST_BASE}_cm_${id}`
|
||||
}
|
||||
const stringDescription = extractTextFromHTML(description)
|
||||
|
||||
@ -322,7 +323,7 @@ export const EditPlaylist = () => {
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
if(isNew){
|
||||
identifier = `${QTUBE_PLAYLIST_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
|
||||
identifier = `${QSHARE_PLAYLIST_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
|
||||
}
|
||||
const requestBodyJson: any = {
|
||||
action: "PUBLISH_QDN_RESOURCE",
|
||||
@ -332,7 +333,7 @@ export const EditPlaylist = () => {
|
||||
title: title.slice(0, 50),
|
||||
description: metadescription,
|
||||
identifier: identifier,
|
||||
tag1: QTUBE_VIDEO_BASE,
|
||||
tag1: QSHARE_FILE_BASE,
|
||||
};
|
||||
|
||||
await qortalRequest(requestBodyJson);
|
||||
|
@ -3,13 +3,13 @@ import { CardContentContainerComment } from "../common/Comments/Comments-styles"
|
||||
import {
|
||||
CrowdfundSubTitle,
|
||||
CrowdfundSubTitleRow,
|
||||
} from "../UploadVideo/Upload-styles";
|
||||
} from "../PublishFile/Upload-styles.tsx";
|
||||
import { Box, Button, Input, Typography, useTheme } from "@mui/material";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
|
||||
import { removeVideo } from "../../state/features/videoSlice";
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import { QTUBE_VIDEO_BASE } from "../../constants";
|
||||
import { QSHARE_FILE_BASE } from "../../constants/Identifiers.ts";
|
||||
import { useSelector } from "react-redux";
|
||||
import { RootState } from "../../state/store";
|
||||
export const PlaylistListEdit = ({ playlistData, removeVideo, addVideo }) => {
|
||||
@ -21,7 +21,7 @@ export const PlaylistListEdit = ({ playlistData, removeVideo, addVideo }) => {
|
||||
const [filterSearch, setFilterSearch] = useState("")
|
||||
const search = async()=> {
|
||||
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&mode=ALL&identifier=${QTUBE_VIDEO_BASE}&title=${filterSearch}&limit=20&includemetadata=true&reverse=true&name=${username}&exactmatchnames=true&offset=0`
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&mode=ALL&identifier=${QSHARE_FILE_BASE}&title=${filterSearch}&limit=20&includemetadata=true&reverse=true&name=${username}&exactmatchnames=true&offset=0`
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { CardContentContainerComment } from '../common/Comments/Comments-styles'
|
||||
import { CrowdfundSubTitle, CrowdfundSubTitleRow } from '../UploadVideo/Upload-styles'
|
||||
import { CrowdfundSubTitle, CrowdfundSubTitleRow } from '../PublishFile/Upload-styles.tsx'
|
||||
import { Box, Typography, useTheme } from '@mui/material'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
|
@ -44,21 +44,23 @@ import {
|
||||
} from "../../state/features/videoSlice";
|
||||
import ImageUploader from "../common/ImageUploader";
|
||||
import {
|
||||
QTUBE_PLAYLIST_BASE,
|
||||
QTUBE_VIDEO_BASE,
|
||||
categories,
|
||||
subCategories,
|
||||
subCategories2,
|
||||
subCategories3,
|
||||
} from "../../constants";
|
||||
import { MultiplePublish } from "../common/MultiplePublish/MultiplePublish";
|
||||
QSHARE_PLAYLIST_BASE,
|
||||
QSHARE_FILE_BASE,
|
||||
|
||||
|
||||
|
||||
|
||||
} from "../../constants/Identifiers.ts";
|
||||
import { MultiplePublish } from "../common/MultiplePublish/MultiplePublishAll";
|
||||
import {
|
||||
CrowdfundSubTitle,
|
||||
CrowdfundSubTitleRow,
|
||||
} from "../EditPlaylist/Upload-styles";
|
||||
} from "../EditPlaylist/Upload-styles.tsx";
|
||||
import { CardContentContainerComment } from "../common/Comments/Comments-styles";
|
||||
import { TextEditor } from "../common/TextEditor/TextEditor";
|
||||
import { extractTextFromHTML } from "../common/TextEditor/utils";
|
||||
import {categories, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
|
||||
import {titleFormatter} from "../../constants/Misc.ts";
|
||||
|
||||
const uid = new ShortUniqueId();
|
||||
const shortuid = new ShortUniqueId({ length: 5 });
|
||||
@ -78,7 +80,7 @@ interface VideoFile {
|
||||
description: string;
|
||||
coverImage?: string;
|
||||
}
|
||||
export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
export const PublishFile = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false);
|
||||
@ -112,7 +114,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
useState<any>(null);
|
||||
|
||||
const [playlistSetting, setPlaylistSetting] = useState<null | string>(null);
|
||||
const [publishes, setPublishes] = useState<any[]>([]);
|
||||
const [publishes, setPublishes] = useState<any>(null);
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
maxFiles: 10,
|
||||
maxSize: 419430400, // 400 MB in bytes
|
||||
@ -214,7 +216,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
const file = publish.file;
|
||||
const id = uid();
|
||||
|
||||
const identifier = `${QTUBE_VIDEO_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
|
||||
const identifier = `${QSHARE_FILE_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
|
||||
|
||||
|
||||
|
||||
@ -260,7 +262,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
description: metadescription,
|
||||
identifier,
|
||||
filename,
|
||||
tag1: QTUBE_VIDEO_BASE,
|
||||
tag1: QSHARE_FILE_BASE,
|
||||
};
|
||||
listOfPublishes.push(requestBodyVideo);
|
||||
fileReferences.push({
|
||||
@ -274,13 +276,13 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
}
|
||||
|
||||
const idMeta = uid();
|
||||
const identifier = `${QTUBE_VIDEO_BASE}${sanitizeTitle.slice(0, 30)}_${idMeta}`;
|
||||
const identifier = `${QSHARE_FILE_BASE}${sanitizeTitle.slice(0, 30)}_${idMeta}`;
|
||||
const fileObject: any = {
|
||||
title,
|
||||
version: 1,
|
||||
fullDescription,
|
||||
htmlDescription: description,
|
||||
commentsId: `${QTUBE_VIDEO_BASE}_cm_${idMeta}`,
|
||||
commentsId: `${QSHARE_FILE_BASE}_cm_${idMeta}`,
|
||||
category,
|
||||
subcategory,
|
||||
subcategory2,
|
||||
@ -302,12 +304,18 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
title: title.slice(0, 50),
|
||||
description: metadescription,
|
||||
identifier: identifier + "_metadata",
|
||||
tag1: QTUBE_VIDEO_BASE,
|
||||
tag1: QSHARE_FILE_BASE,
|
||||
filename: `video_metadata.json`,
|
||||
};
|
||||
listOfPublishes.push(requestBodyJson);
|
||||
setPublishes(listOfPublishes);
|
||||
|
||||
const multiplePublish = {
|
||||
action: "PUBLISH_MULTIPLE_QDN_RESOURCES",
|
||||
resources: [...listOfPublishes],
|
||||
};
|
||||
setPublishes(multiplePublish);
|
||||
setIsOpenMultiplePublish(true);
|
||||
|
||||
} catch (error: any) {
|
||||
let notificationObj: any = null;
|
||||
if (typeof error === "string") {
|
||||
@ -599,10 +607,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
value={title}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
const formattedValue = value.replace(
|
||||
/[^a-zA-Z0-9\s-_!?]/g,
|
||||
""
|
||||
);
|
||||
const formattedValue = value.replace(titleFormatter, "");
|
||||
setTitle(formattedValue);
|
||||
}}
|
||||
inputProps={{ maxLength: 180 }}
|
||||
@ -659,6 +664,18 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
|
||||
{isOpenMultiplePublish && (
|
||||
<MultiplePublish
|
||||
isOpen={isOpenMultiplePublish}
|
||||
onError={(messageNotification)=> {
|
||||
setIsOpenMultiplePublish(false);
|
||||
setPublishes(null)
|
||||
if(messageNotification){
|
||||
dispatch(
|
||||
setNotification({
|
||||
msg: messageNotification,
|
||||
alertType: 'error'
|
||||
})
|
||||
)
|
||||
}
|
||||
}}
|
||||
onSubmit={() => {
|
||||
setIsOpenMultiplePublish(false);
|
||||
setIsOpen(false);
|
@ -67,9 +67,9 @@ export const ModalBody = styled(Box)(({ theme }) => ({
|
||||
overflowY: "auto",
|
||||
maxHeight: "95vh",
|
||||
boxShadow:
|
||||
theme.palette.mode === "dark"
|
||||
? "0px 4px 5px 0px hsla(0,0%,0%,0.14), 0px 1px 10px 0px hsla(0,0%,0%,0.12), 0px 2px 4px -1px hsla(0,0%,0%,0.2)"
|
||||
: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px",
|
||||
theme.palette.mode === "dark"
|
||||
? "0px 4px 5px 0px hsla(0,0%,0%,0.14), 0px 1px 10px 0px hsla(0,0%,0%,0.12), 0px 2px 4px -1px hsla(0,0%,0%,0.2)"
|
||||
: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px",
|
||||
"&::-webkit-scrollbar-track": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
@ -203,11 +203,11 @@ export const CrowdfundDescription = styled(Typography)(({ theme }) => ({
|
||||
|
||||
export const Spacer = ({ height }: any) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: height,
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
height: height,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@ -314,14 +314,14 @@ export const AddCrowdFundButton = styled(Button)(({ theme }) => ({
|
||||
gap: "8px",
|
||||
color: "#ffffff",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
},
|
||||
}));
|
||||
|
||||
@ -333,14 +333,14 @@ export const EditCrowdFundButton = styled(Button)(({ theme }) => ({
|
||||
gap: "8px",
|
||||
color: "#ffffff",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
transition: "all 0.3s ease-in-out",
|
||||
"&:hover": {
|
||||
cursor: "pointer",
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
theme.palette.mode === "dark" ? theme.palette.primary.dark : "#217e6d",
|
||||
},
|
||||
}));
|
||||
|
||||
@ -584,4 +584,4 @@ export const CustomSelect = styled(Select)(({ theme }) => ({
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
}));
|
||||
}));
|
@ -11,7 +11,7 @@ import {
|
||||
CommentInputContainer,
|
||||
SubmitCommentButton,
|
||||
} from "./Comments-styles";
|
||||
import { COMMENT_BASE } from "../../../constants";
|
||||
import { QSHARE_COMMENT_BASE } from "../../../constants/Identifiers.ts";
|
||||
const uid = new ShortUniqueId();
|
||||
|
||||
const notification = localforage.createInstance({
|
||||
@ -201,13 +201,13 @@ export const CommentEditor = ({
|
||||
try {
|
||||
const id = uid();
|
||||
|
||||
let identifier = `${COMMENT_BASE}${postId.slice(-12)}_base_${id}`;
|
||||
let identifier = `${QSHARE_COMMENT_BASE}${postId.slice(-12)}_base_${id}`;
|
||||
let idForNotification = identifier;
|
||||
|
||||
if (isReply && commentId) {
|
||||
const removeBaseCommentId = commentId;
|
||||
removeBaseCommentId.replace("_base_", "");
|
||||
identifier = `${COMMENT_BASE}${postId.slice(
|
||||
identifier = `${QSHARE_COMMENT_BASE}${postId.slice(
|
||||
-12
|
||||
)}_reply_${removeBaseCommentId.slice(-6)}_${id}`;
|
||||
idForNotification = commentId;
|
||||
|
@ -14,8 +14,8 @@ import {
|
||||
LoadMoreCommentsButtonRow,
|
||||
NoCommentsRow,
|
||||
} from "./Comments-styles";
|
||||
import { COMMENT_BASE } from "../../../constants";
|
||||
import { CrowdfundSubTitle, CrowdfundSubTitleRow } from "../../UploadVideo/Upload-styles";
|
||||
import { QSHARE_COMMENT_BASE } from "../../../constants/Identifiers.ts";
|
||||
import { CrowdfundSubTitle, CrowdfundSubTitleRow } from "../../PublishFile/Upload-styles.tsx";
|
||||
|
||||
interface CommentSectionProps {
|
||||
postId: string;
|
||||
@ -105,7 +105,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
|
||||
const offset = 0;
|
||||
|
||||
const removeBaseCommentId = commentId.replace("_base_", "");
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=BLOG_COMMENT&query=${COMMENT_BASE}${postId.slice(
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=BLOG_COMMENT&query=${QSHARE_COMMENT_BASE}${postId.slice(
|
||||
-12
|
||||
)}_reply_${removeBaseCommentId.slice(
|
||||
-6
|
||||
@ -150,7 +150,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
|
||||
if (isNewMessages && numberOfComments) {
|
||||
offset = numberOfComments;
|
||||
}
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=BLOG_COMMENT&query=${COMMENT_BASE}${postId.slice(
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=BLOG_COMMENT&query=${QSHARE_COMMENT_BASE}${postId.slice(
|
||||
-12
|
||||
)}_base_&limit=20&includemetadata=false&offset=${offset}&reverse=false&excludeblocked=true`;
|
||||
const response = await fetch(url, {
|
||||
|
@ -1,136 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
CircularProgress,
|
||||
Modal,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import React, { useCallback, useEffect, useState, useRef } from "react";
|
||||
import { ModalBody } from "../../UploadVideo/Upload-styles";
|
||||
import { CircleSVG } from "../../../assets/svgs/CircleSVG";
|
||||
import { EmptyCircleSVG } from "../../../assets/svgs/EmptyCircleSVG";
|
||||
|
||||
export const MultiplePublish = ({ publishes, isOpen, onSubmit }) => {
|
||||
const theme = useTheme();
|
||||
const listOfSuccessfulPublishesRef = useRef([])
|
||||
const [listOfSuccessfulPublishes, setListOfSuccessfulPublishes] = useState<
|
||||
any[]
|
||||
>([]);
|
||||
const [currentlyInPublish, setCurrentlyInPublish] = useState(null);
|
||||
const hasStarted = useRef(false);
|
||||
const publish = useCallback(async (pub: any) => {
|
||||
await qortalRequest(pub);
|
||||
}, []);
|
||||
const [isPublishing, setIsPublishing] = useState(true)
|
||||
|
||||
const handlePublish = useCallback(
|
||||
async (pub: any) => {
|
||||
try {
|
||||
setCurrentlyInPublish(pub?.identifier);
|
||||
|
||||
await publish(pub);
|
||||
|
||||
setListOfSuccessfulPublishes((prev: any) => [...prev, pub?.identifier]);
|
||||
listOfSuccessfulPublishesRef.current = [...listOfSuccessfulPublishesRef.current, pub?.identifier]
|
||||
} catch (error) {
|
||||
console.log({ error });
|
||||
await new Promise<void>((res) => {
|
||||
setTimeout(() => {
|
||||
res();
|
||||
}, 5000);
|
||||
});
|
||||
// await handlePublish(pub);
|
||||
}
|
||||
},
|
||||
[publish]
|
||||
);
|
||||
|
||||
const startPublish = useCallback(
|
||||
async (pubs: any) => {
|
||||
setIsPublishing(true)
|
||||
const filterPubs = pubs.filter((pub)=> !listOfSuccessfulPublishesRef.current.includes(pub.identifier))
|
||||
for (const pub of filterPubs) {
|
||||
await handlePublish(pub);
|
||||
|
||||
}
|
||||
|
||||
if(listOfSuccessfulPublishesRef.current.length === pubs.length){
|
||||
onSubmit()
|
||||
}
|
||||
setIsPublishing(false)
|
||||
},
|
||||
[handlePublish, onSubmit, listOfSuccessfulPublishes, publishes]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (publishes && !hasStarted.current) {
|
||||
hasStarted.current = true;
|
||||
startPublish(publishes);
|
||||
}
|
||||
}, [startPublish, publishes, listOfSuccessfulPublishes]);
|
||||
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={isOpen}
|
||||
aria-labelledby="modal-title"
|
||||
aria-describedby="modal-description"
|
||||
>
|
||||
<ModalBody
|
||||
sx={{
|
||||
minHeight: "50vh",
|
||||
}}
|
||||
>
|
||||
{publishes.map((publish: any) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography>{publish?.title}</Typography>
|
||||
{publish?.identifier === currentlyInPublish ? (
|
||||
<CircularProgress
|
||||
size={20}
|
||||
thickness={2}
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
}}
|
||||
/>
|
||||
) : listOfSuccessfulPublishes.includes(publish.identifier) ? (
|
||||
<CircleSVG
|
||||
color={theme.palette.text.primary}
|
||||
height="24px"
|
||||
width="24px"
|
||||
/>
|
||||
) : (
|
||||
<EmptyCircleSVG
|
||||
color={theme.palette.text.primary}
|
||||
height="24px"
|
||||
width="24px"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
{!isPublishing && listOfSuccessfulPublishes.length !== publishes.length && (
|
||||
<>
|
||||
<Typography sx={{
|
||||
marginTop: '20px',
|
||||
fontSize: '16px'
|
||||
}}>Some files were not published. Please try again. It's important that all the files get published. Maybe wait a couple minutes if the error keeps occurring</Typography>
|
||||
<Button onClick={()=> {
|
||||
startPublish(publishes)
|
||||
}}>Try again</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
);
|
||||
};
|
211
src/components/common/MultiplePublish/MultiplePublishAll.tsx
Normal file
211
src/components/common/MultiplePublish/MultiplePublishAll.tsx
Normal file
@ -0,0 +1,211 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
CircularProgress,
|
||||
Modal,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import React, { useCallback, useEffect, useState, useRef } from "react";
|
||||
import { CircleSVG } from "../../../assets/svgs/CircleSVG";
|
||||
import { EmptyCircleSVG } from "../../../assets/svgs/EmptyCircleSVG";
|
||||
import { styled } from "@mui/system";
|
||||
|
||||
interface Publish {
|
||||
resources: any[];
|
||||
action: string;
|
||||
}
|
||||
|
||||
interface MultiplePublishProps {
|
||||
publishes: Publish;
|
||||
isOpen: boolean;
|
||||
onSubmit: ()=> void
|
||||
onError: (message?: string)=> void
|
||||
}
|
||||
export const MultiplePublish = ({ publishes, isOpen, onSubmit, onError}: MultiplePublishProps) => {
|
||||
const theme = useTheme();
|
||||
const listOfSuccessfulPublishesRef = useRef([])
|
||||
const [listOfSuccessfulPublishes, setListOfSuccessfulPublishes] = useState<
|
||||
any[]
|
||||
>([]);
|
||||
const [listOfUnsuccessfulPublishes, setListOfUnSuccessfulPublishes] = useState<
|
||||
any[]
|
||||
>([]);
|
||||
const [currentlyInPublish, setCurrentlyInPublish] = useState(null);
|
||||
const hasStarted = useRef(false);
|
||||
const publish = useCallback(async (pub: any) => {
|
||||
const lengthOfResources = pub?.resources?.length
|
||||
const lengthOfTimeout = lengthOfResources * 30000
|
||||
return await qortalRequestWithTimeout(pub, lengthOfTimeout);
|
||||
}, []);
|
||||
const [isPublishing, setIsPublishing] = useState(true)
|
||||
|
||||
const handlePublish = useCallback(
|
||||
async (pub: any) => {
|
||||
try {
|
||||
setCurrentlyInPublish(pub?.identifier);
|
||||
setIsPublishing(true)
|
||||
const res = await publish(pub);
|
||||
|
||||
onSubmit()
|
||||
setListOfUnSuccessfulPublishes([])
|
||||
|
||||
} catch (error: any) {
|
||||
const unsuccessfulPublishes = error?.error?.unsuccessfulPublishes || []
|
||||
if(error?.error === 'User declined request'){
|
||||
onError()
|
||||
return
|
||||
}
|
||||
|
||||
if(error?.error === 'The request timed out'){
|
||||
onError("The request timed out")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if(unsuccessfulPublishes?.length > 0){
|
||||
setListOfUnSuccessfulPublishes(unsuccessfulPublishes)
|
||||
|
||||
}
|
||||
} finally {
|
||||
|
||||
setIsPublishing(false)
|
||||
}
|
||||
},
|
||||
[publish]
|
||||
);
|
||||
|
||||
const retry = ()=> {
|
||||
let newlistOfMultiplePublishes: any[] = [];
|
||||
listOfUnsuccessfulPublishes?.forEach((item)=> {
|
||||
const findPub = publishes?.resources.find((res: any)=> res?.identifier === item.identifier)
|
||||
if(findPub){
|
||||
newlistOfMultiplePublishes.push(findPub)
|
||||
}
|
||||
})
|
||||
const multiplePublish = {
|
||||
...publishes,
|
||||
resources: newlistOfMultiplePublishes
|
||||
};
|
||||
handlePublish(multiplePublish)
|
||||
}
|
||||
|
||||
const startPublish = useCallback(
|
||||
async (pubs: any) => {
|
||||
await handlePublish(pubs);
|
||||
},
|
||||
[handlePublish, onSubmit, listOfSuccessfulPublishes, publishes]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (publishes && !hasStarted.current) {
|
||||
hasStarted.current = true;
|
||||
startPublish(publishes);
|
||||
}
|
||||
}, [startPublish, publishes, listOfSuccessfulPublishes]);
|
||||
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={isOpen}
|
||||
aria-labelledby="modal-title"
|
||||
aria-describedby="modal-description"
|
||||
>
|
||||
<ModalBody
|
||||
sx={{
|
||||
minHeight: "50vh",
|
||||
}}
|
||||
>
|
||||
{publishes?.resources?.map((publish: any) => {
|
||||
const unpublished = listOfUnsuccessfulPublishes.map(item => item?.identifier)
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography>{publish?.identifier}</Typography>
|
||||
{!isPublishing && hasStarted.current ? (
|
||||
<>
|
||||
{!unpublished.includes(publish.identifier) ? (
|
||||
<CircleSVG
|
||||
color={theme.palette.text.primary}
|
||||
height="24px"
|
||||
width="24px"
|
||||
/>
|
||||
) : (
|
||||
<EmptyCircleSVG
|
||||
color={theme.palette.text.primary}
|
||||
height="24px"
|
||||
width="24px"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
): <CircularProgress size={16} color="secondary"/>}
|
||||
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
{!isPublishing && listOfUnsuccessfulPublishes.length > 0 && (
|
||||
<>
|
||||
<Typography sx={{
|
||||
marginTop: '20px',
|
||||
fontSize: '16px'
|
||||
}}>Some files were not published. Please try again. It's important that all the files get published. Maybe wait a couple minutes if the error keeps occurring</Typography>
|
||||
<Button variant="contained" onClick={()=> {
|
||||
retry()
|
||||
}}>Try again</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export const ModalBody = styled(Box)(({ theme }) => ({
|
||||
position: "absolute",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
borderRadius: "4px",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: "75%",
|
||||
maxWidth: "900px",
|
||||
padding: "15px 35px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "17px",
|
||||
overflowY: "auto",
|
||||
maxHeight: "95vh",
|
||||
boxShadow:
|
||||
theme.palette.mode === "dark"
|
||||
? "0px 4px 5px 0px hsla(0,0%,0%,0.14), 0px 1px 10px 0px hsla(0,0%,0%,0.12), 0px 2px 4px -1px hsla(0,0%,0%,0.2)"
|
||||
: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px",
|
||||
"&::-webkit-scrollbar-track": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
"&::-webkit-scrollbar-track:hover": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
"&::-webkit-scrollbar": {
|
||||
width: "16px",
|
||||
height: "10px",
|
||||
backgroundColor: theme.palette.mode === "light" ? "#f6f8fa" : "#292d3e",
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb": {
|
||||
backgroundColor: theme.palette.mode === "light" ? "#d3d9e1" : "#575757",
|
||||
borderRadius: "8px",
|
||||
backgroundClip: "content-box",
|
||||
border: "4px solid transparent",
|
||||
},
|
||||
"&::-webkit-scrollbar-thumb:hover": {
|
||||
backgroundColor: theme.palette.mode === "light" ? "#b7bcc4" : "#474646",
|
||||
},
|
||||
}));
|
@ -35,8 +35,8 @@ import {
|
||||
} from "../../../state/features/videoSlice";
|
||||
import { RootState } from "../../../state/store";
|
||||
import { useWindowSize } from "../../../hooks/useWindowSize";
|
||||
import { UploadVideo } from "../../UploadVideo/UploadVideo";
|
||||
import { StyledButton } from "../../UploadVideo/Upload-styles";
|
||||
import { PublishFile } from "../../PublishFile/PublishFile.tsx";
|
||||
import { StyledButton } from "../../PublishFile/Upload-styles.tsx";
|
||||
interface Props {
|
||||
isAuthenticated: boolean;
|
||||
userName: string | null;
|
||||
@ -400,7 +400,7 @@ const NavBar: React.FC<Props> = ({
|
||||
<AvatarContainer>
|
||||
{isAuthenticated && userName && (
|
||||
<>
|
||||
<UploadVideo />
|
||||
<PublishFile />
|
||||
</>
|
||||
)}
|
||||
|
||||
|
221
src/constants/Categories.ts
Normal file
221
src/constants/Categories.ts
Normal file
@ -0,0 +1,221 @@
|
||||
import softwareIcon from "../assets/icons/software.webp";
|
||||
import gamingIcon from "../assets/icons/gaming.webp";
|
||||
import mediaIcon from "../assets/icons/media.webp";
|
||||
import videoIcon from "../assets/icons/video.webp";
|
||||
import audioIcon from "../assets/icons/audio.webp";
|
||||
import documentIcon from "../assets/icons/document.webp";
|
||||
|
||||
interface SubCategory {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Categories {
|
||||
[key: number]: SubCategory[];
|
||||
}
|
||||
|
||||
const sortCategory = (a: SubCategory, b: SubCategory) => {
|
||||
if (a.name === "Other") return 1;
|
||||
else if (b.name === "Other") return -1;
|
||||
else return a.name.localeCompare(b.name);
|
||||
};
|
||||
|
||||
export const categories = [
|
||||
{"id": 1, "name": "Software"},
|
||||
{"id": 2, "name": "Gaming"},
|
||||
{"id": 3, "name": "Media"},
|
||||
{"id": 4, "name": "Other"}
|
||||
].sort(sortCategory);
|
||||
export const subCategories: Categories = {
|
||||
1: [
|
||||
{"id": 101, "name": "OS"},
|
||||
{"id": 102, "name": "Application"},
|
||||
{"id": 103, "name": "Source Code"},
|
||||
{"id": 104, "name": "Other"}
|
||||
].sort(sortCategory),
|
||||
2: [
|
||||
{"id": 201, "name": "NES"},
|
||||
{"id": 202, "name": "SNES"},
|
||||
{"id": 203, "name": "PC"},
|
||||
{"id": 204, "name": "Other"}
|
||||
].sort(sortCategory),
|
||||
3: [
|
||||
{"id": 301, "name": "Audio"},
|
||||
{"id": 302, "name": "Video"},
|
||||
{"id": 303, "name": "Image"},
|
||||
{"id": 304, "name": "Document"},
|
||||
{"id": 305, "name": "Other"}
|
||||
].sort(sortCategory)
|
||||
};
|
||||
|
||||
const gamingSystems = [
|
||||
{"id": 20101, "name": "ROM"},
|
||||
{"id": 20102, "name": "Romhack"},
|
||||
{"id": 20103, "name": "Emulator"},
|
||||
{"id": 20104, "name": "Guide"},
|
||||
{"id": 20105, "name": "Other"},
|
||||
].sort(sortCategory)
|
||||
export const subCategories2: Categories = {
|
||||
201: gamingSystems, // NES
|
||||
202: gamingSystems, // SNES
|
||||
301: [ // Audio
|
||||
{"id": 30101, "name": "Music"},
|
||||
{"id": 30102, "name": "Podcasts"},
|
||||
{"id": 30103, "name": "Audiobooks"},
|
||||
{"id": 30104, "name": "Sound Effects"},
|
||||
{"id": 30105, "name": "Lectures & Speeches"},
|
||||
{"id": 30106, "name": "Radio Shows"},
|
||||
{"id": 30107, "name": "Ambient Sounds"},
|
||||
{"id": 30108, "name": "Language Learning Material"},
|
||||
{"id": 30109, "name": "Comedy & Satire"},
|
||||
{"id": 30110, "name": "Documentaries"},
|
||||
{"id": 30111, "name": "Guided Meditations & Yoga"},
|
||||
{"id": 30112, "name": "Live Performances"},
|
||||
{"id": 30113, "name": "Nature Sounds"},
|
||||
{"id": 30114, "name": "Soundtracks"},
|
||||
{"id": 30115, "name": "Interviews"}
|
||||
].sort(sortCategory),
|
||||
302: [ // Under Video
|
||||
{"id": 30201, "name": "Movies"},
|
||||
{"id": 30202, "name": "Series"},
|
||||
{"id": 30203, "name": "Music"},
|
||||
{"id": 30204, "name": "Education"},
|
||||
{"id": 30205, "name": "Lifestyle"},
|
||||
{"id": 30206, "name": "Gaming"},
|
||||
{"id": 30207, "name": "Technology"},
|
||||
{"id": 30208, "name": "Sports"},
|
||||
{"id": 30209, "name": "News & Politics"},
|
||||
{"id": 30210, "name": "Cooking & Food"},
|
||||
{"id": 30211, "name": "Animation"},
|
||||
{"id": 30212, "name": "Science"},
|
||||
{"id": 30213, "name": "Health & Wellness"},
|
||||
{"id": 30214, "name": "DIY & Crafts"},
|
||||
{"id": 30215, "name": "Kids & Family"},
|
||||
{"id": 30216, "name": "Comedy"},
|
||||
{"id": 30217, "name": "Travel & Adventure"},
|
||||
{"id": 30218, "name": "Art & Design"},
|
||||
{"id": 30219, "name": "Nature & Environment"},
|
||||
{"id": 30220, "name": "Business & Finance"},
|
||||
{"id": 30221, "name": "Personal Development"},
|
||||
{"id": 30222, "name": "Other"},
|
||||
{"id": 30223, "name": "History"}
|
||||
].sort(sortCategory),
|
||||
303: [ // Image
|
||||
{"id": 30301, "name": "Nature"},
|
||||
{"id": 30302, "name": "Urban & Cityscapes"},
|
||||
{"id": 30303, "name": "People & Portraits"},
|
||||
{"id": 30304, "name": "Art & Abstract"},
|
||||
{"id": 30305, "name": "Travel & Adventure"},
|
||||
{"id": 30306, "name": "Animals & Wildlife"},
|
||||
{"id": 30307, "name": "Sports & Action"},
|
||||
{"id": 30308, "name": "Food & Cuisine"},
|
||||
{"id": 30309, "name": "Fashion & Beauty"},
|
||||
{"id": 30310, "name": "Technology & Science"},
|
||||
{"id": 30311, "name": "Historical & Cultural"},
|
||||
{"id": 30312, "name": "Aerial & Drone"},
|
||||
{"id": 30313, "name": "Black & White"},
|
||||
{"id": 30314, "name": "Events & Celebrations"},
|
||||
{"id": 30315, "name": "Business & Corporate"},
|
||||
{"id": 30316, "name": "Health & Wellness"},
|
||||
{"id": 30317, "name": "Transportation & Vehicles"},
|
||||
{"id": 30318, "name": "Still Life & Objects"},
|
||||
{"id": 30319, "name": "Architecture & Buildings"},
|
||||
{"id": 30320, "name": "Landscapes & Seascapes"}
|
||||
].sort(sortCategory),
|
||||
304: [ // Document
|
||||
{"id": 30401, "name": "PDF"},
|
||||
{"id": 30402, "name": "Word Document"},
|
||||
{"id": 30403, "name": "Spreadsheet"},
|
||||
{"id": 30404, "name": "Powerpoint"},
|
||||
{"id": 30405, "name": "Books"}
|
||||
].sort(sortCategory)
|
||||
};
|
||||
export const subCategories3: Categories = {
|
||||
30201: [ // Under Movies
|
||||
{"id": 3020101, "name": "Action & Adventure"},
|
||||
{"id": 3020102, "name": "Comedy"},
|
||||
{"id": 3020103, "name": "Drama"},
|
||||
{"id": 3020104, "name": "Fantasy & Science Fiction"},
|
||||
{"id": 3020105, "name": "Horror & Thriller"},
|
||||
{"id": 3020106, "name": "Documentaries"},
|
||||
{"id": 3020107, "name": "Animated"},
|
||||
{"id": 3020108, "name": "Family & Kids"},
|
||||
{"id": 3020109, "name": "Romance"},
|
||||
{"id": 3020110, "name": "Mystery & Crime"},
|
||||
{"id": 3020111, "name": "Historical & War"},
|
||||
{"id": 3020112, "name": "Musicals & Music Films"},
|
||||
{"id": 3020113, "name": "Indie Films"},
|
||||
{"id": 3020114, "name": "International Films"},
|
||||
{"id": 3020115, "name": "Biographies & True Stories"},
|
||||
{"id": 3020116, "name": "Other"}
|
||||
].sort(sortCategory),
|
||||
30202: [ // Under Series
|
||||
{"id": 3020201, "name": "Dramas"},
|
||||
{"id": 3020202, "name": "Comedies"},
|
||||
{"id": 3020203, "name": "Reality & Competition"},
|
||||
{"id": 3020204, "name": "Documentaries & Docuseries"},
|
||||
{"id": 3020205, "name": "Sci-Fi & Fantasy"},
|
||||
{"id": 3020206, "name": "Crime & Mystery"},
|
||||
{"id": 3020207, "name": "Animated Series"},
|
||||
{"id": 3020208, "name": "Kids & Family"},
|
||||
{"id": 3020209, "name": "Historical & Period Pieces"},
|
||||
{"id": 3020210, "name": "Action & Adventure"},
|
||||
{"id": 3020211, "name": "Horror & Thriller"},
|
||||
{"id": 3020212, "name": "Romance"},
|
||||
{"id": 3020213, "name": "Anthologies"},
|
||||
{"id": 3020214, "name": "International Series"},
|
||||
{"id": 3020215, "name": "Miniseries"},
|
||||
{"id": 3020216, "name": "Other"}
|
||||
].sort(sortCategory),
|
||||
30405: [ // Under Books
|
||||
{"id": 3040501, "name": "Fiction"},
|
||||
{"id": 3040502, "name": "Non-Fiction"},
|
||||
{"id": 3040503, "name": "Science Fiction & Fantasy"},
|
||||
{"id": 3040504, "name": "Biographies & Memoirs"},
|
||||
{"id": 3040505, "name": "Children's Books"},
|
||||
{"id": 3040506, "name": "Educational"},
|
||||
{"id": 3040507, "name": "Self-Help"},
|
||||
{"id": 3040508, "name": "Cookbooks, Food & Wine"},
|
||||
{"id": 3040509, "name": "Mystery & Thriller"},
|
||||
{"id": 3040510, "name": "History"},
|
||||
{"id": 3040511, "name": "Poetry"},
|
||||
{"id": 3040512, "name": "Art & Photography"},
|
||||
{"id": 3040513, "name": "Religion & Spirituality"},
|
||||
{"id": 3040514, "name": "Travel"},
|
||||
{"id": 3040515, "name": "Comics & Graphic Novels"},
|
||||
|
||||
].sort(sortCategory),
|
||||
30101: [ // Under Music
|
||||
{"id": 3010101, "name": "Rock"},
|
||||
{"id": 3010102, "name": "Pop"},
|
||||
{"id": 3010103, "name": "Classical"},
|
||||
{"id": 3010104, "name": "Jazz"},
|
||||
{"id": 3010105, "name": "Electronic"},
|
||||
{"id": 3010106, "name": "Country"},
|
||||
{"id": 3010107, "name": "Hip Hop/Rap"},
|
||||
{"id": 3010108, "name": "Blues"},
|
||||
{"id": 3010109, "name": "R&B/Soul"},
|
||||
{"id": 3010110, "name": "Reggae"},
|
||||
{"id": 3010111, "name": "Folk"},
|
||||
{"id": 3010112, "name": "Metal"},
|
||||
{"id": 3010113, "name": "World Music"},
|
||||
{"id": 3010114, "name": "Latin"},
|
||||
{"id": 3010115, "name": "Indie"},
|
||||
{"id": 3010116, "name": "Punk"},
|
||||
{"id": 3010117, "name": "Soundtracks"},
|
||||
{"id": 3010118, "name": "Children's Music"},
|
||||
{"id": 3010119, "name": "New Age"},
|
||||
{"id": 3010120, "name": "Classical Crossover"}
|
||||
].sort(sortCategory)
|
||||
|
||||
|
||||
};
|
||||
export const icons = {
|
||||
1: softwareIcon,
|
||||
2: gamingIcon,
|
||||
3: mediaIcon,
|
||||
4: softwareIcon,
|
||||
302: videoIcon,
|
||||
301: audioIcon,
|
||||
304: documentIcon
|
||||
}
|
17
src/constants/Identifiers.ts
Normal file
17
src/constants/Identifiers.ts
Normal file
@ -0,0 +1,17 @@
|
||||
const useTestIdentifiers = false;
|
||||
|
||||
export const QSHARE_FILE_BASE = useTestIdentifiers
|
||||
? "MYTEST_share_vid_"
|
||||
: "qshare_file_";
|
||||
|
||||
export const QSHARE_PLAYLIST_BASE = useTestIdentifiers
|
||||
? "MYTEST_share_playlist_"
|
||||
: "qshare_playlist_";
|
||||
|
||||
export const QSHARE_COMMENT_BASE = useTestIdentifiers
|
||||
? "qcomment_v1_MYTEST_"
|
||||
: "qcomment_v1_qshare_";
|
||||
|
||||
|
||||
|
||||
|
1
src/constants/Misc.ts
Normal file
1
src/constants/Misc.ts
Normal file
@ -0,0 +1 @@
|
||||
export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.~;:|]/g;
|
@ -1,237 +0,0 @@
|
||||
import softwareIcon from '../assets/icons/software.webp'
|
||||
import gamingIcon from '../assets/icons/gaming.webp'
|
||||
import mediaIcon from '../assets/icons/media.webp'
|
||||
import audioIcon from '../assets/icons/audio.webp'
|
||||
import videoIcon from '../assets/icons/video.webp'
|
||||
import documentIcon from '../assets/icons/document.webp'
|
||||
|
||||
|
||||
const useTestIdentifiers = false;
|
||||
|
||||
export const QTUBE_VIDEO_BASE = useTestIdentifiers
|
||||
? "MYTEST_share_vid_"
|
||||
: "qshare_file_";
|
||||
|
||||
export const QTUBE_PLAYLIST_BASE = useTestIdentifiers
|
||||
? "MYTEST_share_playlist_"
|
||||
: "qshare_playlist_";
|
||||
|
||||
export const COMMENT_BASE = useTestIdentifiers
|
||||
? "qcomment_v1_MYTEST_"
|
||||
: "qcomment_v1_qshare_";
|
||||
|
||||
interface SubCategory {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface CategoryMap {
|
||||
[key: number]: SubCategory[];
|
||||
}
|
||||
|
||||
|
||||
export const categories = [
|
||||
{"id": 1, "name": "Software"},
|
||||
{"id": 2, "name": "Gaming"},
|
||||
{"id": 3, "name": "Media"}
|
||||
];
|
||||
|
||||
export const subCategories: CategoryMap = {
|
||||
1: [
|
||||
{"id": 101, "name": "OS"},
|
||||
{"id": 102, "name": "Application"},
|
||||
{"id": 103, "name": "Source Code"},
|
||||
{"id": 104, "name": "Other"}
|
||||
],
|
||||
2: [
|
||||
{"id": 201, "name": "NES"},
|
||||
{"id": 202, "name": "SNES"},
|
||||
{"id": 203, "name": "PC"},
|
||||
{"id": 204, "name": "Other Gaming Systems"}
|
||||
],
|
||||
3: [
|
||||
{"id": 301, "name": "Audio"},
|
||||
{"id": 302, "name": "Video"},
|
||||
{"id": 303, "name": "Image"},
|
||||
{"id": 304, "name": "Document"},
|
||||
{"id": 305, "name": "Other Media Formats"}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
export const subCategories2: CategoryMap = {
|
||||
201: [ // NES
|
||||
{"id": 20101, "name": "ROM"},
|
||||
{"id": 20102, "name": "Romhack"},
|
||||
{"id": 20103, "name": "Emulator"},
|
||||
],
|
||||
202: [ // SNES
|
||||
{"id": 20201, "name": "ROM"},
|
||||
{"id": 20202, "name": "Romhack"},
|
||||
{"id": 20203, "name": "Emulator"},
|
||||
],
|
||||
301: [ // Audio
|
||||
{"id": 30101, "name": "Music"},
|
||||
{"id": 30102, "name": "Podcasts"},
|
||||
{"id": 30103, "name": "Audiobooks"},
|
||||
{"id": 30104, "name": "Sound Effects"},
|
||||
{"id": 30105, "name": "Lectures & Speeches"},
|
||||
{"id": 30106, "name": "Radio Shows"},
|
||||
{"id": 30107, "name": "Ambient Sounds"},
|
||||
{"id": 30108, "name": "Language Learning Material"},
|
||||
{"id": 30109, "name": "Comedy & Satire"},
|
||||
{"id": 30110, "name": "Documentaries"},
|
||||
{"id": 30111, "name": "Guided Meditations & Yoga"},
|
||||
{"id": 30112, "name": "Live Performances"},
|
||||
{"id": 30113, "name": "Nature Sounds"},
|
||||
{"id": 30114, "name": "Soundtracks"},
|
||||
{"id": 30115, "name": "Interviews"}
|
||||
],
|
||||
302: [ // Under Video
|
||||
{"id": 30201, "name": "Movies"},
|
||||
{"id": 30202, "name": "Series"},
|
||||
{"id": 30203, "name": "Music"},
|
||||
{"id": 30204, "name": "Education"},
|
||||
{"id": 30205, "name": "Lifestyle"},
|
||||
{"id": 30206, "name": "Gaming"},
|
||||
{"id": 30207, "name": "Technology"},
|
||||
{"id": 30208, "name": "Sports"},
|
||||
{"id": 30209, "name": "News & Politics"},
|
||||
{"id": 30210, "name": "Cooking & Food"},
|
||||
{"id": 30211, "name": "Animation"},
|
||||
{"id": 30212, "name": "Science"},
|
||||
{"id": 30213, "name": "Health & Wellness"},
|
||||
{"id": 30214, "name": "DIY & Crafts"},
|
||||
{"id": 30215, "name": "Kids & Family"},
|
||||
{"id": 30216, "name": "Comedy"},
|
||||
{"id": 30217, "name": "Travel & Adventure"},
|
||||
{"id": 30218, "name": "Art & Design"},
|
||||
{"id": 30219, "name": "Nature & Environment"},
|
||||
{"id": 30220, "name": "Business & Finance"},
|
||||
{"id": 30221, "name": "Personal Development"},
|
||||
{"id": 30222, "name": "Other"},
|
||||
{"id": 30223, "name": "History"}
|
||||
],
|
||||
303: [ // Image
|
||||
{"id": 30301, "name": "Nature"},
|
||||
{"id": 30302, "name": "Urban & Cityscapes"},
|
||||
{"id": 30303, "name": "People & Portraits"},
|
||||
{"id": 30304, "name": "Art & Abstract"},
|
||||
{"id": 30305, "name": "Travel & Adventure"},
|
||||
{"id": 30306, "name": "Animals & Wildlife"},
|
||||
{"id": 30307, "name": "Sports & Action"},
|
||||
{"id": 30308, "name": "Food & Cuisine"},
|
||||
{"id": 30309, "name": "Fashion & Beauty"},
|
||||
{"id": 30310, "name": "Technology & Science"},
|
||||
{"id": 30311, "name": "Historical & Cultural"},
|
||||
{"id": 30312, "name": "Aerial & Drone"},
|
||||
{"id": 30313, "name": "Black & White"},
|
||||
{"id": 30314, "name": "Events & Celebrations"},
|
||||
{"id": 30315, "name": "Business & Corporate"},
|
||||
{"id": 30316, "name": "Health & Wellness"},
|
||||
{"id": 30317, "name": "Transportation & Vehicles"},
|
||||
{"id": 30318, "name": "Still Life & Objects"},
|
||||
{"id": 30319, "name": "Architecture & Buildings"},
|
||||
{"id": 30320, "name": "Landscapes & Seascapes"}
|
||||
],
|
||||
304: [ // Document
|
||||
{"id": 30401, "name": "PDF"},
|
||||
{"id": 30402, "name": "Word Document"},
|
||||
{"id": 30403, "name": "Spreadsheet"},
|
||||
{"id": 30404, "name": "Powerpoint"},
|
||||
{"id": 30405, "name": "Books"}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
export const subCategories3: CategoryMap = {
|
||||
30201: [ // Under Movies
|
||||
{"id": 3020101, "name": "Action & Adventure"},
|
||||
{"id": 3020102, "name": "Comedy"},
|
||||
{"id": 3020103, "name": "Drama"},
|
||||
{"id": 3020104, "name": "Fantasy & Science Fiction"},
|
||||
{"id": 3020105, "name": "Horror & Thriller"},
|
||||
{"id": 3020106, "name": "Documentaries"},
|
||||
{"id": 3020107, "name": "Animated"},
|
||||
{"id": 3020108, "name": "Family & Kids"},
|
||||
{"id": 3020109, "name": "Romance"},
|
||||
{"id": 3020110, "name": "Mystery & Crime"},
|
||||
{"id": 3020111, "name": "Historical & War"},
|
||||
{"id": 3020112, "name": "Musicals & Music Films"},
|
||||
{"id": 3020113, "name": "Indie Films"},
|
||||
{"id": 3020114, "name": "International Films"},
|
||||
{"id": 3020115, "name": "Biographies & True Stories"},
|
||||
{"id": 3020116, "name": "Other"}
|
||||
],
|
||||
30202: [ // Under Series
|
||||
{"id": 3020201, "name": "Dramas"},
|
||||
{"id": 3020202, "name": "Comedies"},
|
||||
{"id": 3020203, "name": "Reality & Competition"},
|
||||
{"id": 3020204, "name": "Documentaries & Docuseries"},
|
||||
{"id": 3020205, "name": "Sci-Fi & Fantasy"},
|
||||
{"id": 3020206, "name": "Crime & Mystery"},
|
||||
{"id": 3020207, "name": "Animated Series"},
|
||||
{"id": 3020208, "name": "Kids & Family"},
|
||||
{"id": 3020209, "name": "Historical & Period Pieces"},
|
||||
{"id": 3020210, "name": "Action & Adventure"},
|
||||
{"id": 3020211, "name": "Horror & Thriller"},
|
||||
{"id": 3020212, "name": "Romance"},
|
||||
{"id": 3020213, "name": "Anthologies"},
|
||||
{"id": 3020214, "name": "International Series"},
|
||||
{"id": 3020215, "name": "Miniseries"},
|
||||
{"id": 3020216, "name": "Other"}
|
||||
],
|
||||
30405: [ // Under Books
|
||||
{"id": 3040501, "name": "Fiction"},
|
||||
{"id": 3040502, "name": "Non-Fiction"},
|
||||
{"id": 3040503, "name": "Science Fiction & Fantasy"},
|
||||
{"id": 3040504, "name": "Biographies & Memoirs"},
|
||||
{"id": 3040505, "name": "Children's Books"},
|
||||
{"id": 3040506, "name": "Educational"},
|
||||
{"id": 3040507, "name": "Self-Help"},
|
||||
{"id": 3040508, "name": "Cookbooks, Food & Wine"},
|
||||
{"id": 3040509, "name": "Mystery & Thriller"},
|
||||
{"id": 3040510, "name": "History"},
|
||||
{"id": 3040511, "name": "Poetry"},
|
||||
{"id": 3040512, "name": "Art & Photography"},
|
||||
{"id": 3040513, "name": "Religion & Spirituality"},
|
||||
{"id": 3040514, "name": "Travel"},
|
||||
{"id": 3040515, "name": "Comics & Graphic Novels"},
|
||||
|
||||
],
|
||||
30101: [ // Under Music
|
||||
{"id": 3010101, "name": "Rock"},
|
||||
{"id": 3010102, "name": "Pop"},
|
||||
{"id": 3010103, "name": "Classical"},
|
||||
{"id": 3010104, "name": "Jazz"},
|
||||
{"id": 3010105, "name": "Electronic"},
|
||||
{"id": 3010106, "name": "Country"},
|
||||
{"id": 3010107, "name": "Hip Hop/Rap"},
|
||||
{"id": 3010108, "name": "Blues"},
|
||||
{"id": 3010109, "name": "R&B/Soul"},
|
||||
{"id": 3010110, "name": "Reggae"},
|
||||
{"id": 3010111, "name": "Folk"},
|
||||
{"id": 3010112, "name": "Metal"},
|
||||
{"id": 3010113, "name": "World Music"},
|
||||
{"id": 3010114, "name": "Latin"},
|
||||
{"id": 3010115, "name": "Indie"},
|
||||
{"id": 3010116, "name": "Punk"},
|
||||
{"id": 3010117, "name": "Soundtracks"},
|
||||
{"id": 3010118, "name": "Children's Music"},
|
||||
{"id": 3010119, "name": "New Age"},
|
||||
{"id": 3010120, "name": "Classical Crossover"}
|
||||
]
|
||||
|
||||
|
||||
};
|
||||
|
||||
export const icons = {
|
||||
1: softwareIcon,
|
||||
2: gamingIcon,
|
||||
3: mediaIcon,
|
||||
302: videoIcon,
|
||||
301: audioIcon,
|
||||
304: documentIcon
|
||||
}
|
@ -14,13 +14,13 @@ import {
|
||||
} from '../state/features/globalSlice'
|
||||
import { RootState } from '../state/store'
|
||||
import { fetchAndEvaluateVideos } from '../utils/fetchVideos'
|
||||
import { QTUBE_PLAYLIST_BASE, QTUBE_VIDEO_BASE } from '../constants'
|
||||
import { QSHARE_PLAYLIST_BASE, QSHARE_FILE_BASE } from '../constants/Identifiers.ts'
|
||||
import { RequestQueue } from '../utils/queue'
|
||||
import { queue } from '../wrappers/GlobalWrapper'
|
||||
|
||||
|
||||
|
||||
export const useFetchVideos = () => {
|
||||
export const useFetchFiles = () => {
|
||||
const dispatch = useDispatch()
|
||||
const hashMapVideos = useSelector(
|
||||
(state: RootState) => state.video.hashMapVideos
|
||||
@ -95,7 +95,7 @@ export const useFetchVideos = () => {
|
||||
dispatch(setIsLoadingGlobal(true))
|
||||
|
||||
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QTUBE_VIDEO_BASE}&limit=20&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true`
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QSHARE_FILE_BASE}&limit=20&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true`
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@ -213,11 +213,11 @@ export const useFetchVideos = () => {
|
||||
}
|
||||
if(type === 'playlists'){
|
||||
defaultUrl = defaultUrl + `&service=PLAYLIST`
|
||||
defaultUrl = defaultUrl + `&identifier=${QTUBE_PLAYLIST_BASE}`
|
||||
defaultUrl = defaultUrl + `&identifier=${QSHARE_PLAYLIST_BASE}`
|
||||
|
||||
} else {
|
||||
defaultUrl = defaultUrl + `&service=DOCUMENT`
|
||||
defaultUrl = defaultUrl + `&identifier=${QTUBE_VIDEO_BASE}`
|
||||
defaultUrl = defaultUrl + `&identifier=${QSHARE_FILE_BASE}`
|
||||
}
|
||||
|
||||
// const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QTUBE_VIDEO_BASE}&limit=${videoLimit}&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true&offset=${offset}`
|
||||
@ -288,7 +288,7 @@ export const useFetchVideos = () => {
|
||||
const offset = filteredVideos.length
|
||||
const replaceSpacesWithUnderscore = filterValue.replace(/ /g, '_');
|
||||
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${replaceSpacesWithUnderscore}&identifier=${QTUBE_VIDEO_BASE}&limit=10&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true&offset=${offset}`
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${replaceSpacesWithUnderscore}&identifier=${QSHARE_FILE_BASE}&limit=10&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true&offset=${offset}`
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@ -345,7 +345,7 @@ export const useFetchVideos = () => {
|
||||
try {
|
||||
|
||||
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QTUBE_VIDEO_BASE}&limit=20&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true`
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QSHARE_FILE_BASE}&limit=20&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true`
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@ -382,12 +382,12 @@ export const useFetchVideos = () => {
|
||||
|
||||
|
||||
return {
|
||||
getVideos,
|
||||
getFiles: getVideos,
|
||||
checkAndUpdateVideo,
|
||||
getVideo,
|
||||
hashMapVideos,
|
||||
getNewVideos,
|
||||
checkNewVideos,
|
||||
getVideosFiltered
|
||||
getNewFiles: getNewVideos,
|
||||
checkNewFiles: checkNewVideos,
|
||||
getFilesFiltered: getVideosFiltered
|
||||
}
|
||||
}
|
@ -9,9 +9,9 @@ import {
|
||||
Typography,
|
||||
useTheme
|
||||
} from '@mui/material'
|
||||
import { useFetchVideos } from '../../hooks/useFetchVideos'
|
||||
import { useFetchFiles } from '../../hooks/useFetchFiles.tsx'
|
||||
import LazyLoad from '../../components/common/LazyLoad'
|
||||
import { BottomParent, NameContainer, VideoCard, VideoCardName, VideoCardTitle, VideoContainer, VideoUploadDate } from './VideoList-styles'
|
||||
import { BottomParent, NameContainer, VideoCard, VideoCardName, VideoCardTitle, VideoContainer, VideoUploadDate } from './FileList-styles.tsx'
|
||||
import ResponsiveImage from '../../components/ResponsiveImage'
|
||||
import { formatDate, formatTimestampSeconds } from '../../utils/time'
|
||||
import { ChannelCard, ChannelTitle } from './Home-styles'
|
||||
|
@ -21,7 +21,7 @@ import {
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useFetchVideos } from "../../hooks/useFetchVideos";
|
||||
import { useFetchFiles } from "../../hooks/useFetchFiles.tsx";
|
||||
import LazyLoad from "../../components/common/LazyLoad";
|
||||
import {
|
||||
BlockIconContainer,
|
||||
@ -40,7 +40,7 @@ import {
|
||||
VideoCardTitle,
|
||||
VideoContainer,
|
||||
VideoUploadDate,
|
||||
} from "./VideoList-styles";
|
||||
} from "./FileList-styles.tsx";
|
||||
import ResponsiveImage from "../../components/ResponsiveImage";
|
||||
import { formatDate, formatTimestampSeconds } from "../../utils/time";
|
||||
import { Subtitle, SubtitleContainer } from "./Home-styles";
|
||||
@ -59,17 +59,17 @@ import {
|
||||
setEditPlaylist,
|
||||
setEditVideo,
|
||||
} from "../../state/features/videoSlice";
|
||||
import { categories, icons, subCategories, subCategories2, subCategories3 } from "../../constants";
|
||||
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 { formatBytes } from "../VideoContent/VideoContent";
|
||||
import {categories, icons, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
|
||||
|
||||
interface VideoListProps {
|
||||
mode?: string;
|
||||
}
|
||||
export const VideoList = ({ mode }: VideoListProps) => {
|
||||
export const FileList = ({ mode }: VideoListProps) => {
|
||||
const theme = useTheme();
|
||||
const prevVal = useRef("");
|
||||
const isFiltering = useSelector(
|
||||
@ -152,10 +152,10 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
(state: RootState) => state.video
|
||||
);
|
||||
const navigate = useNavigate();
|
||||
const { getVideos, getNewVideos, checkNewVideos, getVideosFiltered } =
|
||||
useFetchVideos();
|
||||
const { getFiles, getNewFiles, checkNewFiles, getFilesFiltered } =
|
||||
useFetchFiles();
|
||||
|
||||
const getVideosHandler = React.useCallback(
|
||||
const getFilesHandler = React.useCallback(
|
||||
async (reset?: boolean, resetFilers?: boolean) => {
|
||||
|
||||
|
||||
@ -168,7 +168,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
subcategory2: selectedSubCategoryVideos2?.id,
|
||||
subcategory3: selectedSubCategoryVideos3?.id,
|
||||
})
|
||||
await getVideos(
|
||||
await getFiles(
|
||||
{
|
||||
name: filterName,
|
||||
category: selectedCategoryVideos?.id,
|
||||
@ -184,9 +184,9 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
isFetching.current = false;
|
||||
},
|
||||
[
|
||||
getVideos,
|
||||
getFiles,
|
||||
filterValue,
|
||||
getVideosFiltered,
|
||||
getFilesFiltered,
|
||||
isFiltering,
|
||||
filterName,
|
||||
selectedCategoryVideos,
|
||||
@ -198,24 +198,30 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
]
|
||||
);
|
||||
|
||||
const searchOnEnter = e => {
|
||||
if (e.keyCode == 13) {
|
||||
getFilesHandler(true);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isFiltering && filterValue !== prevVal?.current) {
|
||||
prevVal.current = filterValue;
|
||||
getVideosHandler();
|
||||
getFilesHandler();
|
||||
}
|
||||
}, [filterValue, isFiltering, filteredVideos]);
|
||||
|
||||
const getVideosHandlerMount = React.useCallback(async () => {
|
||||
const getFilesHandlerMount = React.useCallback(async () => {
|
||||
if (firstFetch.current) return;
|
||||
firstFetch.current = true;
|
||||
setIsLoading(true);
|
||||
|
||||
await getVideos();
|
||||
await getFiles();
|
||||
afterFetch.current = true;
|
||||
isFetching.current = false;
|
||||
|
||||
setIsLoading(false);
|
||||
}, [getVideos]);
|
||||
}, [getFiles]);
|
||||
|
||||
let videos = globalVideos;
|
||||
|
||||
@ -259,12 +265,12 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
globalVideos.length === 0
|
||||
) {
|
||||
isFetching.current = true;
|
||||
getVideosHandlerMount();
|
||||
getFilesHandlerMount();
|
||||
} else {
|
||||
firstFetch.current = true;
|
||||
afterFetch.current = true;
|
||||
}
|
||||
}, [getVideosHandlerMount, globalVideos]);
|
||||
}, [getFilesHandlerMount, globalVideos]);
|
||||
|
||||
const filtersToDefault = async () => {
|
||||
setFilterType("videos");
|
||||
@ -274,7 +280,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
setSelectedSubCategoryVideos(null);
|
||||
|
||||
ReactDOM.flushSync(() => {
|
||||
getVideosHandler(true, true);
|
||||
getFilesHandler(true, true);
|
||||
});
|
||||
};
|
||||
|
||||
@ -340,6 +346,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
onChange={(e) => {
|
||||
setFilterSearch(e.target.value);
|
||||
}}
|
||||
onKeyDown={searchOnEnter}
|
||||
value={filterSearch}
|
||||
placeholder="Search"
|
||||
sx={{
|
||||
@ -367,8 +374,9 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
onChange={(e) => {
|
||||
setFilterName(e.target.value);
|
||||
}}
|
||||
onKeyDown={searchOnEnter}
|
||||
value={filterName}
|
||||
placeholder="User's name"
|
||||
placeholder="User's Name (Exact)"
|
||||
sx={{
|
||||
marginTop: "20px",
|
||||
borderBottom: "1px solid white",
|
||||
@ -640,7 +648,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
getVideosHandler(true);
|
||||
getFilesHandler(true);
|
||||
}}
|
||||
sx={{
|
||||
marginTop: "20px",
|
||||
@ -833,7 +841,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
|
||||
</VideoContainer>
|
||||
|
||||
<LazyLoad
|
||||
onLoadMore={getVideosHandler}
|
||||
onLoadMore={getFilesHandler}
|
||||
isLoading={isLoading}
|
||||
></LazyLoad>
|
||||
</Box>
|
@ -12,20 +12,21 @@ import {
|
||||
Typography,
|
||||
useTheme
|
||||
} from '@mui/material'
|
||||
import { useFetchVideos } from '../../hooks/useFetchVideos'
|
||||
import { useFetchFiles } from '../../hooks/useFetchFiles.tsx'
|
||||
import LazyLoad from '../../components/common/LazyLoad'
|
||||
import { BottomParent, NameContainer, VideoCard, VideoCardName, VideoCardTitle, VideoContainer, VideoUploadDate } from './VideoList-styles'
|
||||
import { BottomParent, NameContainer, VideoCard, VideoCardName, VideoCardTitle, VideoContainer, VideoUploadDate } from './FileList-styles.tsx'
|
||||
import ResponsiveImage from '../../components/ResponsiveImage'
|
||||
import { formatDate, formatTimestampSeconds } from '../../utils/time'
|
||||
import { Video } from '../../state/features/videoSlice'
|
||||
import { queue } from '../../wrappers/GlobalWrapper'
|
||||
import { QTUBE_VIDEO_BASE, categories, icons, subCategories, subCategories2, subCategories3 } from '../../constants'
|
||||
import { QSHARE_FILE_BASE } from '../../constants/Identifiers.ts'
|
||||
import { formatBytes } from '../VideoContent/VideoContent'
|
||||
import {categories, icons, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
|
||||
|
||||
interface VideoListProps {
|
||||
mode?: string
|
||||
}
|
||||
export const VideoListComponentLevel = ({ mode }: VideoListProps) => {
|
||||
export const FileListComponentLevel = ({ mode }: VideoListProps) => {
|
||||
const { name: paramName } = useParams()
|
||||
const theme = useTheme()
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true)
|
||||
@ -48,15 +49,15 @@ export const VideoListComponentLevel = ({ mode }: VideoListProps) => {
|
||||
const navigate = useNavigate()
|
||||
const {
|
||||
getVideo,
|
||||
getNewVideos,
|
||||
checkNewVideos,
|
||||
getNewFiles,
|
||||
checkNewFiles,
|
||||
checkAndUpdateVideo
|
||||
} = useFetchVideos()
|
||||
} = useFetchFiles()
|
||||
|
||||
const getVideos = React.useCallback(async () => {
|
||||
try {
|
||||
const offset = videos.length
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QTUBE_VIDEO_BASE}_&limit=50&includemetadata=false&reverse=true&excludeblocked=true&name=${paramName}&exactmatchnames=true&offset=${offset}`
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QSHARE_FILE_BASE}_&limit=50&includemetadata=false&reverse=true&excludeblocked=true&name=${paramName}&exactmatchnames=true&offset=${offset}`
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { VideoList } from './VideoList'
|
||||
import { FileList } from './FileList.tsx'
|
||||
|
||||
import { useSelector } from 'react-redux'
|
||||
import { RootState } from '../../state/store'
|
||||
@ -8,7 +8,7 @@ export const Home = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<VideoList />
|
||||
<FileList />
|
||||
</>
|
||||
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import { VideoListComponentLevel } from '../Home/VideoListComponentLevel'
|
||||
import { FileListComponentLevel } from '../Home/FileListComponentLevel.tsx'
|
||||
import { HeaderContainer, ProfileContainer } from './Profile-styles'
|
||||
import { AuthorTextComment, StyledCardColComment, StyledCardHeaderComment } from '../VideoContent/VideoContent-styles'
|
||||
import { Avatar, Box, useTheme } from '@mui/material'
|
||||
@ -57,7 +57,7 @@ export const IndividualProfile = () => {
|
||||
</StyledCardHeaderComment>
|
||||
</Box>
|
||||
</HeaderContainer>
|
||||
<VideoListComponentLevel />
|
||||
<FileListComponentLevel />
|
||||
</ProfileContainer>
|
||||
|
||||
)
|
||||
|
@ -32,11 +32,12 @@ import { CommentSection } from "../../components/common/Comments/CommentSection"
|
||||
import {
|
||||
CrowdfundSubTitle,
|
||||
CrowdfundSubTitleRow,
|
||||
} from "../../components/UploadVideo/Upload-styles";
|
||||
import { QTUBE_VIDEO_BASE, categories, subCategories, subCategories2, subCategories3 } from "../../constants";
|
||||
} from "../../components/PublishFile/Upload-styles.tsx";
|
||||
import { QSHARE_FILE_BASE } from "../../constants/Identifiers.ts";
|
||||
import { Playlists } from "../../components/Playlists/Playlists";
|
||||
import { DisplayHtml } from "../../components/common/TextEditor/DisplayHtml";
|
||||
import FileElement from "../../components/common/FileElement";
|
||||
import {categories, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
|
||||
|
||||
export function formatBytes(bytes, decimals = 2) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
@ -110,7 +111,7 @@ export const VideoContent = () => {
|
||||
if (!name || !id) return;
|
||||
dispatch(setIsLoadingGlobal(true));
|
||||
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QTUBE_VIDEO_BASE}&limit=1&includemetadata=true&reverse=true&excludeblocked=true&name=${name}&exactmatchnames=true&offset=0&identifier=${id}`;
|
||||
const url = `/arbitrary/resources/search?mode=ALL&service=DOCUMENT&query=${QSHARE_FILE_BASE}&limit=1&includemetadata=true&reverse=true&excludeblocked=true&name=${name}&exactmatchnames=true&offset=0&identifier=${id}`;
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
|
@ -15,7 +15,7 @@ import { setUserAvatarHash } from "../state/features/globalSlice";
|
||||
import { VideoPlayerGlobal } from "../components/common/VideoPlayerGlobal";
|
||||
import { Rnd } from "react-rnd";
|
||||
import { RequestQueue } from "../utils/queue";
|
||||
import { EditVideo } from "../components/EditVideo/EditVideo";
|
||||
import { EditFile } from "../components/EditFile/EditFile.tsx";
|
||||
import { EditPlaylist } from "../components/EditPlaylist/EditPlaylist";
|
||||
import ConsentModal from "../components/common/ConsentModal";
|
||||
|
||||
@ -138,7 +138,7 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
|
||||
userAvatar={userAvatar}
|
||||
authenticate={askForAccountInformation}
|
||||
/>
|
||||
<EditVideo />
|
||||
<EditFile />
|
||||
<EditPlaylist />
|
||||
<Rnd
|
||||
onDragStart={onDragStart}
|
||||
|
Loading…
Reference in New Issue
Block a user