фикс счетчиков

This commit is contained in:
Professional 2025-05-24 23:52:52 +07:00
parent d4c869a82c
commit a14997b84c
2 changed files with 164 additions and 128 deletions

View File

@ -39,10 +39,12 @@
<script setup>
import { useAuth } from '@/auth';
import { ref, watch, onMounted, computed, onUnmounted } from 'vue';
import { useRoute } from 'vue-router';
import api from '@/services/api';
import { getSocket, connectSocket } from '@/services/socketService';
const { user, isAuthenticated, logout, fetchUser } = useAuth();
const route = useRoute();
// Используем локальные переменные для отслеживания состояния
const userData = ref(null);
@ -83,15 +85,26 @@ const handleNewMessage = (message) => {
// Обработчик прочитанных сообщений
const handleMessagesRead = ({ conversationId, readerId }) => {
console.log('[App] Получено событие messagesRead:', { conversationId, readerId, currentUserId: user.value?._id });
// Если текущий пользователь прочитал сообщения
if (readerId === user.value?._id) {
const conversation = conversations.value.find(c => c._id === conversationId);
if (conversation) {
console.log('[App] Сбрасываем счетчик для диалога:', conversationId);
conversation.unreadCount = 0;
}
}
};
// Дополнительный обработчик для синхронизации при переходе в чат
const handleRouteChange = () => {
// Обновляем данные диалогов при изменении маршрута
if (isAuthenticated.value) {
fetchConversations();
}
};
// Обновляем локальные переменные при изменении состояния аутентификации
watch(() => isAuthenticated.value, (newVal) => {
console.log('[App] isAuthenticated изменился:', newVal);
@ -109,6 +122,18 @@ watch(() => user.value, (newVal) => {
userData.value = newVal;
});
// Следим за изменением маршрута для обновления счетчика
watch(() => route.path, (newPath, oldPath) => {
console.log('[App] Маршрут изменился:', { from: oldPath, to: newPath });
// Если переходим в чат или возвращаемся из чата, обновляем счетчики
if (newPath.startsWith('/chat/') || oldPath?.startsWith('/chat/')) {
setTimeout(() => {
fetchConversations();
}, 500); // Небольшая задержка для завершения операций чтения
}
});
// Настройка сокет-соединения
const setupSocketConnection = () => {
socket = getSocket();

View File

@ -46,12 +46,6 @@
<div v-else class="user-photo-placeholder">
<i class="bi-person"></i>
</div>
<span
v-if="conversation.unreadCount > 0"
class="unread-badge"
>
{{ conversation.unreadCount < 100 ? conversation.unreadCount : '99+' }}
</span>
</div>
<!-- Conversation Info -->
@ -74,9 +68,19 @@
</template>
</p>
</div>
<!-- Right side: Unread badge and arrow -->
<div class="conversation-right">
<span
v-if="conversation.unreadCount > 0"
class="unread-badge"
>
{{ conversation.unreadCount < 100 ? conversation.unreadCount : '99+' }}
</span>
<div class="conversation-arrow">
<i class="bi-chevron-right"></i>
</div>
</div>
</router-link>
</div>
</div>
@ -505,28 +509,82 @@ const getDialogsCountText = (count) => {
font-size: 1.5rem;
}
/* Индикатор непрочитанных сообщений */
.unread-badge {
position: absolute;
top: -2px;
right: -2px;
/* Правая часть диалога с счетчиком и стрелкой */
.conversation-right {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
flex-shrink: 0;
}
/* Индикатор непрочитанных сообщений - теперь в правой части */
.conversation-right .unread-badge {
position: static;
background: linear-gradient(135deg, #ff6b6b, #ff5252);
color: white;
font-size: 0.65rem;
font-weight: 700;
border-radius: 10px;
min-width: 20px;
height: 20px;
border-radius: 12px;
min-width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 6px;
padding: 0 8px;
box-shadow: 0 3px 8px rgba(255, 107, 107, 0.4);
border: 2px solid white;
z-index: 2;
animation: subtle-pulse 2s ease-in-out infinite;
}
/* Стрелка для перехода в диалог */
.conversation-arrow {
display: flex;
align-items: center;
color: #adb5bd;
transition: transform 0.2s ease;
}
.conversation-card:active .conversation-arrow {
transform: translateX(2px);
color: #667eea;
}
/* Неавторизованное состояние */
.not-authenticated-section {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
}
.not-auth-card {
background: white;
border-radius: 20px;
padding: 2rem;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
max-width: 400px;
width: 100%;
}
.not-auth-card i {
font-size: 3rem;
margin-bottom: 1rem;
color: #6c757d;
}
.not-auth-card h3 {
color: #343a40;
margin-bottom: 0.5rem;
}
.not-auth-card p {
margin-bottom: 1.5rem;
color: #6c757d;
}
/* Мягкая анимация пульсации для непрочитанных сообщений */
@keyframes subtle-pulse {
0%, 100% {
@ -545,6 +603,69 @@ const getDialogsCountText = (count) => {
min-width: 0; /* Для корректной работы text-overflow */
}
/* Адаптивные стили */
@media (max-width: 576px) {
.conversation-card {
padding: 0.7rem;
}
.user-photo-container {
width: 45px;
height: 45px;
}
.user-name {
font-size: 0.95rem;
}
.last-message {
font-size: 0.8rem;
}
}
@media (max-width: 375px) {
.conversation-card {
padding: 0.6rem;
}
.user-photo-container {
width: 40px;
height: 40px;
}
.user-photo-placeholder i {
font-size: 1.3rem;
}
}
/* Ландшафтная ориентация */
@media (max-height: 450px) and (orientation: landscape) {
.chatlist-header {
height: 46px;
padding: 0.5rem 0;
}
.section-title {
font-size: 1.1rem;
}
.conversations-container {
padding: 0.3rem;
}
.conversation-card {
padding: 0.5rem 0.7rem;
}
}
/* Учитываем Safe Area для iPhone X+ */
@supports (padding-bottom: env(safe-area-inset-bottom)) {
.conversations-list {
padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
}
}
/* Стили для элементов диалога, которые были в старой структуре */
.conversation-header {
display: flex;
justify-content: space-between;
@ -612,114 +733,4 @@ const getDialogsCountText = (count) => {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-3px); }
}
/* Стрелка для перехода в диалог */
.conversation-arrow {
display: flex;
align-items: center;
color: #adb5bd;
transition: transform 0.2s ease;
}
.conversation-card:active .conversation-arrow {
transform: translateX(2px);
color: #667eea;
}
/* Неавторизованное состояние */
.not-authenticated-section {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
}
.not-auth-card {
background: white;
border-radius: 20px;
padding: 2rem;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
max-width: 400px;
width: 100%;
}
.not-auth-card i {
font-size: 3rem;
margin-bottom: 1rem;
color: #6c757d;
}
.not-auth-card h3 {
color: #343a40;
margin-bottom: 0.5rem;
}
.not-auth-card p {
margin-bottom: 1.5rem;
color: #6c757d;
}
/* Адаптивные стили */
@media (max-width: 576px) {
.conversation-card {
padding: 0.7rem;
}
.user-photo-container {
width: 45px;
height: 45px;
}
.user-name {
font-size: 0.95rem;
}
.last-message {
font-size: 0.8rem;
}
}
@media (max-width: 375px) {
.conversation-card {
padding: 0.6rem;
}
.user-photo-container {
width: 40px;
height: 40px;
}
.user-photo-placeholder i {
font-size: 1.3rem;
}
}
/* Ландшафтная ориентация */
@media (max-height: 450px) and (orientation: landscape) {
.chatlist-header {
height: 46px;
padding: 0.5rem 0;
}
.section-title {
font-size: 1.1rem;
}
.conversations-container {
padding: 0.3rem;
}
.conversation-card {
padding: 0.5rem 0.7rem;
}
}
/* Учитываем Safe Area для iPhone X+ */
@supports (padding-bottom: env(safe-area-inset-bottom)) {
.conversations-list {
padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
}
}
</style>