prefetch user metadata and other fixes
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import { NDKFilter } from '@nostr-dev-kit/ndk';
|
||||
import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { useContext, useEffect, useRef } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { prefetchEvents } from '@libs/ndk';
|
||||
import {
|
||||
countTotalNotes,
|
||||
createChannelMessage,
|
||||
createChat,
|
||||
createNote,
|
||||
getChannels,
|
||||
getAllPubkeys,
|
||||
getLastLogin,
|
||||
updateLastLogin,
|
||||
} from '@libs/storage';
|
||||
@@ -21,10 +21,12 @@ 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();
|
||||
@@ -99,6 +101,34 @@ 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);
|
||||
console.log('authors', events);
|
||||
|
||||
events.forEach((event: NDKEvent) => {
|
||||
const profile = JSON.parse(event.content);
|
||||
profile['image'] = profile.picture;
|
||||
queryClient.setQueryData(['user', event.pubkey], profile);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
async function fetchChannelMessages() {
|
||||
try {
|
||||
@@ -144,8 +174,9 @@ export function Root() {
|
||||
const notes = await fetchNotes();
|
||||
if (notes) {
|
||||
const chats = await fetchChats();
|
||||
const users = await fetchUsersProfile();
|
||||
// const channels = await fetchChannelMessages();
|
||||
if (chats) {
|
||||
if (chats && users) {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
await updateLastLogin(now);
|
||||
navigate('/app/space', { replace: true });
|
||||
|
||||
@@ -184,6 +184,15 @@ export async function createReplyNote(
|
||||
);
|
||||
}
|
||||
|
||||
// get all pubkeys in db
|
||||
export async function getAllPubkeys() {
|
||||
const db = await connect();
|
||||
const notes: any = await db.select('SELECT DISTINCT pubkey FROM notes');
|
||||
const replies: any = await db.select('SELECT DISTINCT pubkey FROM replies');
|
||||
const chats: any = await db.select('SELECT DISTINCT sender_pubkey FROM chats');
|
||||
return [...notes, ...replies, ...chats];
|
||||
}
|
||||
|
||||
// get all channels
|
||||
export async function getChannels() {
|
||||
const db = await connect();
|
||||
|
||||
14
src/main.tsx
14
src/main.tsx
@@ -1,4 +1,7 @@
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
|
||||
import { QueryClient } from '@tanstack/react-query';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
import { getSetting } from '@libs/storage';
|
||||
@@ -17,13 +20,18 @@ const queryClient = new QueryClient({
|
||||
},
|
||||
});
|
||||
|
||||
const persister = createSyncStoragePersister({
|
||||
storage: window.localStorage,
|
||||
});
|
||||
|
||||
const container = document.getElementById('root');
|
||||
const root = createRoot(container);
|
||||
|
||||
root.render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<PersistQueryClientProvider client={queryClient} persistOptions={{ persister }}>
|
||||
<RelayProvider>
|
||||
<App />
|
||||
</RelayProvider>
|
||||
</QueryClientProvider>
|
||||
<ReactQueryDevtools initialIsOpen={false} position="top-right" />
|
||||
</PersistQueryClientProvider>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ export function ImagePreview({ urls, truncate }: { urls: string[]; truncate?: bo
|
||||
<div className="mt-3 max-w-[420px] overflow-hidden">
|
||||
<div className="flex flex-col gap-2">
|
||||
{urls.map((url) => (
|
||||
<div key={url} className="min-w-0 shrink-0 grow-0 basis-full">
|
||||
<div key={url} className="relative min-w-0 shrink-0 grow-0 basis-full">
|
||||
<Image
|
||||
src={url}
|
||||
fallback="https://void.cat/d/XTmrMkpid8DGLjv1AzdvcW"
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import destr from 'destr';
|
||||
import getUrls from 'get-urls';
|
||||
import { parseReferences } from 'nostr-tools';
|
||||
import { Event, parseReferences } from 'nostr-tools';
|
||||
import { ReactNode } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import reactStringReplace from 'react-string-replace';
|
||||
|
||||
import { MentionUser } from '@shared/notes/mentions/user';
|
||||
|
||||
function isJsonString(str: string) {
|
||||
function isJsonString(str: string[][] | string) {
|
||||
try {
|
||||
JSON.parse(str);
|
||||
if (typeof str === 'string') JSON.parse(str);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function parser(event: any) {
|
||||
export function parser(event: Event) {
|
||||
if (isJsonString(event.tags)) {
|
||||
event['tags'] = destr(event.tags);
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export function parser(event: any) {
|
||||
|
||||
const content: {
|
||||
original: string;
|
||||
parsed: ReactNode[];
|
||||
parsed: string | ReactNode[];
|
||||
notes: string[];
|
||||
images: string[];
|
||||
videos: string[];
|
||||
@@ -40,39 +40,30 @@ export function parser(event: any) {
|
||||
links: [],
|
||||
};
|
||||
|
||||
// remove unnecessary whitespaces
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
content.parsed = content.parsed.replace(/\s{2,}/g, ' ');
|
||||
|
||||
// remove unnecessary linebreak
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
content.parsed = content.parsed.replace(/(\r\n|\r|\n){2,}/g, '$1\n');
|
||||
|
||||
// parse urls
|
||||
urls?.forEach((url: string) => {
|
||||
if (url.match(/\.(jpg|jpeg|gif|png|webp|avif)$/)) {
|
||||
// image url
|
||||
content.images.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => '');
|
||||
} else if (url.match(/\.(mp4|webm|mov|ogv|avi|mp3)$/)) {
|
||||
// video
|
||||
content.videos.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => '');
|
||||
} else {
|
||||
if (content.links.length < 1) {
|
||||
// push to store
|
||||
content.links.push(url);
|
||||
// remove url from original content
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => null);
|
||||
content.parsed = reactStringReplace(content.parsed, url, () => '');
|
||||
} else {
|
||||
content.parsed = reactStringReplace(content.parsed, /#(\w+)/g, (match, i) => (
|
||||
content.parsed = reactStringReplace(content.parsed, url, (match, i) => (
|
||||
<Link
|
||||
key={match + i}
|
||||
to={match}
|
||||
target="_blank"
|
||||
className="font-normal text-fuchsia-500 no-underline hover:text-fuchsia-600"
|
||||
>
|
||||
{match}
|
||||
@@ -99,17 +90,18 @@ export function parser(event: any) {
|
||||
|
||||
// parse hashtag
|
||||
content.parsed = reactStringReplace(content.parsed, /#(\w+)/g, (match, i) => (
|
||||
<Link
|
||||
<span
|
||||
key={match + i}
|
||||
to={`/search/${match}`}
|
||||
className="font-normal text-fuchsia-500 no-underline hover:text-fuchsia-600"
|
||||
>
|
||||
#{match}
|
||||
</Link>
|
||||
</span>
|
||||
));
|
||||
|
||||
// clean array
|
||||
content.parsed = content.parsed.filter((el) => el !== '\n');
|
||||
content.parsed = content.parsed.filter(
|
||||
(el) => el !== '\n' && el !== '\n\n' && el !== '\n'
|
||||
);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user