@ -91,12 +91,13 @@ const MemoCommentMessage = observer(({ notification }: Props) => {
if ( ! initialized && ! hasError ) {
return (
< div className = "w-full px- 4 py-3.5 border-b border-border last:border-b-0 bg-muted/2 0 animate-pulse">
< div className = "w-full px- 5 py-4 border-b border-border/60 last:border-b-0 bg-muted/1 0 animate-pulse">
< div className = "flex items-start gap-3" >
< div className = "w-9 h-9 rounded-full bg-muted/60 shrink-0" / >
< div className = "flex-1 space-y-2.5" >
< div className = "h-3.5 bg-muted/60 rounded w-2/5" / >
< div className = "h-16 bg-muted/40 rounded-md" / >
< div className = "w-10 h-10 rounded-full bg-muted/50 shrink-0" / >
< div className = "flex-1 space-y-3" >
< div className = "h-4 bg-muted/50 rounded-md w-2/5" / >
< div className = "h-3 bg-muted/40 rounded-md w-3/4" / >
< div className = "h-20 bg-muted/30 rounded-xl" / >
< / div >
< / div >
< / div >
@ -105,20 +106,20 @@ const MemoCommentMessage = observer(({ notification }: Props) => {
if ( hasError ) {
return (
< div className = "w-full px- 4 py-3.5 border-b border-border last:border-b-0 bg-destructive/[0.03] ">
< div className = "w-full px- 5 py-4 border-b border-border/60 last:border-b-0 bg-destructive/[0.04] group ">
< div className = "flex items-center justify-between" >
< div className = "flex items-center gap-3" >
< div className = "w- 9 h-9 rounded-full bg-destructive/10 flex items-center justify-center shrink- 0">
< XIcon className = "w- 4 h-4 text-destructive" / >
< div className = "w- 10 h-10 rounded-full bg-destructive/15 flex items-center justify-center shrink-0 ring-1 ring-destructive/2 0">
< XIcon className = "w- 5 h-5 text-destructive" strokeWidth = { 2 } / >
< / div >
< span className = "text-sm text-destructive/ 90 "> { t ( "inbox.failed-to-load" ) } < / span >
< span className = "text-sm text-destructive/ 80 font-medium "> { t ( "inbox.failed-to-load" ) } < / span >
< / div >
< button
onClick = { handleDeleteMessage }
className = "p-1.5 hover:bg-destructive/1 0 rounded-md transition-colors "
className = "p-1.5 hover:bg-destructive/1 5 rounded-lg transition-all duration-150 opacity-0 group-hover:opacity-100 "
title = { t ( "common.delete" ) }
>
< TrashIcon className = "w- 3.5 h-3.5 text-destructive/70 hover:text-destructive" / >
< TrashIcon className = "w- 4 h-4 text-destructive/70 hover:text-destructive transition-colors" strokeWidth = { 2 } / >
< / button >
< / div >
< / div >
@ -130,71 +131,86 @@ const MemoCommentMessage = observer(({ notification }: Props) => {
return (
< div
className = { cn (
"w-full px- 4 py-3.5 border-b border-border last:border-b-0 transition-colors group relative",
isUnread ? "bg-primary/[0.0 2] hover:bg-primary/[0.04]" : "hover:bg-muted/4 0",
"w-full px- 5 py-4 border-b border-border/60 last:border-b-0 transition-all duration-200 group relative",
isUnread ? "bg-primary/[0.0 3] hover:bg-primary/[0.05]" : "hover:bg-muted/3 0",
) }
>
{ /* Unread indicator bar */ }
{ isUnread && < div className = "absolute left-0 top-0 bottom-0 w- 1 bg-primary " / > }
{ isUnread && < div className = "absolute left-0 top-0 bottom-0 w- 0.5 bg-gradient-to-b from-primary to-primary/60 " / > }
< div className = "flex items-start gap-3" >
{ /* Avatar & Icon */ }
< div className = "relative shrink-0 mt-0.5 ">
< UserAvatar className = "w- 9 h-9 " avatarUrl = { sender ? . avatarUrl } / >
< div className = "relative shrink-0 ">
< UserAvatar className = "w- 10 h-10 ring-1 ring-border/40 " avatarUrl = { sender ? . avatarUrl } / >
< div
className = { cn (
"absolute -bottom- 0.5 -right-0.5 w-[18px] h-[18px] rounded-full border-[2px] border-background flex items-center justify-center shadow-sm ",
isUnread ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground",
"absolute -bottom- 1 -right-1 w-5 h-5 rounded-full border-2 border-background flex items-center justify-center shadow-md transition-all ",
isUnread ? "bg-primary text-primary-foreground" : "bg-muted /80 text-muted-foreground",
) }
>
< MessageCircleIcon className = "w-2.5 h-2.5" / >
< MessageCircleIcon className = "w-2.5 h-2.5" strokeWidth = { 2.5 } / >
< / div >
< / div >
{ /* Content */ }
< div className = "flex-1 min-w-0" >
{ /* Header */ }
< div className = "flex items- start justify-between gap-2 ">
< div className = "flex -1 min-w-0 flex items-baseline gap-1.5 flex-wrap ">
< span className = "font-semibold text-sm text-foreground "> { sender ? . displayName || sender ? . username } < / span >
< span className = "text-sm text-muted-foreground "> commented on your memo < / span >
< span className = "text-xs text-muted-foreground/ 8 0">
· { notification . createTime ? . toLocaleDateString ( [ ] , { month : "short" , day : "numeric" } ) } at { " " }
< div className = "flex items- center justify-between gap-3 mb-1 ">
< div className = "flex items-center gap-1.5 flex-wrap min-w-0 ">
< span className = "font-semibold text-sm text-foreground /95 "> { sender ? . displayName || sender ? . username } < / span >
< span className = "text-sm text-muted-foreground /80 "> commented on your memo < / span >
< span className = "text-xs text-muted-foreground/ 6 0">
{ notification . createTime ? . toLocaleDateString ( [ ] , { month : "short" , day : "numeric" } ) } at { " " }
{ notification . createTime ? . toLocaleTimeString ( [ ] , { hour : "2-digit" , minute : "2-digit" } ) }
< / span >
< / div >
< div className = "flex items-center gap- 0.5 shrink-0">
< div className = "flex items-center gap- 1 shrink-0">
{ isUnread ? (
< button
onClick = { ( ) = > handleArchiveMessage ( ) }
className = "p-1.5 hover:bg- background/80 rounded-md transition-all opacity-0 group-hover:opacity-100"
className = "p-1.5 hover:bg- primary/10 rounded-lg transition-all duration-150 opacity-0 group-hover:opacity-100"
title = { t ( "common.archive" ) }
>
< CheckIcon className = "w- 3.5 h-3.5 text-muted-foreground hover:text-primary" / >
< CheckIcon className = "w- 4 h-4 text-muted-foreground hover:text-primary transition-colors" strokeWidth = { 2 } / >
< / button >
) : (
< button
onClick = { handleDeleteMessage }
className = "p-1.5 hover:bg- background/80 rounded-md transition-all opacity-0 group-hover:opacity-100"
className = "p-1.5 hover:bg- destructive/10 rounded-lg transition-all duration-150 opacity-0 group-hover:opacity-100"
title = { t ( "common.delete" ) }
>
< TrashIcon className = "w- 3.5 h-3.5 text-muted-foreground hover:text-destructive" / >
< TrashIcon className = "w- 4 h-4 text-muted-foreground hover:text-destructive transition-colors" strokeWidth = { 2 } / >
< / button >
) }
< / div >
< / div >
{ /* Original Memo Snippet */ }
{ relatedMemo && (
< div className = "pl-3 border-l-2 border-muted-foreground/20 mb-3" >
< p className = "text-sm text-foreground/60 line-clamp-1 leading-relaxed" >
< span className = "text-xs text-muted-foreground/50 font-medium mr-2 uppercase tracking-wide" > Original : < / span >
{ relatedMemo . content || < span className = "italic text-muted-foreground/40" > Empty memo < / span > }
< / p >
< / div >
) }
{ /* Comment Preview */ }
{ commentMemo && (
< div
onClick = { handleNavigateToMemo }
className = "mt-2 p-3 rounded-md bg-muted/40 hover:bg-muted/60 cursor-pointer border border-border/50 hover:border-border transition-all group/comment"
className = " p-2 sm:p-3 rounded-lg bg-gradient-to-br from-primary/[0.06] to-primary/[0.03] hover:from-primary/[0.1] hover:to-primary/[0.06] cursor-pointer border border-primary/30 hover:border-primary/50 transition-all duration-200 group/comment shadow-sm hover:shadow "
>
< div className = "flex items-start gap-2" >
< MessageCircleIcon className = "w-3.5 h-3.5 text-muted-foreground/60 shrink-0 mt-0.5" / >
< p className = "text-[13px] text-foreground/90 line-clamp-2 leading-relaxed group-hover/comment:text-foreground transition-colors" >
{ commentMemo . content || < span className = "italic text-muted-foreground" > Empty comment < / span > }
< / p >
< div className = "w-5 h-5 flex items-center justify-center shrink-0" >
< MessageCircleIcon className = "w-4 h-4 text-primary" / >
< / div >
< div className = "flex-1 min-w-0" >
< p className = "text-xs text-primary/60 font-semibold mb-1 uppercase tracking-wider" > Comment < / p >
< p className = "text-sm text-foreground/90 line-clamp-2" >
{ commentMemo . content || < span className = "italic text-muted-foreground/50" > Empty comment < / span > }
< / p >
< / div >
< / div >
< / div >
) }