mirror of
https://github.com/lumehq/lume.git
synced 2025-10-05 20:33:18 +02:00
cache user's metdata in db
This commit is contained in:
@@ -47,4 +47,13 @@ CREATE TABLE
|
|||||||
key TEXT NOT NULL,
|
key TEXT NOT NULL,
|
||||||
value TEXT NOT NULL,
|
value TEXT NOT NULL,
|
||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
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
|
||||||
);
|
);
|
@@ -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"]'
|
'["wss://relayable.org","wss://relay.damus.io","wss://relay.nostr.band/all","wss://relay.nostrgraph.net","wss://nostr.mutinywallet.com"]'
|
||||||
),
|
),
|
||||||
("auto_start", "0"),
|
("auto_start", "0"),
|
||||||
("cache_time", "86400"),
|
("cache_time", "86400000"),
|
||||||
("compose_shortcut", "meta+n"),
|
("compose_shortcut", "meta+n"),
|
||||||
("add_imageblock_shortcut", "meta+i"),
|
("add_imageblock_shortcut", "meta+i"),
|
||||||
("add_feedblock_shortcut", "meta+f")
|
("add_feedblock_shortcut", "meta+f")
|
@@ -1,5 +1,4 @@
|
|||||||
import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk';
|
import { NDKFilter } from '@nostr-dev-kit/ndk';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
|
||||||
import { useContext, useEffect, useRef } from 'react';
|
import { useContext, useEffect, useRef } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
@@ -8,7 +7,6 @@ import {
|
|||||||
countTotalNotes,
|
countTotalNotes,
|
||||||
createChat,
|
createChat,
|
||||||
createNote,
|
createNote,
|
||||||
getAllPubkeys,
|
|
||||||
getLastLogin,
|
getLastLogin,
|
||||||
updateLastLogin,
|
updateLastLogin,
|
||||||
} from '@libs/storage';
|
} from '@libs/storage';
|
||||||
@@ -21,12 +19,10 @@ import { useAccount } from '@utils/hooks/useAccount';
|
|||||||
|
|
||||||
const totalNotes = await countTotalNotes();
|
const totalNotes = await countTotalNotes();
|
||||||
const lastLogin = await getLastLogin();
|
const lastLogin = await getLastLogin();
|
||||||
const users = await getAllPubkeys();
|
|
||||||
|
|
||||||
export function Root() {
|
export function Root() {
|
||||||
const ndk = useContext(RelayContext);
|
const ndk = useContext(RelayContext);
|
||||||
const now = useRef(new Date());
|
const now = useRef(new Date());
|
||||||
const queryClient = useQueryClient();
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { status, account } = useAccount();
|
const { status, account } = useAccount();
|
||||||
@@ -49,8 +45,8 @@ export function Root() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const events = await prefetchEvents(ndk, filter);
|
const events = await prefetchEvents(ndk, filter);
|
||||||
events.forEach((event) => {
|
for (const event of events) {
|
||||||
createNote(
|
await createNote(
|
||||||
event.id,
|
event.id,
|
||||||
event.pubkey,
|
event.pubkey,
|
||||||
event.kind,
|
event.kind,
|
||||||
@@ -58,7 +54,7 @@ export function Root() {
|
|||||||
event.content,
|
event.content,
|
||||||
event.created_at
|
event.created_at
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} 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() {
|
async function fetchChats() {
|
||||||
try {
|
try {
|
||||||
const sendFilter: NDKFilter = {
|
const sendFilter: NDKFilter = {
|
||||||
@@ -108,11 +77,11 @@ export function Root() {
|
|||||||
|
|
||||||
const sendMessages = await prefetchEvents(ndk, sendFilter);
|
const sendMessages = await prefetchEvents(ndk, sendFilter);
|
||||||
const receiveMessages = await prefetchEvents(ndk, receiveFilter);
|
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;
|
const receiverPubkey = event.tags.find((t) => t[0] === 'p')[1] || account.pubkey;
|
||||||
createChat(
|
await createChat(
|
||||||
event.id,
|
event.id,
|
||||||
receiverPubkey,
|
receiverPubkey,
|
||||||
event.pubkey,
|
event.pubkey,
|
||||||
@@ -120,7 +89,7 @@ export function Root() {
|
|||||||
event.tags,
|
event.tags,
|
||||||
event.created_at
|
event.created_at
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -172,8 +141,7 @@ export function Root() {
|
|||||||
async function prefetch() {
|
async function prefetch() {
|
||||||
const notes = await fetchNotes();
|
const notes = await fetchNotes();
|
||||||
const chats = await fetchChats();
|
const chats = await fetchChats();
|
||||||
const users = await fetchUsersProfile();
|
if (notes && chats) {
|
||||||
if (notes && users && chats) {
|
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
await updateLastLogin(now);
|
await updateLastLogin(now);
|
||||||
navigate('/app/space', { replace: true });
|
navigate('/app/space', { replace: true });
|
||||||
|
@@ -17,7 +17,9 @@ export function CacheTimeSetting() {
|
|||||||
return (
|
return (
|
||||||
<div className="inline-flex items-center justify-between px-5 py-4">
|
<div className="inline-flex items-center justify-between px-5 py-4">
|
||||||
<div className="flex flex-col gap-1">
|
<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">
|
<span className="text-sm leading-none text-zinc-400">
|
||||||
The length of time before inactive data gets removed from the cache
|
The length of time before inactive data gets removed from the cache
|
||||||
</span>
|
</span>
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { NDKUserProfile } from '@nostr-dev-kit/ndk';
|
||||||
import Database from 'tauri-plugin-sql-api';
|
import Database from 'tauri-plugin-sql-api';
|
||||||
|
|
||||||
import { getParentID } from '@utils/transform';
|
import { getParentID } from '@utils/transform';
|
||||||
@@ -426,3 +427,24 @@ export async function removeAll() {
|
|||||||
await db.execute('DELETE FROM accounts;');
|
await db.execute('DELETE FROM accounts;');
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
|
||||||
|
import { createMetadata, getUserMetadata } from '@libs/storage';
|
||||||
|
|
||||||
import { RelayContext } from '@shared/relayProvider';
|
import { RelayContext } from '@shared/relayProvider';
|
||||||
|
|
||||||
export function useProfile(pubkey: string, fallback?: string) {
|
export function useProfile(pubkey: string, fallback?: string) {
|
||||||
@@ -13,14 +15,21 @@ export function useProfile(pubkey: string, fallback?: string) {
|
|||||||
} = useQuery(
|
} = useQuery(
|
||||||
['user', pubkey],
|
['user', pubkey],
|
||||||
async () => {
|
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);
|
const profile = JSON.parse(fallback);
|
||||||
return profile;
|
return profile;
|
||||||
} else {
|
|
||||||
const user = ndk.getUser({ hexpubkey: pubkey });
|
|
||||||
await user.fetchProfile();
|
|
||||||
|
|
||||||
return user.profile;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user