style: adjust font size
This commit is contained in:
@@ -36,7 +36,7 @@ const Content = memo(
|
|||||||
if (images.length) {
|
if (images.length) {
|
||||||
nodes.push(
|
nodes.push(
|
||||||
<ImageGallery
|
<ImageGallery
|
||||||
className="mt-2 w-fit"
|
className={`w-fit ${size === 'small' ? 'mt-1' : 'mt-2'}`}
|
||||||
key={`image-gallery-${event.id}`}
|
key={`image-gallery-${event.id}`}
|
||||||
images={images}
|
images={images}
|
||||||
isNsfw={isNsfw}
|
isNsfw={isNsfw}
|
||||||
@@ -50,7 +50,7 @@ const Content = memo(
|
|||||||
videos.forEach((src, index) => {
|
videos.forEach((src, index) => {
|
||||||
nodes.push(
|
nodes.push(
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
className="mt-2"
|
className={size === 'small' ? 'mt-1' : 'mt-2'}
|
||||||
key={`video-${index}-${src}`}
|
key={`video-${index}-${src}`}
|
||||||
src={src}
|
src={src}
|
||||||
isNsfw={isNsfw}
|
isNsfw={isNsfw}
|
||||||
@@ -68,11 +68,7 @@ const Content = memo(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return <div className={cn('text-wrap break-words whitespace-pre-wrap', className)}>{nodes}</div>
|
||||||
<div className={cn('text-sm text-wrap break-words whitespace-pre-wrap', className)}>
|
|
||||||
{nodes}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Content.displayName = 'Content'
|
Content.displayName = 'Content'
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export default function ImageGallery({
|
|||||||
{images.map((src, index) => {
|
{images.map((src, index) => {
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
className={`rounded-lg max-w-full cursor-pointer ${size === 'small' ? 'max-h-[10vh]' : 'max-h-[30vh]'}`}
|
className={`rounded-lg max-w-full cursor-pointer ${size === 'small' ? 'max-h-[15vh]' : 'max-h-[30vh]'}`}
|
||||||
key={index}
|
key={index}
|
||||||
src={src}
|
src={src}
|
||||||
onClick={(e) => handlePhotoClick(e, index)}
|
onClick={(e) => handlePhotoClick(e, index)}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import Content from '../Content'
|
|||||||
import NoteStats from '../NoteStats'
|
import NoteStats from '../NoteStats'
|
||||||
import UserAvatar from '../UserAvatar'
|
import UserAvatar from '../UserAvatar'
|
||||||
import Username from '../Username'
|
import Username from '../Username'
|
||||||
|
import ParentNotePreview from '../ParentNotePreview'
|
||||||
|
|
||||||
export default function Note({
|
export default function Note({
|
||||||
event,
|
event,
|
||||||
@@ -22,45 +23,34 @@ export default function Note({
|
|||||||
hideStats?: boolean
|
hideStats?: boolean
|
||||||
fetchNoteStats?: boolean
|
fetchNoteStats?: boolean
|
||||||
}) {
|
}) {
|
||||||
|
const { push } = useSecondaryPage()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<UserAvatar userId={event.pubkey} size={size === 'small' ? 'small' : 'normal'} />
|
<UserAvatar userId={event.pubkey} size={size === 'small' ? 'small' : 'normal'} />
|
||||||
<div className={`flex-1 w-0 ${size === 'small' ? 'flex space-x-2 items-center' : ''}`}>
|
<div className={`flex-1 w-0 ${size === 'small' ? 'flex space-x-2 items-end' : ''}`}>
|
||||||
<Username
|
<Username
|
||||||
userId={event.pubkey}
|
userId={event.pubkey}
|
||||||
className={`font-semibold max-w-fit flex ${size === 'small' ? 'text-xs' : 'text-sm'}`}
|
className={`font-semibold max-w-fit flex ${size === 'small' ? 'text-sm' : ''}`}
|
||||||
/>
|
/>
|
||||||
<div className="text-xs text-muted-foreground">{formatTimestamp(event.created_at)}</div>
|
<div className="text-xs text-muted-foreground">{formatTimestamp(event.created_at)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{parentEvent && (
|
{parentEvent && (
|
||||||
<div className="text-muted-foreground truncate mt-2">
|
<ParentNotePreview
|
||||||
<ParentNote event={parentEvent} />
|
event={parentEvent}
|
||||||
</div>
|
className="mt-2"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
push(toNote(parentEvent))
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<Content className="mt-2" event={event} />
|
<Content className="mt-2" event={event} />
|
||||||
{!hideStats && (
|
{!hideStats && (
|
||||||
<NoteStats className="mt-2" event={event} fetchIfNotExisting={fetchNoteStats} />
|
<NoteStats className="mt-4" event={event} fetchIfNotExisting={fetchNoteStats} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ParentNote({ event }: { event: Event }) {
|
|
||||||
const { push } = useSecondaryPage()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="flex space-x-1 items-center text-xs rounded-lg px-2 bg-muted w-fit max-w-full hover:text-foreground cursor-pointer"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
push(toNote(event))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>reply to</div>
|
|
||||||
<UserAvatar userId={event.pubkey} size="tiny" />
|
|
||||||
<div className="truncate">{event.content}</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ export default function RepostNoteCard({ event, className }: { event: Event; cla
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
<div className="flex gap-1 mb-1 pl-4 text-xs items-center text-muted-foreground">
|
<div className="flex gap-1 mb-1 pl-4 text-sm items-center text-muted-foreground">
|
||||||
<Repeat2 size={12} className="shrink-0" />
|
<Repeat2 size={16} className="shrink-0" />
|
||||||
<Username userId={event.pubkey} className="font-semibold truncate" />
|
<Username userId={event.pubkey} className="font-semibold truncate" />
|
||||||
<div>reposted</div>
|
<div>reposted</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export default function NoteList({
|
|||||||
<NoteCard key={`${i}-${event.id}`} className="w-full" event={event} />
|
<NoteCard key={`${i}-${event.id}`} className="w-full" event={event} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center text-xs text-muted-foreground mt-2">
|
<div className="text-center text-sm text-muted-foreground mt-2">
|
||||||
{hasMore ? <div ref={bottomRef}>loading...</div> : 'no more notes'}
|
{hasMore ? <div ref={bottomRef}>loading...</div> : 'no more notes'}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default function LikeButton({
|
|||||||
) : (
|
) : (
|
||||||
<Heart size={16} className={hasLiked ? 'fill-red-400' : ''} />
|
<Heart size={16} className={hasLiked ? 'fill-red-400' : ''} />
|
||||||
)}
|
)}
|
||||||
<div className="text-xs">{formatCount(likeCount)}</div>
|
<div className="text-sm">{formatCount(likeCount)}</div>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function NoteOptions({ event }: { event: Event }) {
|
|||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger>
|
<DropdownMenuTrigger>
|
||||||
<Ellipsis
|
<Ellipsis
|
||||||
size={14}
|
size={16}
|
||||||
className="text-muted-foreground hover:text-foreground cursor-pointer"
|
className="text-muted-foreground hover:text-foreground cursor-pointer"
|
||||||
/>
|
/>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function ReplyButton({ event }: { event: Event }) {
|
|||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
<MessageCircle size={16} />
|
<MessageCircle size={16} />
|
||||||
<div className="text-xs">{formatCount(replyCount)}</div>
|
<div className="text-sm">{formatCount(replyCount)}</div>
|
||||||
</button>
|
</button>
|
||||||
</PostDialog>
|
</PostDialog>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export default function RepostButton({
|
|||||||
title="repost"
|
title="repost"
|
||||||
>
|
>
|
||||||
{reposting ? <Loader className="animate-spin" size={16} /> : <Repeat size={16} />}
|
{reposting ? <Loader className="animate-spin" size={16} /> : <Repeat size={16} />}
|
||||||
<div className="text-xs">{formatCount(repostCount)}</div>
|
<div className="text-sm">{formatCount(repostCount)}</div>
|
||||||
</button>
|
</button>
|
||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
import { useSecondaryPage } from '@renderer/PageManager'
|
|
||||||
import { Card } from '@renderer/components/ui/card'
|
|
||||||
import { toNote } from '@renderer/lib/link'
|
|
||||||
import { Event } from 'nostr-tools'
|
|
||||||
import UserAvatar from '../UserAvatar'
|
|
||||||
import Username from '../Username'
|
|
||||||
|
|
||||||
export default function ParentNote({ event }: { event: Event }) {
|
|
||||||
const { push } = useSecondaryPage()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Card
|
|
||||||
className="flex space-x-1 p-1 items-center hover:bg-muted/50 cursor-pointer text-xs text-muted-foreground hover:text-foreground"
|
|
||||||
onClick={() => push(toNote(event))}
|
|
||||||
>
|
|
||||||
<UserAvatar userId={event.pubkey} size="tiny" />
|
|
||||||
<Username userId={event.pubkey} className="font-semibold" />
|
|
||||||
<div className="truncate">{event.content}</div>
|
|
||||||
</Card>
|
|
||||||
<div className="ml-5 w-px h-2 bg-border" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
27
src/renderer/src/components/ParentNotePreview/index.tsx
Normal file
27
src/renderer/src/components/ParentNotePreview/index.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { Event } from 'nostr-tools'
|
||||||
|
import UserAvatar from '../UserAvatar'
|
||||||
|
import { cn } from '@renderer/lib/utils'
|
||||||
|
|
||||||
|
export default function ParentNotePreview({
|
||||||
|
event,
|
||||||
|
className,
|
||||||
|
onClick
|
||||||
|
}: {
|
||||||
|
event: Event
|
||||||
|
className?: string
|
||||||
|
onClick?: React.MouseEventHandler<HTMLDivElement> | undefined
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex space-x-1 items-center text-sm rounded-full px-2 bg-muted w-fit max-w-full text-muted-foreground hover:text-foreground cursor-pointer',
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<div className="shrink-0">reply to</div>
|
||||||
|
<UserAvatar userId={event.pubkey} size="tiny" />
|
||||||
|
<div className="truncate">{event.content}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import UserAvatar from '../UserAvatar'
|
|||||||
import Username from '../Username'
|
import Username from '../Username'
|
||||||
import LikeButton from '../NoteStats/LikeButton'
|
import LikeButton from '../NoteStats/LikeButton'
|
||||||
import PostDialog from '../PostDialog'
|
import PostDialog from '../PostDialog'
|
||||||
|
import ParentNotePreview from '../ParentNotePreview'
|
||||||
|
|
||||||
export default function ReplyNote({
|
export default function ReplyNote({
|
||||||
event,
|
event,
|
||||||
@@ -22,18 +23,13 @@ export default function ReplyNote({
|
|||||||
className={`flex space-x-2 items-start rounded-lg p-2 transition-colors duration-500 ${highlight ? 'bg-highlight/50' : ''}`}
|
className={`flex space-x-2 items-start rounded-lg p-2 transition-colors duration-500 ${highlight ? 'bg-highlight/50' : ''}`}
|
||||||
>
|
>
|
||||||
<UserAvatar userId={event.pubkey} size="small" className="shrink-0" />
|
<UserAvatar userId={event.pubkey} size="small" className="shrink-0" />
|
||||||
<div className="w-full overflow-hidden">
|
<div className="w-full overflow-hidden space-y-1">
|
||||||
<Username
|
<Username
|
||||||
userId={event.pubkey}
|
userId={event.pubkey}
|
||||||
className="text-sm font-semibold text-muted-foreground hover:text-foreground truncate"
|
className="text-sm font-semibold text-muted-foreground hover:text-foreground truncate"
|
||||||
/>
|
/>
|
||||||
{parentEvent && (
|
{parentEvent && (
|
||||||
<div
|
<ParentNotePreview event={parentEvent} onClick={() => onClickParent(parentEvent.id)} />
|
||||||
className="text-xs text-muted-foreground truncate hover:text-foreground cursor-pointer"
|
|
||||||
onClick={() => onClickParent(parentEvent.id)}
|
|
||||||
>
|
|
||||||
<ParentReplyNote event={parentEvent} />
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
<Content event={event} size="small" />
|
<Content event={event} size="small" />
|
||||||
<div className="flex gap-2 text-xs">
|
<div className="flex gap-2 text-xs">
|
||||||
@@ -47,13 +43,3 @@ export default function ReplyNote({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ParentReplyNote({ event }: { event: Event }) {
|
|
||||||
return (
|
|
||||||
<div className="flex space-x-1 items-center text-xs rounded-lg w-fit px-2 bg-muted max-w-full">
|
|
||||||
<div className="shrink-0">reply to</div>
|
|
||||||
<UserAvatar userId={event.pubkey} size="tiny" />
|
|
||||||
<div className="truncate">{event.content}</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default function ReplyNoteList({ event, className }: { event: Event; clas
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`text-xs text-center my-2 text-muted-foreground ${!loading ? 'hover:text-foreground cursor-pointer' : ''}`}
|
className={`text-sm text-center my-2 text-muted-foreground ${!loading ? 'hover:text-foreground cursor-pointer' : ''}`}
|
||||||
onClick={loadMore}
|
onClick={loadMore}
|
||||||
>
|
>
|
||||||
{loading ? 'loading...' : hasMore ? 'load more older replies' : null}
|
{loading ? 'loading...' : hasMore ? 'load more older replies' : null}
|
||||||
@@ -86,7 +86,7 @@ export default function ReplyNoteList({ event, className }: { event: Event; clas
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
{eventsWithParentIds.length === 0 && !loading && !hasMore && (
|
{eventsWithParentIds.length === 0 && !loading && !hasMore && (
|
||||||
<div className="text-xs text-center text-muted-foreground">no replies</div>
|
<div className="text-sm text-center text-muted-foreground">no replies</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default function PostButton() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PostDialog>
|
<PostDialog>
|
||||||
<Button variant="titlebar" size="titlebar">
|
<Button variant="titlebar" size="titlebar" title="new post">
|
||||||
<PencilLine />
|
<PencilLine />
|
||||||
</Button>
|
</Button>
|
||||||
</PostDialog>
|
</PostDialog>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export function SecondaryPageTitlebar({
|
|||||||
<Titlebar className="justify-between">
|
<Titlebar className="justify-between">
|
||||||
<div className="flex items-center gap-2 flex-1 w-0">
|
<div className="flex items-center gap-2 flex-1 w-0">
|
||||||
<BackButton hide={hideBackButton} />
|
<BackButton hide={hideBackButton} />
|
||||||
<div className="truncate">{content}</div>
|
<div className="truncate text-lg">{content}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0 flex items-center">
|
<div className="flex-shrink-0 flex items-center">
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
import { useSecondaryPage } from '@renderer/PageManager'
|
||||||
import Note from '@renderer/components/Note'
|
import Note from '@renderer/components/Note'
|
||||||
import ParentNote from '@renderer/components/ParentNote'
|
|
||||||
import ReplyNoteList from '@renderer/components/ReplyNoteList'
|
import ReplyNoteList from '@renderer/components/ReplyNoteList'
|
||||||
|
import UserAvatar from '@renderer/components/UserAvatar'
|
||||||
|
import Username from '@renderer/components/Username'
|
||||||
|
import { Card } from '@renderer/components/ui/card'
|
||||||
import { Separator } from '@renderer/components/ui/separator'
|
import { Separator } from '@renderer/components/ui/separator'
|
||||||
import { useFetchEventById } from '@renderer/hooks'
|
import { useFetchEventById } from '@renderer/hooks'
|
||||||
import SecondaryPageLayout from '@renderer/layouts/SecondaryPageLayout'
|
import SecondaryPageLayout from '@renderer/layouts/SecondaryPageLayout'
|
||||||
import { getParentEventId, getRootEventId } from '@renderer/lib/event'
|
import { getParentEventId, getRootEventId } from '@renderer/lib/event'
|
||||||
|
import { toNote } from '@renderer/lib/link'
|
||||||
import { Event } from 'nostr-tools'
|
import { Event } from 'nostr-tools'
|
||||||
|
|
||||||
export default function NotePage({ event }: { event?: Event }) {
|
export default function NotePage({ event }: { event?: Event }) {
|
||||||
@@ -14,12 +18,30 @@ export default function NotePage({ event }: { event?: Event }) {
|
|||||||
if (!event) return null
|
if (!event) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecondaryPageLayout titlebarContent="note">
|
<SecondaryPageLayout titlebarContent="Note">
|
||||||
{rootEvent && <ParentNote key={`root-note-${event.id}`} event={rootEvent} />}
|
{rootEvent && <ParentNote key={`root-note-${event.id}`} event={rootEvent} />}
|
||||||
{parentEvent && <ParentNote key={`parent-note-${event.id}`} event={parentEvent} />}
|
{parentEvent && <ParentNote key={`parent-note-${event.id}`} event={parentEvent} />}
|
||||||
<Note key={`note-${event.id}`} event={event} fetchNoteStats />
|
<Note key={`note-${event.id}`} event={event} fetchNoteStats />
|
||||||
<Separator className="my-2" />
|
<Separator className="my-4" />
|
||||||
<ReplyNoteList key={`reply-note-list-${event.id}`} event={event} />
|
<ReplyNoteList key={`reply-note-list-${event.id}`} event={event} />
|
||||||
</SecondaryPageLayout>
|
</SecondaryPageLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ParentNote({ event }: { event: Event }) {
|
||||||
|
const { push } = useSecondaryPage()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Card
|
||||||
|
className="flex space-x-1 p-1 items-center hover:bg-muted/50 cursor-pointer text-sm text-muted-foreground hover:text-foreground"
|
||||||
|
onClick={() => push(toNote(event))}
|
||||||
|
>
|
||||||
|
<UserAvatar userId={event.pubkey} size="tiny" />
|
||||||
|
<Username userId={event.pubkey} className="font-semibold" />
|
||||||
|
<div className="truncate">{event.content}</div>
|
||||||
|
</Card>
|
||||||
|
<div className="ml-5 w-px h-2 bg-border" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default function ProfilePage({ pubkey }: { pubkey?: string }) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm text-wrap break-words whitespace-pre-wrap">
|
<div className="text-wrap break-words whitespace-pre-wrap">
|
||||||
<ProfileAbout about={about} />
|
<ProfileAbout about={about} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user