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

Small Bugfixes:

IssueContent.tsx:
1. Images maintain aspect ratios and have a max height
2. Description field works in light mode

Publish modal resets properly after publish is complete

Deleted Issues no longer show on the Home Page
This commit is contained in:
Qortal Dev 2024-04-17 14:47:26 -06:00
parent 661b554a98
commit 31d4ebbdae
15 changed files with 81 additions and 69 deletions

View File

@ -5,7 +5,7 @@ import {
CustomInputField, CustomInputField,
ModalBody, ModalBody,
NewCrowdfundTitle, NewCrowdfundTitle,
} from "./Upload-styles"; } from "./EditIssue-styles.tsx";
import { Box, Modal, Typography, useTheme } from "@mui/material"; import { Box, Modal, Typography, useTheme } from "@mui/material";
import RemoveIcon from "@mui/icons-material/Remove"; import RemoveIcon from "@mui/icons-material/Remove";

View File

@ -3,7 +3,7 @@ import { CardContentContainerComment } from "../common/Comments/Comments-styles"
import { import {
CrowdfundSubTitle, CrowdfundSubTitle,
CrowdfundSubTitleRow, CrowdfundSubTitleRow,
} from "../PublishIssue/Upload-styles.tsx"; } from "../PublishIssue/PublishIssue-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";

View File

@ -3,7 +3,7 @@ import { CardContentContainerComment } from "../common/Comments/Comments-styles"
import { import {
CrowdfundSubTitle, CrowdfundSubTitle,
CrowdfundSubTitleRow, CrowdfundSubTitleRow,
} from "../PublishIssue/Upload-styles.tsx"; } from "../PublishIssue/PublishIssue-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

@ -6,7 +6,7 @@ import {
ModalBody, ModalBody,
NewCrowdfundTitle, NewCrowdfundTitle,
StyledButton, StyledButton,
} from "./Upload-styles"; } from "./PublishIssue-styles.tsx";
import { Box, Modal, Typography, useTheme } from "@mui/material"; import { Box, Modal, Typography, useTheme } from "@mui/material";
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";
@ -74,8 +74,6 @@ export const PublishIssue = ({ editId, editContent }: NewCrowdfundProps) => {
useState<any>(null); useState<any>(null);
const [playlistTitle, setPlaylistTitle] = useState<string>(""); const [playlistTitle, setPlaylistTitle] = useState<string>("");
const [playlistDescription, setPlaylistDescription] = useState<string>(""); const [playlistDescription, setPlaylistDescription] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<any>(null);
const [selectedSubCategory, setSelectedSubCategory] = useState<any>(null);
const [playlistSetting, setPlaylistSetting] = useState<null | string>(null); const [playlistSetting, setPlaylistSetting] = useState<null | string>(null);
const [publishes, setPublishes] = useState<any>(null); const [publishes, setPublishes] = useState<any>(null);
@ -479,12 +477,13 @@ export const PublishIssue = ({ editId, editContent }: NewCrowdfundProps) => {
setFiles([]); setFiles([]);
setStep("videos"); setStep("videos");
setPlaylistCoverImage(null); setPlaylistCoverImage(null);
setTitle("");
setPlaylistTitle(""); setPlaylistTitle("");
setPlaylistDescription(""); setPlaylistDescription("");
setSelectedCategory(null); setDescription("");
setSelectedSubCategory(null);
setPlaylistSetting(null); setPlaylistSetting(null);
categoryListRef.current?.clearCategories(); categoryListRef.current?.clearCategories();
imagePublisherRef.current?.setImageArray([]);
dispatch( dispatch(
setNotification({ setNotification({
msg: "Issue published", msg: "Issue published",

View File

@ -3,7 +3,7 @@ import { styled } from "@mui/system";
import { Grid } from "@mui/material"; import { Grid } from "@mui/material";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { RootState } from "../state/store.ts"; import { RootState } from "../state/store.ts";
import { useFetchFiles } from "../hooks/useFetchFiles.tsx"; import { useFetchIssues } from "../hooks/useFetchIssues.tsx";
export const StatsData = () => { export const StatsData = () => {
const StatsCol = styled(Grid)(({ theme }) => ({ const StatsCol = styled(Grid)(({ theme }) => ({
@ -23,7 +23,7 @@ export const StatsData = () => {
checkNewFiles, checkNewFiles,
getFilesFiltered, getFilesFiltered,
getFilesCount, getFilesCount,
} = useFetchFiles(); } = useFetchIssues();
const totalIssuesPublished = useSelector( const totalIssuesPublished = useSelector(
(state: RootState) => state.global.totalFilesPublished (state: RootState) => state.global.totalFilesPublished

View File

@ -18,7 +18,7 @@ import { QSUPPORT_COMMENT_BASE } from "../../../constants/Identifiers.ts";
import { import {
CrowdfundSubTitle, CrowdfundSubTitle,
CrowdfundSubTitleRow, CrowdfundSubTitleRow,
} from "../../PublishIssue/Upload-styles.tsx"; } from "../../PublishIssue/PublishIssue-styles.tsx";
interface CommentSectionProps { interface CommentSectionProps {
postId: string; postId: string;

View File

@ -11,6 +11,7 @@ import { useTheme } from "@mui/material";
export type ImagePublisherRef = { export type ImagePublisherRef = {
getImageArray: () => string[]; getImageArray: () => string[];
setImageArray: (imageArray: string[]) => void;
}; };
interface ImagePublisherProps { interface ImagePublisherProps {
@ -27,6 +28,9 @@ export const ImagePublisher = React.forwardRef<
getImageArray: () => { getImageArray: () => {
return imageArray; return imageArray;
}, },
setImageArray: (imageArray: string[]) => {
setImageArray(imageArray);
},
})); }));
return ( return (

View File

@ -3,30 +3,30 @@ import { useDispatch, useSelector } from "react-redux";
import { import {
addFiles, addFiles,
addToHashMap, addToHashMap,
removeFromHashMap,
setCountNewFiles, setCountNewFiles,
upsertFiles, upsertFiles,
upsertFilesBeginning, upsertFilesBeginning,
Video,
upsertFilteredFiles, upsertFilteredFiles,
Video,
} from "../state/features/fileSlice.ts"; } from "../state/features/fileSlice.ts";
import { import {
setFilesPerNamePublished,
setIsLoadingGlobal, setIsLoadingGlobal,
setUserAvatarHash,
setTotalFilesPublished, setTotalFilesPublished,
setTotalNamesPublished, setTotalNamesPublished,
setFilesPerNamePublished, setUserAvatarHash,
} from "../state/features/globalSlice"; } from "../state/features/globalSlice";
import { RootState } from "../state/store"; import { RootState } from "../state/store";
import { fetchAndEvaluateVideos } from "../utils/fetchVideos"; import { fetchAndEvaluateIssues } from "../utils/fetchVideos";
import { import {
QSUPPORT_PLAYLIST_BASE,
QSUPPORT_FILE_BASE, QSUPPORT_FILE_BASE,
QSUPPORT_PLAYLIST_BASE,
} from "../constants/Identifiers.ts"; } from "../constants/Identifiers.ts";
import { RequestQueue } from "../utils/queue";
import { queue } from "../wrappers/GlobalWrapper"; import { queue } from "../wrappers/GlobalWrapper";
import { getCategoriesFetchString } from "../components/common/CategoryList/CategoryList.tsx"; import { getCategoriesFetchString } from "../components/common/CategoryList/CategoryList.tsx";
export const useFetchFiles = () => { export const useFetchIssues = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const hashMapFiles = useSelector( const hashMapFiles = useSelector(
(state: RootState) => state.file.hashMapFiles (state: RootState) => state.file.hashMapFiles
@ -49,7 +49,7 @@ export const useFetchFiles = () => {
(state: RootState) => state.global.filesPerNamePublished (state: RootState) => state.global.filesPerNamePublished
); );
const checkAndUpdateFile = React.useCallback( const checkAndUpdateIssue = React.useCallback(
(video: Video) => { (video: Video) => {
const existingVideo = hashMapFiles[video.id]; const existingVideo = hashMapFiles[video.id];
if (!existingVideo) { if (!existingVideo) {
@ -85,27 +85,29 @@ export const useFetchFiles = () => {
} catch (error) {} } catch (error) {}
}, []); }, []);
const getFile = async ( const getIssue = async (
user: string, user: string,
videoId: string, issueID: string,
content: any, content: any,
retries: number = 0 retries: number = 0
) => { ) => {
try { try {
const res = await fetchAndEvaluateVideos({ const res = await fetchAndEvaluateIssues({
user, user,
videoId, videoId: issueID,
content, content,
}); });
console.log("response is: ", res);
dispatch(addToHashMap(res)); res?.isValid
? dispatch(addToHashMap(res))
: dispatch(removeFromHashMap(issueID));
} catch (error) { } catch (error) {
retries = retries + 1; retries = retries + 1;
if (retries < 2) { if (retries < 2) {
// 3 is the maximum number of retries here, you can adjust it to your needs // 3 is the maximum number of retries here, you can adjust it to your needs
queue.push(() => getFile(user, videoId, content, retries + 1)); queue.push(() => getIssue(user, issueID, content, retries + 1));
} else { } else {
console.error("Failed to get video after 3 attempts", error); console.error("Failed to get issue after 3 attempts", error);
} }
} }
}; };
@ -172,9 +174,9 @@ export const useFetchFiles = () => {
}, 1000); }, 1000);
for (const content of structureData) { for (const content of structureData) {
if (content.user && content.id) { if (content.user && content.id) {
const res = checkAndUpdateFile(content); const res = checkAndUpdateIssue(content);
if (res) { if (res) {
queue.push(() => getFile(content.user, content.id, content)); queue.push(() => getIssue(content.user, content.id, content));
} }
} }
} }
@ -269,9 +271,9 @@ export const useFetchFiles = () => {
} }
for (const content of structureData) { for (const content of structureData) {
if (content.user && content.id) { if (content.user && content.id) {
const res = checkAndUpdateFile(content); const res = checkAndUpdateIssue(content);
if (res) { if (res) {
queue.push(() => getFile(content.user, content.id, content)); queue.push(() => getIssue(content.user, content.id, content));
} }
} }
} }
@ -330,9 +332,9 @@ export const useFetchFiles = () => {
for (const content of structureData) { for (const content of structureData) {
if (content.user && content.id) { if (content.user && content.id) {
const res = checkAndUpdateFile(content); const res = checkAndUpdateIssue(content);
if (res) { if (res) {
queue.push(() => getFile(content.user, content.id, content)); queue.push(() => getIssue(content.user, content.id, content));
} }
} }
} }
@ -410,8 +412,8 @@ export const useFetchFiles = () => {
return { return {
getFiles, getFiles,
checkAndUpdateFile, checkAndUpdateFile: checkAndUpdateIssue,
getFile, getFile: getIssue,
hashMapFiles, hashMapFiles,
getNewFiles, getNewFiles,
checkNewFiles, checkNewFiles,

View File

@ -5,7 +5,7 @@ import { RootState } from "../../state/store";
import AttachFileIcon from "@mui/icons-material/AttachFile"; import AttachFileIcon from "@mui/icons-material/AttachFile";
import { Avatar, Box, Skeleton, useTheme } from "@mui/material"; import { Avatar, Box, Skeleton, useTheme } from "@mui/material";
import { useFetchFiles } from "../../hooks/useFetchFiles.tsx"; import { useFetchIssues } from "../../hooks/useFetchIssues.tsx";
import LazyLoad from "../../components/common/LazyLoad"; import LazyLoad from "../../components/common/LazyLoad";
import { import {
BottomParent, BottomParent,
@ -41,7 +41,7 @@ export const FileListComponentLevel = ({ mode }: VideoListProps) => {
const navigate = useNavigate(); const navigate = useNavigate();
const { getFile, getNewFiles, checkNewFiles, checkAndUpdateFile } = const { getFile, getNewFiles, checkNewFiles, checkAndUpdateFile } =
useFetchFiles(); useFetchIssues();
const getVideos = React.useCallback(async () => { const getVideos = React.useCallback(async () => {
try { try {

View File

@ -4,7 +4,7 @@ import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../state/store"; import { RootState } from "../../state/store";
import { IssueList } from "./IssueList.tsx"; import { IssueList } from "./IssueList.tsx";
import { Box, Grid, Input, useTheme } from "@mui/material"; import { Box, Grid, Input, useTheme } from "@mui/material";
import { useFetchFiles } from "../../hooks/useFetchFiles.tsx"; import { useFetchIssues } from "../../hooks/useFetchIssues.tsx";
import LazyLoad from "../../components/common/LazyLoad"; import LazyLoad from "../../components/common/LazyLoad";
import { FiltersCol, FiltersContainer } from "./IssueList-styles.tsx"; import { FiltersCol, FiltersContainer } from "./IssueList-styles.tsx";
import { SubtitleContainer, ThemeButton } from "./Home-styles"; import { SubtitleContainer, ThemeButton } from "./Home-styles";
@ -87,7 +87,7 @@ export const Home = ({ mode }: HomeProps) => {
checkNewFiles, checkNewFiles,
getFilesFiltered, getFilesFiltered,
getFilesCount, getFilesCount,
} = useFetchFiles(); } = useFetchIssues();
const getFilesHandler = React.useCallback( const getFilesHandler = React.useCallback(
async (reset?: boolean, resetFilers?: boolean) => { async (reset?: boolean, resetFilers?: boolean) => {
@ -314,7 +314,7 @@ export const Home = ({ mode }: HomeProps) => {
maxWidth: "1400px", maxWidth: "1400px",
}} }}
></SubtitleContainer> ></SubtitleContainer>
<IssueList files={videos} /> <IssueList issues={videos} />
<LazyLoad <LazyLoad
onLoadMore={getFilesHandler} onLoadMore={getFilesHandler}
isLoading={isLoading} isLoading={isLoading}

View File

@ -20,17 +20,17 @@ import BlockIcon from "@mui/icons-material/Block";
import AttachFileIcon from "@mui/icons-material/AttachFile"; import AttachFileIcon from "@mui/icons-material/AttachFile";
import { formatBytes } from "../IssueContent/IssueContent.tsx"; import { formatBytes } from "../IssueContent/IssueContent.tsx";
import { formatDate } from "../../utils/time.ts"; import { formatDate } from "../../utils/time.ts";
import React, { useState } from "react"; import React, { useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../state/store.ts"; import { RootState } from "../../state/store.ts";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { getIconsFromObject } from "../../constants/Categories/CategoryFunctions.ts"; import { getIconsFromObject } from "../../constants/Categories/CategoryFunctions.ts";
interface FileListProps { interface FileListProps {
files: Video[]; issues: Video[];
} }
export const IssueList = ({ files }: FileListProps) => { export const IssueList = ({ issues }: FileListProps) => {
const hashMapFiles = useSelector( const hashMapIssues = useSelector(
(state: RootState) => state.file.hashMapFiles (state: RootState) => state.file.hashMapFiles
); );
@ -55,10 +55,14 @@ export const IssueList = ({ files }: FileListProps) => {
} catch (error) {} } catch (error) {}
}; };
const filteredIssues = useMemo(() => {
return issues.filter((issue: any) => hashMapIssues[issue.id]?.isValid);
}, [issues, hashMapIssues]);
return ( return (
<FileContainer> <FileContainer>
{files.map((file: any, index: number) => { {filteredIssues.map((file: any, index: number) => {
const existingFile = hashMapFiles[file?.id]; const existingFile = hashMapIssues[file?.id];
let hasHash = false; let hasHash = false;
let fileObj = file; let fileObj = file;
if (existingFile) { if (existingFile) {

View File

@ -412,9 +412,13 @@ export const IssueContent = () => {
return ( return (
<img <img
src={image} src={image}
width={`${1280 / fileData.images.length}px`} width={`${1080 / fileData.images.length}px`}
height={"480px"} style={{
style={{ marginRight: "10px", marginBottom: "10px" }} marginRight: "10px",
marginBottom: "10px",
objectFit: "contain",
maxHeight: "50vh",
}}
/> />
); );
})} })}
@ -422,7 +426,7 @@ export const IssueContent = () => {
<Spacer height="15px" /> <Spacer height="15px" />
<Box <Box
sx={{ sx={{
background: "#333333", background: theme.palette.mode === "dark" ? "#333333" : "#CCCCCC",
borderRadius: "5px", borderRadius: "5px",
padding: "5px", padding: "5px",
width: "100%", width: "100%",

View File

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