фикс счетчиков
This commit is contained in:
parent
d4c869a82c
commit
a14997b84c
25
src/App.vue
25
src/App.vue
@ -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();
|
||||
|
@ -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,8 +68,18 @@
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
<div class="conversation-arrow">
|
||||
<i class="bi-chevron-right"></i>
|
||||
|
||||
<!-- 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>
|
||||
@ -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>
|
Loading…
x
Reference in New Issue
Block a user