mirror of
https://github.com/usememos/memos.git
synced 2024-12-26 23:22:47 +08:00
feat: add pull to refresh for PagedMemoList (#4128)
This commit is contained in:
parent
1424036ccd
commit
3cbccde67e
3 changed files with 51 additions and 21 deletions
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue