From 66b9fb8b6b489193a64326888097242319fe8b48 Mon Sep 17 00:00:00 2001 From: QortalSeth Date: Wed, 3 Jan 2024 10:01:20 -0700 Subject: [PATCH 1/2] Index.ts refactored into Identifiers.ts and Categories.ts for more clarity Some references to Q-Tube in code replaced with Q-Share Characters allowed in Publish Titles added to constants/Misc.ts, more characters are allowed than before User Search Label now says "User's Exact Name" to communicate that users must be precise about what names they search for Search and Name Search now can perform searches by hitting enter instead of clicking on Search Button --- .../EditVideo.tsx => EditFile/EditFile.tsx} | 54 ++--- .../{EditVideo => EditFile}/Upload-styles.tsx | 0 src/components/EditPlaylist/EditPlaylist.tsx | 11 +- .../PlaylistListEdit/PlaylistListEdit.tsx | 6 +- src/components/Playlists/Playlists.tsx | 2 +- .../PublishFile.tsx} | 35 ++-- .../Upload-styles.tsx | 26 +-- .../common/Comments/CommentEditor.tsx | 6 +- .../common/Comments/CommentSection.tsx | 8 +- .../MultiplePublish/MultiplePublish.tsx | 2 +- src/components/layout/Navbar/Navbar.tsx | 6 +- src/constants/{index.ts => Categories.ts} | 194 ++++++++---------- src/constants/Identifiers.ts | 17 ++ src/constants/Misc.ts | 1 + .../{useFetchVideos.tsx => useFetchFiles.tsx} | 22 +- src/pages/Home/Channels.tsx | 4 +- ...deoList-styles.tsx => FileList-styles.tsx} | 0 .../Home/{VideoList.tsx => FileList.tsx} | 48 +++-- ...ntLevel.tsx => FileListComponentLevel.tsx} | 17 +- src/pages/Home/Home.tsx | 4 +- .../IndividualProfile/IndividualProfile.tsx | 4 +- src/pages/VideoContent/VideoContent.tsx | 7 +- src/wrappers/GlobalWrapper.tsx | 4 +- 23 files changed, 232 insertions(+), 246 deletions(-) rename src/components/{EditVideo/EditVideo.tsx => EditFile/EditFile.tsx} (94%) rename src/components/{EditVideo => EditFile}/Upload-styles.tsx (100%) rename src/components/{UploadVideo/UploadVideo.tsx => PublishFile/PublishFile.tsx} (96%) rename src/components/{UploadVideo => PublishFile}/Upload-styles.tsx (95%) rename src/constants/{index.ts => Categories.ts} (51%) create mode 100644 src/constants/Identifiers.ts create mode 100644 src/constants/Misc.ts rename src/hooks/{useFetchVideos.tsx => useFetchFiles.tsx} (94%) rename src/pages/Home/{VideoList-styles.tsx => FileList-styles.tsx} (100%) rename src/pages/Home/{VideoList.tsx => FileList.tsx} (96%) rename src/pages/Home/{VideoListComponentLevel.tsx => FileListComponentLevel.tsx} (94%) diff --git a/src/components/EditVideo/EditVideo.tsx b/src/components/EditFile/EditFile.tsx similarity index 94% rename from src/components/EditVideo/EditVideo.tsx rename to src/components/EditFile/EditFile.tsx index 2742b40..c7eeabc 100644 --- a/src/components/EditVideo/EditVideo.tsx +++ b/src/components/EditFile/EditFile.tsx @@ -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/MultiplePublish"; +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); @@ -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,7 +373,7 @@ 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); @@ -686,10 +671,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 }} diff --git a/src/components/EditVideo/Upload-styles.tsx b/src/components/EditFile/Upload-styles.tsx similarity index 100% rename from src/components/EditVideo/Upload-styles.tsx rename to src/components/EditFile/Upload-styles.tsx diff --git a/src/components/EditPlaylist/EditPlaylist.tsx b/src/components/EditPlaylist/EditPlaylist.tsx index 614be9c..10e99a5 100644 --- a/src/components/EditPlaylist/EditPlaylist.tsx +++ b/src/components/EditPlaylist/EditPlaylist.tsx @@ -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); diff --git a/src/components/PlaylistListEdit/PlaylistListEdit.tsx b/src/components/PlaylistListEdit/PlaylistListEdit.tsx index ffae637..51cf79f 100644 --- a/src/components/PlaylistListEdit/PlaylistListEdit.tsx +++ b/src/components/PlaylistListEdit/PlaylistListEdit.tsx @@ -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: { diff --git a/src/components/Playlists/Playlists.tsx b/src/components/Playlists/Playlists.tsx index 2492bb2..3e60c90 100644 --- a/src/components/Playlists/Playlists.tsx +++ b/src/components/Playlists/Playlists.tsx @@ -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' diff --git a/src/components/UploadVideo/UploadVideo.tsx b/src/components/PublishFile/PublishFile.tsx similarity index 96% rename from src/components/UploadVideo/UploadVideo.tsx rename to src/components/PublishFile/PublishFile.tsx index 2e8b7e0..402d198 100644 --- a/src/components/UploadVideo/UploadVideo.tsx +++ b/src/components/PublishFile/PublishFile.tsx @@ -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"; + QSHARE_PLAYLIST_BASE, + QSHARE_FILE_BASE, + + + + +} from "../../constants/Identifiers.ts"; import { MultiplePublish } from "../common/MultiplePublish/MultiplePublish"; 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); @@ -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,7 +304,7 @@ 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); @@ -599,10 +601,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 }} diff --git a/src/components/UploadVideo/Upload-styles.tsx b/src/components/PublishFile/Upload-styles.tsx similarity index 95% rename from src/components/UploadVideo/Upload-styles.tsx rename to src/components/PublishFile/Upload-styles.tsx index d6ef999..d31aa96 100644 --- a/src/components/UploadVideo/Upload-styles.tsx +++ b/src/components/PublishFile/Upload-styles.tsx @@ -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 ( - + ); }; @@ -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, }, -})); +})); \ No newline at end of file diff --git a/src/components/common/Comments/CommentEditor.tsx b/src/components/common/Comments/CommentEditor.tsx index c2436d1..1911680 100644 --- a/src/components/common/Comments/CommentEditor.tsx +++ b/src/components/common/Comments/CommentEditor.tsx @@ -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; diff --git a/src/components/common/Comments/CommentSection.tsx b/src/components/common/Comments/CommentSection.tsx index 66dfc14..a6cb325 100644 --- a/src/components/common/Comments/CommentSection.tsx +++ b/src/components/common/Comments/CommentSection.tsx @@ -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, { diff --git a/src/components/common/MultiplePublish/MultiplePublish.tsx b/src/components/common/MultiplePublish/MultiplePublish.tsx index 3070a41..3c1c429 100644 --- a/src/components/common/MultiplePublish/MultiplePublish.tsx +++ b/src/components/common/MultiplePublish/MultiplePublish.tsx @@ -8,7 +8,7 @@ import { useTheme, } from "@mui/material"; import React, { useCallback, useEffect, useState, useRef } from "react"; -import { ModalBody } from "../../UploadVideo/Upload-styles"; +import { ModalBody } from "../../PublishFile/Upload-styles.tsx"; import { CircleSVG } from "../../../assets/svgs/CircleSVG"; import { EmptyCircleSVG } from "../../../assets/svgs/EmptyCircleSVG"; diff --git a/src/components/layout/Navbar/Navbar.tsx b/src/components/layout/Navbar/Navbar.tsx index d85501c..3e6b40d 100644 --- a/src/components/layout/Navbar/Navbar.tsx +++ b/src/components/layout/Navbar/Navbar.tsx @@ -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 = ({ {isAuthenticated && userName && ( <> - + )} diff --git a/src/constants/index.ts b/src/constants/Categories.ts similarity index 51% rename from src/constants/index.ts rename to src/constants/Categories.ts index 128ea8e..035afc0 100644 --- a/src/constants/index.ts +++ b/src/constants/Categories.ts @@ -1,42 +1,25 @@ -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' +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"; - -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 { +interface SubCategory { id: number; name: string; } -interface CategoryMap { +interface Categories { [key: number]: SubCategory[]; } - export const categories = [ {"id": 1, "name": "Software"}, {"id": 2, "name": "Gaming"}, {"id": 3, "name": "Media"} ]; - -export const subCategories: CategoryMap = { +export const subCategories: Categories = { 1: [ {"id": 101, "name": "OS"}, {"id": 102, "name": "Application"}, @@ -57,11 +40,7 @@ export const subCategories: CategoryMap = { {"id": 305, "name": "Other Media Formats"} ] }; - - - - -export const subCategories2: CategoryMap = { +export const subCategories2: Categories = { 201: [ // NES {"id": 20101, "name": "ROM"}, {"id": 20102, "name": "Romhack"}, @@ -73,21 +52,21 @@ export const subCategories2: CategoryMap = { {"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"} + {"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"}, @@ -115,26 +94,26 @@ export const subCategories2: CategoryMap = { {"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"} + {"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"}, @@ -144,9 +123,7 @@ export const subCategories2: CategoryMap = { {"id": 30405, "name": "Books"} ] }; - - -export const subCategories3: CategoryMap = { +export const subCategories3: Categories = { 30201: [ // Under Movies {"id": 3020101, "name": "Action & Adventure"}, {"id": 3020102, "name": "Comedy"}, @@ -184,49 +161,48 @@ export const subCategories3: CategoryMap = { {"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"} -] + {"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, diff --git a/src/constants/Identifiers.ts b/src/constants/Identifiers.ts new file mode 100644 index 0000000..66b2c8b --- /dev/null +++ b/src/constants/Identifiers.ts @@ -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_"; + + + + diff --git a/src/constants/Misc.ts b/src/constants/Misc.ts new file mode 100644 index 0000000..8aaa2a0 --- /dev/null +++ b/src/constants/Misc.ts @@ -0,0 +1 @@ +export const titleFormatter = /[^a-zA-Z0-9\s-_!?()&'",.~;:|]/g; \ No newline at end of file diff --git a/src/hooks/useFetchVideos.tsx b/src/hooks/useFetchFiles.tsx similarity index 94% rename from src/hooks/useFetchVideos.tsx rename to src/hooks/useFetchFiles.tsx index 369fb57..55d5446 100644 --- a/src/hooks/useFetchVideos.tsx +++ b/src/hooks/useFetchFiles.tsx @@ -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 } } diff --git a/src/pages/Home/Channels.tsx b/src/pages/Home/Channels.tsx index d4c62d8..d8c80a3 100644 --- a/src/pages/Home/Channels.tsx +++ b/src/pages/Home/Channels.tsx @@ -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' diff --git a/src/pages/Home/VideoList-styles.tsx b/src/pages/Home/FileList-styles.tsx similarity index 100% rename from src/pages/Home/VideoList-styles.tsx rename to src/pages/Home/FileList-styles.tsx diff --git a/src/pages/Home/VideoList.tsx b/src/pages/Home/FileList.tsx similarity index 96% rename from src/pages/Home/VideoList.tsx rename to src/pages/Home/FileList.tsx index 0cff5cd..f997cf0 100644 --- a/src/pages/Home/VideoList.tsx +++ b/src/pages/Home/FileList.tsx @@ -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 Exact Name" sx={{ marginTop: "20px", borderBottom: "1px solid white", @@ -640,7 +648,7 @@ export const VideoList = ({ mode }: VideoListProps) => { - - )} - - - - ); -}; diff --git a/src/components/common/MultiplePublish/MultiplePublishAll.tsx b/src/components/common/MultiplePublish/MultiplePublishAll.tsx new file mode 100644 index 0000000..36fc0c3 --- /dev/null +++ b/src/components/common/MultiplePublish/MultiplePublishAll.tsx @@ -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 ( + + + {publishes?.resources?.map((publish: any) => { + const unpublished = listOfUnsuccessfulPublishes.map(item => item?.identifier) + return ( + + {publish?.identifier} + {!isPublishing && hasStarted.current ? ( + <> + {!unpublished.includes(publish.identifier) ? ( + + ) : ( + + )} + + ): } + + + ); + })} + {!isPublishing && listOfUnsuccessfulPublishes.length > 0 && ( + <> + 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 + + + )} + + + + ); +}; + + +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", + }, +})); \ No newline at end of file diff --git a/src/constants/Categories.ts b/src/constants/Categories.ts index 035afc0..7a7d2ab 100644 --- a/src/constants/Categories.ts +++ b/src/constants/Categories.ts @@ -14,43 +14,50 @@ 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": 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 Gaming Systems"} - ], + {"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 Media Formats"} - ] + {"id": 305, "name": "Other"} + ].sort(sortCategory) }; -export const subCategories2: Categories = { - 201: [ // NES + +const gamingSystems = [ {"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"}, - ], + {"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"}, @@ -67,7 +74,7 @@ export const subCategories2: Categories = { {"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"}, @@ -92,7 +99,7 @@ export const subCategories2: Categories = { {"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"}, @@ -114,14 +121,14 @@ export const subCategories2: Categories = { {"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 @@ -141,7 +148,7 @@ export const subCategories3: Categories = { {"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"}, @@ -159,7 +166,7 @@ export const subCategories3: Categories = { {"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"}, @@ -177,7 +184,7 @@ export const subCategories3: Categories = { {"id": 3040514, "name": "Travel"}, {"id": 3040515, "name": "Comics & Graphic Novels"}, - ], + ].sort(sortCategory), 30101: [ // Under Music {"id": 3010101, "name": "Rock"}, {"id": 3010102, "name": "Pop"}, @@ -199,7 +206,7 @@ export const subCategories3: Categories = { {"id": 3010118, "name": "Children's Music"}, {"id": 3010119, "name": "New Age"}, {"id": 3010120, "name": "Classical Crossover"} - ] + ].sort(sortCategory) }; @@ -207,6 +214,7 @@ export const icons = { 1: softwareIcon, 2: gamingIcon, 3: mediaIcon, + 4: softwareIcon, 302: videoIcon, 301: audioIcon, 304: documentIcon diff --git a/src/pages/Home/FileList.tsx b/src/pages/Home/FileList.tsx index f997cf0..1badb83 100644 --- a/src/pages/Home/FileList.tsx +++ b/src/pages/Home/FileList.tsx @@ -376,7 +376,7 @@ export const FileList = ({ mode }: VideoListProps) => { }} onKeyDown={searchOnEnter} value={filterName} - placeholder="User's Exact Name" + placeholder="User's Name (Exact)" sx={{ marginTop: "20px", borderBottom: "1px solid white",