feat(web): render smart timestamps and attachment-aware previews in DM sidebar
This commit is contained in:
@@ -17,6 +17,7 @@ import { wsSend } from '../../hooks/useWebSocket';
|
|||||||
import { AudioManager } from '../../audio/AudioManager';
|
import { AudioManager } from '../../audio/AudioManager';
|
||||||
import { hasPermissionBit, PermissionBits } from '../../utils/permissions';
|
import { hasPermissionBit, PermissionBits } from '../../utils/permissions';
|
||||||
import { parseFederatedUsername, isSelf } from '../../utils/identity';
|
import { parseFederatedUsername, isSelf } from '../../utils/identity';
|
||||||
|
import { formatDmTimestamp, formatDmPreview } from '../../utils/dmFormatters';
|
||||||
import { joinVoiceChannel, broadcastVoiceStatus, broadcastDeafenViaLiveKit } from '../../utils/voice';
|
import { joinVoiceChannel, broadcastVoiceStatus, broadcastDeafenViaLiveKit } from '../../utils/voice';
|
||||||
import { useContextMenuStore, type ContextMenuItem } from '../../stores/contextMenuStore';
|
import { useContextMenuStore, type ContextMenuItem } from '../../stores/contextMenuStore';
|
||||||
import { ConfirmDialog } from '../ui/ConfirmDialog';
|
import { ConfirmDialog } from '../ui/ConfirmDialog';
|
||||||
@@ -554,16 +555,37 @@ export function ChannelSidebar() {
|
|||||||
</svg>
|
</svg>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
|
{dm.lastMessage && (
|
||||||
|
<span className="text-[11px] text-txt-tertiary ml-auto flex-shrink-0">
|
||||||
|
{formatDmTimestamp(dm.lastMessage.createdAt)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{isGroup ? (
|
{(() => {
|
||||||
|
const preview = formatDmPreview(dm.lastMessage ?? null);
|
||||||
|
if (isGroup) {
|
||||||
|
const lastMsg = dm.lastMessage;
|
||||||
|
const senderName = (lastMsg && 'user' in lastMsg ? lastMsg.user?.displayName : undefined)
|
||||||
|
?? dm.members.find(m => m.id === lastMsg?.userId)?.displayName
|
||||||
|
?? 'Unknown';
|
||||||
|
const groupPreview = preview
|
||||||
|
? `${senderName}: ${preview}`
|
||||||
|
: `${dm.members.length} Members`;
|
||||||
|
return (
|
||||||
<div className="text-[12px] text-txt-tertiary truncate leading-tight mt-0.5">
|
<div className="text-[12px] text-txt-tertiary truncate leading-tight mt-0.5">
|
||||||
{dm.members.length} Members
|
{groupPreview}
|
||||||
</div>
|
</div>
|
||||||
) : dm.lastMessage ? (
|
);
|
||||||
|
}
|
||||||
|
if (preview) {
|
||||||
|
return (
|
||||||
<div className="text-[12px] text-txt-tertiary truncate leading-tight mt-0.5">
|
<div className="text-[12px] text-txt-tertiary truncate leading-tight mt-0.5">
|
||||||
{dm.lastMessage.content}
|
{preview}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user