implemented infinite loading

This commit is contained in:
Ren Amamiya 2023-02-28 14:53:27 +07:00
parent f4b5764db6
commit 964343ccc8
6 changed files with 122 additions and 121 deletions

View File

@ -48,8 +48,8 @@
"@types/node": "^18.14.2",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"autoprefixer": "^10.4.13",
"csstype": "^3.1.1",
"eslint": "^8.35.0",

View File

@ -13,8 +13,8 @@ specifiers:
'@types/node': ^18.14.2
'@types/react': ^18.0.28
'@types/react-dom': ^18.0.11
'@typescript-eslint/eslint-plugin': ^5.53.0
'@typescript-eslint/parser': ^5.53.0
'@typescript-eslint/eslint-plugin': ^5.54.0
'@typescript-eslint/parser': ^5.54.0
'@uiw/react-markdown-preview': ^4.1.9
'@uiw/react-md-editor': ^3.20.5
autoprefixer: ^10.4.13
@ -90,8 +90,8 @@ devDependencies:
'@types/node': 18.14.2
'@types/react': 18.0.28
'@types/react-dom': 18.0.11
'@typescript-eslint/eslint-plugin': 5.53.0_cjo54hduev4bqhpjw5znwiokqu
'@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/eslint-plugin': 5.54.0_6mj2wypvdnknez7kws2nfdgupi
'@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
autoprefixer: 10.4.13_postcss@8.4.21
csstype: 3.1.1
eslint: 8.35.0
@ -1240,8 +1240,8 @@ packages:
resolution: { integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== }
dev: false
/@typescript-eslint/eslint-plugin/5.53.0_cjo54hduev4bqhpjw5znwiokqu:
resolution: { integrity: sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw== }
/@typescript-eslint/eslint-plugin/5.54.0_6mj2wypvdnknez7kws2nfdgupi:
resolution: { integrity: sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
peerDependencies:
'@typescript-eslint/parser': ^5.0.0
@ -1251,10 +1251,10 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/scope-manager': 5.53.0
'@typescript-eslint/type-utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/scope-manager': 5.54.0
'@typescript-eslint/type-utils': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/utils': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
debug: 4.3.4
eslint: 8.35.0
grapheme-splitter: 1.0.4
@ -1268,8 +1268,8 @@ packages:
- supports-color
dev: true
/@typescript-eslint/parser/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu:
resolution: { integrity: sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ== }
/@typescript-eslint/parser/5.54.0_ycpbpc6yetojsgtrx3mwntkhsu:
resolution: { integrity: sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@ -1278,9 +1278,9 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 5.53.0
'@typescript-eslint/types': 5.53.0
'@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5
'@typescript-eslint/scope-manager': 5.54.0
'@typescript-eslint/types': 5.54.0
'@typescript-eslint/typescript-estree': 5.54.0_typescript@4.9.5
debug: 4.3.4
eslint: 8.35.0
typescript: 4.9.5
@ -1288,16 +1288,16 @@ packages:
- supports-color
dev: true
/@typescript-eslint/scope-manager/5.53.0:
resolution: { integrity: sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w== }
/@typescript-eslint/scope-manager/5.54.0:
resolution: { integrity: sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
dependencies:
'@typescript-eslint/types': 5.53.0
'@typescript-eslint/visitor-keys': 5.53.0
'@typescript-eslint/types': 5.54.0
'@typescript-eslint/visitor-keys': 5.54.0
dev: true
/@typescript-eslint/type-utils/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu:
resolution: { integrity: sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw== }
/@typescript-eslint/type-utils/5.54.0_ycpbpc6yetojsgtrx3mwntkhsu:
resolution: { integrity: sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
peerDependencies:
eslint: '*'
@ -1306,8 +1306,8 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5
'@typescript-eslint/utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/typescript-estree': 5.54.0_typescript@4.9.5
'@typescript-eslint/utils': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
debug: 4.3.4
eslint: 8.35.0
tsutils: 3.21.0_typescript@4.9.5
@ -1316,13 +1316,13 @@ packages:
- supports-color
dev: true
/@typescript-eslint/types/5.53.0:
resolution: { integrity: sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A== }
/@typescript-eslint/types/5.54.0:
resolution: { integrity: sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
dev: true
/@typescript-eslint/typescript-estree/5.53.0_typescript@4.9.5:
resolution: { integrity: sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w== }
/@typescript-eslint/typescript-estree/5.54.0_typescript@4.9.5:
resolution: { integrity: sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
peerDependencies:
typescript: '*'
@ -1330,8 +1330,8 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 5.53.0
'@typescript-eslint/visitor-keys': 5.53.0
'@typescript-eslint/types': 5.54.0
'@typescript-eslint/visitor-keys': 5.54.0
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
@ -1342,17 +1342,17 @@ packages:
- supports-color
dev: true
/@typescript-eslint/utils/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu:
resolution: { integrity: sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g== }
/@typescript-eslint/utils/5.54.0_ycpbpc6yetojsgtrx3mwntkhsu:
resolution: { integrity: sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
'@types/json-schema': 7.0.11
'@types/semver': 7.3.13
'@typescript-eslint/scope-manager': 5.53.0
'@typescript-eslint/types': 5.53.0
'@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5
'@typescript-eslint/scope-manager': 5.54.0
'@typescript-eslint/types': 5.54.0
'@typescript-eslint/typescript-estree': 5.54.0_typescript@4.9.5
eslint: 8.35.0
eslint-scope: 5.1.1
eslint-utils: 3.0.0_eslint@8.35.0
@ -1362,11 +1362,11 @@ packages:
- typescript
dev: true
/@typescript-eslint/visitor-keys/5.53.0:
resolution: { integrity: sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w== }
/@typescript-eslint/visitor-keys/5.54.0:
resolution: { integrity: sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA== }
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
dependencies:
'@typescript-eslint/types': 5.53.0
'@typescript-eslint/types': 5.54.0
eslint-visitor-keys: 3.3.0
dev: true
@ -1733,7 +1733,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001458
electron-to-chromium: 1.4.311
electron-to-chromium: 1.4.313
node-releases: 2.0.10
update-browserslist-db: 1.0.10_browserslist@4.21.5
@ -2047,8 +2047,8 @@ packages:
resolution: { integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== }
dev: true
/electron-to-chromium/1.4.311:
resolution: { integrity: sha512-RoDlZufvrtr2Nx3Yx5MB8jX3aHIxm8nRWPJm3yVvyHmyKaRvn90RjzB6hNnt0AkhS3IInJdyRfQb4mWhPvUjVw== }
/electron-to-chromium/1.4.313:
resolution: { integrity: sha512-QckB9OVqr2oybjIrbMI99uF+b9+iTja5weFe0ePbqLb5BHqXOJUO1SG6kDj/1WtWPRIBr51N153AEq8m7HuIaA== }
/emoji-regex/8.0.0:
resolution: { integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== }
@ -2172,11 +2172,11 @@ packages:
dependencies:
'@next/eslint-plugin-next': 13.2.1
'@rushstack/eslint-patch': 1.2.0
'@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
eslint: 8.35.0
eslint-import-resolver-node: 0.3.7
eslint-import-resolver-typescript: 3.5.3_yckic57kx266ph64dhq6ozvb54
eslint-plugin-import: 2.27.5_z4t62rwba3aha3c5ltpvvca4q4
eslint-plugin-import: 2.27.5_tqrcrxlenpngfto46ddarus52y
eslint-plugin-jsx-a11y: 6.7.1_eslint@8.35.0
eslint-plugin-react: 7.32.2_eslint@8.35.0
eslint-plugin-react-hooks: 4.6.0_eslint@8.35.0
@ -2215,7 +2215,7 @@ packages:
debug: 4.3.4
enhanced-resolve: 5.12.0
eslint: 8.35.0
eslint-plugin-import: 2.27.5_z4t62rwba3aha3c5ltpvvca4q4
eslint-plugin-import: 2.27.5_tqrcrxlenpngfto46ddarus52y
get-tsconfig: 4.4.0
globby: 13.1.3
is-core-module: 2.11.0
@ -2225,7 +2225,7 @@ packages:
- supports-color
dev: true
/eslint-module-utils/2.7.4_wptzf6m7n4mzoakxgrlp7sjl2e:
/eslint-module-utils/2.7.4_igrub7c6rucg6hjc3uqgumd66y:
resolution: { integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== }
engines: { node: '>=4' }
peerDependencies:
@ -2246,7 +2246,7 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
debug: 3.2.7
eslint: 8.35.0
eslint-import-resolver-node: 0.3.7
@ -2255,7 +2255,7 @@ packages:
- supports-color
dev: true
/eslint-plugin-import/2.27.5_z4t62rwba3aha3c5ltpvvca4q4:
/eslint-plugin-import/2.27.5_tqrcrxlenpngfto46ddarus52y:
resolution: { integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== }
engines: { node: '>=4' }
peerDependencies:
@ -2265,7 +2265,7 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
'@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu
'@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu
array-includes: 3.1.6
array.prototype.flat: 1.3.1
array.prototype.flatmap: 1.3.1
@ -2273,7 +2273,7 @@ packages:
doctrine: 2.1.0
eslint: 8.35.0
eslint-import-resolver-node: 0.3.7
eslint-module-utils: 2.7.4_wptzf6m7n4mzoakxgrlp7sjl2e
eslint-module-utils: 2.7.4_igrub7c6rucg6hjc3uqgumd66y
has: 1.0.3
is-core-module: 2.11.0
is-glob: 4.0.3
@ -3472,7 +3472,7 @@ packages:
dependencies:
'@types/mdast': 3.0.10
escape-string-regexp: 5.0.0
unist-util-is: 5.2.0
unist-util-is: 5.2.1
unist-util-visit-parents: 5.1.3
dev: false
@ -3555,7 +3555,7 @@ packages:
resolution: { integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg== }
dependencies:
'@types/mdast': 3.0.10
unist-util-is: 5.2.0
unist-util-is: 5.2.1
dev: false
/mdast-util-to-hast/12.3.0:
@ -5274,7 +5274,7 @@ packages:
resolution: { integrity: sha512-RynicUM/vbOSTSiUK+BnaK9XMfmQUh6gyi7L6taNgc7FIf84GukXVV3ucGzEN/PhUUkdP5hb1MmXc+3cvPUm5Q== }
dependencies:
'@types/unist': 2.0.6
unist-util-is: 5.2.0
unist-util-is: 5.2.1
unist-util-visit-parents: 5.1.3
dev: false
@ -5282,8 +5282,10 @@ packages:
resolution: { integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A== }
dev: false
/unist-util-is/5.2.0:
resolution: { integrity: sha512-Glt17jWwZeyqrFqOK0pF1Ded5U3yzJnFr8CG1GMjCWTp9zDo2p+cmD6pWbZU8AgM5WU3IzRv6+rBwhzsGh6hBQ== }
/unist-util-is/5.2.1:
resolution: { integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== }
dependencies:
'@types/unist': 2.0.6
dev: false
/unist-util-position/4.0.4:
@ -5302,14 +5304,14 @@ packages:
resolution: { integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== }
dependencies:
'@types/unist': 2.0.6
unist-util-is: 5.2.0
unist-util-is: 5.2.1
dev: false
/unist-util-visit/4.1.2:
resolution: { integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== }
dependencies:
'@types/unist': 2.0.6
unist-util-is: 5.2.0
unist-util-is: 5.2.1
unist-util-visit-parents: 5.1.3
dev: false

View File

@ -2,13 +2,12 @@
import { DatabaseContext } from '@components/contexts/database';
import { RelayContext } from '@components/contexts/relay';
import { hoursAgo } from '@utils/getDate';
import { dateToUnix, hoursAgo } from '@utils/getDate';
import { follows } from '@stores/follows';
import { relays } from '@stores/relays';
import { useStore } from '@nanostores/react';
import { dateToUnix } from 'nostr-react';
import { memo, useCallback, useContext, useRef } from 'react';
export const NoteConnector = memo(function NoteConnector() {

View File

@ -1,53 +0,0 @@
import { Placeholder } from '@components/note/placeholder';
import { Repost } from '@components/note/repost';
import { Single } from '@components/note/single';
import { useCallback } from 'react';
import { Virtuoso } from 'react-virtuoso';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function Thread({ data }: { data: any }) {
const ItemContent = useCallback(
(index: string | number) => {
const event = data[index];
if (event.content.includes('#[0]') && event.tags[0][0] == 'e') {
// type: repost
return <Repost root={event.tags} user={event.pubkey} />;
} else {
// type: default
return <Single event={event} />;
}
},
[data]
);
const computeItemKey = useCallback(
(index) => {
return data[index].id;
},
[data]
);
return (
<Virtuoso
data={data}
itemContent={ItemContent}
components={{
EmptyPlaceholder: () => <Placeholder />,
ScrollSeekPlaceholder: () => <Placeholder />,
}}
computeItemKey={computeItemKey}
scrollSeekConfiguration={{
enter: (velocity) => Math.abs(velocity) > 800,
exit: (velocity) => Math.abs(velocity) < 500,
}}
overscan={800}
increaseViewportBy={1000}
className="scrollbar-hide relative h-full w-full rounded-lg"
style={{
contain: 'strict',
}}
/>
);
}

View File

@ -4,14 +4,18 @@ import NewsFeedLayout from '@layouts/newsfeedLayout';
import { DatabaseContext } from '@components/contexts/database';
import { Placeholder } from '@components/note/placeholder';
import { Thread } from '@components/thread';
import { Repost } from '@components/note/repost';
import { Single } from '@components/note/single';
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, Suspense, useContext, useEffect, useRef, useState } from 'react';
import { useCallback } from 'react';
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useContext, useEffect, useRef, useState } from 'react';
import { Virtuoso } from 'react-virtuoso';
export default function Page() {
const db: any = useContext(DatabaseContext);
const [data, setData] = useState([]);
const limit = useRef(25);
const [data, setData] = useState(() => []);
const limit = useRef(30);
const offset = useRef(0);
useEffect(() => {
const getData = async () => {
@ -22,12 +26,55 @@ export default function Page() {
getData().catch(console.error);
}, [db]);
const loadMore = useCallback(async () => {
offset.current += limit.current;
// next query
const result = await db.select(`SELECT * FROM cache_notes ORDER BY created_at DESC LIMIT ${limit.current} OFFSET ${offset.current}`);
setData((data) => [...data, ...result]);
}, [db]);
const ItemContent = useCallback(
(index: string | number) => {
const event = data[index];
if (event.content.includes('#[0]') && event.tags[0][0] == 'e') {
// type: repost
return <Repost root={event.tags} user={event.pubkey} />;
} else {
// type: default
return <Single event={event} />;
}
},
[data]
);
const computeItemKey = useCallback(
(index: string | number) => {
return data[index].id;
},
[data]
);
return (
<div className="h-full w-full">
<Suspense fallback={<Placeholder />}>
<Thread data={data} />
</Suspense>
</div>
<Virtuoso
data={data}
itemContent={ItemContent}
components={{
EmptyPlaceholder: () => <Placeholder />,
ScrollSeekPlaceholder: () => <Placeholder />,
}}
computeItemKey={computeItemKey}
scrollSeekConfiguration={{
enter: (velocity) => Math.abs(velocity) > 800,
exit: (velocity) => Math.abs(velocity) < 500,
}}
endReached={loadMore}
overscan={800}
increaseViewportBy={1000}
className="scrollbar-hide relative h-full w-full rounded-lg"
style={{
contain: 'strict',
}}
/>
);
}

View File

@ -11,3 +11,9 @@ export const hoursAgo = (numOfHours, date = new Date()) => {
return hoursAgo;
};
export const dateToUnix = (_date?: Date) => {
const date = _date || new Date();
return Math.floor(date.getTime() / 1000);
};