mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 20:27:23 +00:00
feat: add collection
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import showToast from "./toast";
|
||||
import { network } from "../network/network";
|
||||
import { InfoAlert } from "./alert";
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import { useNavigate } from "react-router";
|
||||
import { MdOutlineComment } from "react-icons/md";
|
||||
import { Comment } from "../network/models";
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { MdAdd } from "react-icons/md";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import { network } from "../network/network.ts";
|
||||
import showToast from "./toast.ts";
|
||||
import { useState } from "react";
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
|
||||
export default function Loading() {
|
||||
const { t } = useTranslation();
|
||||
|
@@ -3,7 +3,7 @@ import { network } from "../network/network.ts";
|
||||
import { useNavigate, useOutlet } from "react-router";
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
import { MdArrowUpward, MdOutlinePerson, MdSearch } from "react-icons/md";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import UploadingSideBar from "./uploading_side_bar.tsx";
|
||||
import { ThemeSwitcher } from "./theme_switcher.tsx";
|
||||
import { IoLogoGithub } from "react-icons/io";
|
||||
|
@@ -2,8 +2,15 @@ import { Resource } from "../network/models.ts";
|
||||
import { network } from "../network/network.ts";
|
||||
import { useNavigate } from "react-router";
|
||||
import Badge from "./badge.tsx";
|
||||
import React from "react";
|
||||
|
||||
export default function ResourceCard({ resource }: { resource: Resource }) {
|
||||
export default function ResourceCard({
|
||||
resource,
|
||||
action,
|
||||
}: {
|
||||
resource: Resource;
|
||||
action?: React.ReactNode;
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
let tags = resource.tags;
|
||||
@@ -58,6 +65,8 @@ export default function ResourceCard({ resource }: { resource: Resource }) {
|
||||
</div>
|
||||
<div className="w-2"></div>
|
||||
<div className="text-sm">{resource.author.username}</div>
|
||||
<div className="flex-1"></div>
|
||||
{action}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -9,9 +9,11 @@ import { useAppContext } from "./AppContext.tsx";
|
||||
export default function ResourcesView({
|
||||
loader,
|
||||
storageKey,
|
||||
actionBuilder,
|
||||
}: {
|
||||
loader: (page: number) => Promise<PageResponse<Resource>>;
|
||||
storageKey?: string;
|
||||
actionBuilder?: (resource: Resource) => React.ReactNode;
|
||||
}) {
|
||||
const [data, setData] = useState<Resource[]>([]);
|
||||
const pageRef = useRef(1);
|
||||
@@ -54,7 +56,8 @@ export default function ResourcesView({
|
||||
isLoadingRef.current = false;
|
||||
pageRef.current = pageRef.current + 1;
|
||||
totalPagesRef.current = res.totalPages ?? 1;
|
||||
setData((prev) => [...prev, ...res.data!]);
|
||||
let data = res.data ?? [];
|
||||
setData((prev) => [...prev, ...data]);
|
||||
}
|
||||
}, [loader]);
|
||||
|
||||
@@ -71,7 +74,13 @@ export default function ResourcesView({
|
||||
columnWidth={300}
|
||||
items={data}
|
||||
render={(e) => {
|
||||
return <ResourceCard resource={e.data} key={e.data.id} />;
|
||||
return (
|
||||
<ResourceCard
|
||||
resource={e.data}
|
||||
key={e.data.id}
|
||||
action={actionBuilder?.(e.data)}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
></Masonry>
|
||||
{pageRef.current <= totalPagesRef.current && <Loading />}
|
||||
|
@@ -1,12 +1,13 @@
|
||||
import { Tag } from "../network/models.ts";
|
||||
import { useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import { network } from "../network/network.ts";
|
||||
import { LuInfo } from "react-icons/lu";
|
||||
import { MdSearch } from "react-icons/md";
|
||||
import Button from "./button.tsx";
|
||||
import Input, { TextArea } from "./input.tsx";
|
||||
import { ErrorAlert } from "./alert.tsx";
|
||||
import { Debounce } from "../utils/debounce.ts";
|
||||
|
||||
export default function TagInput({
|
||||
onAdd,
|
||||
@@ -177,31 +178,6 @@ export default function TagInput({
|
||||
);
|
||||
}
|
||||
|
||||
class Debounce {
|
||||
private timer: number | null = null;
|
||||
private readonly delay: number;
|
||||
|
||||
constructor(delay: number) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
run(callback: () => void) {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
this.timer = setTimeout(() => {
|
||||
callback();
|
||||
}, this.delay);
|
||||
}
|
||||
|
||||
cancel() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function QuickAddTagDialog({
|
||||
onAdded,
|
||||
}: {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import { MdPalette } from "react-icons/md";
|
||||
|
||||
interface ThemeOption {
|
||||
|
@@ -10,7 +10,7 @@ export default function showToast({
|
||||
type = type || "info";
|
||||
const div = document.createElement("div");
|
||||
div.innerHTML = `
|
||||
<div class="toast toast-center">
|
||||
<div class="toast toast-center z-10">
|
||||
<div class="alert shadow ${type === "success" && "alert-success"} ${type === "error" && "alert-error"} ${type === "warning" && "alert-warning"} ${type === "info" && "alert-info"}">
|
||||
<span>${message}</span>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user