cache user's metdata in db

This commit is contained in:
Ren Amamiya 2023-07-05 17:19:49 +07:00
parent ec9b54cb82
commit c5ba98e37a
6 changed files with 59 additions and 49 deletions

View File

@ -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
);

View File

@ -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")

View File

@ -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 });

View File

@ -17,7 +17,9 @@ export function CacheTimeSetting() {
return (
<div className="inline-flex items-center justify-between px-5 py-4">
<div className="flex flex-col gap-1">
<span className="font-medium leading-none text-zinc-200">Cache time</span>
<span className="font-medium leading-none text-zinc-200">
Cache time (milliseconds)
</span>
<span className="text-sm leading-none text-zinc-400">
The length of time before inactive data gets removed from the cache
</span>

View File

@ -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;
}
}

View File

@ -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;
}
},
{