From c5ba98e37a907d19a6cb7d7e0bfd013023ee22ee Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Wed, 5 Jul 2023 17:19:49 +0700 Subject: [PATCH] cache user's metdata in db --- .../20230418013219_initial_data.sql | 9 ++++ ...20040005_insert_last_login_to_settings.sql | 2 +- src/app/root.tsx | 50 ++++--------------- src/app/settings/components/cacheTime.tsx | 4 +- src/libs/storage.tsx | 22 ++++++++ src/utils/hooks/useProfile.tsx | 21 +++++--- 6 files changed, 59 insertions(+), 49 deletions(-) diff --git a/src-tauri/migrations/20230418013219_initial_data.sql b/src-tauri/migrations/20230418013219_initial_data.sql index c53aa131..9f24dcd7 100644 --- a/src-tauri/migrations/20230418013219_initial_data.sql +++ b/src-tauri/migrations/20230418013219_initial_data.sql @@ -47,4 +47,13 @@ CREATE TABLE key TEXT NOT NULL, value TEXT NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP + ); + +-- create metadata table +CREATE TABLE + metadata ( + id TEXT NOT NULL PRIMARY KEY, + pubkey TEXT NOT NULL, + content TEXT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); \ No newline at end of file diff --git a/src-tauri/migrations/20230420040005_insert_last_login_to_settings.sql b/src-tauri/migrations/20230420040005_insert_last_login_to_settings.sql index 8d97644e..322110a0 100644 --- a/src-tauri/migrations/20230420040005_insert_last_login_to_settings.sql +++ b/src-tauri/migrations/20230420040005_insert_last_login_to_settings.sql @@ -8,7 +8,7 @@ VALUES '["wss://relayable.org","wss://relay.damus.io","wss://relay.nostr.band/all","wss://relay.nostrgraph.net","wss://nostr.mutinywallet.com"]' ), ("auto_start", "0"), - ("cache_time", "86400"), + ("cache_time", "86400000"), ("compose_shortcut", "meta+n"), ("add_imageblock_shortcut", "meta+i"), ("add_feedblock_shortcut", "meta+f") \ No newline at end of file diff --git a/src/app/root.tsx b/src/app/root.tsx index 3d6e22af..9ea2b525 100644 --- a/src/app/root.tsx +++ b/src/app/root.tsx @@ -1,5 +1,4 @@ -import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk'; -import { useQueryClient } from '@tanstack/react-query'; +import { NDKFilter } from '@nostr-dev-kit/ndk'; import { useContext, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; @@ -8,7 +7,6 @@ import { countTotalNotes, createChat, createNote, - getAllPubkeys, getLastLogin, updateLastLogin, } from '@libs/storage'; @@ -21,12 +19,10 @@ import { useAccount } from '@utils/hooks/useAccount'; const totalNotes = await countTotalNotes(); const lastLogin = await getLastLogin(); -const users = await getAllPubkeys(); export function Root() { const ndk = useContext(RelayContext); const now = useRef(new Date()); - const queryClient = useQueryClient(); const navigate = useNavigate(); const { status, account } = useAccount(); @@ -49,8 +45,8 @@ export function Root() { }; const events = await prefetchEvents(ndk, filter); - events.forEach((event) => { - createNote( + for (const event of events) { + await createNote( event.id, event.pubkey, event.kind, @@ -58,7 +54,7 @@ export function Root() { event.content, event.created_at ); - }); + } return true; } catch (e) { @@ -66,33 +62,6 @@ export function Root() { } } - async function fetchUsersProfile() { - const authors = []; - - users.forEach((user) => { - if (user.sender_pubkey) { - authors.push(user.sender_pubkey); - } else { - authors.push(user.pubkey); - } - }); - - const filter: NDKFilter = { - authors: authors, - kinds: [0], - }; - - const events = await ndk.fetchEvents(filter); - - events.forEach((event: NDKEvent) => { - const profile = JSON.parse(event.content); - profile['image'] = profile.picture; - queryClient.setQueryData(['user', event.pubkey], profile); - }); - - return true; - } - async function fetchChats() { try { const sendFilter: NDKFilter = { @@ -108,11 +77,11 @@ export function Root() { const sendMessages = await prefetchEvents(ndk, sendFilter); const receiveMessages = await prefetchEvents(ndk, receiveFilter); - const events = [...sendMessages, ...receiveMessages]; - events.forEach((event) => { + const events = [...sendMessages, ...receiveMessages]; + for (const event of events) { const receiverPubkey = event.tags.find((t) => t[0] === 'p')[1] || account.pubkey; - createChat( + await createChat( event.id, receiverPubkey, event.pubkey, @@ -120,7 +89,7 @@ export function Root() { event.tags, event.created_at ); - }); + } return true; } catch (e) { @@ -172,8 +141,7 @@ export function Root() { async function prefetch() { const notes = await fetchNotes(); const chats = await fetchChats(); - const users = await fetchUsersProfile(); - if (notes && users && chats) { + if (notes && chats) { const now = Math.floor(Date.now() / 1000); await updateLastLogin(now); navigate('/app/space', { replace: true }); diff --git a/src/app/settings/components/cacheTime.tsx b/src/app/settings/components/cacheTime.tsx index 2c62cd52..2234787f 100644 --- a/src/app/settings/components/cacheTime.tsx +++ b/src/app/settings/components/cacheTime.tsx @@ -17,7 +17,9 @@ export function CacheTimeSetting() { return (
- Cache time + + Cache time (milliseconds) + The length of time before inactive data gets removed from the cache diff --git a/src/libs/storage.tsx b/src/libs/storage.tsx index 8262f398..cc678b0b 100644 --- a/src/libs/storage.tsx +++ b/src/libs/storage.tsx @@ -1,3 +1,4 @@ +import { NDKUserProfile } from '@nostr-dev-kit/ndk'; import Database from 'tauri-plugin-sql-api'; import { getParentID } from '@utils/transform'; @@ -426,3 +427,24 @@ export async function removeAll() { await db.execute('DELETE FROM accounts;'); return true; } + +// create metadata +export async function createMetadata(id: string, pubkey: string, content: string) { + const db = await connect(); + const now = Math.floor(Date.now() / 1000); + return await db.execute( + 'INSERT OR REPLACE INTO metadata (id, pubkey, content, created_at) VALUES (?, ?, ?, ?);', + [id, pubkey, content, now] + ); +} + +// get metadata +export async function getUserMetadata(pubkey: string) { + const db = await connect(); + const result = await db.select(`SELECT content FROM metadata WHERE id = "${pubkey}";`); + if (result[0]) { + return JSON.parse(result[0].content); + } else { + return null; + } +} diff --git a/src/utils/hooks/useProfile.tsx b/src/utils/hooks/useProfile.tsx index fac5bdf1..834e9534 100644 --- a/src/utils/hooks/useProfile.tsx +++ b/src/utils/hooks/useProfile.tsx @@ -1,6 +1,8 @@ import { useQuery } from '@tanstack/react-query'; import { useContext } from 'react'; +import { createMetadata, getUserMetadata } from '@libs/storage'; + import { RelayContext } from '@shared/relayProvider'; export function useProfile(pubkey: string, fallback?: string) { @@ -13,14 +15,21 @@ export function useProfile(pubkey: string, fallback?: string) { } = useQuery( ['user', pubkey], async () => { - if (fallback) { + if (!fallback) { + const current = Math.floor(Date.now() / 1000); + const cache = await getUserMetadata(pubkey); + if (cache && parseInt(cache.created_at) + 86400 >= current) { + console.log('use cache', cache); + return cache; + } else { + const user = ndk.getUser({ hexpubkey: pubkey }); + await user.fetchProfile(); + await createMetadata(pubkey, pubkey, JSON.stringify(user.profile)); + return user.profile; + } + } else { const profile = JSON.parse(fallback); return profile; - } else { - const user = ndk.getUser({ hexpubkey: pubkey }); - await user.fetchProfile(); - - return user.profile; } }, {