3
0
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:
Qortal Dev 2024-01-31 08:51:27 -07:00 committed by GitHub
commit fa0a1dc16a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 617 additions and 514 deletions

View File

@ -1,17 +1,10 @@
import React, { useEffect, useState } from "react"; import React, {useEffect, useState} from "react";
import { import {
AddCoverImageButton,
AddLogoIcon,
CoverImagePreview,
CrowdfundActionButton, CrowdfundActionButton,
CrowdfundActionButtonRow, CrowdfundActionButtonRow,
CustomInputField, CustomInputField,
CustomSelect,
LogoPreviewRow,
ModalBody, ModalBody,
NewCrowdfundTitle, NewCrowdfundTitle,
StyledButton,
TimesIcon,
} from "./Upload-styles"; } from "./Upload-styles";
import { import {
Box, Box,
@ -28,27 +21,19 @@ import {
import RemoveIcon from "@mui/icons-material/Remove"; import RemoveIcon from "@mui/icons-material/Remove";
import ShortUniqueId from "short-unique-id"; import ShortUniqueId from "short-unique-id";
import { useDispatch, useSelector } from "react-redux"; import {useDispatch, useSelector} from "react-redux";
import AddBoxIcon from "@mui/icons-material/AddBox"; import {useDropzone} from "react-dropzone";
import { useDropzone } from "react-dropzone";
import { setNotification } from "../../state/features/notificationsSlice"; import {setNotification} from "../../state/features/notificationsSlice";
import { objectToBase64, uint8ArrayToBase64 } from "../../utils/toBase64"; import {objectToBase64} from "../../utils/toBase64";
import { RootState } from "../../state/store"; import {RootState} from "../../state/store";
import { import {setEditVideo, updateInHashMap, updateVideo,} from "../../state/features/videoSlice";
upsertVideosBeginning, import {QSHARE_FILE_BASE,} from "../../constants/Identifiers.ts";
addToHashMap, import {MultiplePublish} from "../common/MultiplePublish/MultiplePublishAll";
upsertVideos, import {TextEditor} from "../common/TextEditor/TextEditor";
setEditVideo, import {extractTextFromHTML} from "../common/TextEditor/utils";
updateVideo, import {categories, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
updateInHashMap, import {titleFormatter} from "../../constants/Misc.ts";
} 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";
const uid = new ShortUniqueId(); const uid = new ShortUniqueId();
const shortuid = new ShortUniqueId({ length: 5 }); const shortuid = new ShortUniqueId({ length: 5 });
@ -70,7 +55,7 @@ interface VideoFile {
identifier?:string; identifier?:string;
filename?:string filename?:string
} }
export const EditVideo = () => { export const EditFile = () => {
const theme = useTheme(); const theme = useTheme();
const dispatch = useDispatch(); const dispatch = useDispatch();
const username = useSelector((state: RootState) => state.auth?.user?.name); const username = useSelector((state: RootState) => state.auth?.user?.name);
@ -80,7 +65,7 @@ export const EditVideo = () => {
const editVideoProperties = useSelector( const editVideoProperties = useSelector(
(state: RootState) => state.video.editVideoProperties (state: RootState) => state.video.editVideoProperties
); );
const [publishes, setPublishes] = useState<any[]>([]); const [publishes, setPublishes] = useState<any>(null);
const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false); const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false);
const [videoPropertiesToSetToRedux, setVideoPropertiesToSetToRedux] = const [videoPropertiesToSetToRedux, setVideoPropertiesToSetToRedux] =
useState(null); useState(null);
@ -302,7 +287,7 @@ export const EditVideo = () => {
const file = publish.file; const file = publish.file;
const id = uid(); 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, description: metadescription,
identifier, identifier,
filename, filename,
tag1: QTUBE_VIDEO_BASE, tag1: QSHARE_FILE_BASE,
}; };
listOfPublishes.push(requestBodyVideo); listOfPublishes.push(requestBodyVideo);
fileReferences.push({ fileReferences.push({
@ -388,12 +373,16 @@ export const EditVideo = () => {
title: title.slice(0, 50), title: title.slice(0, 50),
description: metadescription, description: metadescription,
identifier: editVideoProperties.id, identifier: editVideoProperties.id,
tag1: QTUBE_VIDEO_BASE, tag1: QSHARE_FILE_BASE,
filename: `video_metadata.json`, filename: `video_metadata.json`,
}; };
listOfPublishes.push(requestBodyJson); listOfPublishes.push(requestBodyJson);
setPublishes(listOfPublishes); const multiplePublish = {
action: "PUBLISH_MULTIPLE_QDN_RESOURCES",
resources: [...listOfPublishes],
};
setPublishes(multiplePublish);
setIsOpenMultiplePublish(true); setIsOpenMultiplePublish(true);
setVideoPropertiesToSetToRedux({ setVideoPropertiesToSetToRedux({
...editVideoProperties, ...editVideoProperties,
@ -686,10 +675,7 @@ export const EditVideo = () => {
value={title} value={title}
onChange={(e) => { onChange={(e) => {
const value = e.target.value; const value = e.target.value;
const formattedValue = value.replace( const formattedValue = value.replace(titleFormatter, "");
/[^a-zA-Z0-9\s-_!?]/g,
""
);
setTitle(formattedValue); setTitle(formattedValue);
}} }}
inputProps={{ maxLength: 180 }} inputProps={{ maxLength: 180 }}
@ -744,6 +730,18 @@ export const EditVideo = () => {
{isOpenMultiplePublish && ( {isOpenMultiplePublish && (
<MultiplePublish <MultiplePublish
isOpen={isOpenMultiplePublish} isOpen={isOpenMultiplePublish}
onError={(messageNotification)=> {
setIsOpenMultiplePublish(false);
setPublishes(null)
if(messageNotification){
dispatch(
setNotification({
msg: messageNotification,
alertType: 'error'
})
)
}
}}
onSubmit={() => { onSubmit={() => {
setIsOpenMultiplePublish(false); setIsOpenMultiplePublish(false);
const clonedCopy = structuredClone(videoPropertiesToSetToRedux); const clonedCopy = structuredClone(videoPropertiesToSetToRedux);

View File

@ -12,7 +12,7 @@ import {
NewCrowdfundTitle, NewCrowdfundTitle,
StyledButton, StyledButton,
TimesIcon, TimesIcon,
} from "./Upload-styles"; } from "./Upload-styles.tsx";
import { import {
Box, Box,
FormControl, FormControl,
@ -43,11 +43,12 @@ import {
setEditPlaylist, setEditPlaylist,
} from "../../state/features/videoSlice"; } from "../../state/features/videoSlice";
import ImageUploader from "../common/ImageUploader"; 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 { Playlists } from "../Playlists/Playlists";
import { PlaylistListEdit } from "../PlaylistListEdit/PlaylistListEdit"; import { PlaylistListEdit } from "../PlaylistListEdit/PlaylistListEdit";
import { TextEditor } from "../common/TextEditor/TextEditor"; import { TextEditor } from "../common/TextEditor/TextEditor";
import { extractTextFromHTML } from "../common/TextEditor/utils"; import { extractTextFromHTML } from "../common/TextEditor/utils";
import {categories, subCategories} from "../../constants/Categories.ts";
const uid = new ShortUniqueId(); const uid = new ShortUniqueId();
const shortuid = new ShortUniqueId({ length: 5 }); const shortuid = new ShortUniqueId({ length: 5 });
@ -289,7 +290,7 @@ export const EditPlaylist = () => {
let commentsId = editVideoProperties?.id let commentsId = editVideoProperties?.id
if(isNew){ if(isNew){
commentsId = `${QTUBE_PLAYLIST_BASE}_cm_${id}` commentsId = `${QSHARE_PLAYLIST_BASE}_cm_${id}`
} }
const stringDescription = extractTextFromHTML(description) const stringDescription = extractTextFromHTML(description)
@ -322,7 +323,7 @@ export const EditPlaylist = () => {
.trim() .trim()
.toLowerCase(); .toLowerCase();
if(isNew){ if(isNew){
identifier = `${QTUBE_PLAYLIST_BASE}${sanitizeTitle.slice(0, 30)}_${id}`; identifier = `${QSHARE_PLAYLIST_BASE}${sanitizeTitle.slice(0, 30)}_${id}`;
} }
const requestBodyJson: any = { const requestBodyJson: any = {
action: "PUBLISH_QDN_RESOURCE", action: "PUBLISH_QDN_RESOURCE",
@ -332,7 +333,7 @@ export const EditPlaylist = () => {
title: title.slice(0, 50), title: title.slice(0, 50),
description: metadescription, description: metadescription,
identifier: identifier, identifier: identifier,
tag1: QTUBE_VIDEO_BASE, tag1: QSHARE_FILE_BASE,
}; };
await qortalRequest(requestBodyJson); await qortalRequest(requestBodyJson);

View File

@ -3,13 +3,13 @@ import { CardContentContainerComment } from "../common/Comments/Comments-styles"
import { import {
CrowdfundSubTitle, CrowdfundSubTitle,
CrowdfundSubTitleRow, CrowdfundSubTitleRow,
} from "../UploadVideo/Upload-styles"; } from "../PublishFile/Upload-styles.tsx";
import { Box, Button, Input, Typography, useTheme } from "@mui/material"; import { Box, Button, Input, Typography, useTheme } from "@mui/material";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline"; import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import { removeVideo } from "../../state/features/videoSlice"; import { removeVideo } from "../../state/features/videoSlice";
import AddIcon from '@mui/icons-material/Add'; 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 { useSelector } from "react-redux";
import { RootState } from "../../state/store"; import { RootState } from "../../state/store";
export const PlaylistListEdit = ({ playlistData, removeVideo, addVideo }) => { export const PlaylistListEdit = ({ playlistData, removeVideo, addVideo }) => {
@ -21,7 +21,7 @@ export const PlaylistListEdit = ({ playlistData, removeVideo, addVideo }) => {
const [filterSearch, setFilterSearch] = useState("") const [filterSearch, setFilterSearch] = useState("")
const search = async()=> { 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, { const response = await fetch(url, {
method: 'GET', method: 'GET',
headers: { headers: {

View File

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import { CardContentContainerComment } from '../common/Comments/Comments-styles' 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 { Box, Typography, useTheme } from '@mui/material'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'

View File

@ -44,21 +44,23 @@ import {
} from "../../state/features/videoSlice"; } from "../../state/features/videoSlice";
import ImageUploader from "../common/ImageUploader"; import ImageUploader from "../common/ImageUploader";
import { import {
QTUBE_PLAYLIST_BASE, QSHARE_PLAYLIST_BASE,
QTUBE_VIDEO_BASE, QSHARE_FILE_BASE,
categories,
subCategories,
subCategories2,
subCategories3,
} from "../../constants"; } from "../../constants/Identifiers.ts";
import { MultiplePublish } from "../common/MultiplePublish/MultiplePublish"; import { MultiplePublish } from "../common/MultiplePublish/MultiplePublishAll";
import { import {
CrowdfundSubTitle, CrowdfundSubTitle,
CrowdfundSubTitleRow, CrowdfundSubTitleRow,
} from "../EditPlaylist/Upload-styles"; } from "../EditPlaylist/Upload-styles.tsx";
import { CardContentContainerComment } from "../common/Comments/Comments-styles"; import { CardContentContainerComment } from "../common/Comments/Comments-styles";
import { TextEditor } from "../common/TextEditor/TextEditor"; import { TextEditor } from "../common/TextEditor/TextEditor";
import { extractTextFromHTML } from "../common/TextEditor/utils"; 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 uid = new ShortUniqueId();
const shortuid = new ShortUniqueId({ length: 5 }); const shortuid = new ShortUniqueId({ length: 5 });
@ -78,7 +80,7 @@ interface VideoFile {
description: string; description: string;
coverImage?: string; coverImage?: string;
} }
export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => { export const PublishFile = ({ editId, editContent }: NewCrowdfundProps) => {
const theme = useTheme(); const theme = useTheme();
const dispatch = useDispatch(); const dispatch = useDispatch();
const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false); const [isOpenMultiplePublish, setIsOpenMultiplePublish] = useState(false);
@ -112,7 +114,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
useState<any>(null); useState<any>(null);
const [playlistSetting, setPlaylistSetting] = useState<null | string>(null); const [playlistSetting, setPlaylistSetting] = useState<null | string>(null);
const [publishes, setPublishes] = useState<any[]>([]); const [publishes, setPublishes] = useState<any>(null);
const { getRootProps, getInputProps } = useDropzone({ const { getRootProps, getInputProps } = useDropzone({
maxFiles: 10, maxFiles: 10,
maxSize: 419430400, // 400 MB in bytes maxSize: 419430400, // 400 MB in bytes
@ -214,7 +216,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
const file = publish.file; const file = publish.file;
const id = uid(); 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, description: metadescription,
identifier, identifier,
filename, filename,
tag1: QTUBE_VIDEO_BASE, tag1: QSHARE_FILE_BASE,
}; };
listOfPublishes.push(requestBodyVideo); listOfPublishes.push(requestBodyVideo);
fileReferences.push({ fileReferences.push({
@ -274,13 +276,13 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
} }
const idMeta = uid(); 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 = { const fileObject: any = {
title, title,
version: 1, version: 1,
fullDescription, fullDescription,
htmlDescription: description, htmlDescription: description,
commentsId: `${QTUBE_VIDEO_BASE}_cm_${idMeta}`, commentsId: `${QSHARE_FILE_BASE}_cm_${idMeta}`,
category, category,
subcategory, subcategory,
subcategory2, subcategory2,
@ -302,12 +304,18 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
title: title.slice(0, 50), title: title.slice(0, 50),
description: metadescription, description: metadescription,
identifier: identifier + "_metadata", identifier: identifier + "_metadata",
tag1: QTUBE_VIDEO_BASE, tag1: QSHARE_FILE_BASE,
filename: `video_metadata.json`, filename: `video_metadata.json`,
}; };
listOfPublishes.push(requestBodyJson); listOfPublishes.push(requestBodyJson);
setPublishes(listOfPublishes);
const multiplePublish = {
action: "PUBLISH_MULTIPLE_QDN_RESOURCES",
resources: [...listOfPublishes],
};
setPublishes(multiplePublish);
setIsOpenMultiplePublish(true); setIsOpenMultiplePublish(true);
} catch (error: any) { } catch (error: any) {
let notificationObj: any = null; let notificationObj: any = null;
if (typeof error === "string") { if (typeof error === "string") {
@ -599,10 +607,7 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
value={title} value={title}
onChange={(e) => { onChange={(e) => {
const value = e.target.value; const value = e.target.value;
const formattedValue = value.replace( const formattedValue = value.replace(titleFormatter, "");
/[^a-zA-Z0-9\s-_!?]/g,
""
);
setTitle(formattedValue); setTitle(formattedValue);
}} }}
inputProps={{ maxLength: 180 }} inputProps={{ maxLength: 180 }}
@ -659,6 +664,18 @@ export const UploadVideo = ({ editId, editContent }: NewCrowdfundProps) => {
{isOpenMultiplePublish && ( {isOpenMultiplePublish && (
<MultiplePublish <MultiplePublish
isOpen={isOpenMultiplePublish} isOpen={isOpenMultiplePublish}
onError={(messageNotification)=> {
setIsOpenMultiplePublish(false);
setPublishes(null)
if(messageNotification){
dispatch(
setNotification({
msg: messageNotification,
alertType: 'error'
})
)
}
}}
onSubmit={() => { onSubmit={() => {
setIsOpenMultiplePublish(false); setIsOpenMultiplePublish(false);
setIsOpen(false); setIsOpen(false);

View File

@ -67,9 +67,9 @@ export const ModalBody = styled(Box)(({ theme }) => ({
overflowY: "auto", overflowY: "auto",
maxHeight: "95vh", maxHeight: "95vh",
boxShadow: boxShadow:
theme.palette.mode === "dark" 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)" ? "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", : "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px",
"&::-webkit-scrollbar-track": { "&::-webkit-scrollbar-track": {
backgroundColor: theme.palette.background.paper, backgroundColor: theme.palette.background.paper,
}, },
@ -203,11 +203,11 @@ export const CrowdfundDescription = styled(Typography)(({ theme }) => ({
export const Spacer = ({ height }: any) => { export const Spacer = ({ height }: any) => {
return ( return (
<Box <Box
sx={{ sx={{
height: height, height: height,
}} }}
/> />
); );
}; };
@ -314,14 +314,14 @@ export const AddCrowdFundButton = styled(Button)(({ theme }) => ({
gap: "8px", gap: "8px",
color: "#ffffff", color: "#ffffff",
backgroundColor: backgroundColor:
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86", theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
border: "none", border: "none",
borderRadius: "5px", borderRadius: "5px",
transition: "all 0.3s ease-in-out", transition: "all 0.3s ease-in-out",
"&:hover": { "&:hover": {
cursor: "pointer", cursor: "pointer",
backgroundColor: 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", gap: "8px",
color: "#ffffff", color: "#ffffff",
backgroundColor: backgroundColor:
theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86", theme.palette.mode === "dark" ? theme.palette.primary.main : "#2a9a86",
border: "none", border: "none",
borderRadius: "5px", borderRadius: "5px",
transition: "all 0.3s ease-in-out", transition: "all 0.3s ease-in-out",
"&:hover": { "&:hover": {
cursor: "pointer", cursor: "pointer",
backgroundColor: 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, fontWeight: 400,
color: theme.palette.text.primary, color: theme.palette.text.primary,
}, },
})); }));

View File

@ -11,7 +11,7 @@ import {
CommentInputContainer, CommentInputContainer,
SubmitCommentButton, SubmitCommentButton,
} from "./Comments-styles"; } from "./Comments-styles";
import { COMMENT_BASE } from "../../../constants"; import { QSHARE_COMMENT_BASE } from "../../../constants/Identifiers.ts";
const uid = new ShortUniqueId(); const uid = new ShortUniqueId();
const notification = localforage.createInstance({ const notification = localforage.createInstance({
@ -201,13 +201,13 @@ export const CommentEditor = ({
try { try {
const id = uid(); 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; let idForNotification = identifier;
if (isReply && commentId) { if (isReply && commentId) {
const removeBaseCommentId = commentId; const removeBaseCommentId = commentId;
removeBaseCommentId.replace("_base_", ""); removeBaseCommentId.replace("_base_", "");
identifier = `${COMMENT_BASE}${postId.slice( identifier = `${QSHARE_COMMENT_BASE}${postId.slice(
-12 -12
)}_reply_${removeBaseCommentId.slice(-6)}_${id}`; )}_reply_${removeBaseCommentId.slice(-6)}_${id}`;
idForNotification = commentId; idForNotification = commentId;

View File

@ -14,8 +14,8 @@ import {
LoadMoreCommentsButtonRow, LoadMoreCommentsButtonRow,
NoCommentsRow, NoCommentsRow,
} from "./Comments-styles"; } from "./Comments-styles";
import { COMMENT_BASE } from "../../../constants"; import { QSHARE_COMMENT_BASE } from "../../../constants/Identifiers.ts";
import { CrowdfundSubTitle, CrowdfundSubTitleRow } from "../../UploadVideo/Upload-styles"; import { CrowdfundSubTitle, CrowdfundSubTitleRow } from "../../PublishFile/Upload-styles.tsx";
interface CommentSectionProps { interface CommentSectionProps {
postId: string; postId: string;
@ -105,7 +105,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
const offset = 0; const offset = 0;
const removeBaseCommentId = commentId.replace("_base_", ""); 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 -12
)}_reply_${removeBaseCommentId.slice( )}_reply_${removeBaseCommentId.slice(
-6 -6
@ -150,7 +150,7 @@ export const CommentSection = ({ postId, postName }: CommentSectionProps) => {
if (isNewMessages && numberOfComments) { if (isNewMessages && numberOfComments) {
offset = 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 -12
)}_base_&limit=20&includemetadata=false&offset=${offset}&reverse=false&excludeblocked=true`; )}_base_&limit=20&includemetadata=false&offset=${offset}&reverse=false&excludeblocked=true`;
const response = await fetch(url, { const response = await fetch(url, {

View File

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

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

View File

@ -35,8 +35,8 @@ import {
} from "../../../state/features/videoSlice"; } from "../../../state/features/videoSlice";
import { RootState } from "../../../state/store"; import { RootState } from "../../../state/store";
import { useWindowSize } from "../../../hooks/useWindowSize"; import { useWindowSize } from "../../../hooks/useWindowSize";
import { UploadVideo } from "../../UploadVideo/UploadVideo"; import { PublishFile } from "../../PublishFile/PublishFile.tsx";
import { StyledButton } from "../../UploadVideo/Upload-styles"; import { StyledButton } from "../../PublishFile/Upload-styles.tsx";
interface Props { interface Props {
isAuthenticated: boolean; isAuthenticated: boolean;
userName: string | null; userName: string | null;
@ -400,7 +400,7 @@ const NavBar: React.FC<Props> = ({
<AvatarContainer> <AvatarContainer>
{isAuthenticated && userName && ( {isAuthenticated && userName && (
<> <>
<UploadVideo /> <PublishFile />
</> </>
)} )}

221
src/constants/Categories.ts Normal file
View 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
}

View 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
View File

@ -0,0 +1 @@
export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.~;:|]/g;

View File

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

View File

@ -14,13 +14,13 @@ import {
} from '../state/features/globalSlice' } from '../state/features/globalSlice'
import { RootState } from '../state/store' import { RootState } from '../state/store'
import { fetchAndEvaluateVideos } from '../utils/fetchVideos' 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 { RequestQueue } from '../utils/queue'
import { queue } from '../wrappers/GlobalWrapper' import { queue } from '../wrappers/GlobalWrapper'
export const useFetchVideos = () => { export const useFetchFiles = () => {
const dispatch = useDispatch() const dispatch = useDispatch()
const hashMapVideos = useSelector( const hashMapVideos = useSelector(
(state: RootState) => state.video.hashMapVideos (state: RootState) => state.video.hashMapVideos
@ -95,7 +95,7 @@ export const useFetchVideos = () => {
dispatch(setIsLoadingGlobal(true)) 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, { const response = await fetch(url, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -213,11 +213,11 @@ export const useFetchVideos = () => {
} }
if(type === 'playlists'){ if(type === 'playlists'){
defaultUrl = defaultUrl + `&service=PLAYLIST` defaultUrl = defaultUrl + `&service=PLAYLIST`
defaultUrl = defaultUrl + `&identifier=${QTUBE_PLAYLIST_BASE}` defaultUrl = defaultUrl + `&identifier=${QSHARE_PLAYLIST_BASE}`
} else { } else {
defaultUrl = defaultUrl + `&service=DOCUMENT` 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}` // 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 offset = filteredVideos.length
const replaceSpacesWithUnderscore = filterValue.replace(/ /g, '_'); 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, { const response = await fetch(url, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -345,7 +345,7 @@ export const useFetchVideos = () => {
try { 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, { const response = await fetch(url, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -382,12 +382,12 @@ export const useFetchVideos = () => {
return { return {
getVideos, getFiles: getVideos,
checkAndUpdateVideo, checkAndUpdateVideo,
getVideo, getVideo,
hashMapVideos, hashMapVideos,
getNewVideos, getNewFiles: getNewVideos,
checkNewVideos, checkNewFiles: checkNewVideos,
getVideosFiltered getFilesFiltered: getVideosFiltered
} }
} }

View File

@ -9,9 +9,9 @@ import {
Typography, Typography,
useTheme useTheme
} from '@mui/material' } from '@mui/material'
import { useFetchVideos } from '../../hooks/useFetchVideos' import { useFetchFiles } from '../../hooks/useFetchFiles.tsx'
import LazyLoad from '../../components/common/LazyLoad' 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 ResponsiveImage from '../../components/ResponsiveImage'
import { formatDate, formatTimestampSeconds } from '../../utils/time' import { formatDate, formatTimestampSeconds } from '../../utils/time'
import { ChannelCard, ChannelTitle } from './Home-styles' import { ChannelCard, ChannelTitle } from './Home-styles'

View File

@ -21,7 +21,7 @@ import {
Typography, Typography,
useTheme, useTheme,
} from "@mui/material"; } from "@mui/material";
import { useFetchVideos } from "../../hooks/useFetchVideos"; import { useFetchFiles } from "../../hooks/useFetchFiles.tsx";
import LazyLoad from "../../components/common/LazyLoad"; import LazyLoad from "../../components/common/LazyLoad";
import { import {
BlockIconContainer, BlockIconContainer,
@ -40,7 +40,7 @@ import {
VideoCardTitle, VideoCardTitle,
VideoContainer, VideoContainer,
VideoUploadDate, VideoUploadDate,
} from "./VideoList-styles"; } from "./FileList-styles.tsx";
import ResponsiveImage from "../../components/ResponsiveImage"; import ResponsiveImage from "../../components/ResponsiveImage";
import { formatDate, formatTimestampSeconds } from "../../utils/time"; import { formatDate, formatTimestampSeconds } from "../../utils/time";
import { Subtitle, SubtitleContainer } from "./Home-styles"; import { Subtitle, SubtitleContainer } from "./Home-styles";
@ -59,17 +59,17 @@ import {
setEditPlaylist, setEditPlaylist,
setEditVideo, setEditVideo,
} from "../../state/features/videoSlice"; } from "../../state/features/videoSlice";
import { categories, icons, subCategories, subCategories2, subCategories3 } from "../../constants";
import { Playlists } from "../../components/Playlists/Playlists"; import { Playlists } from "../../components/Playlists/Playlists";
import { PlaylistSVG } from "../../assets/svgs/PlaylistSVG"; import { PlaylistSVG } from "../../assets/svgs/PlaylistSVG";
import BlockIcon from "@mui/icons-material/Block"; import BlockIcon from "@mui/icons-material/Block";
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import { formatBytes } from "../VideoContent/VideoContent"; import { formatBytes } from "../VideoContent/VideoContent";
import {categories, icons, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
interface VideoListProps { interface VideoListProps {
mode?: string; mode?: string;
} }
export const VideoList = ({ mode }: VideoListProps) => { export const FileList = ({ mode }: VideoListProps) => {
const theme = useTheme(); const theme = useTheme();
const prevVal = useRef(""); const prevVal = useRef("");
const isFiltering = useSelector( const isFiltering = useSelector(
@ -152,10 +152,10 @@ export const VideoList = ({ mode }: VideoListProps) => {
(state: RootState) => state.video (state: RootState) => state.video
); );
const navigate = useNavigate(); const navigate = useNavigate();
const { getVideos, getNewVideos, checkNewVideos, getVideosFiltered } = const { getFiles, getNewFiles, checkNewFiles, getFilesFiltered } =
useFetchVideos(); useFetchFiles();
const getVideosHandler = React.useCallback( const getFilesHandler = React.useCallback(
async (reset?: boolean, resetFilers?: boolean) => { async (reset?: boolean, resetFilers?: boolean) => {
@ -168,7 +168,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
subcategory2: selectedSubCategoryVideos2?.id, subcategory2: selectedSubCategoryVideos2?.id,
subcategory3: selectedSubCategoryVideos3?.id, subcategory3: selectedSubCategoryVideos3?.id,
}) })
await getVideos( await getFiles(
{ {
name: filterName, name: filterName,
category: selectedCategoryVideos?.id, category: selectedCategoryVideos?.id,
@ -184,9 +184,9 @@ export const VideoList = ({ mode }: VideoListProps) => {
isFetching.current = false; isFetching.current = false;
}, },
[ [
getVideos, getFiles,
filterValue, filterValue,
getVideosFiltered, getFilesFiltered,
isFiltering, isFiltering,
filterName, filterName,
selectedCategoryVideos, selectedCategoryVideos,
@ -198,24 +198,30 @@ export const VideoList = ({ mode }: VideoListProps) => {
] ]
); );
const searchOnEnter = e => {
if (e.keyCode == 13) {
getFilesHandler(true);
}
};
useEffect(() => { useEffect(() => {
if (isFiltering && filterValue !== prevVal?.current) { if (isFiltering && filterValue !== prevVal?.current) {
prevVal.current = filterValue; prevVal.current = filterValue;
getVideosHandler(); getFilesHandler();
} }
}, [filterValue, isFiltering, filteredVideos]); }, [filterValue, isFiltering, filteredVideos]);
const getVideosHandlerMount = React.useCallback(async () => { const getFilesHandlerMount = React.useCallback(async () => {
if (firstFetch.current) return; if (firstFetch.current) return;
firstFetch.current = true; firstFetch.current = true;
setIsLoading(true); setIsLoading(true);
await getVideos(); await getFiles();
afterFetch.current = true; afterFetch.current = true;
isFetching.current = false; isFetching.current = false;
setIsLoading(false); setIsLoading(false);
}, [getVideos]); }, [getFiles]);
let videos = globalVideos; let videos = globalVideos;
@ -259,12 +265,12 @@ export const VideoList = ({ mode }: VideoListProps) => {
globalVideos.length === 0 globalVideos.length === 0
) { ) {
isFetching.current = true; isFetching.current = true;
getVideosHandlerMount(); getFilesHandlerMount();
} else { } else {
firstFetch.current = true; firstFetch.current = true;
afterFetch.current = true; afterFetch.current = true;
} }
}, [getVideosHandlerMount, globalVideos]); }, [getFilesHandlerMount, globalVideos]);
const filtersToDefault = async () => { const filtersToDefault = async () => {
setFilterType("videos"); setFilterType("videos");
@ -274,7 +280,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
setSelectedSubCategoryVideos(null); setSelectedSubCategoryVideos(null);
ReactDOM.flushSync(() => { ReactDOM.flushSync(() => {
getVideosHandler(true, true); getFilesHandler(true, true);
}); });
}; };
@ -340,6 +346,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
onChange={(e) => { onChange={(e) => {
setFilterSearch(e.target.value); setFilterSearch(e.target.value);
}} }}
onKeyDown={searchOnEnter}
value={filterSearch} value={filterSearch}
placeholder="Search" placeholder="Search"
sx={{ sx={{
@ -367,8 +374,9 @@ export const VideoList = ({ mode }: VideoListProps) => {
onChange={(e) => { onChange={(e) => {
setFilterName(e.target.value); setFilterName(e.target.value);
}} }}
onKeyDown={searchOnEnter}
value={filterName} value={filterName}
placeholder="User's name" placeholder="User's Name (Exact)"
sx={{ sx={{
marginTop: "20px", marginTop: "20px",
borderBottom: "1px solid white", borderBottom: "1px solid white",
@ -640,7 +648,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
</Button> </Button>
<Button <Button
onClick={() => { onClick={() => {
getVideosHandler(true); getFilesHandler(true);
}} }}
sx={{ sx={{
marginTop: "20px", marginTop: "20px",
@ -833,7 +841,7 @@ export const VideoList = ({ mode }: VideoListProps) => {
</VideoContainer> </VideoContainer>
<LazyLoad <LazyLoad
onLoadMore={getVideosHandler} onLoadMore={getFilesHandler}
isLoading={isLoading} isLoading={isLoading}
></LazyLoad> ></LazyLoad>
</Box> </Box>

View File

@ -12,20 +12,21 @@ import {
Typography, Typography,
useTheme useTheme
} from '@mui/material' } from '@mui/material'
import { useFetchVideos } from '../../hooks/useFetchVideos' import { useFetchFiles } from '../../hooks/useFetchFiles.tsx'
import LazyLoad from '../../components/common/LazyLoad' 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 ResponsiveImage from '../../components/ResponsiveImage'
import { formatDate, formatTimestampSeconds } from '../../utils/time' import { formatDate, formatTimestampSeconds } from '../../utils/time'
import { Video } from '../../state/features/videoSlice' import { Video } from '../../state/features/videoSlice'
import { queue } from '../../wrappers/GlobalWrapper' 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 { formatBytes } from '../VideoContent/VideoContent'
import {categories, icons, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
interface VideoListProps { interface VideoListProps {
mode?: string mode?: string
} }
export const VideoListComponentLevel = ({ mode }: VideoListProps) => { export const FileListComponentLevel = ({ mode }: VideoListProps) => {
const { name: paramName } = useParams() const { name: paramName } = useParams()
const theme = useTheme() const theme = useTheme()
const [isLoading, setIsLoading] = useState<boolean>(true) const [isLoading, setIsLoading] = useState<boolean>(true)
@ -48,15 +49,15 @@ export const VideoListComponentLevel = ({ mode }: VideoListProps) => {
const navigate = useNavigate() const navigate = useNavigate()
const { const {
getVideo, getVideo,
getNewVideos, getNewFiles,
checkNewVideos, checkNewFiles,
checkAndUpdateVideo checkAndUpdateVideo
} = useFetchVideos() } = useFetchFiles()
const getVideos = React.useCallback(async () => { const getVideos = React.useCallback(async () => {
try { try {
const offset = videos.length 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, { const response = await fetch(url, {
method: 'GET', method: 'GET',
headers: { headers: {

View File

@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import { VideoList } from './VideoList' import { FileList } from './FileList.tsx'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { RootState } from '../../state/store' import { RootState } from '../../state/store'
@ -8,7 +8,7 @@ export const Home = () => {
return ( return (
<> <>
<VideoList /> <FileList />
</> </>
) )

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react' import React, { useMemo } from 'react'
import { VideoListComponentLevel } from '../Home/VideoListComponentLevel' import { FileListComponentLevel } from '../Home/FileListComponentLevel.tsx'
import { HeaderContainer, ProfileContainer } from './Profile-styles' import { HeaderContainer, ProfileContainer } from './Profile-styles'
import { AuthorTextComment, StyledCardColComment, StyledCardHeaderComment } from '../VideoContent/VideoContent-styles' import { AuthorTextComment, StyledCardColComment, StyledCardHeaderComment } from '../VideoContent/VideoContent-styles'
import { Avatar, Box, useTheme } from '@mui/material' import { Avatar, Box, useTheme } from '@mui/material'
@ -57,7 +57,7 @@ export const IndividualProfile = () => {
</StyledCardHeaderComment> </StyledCardHeaderComment>
</Box> </Box>
</HeaderContainer> </HeaderContainer>
<VideoListComponentLevel /> <FileListComponentLevel />
</ProfileContainer> </ProfileContainer>
) )

View File

@ -32,11 +32,12 @@ import { CommentSection } from "../../components/common/Comments/CommentSection"
import { import {
CrowdfundSubTitle, CrowdfundSubTitle,
CrowdfundSubTitleRow, CrowdfundSubTitleRow,
} from "../../components/UploadVideo/Upload-styles"; } from "../../components/PublishFile/Upload-styles.tsx";
import { QTUBE_VIDEO_BASE, categories, subCategories, subCategories2, subCategories3 } from "../../constants"; import { QSHARE_FILE_BASE } from "../../constants/Identifiers.ts";
import { Playlists } from "../../components/Playlists/Playlists"; import { Playlists } from "../../components/Playlists/Playlists";
import { DisplayHtml } from "../../components/common/TextEditor/DisplayHtml"; import { DisplayHtml } from "../../components/common/TextEditor/DisplayHtml";
import FileElement from "../../components/common/FileElement"; import FileElement from "../../components/common/FileElement";
import {categories, subCategories, subCategories2, subCategories3} from "../../constants/Categories.ts";
export function formatBytes(bytes, decimals = 2) { export function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes'; if (bytes === 0) return '0 Bytes';
@ -110,7 +111,7 @@ export const VideoContent = () => {
if (!name || !id) return; if (!name || !id) return;
dispatch(setIsLoadingGlobal(true)); 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, { const response = await fetch(url, {
method: "GET", method: "GET",
headers: { headers: {

View File

@ -15,7 +15,7 @@ import { setUserAvatarHash } from "../state/features/globalSlice";
import { VideoPlayerGlobal } from "../components/common/VideoPlayerGlobal"; import { VideoPlayerGlobal } from "../components/common/VideoPlayerGlobal";
import { Rnd } from "react-rnd"; import { Rnd } from "react-rnd";
import { RequestQueue } from "../utils/queue"; 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 { EditPlaylist } from "../components/EditPlaylist/EditPlaylist";
import ConsentModal from "../components/common/ConsentModal"; import ConsentModal from "../components/common/ConsentModal";
@ -138,7 +138,7 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
userAvatar={userAvatar} userAvatar={userAvatar}
authenticate={askForAccountInformation} authenticate={askForAccountInformation}
/> />
<EditVideo /> <EditFile />
<EditPlaylist /> <EditPlaylist />
<Rnd <Rnd
onDragStart={onDragStart} onDragStart={onDragStart}