mirror of
https://github.com/Qortal/q-support.git
synced 2025-11-02 01:37:03 +00:00
(Done by greenflame089) Issues can be sorted by Newest, Oldest, Publisher User, and Bounty.
All issues are loaded at once on startup, so that they can be sorted properly.
This commit is contained in:
@@ -210,7 +210,7 @@ export const useFetchIssues = () => {
|
||||
if (reset) {
|
||||
offset = 0;
|
||||
}
|
||||
const videoLimit = limit || 50;
|
||||
const videoLimit = limit || 0;
|
||||
let defaultUrl = `/arbitrary/resources/search?mode=ALL&includemetadata=false&reverse=true&excludeblocked=true&exactmatchnames=true&offset=${offset}&limit=${videoLimit}`;
|
||||
|
||||
if (name) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Box, Grid, Input, useTheme } from "@mui/material";
|
||||
import { Box, Grid, Input, Select, MenuItem, useTheme } from "@mui/material";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
@@ -42,6 +42,7 @@ export const Home = ({ mode }: HomeProps) => {
|
||||
const isFiltering = useSelector((state: RootState) => state.file.isFiltering);
|
||||
const filterValue = useSelector((state: RootState) => state.file.filterValue);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [sortOption, setSortOption] = useState<string>("Newest");
|
||||
const filterType = useSelector((state: RootState) => state.file.filterType);
|
||||
|
||||
const setFilterType = payload => {
|
||||
@@ -187,6 +188,7 @@ export const Home = ({ mode }: HomeProps) => {
|
||||
setFilterType("videos");
|
||||
setFilterSearch("");
|
||||
setFilterName("");
|
||||
setSortOption("Newest");
|
||||
categoryListRef.current?.clearCategories();
|
||||
categorySelectRef.current?.clearCategory();
|
||||
autocompleteRef.current?.setSelectedValue(null);
|
||||
@@ -296,6 +298,19 @@ export const Home = ({ mode }: HomeProps) => {
|
||||
/>
|
||||
)}
|
||||
|
||||
<Box sx={{ marginTop: "20px" }}>
|
||||
<Select
|
||||
value={sortOption}
|
||||
onChange={e => setSortOption(e.target.value as string)}
|
||||
sx={{ width: "100%" }}
|
||||
>
|
||||
<MenuItem value="Newest">Sort by Newest</MenuItem>
|
||||
<MenuItem value="Oldest">Sort by Oldest</MenuItem>
|
||||
<MenuItem value="User">Sort by User</MenuItem>
|
||||
<MenuItem value="Bounty">Sort by Bounty</MenuItem>
|
||||
</Select>
|
||||
</Box>
|
||||
|
||||
<ThemeButton
|
||||
onClick={() => {
|
||||
filtersToDefault();
|
||||
@@ -340,7 +355,7 @@ export const Home = ({ mode }: HomeProps) => {
|
||||
maxWidth: "1400px",
|
||||
}}
|
||||
></SubtitleContainer>
|
||||
<IssueList issues={issues} />
|
||||
<IssueList issues={issues} sortOption={sortOption} />
|
||||
<LazyLoad
|
||||
onLoadMore={getIssuesHandler}
|
||||
isLoading={isLoading}
|
||||
|
||||
@@ -34,8 +34,9 @@ import {
|
||||
|
||||
interface FileListProps {
|
||||
issues: Issue[];
|
||||
sortOption: string;
|
||||
}
|
||||
export const IssueList = ({ issues }: FileListProps) => {
|
||||
export const IssueList = ({ issues, sortOption }: FileListProps) => {
|
||||
const hashMapIssues = useSelector(
|
||||
(state: RootState) => state.file.hashMapFiles
|
||||
);
|
||||
@@ -67,10 +68,43 @@ export const IssueList = ({ issues }: FileListProps) => {
|
||||
return issues.filter((issue: any) => hashMapIssues[issue.id]?.isValid);
|
||||
}, [issues, hashMapIssues]);
|
||||
|
||||
const ts = (value: number | string | undefined): number => {
|
||||
if (value == null) return 0;
|
||||
return typeof value === "number"
|
||||
? value
|
||||
: Date.parse(value);
|
||||
};
|
||||
|
||||
const sortedIssues = useMemo(() => {
|
||||
const sorted = [...filteredIssues];
|
||||
switch (sortOption) {
|
||||
case "Oldest":
|
||||
sorted.sort((a, b) => ts(a.created) - ts(b.created));
|
||||
break;
|
||||
case "User":
|
||||
sorted.sort((a, b) => (a.user || "").localeCompare(b.user || "", undefined, { sensitivity: "base" }));
|
||||
break;
|
||||
case "Bounty":
|
||||
sorted.sort((a, b) => {
|
||||
const bountyA = Number(a.bountyData?.amount) || 0;
|
||||
const bountyB = Number(b.bountyData?.amount) || 0;
|
||||
if (bountyA === bountyB) {
|
||||
return ts(b.created) - ts(a.created);
|
||||
}
|
||||
return bountyB - bountyA;
|
||||
});
|
||||
break;
|
||||
case "Newest":
|
||||
default:
|
||||
sorted.sort((a, b) => ts(b.created) - ts(a.created));
|
||||
}
|
||||
return sorted;
|
||||
}, [filteredIssues, sortOption]);
|
||||
|
||||
return (
|
||||
<IssueContainer>
|
||||
{filteredIssues.map((issue: any, index: number) => {
|
||||
const existingFile = hashMapIssues[issue?.id];
|
||||
{sortedIssues.map((issue: Issue, index: number) => {
|
||||
const existingFile = hashMapIssues[issue.id];
|
||||
let hasHash = false;
|
||||
let issueObj = issue;
|
||||
if (existingFile) {
|
||||
@@ -217,7 +251,7 @@ export const IssueList = ({ issues }: FileListProps) => {
|
||||
|
||||
{issueObj?.created && (
|
||||
<VideoUploadDate>
|
||||
{formatDate(issueObj.created)}
|
||||
{formatDate(ts(issueObj.created))}
|
||||
</VideoUploadDate>
|
||||
)}
|
||||
</NameAndDateContainer>
|
||||
|
||||
Reference in New Issue
Block a user