wip
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import * as Popover from '@radix-ui/react-popover';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { ReactionIcon } from '@shared/icons';
|
||||
import { useNDK } from '@libs/ndk/provider';
|
||||
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
import { ReactionIcon } from '@shared/icons';
|
||||
|
||||
const REACTIONS = [
|
||||
{
|
||||
@@ -30,11 +30,11 @@ const REACTIONS = [
|
||||
];
|
||||
|
||||
export function NoteReaction({ id, pubkey }: { id: string; pubkey: string }) {
|
||||
const { ndk } = useNDK();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [reaction, setReaction] = useState<string | null>(null);
|
||||
|
||||
const { publish } = useNostr();
|
||||
|
||||
const getReactionImage = (content: string) => {
|
||||
const reaction: { img: string } = REACTIONS.find((el) => el.content === content);
|
||||
return reaction.img;
|
||||
@@ -43,16 +43,16 @@ export function NoteReaction({ id, pubkey }: { id: string; pubkey: string }) {
|
||||
const react = async (content: string) => {
|
||||
setReaction(content);
|
||||
|
||||
const event = await publish({
|
||||
content: content,
|
||||
kind: NDKKind.Reaction,
|
||||
tags: [
|
||||
['e', id],
|
||||
['p', pubkey],
|
||||
],
|
||||
});
|
||||
const event = new NDKEvent(ndk);
|
||||
event.content = content;
|
||||
event.kind = NDKKind.Reaction;
|
||||
event.tags = [
|
||||
['e', id],
|
||||
['p', pubkey],
|
||||
];
|
||||
|
||||
if (event) {
|
||||
const publishedRelays = await event.publish();
|
||||
if (publishedRelays) {
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import * as Tooltip from '@radix-ui/react-tooltip';
|
||||
import { createSearchParams, useNavigate } from 'react-router-dom';
|
||||
|
||||
import { ReplyIcon } from '@shared/icons';
|
||||
|
||||
import { useComposer } from '@stores/composer';
|
||||
|
||||
export function NoteReply({
|
||||
id,
|
||||
pubkey,
|
||||
@@ -13,14 +12,23 @@ export function NoteReply({
|
||||
pubkey: string;
|
||||
root?: string;
|
||||
}) {
|
||||
const setReply = useComposer((state) => state.setReply);
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<Tooltip.Root delayDuration={150}>
|
||||
<Tooltip.Trigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setReply(id, pubkey, root)}
|
||||
onClick={() =>
|
||||
navigate({
|
||||
pathname: '/new/',
|
||||
search: createSearchParams({
|
||||
id,
|
||||
pubkey,
|
||||
root,
|
||||
}).toString(),
|
||||
})
|
||||
}
|
||||
className="group inline-flex h-7 w-7 items-center justify-center text-neutral-600 dark:text-neutral-400"
|
||||
>
|
||||
<ReplyIcon className="h-5 w-5 group-hover:text-blue-500" />
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import { NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import * as AlertDialog from '@radix-ui/react-alert-dialog';
|
||||
import * as Tooltip from '@radix-ui/react-tooltip';
|
||||
import { message } from '@tauri-apps/plugin-dialog';
|
||||
import { useState } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
import { useNDK } from '@libs/ndk/provider';
|
||||
|
||||
import { LoaderIcon, RepostIcon } from '@shared/icons';
|
||||
|
||||
import { useNostr } from '@utils/hooks/useNostr';
|
||||
import { sendNativeNotification } from '@utils/notification';
|
||||
|
||||
export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
|
||||
const { publish } = useNostr();
|
||||
const { relayUrls } = useNDK();
|
||||
const { ndk, relayUrls } = useNDK();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -22,18 +18,26 @@ export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
|
||||
|
||||
const submit = async () => {
|
||||
setIsLoading(true);
|
||||
|
||||
const tags = [
|
||||
['e', id, relayUrls[0], 'root'],
|
||||
['p', pubkey],
|
||||
];
|
||||
const event = await publish({ content: '', kind: NDKKind.Repost, tags: tags });
|
||||
if (event) {
|
||||
|
||||
const event = new NDKEvent(ndk);
|
||||
event.content = '';
|
||||
event.kind = NDKKind.Repost;
|
||||
event.tags = tags;
|
||||
|
||||
const publishedRelays = await event.publish();
|
||||
if (publishedRelays) {
|
||||
setOpen(false);
|
||||
setIsRepost(true);
|
||||
await sendNativeNotification('Reposted successfully', 'Lume');
|
||||
|
||||
toast.success(`Broadcasted to ${publishedRelays.size} relays successfully.`);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
await message('Repost failed, try again later', { title: 'Lume', type: 'error' });
|
||||
toast.error('Repost failed, try again later');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,11 +67,11 @@ export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
|
||||
</Tooltip.Portal>
|
||||
</Tooltip.Root>
|
||||
<AlertDialog.Portal>
|
||||
<AlertDialog.Overlay className="fixed inset-0 z-50 bg-black/80 backdrop-blur-2xl" />
|
||||
<AlertDialog.Overlay className="fixed inset-0 z-50 bg-black/20 backdrop-blur-sm dark:bg-white/20" />
|
||||
<AlertDialog.Content className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
|
||||
<div className="relative h-min w-full max-w-md rounded-xl bg-neutral-400 dark:bg-neutral-600">
|
||||
<div className="flex flex-col gap-2 border-b border-white/5 px-5 py-4">
|
||||
<AlertDialog.Title className="text-lg font-semibold leading-none text-white">
|
||||
<div className="relative h-min w-full max-w-md rounded-xl bg-white dark:bg-black">
|
||||
<div className="flex flex-col gap-2 border-b border-neutral-100 px-5 py-6 dark:border-neutral-900">
|
||||
<AlertDialog.Title className="text-lg font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
||||
Confirm repost this post?
|
||||
</AlertDialog.Title>
|
||||
<AlertDialog.Description className="text-sm leading-tight text-neutral-600 dark:text-neutral-400">
|
||||
@@ -77,14 +81,14 @@ export function NoteRepost({ id, pubkey }: { id: string; pubkey: string }) {
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 px-3 py-3">
|
||||
<AlertDialog.Cancel asChild>
|
||||
<button className="inline-flex h-9 w-20 items-center justify-center rounded-md text-sm font-medium leading-none text-white outline-none hover:bg-white/10 hover:backdrop-blur-xl">
|
||||
<button className="inline-flex h-9 w-20 items-center justify-center rounded-md text-sm font-medium text-neutral-600 outline-none hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-400">
|
||||
Cancel
|
||||
</button>
|
||||
</AlertDialog.Cancel>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => submit()}
|
||||
className="inline-flex h-9 w-28 items-center justify-center rounded-md bg-white/10 text-sm font-medium leading-none text-white outline-none hover:bg-blue-600"
|
||||
className="inline-flex h-9 w-24 items-center justify-center rounded-md bg-blue-500 text-sm font-medium leading-none text-white outline-none hover:bg-blue-600"
|
||||
>
|
||||
{isLoading ? (
|
||||
<LoaderIcon className="h-4 w-4 animate-spin text-white" />
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import { nip19 } from 'nostr-tools';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
ArticleNote,
|
||||
@@ -49,24 +48,17 @@ export function ChildNote({ id, root }: { id: string; root?: string }) {
|
||||
<div className="absolute bottom-0 left-[18px] h-[calc(100%-3.4rem)] w-0.5 bg-gradient-to-t from-black/20 to-black/10 dark:from-white/20 dark:to-white/10" />
|
||||
<div className="relative mb-5 flex flex-col">
|
||||
<div className="relative z-10 flex items-start gap-3">
|
||||
<div className="inline-flex h-10 w-10 items-end justify-center rounded-lg bg-black pb-1">
|
||||
<img src="/lume.png" alt="lume" className="h-auto w-1/3" />
|
||||
</div>
|
||||
<h5 className="truncate font-semibold leading-none text-white">
|
||||
Lume <span className="text-green-500">(System)</span>
|
||||
<div className="inline-flex h-10 w-10 shrink-0 items-end justify-center rounded-lg bg-black"></div>
|
||||
<h5 className="truncate font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
||||
Lume <span className="text-teal-500">(System)</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div className="-mt-4 flex items-start gap-3">
|
||||
<div className="w-10 shrink-0" />
|
||||
<div>
|
||||
<div className="relative z-20 mt-1 flex-1 select-text">
|
||||
<div className="mb-1 select-text rounded-lg bg-white/5 p-1.5 text-sm">
|
||||
Lume cannot find this post with your current relays, but you can view it
|
||||
via njump.me.{' '}
|
||||
<Link to={noteLink} className="text-blue-500">
|
||||
Learn more
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="prose prose-neutral max-w-none select-text whitespace-pre-line break-all leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500">
|
||||
Lume cannot find this post with your current relay set, but you can view
|
||||
it via njump.me
|
||||
</div>
|
||||
<LinkPreview urls={[noteLink]} />
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@ export function FileNote(props: { event?: NDKEvent }) {
|
||||
slot="media"
|
||||
src={url}
|
||||
poster={`https://thumbnail.video/api/get?url=${url}&seconds=1`}
|
||||
preload="auto"
|
||||
preload="none"
|
||||
muted
|
||||
crossOrigin=""
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,6 @@ import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { nip19 } from 'nostr-tools';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
import { useNDK } from '@libs/ndk/provider';
|
||||
@@ -113,24 +112,17 @@ export function Repost({
|
||||
>
|
||||
<div className="relative flex flex-col">
|
||||
<div className="relative z-10 flex items-start gap-3">
|
||||
<div className="inline-flex h-11 w-11 items-end justify-center rounded-lg bg-black pb-1">
|
||||
<img src="/lume.png" alt="lume" className="h-auto w-1/3" />
|
||||
</div>
|
||||
<h5 className="truncate font-semibold leading-none text-white">
|
||||
Lume <span className="text-green-500">(System)</span>
|
||||
<div className="inline-flex h-10 w-10 shrink-0 items-end justify-center rounded-lg bg-black"></div>
|
||||
<h5 className="truncate font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
||||
Lume <span className="text-teal-500">(System)</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div className="-mt-4 flex items-start gap-3">
|
||||
<div className="w-11 shrink-0" />
|
||||
<div>
|
||||
<div className="relative z-20 mt-1 flex-1 select-text">
|
||||
<div className="mb-1 select-text rounded-lg bg-white/5 p-1.5 text-sm">
|
||||
Lume cannot find this post with your current relays, but you can view
|
||||
it via njump.me.{' '}
|
||||
<Link to={noteLink} className="text-blue-500">
|
||||
Learn more
|
||||
</Link>
|
||||
</div>
|
||||
<div className="w-10 shrink-0" />
|
||||
<div className="flex-1">
|
||||
<div className="prose prose-neutral max-w-none select-text whitespace-pre-line break-all leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500">
|
||||
Lume cannot find this post with your current relay set, but you can view
|
||||
it via njump.me
|
||||
</div>
|
||||
<LinkPreview urls={[noteLink]} />
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@ export function TextNote(props: { content?: string }) {
|
||||
return (
|
||||
<div>
|
||||
<ReactMarkdown
|
||||
className="prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
|
||||
className="break-p prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
|
||||
remarkPlugins={[remarkGfm]}
|
||||
disallowedElements={['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'code']}
|
||||
unwrapDisallowed={true}
|
||||
@@ -38,7 +38,7 @@ export function TextNote(props: { content?: string }) {
|
||||
return (
|
||||
<div>
|
||||
<ReactMarkdown
|
||||
className="prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:break-words prose-pre:break-all prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
|
||||
className="break-p prose prose-neutral max-w-none select-text whitespace-pre-line leading-normal dark:prose-invert prose-headings:mb-1 prose-headings:mt-3 prose-p:mb-0 prose-p:mt-0 prose-p:last:mb-1 prose-a:font-normal prose-a:text-blue-500 prose-blockquote:mb-1 prose-blockquote:mt-1 prose-blockquote:border-l-[2px] prose-blockquote:border-blue-500 prose-blockquote:pl-2 prose-pre:whitespace-pre-wrap prose-pre:bg-white/10 prose-ol:m-0 prose-ol:mb-1 prose-ul:mb-1 prose-ul:mt-1 prose-img:mb-2 prose-img:mt-3 prose-hr:mx-0 prose-hr:my-2 hover:prose-a:text-blue-500"
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
a: ({ href }) => {
|
||||
|
||||
@@ -52,7 +52,7 @@ export function LinkPreview({ urls }: { urls: string[] }) {
|
||||
</h5>
|
||||
)}
|
||||
{data.description && (
|
||||
<p className="mb-2.5 line-clamp-3 break-words text-sm text-neutral-700 dark:text-neutral-400">
|
||||
<p className="mb-2.5 line-clamp-3 break-all text-sm text-neutral-700 dark:text-neutral-400">
|
||||
{data.description}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -18,7 +18,7 @@ export const VideoPreview = memo(function VideoPreview({ urls }: { urls: string[
|
||||
slot="media"
|
||||
src={url}
|
||||
poster={`https://thumbnail.video/api/get?url=${url}&seconds=1`}
|
||||
preload="auto"
|
||||
preload="none"
|
||||
muted
|
||||
/>
|
||||
<MediaControlBar>
|
||||
|
||||
@@ -2,8 +2,10 @@ export function NoteSkeleton() {
|
||||
return (
|
||||
<div className="flex h-min flex-col">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="relative h-11 w-11 shrink overflow-hidden rounded-lg bg-neutral-400 dark:bg-neutral-600" />
|
||||
<div className="h-3 w-20 rounded bg-neutral-400 dark:bg-neutral-600" />
|
||||
<div className="relative h-10 w-10 shrink-0 overflow-hidden rounded-lg bg-neutral-400 dark:bg-neutral-600" />
|
||||
<div className="h-6 w-full">
|
||||
<div className="h-3 w-24 animate-pulse rounded bg-neutral-300 dark:bg-neutral-700" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="-mt-5 flex animate-pulse gap-3">
|
||||
<div className="w-10 shrink-0" />
|
||||
|
||||
@@ -38,7 +38,7 @@ export function NoteWrapper({
|
||||
children,
|
||||
event.kind === 1 ? { content: event.content } : { event: event }
|
||||
)}
|
||||
<NoteActions id={event.id} pubkey={event.pubkey} />
|
||||
<NoteActions id={event.id} pubkey={event.pubkey} root={root} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user