mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-17 14:04:21 +01:00
feat: parse profile, add relay column
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { For } from 'solid-js';
|
||||
|
||||
import { Kind, Event as NostrEvent } from 'nostr-tools';
|
||||
import { Kind } from 'nostr-tools';
|
||||
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
import EventDisplayById from '@/components/event/EventDisplayById';
|
||||
@@ -11,16 +11,16 @@ import MentionedUserDisplay from '@/components/event/textNote/MentionedUserDispl
|
||||
import VideoDisplay from '@/components/event/textNote/VideoDisplay';
|
||||
import EventLink from '@/components/EventLink';
|
||||
import PreviewedLink from '@/components/utils/PreviewedLink';
|
||||
import { createSearchColumn } from '@/core/column';
|
||||
import { createRelaysColumn, createSearchColumn } from '@/core/column';
|
||||
import useConfig from '@/core/useConfig';
|
||||
import { useRequestCommand } from '@/hooks/useCommandBus';
|
||||
import { textNote } from '@/nostr/event';
|
||||
import { type ParsedTextNoteNode } from '@/nostr/parseTextNote';
|
||||
import { isImageUrl, isVideoUrl } from '@/utils/url';
|
||||
import { ParsedTextNoteResolvedNode, type ParsedTextNoteResolved } from '@/nostr/parseTextNote';
|
||||
import { isImageUrl, isVideoUrl, isWebSocketUrl } from '@/utils/url';
|
||||
|
||||
export type TextNoteContentDisplayProps = {
|
||||
event: NostrEvent;
|
||||
parsed: ParsedTextNoteResolved;
|
||||
embedding: boolean;
|
||||
initialHidden?: boolean;
|
||||
};
|
||||
|
||||
const TextNoteContentDisplay = (props: TextNoteContentDisplayProps) => {
|
||||
@@ -28,22 +28,25 @@ const TextNoteContentDisplay = (props: TextNoteContentDisplayProps) => {
|
||||
|
||||
const request = useRequestCommand();
|
||||
|
||||
const event = () => textNote(props.event);
|
||||
|
||||
const addHashTagColumn = (query: string) => {
|
||||
saveColumn(createSearchColumn({ query }));
|
||||
request({ command: 'moveToLastColumn' }).catch((err) => console.error(err));
|
||||
};
|
||||
|
||||
const addRelayColumn = (url: string) => {
|
||||
saveColumn(createRelaysColumn({ name: url, relayUrls: [url] }));
|
||||
request({ command: 'moveToLastColumn' }).catch((err) => console.error(err));
|
||||
};
|
||||
|
||||
return (
|
||||
<For each={event().parsed()}>
|
||||
{(item: ParsedTextNoteNode) => {
|
||||
<For each={props.parsed}>
|
||||
{(item: ParsedTextNoteResolvedNode) => {
|
||||
if (item.type === 'PlainText') {
|
||||
return <span>{item.content}</span>;
|
||||
}
|
||||
if (item.type === 'URL') {
|
||||
const initialHidden = () =>
|
||||
!config().showMedia || event().contentWarning().contentWarning || !props.embedding;
|
||||
!config().showMedia || !props.embedding || (props.initialHidden ?? false);
|
||||
|
||||
if (isImageUrl(item.content)) {
|
||||
return <ImageDisplay url={item.content} initialHidden={initialHidden()} />;
|
||||
@@ -51,21 +54,30 @@ const TextNoteContentDisplay = (props: TextNoteContentDisplayProps) => {
|
||||
if (isVideoUrl(item.content)) {
|
||||
return <VideoDisplay url={item.content} initialHidden={initialHidden()} />;
|
||||
}
|
||||
if (isWebSocketUrl(item.content)) {
|
||||
return (
|
||||
<button
|
||||
class="select-text text-blue-500 underline"
|
||||
onClick={() => addRelayColumn(item.content)}
|
||||
>
|
||||
{item.content}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
return <PreviewedLink class="text-blue-500 underline" href={item.content} />;
|
||||
}
|
||||
if (item.type === 'TagReference') {
|
||||
const resolved = event().resolveTagReference(item);
|
||||
if (resolved == null) {
|
||||
if (item.type === 'TagReferenceResolved') {
|
||||
if (item.reference == null) {
|
||||
return <span>{item.content}</span>;
|
||||
}
|
||||
if (resolved.type === 'MentionedUser') {
|
||||
return <MentionedUserDisplay pubkey={resolved.pubkey} />;
|
||||
if (item.reference.type === 'MentionedUser') {
|
||||
return <MentionedUserDisplay pubkey={item.reference.pubkey} />;
|
||||
}
|
||||
if (resolved.type === 'MentionedEvent') {
|
||||
if (item.reference.type === 'MentionedEvent') {
|
||||
if (props.embedding) {
|
||||
return <MentionedEventDisplay mentionedEvent={resolved} />;
|
||||
return <MentionedEventDisplay mentionedEvent={item.reference} />;
|
||||
}
|
||||
return <EventLink eventId={resolved.eventId} />;
|
||||
return <EventLink eventId={item.reference.eventId} />;
|
||||
}
|
||||
}
|
||||
if (item.type === 'Bech32Entity') {
|
||||
@@ -94,6 +106,17 @@ const TextNoteContentDisplay = (props: TextNoteContentDisplayProps) => {
|
||||
if (item.data.type === 'nprofile') {
|
||||
return <MentionedUserDisplay pubkey={item.data.data.pubkey} />;
|
||||
}
|
||||
if (item.data.type === 'nrelay') {
|
||||
const url: string = item.data.data;
|
||||
return (
|
||||
<button
|
||||
class="select-text text-blue-500 underline"
|
||||
onClick={() => addRelayColumn(url)}
|
||||
>
|
||||
{url} ({item.content})
|
||||
</button>
|
||||
);
|
||||
}
|
||||
return <span class="text-blue-500 underline">{item.content}</span>;
|
||||
}
|
||||
if (item.type === 'HashTag') {
|
||||
@@ -106,14 +129,13 @@ const TextNoteContentDisplay = (props: TextNoteContentDisplayProps) => {
|
||||
</button>
|
||||
);
|
||||
}
|
||||
if (item.type === 'CustomEmoji') {
|
||||
const emojiUrl = event().getEmojiUrl(item.shortcode);
|
||||
if (emojiUrl == null) return <span>{item.content}</span>;
|
||||
if (item.type === 'CustomEmojiResolved') {
|
||||
if (item.url == null) return <span>{item.content}</span>;
|
||||
// const { imageRef, canvas } = useImageAnimation({ initialPlaying: false });
|
||||
return (
|
||||
<img
|
||||
class="inline-block h-8 max-w-[128px] align-middle"
|
||||
src={emojiUrl}
|
||||
src={item.url}
|
||||
alt={item.content}
|
||||
title={item.shortcode}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user