фикс <был недавно>

This commit is contained in:
max
2026-04-17 22:24:09 +03:00
parent c8b0384392
commit bccbf12a11
2 changed files with 33 additions and 6 deletions

View File

@@ -13,7 +13,7 @@ import Avatar from '../../../../core/presentation/components/ui/Avatar';
import type { Chat } from '../../../../core/domain/types';
import { UserApi } from '../../../users/infrastructure/userApi';
const userStatusCache = new Map<string, { emoji?: string | null; text?: string | null }>();
const userStatusCache = new Map<string, { emoji?: string | null; text?: string | null; isInvisible?: boolean }>();
interface ChatListItemProps {
chat: Chat;
@@ -27,7 +27,7 @@ function ChatListItem({ chat, isActive }: ChatListItemProps) {
const [ctxMenu, setCtxMenu] = useState<{ x: number; y: number } | null>(null);
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
const [otherUserStatus, setOtherUserStatus] = useState<{ emoji?: string | null; text?: string | null } | null>(null);
const [otherUserStatus, setOtherUserStatus] = useState<{ emoji?: string | null; text?: string | null; isInvisible?: boolean } | null>(null);
const ctxRef = useRef<HTMLDivElement>(null);
const myMember = chat.members.find((m) => m.user.id === user?.id);
@@ -49,7 +49,7 @@ function ChatListItem({ chat, isActive }: ChatListItemProps) {
? otherMember?.user.avatarUrl || otherMember?.user.avatar || null
: chat.avatarUrl || chat.avatar || null;
const isOnline = chat.type === 'personal' && !user?.isInvisible && !!otherMember?.user.isOnline;
const isOnline = chat.type === 'personal' && !user?.isInvisible && !otherUserStatus?.isInvisible && !!otherMember?.user.isOnline;
// Check if someone is typing in this chat
const typingInChat = typingUsers.filter((t) => t.chatId === chat.id && t.userId !== user?.id);
@@ -108,7 +108,7 @@ function ChatListItem({ chat, isActive }: ChatListItemProps) {
UserApi.getUser(otherId)
.then((profile) => {
if (cancelled) return;
const status = { emoji: profile.statusEmoji, text: profile.statusText };
const status = { emoji: profile.statusEmoji, text: profile.statusText, isInvisible: !!profile.isInvisible };
userStatusCache.set(otherId, status);
setOtherUserStatus(status);
})

View File

@@ -24,6 +24,7 @@ import { useChatStore } from '../../application/chatStore';
import { httpClient } from '../../../../core/infrastructure/httpClient';
import { useAuthStore } from '../../../auth/application/authStore';
import { ChatApi } from '../../infrastructure/chatApi';
import { UserApi } from '../../../users/infrastructure/userApi';
import { getSocket } from '../../../../core/infrastructure/socket';
import { isChatMuted, toggleMuteChat } from '../../../../core/utils/sounds';
import { useLang } from '../../../../core/infrastructure/i18n';
@@ -75,6 +76,7 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
const [confirmAction, setConfirmAction] = useState<{ message: string; action: () => void } | null>(null);
const [scrollReady, setScrollReady] = useState(false);
const [activeGroupCallParticipants, setActiveGroupCallParticipants] = useState<string[]>([]);
const [otherUserInvisible, setOtherUserInvisible] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
const scrollContainerRef = useRef<HTMLDivElement>(null);
@@ -182,6 +184,31 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
: chat?.avatarUrl || chat?.avatar || null;
const isOnline = chat?.type === 'personal' && otherMember?.user.isOnline;
const privacyExchangeMode = !!user?.isInvisible;
const shouldMaskOtherUserPresence = privacyExchangeMode || otherUserInvisible;
useEffect(() => {
if (chat?.type !== 'personal' || !otherMember?.user.id) {
setOtherUserInvisible(false);
return;
}
let cancelled = false;
UserApi.getUser(otherMember.user.id)
.then((profile) => {
if (!cancelled) {
setOtherUserInvisible(!!profile.isInvisible);
}
})
.catch(() => {
if (!cancelled) {
setOtherUserInvisible(false);
}
});
return () => {
cancelled = true;
};
}, [chat?.type, otherMember?.user.id]);
const typingInChat = typingUsers.filter((t) => t.chatId === activeChat && t.userId !== user?.id);
@@ -846,7 +873,7 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
src={chatAvatar}
name={chatName}
size="md"
online={isOnline ? true : undefined}
online={!shouldMaskOtherUserPresence && isOnline ? true : undefined}
className="avatar-knot-container group-hover:border-primary/30"
/>
)}
@@ -860,7 +887,7 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
? <span className="text-primary font-black animate-pulse">{t('typing')}</span>
: isOnline
? <span className="text-success">{t('online')}</span>
: chat.type === 'personal' && privacyExchangeMode
: chat.type === 'personal' && shouldMaskOtherUserPresence
? t('wasRecently')
: chat.type === 'personal' && otherMember?.user.lastSeen
? `${formatLastSeen(otherMember.user.lastSeen, lang)}`