feat: add pull to refresh for PagedMemoList (#4128)

This commit is contained in:
nlfox 2024-11-19 07:34:47 -08:00 committed by GitHub
parent 1424036ccd
commit 3cbccde67e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 51 additions and 21 deletions

View file

@ -41,6 +41,7 @@
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"react-router-dom": "^6.27.0", "react-router-dom": "^6.27.0",
"react-simple-pull-to-refresh": "^1.3.3",
"react-use": "^17.5.1", "react-use": "^17.5.1",
"tailwind-merge": "^2.5.4", "tailwind-merge": "^2.5.4",
"tailwindcss": "^3.4.14", "tailwindcss": "^3.4.14",

View file

@ -104,6 +104,9 @@ importers:
react-router-dom: react-router-dom:
specifier: ^6.27.0 specifier: ^6.27.0
version: 6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-simple-pull-to-refresh:
specifier: ^1.3.3
version: 1.3.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-use: react-use:
specifier: ^17.5.1 specifier: ^17.5.1
version: 17.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 17.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -2968,6 +2971,12 @@ packages:
peerDependencies: peerDependencies:
react: '>=16.8' react: '>=16.8'
react-simple-pull-to-refresh@1.3.3:
resolution: {integrity: sha512-6qXsa5RtNVmKJhLWvDLIX8UK51HFtCEGjdqQGf+M1Qjrcc4qH4fki97sgVpGEFBRwbY7DiVDA5N5p97kF16DTw==}
peerDependencies:
react: ^16.10.2 || ^17.0.0 || ^18.0.0
react-dom: ^16.10.2 || ^17.0.0 || ^18.0.0
react-style-singleton@2.2.1: react-style-singleton@2.2.1:
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -6449,6 +6458,11 @@ snapshots:
'@remix-run/router': 1.20.0 '@remix-run/router': 1.20.0
react: 18.3.1 react: 18.3.1
react-simple-pull-to-refresh@1.3.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
react-style-singleton@2.2.1(@types/react@18.3.12)(react@18.3.1): react-style-singleton@2.2.1(@types/react@18.3.12)(react@18.3.1):
dependencies: dependencies:
get-nonce: 1.0.1 get-nonce: 1.0.1

View file

@ -1,6 +1,7 @@
import { Button } from "@usememos/mui"; import { Button } from "@usememos/mui";
import { ArrowDownIcon, LoaderIcon } from "lucide-react"; import { ArrowDownIcon, LoaderIcon } from "lucide-react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import PullToRefresh from "react-simple-pull-to-refresh";
import { DEFAULT_LIST_MEMOS_PAGE_SIZE } from "@/helpers/consts"; import { DEFAULT_LIST_MEMOS_PAGE_SIZE } from "@/helpers/consts";
import { useMemoList, useMemoStore } from "@/store/v1"; import { useMemoList, useMemoStore } from "@/store/v1";
import { Memo } from "@/types/proto/api/v1/memo_service"; import { Memo } from "@/types/proto/api/v1/memo_service";
@ -28,7 +29,11 @@ const PagedMemoList = (props: Props) => {
nextPageToken: "", nextPageToken: "",
}); });
const sortedMemoList = props.listSort ? props.listSort(memoList.value) : memoList.value; const sortedMemoList = props.listSort ? props.listSort(memoList.value) : memoList.value;
const handleRefresh = async () => {
memoList.reset();
setState((state) => ({ ...state, nextPageToken: "" }));
fetchMoreMemos("");
};
const setIsRequesting = (isRequesting: boolean) => { const setIsRequesting = (isRequesting: boolean) => {
setState((state) => ({ ...state, isRequesting })); setState((state) => ({ ...state, isRequesting }));
}; };
@ -53,28 +58,38 @@ const PagedMemoList = (props: Props) => {
}, [props.filter, props.pageSize]); }, [props.filter, props.pageSize]);
return ( return (
<> <PullToRefresh
{sortedMemoList.map((memo) => props.renderer(memo))} onRefresh={handleRefresh}
{state.isRequesting && ( pullingContent={<></>}
refreshingContent={
<div className="w-full flex flex-row justify-center items-center my-4"> <div className="w-full flex flex-row justify-center items-center my-4">
<LoaderIcon className="animate-spin text-zinc-500" /> <LoaderIcon className="animate-spin" />
</div> </div>
)} }
{!state.isRequesting && state.nextPageToken && ( >
<div className="w-full flex flex-row justify-center items-center my-4"> <>
<Button variant="plain" onClick={() => fetchMoreMemos(state.nextPageToken)}> {sortedMemoList.map((memo) => props.renderer(memo))}
{t("memo.load-more")} {state.isRequesting && (
<ArrowDownIcon className="ml-2 w-4 h-auto" /> <div className="w-full flex flex-row justify-center items-center my-4">
</Button> <LoaderIcon className="animate-spin text-zinc-500" />
</div> </div>
)} )}
{!state.isRequesting && !state.nextPageToken && sortedMemoList.length === 0 && ( {!state.isRequesting && state.nextPageToken && (
<div className="w-full mt-12 mb-8 flex flex-col justify-center items-center italic"> <div className="w-full flex flex-row justify-center items-center my-4">
<Empty /> <Button variant="plain" onClick={() => fetchMoreMemos(state.nextPageToken)}>
<p className="mt-2 text-gray-600 dark:text-gray-400">{t("message.no-data")}</p> {t("memo.load-more")}
</div> <ArrowDownIcon className="ml-2 w-4 h-auto" />
)} </Button>
</> </div>
)}
{!state.isRequesting && !state.nextPageToken && sortedMemoList.length === 0 && (
<div className="w-full mt-12 mb-8 flex flex-col justify-center items-center italic">
<Empty />
<p className="mt-2 text-gray-600 dark:text-gray-400">{t("message.no-data")}</p>
</div>
)}
</>
</PullToRefresh>
); );
}; };