From 0394d41e470fbed2b94e61b833f2cc3eb504944b Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 1 Apr 2023 09:03:38 +0700 Subject: [PATCH 01/21] refactor multi accounts component --- src/components/columns/account/list.tsx | 36 ---------------- .../activeAccount.tsx} | 15 +++---- .../inactiveAccount.tsx} | 13 ++++-- .../account => multiAccounts}/index.tsx | 42 +++++++++++++------ src/layouts/withSidebar.tsx | 4 +- src/stores/constants.tsx | 1 + 6 files changed, 48 insertions(+), 63 deletions(-) delete mode 100644 src/components/columns/account/list.tsx rename src/components/{columns/account/active.tsx => multiAccounts/activeAccount.tsx} (90%) rename src/components/{columns/account/inactive.tsx => multiAccounts/inactiveAccount.tsx} (55%) rename src/components/{columns/account => multiAccounts}/index.tsx (55%) diff --git a/src/components/columns/account/list.tsx b/src/components/columns/account/list.tsx deleted file mode 100644 index a92141bc..00000000 --- a/src/components/columns/account/list.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { ActiveAccount } from '@components/columns/account/active'; -import { InactiveAccount } from '@components/columns/account/inactive'; - -import { activeAccountAtom } from '@stores/account'; - -import { getAccounts } from '@utils/storage'; - -import { useAtomValue } from 'jotai'; -import { useCallback, useEffect, useState } from 'react'; - -export default function AccountList() { - const activeAccount: any = useAtomValue(activeAccountAtom); - const [users, setUsers] = useState([]); - - const renderAccount = useCallback( - (user: { id: string }) => { - if (user.id === activeAccount.id) { - return ; - } else { - return ; - } - }, - [activeAccount.id] - ); - - useEffect(() => { - const fetchAccount = async () => { - const result: any = await getAccounts(); - setUsers(result); - }; - - fetchAccount().catch(console.error); - }, []); - - return <>{users.map((user) => renderAccount(user))}; -} diff --git a/src/components/columns/account/active.tsx b/src/components/multiAccounts/activeAccount.tsx similarity index 90% rename from src/components/columns/account/active.tsx rename to src/components/multiAccounts/activeAccount.tsx index a2f28c86..3b7fb1de 100644 --- a/src/components/columns/account/active.tsx +++ b/src/components/multiAccounts/activeAccount.tsx @@ -1,25 +1,23 @@ import { RelayContext } from '@components/relaysProvider'; -import { dateToUnix } from '@utils/getDate'; +import { DEFAULT_AVATAR } from '@stores/constants'; + import { createFollows } from '@utils/storage'; import { tagsToArray } from '@utils/transform'; import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; import { AvatarIcon, ExitIcon, GearIcon } from '@radix-ui/react-icons'; import { writeText } from '@tauri-apps/api/clipboard'; -import destr from 'destr'; import Image from 'next/image'; import { useRouter } from 'next/router'; import { nip19 } from 'nostr-tools'; -import { memo, useContext, useEffect, useRef } from 'react'; +import { memo, useContext, useEffect } from 'react'; export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any }) { const [pool, relays]: any = useContext(RelayContext); const router = useRouter(); - const userData = destr(user.metadata); - - const now = useRef(new Date()); + const userData = JSON.parse(user.metadata); const openProfilePage = () => { router.push(`/users/${user.id}`); @@ -35,7 +33,6 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } { kinds: [3], authors: [user.id], - since: dateToUnix(now.current), }, ], relays, @@ -61,12 +58,10 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } diff --git a/src/components/columns/account/inactive.tsx b/src/components/multiAccounts/inactiveAccount.tsx similarity index 55% rename from src/components/columns/account/inactive.tsx rename to src/components/multiAccounts/inactiveAccount.tsx index b9bd5060..1aa710b3 100644 --- a/src/components/columns/account/inactive.tsx +++ b/src/components/multiAccounts/inactiveAccount.tsx @@ -1,9 +1,10 @@ -import destr from 'destr'; +import { DEFAULT_AVATAR } from '@stores/constants'; + import Image from 'next/image'; import { memo } from 'react'; export const InactiveAccount = memo(function InactiveAccount({ user }: { user: any }) { - const userData = destr(user.metadata); + const userData = JSON.parse(user.metadata); const setCurrentUser = () => { console.log('clicked'); @@ -11,7 +12,13 @@ export const InactiveAccount = memo(function InactiveAccount({ user }: { user: a return ( ); }); diff --git a/src/components/columns/account/index.tsx b/src/components/multiAccounts/index.tsx similarity index 55% rename from src/components/columns/account/index.tsx rename to src/components/multiAccounts/index.tsx index 79856a62..fa66b1f1 100644 --- a/src/components/columns/account/index.tsx +++ b/src/components/multiAccounts/index.tsx @@ -1,23 +1,41 @@ -import AccountList from '@components/columns/account/list'; +import { ActiveAccount } from '@components/multiAccounts/activeAccount'; +import { InactiveAccount } from '@components/multiAccounts/inactiveAccount'; + +import { activeAccountAtom } from '@stores/account'; +import { APP_VERSION } from '@stores/constants'; + +import { getAccounts } from '@utils/storage'; import LumeSymbol from '@assets/icons/Lume'; import { PlusIcon } from '@radix-ui/react-icons'; -import { getVersion } from '@tauri-apps/api/app'; +import { useAtomValue } from 'jotai'; import Link from 'next/link'; import { useCallback, useEffect, useState } from 'react'; -export default function AccountColumn() { - const [version, setVersion] = useState(null); +export default function MultiAccounts() { + const activeAccount: any = useAtomValue(activeAccountAtom); + const [users, setUsers] = useState([]); - const getAppVersion = useCallback(async () => { - const appVersion = await getVersion(); - setVersion(appVersion); - }, []); + const renderAccount = useCallback( + (user: { id: string }) => { + if (user.id === activeAccount.id) { + return ; + } else { + return ; + } + }, + [activeAccount.id] + ); useEffect(() => { - getAppVersion().catch(console.error); - }, [getAppVersion]); + const fetchAccount = async () => { + const result: any = await getAccounts(); + setUsers(result); + }; + + fetchAccount().catch(console.error); + }, []); return (
@@ -28,7 +46,7 @@ export default function AccountColumn() { > - +
{users.map((user) => renderAccount(user))}
Lume - v{version} + v{APP_VERSION}
); diff --git a/src/layouts/withSidebar.tsx b/src/layouts/withSidebar.tsx index b474448f..77ccef46 100644 --- a/src/layouts/withSidebar.tsx +++ b/src/layouts/withSidebar.tsx @@ -1,6 +1,6 @@ import AppHeader from '@components/appHeader'; -import AccountColumn from '@components/columns/account'; import NavigatorColumn from '@components/columns/navigator'; +import MultiAccounts from '@components/multiAccounts'; export default function WithSidebarLayout({ children }: { children: React.ReactNode }) { return ( @@ -13,7 +13,7 @@ export default function WithSidebarLayout({ children }: { children: React.ReactN
- +
diff --git a/src/stores/constants.tsx b/src/stores/constants.tsx index 85705f9a..892b0f43 100644 --- a/src/stores/constants.tsx +++ b/src/stores/constants.tsx @@ -1 +1,2 @@ +export const APP_VERSION = '0.2.1'; export const DEFAULT_AVATAR = 'https://void.cat/d/KmypFh2fBdYCEvyJrPiN89.webp'; From ae969baa6df3f5349319090ec616396aef6c5bbe Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 1 Apr 2023 09:27:30 +0700 Subject: [PATCH 02/21] moved navigation to outside, remove columns folder --- src/components/{columns => }/navigator/chats.tsx | 0 src/components/{columns => }/navigator/index.tsx | 6 +++--- src/components/{columns => }/navigator/newsfeed.tsx | 0 src/layouts/withSidebar.tsx | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/components/{columns => }/navigator/chats.tsx (100%) rename src/components/{columns => }/navigator/index.tsx (53%) rename src/components/{columns => }/navigator/newsfeed.tsx (100%) diff --git a/src/components/columns/navigator/chats.tsx b/src/components/navigator/chats.tsx similarity index 100% rename from src/components/columns/navigator/chats.tsx rename to src/components/navigator/chats.tsx diff --git a/src/components/columns/navigator/index.tsx b/src/components/navigator/index.tsx similarity index 53% rename from src/components/columns/navigator/index.tsx rename to src/components/navigator/index.tsx index 324e1582..8dae9db8 100644 --- a/src/components/columns/navigator/index.tsx +++ b/src/components/navigator/index.tsx @@ -1,7 +1,7 @@ -import Chats from '@components/columns/navigator/chats'; -import Newsfeed from '@components/columns/navigator/newsfeed'; +import Chats from '@components/navigator/chats'; +import Newsfeed from '@components/navigator/newsfeed'; -export default function NavigatorColumn() { +export default function Navigation() { return (
{/* Newsfeed */} diff --git a/src/components/columns/navigator/newsfeed.tsx b/src/components/navigator/newsfeed.tsx similarity index 100% rename from src/components/columns/navigator/newsfeed.tsx rename to src/components/navigator/newsfeed.tsx diff --git a/src/layouts/withSidebar.tsx b/src/layouts/withSidebar.tsx index 77ccef46..8b3e8ff0 100644 --- a/src/layouts/withSidebar.tsx +++ b/src/layouts/withSidebar.tsx @@ -1,6 +1,6 @@ import AppHeader from '@components/appHeader'; -import NavigatorColumn from '@components/columns/navigator'; import MultiAccounts from '@components/multiAccounts'; +import Navigation from '@components/navigator'; export default function WithSidebarLayout({ children }: { children: React.ReactNode }) { return ( @@ -17,7 +17,7 @@ export default function WithSidebarLayout({ children }: { children: React.ReactN
- +
{children}
From 383c9e55ac858c034c9bdc58343f8a3179592e3a Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 1 Apr 2023 11:15:47 +0700 Subject: [PATCH 03/21] rename from navigator to navigation --- src/components/{navigator => navigation}/chats.tsx | 0 src/components/{navigator => navigation}/index.tsx | 4 ++-- src/components/{navigator => navigation}/newsfeed.tsx | 0 src/layouts/withSidebar.tsx | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/components/{navigator => navigation}/chats.tsx (100%) rename src/components/{navigator => navigation}/index.tsx (68%) rename src/components/{navigator => navigation}/newsfeed.tsx (100%) diff --git a/src/components/navigator/chats.tsx b/src/components/navigation/chats.tsx similarity index 100% rename from src/components/navigator/chats.tsx rename to src/components/navigation/chats.tsx diff --git a/src/components/navigator/index.tsx b/src/components/navigation/index.tsx similarity index 68% rename from src/components/navigator/index.tsx rename to src/components/navigation/index.tsx index 8dae9db8..a10d3c55 100644 --- a/src/components/navigator/index.tsx +++ b/src/components/navigation/index.tsx @@ -1,5 +1,5 @@ -import Chats from '@components/navigator/chats'; -import Newsfeed from '@components/navigator/newsfeed'; +import Chats from '@components/navigation/chats'; +import Newsfeed from '@components/navigation/newsfeed'; export default function Navigation() { return ( diff --git a/src/components/navigator/newsfeed.tsx b/src/components/navigation/newsfeed.tsx similarity index 100% rename from src/components/navigator/newsfeed.tsx rename to src/components/navigation/newsfeed.tsx diff --git a/src/layouts/withSidebar.tsx b/src/layouts/withSidebar.tsx index 8b3e8ff0..39a3f711 100644 --- a/src/layouts/withSidebar.tsx +++ b/src/layouts/withSidebar.tsx @@ -1,6 +1,6 @@ import AppHeader from '@components/appHeader'; import MultiAccounts from '@components/multiAccounts'; -import Navigation from '@components/navigator'; +import Navigation from '@components/navigation'; export default function WithSidebarLayout({ children }: { children: React.ReactNode }) { return ( From 27082acf5c7bf03ee1380dfd8edde358cdeb85c8 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 1 Apr 2023 15:46:08 +0700 Subject: [PATCH 04/21] updated navigation --- .../multiAccounts/activeAccount.tsx | 4 +-- .../multiAccounts/inactiveAccount.tsx | 4 +-- src/components/multiAccounts/index.tsx | 6 ++--- src/components/navigation/channels.tsx | 25 +++++++++++++++++++ src/components/navigation/chats.tsx | 12 ++++----- src/components/navigation/index.tsx | 5 +++- src/components/navigation/newsfeed.tsx | 18 ++++++------- 7 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 src/components/navigation/channels.tsx diff --git a/src/components/multiAccounts/activeAccount.tsx b/src/components/multiAccounts/activeAccount.tsx index 3b7fb1de..fb244fde 100644 --- a/src/components/multiAccounts/activeAccount.tsx +++ b/src/components/multiAccounts/activeAccount.tsx @@ -56,12 +56,12 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } return ( - diff --git a/src/components/multiAccounts/inactiveAccount.tsx b/src/components/multiAccounts/inactiveAccount.tsx index 1aa710b3..b2d42c6e 100644 --- a/src/components/multiAccounts/inactiveAccount.tsx +++ b/src/components/multiAccounts/inactiveAccount.tsx @@ -11,12 +11,12 @@ export const InactiveAccount = memo(function InactiveAccount({ user }: { user: a }; return ( - diff --git a/src/components/multiAccounts/index.tsx b/src/components/multiAccounts/index.tsx index fa66b1f1..6e7fdc71 100644 --- a/src/components/multiAccounts/index.tsx +++ b/src/components/multiAccounts/index.tsx @@ -38,18 +38,18 @@ export default function MultiAccounts() { }, []); return ( -
+
{users.map((user) => renderAccount(user))}
diff --git a/src/components/navigation/channels.tsx b/src/components/navigation/channels.tsx new file mode 100644 index 00000000..23ce19b9 --- /dev/null +++ b/src/components/navigation/channels.tsx @@ -0,0 +1,25 @@ +import * as Collapsible from '@radix-ui/react-collapsible'; +import { TriangleUpIcon } from '@radix-ui/react-icons'; +import { useState } from 'react'; + +export default function Channels() { + const [open, setOpen] = useState(true); + + return ( + +
+ +
+ +
+

Channels

+
+ +
+
+ ); +} diff --git a/src/components/navigation/chats.tsx b/src/components/navigation/chats.tsx index f9169731..aa2a947d 100644 --- a/src/components/navigation/chats.tsx +++ b/src/components/navigation/chats.tsx @@ -6,21 +6,19 @@ export default function Chats() { const [open, setOpen] = useState(true); return ( - -
+ +
- +
-

- Chats -

+

Chats

- +
); diff --git a/src/components/navigation/index.tsx b/src/components/navigation/index.tsx index a10d3c55..fdfbbab9 100644 --- a/src/components/navigation/index.tsx +++ b/src/components/navigation/index.tsx @@ -1,11 +1,14 @@ +import Channels from '@components/navigation/channels'; import Chats from '@components/navigation/chats'; import Newsfeed from '@components/navigation/newsfeed'; export default function Navigation() { return ( -
+
{/* Newsfeed */} + {/* Channels */} + {/* Chats */}
diff --git a/src/components/navigation/newsfeed.tsx b/src/components/navigation/newsfeed.tsx index 9a1318c7..aa46ff43 100644 --- a/src/components/navigation/newsfeed.tsx +++ b/src/components/navigation/newsfeed.tsx @@ -12,21 +12,19 @@ export default function Newsfeed() {
- +
-

- Newsfeed -

+

Newsfeed

- +
@@ -35,8 +33,8 @@ export default function Newsfeed() {
From 9b8a96c6514d6824eeac4d23d36af4e7d15212d8 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sun, 2 Apr 2023 08:30:36 +0700 Subject: [PATCH 05/21] replaced tauri-sql with prisma-client-rust --- src-tauri/.cargo/config.toml | 2 + src-tauri/.gitignore | 2 + src-tauri/Cargo.lock | 2406 +++++++++++++++++++++++++---- src-tauri/Cargo.toml | 9 +- src-tauri/prisma/migrations/.keep | 0 src-tauri/prisma/schema.prisma | 11 + src-tauri/src/bin/prisma.rs | 3 + src-tauri/src/main.rs | 15 +- 8 files changed, 2117 insertions(+), 331 deletions(-) create mode 100644 src-tauri/.cargo/config.toml create mode 100644 src-tauri/prisma/migrations/.keep create mode 100644 src-tauri/prisma/schema.prisma create mode 100644 src-tauri/src/bin/prisma.rs diff --git a/src-tauri/.cargo/config.toml b/src-tauri/.cargo/config.toml new file mode 100644 index 00000000..97680697 --- /dev/null +++ b/src-tauri/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +prisma = "run --bin prisma --" diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore index f4dfb82b..d35e841c 100644 --- a/src-tauri/.gitignore +++ b/src-tauri/.gitignore @@ -2,3 +2,5 @@ # will have compiled files and executables /target/ +# prisma +src/prisma.rs diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index b1dd6ce0..7640a8e0 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -43,12 +58,38 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + [[package]] name = "atk" version = "0.15.1" @@ -74,12 +115,12 @@ dependencies = [ ] [[package]] -name = "atoi" -version = "1.0.0" +name = "atomic-shim" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "67cd4b51d303cf3501c301e8125df442128d3c6d7c69f71b27833d253de47e77" dependencies = [ - "num-traits", + "crossbeam-utils", ] [[package]] @@ -98,12 +139,60 @@ dependencies = [ "url", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base36" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9c26bddc1271f7112e5ec797e8eeba6de2de211c1488e506b9500196dbf77c5" +dependencies = [ + "base-x", + "failure", +] + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.13.1" @@ -116,6 +205,43 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "bigdecimal" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aaf33151a6429fe9211d1b276eafdf70cdff28b071e76c0b0e1503221ea3744" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bigint" +version = "4.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0e8c8a600052b52482eff2cf4d810e462fdff1f656ac1ecb6232132a1ed7def" +dependencies = [ + "byteorder", + "crunchy", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -128,6 +254,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.3" @@ -168,6 +303,21 @@ dependencies = [ "serde", ] +[[package]] +name = "builtin-psl-connectors" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "connection-string", + "either", + "enumflags2", + "indoc 1.0.9", + "lsp-types", + "once_cell", + "psl-core", + "regex", +] + [[package]] name = "bumpalo" version = "3.12.0" @@ -272,6 +422,22 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time 0.1.43", + "wasm-bindgen", + "winapi", +] + [[package]] name = "cocoa" version = "0.24.1" @@ -303,12 +469,46 @@ dependencies = [ "objc", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "color_quant" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + [[package]] name = "combine" version = "4.6.6" @@ -319,12 +519,37 @@ dependencies = [ "memchr", ] +[[package]] +name = "connection-string" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c4ecb0dc8c35d2c626e45ae70bbfcb1050b302f42bcdf025d913cc0c5a0b443" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "convert_case" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "convert_case" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -375,21 +600,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" - [[package]] name = "crc32fast" version = "1.3.2" @@ -409,6 +619,19 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.8.0", + "scopeguard", +] + [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -428,6 +651,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" + [[package]] name = "crypto-common" version = "0.1.6" @@ -452,7 +681,7 @@ dependencies = [ "proc-macro2", "quote", "smallvec", - "syn", + "syn 1.0.107", ] [[package]] @@ -462,7 +691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" dependencies = [ "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -472,7 +701,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -481,6 +710,77 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" +[[package]] +name = "cuid" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5d03ac594f5f9cc680b142fff46f3ad9f197e19272042ebf1a40b383fee6fb" +dependencies = [ + "base36", + "bigint", + "cuid2", + "hostname", + "num", + "once_cell", + "rand 0.8.5", +] + +[[package]] +name = "cuid2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1debbff0c0f0b54e681296c6f064a78f8ecec8e89e7fcc472443d9f85b98ca9a" +dependencies = [ + "num", + "proptest", + "rand 0.8.5", + "sha3", +] + +[[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.13", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + [[package]] name = "darling" version = "0.13.4" @@ -502,7 +802,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 1.0.107", ] [[package]] @@ -513,7 +813,18 @@ checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.107", +] + +[[package]] +name = "datamodel-renderer" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "base64 0.13.1", + "once_cell", + "psl", + "regex", ] [[package]] @@ -522,11 +833,30 @@ version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ - "convert_case", + "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version 0.4.0", - "syn", + "syn 1.0.107", +] + +[[package]] +name = "diagnostics" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "colored", + "indoc 1.0.9", + "pest", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", ] [[package]] @@ -535,10 +865,19 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer", + "block-buffer 0.10.3", "crypto-common", ] +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -549,6 +888,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -567,10 +917,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] -name = "dotenvy" -version = "0.15.6" +name = "dml" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "chrono", + "cuid", + "either", + "enumflags2", + "indoc 1.0.9", + "prisma-value", + "psl-core", + "schema-ast", + "serde", + "serde_json", + "uuid 1.3.0", +] + +[[package]] +name = "dmmf" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "bigdecimal", + "indexmap", + "prisma-models", + "psl", + "schema", + "schema-builder", + "serde", + "serde_json", +] + +[[package]] +name = "document-features" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" +checksum = "e493c573fce17f00dcab13b6ac057994f3ce17d1af4dc39bfd482b83c6eb6157" +dependencies = [ + "litrs", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "dtoa" @@ -615,10 +1007,64 @@ dependencies = [ ] [[package]] -name = "event-listener" -version = "2.5.3" +name = "endian-type" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enumflags2" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0044ebdf7fbb2a772e0c0233a9d3173c5cd8af8ae7078d4c5188af44ffffaa4b" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2c772ccdbdfd1967b4f5d79d17c98ebf92009fdcc838db7aa434462f600c26" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", + "synstructure", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" @@ -635,7 +1081,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ - "memoffset", + "memoffset 0.6.5", "rustc_version 0.3.3", ] @@ -651,6 +1097,12 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "fixedbitset" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" + [[package]] name = "flate2" version = "1.0.25" @@ -661,18 +1113,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "pin-project", - "spin 0.9.4", -] - [[package]] name = "fnv" version = "1.0.7" @@ -703,6 +1143,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "futf" version = "0.1.5" @@ -755,17 +1201,6 @@ dependencies = [ "futures-util", ] -[[package]] -name = "futures-intrusive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot 0.11.2", -] - [[package]] name = "futures-io" version = "0.3.26" @@ -780,7 +1215,7 @@ checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -795,6 +1230,12 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + [[package]] name = "futures-util" version = "0.3.26" @@ -939,6 +1380,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" + [[package]] name = "gio" version = "0.15.12" @@ -1001,7 +1448,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1044,6 +1491,16 @@ dependencies = [ "system-deps 6.0.3", ] +[[package]] +name = "graphql-parser" +version = "0.3.0" +source = "git+https://github.com/prisma/graphql-parser#6a3f58bd879065588e710cb02b5bd30c1ce182c3" +dependencies = [ + "combine 3.8.1", + "indexmap", + "thiserror", +] + [[package]] name = "gtk" version = "0.15.5" @@ -1096,7 +1553,35 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.107", +] + +[[package]] +name = "h2" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", ] [[package]] @@ -1110,11 +1595,11 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" dependencies = [ - "hashbrown", + "hashbrown 0.11.2", ] [[package]] @@ -1131,8 +1616,14 @@ name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ - "unicode-segmentation", + "libc", ] [[package]] @@ -1150,6 +1641,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "html5ever" version = "0.25.2" @@ -1161,7 +1663,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1175,12 +1677,96 @@ dependencies = [ "itoa 1.0.5", ] +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + [[package]] name = "http-range" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 1.0.5", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "ico" version = "0.2.0" @@ -1238,6 +1824,25 @@ dependencies = [ "num-traits", ] +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "indexmap" version = "1.9.2" @@ -1245,9 +1850,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", ] +[[package]] +name = "indoc" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" + +[[package]] +name = "indoc" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f2cb48b81b1dc9f39676bf99f5499babfec7cd8fe14307f7b3d747208fb5690" + [[package]] name = "infer" version = "0.7.0" @@ -1266,6 +1884,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "introspection-connector" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "anyhow", + "async-trait", + "enumflags2", + "psl", + "serde", + "serde_json", + "thiserror", + "user-facing-errors", +] + +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + [[package]] name = "itertools" version = "0.10.5" @@ -1317,7 +1956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" dependencies = [ "cesu8", - "combine", + "combine 4.6.6", "jni-sys", "log", "thiserror", @@ -1332,9 +1971,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" dependencies = [ "wasm-bindgen", ] @@ -1350,6 +1989,41 @@ dependencies = [ "treediff", ] +[[package]] +name = "json-rpc-api-build" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "backtrace", + "heck 0.3.3", + "serde", + "toml", +] + +[[package]] +name = "jsonrpc-core" +version = "17.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4467ab6dfa369b69e52bd0692e480c4d117410538526a57a304a0f2250fd95e" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kuchiki" version = "0.8.1" @@ -1409,10 +2083,16 @@ dependencies = [ ] [[package]] -name = "libsqlite3-sys" -version = "0.24.2" +name = "libm" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "libsqlite3-sys" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d" dependencies = [ "cc", "pkg-config", @@ -1428,6 +2108,21 @@ dependencies = [ "safemem", ] +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "litrs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9275e0933cf8bb20f008924c0cb07a0692fe54d8064996520bf998de9eb79aa" + [[package]] name = "lock_api" version = "0.4.9" @@ -1462,17 +2157,42 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +dependencies = [ + "hashbrown 0.12.3", +] + +[[package]] +name = "lsp-types" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2368312c59425dd133cb9a327afee65be0a633a8ce471d248e2202a48f8f68ae" +dependencies = [ + "bitflags", + "serde", + "serde_json", + "serde_repr", + "url", +] + [[package]] name = "lume" version = "0.2.1" dependencies = [ "cocoa", "objc", + "prisma-client-rust", + "prisma-client-rust-cli", "serde", "serde_json", + "specta", "tauri", "tauri-build", - "tauri-plugin-sql", + "tauri-specta", ] [[package]] @@ -1481,6 +2201,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -1504,6 +2233,12 @@ dependencies = [ "tendril", ] +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matchers" version = "0.1.0" @@ -1534,6 +2269,146 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metrics" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e52eb6380b6d2a10eb3434aec0885374490f5b82c8aaf5cd487a183c98be834" +dependencies = [ + "ahash", + "metrics-macros", +] + +[[package]] +name = "metrics" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142c53885123b68d94108295a09d4afe1a1388ed95b54d5dacd9a454753030f2" +dependencies = [ + "ahash", + "metrics-macros", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953cbbb6f9ba4b9304f4df79b98cdc9d14071ed93065a9fca11c00c5d9181b66" +dependencies = [ + "hyper", + "indexmap", + "ipnet", + "metrics 0.19.0", + "metrics-util 0.13.0", + "parking_lot 0.11.2", + "quanta", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-macros" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e30813093f757be5cf21e50389a24dc7dbb22c49f23b7e8f51d69b508a5ffa" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "metrics-util" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65a9e83b833e1d2e07010a386b197c13aa199bbd0fca5cf69bfa147972db890a" +dependencies = [ + "aho-corasick", + "atomic-shim", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.11.2", + "indexmap", + "metrics 0.18.1", + "num_cpus", + "ordered-float", + "parking_lot 0.11.2", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + +[[package]] +name = "metrics-util" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd1f4b69bef1e2b392b2d4a12902f2af90bb438ba4a66aa222d1023fa6561b50" +dependencies = [ + "atomic-shim", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.11.2", + "metrics 0.19.0", + "num_cpus", + "parking_lot 0.11.2", + "quanta", + "sketches-ddsketch", +] + +[[package]] +name = "migration-connector" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "chrono", + "enumflags2", + "introspection-connector", + "psl", + "sha2 0.9.9", + "tracing", + "tracing-error", + "user-facing-errors", +] + +[[package]] +name = "migration-core" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "async-trait", + "chrono", + "enumflags2", + "json-rpc-api-build", + "jsonrpc-core", + "migration-connector", + "psl", + "serde", + "serde_json", + "sql-migration-connector", + "tokio", + "tracing", + "tracing-futures", + "tracing-subscriber", + "url", + "user-facing-errors", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1561,6 +2436,24 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "mobc" +version = "0.7.3" +source = "git+https://github.com/prisma/mobc?tag=1.0.6#80462c4870a2bf6aab49da15c88c021bae531da8" +dependencies = [ + "async-trait", + "futures-channel", + "futures-core", + "futures-timer", + "futures-util", + "log", + "metrics 0.18.1", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -1613,6 +2506,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -1648,6 +2550,40 @@ dependencies = [ "winapi", ] +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +dependencies = [ + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -1658,6 +2594,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.1" @@ -1665,6 +2612,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", + "num-bigint", "num-integer", "num-traits", ] @@ -1676,6 +2624,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1684,7 +2633,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -1706,7 +2655,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1737,12 +2686,27 @@ dependencies = [ "objc", ] +[[package]] +name = "object" +version = "0.30.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "open" version = "3.2.0" @@ -1776,7 +2740,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1798,6 +2762,41 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6105e89802af13fdf48c49d7646d3b533a70e536d818aae7e78ba0433d01acb8" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "js-sys", + "lazy_static", + "percent-encoding", + "pin-project", + "rand 0.8.5", + "thiserror", + "tokio", +] + +[[package]] +name = "ordered-float" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordermap" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" + [[package]] name = "os_info" version = "3.6.0" @@ -1888,6 +2887,18 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "parser-database" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "diagnostics", + "either", + "enumflags2", + "indexmap", + "schema-ast", +] + [[package]] name = "paste" version = "1.0.11" @@ -1916,6 +2927,50 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "pest_derive" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "pest_meta" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.6", +] + +[[package]] +name = "petgraph" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" +dependencies = [ + "fixedbitset", + "ordermap", +] + [[package]] name = "phf" version = "0.8.0" @@ -1979,7 +3034,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1993,7 +3048,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2031,7 +3086,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2063,7 +3118,7 @@ dependencies = [ "line-wrap", "quick-xml", "serde", - "time", + "time 0.3.17", ] [[package]] @@ -2090,6 +3145,125 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prisma-client-rust" +version = "0.6.7" +source = "git+https://github.com/Brendonovich/prisma-client-rust?tag=0.6.7#f71ad9122537c4ed29bf496a4a643947a5fe9aef" +dependencies = [ + "base64 0.13.1", + "bigdecimal", + "chrono", + "diagnostics", + "dml", + "dmmf", + "dotenv", + "futures", + "include_dir", + "indexmap", + "migration-core", + "paste", + "prisma-client-rust-macros", + "prisma-models", + "psl", + "query-connector", + "query-core", + "schema", + "serde", + "serde-value", + "serde_json", + "specta", + "tempdir", + "thiserror", + "tokio", + "tracing", + "user-facing-errors", + "uuid 1.3.0", +] + +[[package]] +name = "prisma-client-rust-cli" +version = "0.6.7" +source = "git+https://github.com/Brendonovich/prisma-client-rust?tag=0.6.7#f71ad9122537c4ed29bf496a4a643947a5fe9aef" +dependencies = [ + "directories", + "flate2", + "http", + "prisma-client-rust-sdk", + "proc-macro2", + "quote", + "regex", + "reqwest", + "serde", + "serde_json", + "serde_path_to_error", + "syn 1.0.107", + "thiserror", +] + +[[package]] +name = "prisma-client-rust-macros" +version = "0.6.7" +source = "git+https://github.com/Brendonovich/prisma-client-rust?tag=0.6.7#f71ad9122537c4ed29bf496a4a643947a5fe9aef" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "specta", + "syn 1.0.107", +] + +[[package]] +name = "prisma-client-rust-sdk" +version = "0.6.7" +source = "git+https://github.com/Brendonovich/prisma-client-rust?tag=0.6.7#f71ad9122537c4ed29bf496a4a643947a5fe9aef" +dependencies = [ + "convert_case 0.5.0", + "dml", + "dmmf", + "prisma-models", + "proc-macro2", + "psl", + "query-core", + "quote", + "request-handlers", + "serde", + "serde_json", + "serde_path_to_error", + "syn 1.0.107", + "thiserror", +] + +[[package]] +name = "prisma-models" +version = "0.0.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "bigdecimal", + "chrono", + "itertools", + "once_cell", + "prisma-value", + "psl", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "prisma-value" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "base64 0.12.3", + "bigdecimal", + "chrono", + "once_cell", + "regex", + "serde", + "serde_json", + "uuid 1.3.0", +] + [[package]] name = "proc-macro-crate" version = "1.3.0" @@ -2109,7 +3283,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "version_check", ] @@ -2132,13 +3306,203 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f1b898011ce9595050a68e60f90bad083ff2987a695a42357134c8381fba70" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.1", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "psl" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "builtin-psl-connectors", + "dml", + "psl-core", +] + +[[package]] +name = "psl-core" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "bigdecimal", + "chrono", + "diagnostics", + "enumflags2", + "indoc 1.0.9", + "itertools", + "lsp-types", + "once_cell", + "parser-database", + "prisma-value", + "regex", + "schema-ast", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "quaint" +version = "0.2.0-alpha.13" +source = "git+https://github.com/Brendonovich/quaint?tag=0.6.5#2bf0c3620f76d83982c17e567b71da6fc9d65d14" +dependencies = [ + "async-trait", + "base64 0.12.3", + "bigdecimal", + "chrono", + "connection-string", + "futures", + "hex", + "libsqlite3-sys", + "metrics 0.18.1", + "mobc", + "num_cpus", + "percent-encoding", + "rusqlite", + "serde_json", + "sqlformat", + "thiserror", + "tokio", + "tracing", + "tracing-core", + "url", + "uuid 1.3.0", +] + +[[package]] +name = "quanta" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8" +dependencies = [ + "crossbeam-utils", + "libc", + "mach", + "once_cell", + "raw-cpuid", + "wasi 0.10.2+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "query-connector" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "futures", + "indexmap", + "itertools", + "prisma-models", + "prisma-value", + "serde", + "serde_json", + "thiserror", + "user-facing-errors", + "uuid 1.3.0", +] + +[[package]] +name = "query-core" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "async-trait", + "base64 0.12.3", + "bigdecimal", + "chrono", + "connection-string", + "crossbeam-queue", + "cuid", + "enumflags2", + "futures", + "indexmap", + "itertools", + "lazy_static", + "lru", + "once_cell", + "opentelemetry", + "parking_lot 0.12.1", + "petgraph", + "pin-utils", + "prisma-models", + "prisma-value", + "psl", + "query-connector", + "query-engine-metrics", + "schema", + "schema-builder", + "serde", + "serde_json", + "sql-query-connector", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "tracing-opentelemetry", + "tracing-subscriber", + "url", + "user-facing-errors", + "uuid 1.3.0", +] + +[[package]] +name = "query-engine-metrics" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "metrics 0.18.1", + "metrics-exporter-prometheus", + "metrics-util 0.12.1", + "once_cell", + "parking_lot 0.12.1", + "serde", + "serde_json", + "tracing", + "tracing-futures", + "tracing-subscriber", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.26.0" @@ -2150,13 +3514,36 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + [[package]] name = "rand" version = "0.7.3" @@ -2202,6 +3589,21 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -2238,6 +3640,24 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "raw-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags", +] + [[package]] name = "raw-window-handle" version = "0.5.0" @@ -2247,6 +3667,15 @@ dependencies = [ "cty", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2303,20 +3732,86 @@ dependencies = [ ] [[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +name = "request-handlers" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted", - "web-sys", - "winapi", + "bigdecimal", + "connection-string", + "dmmf", + "futures", + "graphql-parser", + "indexmap", + "itertools", + "psl", + "query-core", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "user-facing-errors", ] +[[package]] +name = "reqwest" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rusqlite" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4b1eaf239b47034fb450ee9cdedd7d0226571689d8823030c4b6c2cb407152" +dependencies = [ + "bitflags", + "chrono", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "memchr", + "smallvec", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" + [[package]] name = "rustc_version" version = "0.3.3" @@ -2335,33 +3830,24 @@ dependencies = [ "semver 1.0.16", ] -[[package]] -name = "rustls" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" -dependencies = [ - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" -dependencies = [ - "base64 0.21.0", -] - [[package]] name = "rustversion" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.12" @@ -2392,6 +3878,39 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "schema" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "once_cell", + "prisma-models", + "psl", +] + +[[package]] +name = "schema-ast" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "diagnostics", + "pest", + "pest_derive", +] + +[[package]] +name = "schema-builder" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "itertools", + "lazy_static", + "once_cell", + "prisma-models", + "psl", + "schema", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -2405,14 +3924,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "sct" -version = "0.7.0" +name = "scratch" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" [[package]] name = "security-framework" @@ -2493,6 +4008,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.152" @@ -2501,20 +4026,30 @@ checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "serde_json" -version = "1.0.92" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7434af0dc1cbd59268aa98b4c22c131c0584d2232f6fb166efb993e2832e896a" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" dependencies = [ + "indexmap", "itoa 1.0.5", "ryu", "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +dependencies = [ + "serde", +] + [[package]] name = "serde_repr" version = "0.1.10" @@ -2523,7 +4058,7 @@ checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2557,7 +4092,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2579,7 +4114,7 @@ checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2592,6 +4127,19 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.6" @@ -2600,7 +4148,17 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.6", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +dependencies = [ + "digest 0.10.6", + "keccak", ] [[package]] @@ -2618,6 +4176,12 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +[[package]] +name = "sketches-ddsketch" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04d2ecae5fcf33b122e2e6bd520a57ccf152d2dde3b38c71039df1a6867264ee" + [[package]] name = "slab" version = "0.4.7" @@ -2635,9 +4199,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -2672,18 +4236,144 @@ dependencies = [ ] [[package]] -name = "spin" -version = "0.5.2" +name = "specta" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "4be6d92bb3d2a34fd5da2463089b44e67d6e83eedff074a82ba0b3e830dbff7c" +dependencies = [ + "chrono", + "document-features", + "indexmap", + "indoc 1.0.9", + "once_cell", + "paste", + "serde", + "serde_json", + "specta-macros", + "tauri", + "thiserror", + "uuid 1.3.0", +] [[package]] -name = "spin" -version = "0.9.4" +name = "specta-macros" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +checksum = "123bd8f0d65f556dce3d0e84346b759ad9701c49700cd9aa12c522bd0310d90b" dependencies = [ - "lock_api", + "Inflector", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.107", + "termcolor", +] + +[[package]] +name = "sql-ddl" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" + +[[package]] +name = "sql-introspection-connector" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "anyhow", + "async-trait", + "bigdecimal", + "datamodel-renderer", + "enumflags2", + "introspection-connector", + "once_cell", + "psl", + "quaint", + "regex", + "serde", + "serde_json", + "sql-schema-describer", + "thiserror", + "tracing", + "tracing-futures", + "user-facing-errors", +] + +[[package]] +name = "sql-migration-connector" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "chrono", + "connection-string", + "either", + "enumflags2", + "indoc 1.0.9", + "migration-connector", + "once_cell", + "psl", + "quaint", + "regex", + "serde_json", + "sql-ddl", + "sql-introspection-connector", + "sql-schema-describer", + "tokio", + "tracing", + "tracing-futures", + "url", + "user-facing-errors", + "uuid 1.3.0", +] + +[[package]] +name = "sql-query-connector" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "anyhow", + "async-trait", + "bigdecimal", + "chrono", + "cuid", + "futures", + "itertools", + "once_cell", + "opentelemetry", + "prisma-models", + "prisma-value", + "psl", + "quaint", + "query-connector", + "rand 0.7.3", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "tracing-opentelemetry", + "user-facing-errors", + "uuid 1.3.0", +] + +[[package]] +name = "sql-schema-describer" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "async-trait", + "bigdecimal", + "enumflags2", + "indexmap", + "indoc 1.0.9", + "once_cell", + "psl", + "quaint", + "regex", + "serde", + "tracing", + "tracing-error", + "tracing-futures", ] [[package]] @@ -2697,95 +4387,6 @@ dependencies = [ "unicode_categories", ] -[[package]] -name = "sqlx" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428" -dependencies = [ - "sqlx-core", - "sqlx-macros", -] - -[[package]] -name = "sqlx-core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" -dependencies = [ - "ahash", - "atoi", - "bitflags", - "byteorder", - "bytes", - "crc", - "crossbeam-queue", - "dotenvy", - "either", - "event-listener", - "flume", - "futures-channel", - "futures-core", - "futures-executor", - "futures-intrusive", - "futures-util", - "hashlink", - "hex", - "indexmap", - "itoa 1.0.5", - "libc", - "libsqlite3-sys", - "log", - "memchr", - "once_cell", - "paste", - "percent-encoding", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "sha2", - "smallvec", - "sqlformat", - "sqlx-rt", - "stringprep", - "thiserror", - "tokio-stream", - "url", - "webpki-roots", -] - -[[package]] -name = "sqlx-macros" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9" -dependencies = [ - "dotenvy", - "either", - "heck 0.4.1", - "once_cell", - "proc-macro2", - "quote", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-rt", - "syn", - "url", -] - -[[package]] -name = "sqlx-rt" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396" -dependencies = [ - "once_cell", - "tokio", - "tokio-rustls", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -2827,16 +4428,6 @@ dependencies = [ "quote", ] -[[package]] -name = "stringprep" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "strsim" version = "0.10.0" @@ -2854,6 +4445,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", + "unicode-xid", +] + [[package]] name = "system-deps" version = "5.0.0" @@ -3022,10 +4636,10 @@ dependencies = [ "semver 1.0.16", "serde", "serde_json", - "sha2", + "sha2 0.10.6", "tauri-utils", "thiserror", - "time", + "time 0.3.17", "uuid 1.3.0", "walkdir", ] @@ -3039,26 +4653,11 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "tauri-codegen", "tauri-utils", ] -[[package]] -name = "tauri-plugin-sql" -version = "0.1.0" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=dev#8f34eb83e4f9a8c72fd3823a066c94f861f2d021" -dependencies = [ - "futures", - "log", - "serde", - "serde_json", - "sqlx", - "tauri", - "thiserror", - "tokio", -] - [[package]] name = "tauri-runtime" version = "0.12.1" @@ -3099,6 +4698,21 @@ dependencies = [ "wry", ] +[[package]] +name = "tauri-specta" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23419889204476d5a70a04077d4628061a5bb667b18804a4572df2fe6ccb8ba5" +dependencies = [ + "heck 0.4.1", + "indoc 2.0.1", + "serde", + "serde_json", + "specta", + "tauri", + "thiserror", +] + [[package]] name = "tauri-utils" version = "1.2.1" @@ -3127,6 +4741,16 @@ dependencies = [ "windows", ] +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand 0.4.6", + "remove_dir_all", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -3152,6 +4776,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + [[package]] name = "thin-slice" version = "0.1.1" @@ -3175,7 +4808,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -3187,6 +4820,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "time" version = "0.3.17" @@ -3231,41 +4874,55 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.25.0" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", + "parking_lot 0.12.1", "pin-project-lite", "socket2", - "windows-sys 0.42.0", + "tokio-macros", + "windows-sys 0.45.0", ] [[package]] -name = "tokio-rustls" -version = "0.23.4" +name = "tokio-macros" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" dependencies = [ - "rustls", + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", "tokio", - "webpki", ] [[package]] -name = "tokio-stream" -version = "0.1.11" +name = "tokio-util" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" dependencies = [ + "bytes", "futures-core", + "futures-sink", "pin-project-lite", "tokio", + "tracing", ] [[package]] @@ -3294,6 +4951,12 @@ dependencies = [ "toml_datetime", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.37" @@ -3314,7 +4977,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -3327,6 +4990,26 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-log" version = "0.1.3" @@ -3338,6 +5021,20 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-opentelemetry" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbe89715c1dbbb790059e2565353978564924ee85017b5fff365c872ff6721f" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + [[package]] name = "tracing-subscriber" version = "0.3.16" @@ -3365,6 +5062,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "typenum" version = "1.16.0" @@ -3377,6 +5080,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-bidi" version = "0.3.10" @@ -3404,6 +5113,18 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "unicode_categories" version = "0.1.1" @@ -3411,10 +5132,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] -name = "untrusted" -version = "0.7.1" +name = "unreachable" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] [[package]] name = "url" @@ -3428,6 +5152,30 @@ dependencies = [ "serde", ] +[[package]] +name = "user-facing-error-macros" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "user-facing-errors" +version = "0.1.0" +source = "git+https://github.com/Brendonovich/prisma-engines?tag=pcr-0.6.5#7cc20cc54a7ab0b5e38c81901826939a91a17ba0" +dependencies = [ + "backtrace", + "indoc 1.0.9", + "quaint", + "serde", + "serde_json", + "tracing", + "user-facing-error-macros", +] + [[package]] name = "utf-8" version = "0.7.6" @@ -3447,6 +5195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ "getrandom 0.2.8", + "serde", ] [[package]] @@ -3479,6 +5228,21 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" @@ -3490,12 +5254,28 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3504,9 +5284,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3514,24 +5294,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ "bumpalo", + "lazy_static", "log", - "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.84" +name = "wasm-bindgen-futures" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3539,28 +5331,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" dependencies = [ "js-sys", "wasm-bindgen", @@ -3613,25 +5405,6 @@ dependencies = [ "system-deps 6.0.3", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] - [[package]] name = "webview2-com" version = "0.19.1" @@ -3652,7 +5425,7 @@ checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -3731,7 +5504,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" dependencies = [ - "syn", + "syn 1.0.107", "windows-tokens", ] @@ -3858,6 +5631,15 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "winres" version = "0.1.12" @@ -3893,7 +5675,7 @@ dependencies = [ "once_cell", "serde", "serde_json", - "sha2", + "sha2 0.10.6", "soup2", "tao", "thiserror", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b95c9fe2..6cd5dc26 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -17,11 +17,10 @@ tauri-build = { version = "1.2", features = [] } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } tauri = { version = "1.2", features = ["clipboard-read-text", "clipboard-write-text", "http-request", "os-all", "shell-open", "system-tray", "window-close", "window-start-dragging"] } - -[dependencies.tauri-plugin-sql] -git = "https://github.com/tauri-apps/plugins-workspace" -branch = "dev" -features = ["sqlite"] +prisma-client-rust = { git = "https://github.com/Brendonovich/prisma-client-rust", tag = "0.6.7", default-features = false, features = ["sqlite", "migrations", "mocking", "specta"] } +prisma-client-rust-cli = { git = "https://github.com/Brendonovich/prisma-client-rust", tag = "0.6.7", default-features = false, features = ["sqlite", "migrations", "mocking", "specta"] } +specta = "1.0.0" +tauri-specta = { version = "1.0.0", features = ["typescript"] } [target.'cfg(target_os = "macos")'.dependencies] objc = "0.2.7" diff --git a/src-tauri/prisma/migrations/.keep b/src-tauri/prisma/migrations/.keep new file mode 100644 index 00000000..e69de29b diff --git a/src-tauri/prisma/schema.prisma b/src-tauri/prisma/schema.prisma new file mode 100644 index 00000000..801e4503 --- /dev/null +++ b/src-tauri/prisma/schema.prisma @@ -0,0 +1,11 @@ +datasource db { + provider = "sqlite" + url = "file:lume.db" +} + +generator client { + // Corresponds to the cargo alias created earlier + provider = "cargo prisma" + // The location to generate the client. Is relative to the position of the schema + output = "../src/prisma.rs" +} diff --git a/src-tauri/src/bin/prisma.rs b/src-tauri/src/bin/prisma.rs new file mode 100644 index 00000000..b873b532 --- /dev/null +++ b/src-tauri/src/bin/prisma.rs @@ -0,0 +1,3 @@ +fn main() { + prisma_client_rust_cli::run(); +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 5001c2e3..67fe56dc 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -8,7 +8,6 @@ extern crate objc; use tauri::{Manager, WindowEvent}; -use tauri_plugin_sql::{Migration, MigrationKind}; #[cfg(target_os = "macos")] use window_ext::WindowExt; @@ -25,23 +24,11 @@ fn main() { Ok(()) }) - .plugin( - tauri_plugin_sql::Builder::default() - .add_migrations( - "sqlite:lume.db", - vec![Migration { - version: 1, - description: "create default tables", - sql: include_str!("../migrations/20230226004139_create_tables.sql"), - kind: MigrationKind::Up, - }], - ) - .build(), - ) .on_window_event(|e| { #[cfg(target_os = "macos")] let apply_offset = || { let win = e.window(); + // keep inset for traffic lights when window resize (macos) win.position_traffic_lights(8.0, 20.0); }; #[cfg(target_os = "macos")] From 39e7c9bf34c05fe04e22b3cc63ee345e93e98051 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sun, 2 Apr 2023 16:22:50 +0700 Subject: [PATCH 06/21] wip: convert tauri sql to prisma --- src-tauri/.gitignore | 3 +- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + .../20230226004139_create_tables.sql | 104 ------------------ src-tauri/prisma/schema.prisma | 72 +++++++++++- src-tauri/src/main.rs | 84 +++++++++++++- src/pages/index.tsx | 17 +-- src/pages/onboarding/create/index.tsx | 38 +++---- src/pages/onboarding/create/step-2.tsx | 35 ++---- src/utils/bindings.ts | 26 +++++ src/utils/transform.tsx | 9 ++ 11 files changed, 228 insertions(+), 162 deletions(-) delete mode 100644 src-tauri/migrations/20230226004139_create_tables.sql create mode 100644 src/utils/bindings.ts diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore index d35e841c..9f4929f3 100644 --- a/src-tauri/.gitignore +++ b/src-tauri/.gitignore @@ -3,4 +3,5 @@ /target/ # prisma -src/prisma.rs +src/db.rs +lume.db diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 7640a8e0..7129ab10 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2193,6 +2193,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-specta", + "tokio", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 6cd5dc26..a01d8208 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -21,6 +21,7 @@ prisma-client-rust = { git = "https://github.com/Brendonovich/prisma-client-rust prisma-client-rust-cli = { git = "https://github.com/Brendonovich/prisma-client-rust", tag = "0.6.7", default-features = false, features = ["sqlite", "migrations", "mocking", "specta"] } specta = "1.0.0" tauri-specta = { version = "1.0.0", features = ["typescript"] } +tokio = { version = "1.26.0", features = ["macros"] } [target.'cfg(target_os = "macos")'.dependencies] objc = "0.2.7" diff --git a/src-tauri/migrations/20230226004139_create_tables.sql b/src-tauri/migrations/20230226004139_create_tables.sql deleted file mode 100644 index ee4a05b7..00000000 --- a/src-tauri/migrations/20230226004139_create_tables.sql +++ /dev/null @@ -1,104 +0,0 @@ --- Add migration script here --- create relays -CREATE TABLE - relays ( - id INTEGER PRIMARY KEY, - relay_url TEXT NOT NULL, - relay_status INTEGER NOT NULL DEFAULT 1, - created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP - ); - --- add default relays --- relay status: --- 0: off --- 1: on -INSERT INTO - relays (relay_url, relay_status) -VALUES - ("wss://relay.damus.io", "1"), - ("wss://eden.nostr.land", "0"), - ("wss://nostr-pub.wellorder.net", "1"), - ("wss://nostr.bongbong.com", "1"), - ("wss://nostr.zebedee.cloud", "1"), - ("wss://nostr.fmt.wiz.biz", "1"), - ("wss://nostr.walletofsatoshi.com", "0"), - ("wss://relay.snort.social", "1"), - ("wss://offchain.pub", "1"), - ("wss://brb.io", "0"), - ("wss://relay.current.fyi", "1"), - ("wss://nostr.relayer.se", "0"), - ("wss://nostr.bitcoiner.social", "1"), - ("wss://relay.nostr.info", "1"), - ("wss://relay.zeh.app", "0"), - ("wss://nostr-01.dorafactory.org", "1"), - ("wss://nostr.zhongwen.world", "1"), - ("wss://nostro.cc", "1"), - ("wss://relay.nostr.net.in", "1"), - ("wss://nos.lol", "1"); - --- create accounts --- is_active (part of multi-account feature): --- 0: false --- 1: true -CREATE TABLE - accounts ( - id TEXT PRIMARY KEY, - privkey TEXT NOT NULL, - npub TEXT NOT NULL, - nsec TEXT NOT NULL, - is_active INTEGER NOT NULL DEFAULT 0, - metadata TEXT - ); - --- create follows --- kind (part of multi-newsfeed feature): --- 0: direct --- 1: follow of follow -CREATE TABLE - follows ( - id INTEGER PRIMARY KEY, - pubkey TEXT NOT NULL, - account TEXT NOT NULL, - kind INTEGER NOT NULL DEFAULT 0, - metadata TEXT - ); - --- create index for pubkey in follows -CREATE UNIQUE INDEX index_pubkey_on_follows ON follows (pubkey); - --- create cache profiles -CREATE TABLE - cache_profiles ( - id TEXT PRIMARY KEY, - metadata TEXT, - created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP - ); - --- create cache notes -CREATE TABLE - cache_notes ( - id TEXT PRIMARY KEY, - pubkey TEXT NOT NULL, - created_at TEXT, - kind INTEGER NOT NULL DEFAULT 1, - tags TEXT NOT NULL, - content TEXT NOT NULL, - parent_id TEXT, - parent_comment_id TEXT - ); - --- create settings -CREATE TABLE - settings ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - setting_key TEXT NOT NULL, - setting_value TEXT NOT NULL - ); - --- add default setting -INSERT INTO - settings (setting_key, setting_value) -VALUES - ("last_login", "0"); \ No newline at end of file diff --git a/src-tauri/prisma/schema.prisma b/src-tauri/prisma/schema.prisma index 801e4503..3d8f7c78 100644 --- a/src-tauri/prisma/schema.prisma +++ b/src-tauri/prisma/schema.prisma @@ -1,11 +1,75 @@ datasource db { provider = "sqlite" - url = "file:lume.db" + url = "file:../lume.db" } generator client { - // Corresponds to the cargo alias created earlier - provider = "cargo prisma" + provider = "cargo prisma" // The location to generate the client. Is relative to the position of the schema - output = "../src/prisma.rs" + output = "../src/db.rs" + module_path = "db" +} + +model Account { + id Int @id @default(autoincrement()) + pubkey String + privkey String @unique + active Boolean @default(false) + metadata String + + // related + follows Follow[] + messages Message[] + notes Note[] + + @@index([pubkey]) +} + +model Follow { + id Int @id @default(autoincrement()) + pubkey String + kind Int + metadata String + + Account Account @relation(fields: [accountId], references: [id]) + accountId Int +} + +model Note { + id Int @id @default(autoincrement()) + pubkey String + kind Int + tags String + content String + parent_id String + parent_comment_id String + createdAt DateTime @default(now()) + + Account Account @relation(fields: [accountId], references: [id]) + accountId Int +} + +model Message { + id Int @id @default(autoincrement()) + pubkey String + content String + tags String + createdAt DateTime @default(now()) + + Account Account @relation(fields: [accountId], references: [id]) + accountId Int + + @@index([pubkey]) +} + +model Relay { + id Int @id @default(autoincrement()) + url String + active Boolean @default(true) +} + +model Setting { + id Int @id @default(autoincrement()) + key String + value String } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 67fe56dc..fafb703b 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -8,13 +8,87 @@ extern crate objc; use tauri::{Manager, WindowEvent}; - #[cfg(target_os = "macos")] use window_ext::WindowExt; #[cfg(target_os = "macos")] mod window_ext; -fn main() { +mod db; + +use db::*; +use serde::Deserialize; +use specta::{collect_types, Type}; +use std::sync::Arc; +use tauri::State; +use tauri_specta::ts; + +type DbState<'a> = State<'a, Arc>; + +#[derive(Deserialize, Type)] +struct CreateAccountData { + pubkey: String, + privkey: String, + metadata: String, +} + +#[derive(Deserialize, Type)] +struct CreateFollowData { + pubkey: String, + kind: i32, + metadata: String, + account_id: i32, +} + +#[tauri::command] +#[specta::specta] +async fn get_account(db: DbState<'_>) -> Result, ()> { + db.account() + .find_many(vec![account::active::equals(true)]) + .exec() + .await + .map_err(|_| ()) +} + +#[tauri::command] +#[specta::specta] +async fn create_account(db: DbState<'_>, data: CreateAccountData) -> Result { + db.account() + .create(data.pubkey, data.privkey, data.metadata, vec![]) + .exec() + .await + .map_err(|_| ()) +} + +#[tauri::command] +#[specta::specta] +async fn create_follow(db: DbState<'_>, data: CreateFollowData) -> Result { + db.follow() + .create( + data.pubkey, + data.kind, + data.metadata, + account::id::equals(data.account_id), + vec![], + ) + .exec() + .await + .map_err(|_| ()) +} + +#[tokio::main] +async fn main() { + let db = PrismaClient::_builder().build().await.unwrap(); + + #[cfg(debug_assertions)] + ts::export( + collect_types![get_account, create_account, create_follow], + "../src/utils/bindings.ts", + ) + .unwrap(); + + #[cfg(debug_assertions)] + db._db_push().await.unwrap(); + tauri::Builder::default() .setup(|app| { let main_window = app.get_window("main").unwrap(); @@ -38,6 +112,12 @@ fn main() { _ => {} } }) + .invoke_handler(tauri::generate_handler![ + get_account, + create_account, + create_follow + ]) + .manage(Arc::new(db)) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 7b816aa6..c9581d5a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -2,24 +2,27 @@ import BaseLayout from '@layouts/base'; import { activeAccountAtom } from '@stores/account'; -import { getActiveAccount } from '@utils/storage'; - import LumeSymbol from '@assets/icons/Lume'; import { useSetAtom } from 'jotai'; import { useRouter } from 'next/router'; -import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useEffect } from 'react'; +import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useCallback, useEffect } from 'react'; export default function Page() { const router = useRouter(); const setActiveAccount = useSetAtom(activeAccountAtom); + const fetchActiveAccount = useCallback(async () => { + const { getAccount } = await import('@utils/bindings'); + return await getAccount(); + }, []); + useEffect(() => { - getActiveAccount() + fetchActiveAccount() .then((res: any) => { - if (res) { + if (res.length > 0) { // update local storage - setActiveAccount(res); + setActiveAccount(res[0]); // redirect router.replace('/init'); } else { @@ -27,7 +30,7 @@ export default function Page() { } }) .catch(console.error); - }, [router, setActiveAccount]); + }, [fetchActiveAccount, setActiveAccount, router]); return (
diff --git a/src/pages/onboarding/create/index.tsx b/src/pages/onboarding/create/index.tsx index 70e3c265..55f86ea4 100644 --- a/src/pages/onboarding/create/index.tsx +++ b/src/pages/onboarding/create/index.tsx @@ -2,13 +2,20 @@ import BaseLayout from '@layouts/base'; import { RelayContext } from '@components/relaysProvider'; -import { createAccount } from '@utils/storage'; - import { ArrowLeftIcon, EyeClosedIcon, EyeOpenIcon } from '@radix-ui/react-icons'; import Image from 'next/image'; import { useRouter } from 'next/router'; import { generatePrivateKey, getEventHash, getPublicKey, nip19, signEvent } from 'nostr-tools'; -import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useContext, useMemo, useState } from 'react'; +import { + JSXElementConstructor, + ReactElement, + ReactFragment, + ReactPortal, + useCallback, + useContext, + useMemo, + useState, +} from 'react'; import { Config, names, uniqueNamesGenerator } from 'unique-names-generator'; const config: Config = { @@ -39,23 +46,11 @@ export default function Page() { display_name: name, name: name, username: name.toLowerCase(), - picture: 'https://void.cat/d/KmypFh2fBdYCEvyJrPiN89', + picture: 'https://void.cat/d/KmypFh2fBdYCEvyJrPiN89.webp', }), [name] ); - // build profile - const data = useMemo( - () => ({ - pubkey: pubKey, - privkey: privKey, - npub: npub, - nsec: nsec, - metadata: metadata, - }), - [metadata, npub, nsec, privKey, pubKey] - ); - // toggle privatek key const showPrivateKey = () => { if (type === 'password') { @@ -66,7 +61,8 @@ export default function Page() { }; // create account and broadcast to all relays - const submit = () => { + const submit = useCallback(async () => { + const { createAccount } = await import('@utils/bindings'); setLoading(true); // build event @@ -81,16 +77,16 @@ export default function Page() { event.sig = signEvent(event, privKey); // insert to database then broadcast - createAccount(data) - .then(() => { + createAccount({ pubkey: pubKey, privkey: privKey, metadata: JSON.stringify(metadata) }) + .then((res) => { pool.publish(event, relays); router.push({ pathname: '/onboarding/create/step-2', - query: { id: pubKey, privkey: privKey }, + query: { id: res.id, privkey: res.privkey }, }); }) .catch(console.error); - }; + }, [pool, pubKey, privKey, metadata, relays, router]); return (
diff --git a/src/pages/onboarding/create/step-2.tsx b/src/pages/onboarding/create/step-2.tsx index 9c8e6bd5..b31d4f78 100644 --- a/src/pages/onboarding/create/step-2.tsx +++ b/src/pages/onboarding/create/step-2.tsx @@ -3,7 +3,7 @@ import BaseLayout from '@layouts/base'; import { RelayContext } from '@components/relaysProvider'; import { UserBase } from '@components/user/base'; -import { createFollows } from '@utils/storage'; +import { followsTag } from '@utils/transform'; import { CheckCircledIcon } from '@radix-ui/react-icons'; import { createClient } from '@supabase/supabase-js'; @@ -15,6 +15,7 @@ import { ReactElement, ReactFragment, ReactPortal, + useCallback, useContext, useEffect, useState, @@ -76,18 +77,9 @@ export default function Page() { setFollows(arr); }; - // build event tags - const tags = () => { - const arr = []; - // push item to tags - follows.forEach((item) => { - arr.push(['p', item]); - }); - return arr; - }; - // save follows to database then broadcast - const submit = () => { + const submit = useCallback(async () => { + const { createFollow } = await import('@utils/bindings'); setLoading(true); // build event @@ -96,21 +88,18 @@ export default function Page() { created_at: Math.floor(Date.now() / 1000), kind: 3, pubkey: id, - tags: tags(), + tags: followsTag(follows), }; event.id = getEventHash(event); event.sig = signEvent(event, privkey); - createFollows(follows, id, 0) - .then((res) => { - if (res === 'ok') { - // publish to relays - pool.publish(event, relays); - router.replace('/'); - } - }) - .catch(console.error); - }; + follows.forEach((item) => { + createFollow({ pubkey: item, kind: 0, metadata: JSON.stringify({}), account_id: id }); + }); + + pool.publish(event, relays); + router.replace('/'); + }, [follows, id, pool, privkey, relays, router]); useEffect(() => { const fetchData = async () => { diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts new file mode 100644 index 00000000..28b56dab --- /dev/null +++ b/src/utils/bindings.ts @@ -0,0 +1,26 @@ +// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually. + +declare global { + interface Window { + __TAURI_INVOKE__(cmd: string, args?: Record): Promise; + } +} + +const invoke = window.__TAURI_INVOKE__; + +export function getAccount() { + return invoke('get_account'); +} + +export function createAccount(data: CreateAccountData) { + return invoke('create_account', { data }); +} + +export function createFollow(data: CreateFollowData) { + return invoke('create_follow', { data }); +} + +export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; +export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; +export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; +export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; diff --git a/src/utils/transform.tsx b/src/utils/transform.tsx index 31dda620..ebc01fb9 100644 --- a/src/utils/transform.tsx +++ b/src/utils/transform.tsx @@ -9,6 +9,15 @@ export const tagsToArray = (arr) => { return newarr; }; +export const followsTag = (arr) => { + const newarr = []; + // push item to tags + arr.forEach((item) => { + arr.push(['p', item]); + }); + return newarr; +}; + export const pubkeyArray = (arr) => { const newarr = []; // push item to newarr From 33000979edbe5f7f2195003d641723979eb4ff85 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Mon, 3 Apr 2023 08:43:37 +0700 Subject: [PATCH 07/21] refactor user component and updated onboarding --- src-tauri/src/main.rs | 2 +- src/components/user/base.tsx | 27 +++++----------- src/components/user/extend.tsx | 33 +++++-------------- src/components/user/large.tsx | 33 +++++-------------- src/components/user/mention.tsx | 34 ++++++------------- src/components/user/mini.tsx | 18 +++++------ src/pages/onboarding/create/index.tsx | 2 +- src/pages/onboarding/create/step-2.tsx | 16 +++++---- src/pages/onboarding/login/step-2.tsx | 45 +++++++++++++++++--------- src/utils/metadata.tsx | 6 ++++ src/utils/transform.tsx | 2 +- 11 files changed, 89 insertions(+), 129 deletions(-) create mode 100644 src/utils/metadata.tsx diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index fafb703b..3a431503 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -43,7 +43,7 @@ struct CreateFollowData { #[specta::specta] async fn get_account(db: DbState<'_>) -> Result, ()> { db.account() - .find_many(vec![account::active::equals(true)]) + .find_many(vec![account::active::equals(false)]) .exec() .await .map_err(|_| ()) diff --git a/src/components/user/base.tsx b/src/components/user/base.tsx index d8feabba..9f87cfbd 100644 --- a/src/components/user/base.tsx +++ b/src/components/user/base.tsx @@ -1,33 +1,22 @@ import { ImageWithFallback } from '@components/imageWithFallback'; +import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; -import { createCacheProfile } from '@utils/storage'; import { truncate } from '@utils/truncate'; -import { fetch } from '@tauri-apps/api/http'; -import destr from 'destr'; -import { memo, useCallback, useEffect, useState } from 'react'; +import { Author } from 'nostr-relaypool'; +import { memo, useContext, useEffect, useMemo, useState } from 'react'; export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) { - const [profile, setProfile] = useState(null); + const [pool, relays]: any = useContext(RelayContext); - const fetchProfile = useCallback(async (id: string) => { - const res = await fetch(`https://rbr.bio/${id}/metadata.json`, { - method: 'GET', - timeout: 30, - }); - return res.data; - }, []); + const [profile, setProfile] = useState(null); + const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { - fetchProfile(pubkey) - .then((res: any) => { - setProfile(destr(res.content)); - createCacheProfile(res.pubkey, res.content); - }) - .catch(console.error); - }, [fetchProfile, pubkey]); + user.metaData((res) => setProfile(JSON.parse(res.content)), 0); + }, [user]); return (
diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx index 8672de8c..7039cea1 100644 --- a/src/components/user/extend.tsx +++ b/src/components/user/extend.tsx @@ -1,51 +1,34 @@ import { ImageWithFallback } from '@components/imageWithFallback'; +import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; -import { createCacheProfile, getCacheProfile } from '@utils/storage'; import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; -import { fetch } from '@tauri-apps/api/http'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; -import destr from 'destr'; import { useRouter } from 'next/router'; -import { memo, useCallback, useEffect, useState } from 'react'; +import { Author } from 'nostr-relaypool'; +import { memo, useContext, useEffect, useMemo, useState } from 'react'; dayjs.extend(relativeTime); export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: string; time: any }) { + const [pool, relays]: any = useContext(RelayContext); const router = useRouter(); + const [profile, setProfile] = useState(null); + const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); const openUserPage = (e) => { e.stopPropagation(); router.push(`/users/${pubkey}`); }; - const fetchProfile = useCallback(async (id: string) => { - const res = await fetch(`https://rbr.bio/${id}/metadata.json`, { - method: 'GET', - timeout: 30, - }); - return res.data; - }, []); - useEffect(() => { - getCacheProfile(pubkey).then((res) => { - if (res) { - setProfile(destr(res.metadata)); - } else { - fetchProfile(pubkey) - .then((res: any) => { - setProfile(destr(res.content)); - createCacheProfile(pubkey, res.content); - }) - .catch(console.error); - } - }); - }, [fetchProfile, pubkey]); + user.metaData((res) => setProfile(JSON.parse(res.content)), 0); + }, [user]); return (
diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx index 634ab02e..0a660dd2 100644 --- a/src/components/user/large.tsx +++ b/src/components/user/large.tsx @@ -1,44 +1,27 @@ import { ImageWithFallback } from '@components/imageWithFallback'; +import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; -import { createCacheProfile, getCacheProfile } from '@utils/storage'; import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; -import { fetch } from '@tauri-apps/api/http'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; -import destr from 'destr'; -import { memo, useCallback, useEffect, useState } from 'react'; +import { Author } from 'nostr-relaypool'; +import { memo, useContext, useEffect, useMemo, useState } from 'react'; dayjs.extend(relativeTime); export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: string; time: any }) { - const [profile, setProfile] = useState(null); + const [pool, relays]: any = useContext(RelayContext); - const fetchProfile = useCallback(async (id: string) => { - const res = await fetch(`https://rbr.bio/${id}/metadata.json`, { - method: 'GET', - timeout: 30, - }); - return res.data; - }, []); + const [profile, setProfile] = useState(null); + const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { - getCacheProfile(pubkey).then((res) => { - if (res) { - setProfile(destr(res.metadata)); - } else { - fetchProfile(pubkey) - .then((res: any) => { - setProfile(destr(res.content)); - createCacheProfile(pubkey, res.content); - }) - .catch(console.error); - } - }); - }, [fetchProfile, pubkey]); + user.metaData((res) => setProfile(JSON.parse(res.content)), 0); + }, [user]); return (
diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx index 06b4b0bf..4cae27fd 100644 --- a/src/components/user/mention.tsx +++ b/src/components/user/mention.tsx @@ -1,35 +1,19 @@ -import { createCacheProfile, getCacheProfile } from '@utils/storage'; +import { RelayContext } from '@components/relaysProvider'; + import { truncate } from '@utils/truncate'; -import { fetch } from '@tauri-apps/api/http'; -import destr from 'destr'; -import { memo, useCallback, useEffect, useState } from 'react'; +import { Author } from 'nostr-relaypool'; +import { memo, useContext, useEffect, useMemo, useState } from 'react'; export const UserMention = memo(function UserMention({ pubkey }: { pubkey: string }) { - const [profile, setProfile] = useState(null); + const [pool, relays]: any = useContext(RelayContext); - const fetchProfile = useCallback(async (id: string) => { - const res = await fetch(`https://rbr.bio/${id}/metadata.json`, { - method: 'GET', - timeout: 30, - }); - return res.data; - }, []); + const [profile, setProfile] = useState(null); + const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { - getCacheProfile(pubkey).then((res) => { - if (res) { - setProfile(destr(res.metadata)); - } else { - fetchProfile(pubkey) - .then((res: any) => { - setProfile(destr(res.content)); - createCacheProfile(pubkey, res.content); - }) - .catch(console.error); - } - }); - }, [fetchProfile, pubkey]); + user.metaData((res) => setProfile(JSON.parse(res.content)), 0); + }, [user]); return @{profile?.name || truncate(pubkey, 16, ' .... ')}; }); diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx index b5fa2bdd..22b74547 100644 --- a/src/components/user/mini.tsx +++ b/src/components/user/mini.tsx @@ -1,24 +1,22 @@ import { ImageWithFallback } from '@components/imageWithFallback'; +import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; -import { getCacheProfile } from '@utils/storage'; import { truncate } from '@utils/truncate'; -import { useCallback, useEffect, useState } from 'react'; +import { Author } from 'nostr-relaypool'; +import { useContext, useEffect, useMemo, useState } from 'react'; export const UserMini = ({ pubkey }: { pubkey: string }) => { - const [profile, setProfile] = useState(null); + const [pool, relays]: any = useContext(RelayContext); - const fetchCacheProfile = useCallback(async (id: string) => { - const res = await getCacheProfile(id); - const data = JSON.parse(res.metadata); - setProfile(data); - }, []); + const [profile, setProfile] = useState(null); + const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { - fetchCacheProfile(pubkey).catch(console.error); - }, [fetchCacheProfile, pubkey]); + user.metaData((res) => setProfile(JSON.parse(res.content)), 0); + }, [user]); if (profile) { return ( diff --git a/src/pages/onboarding/create/index.tsx b/src/pages/onboarding/create/index.tsx index 55f86ea4..9e9d7880 100644 --- a/src/pages/onboarding/create/index.tsx +++ b/src/pages/onboarding/create/index.tsx @@ -82,7 +82,7 @@ export default function Page() { pool.publish(event, relays); router.push({ pathname: '/onboarding/create/step-2', - query: { id: res.id, privkey: res.privkey }, + query: { id: res.id, pubkey: res.pubkey, privkey: res.privkey }, }); }) .catch(console.error); diff --git a/src/pages/onboarding/create/step-2.tsx b/src/pages/onboarding/create/step-2.tsx index b31d4f78..4831a6e4 100644 --- a/src/pages/onboarding/create/step-2.tsx +++ b/src/pages/onboarding/create/step-2.tsx @@ -3,6 +3,7 @@ import BaseLayout from '@layouts/base'; import { RelayContext } from '@components/relaysProvider'; import { UserBase } from '@components/user/base'; +import { fetchMetadata } from '@utils/metadata'; import { followsTag } from '@utils/transform'; import { CheckCircledIcon } from '@radix-ui/react-icons'; @@ -65,7 +66,7 @@ export default function Page() { const [pool, relays]: any = useContext(RelayContext); const router = useRouter(); - const { id, privkey }: any = router.query || ''; + const { id, pubkey, privkey }: any = router.query || ''; const [loading, setLoading] = useState(false); const [list, setList]: any = useState(initialList); @@ -82,24 +83,25 @@ export default function Page() { const { createFollow } = await import('@utils/bindings'); setLoading(true); + for (const follow of follows) { + const metadata: any = await fetchMetadata(follow, pool, relays); + createFollow({ pubkey: follow, kind: 0, metadata: metadata.content, account_id: parseInt(id) }); + } + // build event const event: any = { content: '', created_at: Math.floor(Date.now() / 1000), kind: 3, - pubkey: id, + pubkey: pubkey, tags: followsTag(follows), }; event.id = getEventHash(event); event.sig = signEvent(event, privkey); - follows.forEach((item) => { - createFollow({ pubkey: item, kind: 0, metadata: JSON.stringify({}), account_id: id }); - }); - pool.publish(event, relays); router.replace('/'); - }, [follows, id, pool, privkey, relays, router]); + }, [follows, id, pool, pubkey, privkey, relays, router]); useEffect(() => { const fetchData = async () => { diff --git a/src/pages/onboarding/login/step-2.tsx b/src/pages/onboarding/login/step-2.tsx index 9e40f6c0..fee12df2 100644 --- a/src/pages/onboarding/login/step-2.tsx +++ b/src/pages/onboarding/login/step-2.tsx @@ -2,21 +2,21 @@ import BaseLayout from '@layouts/base'; import { RelayContext } from '@components/relaysProvider'; -import { createAccount, createFollows } from '@utils/storage'; -import { tagsToArray } from '@utils/transform'; +import { fetchMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; -import destr from 'destr'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import { getPublicKey, nip19 } from 'nostr-tools'; +import { getPublicKey } from 'nostr-tools'; import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, + useCallback, useContext, useEffect, + useRef, useState, } from 'react'; @@ -30,6 +30,28 @@ export default function Page() { const [profile, setProfile] = useState(null); const [done, setDone] = useState(false); + const accountId = useRef(null); + + const insertAccountToStorage = useCallback(async (pubkey, privkey, metadata) => { + const { createAccount } = await import('@utils/bindings'); + createAccount({ pubkey: pubkey, privkey: privkey, metadata: JSON.stringify(metadata) }).then( + (res) => (accountId.current = res.id) + ); + }, []); + + const insertFollowsToStorage = useCallback( + async (tags) => { + const { createFollow } = await import('@utils/bindings'); + if (accountId.current !== null) { + for (const tag of tags) { + const metadata: any = await fetchMetadata(tag[1], pool, relays); + createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: accountId.current }); + } + } + }, + [pool, relays] + ); + useEffect(() => { const unsubscribe = pool.subscribe( [ @@ -42,18 +64,11 @@ export default function Page() { relays, (event: any) => { if (event.kind === 0) { - const data = { - pubkey: pubkey, - privkey: privkey, - npub: nip19.npubEncode(pubkey), - nsec: nip19.nsecEncode(privkey), - metadata: event.content, - }; - setProfile(destr(event.content)); - createAccount(data); + setProfile(JSON.parse(event.content)); + insertAccountToStorage(pubkey, privkey, event.content); } else { if (event.tags.length > 0) { - createFollows(tagsToArray(event.tags), pubkey, 0); + insertFollowsToStorage(event.tags); } } }, @@ -69,7 +84,7 @@ export default function Page() { return () => { unsubscribe; }; - }, [pool, privkey, pubkey, relays]); + }, [insertAccountToStorage, insertFollowsToStorage, pool, relays, privkey, pubkey]); // submit then redirect to home const submit = () => { diff --git a/src/utils/metadata.tsx b/src/utils/metadata.tsx new file mode 100644 index 00000000..5598ed8a --- /dev/null +++ b/src/utils/metadata.tsx @@ -0,0 +1,6 @@ +import { Author } from 'nostr-relaypool'; + +export const fetchMetadata = (pubkey: string, pool: any, relays: any) => { + const author = new Author(pool, relays, pubkey); + return new Promise((resolve) => author.metaData(resolve, 0)); +}; diff --git a/src/utils/transform.tsx b/src/utils/transform.tsx index ebc01fb9..e9bb58e5 100644 --- a/src/utils/transform.tsx +++ b/src/utils/transform.tsx @@ -13,7 +13,7 @@ export const followsTag = (arr) => { const newarr = []; // push item to tags arr.forEach((item) => { - arr.push(['p', item]); + newarr.push(['p', item]); }); return newarr; }; From 3f87d510ab4c63b1f22923a6fa750b17f1884ba2 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:03:07 +0700 Subject: [PATCH 08/21] converted full sql from onboarding flow to prisma --- .gitignore | 2 + src-tauri/.gitignore | 1 - .../20230403043730_initial/migration.sql | 73 ++++++++++++++ .../prisma/migrations/migration_lock.toml | 3 + src-tauri/prisma/schema.prisma | 5 +- src-tauri/src/main.rs | 91 ++++++++++++++++- src/components/note/connector.tsx | 7 +- src/pages/index.tsx | 14 ++- src/pages/init.tsx | 97 ++++++++++--------- src/pages/onboarding/create/index.tsx | 4 +- src/pages/onboarding/create/step-2.tsx | 4 +- src/pages/onboarding/login/step-2.tsx | 42 +++++--- src/stores/account.tsx | 2 + src/utils/bindings.ts | 43 +++++++- 14 files changed, 314 insertions(+), 74 deletions(-) create mode 100644 src-tauri/prisma/migrations/20230403043730_initial/migration.sql create mode 100644 src-tauri/prisma/migrations/migration_lock.toml diff --git a/.gitignore b/.gitignore index 4094a70b..7afdbe21 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ out .next .vscode pnpm-lock.yaml +*.db +*.db-journal # Editor directories and files .vscode/* diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore index 9f4929f3..0c1d05c7 100644 --- a/src-tauri/.gitignore +++ b/src-tauri/.gitignore @@ -4,4 +4,3 @@ # prisma src/db.rs -lume.db diff --git a/src-tauri/prisma/migrations/20230403043730_initial/migration.sql b/src-tauri/prisma/migrations/20230403043730_initial/migration.sql new file mode 100644 index 00000000..e86009dc --- /dev/null +++ b/src-tauri/prisma/migrations/20230403043730_initial/migration.sql @@ -0,0 +1,73 @@ +-- CreateTable +CREATE TABLE "Account" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "pubkey" TEXT NOT NULL, + "privkey" TEXT NOT NULL, + "active" BOOLEAN NOT NULL DEFAULT false, + "metadata" TEXT NOT NULL +); + +-- CreateTable +CREATE TABLE "Follow" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "pubkey" TEXT NOT NULL, + "kind" INTEGER NOT NULL, + "metadata" TEXT NOT NULL, + "accountId" INTEGER NOT NULL, + CONSTRAINT "Follow_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "Note" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "eventId" TEXT NOT NULL, + "pubkey" TEXT NOT NULL, + "kind" INTEGER NOT NULL, + "tags" TEXT NOT NULL, + "content" TEXT NOT NULL, + "parent_id" TEXT NOT NULL, + "parent_comment_id" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "accountId" INTEGER NOT NULL, + CONSTRAINT "Note_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "Message" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "pubkey" TEXT NOT NULL, + "content" TEXT NOT NULL, + "tags" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "accountId" INTEGER NOT NULL, + CONSTRAINT "Message_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "Relay" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "url" TEXT NOT NULL, + "active" BOOLEAN NOT NULL DEFAULT true +); + +-- CreateTable +CREATE TABLE "Setting" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "key" TEXT NOT NULL, + "value" TEXT NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "Account_privkey_key" ON "Account"("privkey"); + +-- CreateIndex +CREATE INDEX "Account_pubkey_idx" ON "Account"("pubkey"); + +-- CreateIndex +CREATE UNIQUE INDEX "Note_eventId_key" ON "Note"("eventId"); + +-- CreateIndex +CREATE INDEX "Note_eventId_idx" ON "Note"("eventId"); + +-- CreateIndex +CREATE INDEX "Message_pubkey_idx" ON "Message"("pubkey"); diff --git a/src-tauri/prisma/migrations/migration_lock.toml b/src-tauri/prisma/migrations/migration_lock.toml new file mode 100644 index 00000000..e5e5c470 --- /dev/null +++ b/src-tauri/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "sqlite" \ No newline at end of file diff --git a/src-tauri/prisma/schema.prisma b/src-tauri/prisma/schema.prisma index 3d8f7c78..44f8fae3 100644 --- a/src-tauri/prisma/schema.prisma +++ b/src-tauri/prisma/schema.prisma @@ -1,6 +1,6 @@ datasource db { provider = "sqlite" - url = "file:../lume.db" + url = "file:../../lume.db" } generator client { @@ -37,6 +37,7 @@ model Follow { model Note { id Int @id @default(autoincrement()) + eventId String @unique pubkey String kind Int tags String @@ -47,6 +48,8 @@ model Note { Account Account @relation(fields: [accountId], references: [id]) accountId Int + + @@index([eventId]) } model Message { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 3a431503..c6bde5af 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -7,6 +7,7 @@ #[macro_use] extern crate objc; +use prisma_client_rust::raw; use tauri::{Manager, WindowEvent}; #[cfg(target_os = "macos")] use window_ext::WindowExt; @@ -31,6 +32,11 @@ struct CreateAccountData { metadata: String, } +#[derive(Deserialize, Type)] +struct GetFollowData { + account_id: i32, +} + #[derive(Deserialize, Type)] struct CreateFollowData { pubkey: String, @@ -39,6 +45,18 @@ struct CreateFollowData { account_id: i32, } +#[derive(Deserialize, Type)] +struct CreateNoteData { + event_id: String, + pubkey: String, + kind: i32, + tags: String, + content: String, + parent_id: String, + parent_comment_id: String, + account_id: i32, +} + #[tauri::command] #[specta::specta] async fn get_account(db: DbState<'_>) -> Result, ()> { @@ -59,6 +77,16 @@ async fn create_account(db: DbState<'_>, data: CreateAccountData) -> Result, data: GetFollowData) -> Result, ()> { + db.follow() + .find_many(vec![follow::account_id::equals(data.account_id)]) + .exec() + .await + .map_err(|_| ()) +} + #[tauri::command] #[specta::specta] async fn create_follow(db: DbState<'_>, data: CreateFollowData) -> Result { @@ -75,13 +103,68 @@ async fn create_follow(db: DbState<'_>, data: CreateFollowData) -> Result, data: CreateNoteData) -> Result { + let event_id = data.event_id.clone(); + let content = data.content.clone(); + + db.note() + .upsert( + note::event_id::equals(event_id), + note::create( + data.event_id, + data.pubkey, + data.kind, + data.tags, + data.content, + data.parent_id, + data.parent_comment_id, + account::id::equals(data.account_id), + vec![], + ), + vec![note::content::set(content)], + ) + .exec() + .await + .map_err(|_| ()) +} + +#[tauri::command] +#[specta::specta] +async fn get_notes(db: DbState<'_>) -> Result, ()> { + db._query_raw(raw!("SELECT * FROM Note")) + .exec() + .await + .map_err(|_| ()) +} + +#[tauri::command] +#[specta::specta] +async fn check_note(db: DbState<'_>) -> Result, ()> { + db.note() + .find_many(vec![]) + .take(5) + .exec() + .await + .map_err(|_| ()) +} + #[tokio::main] async fn main() { let db = PrismaClient::_builder().build().await.unwrap(); #[cfg(debug_assertions)] ts::export( - collect_types![get_account, create_account, create_follow], + collect_types![ + get_account, + create_account, + get_follows, + create_follow, + create_note, + get_notes, + check_note + ], "../src/utils/bindings.ts", ) .unwrap(); @@ -115,7 +198,11 @@ async fn main() { .invoke_handler(tauri::generate_handler![ get_account, create_account, - create_follow + get_follows, + create_follow, + create_note, + get_notes, + check_note ]) .manage(Arc::new(db)) .run(tauri::generate_context!()) diff --git a/src/components/note/connector.tsx b/src/components/note/connector.tsx index 12ef9ac7..49852348 100644 --- a/src/components/note/connector.tsx +++ b/src/components/note/connector.tsx @@ -1,10 +1,10 @@ import { RelayContext } from '@components/relaysProvider'; -import { activeAccountAtom } from '@stores/account'; +import { activeAccountAtom, lastLoginAtom } from '@stores/account'; import { hasNewerNoteAtom } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; -import { createCacheNote, getAllFollowsByID, updateLastLoginTime } from '@utils/storage'; +import { createCacheNote, getAllFollowsByID } from '@utils/storage'; import { pubkeyArray } from '@utils/transform'; import { TauriEvent } from '@tauri-apps/api/event'; @@ -15,6 +15,7 @@ import { useCallback, useContext, useEffect, useRef, useState } from 'react'; export default function NoteConnector() { const [pool, relays]: any = useContext(RelayContext); + const setLastLoginAtom = useSetAtom(lastLoginAtom); const setHasNewerNote = useSetAtom(hasNewerNoteAtom); const activeAccount: any = useAtomValue(activeAccountAtom); @@ -44,7 +45,7 @@ export default function NoteConnector() { useEffect(() => { subscribe(); getCurrent().listen(TauriEvent.WINDOW_CLOSE_REQUESTED, () => { - updateLastLoginTime(now.current); + setLastLoginAtom(now.current); appWindow.close(); }); }, [activeAccount.id, pool, relays, setHasNewerNote, subscribe]); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index c9581d5a..4b0af815 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,6 +1,6 @@ import BaseLayout from '@layouts/base'; -import { activeAccountAtom } from '@stores/account'; +import { activeAccountAtom, activeAccountFollowsAtom } from '@stores/account'; import LumeSymbol from '@assets/icons/Lume'; @@ -11,16 +11,26 @@ import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useCal export default function Page() { const router = useRouter(); const setActiveAccount = useSetAtom(activeAccountAtom); + const setActiveAccountFollows = useSetAtom(activeAccountFollowsAtom); const fetchActiveAccount = useCallback(async () => { const { getAccount } = await import('@utils/bindings'); return await getAccount(); }, []); + const fetchFollowsByAccount = useCallback(async (id) => { + const { getFollows } = await import('@utils/bindings'); + return await getFollows({ account_id: id }); + }, []); + useEffect(() => { fetchActiveAccount() .then((res: any) => { if (res.length > 0) { + // fetch follows + fetchFollowsByAccount(res[0].id).then((follows) => { + setActiveAccountFollows(follows); + }); // update local storage setActiveAccount(res[0]); // redirect @@ -30,7 +40,7 @@ export default function Page() { } }) .catch(console.error); - }, [fetchActiveAccount, setActiveAccount, router]); + }, [fetchActiveAccount, setActiveAccount, fetchFollowsByAccount, setActiveAccountFollows, router]); return (
diff --git a/src/pages/init.tsx b/src/pages/init.tsx index 562318e4..4ab32b69 100644 --- a/src/pages/init.tsx +++ b/src/pages/init.tsx @@ -2,12 +2,10 @@ import BaseLayout from '@layouts/base'; import { RelayContext } from '@components/relaysProvider'; -import { activeAccountAtom } from '@stores/account'; -import { relaysAtom } from '@stores/relays'; +import { activeAccountAtom, activeAccountFollowsAtom, lastLoginAtom } from '@stores/account'; import { dateToUnix, hoursAgo } from '@utils/getDate'; -import { countTotalNotes, createCacheNote, getAllFollowsByID, getLastLoginTime } from '@utils/storage'; -import { pubkeyArray } from '@utils/transform'; +import { getParentID, pubkeyArray } from '@utils/transform'; import LumeSymbol from '@assets/icons/Lume'; @@ -30,64 +28,75 @@ export default function Page() { const [pool, relays]: any = useContext(RelayContext); const activeAccount: any = useAtomValue(activeAccountAtom); - const [done, setDone] = useState(false); + const activeAccountFollows: any = useAtomValue(activeAccountFollowsAtom); + const lastLogin: any = useAtomValue(lastLoginAtom); const now = useRef(new Date()); const unsubscribe = useRef(null); - const timer = useRef(null); + + const [eose, setEose] = useState(false); const fetchData = useCallback( - (since) => { - getAllFollowsByID(activeAccount.id).then((follows) => { - unsubscribe.current = pool.subscribe( - [ - { - kinds: [1], - authors: pubkeyArray(follows), - since: dateToUnix(since), - until: dateToUnix(now.current), - }, - ], - relays, - (event) => { - // insert event to local database - createCacheNote(event); - }, - undefined, - () => { - // wait for 8 seconds - timer.current = setTimeout(() => setDone(true), 8000); - }, + async (since) => { + const { createNote } = await import('@utils/bindings'); + unsubscribe.current = pool.subscribe( + [ { - unsubscribeOnEose: true, - } - ); - }); + kinds: [1], + authors: pubkeyArray(activeAccountFollows), + since: dateToUnix(since), + until: dateToUnix(now.current), + }, + ], + relays, + (event) => { + const parentID = getParentID(event.tags, event.id); + // insert event to local database + createNote({ + event_id: event.id, + pubkey: event.pubkey, + kind: event.kind, + tags: JSON.stringify(event.tags), + content: event.content, + parent_id: parentID, + parent_comment_id: 'aaa', + account_id: activeAccount.id, + }).catch(console.error); + }, + undefined, + () => { + setEose(true); + } + ); }, - [activeAccount.id, pool, relays] + [activeAccount.id, activeAccountFollows, pool, relays] ); - useEffect(() => { - if (!done) { - countTotalNotes().then((count) => { - if (count.total === 0) { - fetchData(hoursAgo(24, now.current)); + const isNoteExist = useCallback(async () => { + const { checkNote } = await import('@utils/bindings'); + checkNote() + .then((res) => { + if (res.length === 5) { + const parseDate = new Date(lastLogin); + fetchData(parseDate); } else { - getLastLoginTime().then((time) => { - const parseDate = new Date(time.setting_value); - fetchData(parseDate); - }); + fetchData(hoursAgo(24, now.current)); } - }); + }) + .catch(console.error); + }, [fetchData, lastLogin]); + + useEffect(() => { + if (eose === false) { + isNoteExist(); } else { router.replace('/newsfeed/following'); } return () => { unsubscribe.current; - clearTimeout(timer.current); }; - }, [activeAccount.id, done, pool, relays, router, fetchData]); + }, [router, eose, isNoteExist]); return (
diff --git a/src/pages/onboarding/create/index.tsx b/src/pages/onboarding/create/index.tsx index 9e9d7880..b445e068 100644 --- a/src/pages/onboarding/create/index.tsx +++ b/src/pages/onboarding/create/index.tsx @@ -41,7 +41,7 @@ export default function Page() { }; // auto-generated profile metadata - const metadata = useMemo( + const metadata: any = useMemo( () => ({ display_name: name, name: name, @@ -77,7 +77,7 @@ export default function Page() { event.sig = signEvent(event, privKey); // insert to database then broadcast - createAccount({ pubkey: pubKey, privkey: privKey, metadata: JSON.stringify(metadata) }) + createAccount({ pubkey: pubKey, privkey: privKey, metadata: metadata }) .then((res) => { pool.publish(event, relays); router.push({ diff --git a/src/pages/onboarding/create/step-2.tsx b/src/pages/onboarding/create/step-2.tsx index 4831a6e4..63b5e7c8 100644 --- a/src/pages/onboarding/create/step-2.tsx +++ b/src/pages/onboarding/create/step-2.tsx @@ -85,7 +85,9 @@ export default function Page() { for (const follow of follows) { const metadata: any = await fetchMetadata(follow, pool, relays); - createFollow({ pubkey: follow, kind: 0, metadata: metadata.content, account_id: parseInt(id) }); + createFollow({ pubkey: follow, kind: 0, metadata: metadata.content, account_id: parseInt(id) }).catch( + console.error + ); } // build event diff --git a/src/pages/onboarding/login/step-2.tsx b/src/pages/onboarding/login/step-2.tsx index fee12df2..c9d16c7b 100644 --- a/src/pages/onboarding/login/step-2.tsx +++ b/src/pages/onboarding/login/step-2.tsx @@ -2,6 +2,8 @@ import BaseLayout from '@layouts/base'; import { RelayContext } from '@components/relaysProvider'; +import { DEFAULT_AVATAR } from '@stores/constants'; + import { fetchMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; @@ -27,29 +29,34 @@ export default function Page() { const privkey: any = router.query.privkey || null; const pubkey = privkey ? getPublicKey(privkey) : null; - const [profile, setProfile] = useState(null); + const [profile, setProfile] = useState({ id: null, metadata: null }); const [done, setDone] = useState(false); - const accountId = useRef(null); - const insertAccountToStorage = useCallback(async (pubkey, privkey, metadata) => { const { createAccount } = await import('@utils/bindings'); - createAccount({ pubkey: pubkey, privkey: privkey, metadata: JSON.stringify(metadata) }).then( - (res) => (accountId.current = res.id) - ); + createAccount({ pubkey: pubkey, privkey: privkey, metadata: metadata }) + .then((res) => + setProfile({ + id: res.id, + metadata: JSON.parse(res.metadata), + }) + ) + .catch(console.error); }, []); const insertFollowsToStorage = useCallback( async (tags) => { const { createFollow } = await import('@utils/bindings'); - if (accountId.current !== null) { + if (profile?.id !== null) { for (const tag of tags) { const metadata: any = await fetchMetadata(tag[1], pool, relays); - createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: accountId.current }); + createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: profile.id }).catch( + console.error + ); } } }, - [pool, relays] + [pool, profile.id, relays] ); useEffect(() => { @@ -64,7 +71,6 @@ export default function Page() { relays, (event: any) => { if (event.kind === 0) { - setProfile(JSON.parse(event.content)); insertAccountToStorage(pubkey, privkey, event.content); } else { if (event.tags.length > 0) { @@ -75,9 +81,6 @@ export default function Page() { undefined, () => { setDone(true); - }, - { - unsubscribeOnEose: true, } ); @@ -106,13 +109,20 @@ export default function Page() {
- +
-

{profile?.display_name || profile?.name}

+

{profile.metadata?.display_name || profile.metadata?.name}

· -

@{profile?.username || (pubkey && truncate(pubkey, 16, ' .... '))}

+

+ @{profile.metadata?.username || (pubkey && truncate(pubkey, 16, ' .... '))} +

diff --git a/src/stores/account.tsx b/src/stores/account.tsx index f5568ba4..7c70b99e 100644 --- a/src/stores/account.tsx +++ b/src/stores/account.tsx @@ -10,3 +10,5 @@ const createMyJsonStorage = () => { }; export const activeAccountAtom = atomWithStorage('activeAccount', {}, createMyJsonStorage()); +export const activeAccountFollowsAtom = atomWithStorage('activeAccountFollows', [], createMyJsonStorage()); +export const lastLoginAtom = atomWithStorage('lastLoginAtom', [], createMyJsonStorage()); diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts index 28b56dab..b483e75c 100644 --- a/src/utils/bindings.ts +++ b/src/utils/bindings.ts @@ -16,11 +16,50 @@ export function createAccount(data: CreateAccountData) { return invoke('create_account', { data }); } +export function getFollows(data: GetFollowData) { + return invoke('get_follows', { data }); +} + export function createFollow(data: CreateFollowData) { return invoke('create_follow', { data }); } -export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; -export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; +export function createNote(data: CreateNoteData) { + return invoke('create_note', { data }); +} + +export function getNotes() { + return invoke('get_notes'); +} + +export function checkNote() { + return invoke('check_note'); +} + +export type GetFollowData = { account_id: number }; +export type Note = { + id: number; + eventId: string; + pubkey: string; + kind: number; + tags: string; + content: string; + parent_id: string; + parent_comment_id: string; + createdAt: string; + accountId: number; +}; export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; +export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; +export type CreateNoteData = { + event_id: string; + pubkey: string; + kind: number; + tags: string; + content: string; + parent_id: string; + parent_comment_id: string; + account_id: number; +}; export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; +export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; From fc8dc8fd0dc053b99e5022b23e91294d0480c9e0 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Wed, 5 Apr 2023 09:20:33 +0700 Subject: [PATCH 09/21] completed migrate to prisma-rust-client --- .../migration.sql | 4 +- .../migration.sql | 11 +++ src-tauri/prisma/schema.prisma | 14 +-- src-tauri/src/main.rs | 63 +++++++++--- .../multiAccounts/activeAccount.tsx | 24 ++++- src/components/multiAccounts/index.tsx | 40 ++++---- src/components/note/base.tsx | 10 +- src/components/note/comment.tsx | 6 +- src/components/note/connector.tsx | 98 +++++++++++-------- src/components/note/extend.tsx | 6 +- src/components/note/parent.tsx | 50 +++++++--- src/components/note/repost.tsx | 46 ++++++--- src/components/user/base.tsx | 6 +- src/components/user/extend.tsx | 8 +- src/components/user/follow.tsx | 27 ++--- src/components/user/large.tsx | 7 +- src/components/user/mention.tsx | 7 +- src/components/user/mini.tsx | 7 +- src/pages/index.tsx | 4 +- src/pages/init.tsx | 42 ++++---- src/pages/newsfeed/following.tsx | 29 ++++-- src/stores/account.tsx | 2 +- src/stores/relays.tsx | 9 -- src/utils/bindings.ts | 22 +++-- src/utils/transform.tsx | 13 +++ 25 files changed, 342 insertions(+), 213 deletions(-) rename src-tauri/prisma/migrations/{20230403043730_initial => 20230404081740_initial}/migration.sql (94%) create mode 100644 src-tauri/prisma/migrations/20230405012355_add_index_to_created_at/migration.sql delete mode 100644 src/stores/relays.tsx diff --git a/src-tauri/prisma/migrations/20230403043730_initial/migration.sql b/src-tauri/prisma/migrations/20230404081740_initial/migration.sql similarity index 94% rename from src-tauri/prisma/migrations/20230403043730_initial/migration.sql rename to src-tauri/prisma/migrations/20230404081740_initial/migration.sql index e86009dc..a682a658 100644 --- a/src-tauri/prisma/migrations/20230403043730_initial/migration.sql +++ b/src-tauri/prisma/migrations/20230404081740_initial/migration.sql @@ -27,7 +27,7 @@ CREATE TABLE "Note" ( "content" TEXT NOT NULL, "parent_id" TEXT NOT NULL, "parent_comment_id" TEXT NOT NULL, - "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "createdAt" INTEGER NOT NULL, "accountId" INTEGER NOT NULL, CONSTRAINT "Note_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account" ("id") ON DELETE RESTRICT ON UPDATE CASCADE ); @@ -38,7 +38,7 @@ CREATE TABLE "Message" ( "pubkey" TEXT NOT NULL, "content" TEXT NOT NULL, "tags" TEXT NOT NULL, - "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "createdAt" INTEGER NOT NULL, "accountId" INTEGER NOT NULL, CONSTRAINT "Message_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account" ("id") ON DELETE RESTRICT ON UPDATE CASCADE ); diff --git a/src-tauri/prisma/migrations/20230405012355_add_index_to_created_at/migration.sql b/src-tauri/prisma/migrations/20230405012355_add_index_to_created_at/migration.sql new file mode 100644 index 00000000..bea82ded --- /dev/null +++ b/src-tauri/prisma/migrations/20230405012355_add_index_to_created_at/migration.sql @@ -0,0 +1,11 @@ +-- DropIndex +DROP INDEX "Message_pubkey_idx"; + +-- DropIndex +DROP INDEX "Note_eventId_idx"; + +-- CreateIndex +CREATE INDEX "Message_pubkey_createdAt_idx" ON "Message"("pubkey", "createdAt"); + +-- CreateIndex +CREATE INDEX "Note_eventId_createdAt_idx" ON "Note"("eventId", "createdAt"); diff --git a/src-tauri/prisma/schema.prisma b/src-tauri/prisma/schema.prisma index 44f8fae3..7cc44f70 100644 --- a/src-tauri/prisma/schema.prisma +++ b/src-tauri/prisma/schema.prisma @@ -36,33 +36,33 @@ model Follow { } model Note { - id Int @id @default(autoincrement()) - eventId String @unique + id Int @id @default(autoincrement()) + eventId String @unique pubkey String kind Int tags String content String parent_id String parent_comment_id String - createdAt DateTime @default(now()) + createdAt Int Account Account @relation(fields: [accountId], references: [id]) accountId Int - @@index([eventId]) + @@index([eventId, createdAt]) } model Message { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) pubkey String content String tags String - createdAt DateTime @default(now()) + createdAt Int Account Account @relation(fields: [accountId], references: [id]) accountId Int - @@index([pubkey]) + @@index([pubkey, createdAt]) } model Relay { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index c6bde5af..196aa2ff 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -7,7 +7,7 @@ #[macro_use] extern crate objc; -use prisma_client_rust::raw; +use prisma_client_rust::Direction; use tauri::{Manager, WindowEvent}; #[cfg(target_os = "macos")] use window_ext::WindowExt; @@ -54,12 +54,30 @@ struct CreateNoteData { content: String, parent_id: String, parent_comment_id: String, + created_at: i32, account_id: i32, } +#[derive(Deserialize, Type)] +struct GetNoteByIdData { + event_id: String, +} + +#[derive(Deserialize, Type)] +struct GetNoteData { + date: i32, + limit: i32, + offset: i32, +} + +#[derive(Deserialize, Type)] +struct GetLatestNoteData { + date: i32, +} + #[tauri::command] #[specta::specta] -async fn get_account(db: DbState<'_>) -> Result, ()> { +async fn get_accounts(db: DbState<'_>) -> Result, ()> { db.account() .find_many(vec![account::active::equals(false)]) .exec() @@ -120,6 +138,7 @@ async fn create_note(db: DbState<'_>, data: CreateNoteData) -> Result, data: CreateNoteData) -> Result) -> Result, ()> { - db._query_raw(raw!("SELECT * FROM Note")) +async fn get_notes(db: DbState<'_>, data: GetNoteData) -> Result, ()> { + db.note() + .find_many(vec![note::created_at::lte(data.date)]) + .order_by(note::created_at::order(Direction::Desc)) + .take(data.limit.into()) + .skip(data.offset.into()) .exec() .await .map_err(|_| ()) @@ -141,15 +164,30 @@ async fn get_notes(db: DbState<'_>) -> Result, ()> { #[tauri::command] #[specta::specta] -async fn check_note(db: DbState<'_>) -> Result, ()> { +async fn get_latest_notes(db: DbState<'_>, data: GetLatestNoteData) -> Result, ()> { db.note() - .find_many(vec![]) - .take(5) + .find_many(vec![note::created_at::gt(data.date)]) + .order_by(note::created_at::order(Direction::Desc)) .exec() .await .map_err(|_| ()) } +#[tauri::command] +#[specta::specta] +async fn get_note_by_id(db: DbState<'_>, data: GetNoteByIdData) -> Result, ()> { + db.note() + .find_unique(note::event_id::equals(data.event_id)) + .exec() + .await + .map_err(|_| ()) +} + +#[tauri::command] +async fn count_total_notes(db: DbState<'_>) -> Result { + db.note().count(vec![]).exec().await.map_err(|_| ()) +} + #[tokio::main] async fn main() { let db = PrismaClient::_builder().build().await.unwrap(); @@ -157,13 +195,14 @@ async fn main() { #[cfg(debug_assertions)] ts::export( collect_types![ - get_account, + get_accounts, create_account, get_follows, create_follow, create_note, get_notes, - check_note + get_latest_notes, + get_note_by_id ], "../src/utils/bindings.ts", ) @@ -196,13 +235,15 @@ async fn main() { } }) .invoke_handler(tauri::generate_handler![ - get_account, + get_accounts, create_account, get_follows, create_follow, create_note, get_notes, - check_note + get_latest_notes, + get_note_by_id, + count_total_notes ]) .manage(Arc::new(db)) .run(tauri::generate_context!()) diff --git a/src/components/multiAccounts/activeAccount.tsx b/src/components/multiAccounts/activeAccount.tsx index fb244fde..9aa088df 100644 --- a/src/components/multiAccounts/activeAccount.tsx +++ b/src/components/multiAccounts/activeAccount.tsx @@ -2,8 +2,7 @@ import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; -import { createFollows } from '@utils/storage'; -import { tagsToArray } from '@utils/transform'; +import { fetchMetadata } from '@utils/metadata'; import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; import { AvatarIcon, ExitIcon, GearIcon } from '@radix-ui/react-icons'; @@ -11,7 +10,7 @@ import { writeText } from '@tauri-apps/api/clipboard'; import Image from 'next/image'; import { useRouter } from 'next/router'; import { nip19 } from 'nostr-tools'; -import { memo, useContext, useEffect } from 'react'; +import { memo, useCallback, useContext, useEffect } from 'react'; export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any }) { const [pool, relays]: any = useContext(RelayContext); @@ -27,6 +26,21 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } await writeText(nip19.npubEncode(user.id)); }; + const insertFollowsToStorage = useCallback( + async (tags) => { + const { createFollow } = await import('@utils/bindings'); + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + + for (const tag of tags) { + const metadata: any = await fetchMetadata(tag[1], pool, relays); + createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: activeAccount.id }).catch( + console.error + ); + } + }, + [pool, relays] + ); + useEffect(() => { const unsubscribe = pool.subscribe( [ @@ -38,7 +52,7 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } relays, (event: any) => { if (event.tags.length > 0) { - createFollows(tagsToArray(event.tags), user.id, 0); + insertFollowsToStorage(event.tags); } }, undefined, @@ -51,7 +65,7 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } return () => { unsubscribe; }; - }, [pool, relays, user.id]); + }, [insertFollowsToStorage, pool, relays, user.id]); return ( diff --git a/src/components/multiAccounts/index.tsx b/src/components/multiAccounts/index.tsx index 6e7fdc71..d23161ab 100644 --- a/src/components/multiAccounts/index.tsx +++ b/src/components/multiAccounts/index.tsx @@ -1,41 +1,37 @@ import { ActiveAccount } from '@components/multiAccounts/activeAccount'; import { InactiveAccount } from '@components/multiAccounts/inactiveAccount'; -import { activeAccountAtom } from '@stores/account'; import { APP_VERSION } from '@stores/constants'; -import { getAccounts } from '@utils/storage'; - import LumeSymbol from '@assets/icons/Lume'; import { PlusIcon } from '@radix-ui/react-icons'; -import { useAtomValue } from 'jotai'; import Link from 'next/link'; import { useCallback, useEffect, useState } from 'react'; export default function MultiAccounts() { - const activeAccount: any = useAtomValue(activeAccountAtom); const [users, setUsers] = useState([]); - const renderAccount = useCallback( - (user: { id: string }) => { - if (user.id === activeAccount.id) { - return ; - } else { - return ; - } - }, - [activeAccount.id] - ); + const renderAccount = useCallback((user: { id: string }) => { + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + + if (user.id === activeAccount.id) { + return ; + } else { + return ; + } + }, []); + + const fetchAccounts = useCallback(async () => { + const { getAccounts } = await import('@utils/bindings'); + const accounts = await getAccounts(); + // update state + setUsers(accounts); + }, []); useEffect(() => { - const fetchAccount = async () => { - const result: any = await getAccounts(); - setUsers(result); - }; - - fetchAccount().catch(console.error); - }, []); + fetchAccounts().catch(console.error); + }, [fetchAccounts]); return (
diff --git a/src/components/note/base.tsx b/src/components/note/base.tsx index f0c9e2c7..4ad3dae5 100644 --- a/src/components/note/base.tsx +++ b/src/components/note/base.tsx @@ -63,13 +63,13 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) { const getParent = useMemo(() => { if (event.parent_id) { - if (event.parent_id !== event.id && !event.content.includes('#[0]')) { + if (event.parent_id !== event.eventId && !event.content.includes('#[0]')) { return ; } } return; - }, [event.content, event.id, event.parent_id]); + }, [event.content, event.eventId, event.parent_id]); const openThread = (e) => { const selection = window.getSelection(); @@ -87,7 +87,7 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) { > <>{getParent}
- +
@@ -97,10 +97,10 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) {
e.stopPropagation()} className="mt-5 pl-[52px]">
diff --git a/src/components/note/comment.tsx b/src/components/note/comment.tsx index 9868cb03..da739b18 100644 --- a/src/components/note/comment.tsx +++ b/src/components/note/comment.tsx @@ -60,7 +60,7 @@ export const NoteComment = memo(function NoteComment({ event }: { event: any }) return (
- +
@@ -70,10 +70,10 @@ export const NoteComment = memo(function NoteComment({ event }: { event: any })
e.stopPropagation()} className="mt-5 pl-[52px]">
diff --git a/src/components/note/connector.tsx b/src/components/note/connector.tsx index 49852348..38500849 100644 --- a/src/components/note/connector.tsx +++ b/src/components/note/connector.tsx @@ -1,15 +1,14 @@ import { RelayContext } from '@components/relaysProvider'; -import { activeAccountAtom, lastLoginAtom } from '@stores/account'; +import { lastLoginAtom } from '@stores/account'; import { hasNewerNoteAtom } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; -import { createCacheNote, getAllFollowsByID } from '@utils/storage'; -import { pubkeyArray } from '@utils/transform'; +import { getParentID, pubkeyArray } from '@utils/transform'; import { TauriEvent } from '@tauri-apps/api/event'; import { appWindow, getCurrent } from '@tauri-apps/api/window'; -import { useAtomValue, useSetAtom } from 'jotai'; +import { useSetAtom } from 'jotai'; import { useCallback, useContext, useEffect, useRef, useState } from 'react'; export default function NoteConnector() { @@ -17,30 +16,45 @@ export default function NoteConnector() { const setLastLoginAtom = useSetAtom(lastLoginAtom); const setHasNewerNote = useSetAtom(hasNewerNoteAtom); - const activeAccount: any = useAtomValue(activeAccountAtom); const [isOnline] = useState(true); - const now = useRef(new Date()); - const subscribe = useCallback(() => { - getAllFollowsByID(activeAccount.id).then((follows) => { - pool.subscribe( - [ - { - kinds: [1], - authors: pubkeyArray(follows), - since: dateToUnix(now.current), - }, - ], - relays, - (event: any) => { - // insert event to local database - createCacheNote(event); - setHasNewerNote(true); - } - ); - }); - }, [activeAccount.id, pool, relays, setHasNewerNote]); + const now = useRef(new Date()); + const unsubscribe = useRef(null); + + const subscribe = useCallback(async () => { + const { createNote } = await import('@utils/bindings'); + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + const follows = JSON.parse(localStorage.getItem('activeAccountFollows')); + + unsubscribe.current = pool.subscribe( + [ + { + kinds: [1], + authors: pubkeyArray(follows), + since: dateToUnix(now.current), + }, + ], + relays, + (event) => { + const parentID = getParentID(event.tags, event.id); + // insert event to local database + createNote({ + event_id: event.id, + pubkey: event.pubkey, + kind: event.kind, + tags: JSON.stringify(event.tags), + content: event.content, + parent_id: parentID, + parent_comment_id: '', + created_at: event.created_at, + account_id: activeAccount.id, + }).catch(console.error); + // notify user reload to get newer note + setHasNewerNote(true); + } + ); + }, [pool, relays, setHasNewerNote]); useEffect(() => { subscribe(); @@ -48,23 +62,25 @@ export default function NoteConnector() { setLastLoginAtom(now.current); appWindow.close(); }); - }, [activeAccount.id, pool, relays, setHasNewerNote, subscribe]); + + return () => { + unsubscribe.current; + }; + }, [setHasNewerNote, setLastLoginAtom, subscribe]); return ( - <> -
- - - - -

{isOnline ? 'Online' : 'Offline'}

-
- +
+ + + + +

{isOnline ? 'Online' : 'Offline'}

+
); } diff --git a/src/components/note/extend.tsx b/src/components/note/extend.tsx index 1c9679cc..255343b4 100644 --- a/src/components/note/extend.tsx +++ b/src/components/note/extend.tsx @@ -60,7 +60,7 @@ export const NoteExtend = memo(function NoteExtend({ event }: { event: any }) { return (
- +
@@ -70,10 +70,10 @@ export const NoteExtend = memo(function NoteExtend({ event }: { event: any }) {
diff --git a/src/components/note/parent.tsx b/src/components/note/parent.tsx index e48e9694..8614e3f9 100644 --- a/src/components/note/parent.tsx +++ b/src/components/note/parent.tsx @@ -6,7 +6,7 @@ import { RelayContext } from '@components/relaysProvider'; import { UserExtend } from '@components/user/extend'; import { UserMention } from '@components/user/mention'; -import { createCacheNote, getNoteByID } from '@utils/storage'; +import { getParentID } from '@utils/transform'; import destr from 'destr'; import { memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; @@ -18,7 +18,10 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { const [event, setEvent] = useState(null); const unsubscribe = useRef(null); - const fetchEvent = useCallback(() => { + const fetchEvent = useCallback(async () => { + const { createNote } = await import('@utils/bindings'); + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + unsubscribe.current = pool.subscribe( [ { @@ -31,7 +34,19 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { // update state setEvent(event); // insert to database - createCacheNote(event); + const parentID = getParentID(event.tags, event.id); + // insert event to local database + createNote({ + event_id: event.id, + pubkey: event.pubkey, + kind: event.kind, + tags: JSON.stringify(event.tags), + content: event.content, + parent_id: parentID, + parent_comment_id: '', + created_at: event.created_at, + account_id: activeAccount.id, + }).catch(console.error); }, undefined, undefined, @@ -41,19 +56,26 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { ); }, [id, pool, relays]); + const checkNoteExist = useCallback(async () => { + const { getNoteById } = await import('@utils/bindings'); + getNoteById({ event_id: id }) + .then((res) => { + if (res) { + setEvent(res); + } else { + fetchEvent(); + } + }) + .catch(console.error); + }, [fetchEvent, id]); + useEffect(() => { - getNoteByID(id).then((res) => { - if (res) { - setEvent(res); - } else { - fetchEvent(); - } - }); + checkNoteExist(); return () => { unsubscribe.current; }; - }, [fetchEvent, id]); + }, [checkNoteExist]); const content = useMemo(() => { let parsedContent = event ? event.content : null; @@ -110,7 +132,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
- +
@@ -120,10 +142,10 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
e.stopPropagation()} className="mt-5 pl-[52px]">
diff --git a/src/components/note/repost.tsx b/src/components/note/repost.tsx index 99b00334..1a8590ce 100644 --- a/src/components/note/repost.tsx +++ b/src/components/note/repost.tsx @@ -2,7 +2,7 @@ import { RelayContext } from '@components/relaysProvider'; import { UserExtend } from '@components/user/extend'; import { UserMention } from '@components/user/mention'; -import { createCacheNote, getNoteByID } from '@utils/storage'; +import { getParentID } from '@utils/transform'; import destr from 'destr'; import { memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; @@ -14,7 +14,10 @@ export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) { const [event, setEvent] = useState(null); const unsubscribe = useRef(null); - const fetchEvent = useCallback(() => { + const fetchEvent = useCallback(async () => { + const { createNote } = await import('@utils/bindings'); + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + unsubscribe.current = pool.subscribe( [ { @@ -27,7 +30,19 @@ export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) { // update state setEvent(event); // insert to database - createCacheNote(event); + const parentID = getParentID(event.tags, event.id); + // insert event to local database + createNote({ + event_id: event.id, + pubkey: event.pubkey, + kind: event.kind, + tags: JSON.stringify(event.tags), + content: event.content, + parent_id: parentID, + parent_comment_id: '', + created_at: event.created_at, + account_id: activeAccount.id, + }).catch(console.error); }, undefined, undefined, @@ -37,19 +52,26 @@ export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) { ); }, [id, pool, relays]); + const checkNoteExist = useCallback(async () => { + const { getNoteById } = await import('@utils/bindings'); + getNoteById({ event_id: id }) + .then((res) => { + if (res) { + setEvent(res); + } else { + fetchEvent(); + } + }) + .catch(console.error); + }, [fetchEvent, id]); + useEffect(() => { - getNoteByID(id).then((res) => { - if (res) { - setEvent(res); - } else { - fetchEvent(); - } - }); + checkNoteExist(); return () => { unsubscribe.current; }; - }, [fetchEvent, id]); + }, [checkNoteExist]); const content = useMemo(() => { let parsedContent = event ? event.content : null; @@ -89,7 +111,7 @@ export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) { return (
- +
diff --git a/src/components/user/base.tsx b/src/components/user/base.tsx index 9f87cfbd..e6680769 100644 --- a/src/components/user/base.tsx +++ b/src/components/user/base.tsx @@ -6,17 +6,17 @@ import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useMemo, useState } from 'react'; +import { memo, useContext, useEffect, useState } from 'react'; export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) { const [pool, relays]: any = useContext(RelayContext); const [profile, setProfile] = useState(null); - const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { + const user = new Author(pool, relays, pubkey); user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [user]); + }, [pool, relays, pubkey]); return (
diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx index 7039cea1..d5026177 100644 --- a/src/components/user/extend.tsx +++ b/src/components/user/extend.tsx @@ -10,16 +10,15 @@ import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import { useRouter } from 'next/router'; import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useMemo, useState } from 'react'; +import { memo, useContext, useEffect, useState } from 'react'; dayjs.extend(relativeTime); export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: string; time: any }) { - const [pool, relays]: any = useContext(RelayContext); const router = useRouter(); + const [pool, relays]: any = useContext(RelayContext); const [profile, setProfile] = useState(null); - const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); const openUserPage = (e) => { e.stopPropagation(); @@ -27,8 +26,9 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s }; useEffect(() => { + const user = new Author(pool, relays, pubkey); user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [user]); + }, [pool, relays, pubkey]); return (
diff --git a/src/components/user/follow.tsx b/src/components/user/follow.tsx index 58b34778..d3f8505b 100644 --- a/src/components/user/follow.tsx +++ b/src/components/user/follow.tsx @@ -1,33 +1,22 @@ import { ImageWithFallback } from '@components/imageWithFallback'; +import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; -import { createCacheProfile } from '@utils/storage'; import { truncate } from '@utils/truncate'; -import { fetch } from '@tauri-apps/api/http'; -import destr from 'destr'; -import { memo, useCallback, useEffect, useState } from 'react'; +import { Author } from 'nostr-relaypool'; +import { memo, useContext, useEffect, useMemo, useState } from 'react'; export const UserFollow = memo(function UserFollow({ pubkey }: { pubkey: string }) { - const [profile, setProfile] = useState(null); + const [pool, relays]: any = useContext(RelayContext); - const fetchProfile = useCallback(async (id: string) => { - const res = await fetch(`https://rbr.bio/${id}/metadata.json`, { - method: 'GET', - timeout: 30, - }); - return res.data; - }, []); + const [profile, setProfile] = useState(null); + const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { - fetchProfile(pubkey) - .then((res: any) => { - setProfile(destr(res.content)); - createCacheProfile(res.pubkey, res.content); - }) - .catch(console.error); - }, [fetchProfile, pubkey]); + user.metaData((res) => setProfile(JSON.parse(res.content)), 0); + }, [user]); return (
diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx index 0a660dd2..45e75ec8 100644 --- a/src/components/user/large.tsx +++ b/src/components/user/large.tsx @@ -9,19 +9,18 @@ import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useMemo, useState } from 'react'; +import { memo, useContext, useEffect, useState } from 'react'; dayjs.extend(relativeTime); export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: string; time: any }) { const [pool, relays]: any = useContext(RelayContext); - const [profile, setProfile] = useState(null); - const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { + const user = new Author(pool, relays, pubkey); user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [user]); + }, [pool, relays, pubkey]); return (
diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx index 4cae27fd..e5d8da89 100644 --- a/src/components/user/mention.tsx +++ b/src/components/user/mention.tsx @@ -3,17 +3,16 @@ import { RelayContext } from '@components/relaysProvider'; import { truncate } from '@utils/truncate'; import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useMemo, useState } from 'react'; +import { memo, useContext, useEffect, useState } from 'react'; export const UserMention = memo(function UserMention({ pubkey }: { pubkey: string }) { const [pool, relays]: any = useContext(RelayContext); - const [profile, setProfile] = useState(null); - const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { + const user = new Author(pool, relays, pubkey); user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [user]); + }, [pool, relays, pubkey]); return @{profile?.name || truncate(pubkey, 16, ' .... ')}; }); diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx index 22b74547..2392ff62 100644 --- a/src/components/user/mini.tsx +++ b/src/components/user/mini.tsx @@ -6,17 +6,16 @@ import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; import { Author } from 'nostr-relaypool'; -import { useContext, useEffect, useMemo, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; export const UserMini = ({ pubkey }: { pubkey: string }) => { const [pool, relays]: any = useContext(RelayContext); - const [profile, setProfile] = useState(null); - const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); useEffect(() => { + const user = new Author(pool, relays, pubkey); user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [user]); + }, [pool, relays, pubkey]); if (profile) { return ( diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 4b0af815..cb67651c 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -14,8 +14,8 @@ export default function Page() { const setActiveAccountFollows = useSetAtom(activeAccountFollowsAtom); const fetchActiveAccount = useCallback(async () => { - const { getAccount } = await import('@utils/bindings'); - return await getAccount(); + const { getAccounts } = await import('@utils/bindings'); + return await getAccounts(); }, []); const fetchFollowsByAccount = useCallback(async (id) => { diff --git a/src/pages/init.tsx b/src/pages/init.tsx index 4ab32b69..a7b7397d 100644 --- a/src/pages/init.tsx +++ b/src/pages/init.tsx @@ -2,14 +2,12 @@ import BaseLayout from '@layouts/base'; import { RelayContext } from '@components/relaysProvider'; -import { activeAccountAtom, activeAccountFollowsAtom, lastLoginAtom } from '@stores/account'; - import { dateToUnix, hoursAgo } from '@utils/getDate'; import { getParentID, pubkeyArray } from '@utils/transform'; import LumeSymbol from '@assets/icons/Lume'; -import { useAtomValue } from 'jotai'; +import { invoke } from '@tauri-apps/api/tauri'; import { useRouter } from 'next/router'; import { JSXElementConstructor, @@ -27,23 +25,22 @@ export default function Page() { const router = useRouter(); const [pool, relays]: any = useContext(RelayContext); - const activeAccount: any = useAtomValue(activeAccountAtom); - const activeAccountFollows: any = useAtomValue(activeAccountFollowsAtom); - const lastLogin: any = useAtomValue(lastLoginAtom); - const now = useRef(new Date()); const unsubscribe = useRef(null); const [eose, setEose] = useState(false); const fetchData = useCallback( - async (since) => { + async (since: Date) => { const { createNote } = await import('@utils/bindings'); + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + const follows = JSON.parse(localStorage.getItem('activeAccountFollows')); + unsubscribe.current = pool.subscribe( [ { kinds: [1], - authors: pubkeyArray(activeAccountFollows), + authors: pubkeyArray(follows), since: dateToUnix(since), until: dateToUnix(now.current), }, @@ -59,7 +56,8 @@ export default function Page() { tags: JSON.stringify(event.tags), content: event.content, parent_id: parentID, - parent_comment_id: 'aaa', + parent_comment_id: '', + created_at: event.created_at, account_id: activeAccount.id, }).catch(console.error); }, @@ -69,22 +67,20 @@ export default function Page() { } ); }, - [activeAccount.id, activeAccountFollows, pool, relays] + [pool, relays] ); const isNoteExist = useCallback(async () => { - const { checkNote } = await import('@utils/bindings'); - checkNote() - .then((res) => { - if (res.length === 5) { - const parseDate = new Date(lastLogin); - fetchData(parseDate); - } else { - fetchData(hoursAgo(24, now.current)); - } - }) - .catch(console.error); - }, [fetchData, lastLogin]); + invoke('count_total_notes').then((res: number) => { + if (res > 0) { + const lastLogin = JSON.parse(localStorage.getItem('lastLogin')); + const parseDate = new Date(lastLogin); + fetchData(parseDate); + } else { + fetchData(hoursAgo(24, now.current)); + } + }); + }, [fetchData]); useEffect(() => { if (eose === false) { diff --git a/src/pages/newsfeed/following.tsx b/src/pages/newsfeed/following.tsx index f7fd0446..6231147d 100644 --- a/src/pages/newsfeed/following.tsx +++ b/src/pages/newsfeed/following.tsx @@ -8,7 +8,7 @@ import { Placeholder } from '@components/note/placeholder'; import { hasNewerNoteAtom } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; -import { getLatestNotes, getNotes } from '@utils/storage'; +import { filteredData } from '@utils/transform'; import { ArrowUpIcon } from '@radix-ui/react-icons'; import { useAtom } from 'jotai'; @@ -48,23 +48,36 @@ export default function Page() { ); const initialData = useCallback(async () => { - const result: any = await getNotes(dateToUnix(now.current), limit.current, offset.current); - setData((data) => [...data, ...result]); + const { getNotes } = await import('@utils/bindings'); + const result: any = await getNotes({ + date: dateToUnix(now.current), + limit: limit.current, + offset: offset.current, + }); + const filteredResult = filteredData(result); + setData((data) => [...data, ...filteredResult]); }, []); const loadMore = useCallback(async () => { + const { getNotes } = await import('@utils/bindings'); offset.current += limit.current; // next query - const result: any = await getNotes(dateToUnix(now.current), limit.current, offset.current); - setData((data) => [...data, ...result]); + const result: any = await getNotes({ + date: dateToUnix(now.current), + limit: limit.current, + offset: offset.current, + }); + const filteredResult = filteredData(result); + setData((data) => [...data, ...filteredResult]); }, []); const loadLatest = useCallback(async () => { - offset.current += limit.current; + const { getLatestNotes } = await import('@utils/bindings'); // next query - const result: any = await getLatestNotes(dateToUnix(now.current)); + const result: any = await getLatestNotes({ date: dateToUnix(now.current) }); // update data - setData((data) => [...result, ...data]); + const filteredResult = filteredData(result); + setData((data) => [...data, ...filteredResult]); // hide newer trigger setHasNewerNote(false); // scroll to top diff --git a/src/stores/account.tsx b/src/stores/account.tsx index 7c70b99e..9605714f 100644 --- a/src/stores/account.tsx +++ b/src/stores/account.tsx @@ -11,4 +11,4 @@ const createMyJsonStorage = () => { export const activeAccountAtom = atomWithStorage('activeAccount', {}, createMyJsonStorage()); export const activeAccountFollowsAtom = atomWithStorage('activeAccountFollows', [], createMyJsonStorage()); -export const lastLoginAtom = atomWithStorage('lastLoginAtom', [], createMyJsonStorage()); +export const lastLoginAtom = atomWithStorage('lastLogin', [], createMyJsonStorage()); diff --git a/src/stores/relays.tsx b/src/stores/relays.tsx deleted file mode 100644 index 8b9a06e7..00000000 --- a/src/stores/relays.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { isSSR } from '@utils/ssr'; -import { getAllRelays } from '@utils/storage'; - -import { atomWithCache } from 'jotai-cache'; - -export const relaysAtom = atomWithCache(async () => { - const response = isSSR ? [] : await getAllRelays(); - return response; -}); diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts index b483e75c..f755e763 100644 --- a/src/utils/bindings.ts +++ b/src/utils/bindings.ts @@ -8,8 +8,8 @@ declare global { const invoke = window.__TAURI_INVOKE__; -export function getAccount() { - return invoke('get_account'); +export function getAccounts() { + return invoke('get_accounts'); } export function createAccount(data: CreateAccountData) { @@ -28,15 +28,20 @@ export function createNote(data: CreateNoteData) { return invoke('create_note', { data }); } -export function getNotes() { - return invoke('get_notes'); +export function getNotes(data: GetNoteData) { + return invoke('get_notes', { data }); } -export function checkNote() { - return invoke('check_note'); +export function getLatestNotes(data: GetLatestNoteData) { + return invoke('get_latest_notes', { data }); +} + +export function getNoteById(data: GetNoteByIdData) { + return invoke('get_note_by_id', { data }); } export type GetFollowData = { account_id: number }; +export type GetNoteByIdData = { event_id: string }; export type Note = { id: number; eventId: string; @@ -46,9 +51,10 @@ export type Note = { content: string; parent_id: string; parent_comment_id: string; - createdAt: string; + createdAt: number; accountId: number; }; +export type GetNoteData = { date: number; limit: number; offset: number }; export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; export type CreateNoteData = { @@ -59,7 +65,9 @@ export type CreateNoteData = { content: string; parent_id: string; parent_comment_id: string; + created_at: number; account_id: number; }; +export type GetLatestNoteData = { date: number }; export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; diff --git a/src/utils/transform.tsx b/src/utils/transform.tsx index e9bb58e5..ca664c37 100644 --- a/src/utils/transform.tsx +++ b/src/utils/transform.tsx @@ -45,3 +45,16 @@ export const getParentID = (arr, fallback) => { return parentID; }; + +export const filteredData = (obj) => { + const filteredArr = obj.reduce((item, current) => { + const x = item.find((item) => item.parent_id === current.parent_id); + if (!x) { + return item.concat([current]); + } else { + return item; + } + }, []); + + return filteredArr; +}; From beb622f05e8ea841e806112101600abe34da4038 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Wed, 5 Apr 2023 09:48:57 +0700 Subject: [PATCH 10/21] clean up --- package.json | 2 - pnpm-lock.yaml | 24 --- src/components/form/base.tsx | 13 +- src/components/form/comment.tsx | 4 +- .../multiAccounts/activeAccount.tsx | 8 +- src/components/multiAccounts/index.tsx | 8 +- src/components/note/meta/comment.tsx | 6 +- src/components/note/meta/reaction.tsx | 2 +- src/components/note/metadata.tsx | 4 +- src/components/note/parent.tsx | 2 +- src/components/note/repost.tsx | 2 +- src/pages/newsfeed/[id].tsx | 6 +- src/utils/storage.tsx | 175 ------------------ 13 files changed, 23 insertions(+), 233 deletions(-) delete mode 100644 src/utils/storage.tsx diff --git a/package.json b/package.json index 6edca038..1c97c254 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "emoji-mart": "^5.5.2", "framer-motion": "^9.1.7", "jotai": "^2.0.3", - "jotai-cache": "^0.3.0", "next": "^13.2.4", "nostr-relaypool": "^0.5.18", "nostr-tools": "^1.8.1", @@ -37,7 +36,6 @@ "react-player": "^2.12.0", "react-string-replace": "^1.1.0", "react-virtuoso": "^4.1.1", - "tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql", "unique-names-generator": "^4.7.1", "ws": "^8.13.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2b8a461..b262bab6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,7 +32,6 @@ specifiers: framer-motion: ^9.1.7 husky: ^8.0.3 jotai: ^2.0.3 - jotai-cache: ^0.3.0 lint-staged: ^13.2.0 next: ^13.2.4 nostr-relaypool: ^0.5.18 @@ -48,7 +47,6 @@ specifiers: react-string-replace: ^1.1.0 react-virtuoso: ^4.1.1 tailwindcss: ^3.3.1 - tauri-plugin-sql-api: github:tauri-apps/tauri-plugin-sql typescript: ^4.9.5 unique-names-generator: ^4.7.1 ws: ^8.13.0 @@ -69,7 +67,6 @@ dependencies: emoji-mart: 5.5.2 framer-motion: 9.1.7_biqbaboplfbrettd7655fr4n2y jotai: 2.0.3_react@18.2.0 - jotai-cache: 0.3.0_jotai@2.0.3 next: 13.2.4_biqbaboplfbrettd7655fr4n2y nostr-relaypool: 0.5.18_ws@8.13.0 nostr-tools: 1.8.1 @@ -79,7 +76,6 @@ dependencies: react-player: 2.12.0_react@18.2.0 react-string-replace: 1.1.0 react-virtuoso: 4.1.1_biqbaboplfbrettd7655fr4n2y - tauri-plugin-sql-api: github.com/tauri-apps/tauri-plugin-sql/3a8b9a6b244df7512bc5ef8692cebdedbab3ccce unique-names-generator: 4.7.1 ws: 8.13.0 @@ -3231,15 +3227,6 @@ packages: hasBin: true dev: true - /jotai-cache/0.3.0_jotai@2.0.3: - resolution: - { integrity: sha512-hV6DUD1frRpW0EN8Ss7n4KNaMZRBokQw6KPT3seA4P35QRXctMNUn4pHRlg3hzO+KBPpEZw+fyKlWAqagmuIwQ== } - peerDependencies: - jotai: '>=1.11.0' - dependencies: - jotai: 2.0.3_react@18.2.0 - dev: false - /jotai/2.0.3_react@18.2.0: resolution: { integrity: sha512-MMjhSPAL3RoeZD9WbObufRT2quThEAEknHHridf2ma8Ml7ZVQmUiHk0ssdbR3F0h3kcwhYqSGJ59OjhPge7RRg== } @@ -4995,14 +4982,3 @@ packages: { integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== } engines: { node: '>=10' } dev: true - - github.com/tauri-apps/tauri-plugin-sql/3a8b9a6b244df7512bc5ef8692cebdedbab3ccce: - resolution: - { - tarball: https://codeload.github.com/tauri-apps/tauri-plugin-sql/tar.gz/3a8b9a6b244df7512bc5ef8692cebdedbab3ccce, - } - name: tauri-plugin-sql-api - version: 0.0.0 - dependencies: - '@tauri-apps/api': 1.2.0 - dev: false diff --git a/src/components/form/base.tsx b/src/components/form/base.tsx index 1a940502..c34e270e 100644 --- a/src/components/form/base.tsx +++ b/src/components/form/base.tsx @@ -2,12 +2,11 @@ import EmojiPicker from '@components/form/emojiPicker'; import ImagePicker from '@components/form/imagePicker'; import { RelayContext } from '@components/relaysProvider'; -import { activeAccountAtom } from '@stores/account'; import { noteContentAtom } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; -import { useAtom, useAtomValue } from 'jotai'; +import { useAtom } from 'jotai'; import { useResetAtom } from 'jotai/utils'; import { getEventHash, signEvent } from 'nostr-tools'; import { useContext } from 'react'; @@ -15,23 +14,21 @@ import { useContext } from 'react'; export default function FormBase() { const [pool, relays]: any = useContext(RelayContext); - const activeAccount: any = useAtomValue(activeAccountAtom); const [value, setValue] = useAtom(noteContentAtom); const resetValue = useResetAtom(noteContentAtom); - const pubkey = activeAccount.id; - const privkey = activeAccount.privkey; - const submitEvent = () => { + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + const event: any = { content: value, created_at: dateToUnix(), kind: 1, - pubkey: pubkey, + pubkey: activeAccount.pubkey, tags: [], }; event.id = getEventHash(event); - event.sig = signEvent(event, privkey); + event.sig = signEvent(event, activeAccount.privkey); // publish note pool.publish(event, relays); diff --git a/src/components/form/comment.tsx b/src/components/form/comment.tsx index f8212896..08f13212 100644 --- a/src/components/form/comment.tsx +++ b/src/components/form/comment.tsx @@ -23,7 +23,7 @@ export default function FormComment({ eventID }: { eventID: any }) { content: value, created_at: dateToUnix(), kind: 1, - pubkey: activeAccount.id, + pubkey: activeAccount.pubkey, tags: [['e', eventID]], }; event.id = getEventHash(event); @@ -42,7 +42,7 @@ export default function FormComment({ eventID }: { eventID: any }) {
diff --git a/src/components/multiAccounts/activeAccount.tsx b/src/components/multiAccounts/activeAccount.tsx index 9aa088df..effd9c2b 100644 --- a/src/components/multiAccounts/activeAccount.tsx +++ b/src/components/multiAccounts/activeAccount.tsx @@ -19,11 +19,11 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } const userData = JSON.parse(user.metadata); const openProfilePage = () => { - router.push(`/users/${user.id}`); + router.push(`/users/${user.pubkey}`); }; const copyPublicKey = async () => { - await writeText(nip19.npubEncode(user.id)); + await writeText(nip19.npubEncode(user.pubkey)); }; const insertFollowsToStorage = useCallback( @@ -46,7 +46,7 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } [ { kinds: [3], - authors: [user.id], + authors: [user.pubkey], }, ], relays, @@ -65,7 +65,7 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } return () => { unsubscribe; }; - }, [insertFollowsToStorage, pool, relays, user.id]); + }, [insertFollowsToStorage, pool, relays, user.pubkey]); return ( diff --git a/src/components/multiAccounts/index.tsx b/src/components/multiAccounts/index.tsx index d23161ab..931127c5 100644 --- a/src/components/multiAccounts/index.tsx +++ b/src/components/multiAccounts/index.tsx @@ -12,13 +12,13 @@ import { useCallback, useEffect, useState } from 'react'; export default function MultiAccounts() { const [users, setUsers] = useState([]); - const renderAccount = useCallback((user: { id: string }) => { + const renderAccount = useCallback((user: { pubkey: string }) => { const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); - if (user.id === activeAccount.id) { - return ; + if (user.pubkey === activeAccount.pubkey) { + return ; } else { - return ; + return ; } }, []); diff --git a/src/components/note/meta/comment.tsx b/src/components/note/meta/comment.tsx index 7ea74e15..9c9a6d60 100644 --- a/src/components/note/meta/comment.tsx +++ b/src/components/note/meta/comment.tsx @@ -3,7 +3,6 @@ import { RelayContext } from '@components/relaysProvider'; import { UserExtend } from '@components/user/extend'; import { activeAccountAtom } from '@stores/account'; -import { relaysAtom } from '@stores/relays'; import { dateToUnix } from '@utils/getDate'; @@ -33,11 +32,10 @@ export const NoteComment = memo(function NoteComment({ const router = useRouter(); const [pool, relays]: any = useContext(RelayContext); - const activeAccount: any = useAtomValue(activeAccountAtom); - const [open, setOpen] = useState(false); const [value, setValue] = useState(''); + const activeAccount: any = useAtomValue(activeAccountAtom); const profile = destr(activeAccount.metadata); const openThread = () => { @@ -49,7 +47,7 @@ export const NoteComment = memo(function NoteComment({ content: value, created_at: dateToUnix(), kind: 1, - pubkey: activeAccount.id, + pubkey: activeAccount.pubkey, tags: [['e', eventID]], }; event.id = getEventHash(event); diff --git a/src/components/note/meta/reaction.tsx b/src/components/note/meta/reaction.tsx index 018d196b..00db6551 100644 --- a/src/components/note/meta/reaction.tsx +++ b/src/components/note/meta/reaction.tsx @@ -38,7 +38,7 @@ export const NoteReaction = memo(function NoteReaction({ ['p', eventPubkey], ], created_at: dateToUnix(), - pubkey: activeAccount.id, + pubkey: activeAccount.pubkey, }; event.id = getEventHash(event); event.sig = signEvent(event, activeAccount.privkey); diff --git a/src/components/note/metadata.tsx b/src/components/note/metadata.tsx index 0f7c0be4..15cbc5a5 100644 --- a/src/components/note/metadata.tsx +++ b/src/components/note/metadata.tsx @@ -2,8 +2,6 @@ import { NoteComment } from '@components/note/meta/comment'; import { NoteReaction } from '@components/note/meta/reaction'; import { RelayContext } from '@components/relaysProvider'; -import { createCacheCommentNote } from '@utils/storage'; - import { useContext, useEffect, useState } from 'react'; export default function NoteMetadata({ @@ -39,7 +37,7 @@ export default function NoteMetadata({ // update state setComments((comments) => (comments += 1)); // save comment to database - createCacheCommentNote(event, eventID); + // createCacheCommentNote(event, eventID); break; case 7: if (event.content === '🤙' || event.content === '+') { diff --git a/src/components/note/parent.tsx b/src/components/note/parent.tsx index 8614e3f9..07399915 100644 --- a/src/components/note/parent.tsx +++ b/src/components/note/parent.tsx @@ -45,7 +45,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { parent_id: parentID, parent_comment_id: '', created_at: event.created_at, - account_id: activeAccount.id, + account_id: activeAccount.pubkey, }).catch(console.error); }, undefined, diff --git a/src/components/note/repost.tsx b/src/components/note/repost.tsx index 1a8590ce..80394934 100644 --- a/src/components/note/repost.tsx +++ b/src/components/note/repost.tsx @@ -41,7 +41,7 @@ export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) { parent_id: parentID, parent_comment_id: '', created_at: event.created_at, - account_id: activeAccount.id, + account_id: activeAccount.pubkey, }).catch(console.error); }, undefined, diff --git a/src/pages/newsfeed/[id].tsx b/src/pages/newsfeed/[id].tsx index 8fb1509d..33104674 100644 --- a/src/pages/newsfeed/[id].tsx +++ b/src/pages/newsfeed/[id].tsx @@ -6,8 +6,6 @@ import { NoteComment } from '@components/note/comment'; import { NoteExtend } from '@components/note/extend'; import { RelayContext } from '@components/relaysProvider'; -import { getAllCommentNotes, getNoteByID } from '@utils/storage'; - import { useRouter } from 'next/router'; import { JSXElementConstructor, @@ -29,12 +27,12 @@ export default function Page() { const [comments, setComments] = useState([]); useEffect(() => { - getNoteByID(id) + /*getNoteByID(id) .then((res) => { setRootEvent(res); getAllCommentNotes(id).then((res: any) => setComments(res)); }) - .catch(console.error); + .catch(console.error);*/ }, [id, pool, relays]); return ( diff --git a/src/utils/storage.tsx b/src/utils/storage.tsx deleted file mode 100644 index e9a5a812..00000000 --- a/src/utils/storage.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import { getParentID } from '@utils/transform'; - -import Database from 'tauri-plugin-sql-api'; - -let db: null | Database = null; - -// connect database (sqlite) -// path: tauri::api::path::BaseDirectory::App -export async function connect(): Promise { - if (db) { - return db; - } - db = await Database.load('sqlite:lume.db'); - return db; -} - -// get all relays -export async function getAllRelays() { - const db = await connect(); - const result: any = await db.select('SELECT relay_url FROM relays WHERE relay_status = "1";'); - return result.reduce((relays, { relay_url }) => { - relays.push(relay_url); - return relays; - }, []); -} - -// get active account -export async function getActiveAccount() { - const db = await connect(); - const result = await db.select(`SELECT * FROM accounts LIMIT 1;`); - return result[0]; -} - -// get all accounts -export async function getAccounts() { - const db = await connect(); - return await db.select(`SELECT * FROM accounts`); -} - -// get all follows by account id -export async function getAllFollowsByID(id) { - const db = await connect(); - return await db.select(`SELECT pubkey FROM follows WHERE account = "${id}";`); -} - -// create account -export async function createAccount(data) { - const db = await connect(); - return await db.execute( - 'INSERT OR IGNORE INTO accounts (id, privkey, npub, nsec, metadata) VALUES (?, ?, ?, ?, ?);', - [data.pubkey, data.privkey, data.npub, data.nsec, data.metadata] - ); -} - -// create follow -export async function createFollow(pubkey, account, kind) { - const db = await connect(); - return await db.execute('INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES (?, ?, ?);', [ - pubkey, - account, - kind || 0, - ]); -} - -// create follow -export async function createFollows(data, account, kind) { - const db = await connect(); - data.forEach(async (item) => { - await db.execute('INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES (?, ?, ?);', [ - item, - account, - kind || 0, - ]); - }); - return 'ok'; -} - -// create cache profile -export async function createCacheProfile(id, metadata) { - const db = await connect(); - return await db.execute('INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES (?, ?);', [id, metadata]); -} - -// get cache profile -export async function getCacheProfile(id) { - const db = await connect(); - const result = await db.select(`SELECT metadata FROM cache_profiles WHERE id = "${id}"`); - return result[0]; -} - -// get all notes -export async function getNotes(time, limit, offset) { - const db = await connect(); - return await db.select( - `SELECT * FROM cache_notes WHERE created_at <= "${time}" GROUP BY parent_id ORDER BY created_at DESC LIMIT "${limit}" OFFSET "${offset}"` - ); -} - -// get all latest notes -export async function getLatestNotes(time) { - const db = await connect(); - return await db.select( - `SELECT * FROM cache_notes WHERE created_at > "${time}" GROUP BY parent_id ORDER BY created_at DESC` - ); -} - -// get note by id -export async function getNoteByID(id) { - const db = await connect(); - const result = await db.select(`SELECT * FROM cache_notes WHERE id = "${id}"`); - return result[0]; -} - -// create cache note -export async function createCacheNote(data) { - const db = await connect(); - return await db.execute( - 'INSERT OR IGNORE INTO cache_notes (id, pubkey, created_at, kind, content, tags, parent_id) VALUES (?, ?, ?, ?, ?, ?, ?);', - [ - data.id, - data.pubkey, - data.created_at, - data.kind, - data.content, - JSON.stringify(data.tags), - getParentID(data.tags, data.id), - ] - ); -} - -// get all comment notes -export async function getAllCommentNotes(eid) { - const db = await connect(); - return await db.select( - `SELECT * FROM cache_notes WHERE parent_comment_id = "${eid}" ORDER BY created_at DESC LIMIT 500` - ); -} - -// create cache comment note -export async function createCacheCommentNote(data, eid) { - const db = await connect(); - return await db.execute( - 'INSERT OR IGNORE INTO cache_notes (id, pubkey, created_at, kind, content, tags, parent_id, parent_comment_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?);', - [ - data.id, - data.pubkey, - data.created_at, - data.kind, - data.content, - JSON.stringify(data.tags), - getParentID(data.tags, data.id), - eid, - ] - ); -} - -// create cache comment note -export async function countTotalNotes() { - const db = await connect(); - const result = await db.select('SELECT COUNT(*) AS "total" FROM cache_notes;'); - return result[0]; -} - -// get last login time -export async function getLastLoginTime() { - const db = await connect(); - const result = await db.select('SELECT setting_value FROM settings WHERE setting_key = "last_login"'); - return result[0]; -} - -// update last login time -export async function updateLastLoginTime(time) { - const db = await connect(); - return await db.execute(`UPDATE settings SET setting_value = "${time}" WHERE setting_key = "last_login"`); -} From 0d94313b45d08ab6a9bf889048ba4406e804b9b7 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Wed, 5 Apr 2023 10:00:16 +0700 Subject: [PATCH 11/21] updated dependencies --- package.json | 14 +-- pnpm-lock.yaml | 262 ++++++++++++++++++++++++------------------------- 2 files changed, 138 insertions(+), 138 deletions(-) diff --git a/package.json b/package.json index 1c97c254..1278e87c 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-popover": "^1.0.5", "@radix-ui/react-tabs": "^1.0.3", - "@supabase/supabase-js": "^2.13.0", + "@supabase/supabase-js": "^2.14.0", "@tauri-apps/api": "^1.2.0", "dayjs": "^1.11.7", "destr": "^1.2.2", @@ -29,13 +29,13 @@ "jotai": "^2.0.3", "next": "^13.2.4", "nostr-relaypool": "^0.5.18", - "nostr-tools": "^1.8.1", + "nostr-tools": "^1.8.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.43.9", "react-player": "^2.12.0", "react-string-replace": "^1.1.0", - "react-virtuoso": "^4.1.1", + "react-virtuoso": "^4.2.0", "unique-names-generator": "^4.7.1", "ws": "^8.13.0" }, @@ -44,12 +44,12 @@ "@tauri-apps/cli": "^1.2.3", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/node": "^18.15.11", - "@types/react": "^18.0.31", + "@types/react": "^18.0.33", "@types/react-dom": "^18.0.11", - "@typescript-eslint/eslint-plugin": "^5.57.0", - "@typescript-eslint/parser": "^5.57.0", + "@typescript-eslint/eslint-plugin": "^5.57.1", + "@typescript-eslint/parser": "^5.57.1", "autoprefixer": "^10.4.14", - "csstype": "^3.1.1", + "csstype": "^3.1.2", "eslint": "^8.37.0", "eslint-config-next": "^13.2.4", "eslint-config-prettier": "^8.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b262bab6..fbd5daab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,18 +9,18 @@ specifiers: '@radix-ui/react-icons': ^1.3.0 '@radix-ui/react-popover': ^1.0.5 '@radix-ui/react-tabs': ^1.0.3 - '@supabase/supabase-js': ^2.13.0 + '@supabase/supabase-js': ^2.14.0 '@tailwindcss/typography': ^0.5.9 '@tauri-apps/api': ^1.2.0 '@tauri-apps/cli': ^1.2.3 '@trivago/prettier-plugin-sort-imports': ^4.1.1 '@types/node': ^18.15.11 - '@types/react': ^18.0.31 + '@types/react': ^18.0.33 '@types/react-dom': ^18.0.11 - '@typescript-eslint/eslint-plugin': ^5.57.0 - '@typescript-eslint/parser': ^5.57.0 + '@typescript-eslint/eslint-plugin': ^5.57.1 + '@typescript-eslint/parser': ^5.57.1 autoprefixer: ^10.4.14 - csstype: ^3.1.1 + csstype: ^3.1.2 dayjs: ^1.11.7 destr: ^1.2.2 emoji-mart: ^5.5.2 @@ -35,7 +35,7 @@ specifiers: lint-staged: ^13.2.0 next: ^13.2.4 nostr-relaypool: ^0.5.18 - nostr-tools: ^1.8.1 + nostr-tools: ^1.8.2 postcss: ^8.4.21 prettier: ^2.8.7 prettier-plugin-tailwindcss: ^0.2.6 @@ -45,7 +45,7 @@ specifiers: react-hook-form: ^7.43.9 react-player: ^2.12.0 react-string-replace: ^1.1.0 - react-virtuoso: ^4.1.1 + react-virtuoso: ^4.2.0 tailwindcss: ^3.3.1 typescript: ^4.9.5 unique-names-generator: ^4.7.1 @@ -55,12 +55,12 @@ dependencies: '@emoji-mart/data': 1.1.2 '@emoji-mart/react': 1.1.1_kyrnz3vmphzqyjjk2ivrm6bcsu '@radix-ui/react-collapsible': 1.0.2_biqbaboplfbrettd7655fr4n2y - '@radix-ui/react-dialog': 1.0.3_6ayuu6vm2uqggsikytom4xssc4 - '@radix-ui/react-dropdown-menu': 2.0.4_6ayuu6vm2uqggsikytom4xssc4 + '@radix-ui/react-dialog': 1.0.3_zn3vyfk3tbnwebg5ldvieekjaq + '@radix-ui/react-dropdown-menu': 2.0.4_zn3vyfk3tbnwebg5ldvieekjaq '@radix-ui/react-icons': 1.3.0_react@18.2.0 - '@radix-ui/react-popover': 1.0.5_6ayuu6vm2uqggsikytom4xssc4 + '@radix-ui/react-popover': 1.0.5_zn3vyfk3tbnwebg5ldvieekjaq '@radix-ui/react-tabs': 1.0.3_biqbaboplfbrettd7655fr4n2y - '@supabase/supabase-js': 2.13.0 + '@supabase/supabase-js': 2.14.0 '@tauri-apps/api': 1.2.0 dayjs: 1.11.7 destr: 1.2.2 @@ -69,13 +69,13 @@ dependencies: jotai: 2.0.3_react@18.2.0 next: 13.2.4_biqbaboplfbrettd7655fr4n2y nostr-relaypool: 0.5.18_ws@8.13.0 - nostr-tools: 1.8.1 + nostr-tools: 1.8.2 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 react-hook-form: 7.43.9_react@18.2.0 react-player: 2.12.0_react@18.2.0 react-string-replace: 1.1.0 - react-virtuoso: 4.1.1_biqbaboplfbrettd7655fr4n2y + react-virtuoso: 4.2.0_biqbaboplfbrettd7655fr4n2y unique-names-generator: 4.7.1 ws: 8.13.0 @@ -84,12 +84,12 @@ devDependencies: '@tauri-apps/cli': 1.2.3 '@trivago/prettier-plugin-sort-imports': 4.1.1_prettier@2.8.7 '@types/node': 18.15.11 - '@types/react': 18.0.31 + '@types/react': 18.0.33 '@types/react-dom': 18.0.11 - '@typescript-eslint/eslint-plugin': 5.57.0_x4rubgibnu7ujqspfqdeho4yiu - '@typescript-eslint/parser': 5.57.0_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/eslint-plugin': 5.57.1_iify4w3mi7rbbu6mxzspkpx4b4 + '@typescript-eslint/parser': 5.57.1_ip5up2nocltd47wbnuyybe5dxu autoprefixer: 10.4.14_postcss@8.4.21 - csstype: 3.1.1 + csstype: 3.1.2 eslint: 8.37.0 eslint-config-next: 13.2.4_ip5up2nocltd47wbnuyybe5dxu eslint-config-prettier: 8.8.0_eslint@8.37.0 @@ -105,9 +105,9 @@ devDependencies: typescript: 4.9.5 packages: - /@babel/code-frame/7.18.6: + /@babel/code-frame/7.21.4: resolution: - { integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== } + { integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== } engines: { node: '>=6.9.0' } dependencies: '@babel/highlight': 7.18.6 @@ -135,7 +135,7 @@ packages: engines: { node: '>=6.9.0' } dependencies: '@babel/template': 7.20.7 - '@babel/types': 7.21.3 + '@babel/types': 7.21.4 dev: true /@babel/helper-hoist-variables/7.18.6: @@ -143,7 +143,7 @@ packages: { integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== } engines: { node: '>=6.9.0' } dependencies: - '@babel/types': 7.21.3 + '@babel/types': 7.21.4 dev: true /@babel/helper-split-export-declaration/7.18.6: @@ -151,7 +151,7 @@ packages: { integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== } engines: { node: '>=6.9.0' } dependencies: - '@babel/types': 7.21.3 + '@babel/types': 7.21.4 dev: true /@babel/helper-string-parser/7.19.4: @@ -176,9 +176,9 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/parser/7.21.3: + /@babel/parser/7.21.4: resolution: - { integrity: sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ== } + { integrity: sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== } engines: { node: '>=6.0.0' } hasBin: true dependencies: @@ -197,9 +197,9 @@ packages: { integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== } engines: { node: '>=6.9.0' } dependencies: - '@babel/code-frame': 7.18.6 - '@babel/parser': 7.21.3 - '@babel/types': 7.21.3 + '@babel/code-frame': 7.21.4 + '@babel/parser': 7.21.4 + '@babel/types': 7.21.4 dev: true /@babel/traverse/7.17.3: @@ -207,13 +207,13 @@ packages: { integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== } engines: { node: '>=6.9.0' } dependencies: - '@babel/code-frame': 7.18.6 + '@babel/code-frame': 7.21.4 '@babel/generator': 7.17.7 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.3 + '@babel/parser': 7.21.4 '@babel/types': 7.17.0 debug: 4.3.4 globals: 11.12.0 @@ -230,9 +230,9 @@ packages: to-fast-properties: 2.0.0 dev: true - /@babel/types/7.21.3: + /@babel/types/7.21.4: resolution: - { integrity: sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg== } + { integrity: sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== } engines: { node: '>=6.9.0' } dependencies: '@babel/helper-string-parser': 7.19.4 @@ -324,7 +324,7 @@ packages: '@floating-ui/core': 0.7.3 dev: false - /@floating-ui/react-dom/0.7.2_6ayuu6vm2uqggsikytom4xssc4: + /@floating-ui/react-dom/0.7.2_zn3vyfk3tbnwebg5ldvieekjaq: resolution: { integrity: sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg== } peerDependencies: @@ -334,7 +334,7 @@ packages: '@floating-ui/dom': 0.5.4 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - use-isomorphic-layout-effect: 1.1.2_o2wclmlv6kymw75psj4clbbe6a + use-isomorphic-layout-effect: 1.1.2_pofolu2o2erjq4lhyzl3hqovzq transitivePeerDependencies: - '@types/react' dev: false @@ -668,7 +668,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-dialog/1.0.3_6ayuu6vm2uqggsikytom4xssc4: + /@radix-ui/react-dialog/1.0.3_zn3vyfk3tbnwebg5ldvieekjaq: resolution: { integrity: sha512-owNhq36kNPqC2/a+zJRioPg6HHnTn5B/sh/NjTY8r4W9g1L5VJlrzZIVcBr7R9Mg8iLjVmh6MGgMlfoVf/WO/A== } peerDependencies: @@ -691,7 +691,7 @@ packages: aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-remove-scroll: 2.5.5_o2wclmlv6kymw75psj4clbbe6a + react-remove-scroll: 2.5.5_pofolu2o2erjq4lhyzl3hqovzq transitivePeerDependencies: - '@types/react' dev: false @@ -723,7 +723,7 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: false - /@radix-ui/react-dropdown-menu/2.0.4_6ayuu6vm2uqggsikytom4xssc4: + /@radix-ui/react-dropdown-menu/2.0.4_zn3vyfk3tbnwebg5ldvieekjaq: resolution: { integrity: sha512-y6AT9+MydyXcByivdK1+QpjWoKaC7MLjkS/cH1Q3keEyMvDkiY85m8o2Bi6+Z1PPUlCsMULopxagQOSfN0wahg== } peerDependencies: @@ -735,7 +735,7 @@ packages: '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 '@radix-ui/react-context': 1.0.0_react@18.2.0 '@radix-ui/react-id': 1.0.0_react@18.2.0 - '@radix-ui/react-menu': 2.0.4_6ayuu6vm2uqggsikytom4xssc4 + '@radix-ui/react-menu': 2.0.4_zn3vyfk3tbnwebg5ldvieekjaq '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-use-controllable-state': 1.0.0_react@18.2.0 react: 18.2.0 @@ -789,7 +789,7 @@ packages: react: 18.2.0 dev: false - /@radix-ui/react-menu/2.0.4_6ayuu6vm2uqggsikytom4xssc4: + /@radix-ui/react-menu/2.0.4_zn3vyfk3tbnwebg5ldvieekjaq: resolution: { integrity: sha512-mzKR47tZ1t193trEqlQoJvzY4u9vYfVH16ryBrVrCAGZzkgyWnMQYEZdUkM7y8ak9mrkKtJiqB47TlEnubeOFQ== } peerDependencies: @@ -806,7 +806,7 @@ packages: '@radix-ui/react-focus-guards': 1.0.0_react@18.2.0 '@radix-ui/react-focus-scope': 1.0.2_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-id': 1.0.0_react@18.2.0 - '@radix-ui/react-popper': 1.1.1_6ayuu6vm2uqggsikytom4xssc4 + '@radix-ui/react-popper': 1.1.1_zn3vyfk3tbnwebg5ldvieekjaq '@radix-ui/react-portal': 1.0.2_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-presence': 1.0.0_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y @@ -816,12 +816,12 @@ packages: aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-remove-scroll: 2.5.5_o2wclmlv6kymw75psj4clbbe6a + react-remove-scroll: 2.5.5_pofolu2o2erjq4lhyzl3hqovzq transitivePeerDependencies: - '@types/react' dev: false - /@radix-ui/react-popover/1.0.5_6ayuu6vm2uqggsikytom4xssc4: + /@radix-ui/react-popover/1.0.5_zn3vyfk3tbnwebg5ldvieekjaq: resolution: { integrity: sha512-GRHZ8yD12MrN2NLobHPE8Rb5uHTxd9x372DE9PPNnBjpczAQHcZ5ne0KXG4xpf+RDdXSzdLv9ym6mYJCDTaUZg== } peerDependencies: @@ -836,7 +836,7 @@ packages: '@radix-ui/react-focus-guards': 1.0.0_react@18.2.0 '@radix-ui/react-focus-scope': 1.0.2_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-id': 1.0.0_react@18.2.0 - '@radix-ui/react-popper': 1.1.1_6ayuu6vm2uqggsikytom4xssc4 + '@radix-ui/react-popper': 1.1.1_zn3vyfk3tbnwebg5ldvieekjaq '@radix-ui/react-portal': 1.0.2_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-presence': 1.0.0_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y @@ -845,12 +845,12 @@ packages: aria-hidden: 1.2.3 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-remove-scroll: 2.5.5_o2wclmlv6kymw75psj4clbbe6a + react-remove-scroll: 2.5.5_pofolu2o2erjq4lhyzl3hqovzq transitivePeerDependencies: - '@types/react' dev: false - /@radix-ui/react-popper/1.1.1_6ayuu6vm2uqggsikytom4xssc4: + /@radix-ui/react-popper/1.1.1_zn3vyfk3tbnwebg5ldvieekjaq: resolution: { integrity: sha512-keYDcdMPNMjSC8zTsZ8wezUMiWM9Yj14wtF3s0PTIs9srnEPC9Kt2Gny1T3T81mmSeyDjZxsD9N5WCwNNb712w== } peerDependencies: @@ -858,7 +858,7 @@ packages: react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: '@babel/runtime': 7.21.0 - '@floating-ui/react-dom': 0.7.2_6ayuu6vm2uqggsikytom4xssc4 + '@floating-ui/react-dom': 0.7.2_zn3vyfk3tbnwebg5ldvieekjaq '@radix-ui/react-arrow': 1.0.2_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 '@radix-ui/react-context': 1.0.0_react@18.2.0 @@ -1073,18 +1073,18 @@ packages: - encoding dev: false - /@supabase/gotrue-js/2.16.0: + /@supabase/gotrue-js/2.20.0: resolution: - { integrity: sha512-k7curH5xxnQmUiG8AeFW7KEJST99vhFnBCidWFhuSSyLP1Ja8Ix3g4bmLUv209mhX8LmAaDMGKNQs8gG0MOKCw== } + { integrity: sha512-dbbEXrzb6OdWeYJQ8VYnJj2sMiZYw8XGj1B5rZlbcjDxkW0Za04x+wWn6g6T5/6RwNm2kReqgAR5ufYeCPuCDA== } dependencies: cross-fetch: 3.1.5 transitivePeerDependencies: - encoding dev: false - /@supabase/postgrest-js/1.4.1: + /@supabase/postgrest-js/1.5.0: resolution: - { integrity: sha512-aruqwV/aTggkM7OVv2JinCeXmRMKHJCZpkuS1nuoa0NgLw7g3NyILSyWOKYTBJ/PxE/zXtWsBhdxFzaaNz5uxg== } + { integrity: sha512-YaU1HBE43Ba+FGmnXuvK+xYeHylkDKd04PYeKDUCoE2bUHoxSDqnjHbOwmLjnusGZi3X1MrFeUH1Wwb4bHYyIg== } dependencies: cross-fetch: 3.1.5 transitivePeerDependencies: @@ -1111,13 +1111,13 @@ packages: - encoding dev: false - /@supabase/supabase-js/2.13.0: + /@supabase/supabase-js/2.14.0: resolution: - { integrity: sha512-D37k5BIwYa4/XNe9eEPz8W0L8MS5w0j16wFDd0twClJC/z+wA4tbcaeWm5Q8IsMeExPa0LrdSrQwPI5bBg6trg== } + { integrity: sha512-pdcYDaxTUqv5A8NqDnLn731rTP0Wm469H+0ag6Jb8YpWR95rmusfpGY7vrykWXvdnvCMxoG6eEwSF9vQtxVrow== } dependencies: '@supabase/functions-js': 2.1.0 - '@supabase/gotrue-js': 2.16.0 - '@supabase/postgrest-js': 1.4.1 + '@supabase/gotrue-js': 2.20.0 + '@supabase/postgrest-js': 1.5.0 '@supabase/realtime-js': 2.7.1 '@supabase/storage-js': 2.3.1 cross-fetch: 3.1.5 @@ -1270,7 +1270,7 @@ packages: optional: true dependencies: '@babel/generator': 7.17.7 - '@babel/parser': 7.21.3 + '@babel/parser': 7.21.4 '@babel/traverse': 7.17.3 '@babel/types': 7.17.0 javascript-natural-sort: 0.7.1 @@ -1307,16 +1307,16 @@ packages: resolution: { integrity: sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw== } dependencies: - '@types/react': 18.0.31 + '@types/react': 18.0.33 dev: true - /@types/react/18.0.31: + /@types/react/18.0.33: resolution: - { integrity: sha512-EEG67of7DsvRDU6BLLI0p+k1GojDLz9+lZsnCpCRTa/lOokvyPBvp8S5x+A24hME3yyQuIipcP70KJ6H7Qupww== } + { integrity: sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA== } dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 - csstype: 3.1.1 + csstype: 3.1.2 /@types/scheduler/0.16.3: resolution: @@ -1334,9 +1334,9 @@ packages: '@types/node': 18.15.11 dev: false - /@typescript-eslint/eslint-plugin/5.57.0_x4rubgibnu7ujqspfqdeho4yiu: + /@typescript-eslint/eslint-plugin/5.57.1_iify4w3mi7rbbu6mxzspkpx4b4: resolution: - { integrity: sha512-itag0qpN6q2UMM6Xgk6xoHa0D0/P+M17THnr4SVgqn9Rgam5k/He33MA7/D7QoJcdMxHFyX7U9imaBonAX/6qA== } + { integrity: sha512-1MeobQkQ9tztuleT3v72XmY0XuKXVXusAhryoLuU5YZ+mXoYKZP9SQ7Flulh1NX4DTjpGTc2b/eMu4u7M7dhnQ== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -1347,10 +1347,10 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.5.0 - '@typescript-eslint/parser': 5.57.0_ip5up2nocltd47wbnuyybe5dxu - '@typescript-eslint/scope-manager': 5.57.0 - '@typescript-eslint/type-utils': 5.57.0_ip5up2nocltd47wbnuyybe5dxu - '@typescript-eslint/utils': 5.57.0_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/parser': 5.57.1_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/scope-manager': 5.57.1 + '@typescript-eslint/type-utils': 5.57.1_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/utils': 5.57.1_ip5up2nocltd47wbnuyybe5dxu debug: 4.3.4 eslint: 8.37.0 grapheme-splitter: 1.0.4 @@ -1363,9 +1363,9 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.57.0_ip5up2nocltd47wbnuyybe5dxu: + /@typescript-eslint/parser/5.57.1_ip5up2nocltd47wbnuyybe5dxu: resolution: - { integrity: sha512-orrduvpWYkgLCyAdNtR1QIWovcNZlEm6yL8nwH/eTxWLd8gsP+25pdLHYzL2QdkqrieaDwLpytHqycncv0woUQ== } + { integrity: sha512-hlA0BLeVSA/wBPKdPGxoVr9Pp6GutGoY380FEhbVi0Ph4WNe8kLvqIRx76RSQt1lynZKfrXKs0/XeEk4zZycuA== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1374,9 +1374,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.57.0 - '@typescript-eslint/types': 5.57.0 - '@typescript-eslint/typescript-estree': 5.57.0_typescript@4.9.5 + '@typescript-eslint/scope-manager': 5.57.1 + '@typescript-eslint/types': 5.57.1 + '@typescript-eslint/typescript-estree': 5.57.1_typescript@4.9.5 debug: 4.3.4 eslint: 8.37.0 typescript: 4.9.5 @@ -1384,18 +1384,18 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager/5.57.0: + /@typescript-eslint/scope-manager/5.57.1: resolution: - { integrity: sha512-NANBNOQvllPlizl9LatX8+MHi7bx7WGIWYjPHDmQe5Si/0YEYfxSljJpoTyTWFTgRy3X8gLYSE4xQ2U+aCozSw== } + { integrity: sha512-N/RrBwEUKMIYxSKl0oDK5sFVHd6VI7p9K5MyUlVYAY6dyNb/wHUqndkTd3XhpGlXgnQsBkRZuu4f9kAHghvgPw== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } dependencies: - '@typescript-eslint/types': 5.57.0 - '@typescript-eslint/visitor-keys': 5.57.0 + '@typescript-eslint/types': 5.57.1 + '@typescript-eslint/visitor-keys': 5.57.1 dev: true - /@typescript-eslint/type-utils/5.57.0_ip5up2nocltd47wbnuyybe5dxu: + /@typescript-eslint/type-utils/5.57.1_ip5up2nocltd47wbnuyybe5dxu: resolution: - { integrity: sha512-kxXoq9zOTbvqzLbdNKy1yFrxLC6GDJFE2Yuo3KqSwTmDOFjUGeWSakgoXT864WcK5/NAJkkONCiKb1ddsqhLXQ== } + { integrity: sha512-/RIPQyx60Pt6ga86hKXesXkJ2WOS4UemFrmmq/7eOyiYjYv/MUSHPlkhU6k9T9W1ytnTJueqASW+wOmW4KrViw== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: eslint: '*' @@ -1404,8 +1404,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.57.0_typescript@4.9.5 - '@typescript-eslint/utils': 5.57.0_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/typescript-estree': 5.57.1_typescript@4.9.5 + '@typescript-eslint/utils': 5.57.1_ip5up2nocltd47wbnuyybe5dxu debug: 4.3.4 eslint: 8.37.0 tsutils: 3.21.0_typescript@4.9.5 @@ -1414,15 +1414,15 @@ packages: - supports-color dev: true - /@typescript-eslint/types/5.57.0: + /@typescript-eslint/types/5.57.1: resolution: - { integrity: sha512-mxsod+aZRSyLT+jiqHw1KK6xrANm19/+VFALVFP5qa/aiJnlP38qpyaTd0fEKhWvQk6YeNZ5LGwI1pDpBRBhtQ== } + { integrity: sha512-bSs4LOgyV3bJ08F5RDqO2KXqg3WAdwHCu06zOqcQ6vqbTJizyBhuh1o1ImC69X4bV2g1OJxbH71PJqiO7Y1RuA== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } dev: true - /@typescript-eslint/typescript-estree/5.57.0_typescript@4.9.5: + /@typescript-eslint/typescript-estree/5.57.1_typescript@4.9.5: resolution: - { integrity: sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw== } + { integrity: sha512-A2MZqD8gNT0qHKbk2wRspg7cHbCDCk2tcqt6ScCFLr5Ru8cn+TCfM786DjPhqwseiS+PrYwcXht5ztpEQ6TFTw== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: typescript: '*' @@ -1430,8 +1430,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.57.0 - '@typescript-eslint/visitor-keys': 5.57.0 + '@typescript-eslint/types': 5.57.1 + '@typescript-eslint/visitor-keys': 5.57.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -1442,9 +1442,9 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.57.0_ip5up2nocltd47wbnuyybe5dxu: + /@typescript-eslint/utils/5.57.1_ip5up2nocltd47wbnuyybe5dxu: resolution: - { integrity: sha512-ps/4WohXV7C+LTSgAL5CApxvxbMkl9B9AUZRtnEFonpIxZDIT7wC1xfvuJONMidrkB9scs4zhtRyIwHh4+18kw== } + { integrity: sha512-kN6vzzf9NkEtawECqze6v99LtmDiUJCVpvieTFA1uL7/jDghiJGubGZ5csicYHU1Xoqb3oH/R5cN5df6W41Nfg== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1452,9 +1452,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0_eslint@8.37.0 '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.57.0 - '@typescript-eslint/types': 5.57.0 - '@typescript-eslint/typescript-estree': 5.57.0_typescript@4.9.5 + '@typescript-eslint/scope-manager': 5.57.1 + '@typescript-eslint/types': 5.57.1 + '@typescript-eslint/typescript-estree': 5.57.1_typescript@4.9.5 eslint: 8.37.0 eslint-scope: 5.1.1 semver: 7.3.8 @@ -1463,12 +1463,12 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/5.57.0: + /@typescript-eslint/visitor-keys/5.57.1: resolution: - { integrity: sha512-ery2g3k0hv5BLiKpPuwYt9KBkAp2ugT6VvyShXdLOkax895EC55sP0Tx5L0fZaQueiK3fBLvHVvEl3jFS5ia+g== } + { integrity: sha512-RjQrAniDU0CEk5r7iphkm731zKlFiUjvcBS2yHAg8WWqFMCaCrD0rKEVOMUyMMcbGPZ0bPp56srkGWrgfZqLRA== } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } dependencies: - '@typescript-eslint/types': 5.57.0 + '@typescript-eslint/types': 5.57.1 eslint-visitor-keys: 3.4.0 dev: true @@ -1667,7 +1667,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.5 - caniuse-lite: 1.0.30001473 + caniuse-lite: 1.0.30001474 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -1727,8 +1727,8 @@ packages: engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true dependencies: - caniuse-lite: 1.0.30001473 - electron-to-chromium: 1.4.347 + caniuse-lite: 1.0.30001474 + electron-to-chromium: 1.4.352 node-releases: 2.0.10 update-browserslist-db: 1.0.10_browserslist@4.21.5 dev: true @@ -1761,9 +1761,9 @@ packages: engines: { node: '>= 6' } dev: true - /caniuse-lite/1.0.30001473: + /caniuse-lite/1.0.30001474: resolution: - { integrity: sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg== } + { integrity: sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q== } /chalk/2.4.2: resolution: @@ -1916,9 +1916,9 @@ packages: hasBin: true dev: true - /csstype/3.1.1: + /csstype/3.1.2: resolution: - { integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== } + { integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== } /d/1.0.1: resolution: @@ -2073,9 +2073,9 @@ packages: { integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== } dev: true - /electron-to-chromium/1.4.347: + /electron-to-chromium/1.4.352: resolution: - { integrity: sha512-LNi3+/9nV0vT6Bz1OsSoZ/w7IgNuWdefZ7mjKNjZxyRlI/ag6uMXxsxAy5Etvuixq3Q26exw2fc4bNYvYQqXSw== } + { integrity: sha512-ikFUEyu5/q+wJpMOxWxTaEVk2M1qKqTGKKyfJmod1CPZxKfYnxVS41/GCBQg21ItBpZybyN8sNpRqCUGm+Zc4Q== } dev: true /emoji-mart/5.5.2: @@ -2243,11 +2243,11 @@ packages: dependencies: '@next/eslint-plugin-next': 13.2.4 '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/parser': 5.57.0_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/parser': 5.57.1_ip5up2nocltd47wbnuyybe5dxu eslint: 8.37.0 eslint-import-resolver-node: 0.3.7 eslint-import-resolver-typescript: 3.5.4_rbts4wm34tb3x7owcp777e4f4y - eslint-plugin-import: 2.27.5_f66okp2kqrdiymeqhgaog6g5pu + eslint-plugin-import: 2.27.5_7soxczgm5ptvp6hrqgvvlsfewi eslint-plugin-jsx-a11y: 6.7.1_eslint@8.37.0 eslint-plugin-react: 7.32.2_eslint@8.37.0 eslint-plugin-react-hooks: 4.6.0_eslint@8.37.0 @@ -2289,7 +2289,7 @@ packages: debug: 4.3.4 enhanced-resolve: 5.12.0 eslint: 8.37.0 - eslint-plugin-import: 2.27.5_f66okp2kqrdiymeqhgaog6g5pu + eslint-plugin-import: 2.27.5_7soxczgm5ptvp6hrqgvvlsfewi get-tsconfig: 4.5.0 globby: 13.1.3 is-core-module: 2.11.0 @@ -2299,7 +2299,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.4_kilwkdng6ctuxxd7dfjxtekdra: + /eslint-module-utils/2.7.4_kjku44dhmtuergedsk2nvqsxum: resolution: { integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== } engines: { node: '>=4' } @@ -2321,7 +2321,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.57.0_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/parser': 5.57.1_ip5up2nocltd47wbnuyybe5dxu debug: 3.2.7 eslint: 8.37.0 eslint-import-resolver-node: 0.3.7 @@ -2330,7 +2330,7 @@ packages: - supports-color dev: true - /eslint-plugin-import/2.27.5_f66okp2kqrdiymeqhgaog6g5pu: + /eslint-plugin-import/2.27.5_7soxczgm5ptvp6hrqgvvlsfewi: resolution: { integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== } engines: { node: '>=4' } @@ -2341,7 +2341,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.57.0_ip5up2nocltd47wbnuyybe5dxu + '@typescript-eslint/parser': 5.57.1_ip5up2nocltd47wbnuyybe5dxu array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -2349,7 +2349,7 @@ packages: doctrine: 2.1.0 eslint: 8.37.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.7.4_kilwkdng6ctuxxd7dfjxtekdra + eslint-module-utils: 2.7.4_kjku44dhmtuergedsk2nvqsxum has: 1.0.3 is-core-module: 2.11.0 is-glob: 4.0.3 @@ -3544,7 +3544,7 @@ packages: dependencies: '@next/env': 13.2.4 '@swc/helpers': 0.4.14 - caniuse-lite: 1.0.30001473 + caniuse-lite: 1.0.30001474 postcss: 8.4.14 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 @@ -3610,15 +3610,15 @@ packages: dependencies: '@jest/source-map': 29.4.3 isomorphic-ws: 5.0.0_ws@8.13.0 - nostr-tools: 1.8.1 + nostr-tools: 1.8.2 safe-stable-stringify: 2.4.3 transitivePeerDependencies: - ws dev: false - /nostr-tools/1.8.1: + /nostr-tools/1.8.2: resolution: - { integrity: sha512-/2IUe5xINUYT5hYBoEz51dfRaodbRHnyF8n+ZbKWCoh0ZRX6AL88OoDNrWaWWo7tP5j5OyzSL9g/z4TP7bshEA== } + { integrity: sha512-r9erqxO96E2BqvOvR/5W0usY7GlcO9fVLKc1Q8b/LCBgISVaMWD2VFmjdSUcHSGPMWHLvB6k4Jui+FTi5KAprw== } dependencies: '@noble/hashes': 1.0.0 '@noble/secp256k1': 1.7.1 @@ -4092,7 +4092,7 @@ packages: react-fast-compare: 3.2.1 dev: false - /react-remove-scroll-bar/2.3.4_o2wclmlv6kymw75psj4clbbe6a: + /react-remove-scroll-bar/2.3.4_pofolu2o2erjq4lhyzl3hqovzq: resolution: { integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== } engines: { node: '>=10' } @@ -4103,13 +4103,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.0.31 + '@types/react': 18.0.33 react: 18.2.0 - react-style-singleton: 2.2.1_o2wclmlv6kymw75psj4clbbe6a + react-style-singleton: 2.2.1_pofolu2o2erjq4lhyzl3hqovzq tslib: 2.5.0 dev: false - /react-remove-scroll/2.5.5_o2wclmlv6kymw75psj4clbbe6a: + /react-remove-scroll/2.5.5_pofolu2o2erjq4lhyzl3hqovzq: resolution: { integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== } engines: { node: '>=10' } @@ -4120,13 +4120,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.0.31 + '@types/react': 18.0.33 react: 18.2.0 - react-remove-scroll-bar: 2.3.4_o2wclmlv6kymw75psj4clbbe6a - react-style-singleton: 2.2.1_o2wclmlv6kymw75psj4clbbe6a + react-remove-scroll-bar: 2.3.4_pofolu2o2erjq4lhyzl3hqovzq + react-style-singleton: 2.2.1_pofolu2o2erjq4lhyzl3hqovzq tslib: 2.5.0 - use-callback-ref: 1.3.0_o2wclmlv6kymw75psj4clbbe6a - use-sidecar: 1.1.2_o2wclmlv6kymw75psj4clbbe6a + use-callback-ref: 1.3.0_pofolu2o2erjq4lhyzl3hqovzq + use-sidecar: 1.1.2_pofolu2o2erjq4lhyzl3hqovzq dev: false /react-string-replace/1.1.0: @@ -4135,7 +4135,7 @@ packages: engines: { node: '>=0.12.0' } dev: false - /react-style-singleton/2.2.1_o2wclmlv6kymw75psj4clbbe6a: + /react-style-singleton/2.2.1_pofolu2o2erjq4lhyzl3hqovzq: resolution: { integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== } engines: { node: '>=10' } @@ -4146,16 +4146,16 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.0.31 + '@types/react': 18.0.33 get-nonce: 1.0.1 invariant: 2.2.4 react: 18.2.0 tslib: 2.5.0 dev: false - /react-virtuoso/4.1.1_biqbaboplfbrettd7655fr4n2y: + /react-virtuoso/4.2.0_biqbaboplfbrettd7655fr4n2y: resolution: - { integrity: sha512-G2lyifG5UIRZI9vgcBt+6OLDL6CO5/O6YiGS+O9z+VNRjVSTioSwfBC7sVSLspYq7iyL60aIXlVqSKVJiSVhlg== } + { integrity: sha512-lO1akVyALlDMp+eIo4E99HjSQ8Cn2AKXBVfq7GaBjdlnlJaRvou8az6tVYGHFD6Az5EcPUc7OfzHvAyojOhgqw== } engines: { node: '>=10' } peerDependencies: react: '>=16 || >=17 || >= 18' @@ -4777,7 +4777,7 @@ packages: punycode: 2.3.0 dev: true - /use-callback-ref/1.3.0_o2wclmlv6kymw75psj4clbbe6a: + /use-callback-ref/1.3.0_pofolu2o2erjq4lhyzl3hqovzq: resolution: { integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w== } engines: { node: '>=10' } @@ -4788,12 +4788,12 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.0.31 + '@types/react': 18.0.33 react: 18.2.0 tslib: 2.5.0 dev: false - /use-isomorphic-layout-effect/1.1.2_o2wclmlv6kymw75psj4clbbe6a: + /use-isomorphic-layout-effect/1.1.2_pofolu2o2erjq4lhyzl3hqovzq: resolution: { integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== } peerDependencies: @@ -4803,11 +4803,11 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.0.31 + '@types/react': 18.0.33 react: 18.2.0 dev: false - /use-sidecar/1.1.2_o2wclmlv6kymw75psj4clbbe6a: + /use-sidecar/1.1.2_pofolu2o2erjq4lhyzl3hqovzq: resolution: { integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== } engines: { node: '>=10' } @@ -4818,7 +4818,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.0.31 + '@types/react': 18.0.33 detect-node-es: 1.1.0 react: 18.2.0 tslib: 2.5.0 From 5da94e091f43761020f0b2556c5b93872bd50774 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Wed, 5 Apr 2023 15:24:44 +0700 Subject: [PATCH 12/21] fixed errors --- src-tauri/src/main.rs | 20 +++++++++++++++ src/components/note/parent.tsx | 2 +- src/components/note/repost.tsx | 2 +- src/components/user/extend.tsx | 43 ++++++++++++++++++++++++-------- src/components/user/follow.tsx | 27 ++++++++++++-------- src/components/user/large.tsx | 26 ++++++++++++------- src/components/user/mention.tsx | 39 +++++++++++++++++++++++------ src/components/user/mini.tsx | 22 ++++++++++------ src/pages/newsfeed/following.tsx | 2 +- src/utils/bindings.ts | 17 ++++++++----- 10 files changed, 147 insertions(+), 53 deletions(-) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 196aa2ff..cd9fdb11 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -37,6 +37,11 @@ struct GetFollowData { account_id: i32, } +#[derive(Deserialize, Type)] +struct GetFollowPubkeyData { + pubkey: String, +} + #[derive(Deserialize, Type)] struct CreateFollowData { pubkey: String, @@ -105,6 +110,19 @@ async fn get_follows(db: DbState<'_>, data: GetFollowData) -> Result, + data: GetFollowPubkeyData, +) -> Result, ()> { + db.follow() + .find_first(vec![follow::pubkey::equals(data.pubkey)]) + .exec() + .await + .map_err(|_| ()) +} + #[tauri::command] #[specta::specta] async fn create_follow(db: DbState<'_>, data: CreateFollowData) -> Result { @@ -198,6 +216,7 @@ async fn main() { get_accounts, create_account, get_follows, + get_follow_by_pubkey, create_follow, create_note, get_notes, @@ -238,6 +257,7 @@ async fn main() { get_accounts, create_account, get_follows, + get_follow_by_pubkey, create_follow, create_note, get_notes, diff --git a/src/components/note/parent.tsx b/src/components/note/parent.tsx index 07399915..8614e3f9 100644 --- a/src/components/note/parent.tsx +++ b/src/components/note/parent.tsx @@ -45,7 +45,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { parent_id: parentID, parent_comment_id: '', created_at: event.created_at, - account_id: activeAccount.pubkey, + account_id: activeAccount.id, }).catch(console.error); }, undefined, diff --git a/src/components/note/repost.tsx b/src/components/note/repost.tsx index 80394934..1a8590ce 100644 --- a/src/components/note/repost.tsx +++ b/src/components/note/repost.tsx @@ -41,7 +41,7 @@ export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) { parent_id: parentID, parent_comment_id: '', created_at: event.created_at, - account_id: activeAccount.pubkey, + account_id: activeAccount.id, }).catch(console.error); }, undefined, diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx index d5026177..b04934b5 100644 --- a/src/components/user/extend.tsx +++ b/src/components/user/extend.tsx @@ -1,23 +1,20 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; +import { fetch } from '@tauri-apps/api/http'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import { useRouter } from 'next/router'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; dayjs.extend(relativeTime); -export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: string; time: any }) { +export const UserExtend = ({ pubkey, time }: { pubkey: string; time: number }) => { const router = useRouter(); - const [pool, relays]: any = useContext(RelayContext); - const [profile, setProfile] = useState(null); const openUserPage = (e) => { @@ -25,10 +22,36 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s router.push(`/users/${pubkey}`); }; + const fetchMetadata = useCallback(async (pubkey: string) => { + const res = await fetch(`https://rbr.bio/${pubkey}/metadata.json`, { + method: 'GET', + timeout: 5, + }); + return res.data; + }, []); + + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } else { + fetchMetadata(pubkey).then((res: any) => { + if (res.content) { + const metadata = JSON.parse(res.content); + setProfile(metadata); + } + }); + } + }) + .catch(console.error); + }, [fetchMetadata, pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return (
@@ -61,4 +84,4 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s
); -}); +}; diff --git a/src/components/user/follow.tsx b/src/components/user/follow.tsx index d3f8505b..8548f1b5 100644 --- a/src/components/user/follow.tsx +++ b/src/components/user/follow.tsx @@ -1,22 +1,29 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useMemo, useState } from 'react'; - -export const UserFollow = memo(function UserFollow({ pubkey }: { pubkey: string }) { - const [pool, relays]: any = useContext(RelayContext); +import { useCallback, useEffect, useState } from 'react'; +export const UserFollow = ({ pubkey }: { pubkey: string }) => { const [profile, setProfile] = useState(null); - const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); + + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } + }) + .catch(console.error); + }, [pubkey]); useEffect(() => { - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [user]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return (
@@ -36,4 +43,4 @@ export const UserFollow = memo(function UserFollow({ pubkey }: { pubkey: string
); -}); +}; diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx index 45e75ec8..11474890 100644 --- a/src/components/user/large.tsx +++ b/src/components/user/large.tsx @@ -1,5 +1,4 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; @@ -8,19 +7,28 @@ import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; dayjs.extend(relativeTime); -export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: string; time: any }) { - const [pool, relays]: any = useContext(RelayContext); +export const UserLarge = ({ pubkey, time }: { pubkey: string; time: number }) => { const [profile, setProfile] = useState(null); + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } + }) + .catch(console.error); + }, [pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return (
@@ -51,4 +59,4 @@ export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: str
); -}); +}; diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx index e5d8da89..34fbb60b 100644 --- a/src/components/user/mention.tsx +++ b/src/components/user/mention.tsx @@ -1,18 +1,41 @@ -import { RelayContext } from '@components/relaysProvider'; - import { truncate } from '@utils/truncate'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useState } from 'react'; +import { fetch } from '@tauri-apps/api/http'; +import { memo, useCallback, useEffect, useState } from 'react'; export const UserMention = memo(function UserMention({ pubkey }: { pubkey: string }) { - const [pool, relays]: any = useContext(RelayContext); const [profile, setProfile] = useState(null); + const fetchMetadata = useCallback(async (pubkey: string) => { + const res = await fetch(`https://rbr.bio/${pubkey}/metadata.json`, { + method: 'GET', + timeout: 5, + }); + return res.data; + }, []); + + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } else { + fetchMetadata(pubkey).then((res: any) => { + if (res.content) { + const metadata = JSON.parse(res.content); + setProfile(metadata); + } + }); + } + }) + .catch(console.error); + }, [fetchMetadata, pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return @{profile?.name || truncate(pubkey, 16, ' .... ')}; }); diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx index 2392ff62..a8ee798a 100644 --- a/src/components/user/mini.tsx +++ b/src/components/user/mini.tsx @@ -1,21 +1,29 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; -import { Author } from 'nostr-relaypool'; -import { useContext, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; export const UserMini = ({ pubkey }: { pubkey: string }) => { - const [pool, relays]: any = useContext(RelayContext); const [profile, setProfile] = useState(null); + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } + }) + .catch(console.error); + }, [pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); if (profile) { return ( diff --git a/src/pages/newsfeed/following.tsx b/src/pages/newsfeed/following.tsx index 6231147d..cc36a953 100644 --- a/src/pages/newsfeed/following.tsx +++ b/src/pages/newsfeed/following.tsx @@ -42,7 +42,7 @@ export default function Page() { const computeItemKey = useCallback( (index: string | number) => { - return data[index].id; + return data[index].eventId; }, [data] ); diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts index f755e763..708147a7 100644 --- a/src/utils/bindings.ts +++ b/src/utils/bindings.ts @@ -20,6 +20,10 @@ export function getFollows(data: GetFollowData) { return invoke('get_follows', { data }); } +export function getFollowByPubkey(data: GetFollowPubkeyData) { + return invoke('get_follow_by_pubkey', { data }); +} + export function createFollow(data: CreateFollowData) { return invoke('create_follow', { data }); } @@ -41,7 +45,6 @@ export function getNoteById(data: GetNoteByIdData) { } export type GetFollowData = { account_id: number }; -export type GetNoteByIdData = { event_id: string }; export type Note = { id: number; eventId: string; @@ -54,9 +57,12 @@ export type Note = { createdAt: number; accountId: number; }; -export type GetNoteData = { date: number; limit: number; offset: number }; -export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; +export type GetLatestNoteData = { date: number }; +export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; +export type GetFollowPubkeyData = { pubkey: string }; +export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; +export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; export type CreateNoteData = { event_id: string; pubkey: string; @@ -68,6 +74,5 @@ export type CreateNoteData = { created_at: number; account_id: number; }; -export type GetLatestNoteData = { date: number }; -export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; -export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; +export type GetNoteByIdData = { event_id: string }; +export type GetNoteData = { date: number; limit: number; offset: number }; From 3c63dece4606640289bea7a07ae411f38937cdd2 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Wed, 5 Apr 2023 15:38:41 +0700 Subject: [PATCH 13/21] renamed model follow to pleb --- .../migration.sql | 30 +++++++++++++++ src-tauri/prisma/schema.prisma | 10 +++-- src-tauri/src/main.rs | 38 +++++++++---------- .../multiAccounts/activeAccount.tsx | 4 +- src/components/user/extend.tsx | 4 +- src/components/user/follow.tsx | 4 +- src/components/user/large.tsx | 4 +- src/components/user/mention.tsx | 4 +- src/components/user/mini.tsx | 4 +- src/pages/index.tsx | 4 +- src/pages/onboarding/create/step-2.tsx | 4 +- src/pages/onboarding/login/step-2.tsx | 4 +- src/utils/bindings.ts | 24 ++++++------ 13 files changed, 85 insertions(+), 53 deletions(-) create mode 100644 src-tauri/prisma/migrations/20230405082721_rename_follow_to_pleb/migration.sql diff --git a/src-tauri/prisma/migrations/20230405082721_rename_follow_to_pleb/migration.sql b/src-tauri/prisma/migrations/20230405082721_rename_follow_to_pleb/migration.sql new file mode 100644 index 00000000..84fee655 --- /dev/null +++ b/src-tauri/prisma/migrations/20230405082721_rename_follow_to_pleb/migration.sql @@ -0,0 +1,30 @@ +/* + Warnings: + + - You are about to drop the `Follow` table. If the table is not empty, all the data it contains will be lost. + - A unique constraint covering the columns `[pubkey]` on the table `Account` will be added. If there are existing duplicate values, this will fail. + +*/ +-- DropTable +PRAGMA foreign_keys=off; +DROP TABLE "Follow"; +PRAGMA foreign_keys=on; + +-- CreateTable +CREATE TABLE "Pleb" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "pubkey" TEXT NOT NULL, + "kind" INTEGER NOT NULL, + "metadata" TEXT NOT NULL, + "accountId" INTEGER NOT NULL, + CONSTRAINT "Pleb_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateIndex +CREATE UNIQUE INDEX "Pleb_pubkey_key" ON "Pleb"("pubkey"); + +-- CreateIndex +CREATE INDEX "Pleb_pubkey_idx" ON "Pleb"("pubkey"); + +-- CreateIndex +CREATE UNIQUE INDEX "Account_pubkey_key" ON "Account"("pubkey"); diff --git a/src-tauri/prisma/schema.prisma b/src-tauri/prisma/schema.prisma index 7cc44f70..234522da 100644 --- a/src-tauri/prisma/schema.prisma +++ b/src-tauri/prisma/schema.prisma @@ -12,27 +12,29 @@ generator client { model Account { id Int @id @default(autoincrement()) - pubkey String + pubkey String @unique privkey String @unique active Boolean @default(false) metadata String // related - follows Follow[] + plebs Pleb[] messages Message[] notes Note[] @@index([pubkey]) } -model Follow { +model Pleb { id Int @id @default(autoincrement()) - pubkey String + pubkey String @unique kind Int metadata String Account Account @relation(fields: [accountId], references: [id]) accountId Int + + @@index([pubkey]) } model Note { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index cd9fdb11..84332605 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -33,17 +33,17 @@ struct CreateAccountData { } #[derive(Deserialize, Type)] -struct GetFollowData { +struct GetPlebData { account_id: i32, } #[derive(Deserialize, Type)] -struct GetFollowPubkeyData { +struct GetPlebPubkeyData { pubkey: String, } #[derive(Deserialize, Type)] -struct CreateFollowData { +struct CreatePlebData { pubkey: String, kind: i32, metadata: String, @@ -102,9 +102,9 @@ async fn create_account(db: DbState<'_>, data: CreateAccountData) -> Result, data: GetFollowData) -> Result, ()> { - db.follow() - .find_many(vec![follow::account_id::equals(data.account_id)]) +async fn get_plebs(db: DbState<'_>, data: GetPlebData) -> Result, ()> { + db.pleb() + .find_many(vec![pleb::account_id::equals(data.account_id)]) .exec() .await .map_err(|_| ()) @@ -112,12 +112,12 @@ async fn get_follows(db: DbState<'_>, data: GetFollowData) -> Result, - data: GetFollowPubkeyData, -) -> Result, ()> { - db.follow() - .find_first(vec![follow::pubkey::equals(data.pubkey)]) + data: GetPlebPubkeyData, +) -> Result, ()> { + db.pleb() + .find_first(vec![pleb::pubkey::equals(data.pubkey)]) .exec() .await .map_err(|_| ()) @@ -125,8 +125,8 @@ async fn get_follow_by_pubkey( #[tauri::command] #[specta::specta] -async fn create_follow(db: DbState<'_>, data: CreateFollowData) -> Result { - db.follow() +async fn create_pleb(db: DbState<'_>, data: CreatePlebData) -> Result { + db.pleb() .create( data.pubkey, data.kind, @@ -215,9 +215,9 @@ async fn main() { collect_types![ get_accounts, create_account, - get_follows, - get_follow_by_pubkey, - create_follow, + get_plebs, + get_pleb_by_pubkey, + create_pleb, create_note, get_notes, get_latest_notes, @@ -256,9 +256,9 @@ async fn main() { .invoke_handler(tauri::generate_handler![ get_accounts, create_account, - get_follows, - get_follow_by_pubkey, - create_follow, + get_plebs, + get_pleb_by_pubkey, + create_pleb, create_note, get_notes, get_latest_notes, diff --git a/src/components/multiAccounts/activeAccount.tsx b/src/components/multiAccounts/activeAccount.tsx index effd9c2b..fa843fcc 100644 --- a/src/components/multiAccounts/activeAccount.tsx +++ b/src/components/multiAccounts/activeAccount.tsx @@ -28,12 +28,12 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } const insertFollowsToStorage = useCallback( async (tags) => { - const { createFollow } = await import('@utils/bindings'); + const { createPleb } = await import('@utils/bindings'); const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); for (const tag of tags) { const metadata: any = await fetchMetadata(tag[1], pool, relays); - createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: activeAccount.id }).catch( + createPleb({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: activeAccount.id }).catch( console.error ); } diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx index b04934b5..64a37557 100644 --- a/src/components/user/extend.tsx +++ b/src/components/user/extend.tsx @@ -31,8 +31,8 @@ export const UserExtend = ({ pubkey, time }: { pubkey: string; time: number }) = }, []); const getCachedMetadata = useCallback(async () => { - const { getFollowByPubkey } = await import('@utils/bindings'); - getFollowByPubkey({ pubkey: pubkey }) + const { getPlebByPubkey } = await import('@utils/bindings'); + getPlebByPubkey({ pubkey: pubkey }) .then((res) => { if (res) { const metadata = JSON.parse(res.metadata); diff --git a/src/components/user/follow.tsx b/src/components/user/follow.tsx index 8548f1b5..41f8db9b 100644 --- a/src/components/user/follow.tsx +++ b/src/components/user/follow.tsx @@ -10,8 +10,8 @@ export const UserFollow = ({ pubkey }: { pubkey: string }) => { const [profile, setProfile] = useState(null); const getCachedMetadata = useCallback(async () => { - const { getFollowByPubkey } = await import('@utils/bindings'); - getFollowByPubkey({ pubkey: pubkey }) + const { getPlebByPubkey } = await import('@utils/bindings'); + getPlebByPubkey({ pubkey: pubkey }) .then((res) => { if (res) { const metadata = JSON.parse(res.metadata); diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx index 11474890..58d579c4 100644 --- a/src/components/user/large.tsx +++ b/src/components/user/large.tsx @@ -15,8 +15,8 @@ export const UserLarge = ({ pubkey, time }: { pubkey: string; time: number }) => const [profile, setProfile] = useState(null); const getCachedMetadata = useCallback(async () => { - const { getFollowByPubkey } = await import('@utils/bindings'); - getFollowByPubkey({ pubkey: pubkey }) + const { getPlebByPubkey } = await import('@utils/bindings'); + getPlebByPubkey({ pubkey: pubkey }) .then((res) => { if (res) { const metadata = JSON.parse(res.metadata); diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx index 34fbb60b..72d1d8c5 100644 --- a/src/components/user/mention.tsx +++ b/src/components/user/mention.tsx @@ -15,8 +15,8 @@ export const UserMention = memo(function UserMention({ pubkey }: { pubkey: strin }, []); const getCachedMetadata = useCallback(async () => { - const { getFollowByPubkey } = await import('@utils/bindings'); - getFollowByPubkey({ pubkey: pubkey }) + const { getPlebByPubkey } = await import('@utils/bindings'); + getPlebByPubkey({ pubkey: pubkey }) .then((res) => { if (res) { const metadata = JSON.parse(res.metadata); diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx index a8ee798a..0869d483 100644 --- a/src/components/user/mini.tsx +++ b/src/components/user/mini.tsx @@ -10,8 +10,8 @@ export const UserMini = ({ pubkey }: { pubkey: string }) => { const [profile, setProfile] = useState(null); const getCachedMetadata = useCallback(async () => { - const { getFollowByPubkey } = await import('@utils/bindings'); - getFollowByPubkey({ pubkey: pubkey }) + const { getPlebByPubkey } = await import('@utils/bindings'); + getPlebByPubkey({ pubkey: pubkey }) .then((res) => { if (res) { const metadata = JSON.parse(res.metadata); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index cb67651c..47985259 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -19,8 +19,8 @@ export default function Page() { }, []); const fetchFollowsByAccount = useCallback(async (id) => { - const { getFollows } = await import('@utils/bindings'); - return await getFollows({ account_id: id }); + const { getPlebs } = await import('@utils/bindings'); + return await getPlebs({ account_id: id }); }, []); useEffect(() => { diff --git a/src/pages/onboarding/create/step-2.tsx b/src/pages/onboarding/create/step-2.tsx index 63b5e7c8..6ccb249c 100644 --- a/src/pages/onboarding/create/step-2.tsx +++ b/src/pages/onboarding/create/step-2.tsx @@ -80,12 +80,12 @@ export default function Page() { // save follows to database then broadcast const submit = useCallback(async () => { - const { createFollow } = await import('@utils/bindings'); + const { createPleb } = await import('@utils/bindings'); setLoading(true); for (const follow of follows) { const metadata: any = await fetchMetadata(follow, pool, relays); - createFollow({ pubkey: follow, kind: 0, metadata: metadata.content, account_id: parseInt(id) }).catch( + createPleb({ pubkey: follow, kind: 0, metadata: metadata.content, account_id: parseInt(id) }).catch( console.error ); } diff --git a/src/pages/onboarding/login/step-2.tsx b/src/pages/onboarding/login/step-2.tsx index c9d16c7b..a6467de0 100644 --- a/src/pages/onboarding/login/step-2.tsx +++ b/src/pages/onboarding/login/step-2.tsx @@ -46,11 +46,11 @@ export default function Page() { const insertFollowsToStorage = useCallback( async (tags) => { - const { createFollow } = await import('@utils/bindings'); + const { createPleb } = await import('@utils/bindings'); if (profile?.id !== null) { for (const tag of tags) { const metadata: any = await fetchMetadata(tag[1], pool, relays); - createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: profile.id }).catch( + createPleb({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: profile.id }).catch( console.error ); } diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts index 708147a7..6c2b38d3 100644 --- a/src/utils/bindings.ts +++ b/src/utils/bindings.ts @@ -16,16 +16,16 @@ export function createAccount(data: CreateAccountData) { return invoke('create_account', { data }); } -export function getFollows(data: GetFollowData) { - return invoke('get_follows', { data }); +export function getPlebs(data: GetPlebData) { + return invoke('get_plebs', { data }); } -export function getFollowByPubkey(data: GetFollowPubkeyData) { - return invoke('get_follow_by_pubkey', { data }); +export function getPlebByPubkey(data: GetPlebPubkeyData) { + return invoke('get_pleb_by_pubkey', { data }); } -export function createFollow(data: CreateFollowData) { - return invoke('create_follow', { data }); +export function createPleb(data: CreatePlebData) { + return invoke('create_pleb', { data }); } export function createNote(data: CreateNoteData) { @@ -44,7 +44,11 @@ export function getNoteById(data: GetNoteByIdData) { return invoke('get_note_by_id', { data }); } -export type GetFollowData = { account_id: number }; +export type CreatePlebData = { pubkey: string; kind: number; metadata: string; account_id: number }; +export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; +export type GetLatestNoteData = { date: number }; +export type Pleb = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; +export type GetPlebPubkeyData = { pubkey: string }; export type Note = { id: number; eventId: string; @@ -57,12 +61,8 @@ export type Note = { createdAt: number; accountId: number; }; -export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; -export type GetLatestNoteData = { date: number }; -export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; -export type GetFollowPubkeyData = { pubkey: string }; +export type GetPlebData = { account_id: number }; export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; -export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; export type CreateNoteData = { event_id: string; pubkey: string; From 5437ec5c92f953cb26ace6777aab190821d481fd Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:25:18 +0700 Subject: [PATCH 14/21] added useMetadata and refactor user component --- .../migration.sql | 5 ++ .../migration.sql | 23 ++++++++ src-tauri/prisma/schema.prisma | 5 +- src-tauri/src/main.rs | 23 +++++--- .../multiAccounts/activeAccount.tsx | 10 +++- src/components/note/base.tsx | 9 ++- src/components/user/base.tsx | 14 +---- src/components/user/extend.tsx | 50 ++-------------- src/components/user/follow.tsx | 21 +------ src/components/user/large.tsx | 20 +------ src/components/user/mention.tsx | 37 +----------- src/components/user/mini.tsx | 57 ++++++------------- src/pages/newsfeed/following.tsx | 11 ++-- src/pages/onboarding/create/step-2.tsx | 10 +++- src/pages/onboarding/login/step-2.tsx | 10 +++- src/utils/bindings.ts | 34 +++++------ src/utils/metadata.tsx | 33 +++++++++++ 17 files changed, 161 insertions(+), 211 deletions(-) create mode 100644 src-tauri/prisma/migrations/20230406012222_remove_unique_from_pleb/migration.sql create mode 100644 src-tauri/prisma/migrations/20230406014004_add_plebid_to_pleb/migration.sql diff --git a/src-tauri/prisma/migrations/20230406012222_remove_unique_from_pleb/migration.sql b/src-tauri/prisma/migrations/20230406012222_remove_unique_from_pleb/migration.sql new file mode 100644 index 00000000..8bac356c --- /dev/null +++ b/src-tauri/prisma/migrations/20230406012222_remove_unique_from_pleb/migration.sql @@ -0,0 +1,5 @@ +-- DropIndex +DROP INDEX "Pleb_pubkey_idx"; + +-- DropIndex +DROP INDEX "Pleb_pubkey_key"; diff --git a/src-tauri/prisma/migrations/20230406014004_add_plebid_to_pleb/migration.sql b/src-tauri/prisma/migrations/20230406014004_add_plebid_to_pleb/migration.sql new file mode 100644 index 00000000..e2ed75a4 --- /dev/null +++ b/src-tauri/prisma/migrations/20230406014004_add_plebid_to_pleb/migration.sql @@ -0,0 +1,23 @@ +/* + Warnings: + + - Added the required column `plebId` to the `Pleb` table without a default value. This is not possible if the table is not empty. + +*/ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Pleb" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "plebId" TEXT NOT NULL, + "pubkey" TEXT NOT NULL, + "kind" INTEGER NOT NULL, + "metadata" TEXT NOT NULL, + "accountId" INTEGER NOT NULL, + CONSTRAINT "Pleb_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); +INSERT INTO "new_Pleb" ("accountId", "id", "kind", "metadata", "pubkey") SELECT "accountId", "id", "kind", "metadata", "pubkey" FROM "Pleb"; +DROP TABLE "Pleb"; +ALTER TABLE "new_Pleb" RENAME TO "Pleb"; +CREATE UNIQUE INDEX "Pleb_plebId_key" ON "Pleb"("plebId"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/src-tauri/prisma/schema.prisma b/src-tauri/prisma/schema.prisma index 234522da..780eca94 100644 --- a/src-tauri/prisma/schema.prisma +++ b/src-tauri/prisma/schema.prisma @@ -27,14 +27,13 @@ model Account { model Pleb { id Int @id @default(autoincrement()) - pubkey String @unique + plebId String @unique + pubkey String kind Int metadata String Account Account @relation(fields: [accountId], references: [id]) accountId Int - - @@index([pubkey]) } model Note { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 84332605..fe5caa84 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -19,7 +19,7 @@ mod db; use db::*; use serde::Deserialize; use specta::{collect_types, Type}; -use std::sync::Arc; +use std::{sync::Arc, vec}; use tauri::State; use tauri_specta::ts; @@ -44,6 +44,7 @@ struct GetPlebPubkeyData { #[derive(Deserialize, Type)] struct CreatePlebData { + pleb_id: String, pubkey: String, kind: i32, metadata: String, @@ -126,13 +127,21 @@ async fn get_pleb_by_pubkey( #[tauri::command] #[specta::specta] async fn create_pleb(db: DbState<'_>, data: CreatePlebData) -> Result { + let pleb_id = data.pleb_id.clone(); + let metadata = data.metadata.clone(); + db.pleb() - .create( - data.pubkey, - data.kind, - data.metadata, - account::id::equals(data.account_id), - vec![], + .upsert( + pleb::pleb_id::equals(pleb_id), + pleb::create( + data.pleb_id, + data.pubkey, + data.kind, + data.metadata, + account::id::equals(data.account_id), + vec![], + ), + vec![pleb::metadata::set(metadata)], ) .exec() .await diff --git a/src/components/multiAccounts/activeAccount.tsx b/src/components/multiAccounts/activeAccount.tsx index fa843fcc..46a8926a 100644 --- a/src/components/multiAccounts/activeAccount.tsx +++ b/src/components/multiAccounts/activeAccount.tsx @@ -33,9 +33,13 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any } for (const tag of tags) { const metadata: any = await fetchMetadata(tag[1], pool, relays); - createPleb({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: activeAccount.id }).catch( - console.error - ); + createPleb({ + pleb_id: tag[1] + '-lume' + activeAccount.id.toString(), + pubkey: tag[1], + kind: 0, + metadata: metadata.content, + account_id: activeAccount.id, + }).catch(console.error); } }, [pool, relays] diff --git a/src/components/note/base.tsx b/src/components/note/base.tsx index 4ad3dae5..17e7d90f 100644 --- a/src/components/note/base.tsx +++ b/src/components/note/base.tsx @@ -71,6 +71,11 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) { return; }, [event.content, event.eventId, event.parent_id]); + const openUserPage = (e) => { + e.stopPropagation(); + router.push(`/users/${event.pubkey}`); + }; + const openThread = (e) => { const selection = window.getSelection(); if (selection.toString().length === 0) { @@ -87,7 +92,9 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) { > <>{getParent}
- +
openUserPage(e)}> + +
diff --git a/src/components/user/base.tsx b/src/components/user/base.tsx index e6680769..7551b520 100644 --- a/src/components/user/base.tsx +++ b/src/components/user/base.tsx @@ -1,22 +1,14 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; +import { useMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useState } from 'react'; +import { memo } from 'react'; export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) { - const [pool, relays]: any = useContext(RelayContext); - - const [profile, setProfile] = useState(null); - - useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + const profile = useMetadata(pubkey); return (
diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx index 64a37557..bc8bd7cd 100644 --- a/src/components/user/extend.tsx +++ b/src/components/user/extend.tsx @@ -2,63 +2,21 @@ import { ImageWithFallback } from '@components/imageWithFallback'; import { DEFAULT_AVATAR } from '@stores/constants'; +import { useMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; -import { fetch } from '@tauri-apps/api/http'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; -import { useRouter } from 'next/router'; -import { useCallback, useEffect, useState } from 'react'; dayjs.extend(relativeTime); export const UserExtend = ({ pubkey, time }: { pubkey: string; time: number }) => { - const router = useRouter(); - const [profile, setProfile] = useState(null); - - const openUserPage = (e) => { - e.stopPropagation(); - router.push(`/users/${pubkey}`); - }; - - const fetchMetadata = useCallback(async (pubkey: string) => { - const res = await fetch(`https://rbr.bio/${pubkey}/metadata.json`, { - method: 'GET', - timeout: 5, - }); - return res.data; - }, []); - - const getCachedMetadata = useCallback(async () => { - const { getPlebByPubkey } = await import('@utils/bindings'); - getPlebByPubkey({ pubkey: pubkey }) - .then((res) => { - if (res) { - const metadata = JSON.parse(res.metadata); - setProfile(metadata); - } else { - fetchMetadata(pubkey).then((res: any) => { - if (res.content) { - const metadata = JSON.parse(res.content); - setProfile(metadata); - } - }); - } - }) - .catch(console.error); - }, [fetchMetadata, pubkey]); - - useEffect(() => { - getCachedMetadata().catch(console.error); - }, [getCachedMetadata]); + const profile = useMetadata(pubkey); return (
-
openUserPage(e)} - className="relative h-11 w-11 shrink overflow-hidden rounded-md bg-zinc-900 ring-fuchsia-500 ring-offset-1 ring-offset-zinc-900 group-hover:ring-1" - > +
- openUserPage(e)} className="font-bold leading-tight group-hover:underline"> + {profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')} · diff --git a/src/components/user/follow.tsx b/src/components/user/follow.tsx index 41f8db9b..fe7b0306 100644 --- a/src/components/user/follow.tsx +++ b/src/components/user/follow.tsx @@ -2,28 +2,11 @@ import { ImageWithFallback } from '@components/imageWithFallback'; import { DEFAULT_AVATAR } from '@stores/constants'; +import { useMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; -import { useCallback, useEffect, useState } from 'react'; - export const UserFollow = ({ pubkey }: { pubkey: string }) => { - const [profile, setProfile] = useState(null); - - const getCachedMetadata = useCallback(async () => { - const { getPlebByPubkey } = await import('@utils/bindings'); - getPlebByPubkey({ pubkey: pubkey }) - .then((res) => { - if (res) { - const metadata = JSON.parse(res.metadata); - setProfile(metadata); - } - }) - .catch(console.error); - }, [pubkey]); - - useEffect(() => { - getCachedMetadata().catch(console.error); - }, [getCachedMetadata]); + const profile = useMetadata(pubkey); return (
diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx index 58d579c4..d896e379 100644 --- a/src/components/user/large.tsx +++ b/src/components/user/large.tsx @@ -2,33 +2,17 @@ import { ImageWithFallback } from '@components/imageWithFallback'; import { DEFAULT_AVATAR } from '@stores/constants'; +import { useMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; -import { useCallback, useEffect, useState } from 'react'; dayjs.extend(relativeTime); export const UserLarge = ({ pubkey, time }: { pubkey: string; time: number }) => { - const [profile, setProfile] = useState(null); - - const getCachedMetadata = useCallback(async () => { - const { getPlebByPubkey } = await import('@utils/bindings'); - getPlebByPubkey({ pubkey: pubkey }) - .then((res) => { - if (res) { - const metadata = JSON.parse(res.metadata); - setProfile(metadata); - } - }) - .catch(console.error); - }, [pubkey]); - - useEffect(() => { - getCachedMetadata().catch(console.error); - }, [getCachedMetadata]); + const profile = useMetadata(pubkey); return (
diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx index 72d1d8c5..2d210350 100644 --- a/src/components/user/mention.tsx +++ b/src/components/user/mention.tsx @@ -1,41 +1,10 @@ +import { useMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; -import { fetch } from '@tauri-apps/api/http'; -import { memo, useCallback, useEffect, useState } from 'react'; +import { memo } from 'react'; export const UserMention = memo(function UserMention({ pubkey }: { pubkey: string }) { - const [profile, setProfile] = useState(null); - - const fetchMetadata = useCallback(async (pubkey: string) => { - const res = await fetch(`https://rbr.bio/${pubkey}/metadata.json`, { - method: 'GET', - timeout: 5, - }); - return res.data; - }, []); - - const getCachedMetadata = useCallback(async () => { - const { getPlebByPubkey } = await import('@utils/bindings'); - getPlebByPubkey({ pubkey: pubkey }) - .then((res) => { - if (res) { - const metadata = JSON.parse(res.metadata); - setProfile(metadata); - } else { - fetchMetadata(pubkey).then((res: any) => { - if (res.content) { - const metadata = JSON.parse(res.content); - setProfile(metadata); - } - }); - } - }) - .catch(console.error); - }, [fetchMetadata, pubkey]); - - useEffect(() => { - getCachedMetadata().catch(console.error); - }, [getCachedMetadata]); + const profile = useMetadata(pubkey); return @{profile?.name || truncate(pubkey, 16, ' .... ')}; }); diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx index 0869d483..5f2a7505 100644 --- a/src/components/user/mini.tsx +++ b/src/components/user/mini.tsx @@ -2,48 +2,27 @@ import { ImageWithFallback } from '@components/imageWithFallback'; import { DEFAULT_AVATAR } from '@stores/constants'; +import { useMetadata } from '@utils/metadata'; import { truncate } from '@utils/truncate'; -import { useCallback, useEffect, useState } from 'react'; - export const UserMini = ({ pubkey }: { pubkey: string }) => { - const [profile, setProfile] = useState(null); + const profile = useMetadata(pubkey); - const getCachedMetadata = useCallback(async () => { - const { getPlebByPubkey } = await import('@utils/bindings'); - getPlebByPubkey({ pubkey: pubkey }) - .then((res) => { - if (res) { - const metadata = JSON.parse(res.metadata); - setProfile(metadata); - } - }) - .catch(console.error); - }, [pubkey]); - - useEffect(() => { - getCachedMetadata().catch(console.error); - }, [getCachedMetadata]); - - if (profile) { - return ( -
-
- -
-
-

- {profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')} -

-
+ return ( +
+
+
- ); - } else { - return <>; - } +
+

+ {profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')} +

+
+
+ ); }; diff --git a/src/pages/newsfeed/following.tsx b/src/pages/newsfeed/following.tsx index cc36a953..22969499 100644 --- a/src/pages/newsfeed/following.tsx +++ b/src/pages/newsfeed/following.tsx @@ -54,8 +54,7 @@ export default function Page() { limit: limit.current, offset: offset.current, }); - const filteredResult = filteredData(result); - setData((data) => [...data, ...filteredResult]); + setData((data) => [...data, ...result]); }, []); const loadMore = useCallback(async () => { @@ -67,8 +66,7 @@ export default function Page() { limit: limit.current, offset: offset.current, }); - const filteredResult = filteredData(result); - setData((data) => [...data, ...filteredResult]); + setData((data) => [...data, ...result]); }, []); const loadLatest = useCallback(async () => { @@ -76,8 +74,7 @@ export default function Page() { // next query const result: any = await getLatestNotes({ date: dateToUnix(now.current) }); // update data - const filteredResult = filteredData(result); - setData((data) => [...data, ...filteredResult]); + setData((data) => [...data, ...result]); // hide newer trigger setHasNewerNote(false); // scroll to top @@ -103,7 +100,7 @@ export default function Page() { )} ('get_note_by_id', { data }); } -export type CreatePlebData = { pubkey: string; kind: number; metadata: string; account_id: number }; -export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; -export type GetLatestNoteData = { date: number }; -export type Pleb = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; -export type GetPlebPubkeyData = { pubkey: string }; +export type CreateNoteData = { + event_id: string; + pubkey: string; + kind: number; + tags: string; + content: string; + parent_id: string; + parent_comment_id: string; + created_at: number; + account_id: number; +}; +export type CreatePlebData = { pleb_id: string; pubkey: string; kind: number; metadata: string; account_id: number }; +export type GetNoteByIdData = { event_id: string }; +export type Pleb = { id: number; plebId: string; pubkey: string; kind: number; metadata: string; accountId: number }; export type Note = { id: number; eventId: string; @@ -61,18 +70,9 @@ export type Note = { createdAt: number; accountId: number; }; +export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; +export type GetPlebPubkeyData = { pubkey: string }; export type GetPlebData = { account_id: number }; export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; -export type CreateNoteData = { - event_id: string; - pubkey: string; - kind: number; - tags: string; - content: string; - parent_id: string; - parent_comment_id: string; - created_at: number; - account_id: number; -}; -export type GetNoteByIdData = { event_id: string }; +export type GetLatestNoteData = { date: number }; export type GetNoteData = { date: number; limit: number; offset: number }; diff --git a/src/utils/metadata.tsx b/src/utils/metadata.tsx index 5598ed8a..2a599ffb 100644 --- a/src/utils/metadata.tsx +++ b/src/utils/metadata.tsx @@ -1,6 +1,39 @@ +import { RelayContext } from '@components/relaysProvider'; + import { Author } from 'nostr-relaypool'; +import { useCallback, useContext, useEffect, useState } from 'react'; export const fetchMetadata = (pubkey: string, pool: any, relays: any) => { const author = new Author(pool, relays, pubkey); return new Promise((resolve) => author.metaData(resolve, 0)); }; + +export const useMetadata = (pubkey) => { + const [pool, relays]: any = useContext(RelayContext); + const [profile, setProfile] = useState(null); + + const getCachedMetadata = useCallback(async () => { + const { getPlebByPubkey } = await import('@utils/bindings'); + getPlebByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } else { + fetchMetadata(pubkey, pool, relays).then((res: any) => { + if (res.content) { + const metadata = JSON.parse(res.content); + setProfile(metadata); + } + }); + } + }) + .catch(console.error); + }, [pool, relays, pubkey]); + + useEffect(() => { + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); + + return profile; +}; From 365ec3df8850b4ec4199f3a6dbd26d54a1076e4b Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:49:46 +0700 Subject: [PATCH 15/21] updated note connector --- src/components/note/connector.tsx | 9 ++++++--- src/pages/newsfeed/following.tsx | 3 +-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/note/connector.tsx b/src/components/note/connector.tsx index 38500849..0c0020b0 100644 --- a/src/components/note/connector.tsx +++ b/src/components/note/connector.tsx @@ -49,9 +49,12 @@ export default function NoteConnector() { parent_comment_id: '', created_at: event.created_at, account_id: activeAccount.id, - }).catch(console.error); - // notify user reload to get newer note - setHasNewerNote(true); + }) + .then(() => + // notify user reload to get newer note + setHasNewerNote(true) + ) + .catch(console.error); } ); }, [pool, relays, setHasNewerNote]); diff --git a/src/pages/newsfeed/following.tsx b/src/pages/newsfeed/following.tsx index 22969499..1bc40462 100644 --- a/src/pages/newsfeed/following.tsx +++ b/src/pages/newsfeed/following.tsx @@ -8,7 +8,6 @@ import { Placeholder } from '@components/note/placeholder'; import { hasNewerNoteAtom } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; -import { filteredData } from '@utils/transform'; import { ArrowUpIcon } from '@radix-ui/react-icons'; import { useAtom } from 'jotai'; @@ -100,7 +99,7 @@ export default function Page() { )} Date: Thu, 6 Apr 2023 16:42:28 +0700 Subject: [PATCH 16/21] added chats --- src/components/chats/chatList.tsx | 44 ++++++++++++++ src/components/chats/message.tsx | 49 +++++++++++++++ src/components/chats/messageList.tsx | 44 ++++++++++++++ src/components/chats/user.tsx | 37 ++++++++++++ src/components/form/chat.tsx | 79 +++++++++++++++++++++++++ src/components/navigation/channels.tsx | 8 +-- src/components/navigation/chats.tsx | 14 +++-- src/components/navigation/newsfeed.tsx | 12 +--- src/components/user/extend.tsx | 4 +- src/components/user/large.tsx | 2 +- src/components/user/mention.tsx | 13 ++-- src/components/user/mini.tsx | 28 --------- src/pages/chats/[pubkey].tsx | 82 ++++++++++++++++++++++++++ 13 files changed, 361 insertions(+), 55 deletions(-) create mode 100644 src/components/chats/chatList.tsx create mode 100644 src/components/chats/message.tsx create mode 100644 src/components/chats/messageList.tsx create mode 100644 src/components/chats/user.tsx create mode 100644 src/components/form/chat.tsx delete mode 100644 src/components/user/mini.tsx create mode 100644 src/pages/chats/[pubkey].tsx diff --git a/src/components/chats/chatList.tsx b/src/components/chats/chatList.tsx new file mode 100644 index 00000000..d3b9c2f2 --- /dev/null +++ b/src/components/chats/chatList.tsx @@ -0,0 +1,44 @@ +import { ImageWithFallback } from '@components/imageWithFallback'; + +import { activeAccountAtom } from '@stores/account'; +import { DEFAULT_AVATAR } from '@stores/constants'; + +import { useAtomValue } from 'jotai'; +import { useRouter } from 'next/router'; + +export default function ChatList() { + const router = useRouter(); + + const activeAccount: any = useAtomValue(activeAccountAtom); + const accountProfile = JSON.parse(activeAccount.metadata); + + const openChats = () => { + router.push({ + pathname: '/chats/[pubkey]', + query: { pubkey: activeAccount.pubkey }, + }); + }; + + return ( +
+
openChats()} + className="inline-flex items-center gap-2 rounded-md px-2.5 py-2 hover:bg-zinc-900" + > +
+ +
+
+
+ {accountProfile.display_name || accountProfile.name} (you) +
+
+
+
+ ); +} diff --git a/src/components/chats/message.tsx b/src/components/chats/message.tsx new file mode 100644 index 00000000..c17b4fb9 --- /dev/null +++ b/src/components/chats/message.tsx @@ -0,0 +1,49 @@ +import { MessageUser } from '@components/chats/user'; + +import { nip04 } from 'nostr-tools'; +import { useCallback, useEffect, useMemo, useState } from 'react'; + +export const Message = ({ + data, + activeAccountPubkey, + activeAccountPrivkey, +}: { + data: any; + activeAccountPubkey: string; + activeAccountPrivkey: string; +}) => { + const [content, setContent] = useState(''); + + const sender = useMemo(() => { + const pTag = data.tags.find(([k, v]) => k === 'p' && v && v !== '')[1]; + if (pTag === activeAccountPubkey) { + return data.pubkey; + } else { + return pTag; + } + }, [data.pubkey, data.tags, activeAccountPubkey]); + + const decryptContent = useCallback(async () => { + const result = await nip04.decrypt(activeAccountPrivkey, sender, data.content); + setContent(result); + }, [data.content, activeAccountPrivkey, sender]); + + useEffect(() => { + decryptContent().catch(console.error); + }, [decryptContent]); + + return ( +
+
+ +
+
+
+ {content} +
+
+
+
+
+ ); +}; diff --git a/src/components/chats/messageList.tsx b/src/components/chats/messageList.tsx new file mode 100644 index 00000000..6ad400ad --- /dev/null +++ b/src/components/chats/messageList.tsx @@ -0,0 +1,44 @@ +import { Message } from '@components/chats/message'; + +import { useCallback, useRef } from 'react'; +import { Virtuoso } from 'react-virtuoso'; + +export const MessageList = ({ data }: { data: any }) => { + const virtuosoRef = useRef(null); + + const itemContent: any = useCallback( + (index: string | number) => { + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + return ( + + ); + }, + [data] + ); + + const computeItemKey = useCallback( + (index: string | number) => { + return data[index].id; + }, + [data] + ); + + return ( +
+ +
+ ); +}; diff --git a/src/components/chats/user.tsx b/src/components/chats/user.tsx new file mode 100644 index 00000000..9ac89062 --- /dev/null +++ b/src/components/chats/user.tsx @@ -0,0 +1,37 @@ +import { ImageWithFallback } from '@components/imageWithFallback'; + +import { DEFAULT_AVATAR } from '@stores/constants'; + +import { useMetadata } from '@utils/metadata'; +import { truncate } from '@utils/truncate'; + +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; + +dayjs.extend(relativeTime); + +export const MessageUser = ({ pubkey, time }: { pubkey: string; time: number }) => { + const profile = useMetadata(pubkey); + + return ( +
+
+ +
+
+
+ + {profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')} + + · + {dayjs().to(dayjs.unix(time))} +
+
+
+ ); +}; diff --git a/src/components/form/chat.tsx b/src/components/form/chat.tsx new file mode 100644 index 00000000..6681b1d2 --- /dev/null +++ b/src/components/form/chat.tsx @@ -0,0 +1,79 @@ +import ImagePicker from '@components/form/imagePicker'; +import { RelayContext } from '@components/relaysProvider'; + +import { dateToUnix } from '@utils/getDate'; + +import { getEventHash, nip04, signEvent } from 'nostr-tools'; +import { useCallback, useContext, useState } from 'react'; + +export default function FormChat({ receiverPubkey }: { receiverPubkey: string }) { + const [pool, relays]: any = useContext(RelayContext); + const [value, setValue] = useState(''); + + const encryptMessage = useCallback( + async (privkey: string) => { + return await nip04.encrypt(privkey, receiverPubkey, value); + }, + [receiverPubkey, value] + ); + + const submitEvent = useCallback(() => { + const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); + encryptMessage(activeAccount.privkey) + .then((encryptedContent) => { + const event: any = { + content: encryptedContent, + created_at: dateToUnix(), + kind: 4, + pubkey: activeAccount.pubkey, + tags: [['p', receiverPubkey]], + }; + event.id = getEventHash(event); + event.sig = signEvent(event, activeAccount.privkey); + // publish note + pool.publish(event, relays); + // reset state + setValue(''); + }) + .catch(console.error); + }, [encryptMessage, receiverPubkey, pool, relays]); + + const handleEnterPress = (e) => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + submitEvent(); + } + }; + + return ( +
+
+