mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-18 03:03:31 +00:00
restructure note component
This commit is contained in:
parent
aa8531b32b
commit
9b84068e6d
@ -15,7 +15,7 @@
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "^0.23.1",
|
||||
"@headlessui/react": "^1.7.15",
|
||||
"@nostr-dev-kit/ndk": "^0.5.3",
|
||||
"@nostr-dev-kit/ndk": "^0.5.4",
|
||||
"@tanstack/react-virtual": "3.0.0-beta.54",
|
||||
"@tauri-apps/api": "^1.4.0",
|
||||
"@vidstack/react": "^0.4.5",
|
||||
@ -27,7 +27,7 @@
|
||||
"nostr-tools": "^1.12.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.44.3",
|
||||
"react-hook-form": "^7.45.0",
|
||||
"react-resizable-panels": "^0.0.48",
|
||||
"react-string-replace": "^1.1.1",
|
||||
"react-virtuoso": "^4.3.10",
|
||||
|
@ -8,8 +8,8 @@ dependencies:
|
||||
specifier: ^1.7.15
|
||||
version: 1.7.15(react-dom@18.2.0)(react@18.2.0)
|
||||
'@nostr-dev-kit/ndk':
|
||||
specifier: ^0.5.3
|
||||
version: 0.5.3(typescript@4.9.5)
|
||||
specifier: ^0.5.4
|
||||
version: 0.5.4(typescript@4.9.5)
|
||||
'@tanstack/react-virtual':
|
||||
specifier: 3.0.0-beta.54
|
||||
version: 3.0.0-beta.54(react@18.2.0)
|
||||
@ -44,8 +44,8 @@ dependencies:
|
||||
specifier: ^18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
react-hook-form:
|
||||
specifier: ^7.44.3
|
||||
version: 7.44.3(react@18.2.0)
|
||||
specifier: ^7.45.0
|
||||
version: 7.45.0(react@18.2.0)
|
||||
react-resizable-panels:
|
||||
specifier: ^0.0.48
|
||||
version: 0.0.48(react-dom@18.2.0)(react@18.2.0)
|
||||
@ -571,8 +571,8 @@ packages:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.15.0
|
||||
|
||||
/@nostr-dev-kit/ndk@0.5.3(typescript@4.9.5):
|
||||
resolution: {integrity: sha512-GLmuAoor4oMxxKjFeZ4viHR9XEI61m0wBm78vTUzY1Ev+bBdDzorv6heBz7TWmQirtoJ32r/zIgWdzHsHC6h3A==}
|
||||
/@nostr-dev-kit/ndk@0.5.4(typescript@4.9.5):
|
||||
resolution: {integrity: sha512-A1JXJVJjyO8q53KXHnmFG6lf/b+7LSveLpHOJvUtcnbM/mkMtYlPJknMQ3i08oDdBO1j+nG3/8xYC3Y/8+arVw==}
|
||||
dependencies:
|
||||
'@noble/hashes': 1.3.1
|
||||
'@noble/secp256k1': 2.0.0
|
||||
@ -699,8 +699,8 @@ packages:
|
||||
resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==}
|
||||
dev: false
|
||||
|
||||
/@swc/core-darwin-arm64@1.3.64:
|
||||
resolution: {integrity: sha512-gSPld6wxZBZoEvZXWmNfd+eJGlGvrEXmhMBCUwSccpuMa0KqK7F6AAZVu7kFkmlXPq2kS8owjk6/VXnVBmm5Vw==}
|
||||
/@swc/core-darwin-arm64@1.3.65:
|
||||
resolution: {integrity: sha512-fQIXZgr7CD/+1ADqrVbz/gHvSoIMmggHvPzguQjV8FggBuS9Efm1D1ZrdUSqptggKvuLLHMZf+49tENq8NWWcg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
@ -708,8 +708,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-darwin-x64@1.3.64:
|
||||
resolution: {integrity: sha512-SJd1pr+U2pz5ZVv5BL36CN879Pn1V0014uVNlB+6yNh3e8T0fjUbtRJcbFiBB+OeYuJ1UNUeslaRJtKJNtMH7A==}
|
||||
/@swc/core-darwin-x64@1.3.65:
|
||||
resolution: {integrity: sha512-kGuWP7OP9mwOiIcJpEVa+ydC3Wxf0fPQ1MK0hUIPFcR6tAUEdOvdAuCzP6U20RX/JbbgwfI/Qq6ugT7VL6omgg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
@ -717,8 +717,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm-gnueabihf@1.3.64:
|
||||
resolution: {integrity: sha512-XE60bZS+qO+d8IQYAayhn3TRqyzVmQeOsX2B1yUHuKZU3Zb/mt/cmD/HLzZZW7J3z19kYf2na7Hvmnt3amUGoA==}
|
||||
/@swc/core-linux-arm-gnueabihf@1.3.65:
|
||||
resolution: {integrity: sha512-Bjbzldp8n4mWSdAvBt4VuLiHlfFM5pyftjJvJnmSY4H1IzbxkByyT60OHOedcIPRiZveD8NJzUJqutqrgTmtLg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
@ -726,8 +726,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-gnu@1.3.64:
|
||||
resolution: {integrity: sha512-+jcUua4cYLRMqDicv+4AaTZUGgYWXkXVI9AzaAgfkMNLU2TMXwuYXopxk1giAMop88+ovzYIqrxErRdu70CgtQ==}
|
||||
/@swc/core-linux-arm64-gnu@1.3.65:
|
||||
resolution: {integrity: sha512-GmxtcCymeQqEqT9n5mo857koRsUbEwmuijrBA4OeD5KOPW9gqAmUxr+ZgwgYHwyJ3CiN+UbK8uEqPsL6UVQmLg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
@ -735,8 +735,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-arm64-musl@1.3.64:
|
||||
resolution: {integrity: sha512-50MI8NFYUKhLncqY2piM/XOnNqZT6zY2ZoNOFsy63/T2gAYy1ts4mF4YUEkg4XOA2zhue1JSLZBUrHQXbgMYUQ==}
|
||||
/@swc/core-linux-arm64-musl@1.3.65:
|
||||
resolution: {integrity: sha512-yv9jP3gbfMsYrqswT2MwK5Q1+avSwRXAKo+LYUknTeoLQNNlukDfqSLHajNq23XrVDRP4B3Pjn7kaqjxRcihbg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
@ -744,8 +744,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-gnu@1.3.64:
|
||||
resolution: {integrity: sha512-bT8seQ41Q4J2JDgn2JpFCGNehGAIilAkZ476gEaKKroEWepBhkD0K1MspSSVYSJhLSGbBVSaadUEiBPxWgu1Rw==}
|
||||
/@swc/core-linux-x64-gnu@1.3.65:
|
||||
resolution: {integrity: sha512-GQkwysEPTlAOQ3jiTiedObzh6pBaf9RLaQqpGdCp+iKze9+BR+STBP0IIKhZDMPG/nWWNhrYFD/VMQxRoYPjfw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
@ -753,8 +753,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-linux-x64-musl@1.3.64:
|
||||
resolution: {integrity: sha512-sJgh3TXCDOEq/Au4XLAgNqy4rVcLeywQBoftnV3rcvX1/u9OCSRzgKLgYc5d1pEN5AMJV1l4u26kbGlQuZ+yRw==}
|
||||
/@swc/core-linux-x64-musl@1.3.65:
|
||||
resolution: {integrity: sha512-ETzhOhtDluYFK4x73OTM9gVTMyzGd2WeWGlCu3WoT1EPPUwCqQpcAqI3TfEcP1ljFDG0pPkpYzVpwNf8yjQElg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
@ -762,8 +762,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-arm64-msvc@1.3.64:
|
||||
resolution: {integrity: sha512-zWIy+mAWDjtJjl4e4mmhQL7g9KbkOwcWbeoIk4C6NT4VpjnjdX1pMml/Ez2sF5J5cGBwu7B1ePfTe/kAE6G36Q==}
|
||||
/@swc/core-win32-arm64-msvc@1.3.65:
|
||||
resolution: {integrity: sha512-3weD0I6F8bggN0KOnbZkvYC1PBrT5wrvohpvtgijRsODxjoWwztozjawJxF3rqgVqlSI/+nA+JkrN48e2cxJjQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
@ -771,8 +771,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-ia32-msvc@1.3.64:
|
||||
resolution: {integrity: sha512-6HMiuUeSMpTUAimb1E+gUNjy8m211oAzw+wjU8oOdA6iihWaLBz4TOhU9IaKZPPjqEcYGwqaT3tj5b5+mxde6Q==}
|
||||
/@swc/core-win32-ia32-msvc@1.3.65:
|
||||
resolution: {integrity: sha512-i6c3D7E9Ca41HteW3+hn1OKQfjIabc2P0p1mJRXBkn+igwb+Ba6gXJc7NqhrlF8uZsDhhcGZTsAqBBtfcfTuHQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
@ -780,8 +780,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core-win32-x64-msvc@1.3.64:
|
||||
resolution: {integrity: sha512-c8Al0JJfmgnO9sg6w34PICibqI4p7iXywo+wOxjY88oFwMcfV5rGaif1Fe3RqxJP/1WtUV7lYuKKZrneMXtyLA==}
|
||||
/@swc/core-win32-x64-msvc@1.3.65:
|
||||
resolution: {integrity: sha512-tQ9hEDtwPZxQ2sYb2n8ypfmdMjobKAf6VSnChteLMktofU7o562op5pLS6D6QCP2AtL3lcwe1piTCgIhk4vmjA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@ -789,8 +789,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@swc/core@1.3.64:
|
||||
resolution: {integrity: sha512-be1dk2pfjzBjFp/+p47/wvOAm7KpEtsi7hqI3ofox6pK3hBJChHgVTLVV9xqZm7CnYdyYYw3Z78hH6lrwutxXQ==}
|
||||
/@swc/core@1.3.65:
|
||||
resolution: {integrity: sha512-d5iDiKWf12FBo6h9Fro2pcnLK6HSPbyZ7A1U5iFNpRRx8XEd4uGdKtf5NoXJ3GDLQDLXnNSLA82Cl6SfrJ1lyw==}
|
||||
engines: {node: '>=10'}
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
@ -799,16 +799,16 @@ packages:
|
||||
'@swc/helpers':
|
||||
optional: true
|
||||
optionalDependencies:
|
||||
'@swc/core-darwin-arm64': 1.3.64
|
||||
'@swc/core-darwin-x64': 1.3.64
|
||||
'@swc/core-linux-arm-gnueabihf': 1.3.64
|
||||
'@swc/core-linux-arm64-gnu': 1.3.64
|
||||
'@swc/core-linux-arm64-musl': 1.3.64
|
||||
'@swc/core-linux-x64-gnu': 1.3.64
|
||||
'@swc/core-linux-x64-musl': 1.3.64
|
||||
'@swc/core-win32-arm64-msvc': 1.3.64
|
||||
'@swc/core-win32-ia32-msvc': 1.3.64
|
||||
'@swc/core-win32-x64-msvc': 1.3.64
|
||||
'@swc/core-darwin-arm64': 1.3.65
|
||||
'@swc/core-darwin-x64': 1.3.65
|
||||
'@swc/core-linux-arm-gnueabihf': 1.3.65
|
||||
'@swc/core-linux-arm64-gnu': 1.3.65
|
||||
'@swc/core-linux-arm64-musl': 1.3.65
|
||||
'@swc/core-linux-x64-gnu': 1.3.65
|
||||
'@swc/core-linux-x64-musl': 1.3.65
|
||||
'@swc/core-win32-arm64-msvc': 1.3.65
|
||||
'@swc/core-win32-ia32-msvc': 1.3.65
|
||||
'@swc/core-win32-x64-msvc': 1.3.65
|
||||
dev: true
|
||||
|
||||
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.2):
|
||||
@ -1175,7 +1175,7 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^4
|
||||
dependencies:
|
||||
'@swc/core': 1.3.64
|
||||
'@swc/core': 1.3.65
|
||||
vite: 4.3.9(@types/node@18.16.18)
|
||||
transitivePeerDependencies:
|
||||
- '@swc/helpers'
|
||||
@ -3777,8 +3777,8 @@ packages:
|
||||
scheduler: 0.23.0
|
||||
dev: false
|
||||
|
||||
/react-hook-form@7.44.3(react@18.2.0):
|
||||
resolution: {integrity: sha512-/tHId6p2ViAka1wECMw8FEPn/oz/w226zehHrJyQ1oIzCBNMIJCaj6ZkQcv+MjDxYh9MWR7RQic7Qqwe4a5nkw==}
|
||||
/react-hook-form@7.45.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-AbHeZ4ad+0dEIknSW9dBgIwcvRDfZ1O97sgj75WaMdOX0eg8TBiUf9wxzVkIjZbk76BBIE9lmFOzyD4PN80ZQg==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17 || ^18
|
||||
@ -4701,7 +4701,7 @@ packages:
|
||||
vite: '>=2.8'
|
||||
dependencies:
|
||||
'@rollup/plugin-virtual': 3.0.1
|
||||
'@swc/core': 1.3.64
|
||||
'@swc/core': 1.3.65
|
||||
uuid: 9.0.0
|
||||
vite: 4.3.9(@types/node@18.16.18)
|
||||
transitivePeerDependencies:
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { getNotesByAuthor } from "@libs/storage";
|
||||
import { CancelIcon } from "@shared/icons";
|
||||
import { NoteBase } from "@shared/notes/base";
|
||||
import { NoteQuoteRepost } from "@shared/notes/quoteRepost";
|
||||
import { Note } from "@shared/notes/note";
|
||||
import { NoteSkeleton } from "@shared/notes/skeleton";
|
||||
import { useActiveAccount } from "@stores/accounts";
|
||||
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||
@ -101,35 +100,15 @@ export function FeedBlock({ params }: { params: any }) {
|
||||
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
||||
const note = notes[virtualRow.index];
|
||||
if (note) {
|
||||
if (note.kind === 1) {
|
||||
return (
|
||||
<div
|
||||
key={virtualRow.index}
|
||||
data-index={virtualRow.index}
|
||||
ref={rowVirtualizer.measureElement}
|
||||
>
|
||||
<NoteBase
|
||||
key={note.event_id}
|
||||
block={params.id}
|
||||
event={note}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
key={virtualRow.index}
|
||||
data-index={virtualRow.index}
|
||||
ref={rowVirtualizer.measureElement}
|
||||
>
|
||||
<NoteQuoteRepost
|
||||
key={note.event_id}
|
||||
block={params.id}
|
||||
event={note}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={virtualRow.index}
|
||||
data-index={virtualRow.index}
|
||||
ref={rowVirtualizer.measureElement}
|
||||
>
|
||||
<Note event={note} block={params.id} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { createNote, getNotes } from "@libs/storage";
|
||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||
import { NoteBase } from "@shared/notes/base";
|
||||
import { NoteQuoteRepost } from "@shared/notes/quoteRepost";
|
||||
import { Note } from "@shared/notes/note";
|
||||
import { NoteSkeleton } from "@shared/notes/skeleton";
|
||||
import { RelayContext } from "@shared/relayProvider";
|
||||
import { useActiveAccount } from "@stores/accounts";
|
||||
@ -86,20 +85,11 @@ export function FollowingBlock({ block }: { block: number }) {
|
||||
const note = notes[index];
|
||||
|
||||
if (!note) return;
|
||||
|
||||
if (note.kind === 1) {
|
||||
return (
|
||||
<div key={index} data-index={index} ref={rowVirtualizer.measureElement}>
|
||||
<NoteBase block={block} event={note} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div key={index} data-index={index} ref={rowVirtualizer.measureElement}>
|
||||
<NoteQuoteRepost block={block} event={note} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div key={index} data-index={index} ref={rowVirtualizer.measureElement}>
|
||||
<Note event={note} block={block} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { getNoteByID } from "@libs/storage";
|
||||
import { ArrowLeftIcon } from "@shared/icons";
|
||||
import { Kind1 } from "@shared/notes/kind1";
|
||||
import { Kind1063 } from "@shared/notes/kind1063";
|
||||
import { Kind1 } from "@shared/notes/contents/kind1";
|
||||
import { Kind1063 } from "@shared/notes/contents/kind1063";
|
||||
import { NoteMetadata } from "@shared/notes/metadata";
|
||||
import { NoteReplyForm } from "@shared/notes/replies/form";
|
||||
import { RepliesList } from "@shared/notes/replies/list";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Profile } from "@app/trending/components/profile";
|
||||
import { NoteBase } from "@shared/notes/base";
|
||||
import { Note } from "@shared/notes/note";
|
||||
import { NoteSkeleton } from "@shared/notes/skeleton";
|
||||
import useSWR from "swr";
|
||||
|
||||
@ -30,7 +29,7 @@ export function TrendingNotes() {
|
||||
) : (
|
||||
<div className="relative w-full flex flex-col pt-1.5">
|
||||
{data.notes.map((item) => (
|
||||
<NoteBase key={item.id} event={item.event} metadata={false} />
|
||||
<Note key={item.id} event={item.event} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
@ -206,8 +206,8 @@ export async function createReplyNote(
|
||||
) {
|
||||
const db = await connect();
|
||||
return await db.execute(
|
||||
"INSERT OR IGNORE INTO replies (parent_id, event_id, pubkey, kind, tags, content, created_at) VALUES (?, ?, ?, ?, ?, ?, ?);",
|
||||
[parent_id, event_id, pubkey, kind, tags, content, created_at],
|
||||
"INSERT OR IGNORE INTO replies (event_id, parent_id, pubkey, kind, tags, content, created_at) VALUES (?, ?, ?, ?, ?, ?, ?);",
|
||||
[event_id, parent_id, pubkey, kind, tags, content, created_at],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ export function Button({
|
||||
switch (preset) {
|
||||
case "small":
|
||||
preClass =
|
||||
"w-min h-9 px-4 bg-zinc-900 rounded-md text-sm font-medium text-zinc-100 hover:bg-fuchsia-600";
|
||||
"w-min h-9 px-4 bg-fuchsia-500 rounded-md text-sm font-medium text-zinc-100 hover:bg-fuchsia-600";
|
||||
break;
|
||||
case "publish":
|
||||
preClass =
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
import { useActiveAccount } from "@stores/accounts";
|
||||
import { useComposer } from "@stores/composer";
|
||||
import { COMPOSE_SHORTCUT } from "@stores/shortcuts";
|
||||
import { register } from "@tauri-apps/api/globalShortcut";
|
||||
import { isRegistered, register } from "@tauri-apps/api/globalShortcut";
|
||||
import { Fragment, useEffect } from "react";
|
||||
|
||||
export function Composer() {
|
||||
@ -26,14 +26,17 @@ export function Composer() {
|
||||
};
|
||||
|
||||
const registerShortcut = async () => {
|
||||
await register(COMPOSE_SHORTCUT, () => {
|
||||
toggle(true);
|
||||
});
|
||||
const isShortcutRegistered = await isRegistered(COMPOSE_SHORTCUT);
|
||||
if (!isShortcutRegistered) {
|
||||
await register(COMPOSE_SHORTCUT, () => {
|
||||
toggle(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
registerShortcut();
|
||||
}, [registerShortcut]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
23
src/shared/icons/cmd.tsx
Normal file
23
src/shared/icons/cmd.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { SVGProps } from "react";
|
||||
|
||||
export function CommandIcon(
|
||||
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>,
|
||||
) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="square"
|
||||
strokeWidth="1.5"
|
||||
d="M9.25 9.25V6.5A2.75 2.75 0 106.5 9.25h2.75zm0 0h5.5m-5.5 0v5.5m5.5-5.5V6.5a2.75 2.75 0 112.75 2.75h-2.75zm0 0v5.5m0 0h-5.5m5.5 0v2.75a2.75 2.75 0 102.75-2.75h-2.75zm-5.5 0v2.75a2.75 2.75 0 11-2.75-2.75h2.75z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
@ -35,4 +35,5 @@ export * from "./zap";
|
||||
export * from "./loader";
|
||||
export * from "./trending";
|
||||
export * from "./empty";
|
||||
export * from "./cmd";
|
||||
// @endindex
|
||||
|
@ -1,47 +0,0 @@
|
||||
import { Kind1 } from "@shared/notes/kind1";
|
||||
import { Kind1063 } from "@shared/notes/kind1063";
|
||||
import { NoteMetadata } from "@shared/notes/metadata";
|
||||
import { NoteParent } from "@shared/notes/parent";
|
||||
import { User } from "@shared/user";
|
||||
import { parser } from "@utils/parser";
|
||||
import { isTagsIncludeID } from "@utils/transform";
|
||||
import { LumeEvent } from "@utils/types";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export function NoteBase({
|
||||
event,
|
||||
block,
|
||||
metadata = true,
|
||||
}: { event: LumeEvent; block?: number; metadata?: boolean }) {
|
||||
const content = useMemo(() => parser(event), [event]);
|
||||
const checkParentID = isTagsIncludeID(event.parent_id, event.tags);
|
||||
|
||||
return (
|
||||
<div className="h-min w-full px-3 py-1.5">
|
||||
<div className="rounded-md bg-zinc-900 px-5 pt-5">
|
||||
{event.parent_id &&
|
||||
(event.parent_id !== event.event_id || checkParentID) ? (
|
||||
<NoteParent id={event.parent_id} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<div className="flex flex-col">
|
||||
<User pubkey={event.pubkey} time={event.created_at} />
|
||||
<div className="-mt-5 pl-[49px]">
|
||||
{event.kind === 1 && <Kind1 content={content} />}
|
||||
{event.kind === 1063 && <Kind1063 metadata={event.tags} />}
|
||||
{metadata ? (
|
||||
<NoteMetadata
|
||||
id={event.event_id}
|
||||
eventPubkey={event.pubkey}
|
||||
currentBlock={block || 1}
|
||||
/>
|
||||
) : (
|
||||
<div className="h-5" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { Kind1 } from "@shared/notes/kind1";
|
||||
import { Kind1063 } from "@shared/notes/kind1063";
|
||||
import { Kind1 } from "@shared/notes/contents/kind1";
|
||||
import { Kind1063 } from "@shared/notes/contents/kind1063";
|
||||
import { NoteSkeleton } from "@shared/notes/skeleton";
|
||||
import { User } from "@shared/user";
|
||||
import { useEvent } from "@utils/hooks/useEvent";
|
||||
|
89
src/shared/notes/note.tsx
Normal file
89
src/shared/notes/note.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
import { Kind1 } from "@shared/notes/contents/kind1";
|
||||
import { Kind1063 } from "@shared/notes/contents/kind1063";
|
||||
import { NoteMetadata } from "@shared/notes/metadata";
|
||||
import { NoteParent } from "@shared/notes/parent";
|
||||
import { Repost } from "@shared/notes/repost";
|
||||
import { User } from "@shared/user";
|
||||
import { parser } from "@utils/parser";
|
||||
import { LumeEvent } from "@utils/types";
|
||||
import { useMemo } from "react";
|
||||
|
||||
interface Note {
|
||||
event: LumeEvent;
|
||||
block?: number;
|
||||
}
|
||||
|
||||
export function Note({ event, block }: Note) {
|
||||
const isRepost = event.kind === 6;
|
||||
|
||||
const renderParent = useMemo(() => {
|
||||
if (!isRepost && event.parent_id && event.parent_id !== event.event_id) {
|
||||
return <NoteParent id={event.parent_id} currentBlock={block} />;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [event.parent_id]);
|
||||
|
||||
const renderRepost = useMemo(() => {
|
||||
if (isRepost) {
|
||||
return <Repost event={event} currentBlock={block} />;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [event.kind]);
|
||||
|
||||
const renderContent = useMemo(() => {
|
||||
switch (event.kind) {
|
||||
case 1: {
|
||||
const content = parser(event);
|
||||
return <Kind1 content={content} />;
|
||||
}
|
||||
case 6:
|
||||
return null;
|
||||
case 1063:
|
||||
return <Kind1063 metadata={event.tags} />;
|
||||
default:
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="px-2 py-2 inline-flex flex-col gap-1 bg-zinc-800 rounded-md">
|
||||
<span className="text-zinc-500 text-sm font-medium leading-none">
|
||||
Kind: {event.kind}
|
||||
</span>
|
||||
<p className="text-fuchsia-500 text-sm leading-none">
|
||||
Lume isn't fully support this kind in newsfeed
|
||||
</p>
|
||||
</div>
|
||||
<div className="markdown">
|
||||
<p>{event.content}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}, [event.kind]);
|
||||
|
||||
return (
|
||||
<div className="h-min w-full px-3 py-1.5">
|
||||
<div className="rounded-md bg-zinc-900 px-5 pt-5">
|
||||
{renderParent}
|
||||
<div className="flex flex-col">
|
||||
<User
|
||||
pubkey={event.pubkey}
|
||||
time={event.created_at}
|
||||
repost={isRepost}
|
||||
/>
|
||||
<div className="-mt-5 pl-[49px]">
|
||||
{renderContent}
|
||||
{!isRepost && (
|
||||
<NoteMetadata
|
||||
id={event.event_id}
|
||||
eventPubkey={event.pubkey}
|
||||
currentBlock={block || 1}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{renderRepost}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
import { Kind1 } from "@shared/notes/kind1";
|
||||
import { Kind1063 } from "@shared/notes/kind1063";
|
||||
import { Kind1 } from "@shared/notes/contents/kind1";
|
||||
import { Kind1063 } from "@shared/notes/contents/kind1063";
|
||||
import { NoteMetadata } from "@shared/notes/metadata";
|
||||
import { NoteSkeleton } from "@shared/notes/skeleton";
|
||||
import { User } from "@shared/user";
|
||||
import { useEvent } from "@utils/hooks/useEvent";
|
||||
import { parser } from "@utils/parser";
|
||||
import { memo } from "react";
|
||||
|
||||
export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
|
||||
export function NoteParent({
|
||||
id,
|
||||
currentBlock,
|
||||
}: { id: string; currentBlock: number }) {
|
||||
const data = useEvent(id);
|
||||
|
||||
const kind1 = data?.kind === 1 ? parser(data) : null;
|
||||
@ -33,13 +35,14 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
|
||||
</p>
|
||||
</div>
|
||||
<div className="markdown">
|
||||
<p>{data.content}</p>
|
||||
<p>{data.content || data.toString()}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<NoteMetadata
|
||||
id={data.event_id || data.id}
|
||||
eventPubkey={data.pubkey}
|
||||
currentBlock={currentBlock}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@ -48,4 +51,4 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
import { RootNote } from "@shared/notes/rootNote";
|
||||
import { User } from "@shared/user";
|
||||
import { getQuoteID } from "@utils/transform";
|
||||
import { LumeEvent } from "@utils/types";
|
||||
|
||||
export function NoteQuoteRepost({
|
||||
block,
|
||||
event,
|
||||
}: { block: number; event: LumeEvent }) {
|
||||
const rootID = getQuoteID(event.tags);
|
||||
|
||||
return (
|
||||
<div className="h-min w-full px-3 py-1.5">
|
||||
<div className="rounded-md bg-zinc-900">
|
||||
<div className="relative px-5 pb-5 pt-5">
|
||||
<div className="absolute left-[35px] top-[20px] h-[70px] w-0.5 bg-gradient-to-t from-zinc-800 to-zinc-600" />
|
||||
<User pubkey={event.pubkey} time={event.created_at} repost={true} />
|
||||
</div>
|
||||
<RootNote id={rootID} fallback={event.content} currentBlock={block} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Kind1 } from "@shared/notes/kind1";
|
||||
import { Kind1 } from "@shared/notes/contents/kind1";
|
||||
import { NoteMetadata } from "@shared/notes/metadata";
|
||||
import { User } from "@shared/user";
|
||||
import { parser } from "@utils/parser";
|
||||
|
56
src/shared/notes/repost.tsx
Normal file
56
src/shared/notes/repost.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import { Kind1 } from "@shared/notes/contents/kind1";
|
||||
import { Kind1063 } from "@shared/notes/contents/kind1063";
|
||||
import { NoteMetadata } from "@shared/notes/metadata";
|
||||
import { NoteSkeleton } from "@shared/notes/skeleton";
|
||||
import { User } from "@shared/user";
|
||||
import { useEvent } from "@utils/hooks/useEvent";
|
||||
import { parser } from "@utils/parser";
|
||||
import { getRepostID } from "@utils/transform";
|
||||
import { LumeEvent } from "@utils/types";
|
||||
|
||||
export function Repost({
|
||||
event,
|
||||
currentBlock,
|
||||
}: { event: LumeEvent; currentBlock?: number }) {
|
||||
const repostID = getRepostID(event.tags);
|
||||
const data = useEvent(repostID);
|
||||
|
||||
const kind1 = data?.kind === 1 ? parser(data) : null;
|
||||
const kind1063 = data?.kind === 1063 ? data.tags : null;
|
||||
|
||||
return (
|
||||
<div className="relative overflow-hidden flex flex-col mt-12 pb-6">
|
||||
{data ? (
|
||||
<>
|
||||
<User pubkey={data.pubkey} time={data.created_at} />
|
||||
<div className="-mt-5 pl-[49px]">
|
||||
{kind1 && <Kind1 content={kind1} />}
|
||||
{kind1063 && <Kind1063 metadata={kind1063} />}
|
||||
{!kind1 && !kind1063 && (
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="px-2 py-2 inline-flex flex-col gap-1 bg-zinc-800 rounded-md">
|
||||
<span className="text-zinc-500 text-sm font-medium leading-none">
|
||||
Kind: {data.kind}
|
||||
</span>
|
||||
<p className="text-fuchsia-500 text-sm leading-none">
|
||||
Lume isn't fully support this kind in newsfeed
|
||||
</p>
|
||||
</div>
|
||||
<div className="markdown">
|
||||
<p>{data.content || data.toString()}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<NoteMetadata
|
||||
id={data.event_id || data.id}
|
||||
eventPubkey={data.pubkey}
|
||||
currentBlock={currentBlock}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<NoteSkeleton />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||
import { Kind1 } from "@shared/notes/kind1";
|
||||
import { Kind1063 } from "@shared/notes/kind1063";
|
||||
import { NoteMetadata } from "@shared/notes/metadata";
|
||||
import { NoteSkeleton } from "@shared/notes/skeleton";
|
||||
import { RelayContext } from "@shared/relayProvider";
|
||||
import { User } from "@shared/user";
|
||||
import { parser } from "@utils/parser";
|
||||
import { memo, useContext } from "react";
|
||||
import useSWRSubscription from "swr/subscription";
|
||||
|
||||
function isJSON(str: string) {
|
||||
try {
|
||||
JSON.parse(str);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export const RootNote = memo(function RootNote({
|
||||
id,
|
||||
fallback,
|
||||
currentBlock,
|
||||
}: { id: string; fallback?: any; currentBlock?: number }) {
|
||||
const ndk = useContext(RelayContext);
|
||||
const parseFallback = isJSON(fallback) ? JSON.parse(fallback) : null;
|
||||
|
||||
const { data, error } = useSWRSubscription(
|
||||
parseFallback ? null : id,
|
||||
(key, { next }) => {
|
||||
const sub = ndk.subscribe({
|
||||
ids: [key],
|
||||
});
|
||||
|
||||
sub.addListener("event", (event: NDKEvent) => {
|
||||
next(null, event);
|
||||
});
|
||||
|
||||
return () => {
|
||||
sub.stop();
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
const kind1 = !error && data?.kind === 1 ? parser(data) : null;
|
||||
const kind1063 = !error && data?.kind === 1063 ? data.tags : null;
|
||||
|
||||
if (parseFallback) {
|
||||
const contentFallback = parser(parseFallback);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col px-5">
|
||||
<User pubkey={parseFallback.pubkey} time={parseFallback.created_at} />
|
||||
<div className="-mt-5 pl-[49px]">
|
||||
<Kind1 content={contentFallback} />
|
||||
<NoteMetadata
|
||||
id={parseFallback.id}
|
||||
eventPubkey={parseFallback.pubkey}
|
||||
currentBlock={currentBlock}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col px-5">
|
||||
{data ? (
|
||||
<>
|
||||
<User pubkey={data.pubkey} time={data.created_at} />
|
||||
<div className="-mt-5 pl-[49px]">
|
||||
{kind1 && <Kind1 content={kind1} />}
|
||||
{kind1063 && <Kind1063 metadata={kind1063} />}
|
||||
{!kind1 && !kind1063 && (
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="px-2 py-2 inline-flex flex-col gap-1 bg-zinc-800 rounded-md">
|
||||
<span className="text-zinc-500 text-sm font-medium leading-none">
|
||||
Kind: {data.kind}
|
||||
</span>
|
||||
<p className="text-fuchsia-500 text-sm leading-none">
|
||||
Lume isn't fully support this kind in newsfeed
|
||||
</p>
|
||||
</div>
|
||||
<div className="markdown">
|
||||
<p>{data.content}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<NoteMetadata
|
||||
id={data.id}
|
||||
eventPubkey={data.pubkey}
|
||||
currentBlock={currentBlock}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<NoteSkeleton />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
@ -80,7 +80,7 @@ export function isTagsIncludeID(id: string, arr: NDKTag[]) {
|
||||
}
|
||||
|
||||
// get parent id from event tags
|
||||
export function getQuoteID(arr: NDKTag[]) {
|
||||
export function getRepostID(arr: NDKTag[]) {
|
||||
const tags = destr(arr);
|
||||
let quoteID = null;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user