Миграции, сборка
This commit is contained in:
@@ -95,7 +95,14 @@ export interface Message {
|
||||
isDeleted?: boolean;
|
||||
quote?: string | null;
|
||||
media?: MediaItem[];
|
||||
sender: { id: string; username: string; displayName: string };
|
||||
sender: {
|
||||
id: string;
|
||||
username: string;
|
||||
userName?: string;
|
||||
displayName: string;
|
||||
avatar?: string | null;
|
||||
avatarUrl?: string | null;
|
||||
};
|
||||
} | null;
|
||||
forwardedFrom?: UserBasic | null;
|
||||
media: MediaItem[];
|
||||
|
||||
@@ -135,7 +135,7 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
|
||||
onClose();
|
||||
};
|
||||
|
||||
const initials = (user?.displayName || user?.username || '??')
|
||||
const initials = (user?.displayName || user?.userName || user?.username || '??')
|
||||
.split(' ')
|
||||
.map((w: string) => w[0])
|
||||
.join('')
|
||||
@@ -193,11 +193,11 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
|
||||
</div>
|
||||
{/* Name & username */}
|
||||
<h3 className="text-xl font-bold text-transparent bg-clip-text bg-gradient-to-b from-white to-white/70 tracking-tight leading-tight">
|
||||
{user?.displayName || user?.username}
|
||||
{user?.displayName || user?.userName || user?.username || ''}
|
||||
</h3>
|
||||
<div className="flex items-center gap-1.5 mt-1.5">
|
||||
<AtSign size={12} className="text-knot-400" />
|
||||
<span className="text-sm font-medium text-knot-100/70">{user?.username}</span>
|
||||
<span className="text-sm font-medium text-knot-100/70">{user?.userName || user?.username || ''}</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Bottom fade line */}
|
||||
@@ -526,8 +526,8 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm font-medium text-white truncate">{u.displayName || u.username}</p>
|
||||
<p className="text-xs text-zinc-500">@{u.username}</p>
|
||||
<p className="text-sm font-medium text-white truncate">{u.displayName || u.userName || u.username || ''}</p>
|
||||
<p className="text-xs text-zinc-500">@{u.userName || u.username || ''}</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => handleSendFriendRequest(u.id)}
|
||||
@@ -561,8 +561,8 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm font-medium text-white truncate">{req.user.displayName || req.user.username}</p>
|
||||
<p className="text-xs text-zinc-500">@{req.user.username}</p>
|
||||
<p className="text-sm font-medium text-white truncate">{req.user.displayName || req.user.userName || req.user.username || ''}</p>
|
||||
<p className="text-xs text-zinc-500">@{req.user.userName || req.user.username || ''}</p>
|
||||
</div>
|
||||
<div className="flex gap-1.5">
|
||||
<button
|
||||
@@ -610,9 +610,9 @@ export default function SideMenu({ isOpen, onClose, onOpenProfile }: SideMenuPro
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm font-medium text-white truncate">{friend.displayName || friend.username}</p>
|
||||
<p className="text-sm font-medium text-white truncate">{friend.displayName || friend.userName || friend.username || ''}</p>
|
||||
<p className="text-xs text-zinc-500">
|
||||
{friend.isOnline ? t('online') : `@${friend.username}`}
|
||||
{friend.isOnline ? t('online') : `@${friend.userName || friend.username || ''}`}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -74,7 +74,7 @@ export default function Sidebar() {
|
||||
(m) =>
|
||||
m.user.id !== user?.id &&
|
||||
((m.user.username || m.user.userName || '').toLowerCase().includes(q) ||
|
||||
m.user.displayName.toLowerCase().includes(q))
|
||||
(m.user.displayName || '').toLowerCase().includes(q))
|
||||
);
|
||||
}).sort((a, b) => {
|
||||
// 1. Favorites chat always on top
|
||||
@@ -82,8 +82,8 @@ export default function Sidebar() {
|
||||
if (b.type === 'favorites') return 1;
|
||||
|
||||
// 2. Pinned chats next
|
||||
const aPinned = a.members.find(m => m.user.id === user?.id)?.isPinned;
|
||||
const bPinned = b.members.find(m => m.user.id === user?.id)?.isPinned;
|
||||
const aPinned = a.members.find(m => m.user.id === user?.id)?.isPinned ?? false;
|
||||
const bPinned = b.members.find(m => m.user.id === user?.id)?.isPinned ?? false;
|
||||
if (aPinned && !bPinned) return -1;
|
||||
if (!aPinned && bPinned) return 1;
|
||||
|
||||
@@ -182,13 +182,13 @@ export default function Sidebar() {
|
||||
<div className="w-[44px] h-[44px] rounded-full flex items-center justify-center overflow-hidden">
|
||||
<Avatar
|
||||
src={avatarUrl}
|
||||
name={group.user.displayName || group.user.username}
|
||||
name={group.user.displayName || group.user.userName || group.user.username || '?'}
|
||||
size="md"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-[11px] text-zinc-400 truncate w-full text-center">
|
||||
{isMine ? t('myStory') : (group.user.displayName || group.user.userName || group.user.username || '').split(' ')[0]}
|
||||
{isMine ? t('myStory') : (group.user.displayName || group.user.userName || group.user.username || '?').split(' ')[0]}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
@@ -218,7 +218,7 @@ export default function Sidebar() {
|
||||
{showNewChat && <NewChatModal onClose={() => setShowNewChat(false)} />}
|
||||
</AnimatePresence>
|
||||
<AnimatePresence>
|
||||
{showProfile && <UserProfile userId={user!.id} onClose={() => setShowProfile(false)} isSelf />}
|
||||
{showProfile && user && <UserProfile userId={user.id} onClose={() => setShowProfile(false)} isSelf />}
|
||||
</AnimatePresence>
|
||||
<SideMenu
|
||||
isOpen={showSideMenu}
|
||||
|
||||
Reference in New Issue
Block a user