diff --git a/src/handlers/p2p_chat.py b/src/handlers/p2p_chat.py index d10bfc5..0423b58 100644 --- a/src/handlers/p2p_chat.py +++ b/src/handlers/p2p_chat.py @@ -30,6 +30,31 @@ def is_admin(user_id: int) -> bool: return user_id in ADMIN_IDS +def format_sender_name(user: User, is_current_user: bool = False, current_user_is_admin: bool = False) -> str: + """ + Форматирует имя отправителя для отображения в чате + + Args: + user: Объект пользователя + is_current_user: Текущий ли это пользователь + current_user_is_admin: Админ ли текущий пользователь + + Returns: + Отформатированное имя + """ + if is_current_user: + return "🔵 Вы" + + # Формируем базовое имя + name = f"@{user.username}" if user.username else user.first_name or "Unknown" + + # Добавляем информацию о карте если пользователь админ и у собеседника есть карта + if current_user_is_admin and user.club_card_number: + name += f" (карта: {user.club_card_number})" + + return f"🔵 {name}" + + @router.message(CaseInsensitiveCommand("chat")) async def show_chat_menu(message: Message, state: FSMContext): """ @@ -169,7 +194,11 @@ async def start_conversation(callback: CallbackQuery, state: FSMContext): if messages: text += "📝 Последние сообщения:\n\n" for msg in reversed(messages[-5:]): # Последние 5 сообщений - sender_name = "Вы" if msg.sender_id == sender.id else recipient_name + # Определяем имя отправителя + is_current = msg.sender_id == sender.id + user_for_display = sender if is_current else recipient + sender_name = format_sender_name(user_for_display, is_current, is_admin(sender.telegram_id)) + msg_text = msg.text[:50] + "..." if msg.text and len(msg.text) > 50 else (msg.text or f"[{msg.message_type}]") text += f"• {sender_name}: {msg_text}\n" text += "\n" @@ -234,7 +263,11 @@ async def show_conversations(callback: CallbackQuery): callback_data=f"p2p:user:{peer.id}" )]) - text += f"{icon} {peer_name}\n" + text += f"{icon} {peer_name}" + # Показываем номер карты если есть + if peer.club_card_number: + text += f" (карта: {peer.club_card_number})" + text += "\n" text += f" {preview}\n" if unread > 0: text += f" 📨 Непрочитанных: {unread}\n" @@ -268,12 +301,53 @@ async def end_conversation(callback: CallbackQuery, state: FSMContext): async def back_to_menu(callback: CallbackQuery, state: FSMContext): """Вернуться в главное меню""" await callback.answer() + await state.clear() - # Имитируем команду /chat - fake_message = callback.message - fake_message.from_user = callback.from_user + async with async_session_maker() as session: + user = await UserService.get_or_create_user( + session, + callback.from_user.id, + username=callback.from_user.username, + first_name=callback.from_user.first_name, + last_name=callback.from_user.last_name + ) + + if not user: + await callback.message.edit_text("❌ Вы не зарегистрированы. Используйте /start") + return + + # Получаем количество непрочитанных сообщений + unread_count = await P2PMessageService.get_unread_count(session, user.id) + + # Получаем последние диалоги + recent = await P2PMessageService.get_recent_conversations(session, user.id, limit=5) - await show_chat_menu(fake_message, state) + text = "💬 Чат\n\n" + + if unread_count > 0: + text += f"📨 У вас {unread_count} непрочитанных сообщений\n\n" + + text += "Выберите действие:" + + buttons = [ + [InlineKeyboardButton( + text="✉️ Написать пользователю", + callback_data="p2p:select_user" + )], + [InlineKeyboardButton( + text="📋 Мои диалоги", + callback_data="p2p:my_conversations" + )] + ] + + if recent: + text += "\n\nПоследние диалоги:\n" + for peer, last_msg, unread in recent: + unread_badge = f" ({unread})" if unread > 0 else "" + text += f" • @{peer.username or peer.first_name}{unread_badge}\n" + + kb = InlineKeyboardMarkup(inline_keyboard=buttons) + await callback.message.edit_text(text, reply_markup=kb, parse_mode="HTML") # Обработчик сообщений в состоянии chatting