Tg with Notifications, bags fixxed (Removed)
This commit is contained in:
@@ -1,134 +0,0 @@
|
||||
# Улучшения игры - Полный список
|
||||
|
||||
## 🆕 Новые функции
|
||||
|
||||
### 1. Уведомления о сообщениях в Telegram
|
||||
- **Описание**: Показываются уведомления о новых сообщениях, когда Telegram не открыт
|
||||
- **Как работает**:
|
||||
- WebSocket событие `newMessage` обрабатывается на клиенте
|
||||
- Уведомление появляется в правом верхнем углу экрана
|
||||
- Автоматически исчезает через 5 секунд
|
||||
- Анимированное появление и исчезновение
|
||||
- **Файлы**: `src/Game.js` - добавлена функция `showMessageNotification()`
|
||||
|
||||
### 2. Уведомления о перезагрузке сервера
|
||||
- **Описание**: Игроки получают предупреждение о перезагрузке сервера
|
||||
- **Как работает**:
|
||||
- Сервер отправляет событие `serverRestart` всем клиентам
|
||||
- Показывается красное уведомление с обратным отсчетом
|
||||
- Сервер корректно завершает работу через 5 секунд
|
||||
- **Файлы**:
|
||||
- `server.js` - добавлена функция `gracefulShutdown()`
|
||||
- `src/Game.js` - добавлена функция `showServerRestartNotification()`
|
||||
|
||||
## 🎮 Улучшения управления
|
||||
|
||||
### 3. Исправление застревания в текстурах
|
||||
- **Проблема**: Игрок застревал в текстурах и не мог выбраться
|
||||
- **Решение**:
|
||||
- Уменьшены размеры коллизионной коробки игрока (с 0.25 до 0.2)
|
||||
- Добавлено скольжение вдоль стен при столкновении
|
||||
- Увеличен зазор между игроком и объектами (с 0.01 до 0.05)
|
||||
- Улучшена система определения направления скольжения
|
||||
- **Файлы**: `src/Game.js` - улучшена функция `updateFirstPersonMovement()`
|
||||
|
||||
### 4. Улучшенное управление камерой
|
||||
- **Новые возможности**:
|
||||
- `Ctrl + колесо` = вертикальный поворот камеры (как было)
|
||||
- `Shift + Ctrl + колесо` = горизонтальный поворот камеры (±90 градусов)
|
||||
- **Ограничения**: Горизонтальный поворот ограничен для предотвращения дезориентации
|
||||
- **Файлы**: `src/Game.js` - улучшена функция `onMouseWheel()`
|
||||
|
||||
### 5. Отключение браузерного масштабирования
|
||||
- **Проблема**: Браузер масштабировал страницу при Ctrl + колесо
|
||||
- **Решение**: Добавлены обработчики событий для предотвращения масштабирования
|
||||
- **Файлы**: `src/Game.js` - добавлены обработчики `wheel` и `keydown`
|
||||
|
||||
## 🚀 Оптимизация производительности
|
||||
|
||||
### 6. Улучшенная система загрузки ресурсов
|
||||
- **Проблема**: Панель загрузки блокировала управление игрой
|
||||
- **Решение**:
|
||||
- Панель показывается только при начальной загрузке или загрузке >5 ресурсов
|
||||
- Малые загрузки происходят в фоне без блокировки
|
||||
- Добавлен флаг `isInitialLoad` для контроля отображения
|
||||
- **Файлы**: `src/Game.js` - улучшен `LoadingManager`
|
||||
|
||||
## 🔧 Технические улучшения
|
||||
|
||||
### 7. Graceful Shutdown сервера
|
||||
- **Описание**: Сервер корректно завершает работу при получении сигналов
|
||||
- **Сигналы**: `SIGTERM`, `SIGINT` (Ctrl+C)
|
||||
- **Процесс**:
|
||||
1. Уведомление всех клиентов
|
||||
2. Ожидание 5 секунд
|
||||
3. Закрытие HTTP сервера
|
||||
4. Принудительное завершение через 10 секунд
|
||||
|
||||
### 8. Улучшенная система коллизий
|
||||
- **Алгоритм скольжения**:
|
||||
- Определение ближайшего препятствия
|
||||
- Вычисление направления скольжения
|
||||
- Проверка возможности движения в направлении скольжения
|
||||
- Применение скольжения с уменьшенной дистанцией
|
||||
|
||||
## 📱 Пользовательский интерфейс
|
||||
|
||||
### 9. Подсказки по управлению
|
||||
- **Описание**: Автоматически показывается подсказка об управлении камерой
|
||||
- **Время**: Появляется через 3 секунды после загрузки игры
|
||||
- **Длительность**: Висит 10 секунд, затем плавно исчезает
|
||||
- **Стиль**: Темная полупрозрачная панель с анимацией
|
||||
|
||||
## 🧪 Тестирование
|
||||
|
||||
### 10. Тестовые файлы
|
||||
- `test_telegram_status.html` - тест API статуса пользователей
|
||||
- `TELEGRAM_STATUS_README.md` - документация по системе статусов
|
||||
- `TESTING_INSTRUCTIONS.md` - инструкции по тестированию
|
||||
- `GAME_IMPROVEMENTS_README.md` - этот файл
|
||||
|
||||
## 🚀 Как запустить
|
||||
|
||||
1. **Запуск сервера**:
|
||||
```bash
|
||||
node server.js
|
||||
```
|
||||
|
||||
2. **Тестирование уведомлений**:
|
||||
- Откройте игру в браузере
|
||||
- Войдите в систему
|
||||
- Откройте Telegram и отправьте сообщение
|
||||
- Проверьте уведомления
|
||||
|
||||
3. **Тестирование перезагрузки**:
|
||||
- Нажмите Ctrl+C в терминале сервера
|
||||
- Проверьте уведомление о перезагрузке
|
||||
|
||||
4. **Тестирование управления**:
|
||||
- `Ctrl + колесо` = вертикальный поворот
|
||||
- `Shift + Ctrl + колесо` = горизонтальный поворот
|
||||
|
||||
## 🔍 Отладка
|
||||
|
||||
- **Сервер**: Логи в консоли терминала
|
||||
- **Клиент**: Логи в консоли браузера (F12)
|
||||
- **WebSocket**: Проверка соединения в Network tab
|
||||
|
||||
## 📋 Чек-лист тестирования
|
||||
|
||||
- [ ] Уведомления о сообщениях работают
|
||||
- [ ] Уведомления о перезагрузке сервера работают
|
||||
- [ ] Игрок не застревает в текстурах
|
||||
- [ ] Управление камерой работает корректно
|
||||
- [ ] Браузерное масштабирование отключено
|
||||
- [ ] Панель загрузки не блокирует игру
|
||||
- [ ] Подсказки по управлению отображаются
|
||||
|
||||
## 🎯 Следующие шаги
|
||||
|
||||
1. **Кэширование**: Добавить кэширование статуса пользователей
|
||||
2. **Группировка**: Группировать пользователей по статусу в Telegram
|
||||
3. **Уведомления**: Push-уведомления для важных событий
|
||||
4. **Статистика**: Время онлайн, активность пользователей
|
||||
5. **Оптимизация**: Дальнейшее улучшение производительности
|
||||
@@ -1,164 +0,0 @@
|
||||
# Улучшения Telegram в игре
|
||||
|
||||
## Обзор
|
||||
|
||||
Этот документ описывает улучшения, внесенные в приложение Telegram (Shipgram) в игре, включая систему уведомлений, индикаторы непрочитанных сообщений и исправление проблемы "неизвестного отправителя".
|
||||
|
||||
## Основные улучшения
|
||||
|
||||
### 1. Уведомления о новых сообщениях
|
||||
|
||||
**Проблема**: При получении новых сообщений в Telegram не было уведомлений, если приложение не было открыто.
|
||||
|
||||
**Решение**: Реализована система уведомлений, которая показывает красивые всплывающие уведомления в правом верхнем углу экрана.
|
||||
|
||||
**Функциональность**:
|
||||
- Уведомления появляются только когда Telegram не открыт
|
||||
- Отображают имя отправителя и текст сообщения
|
||||
- Автоматически исчезают через 5 секунд
|
||||
- Красивый дизайн с градиентом и анимацией
|
||||
|
||||
**Код**: `showMessageNotification(senderId, messageText)` в `src/Game.js`
|
||||
|
||||
### 2. Исправление проблемы "неизвестного отправителя"
|
||||
|
||||
**Проблема**: В уведомлениях отображалось "Неизвестный" вместо имени отправителя.
|
||||
|
||||
**Решение**: Реализована система поиска информации об отправителе:
|
||||
1. Сначала ищет в списке контактов
|
||||
2. Если не найден, загружает информацию с сервера через новый API endpoint
|
||||
|
||||
**Новые API endpoints**:
|
||||
- `GET /api/users/:userId` - получение информации о пользователе по ID
|
||||
- `GET /api/messages-read/:contactId` - получение количества непрочитанных сообщений
|
||||
|
||||
**Код**: Обновленная функция `showMessageNotification` в `src/Game.js`
|
||||
|
||||
### 3. Индикаторы непрочитанных сообщений
|
||||
|
||||
**Проблема**: Не было визуального индикатора непрочитанных сообщений в списке контактов.
|
||||
|
||||
**Решение**: Добавлены счетчики непрочитанных сообщений:
|
||||
- Красные бейджи с количеством непрочитанных сообщений
|
||||
- Имена контактов выделяются жирным шрифтом при наличии непрочитанных сообщений
|
||||
- Автоматическое обновление счетчиков
|
||||
|
||||
**Функциональность**:
|
||||
- `updateUnreadCount(senderId)` - обновляет счетчик для конкретного отправителя
|
||||
- Автоматическое обновление при получении новых сообщений
|
||||
- Периодическое обновление каждые 30 секунд
|
||||
|
||||
**Код**: Функция `updateUnreadCount` и обновленный UI в `src/Game.js`
|
||||
|
||||
## Технические детали
|
||||
|
||||
### Серверная часть (`server.js`)
|
||||
|
||||
#### Новые API endpoints
|
||||
|
||||
```javascript
|
||||
// Получение информации о пользователе по ID
|
||||
app.get('/api/users/:userId', authenticate, async (req, res) => {
|
||||
// Возвращает: id, firstName, lastName, avatarURL, isOnline, lastSeen
|
||||
});
|
||||
|
||||
// Получение количества непрочитанных сообщений
|
||||
app.get('/api/messages-read/:contactId', authenticate, async (req, res) => {
|
||||
// Возвращает: { unreadCount: number }
|
||||
});
|
||||
```
|
||||
|
||||
#### Исправления для onlineUsers и lastSeenTimes
|
||||
|
||||
- Заменены `onlineUsers.hasOwnProperty()` на `onlineUsers.has()`
|
||||
- Заменены `lastSeenTimes[userId]` на `lastSeenTimes.get(userId)`
|
||||
- Исправлен `console.log` для отображения ключей Map
|
||||
|
||||
### Клиентская часть (`src/Game.js`)
|
||||
|
||||
#### Новые функции
|
||||
|
||||
```javascript
|
||||
// Показ уведомлений о сообщениях
|
||||
const showMessageNotification = async (senderId, messageText) => {
|
||||
// Логика поиска имени отправителя и показа уведомления
|
||||
};
|
||||
|
||||
// Обновление счетчика непрочитанных сообщений
|
||||
const updateUnreadCount = async (senderId) => {
|
||||
// Загрузка и обновление счетчика
|
||||
};
|
||||
```
|
||||
|
||||
#### Обновленный UI
|
||||
|
||||
- Счетчики непрочитанных сообщений (красные бейджи)
|
||||
- Выделение имен контактов жирным шрифтом
|
||||
- Улучшенная структура контактов
|
||||
|
||||
### API функции (`src/api/auth.js`)
|
||||
|
||||
```javascript
|
||||
// Загрузка информации о пользователе по ID
|
||||
export const loadUserInfo = async (userId, token) => {
|
||||
// Запрос к /api/users/:userId
|
||||
};
|
||||
|
||||
// Обновленная функция получения статуса пользователей
|
||||
export const getUsersStatus = async (token) => {
|
||||
// Улучшенная обработка ошибок
|
||||
};
|
||||
```
|
||||
|
||||
## Тестирование
|
||||
|
||||
### Тестовый файл
|
||||
|
||||
Создан `test_telegram_improvements.html` для тестирования новых API endpoints:
|
||||
|
||||
1. **Тест статуса пользователей** - `/api/users/status`
|
||||
2. **Тест информации о пользователе** - `/api/users/:userId`
|
||||
3. **Тест количества непрочитанных сообщений** - `/api/messages-read/:contactId`
|
||||
|
||||
### Инструкции по тестированию
|
||||
|
||||
1. Откройте `test_telegram_improvements.html` в браузере
|
||||
2. Введите JWT токен пользователя
|
||||
3. Протестируйте каждый endpoint
|
||||
4. Проверьте корректность возвращаемых данных
|
||||
|
||||
## Интеграция с существующим кодом
|
||||
|
||||
### WebSocket события
|
||||
|
||||
- `newMessage` - автоматически вызывает `updateUnreadCount` и `showMessageNotification`
|
||||
- `userStatusChanged` - обновляет статус пользователей в реальном времени
|
||||
|
||||
### Интервалы обновления
|
||||
|
||||
- `statusInterval` - каждые 30 секунд обновляет статусы и счетчики непрочитанных сообщений
|
||||
|
||||
### Состояние компонента
|
||||
|
||||
- `telegramContacts` - расширен для хранения `unreadCount`
|
||||
- Автоматическое обновление при изменении данных
|
||||
|
||||
## Преимущества
|
||||
|
||||
1. **Лучший UX**: Пользователи видят уведомления о новых сообщениях
|
||||
2. **Информативность**: Четко видно, от кого пришло сообщение
|
||||
3. **Отслеживание**: Легко понять, какие чаты требуют внимания
|
||||
4. **Производительность**: Эффективное обновление данных через интервалы
|
||||
5. **Надежность**: Обработка ошибок и fallback для неизвестных отправителей
|
||||
|
||||
## Возможные улучшения в будущем
|
||||
|
||||
1. **Звуковые уведомления** - добавление звуковых сигналов
|
||||
2. **Настройки уведомлений** - возможность отключения для определенных контактов
|
||||
3. **Push-уведомления** - интеграция с браузерными push-уведомлениями
|
||||
4. **Группировка уведомлений** - объединение уведомлений от одного отправителя
|
||||
5. **История уведомлений** - сохранение истории показанных уведомлений
|
||||
|
||||
## Заключение
|
||||
|
||||
Реализованные улучшения значительно повышают удобство использования Telegram в игре, решая основные проблемы с уведомлениями и отображением информации об отправителях. Система стала более информативной и удобной для пользователей.
|
||||
@@ -1,78 +0,0 @@
|
||||
# Система статуса пользователей для Telegram (Shipgram)
|
||||
|
||||
## Описание
|
||||
|
||||
Реализована система отображения статуса "online/offline" для пользователей в Telegram приложении (Shipgram) игрового телефона. Статус показывает, действительно ли игрок находится онлайн в игре.
|
||||
|
||||
## Что реализовано
|
||||
|
||||
### 1. Серверная часть (server.js)
|
||||
|
||||
- **Отслеживание онлайн пользователей**: Переменная `onlineUsers` хранит ID пользователей, которые в данный момент подключены к WebSocket
|
||||
- **Отслеживание времени последнего онлайн**: Переменная `lastSeenTimes` хранит время последнего подключения/отключения каждого пользователя
|
||||
- **WebSocket события**:
|
||||
- При подключении: `userStatusChanged` с `isOnline: true`
|
||||
- При отключении: `userStatusChanged` с `isOnline: false`
|
||||
- **API endpoint**: `/api/users/status` возвращает список пользователей с их статусом
|
||||
|
||||
### 2. Клиентская часть (Game.js)
|
||||
|
||||
- **Обновленный API вызов**: `loadTelegramContacts()` теперь использует `/api/users/status` вместо `/api/users`
|
||||
- **WebSocket обработчик**: Слушает события `userStatusChanged` и обновляет статус в реальном времени
|
||||
- **Периодическое обновление**: Каждые 30 секунд обновляет статус пользователей
|
||||
- **Визуальные индикаторы**:
|
||||
- Зеленая точка для онлайн пользователей
|
||||
- Цветной текст статуса (зеленый для онлайн, серый для офлайн)
|
||||
- Время последнего онлайн для офлайн пользователей
|
||||
|
||||
### 3. API функции (auth.js)
|
||||
|
||||
- Добавлена функция `getUsersStatus()` для получения статуса пользователей
|
||||
|
||||
## Как это работает
|
||||
|
||||
1. **Подключение пользователя**:
|
||||
- Пользователь входит в игру
|
||||
- WebSocket middleware добавляет его в `onlineUsers`
|
||||
- Обновляется `lastSeenTimes`
|
||||
- Отправляется событие `userStatusChanged` всем клиентам
|
||||
|
||||
2. **Отключение пользователя**:
|
||||
- Пользователь выходит из игры или теряет соединение
|
||||
- Обновляется `lastSeenTimes`
|
||||
- Отправляется событие `userStatusChanged` всем клиентам
|
||||
- Пользователь удаляется из `onlineUsers`
|
||||
|
||||
3. **Отображение в Telegram**:
|
||||
- При открытии Telegram загружается список пользователей с их статусом
|
||||
- Статус обновляется в реальном времени через WebSocket
|
||||
- Периодически обновляется через API для синхронизации
|
||||
|
||||
## Файлы, которые были изменены
|
||||
|
||||
- `server.js` - добавлена логика отслеживания статуса и WebSocket события
|
||||
- `src/Game.js` - обновлено Telegram приложение для отображения статуса
|
||||
- `src/api/auth.js` - добавлена функция для получения статуса пользователей
|
||||
- `test_telegram_status.html` - тестовый файл для проверки API
|
||||
|
||||
## Тестирование
|
||||
|
||||
1. Запустите сервер
|
||||
2. Откройте `test_telegram_status.html` в браузере
|
||||
3. Введите JWT токен пользователя
|
||||
4. Нажмите "Тестировать API"
|
||||
5. Проверьте, что статус пользователей отображается корректно
|
||||
|
||||
## Особенности
|
||||
|
||||
- **Реальное время**: Статус обновляется мгновенно при подключении/отключении
|
||||
- **Надежность**: Периодическое обновление через API обеспечивает синхронизацию
|
||||
- **Производительность**: WebSocket события отправляются только при изменении статуса
|
||||
- **Визуальная обратная связь**: Зеленые точки и цветной текст для лучшего UX
|
||||
|
||||
## Возможные улучшения
|
||||
|
||||
1. **Кэширование**: Добавить кэширование статуса пользователей
|
||||
2. **Группировка**: Группировать пользователей по статусу
|
||||
3. **Уведомления**: Уведомления о том, что пользователь стал онлайн
|
||||
4. **Статистика**: Время, проведенное онлайн, активность и т.д.
|
||||
@@ -1,60 +0,0 @@
|
||||
# Инструкция по тестированию системы статуса пользователей
|
||||
|
||||
## Быстрый тест
|
||||
|
||||
1. **Запустите сервер**:
|
||||
```bash
|
||||
node server.js
|
||||
```
|
||||
|
||||
2. **Откройте игру в браузере** и войдите в систему
|
||||
|
||||
3. **Откройте Telegram в игровом телефоне** и проверьте:
|
||||
- Отображается ли статус "Онлайн" для текущего пользователя
|
||||
- Есть ли зеленая точка рядом с аватаром
|
||||
- Показывает ли статус "Офлайн" для других пользователей
|
||||
|
||||
## Детальное тестирование
|
||||
|
||||
### Тест 1: Проверка API
|
||||
1. Откройте `test_telegram_status.html` в браузере
|
||||
2. Введите JWT токен из localStorage браузера
|
||||
3. Нажмите "Тестировать API"
|
||||
4. Проверьте, что возвращается список пользователей с полями:
|
||||
- `isOnline`: boolean
|
||||
- `lastSeen`: timestamp или null
|
||||
|
||||
### Тест 2: Проверка WebSocket событий
|
||||
1. Откройте консоль браузера
|
||||
2. Войдите в игру
|
||||
3. Проверьте логи:
|
||||
```
|
||||
Статус пользователя изменился: {userId: X, isOnline: true}
|
||||
```
|
||||
|
||||
### Тест 3: Проверка реального времени
|
||||
1. Откройте игру в двух вкладках браузера
|
||||
2. Войдите под разными пользователями
|
||||
3. В одной вкладке откройте Telegram
|
||||
4. В другой вкладке закройте игру
|
||||
5. Проверьте, что статус изменился на "Офлайн" в реальном времени
|
||||
|
||||
## Ожидаемые результаты
|
||||
|
||||
- ✅ Статус "Онлайн" отображается только для пользователей, которые действительно в игре
|
||||
- ✅ Зеленая точка появляется рядом с аватаром онлайн пользователей
|
||||
- ✅ Статус обновляется в реальном времени при подключении/отключении
|
||||
- ✅ Время последнего онлайн отображается для офлайн пользователей
|
||||
- ✅ В консоли сервера видны логи подключения/отключения пользователей
|
||||
|
||||
## Возможные проблемы
|
||||
|
||||
1. **Статус не обновляется**: Проверьте WebSocket соединение
|
||||
2. **API возвращает ошибку**: Проверьте JWT токен и права доступа
|
||||
3. **Статус не синхронизируется**: Проверьте логи сервера на наличие ошибок
|
||||
|
||||
## Отладка
|
||||
|
||||
- **Сервер**: Смотрите логи в консоли сервера
|
||||
- **Клиент**: Смотрите логи в консоли браузера
|
||||
- **WebSocket**: Проверьте соединение в Network tab браузера
|
||||
@@ -1,14 +0,0 @@
|
||||
warning: in the working copy of '.env', LF will be replaced by CRLF the next time Git touches it
|
||||
warning: in the working copy of '.gitignore', LF will be replaced by CRLF the next time Git touches it
|
||||
warning: in the working copy of 'db.js', LF will be replaced by CRLF the next time Git touches it
|
||||
warning: in the working copy of 'db1.js', LF will be replaced by CRLF the next time Git touches it
|
||||
warning: in the working copy of 'package-lock.json', LF will be replaced by CRLF the next time Git touches it
|
||||
warning: in the working copy of 'server.js', LF will be replaced by CRLF the next time Git touches it
|
||||
warning: in the working copy of 'src/Game.js', LF will be replaced by CRLF the next time Git touches it
|
||||
.env | 4 [32m++[m[31m--[m
|
||||
db.js | 4 [32m+[m[31m---[m
|
||||
db1.js | 2 [32m+[m[31m-[m
|
||||
package-lock.json | 57 [32m+++++++++++++++++++++++++++++[m[31m--------------------------[m
|
||||
server.js | 10 [32m++++[m[31m------[m
|
||||
src/Game.js | 40 [32m+++++++++++++[m[31m-------------------------[m
|
||||
6 files changed, 51 insertions(+), 66 deletions(-)
|
||||
@@ -1,217 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Тест исправления Telegram</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.test-section {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.input-group {
|
||||
margin: 10px 0;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
input, button {
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
button {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
}
|
||||
button:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
.result {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
.success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Тест исправления Telegram контактов</h1>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>1. Тест загрузки контактов</h2>
|
||||
<div class="input-group">
|
||||
<label for="token1">JWT Token:</label>
|
||||
<input type="text" id="token1" placeholder="Введите JWT токен" style="width: 400px;">
|
||||
</div>
|
||||
<button onclick="testLoadContacts()">Загрузить контакты</button>
|
||||
<div id="contactsResult" class="result"></div>
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>2. Тест получения информации о пользователе</h2>
|
||||
<div class="input-group">
|
||||
<label for="token2">JWT Token:</label>
|
||||
<input type="text" id="token2" placeholder="Введите JWT токен" style="width: 400px;">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="userId">User ID:</label>
|
||||
<input type="number" id="userId" placeholder="Введите ID пользователя">
|
||||
</div>
|
||||
<button onclick="testGetUserInfo()">Получить информацию о пользователе</button>
|
||||
<div id="userInfoResult" class="result"></div>
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>3. Тест количества непрочитанных сообщений</h2>
|
||||
<div class="input-group">
|
||||
<label for="token3">JWT Token:</label>
|
||||
<input type="text" id="token3" placeholder="Введите JWT токен" style="width: 400px;">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="contactId">Contact ID:</label>
|
||||
<input type="number" id="contactId" placeholder="Введите ID контакта">
|
||||
</div>
|
||||
<button onclick="testUnreadCount()">Получить количество непрочитанных</button>
|
||||
<div id="unreadResult" class="result"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function testLoadContacts() {
|
||||
const token = document.getElementById('token1').value;
|
||||
const resultDiv = document.getElementById('contactsResult');
|
||||
|
||||
if (!token) {
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = 'Ошибка: Введите JWT токен';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/users/status', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
resultDiv.className = 'result success';
|
||||
resultDiv.textContent = `✅ Успешно загружено ${data.length} контактов:\n\n${JSON.stringify(data, null, 2)}`;
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = `❌ Ошибка ${response.status}: ${errorText}`;
|
||||
}
|
||||
} catch (error) {
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = `❌ Ошибка сети: ${error.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
async function testGetUserInfo() {
|
||||
const token = document.getElementById('token2').value;
|
||||
const userId = document.getElementById('userId').value;
|
||||
const resultDiv = document.getElementById('userInfoResult');
|
||||
|
||||
if (!token || !userId) {
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = 'Ошибка: Введите JWT токен и User ID';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/users/${userId}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
resultDiv.className = 'result success';
|
||||
resultDiv.textContent = `✅ Информация о пользователе:\n\n${JSON.stringify(data, null, 2)}`;
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = `❌ Ошибка ${response.status}: ${errorText}`;
|
||||
}
|
||||
} catch (error) {
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = `❌ Ошибка сети: ${error.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
async function testUnreadCount() {
|
||||
const token = document.getElementById('token3').value;
|
||||
const contactId = document.getElementById('contactId').value;
|
||||
const resultDiv = document.getElementById('unreadResult');
|
||||
|
||||
if (!token || !contactId) {
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = 'Ошибка: Введите JWT токен и Contact ID';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/messages-read/${contactId}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
resultDiv.className = 'result success';
|
||||
resultDiv.textContent = `✅ Количество непрочитанных сообщений:\n\n${JSON.stringify(data, null, 2)}`;
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = `❌ Ошибка ${response.status}: ${errorText}`;
|
||||
}
|
||||
} catch (error) {
|
||||
resultDiv.className = 'result error';
|
||||
resultDiv.textContent = `❌ Ошибка сети: ${error.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Автоматически копируем токен между полями
|
||||
document.getElementById('token1').addEventListener('input', function() {
|
||||
document.getElementById('token2').value = this.value;
|
||||
document.getElementById('token3').value = this.value;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,201 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Тест улучшений Telegram</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
input[type="text"], input[type="number"] {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
button {
|
||||
background: #0084ff;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
}
|
||||
button:hover {
|
||||
background: #0073e6;
|
||||
}
|
||||
.result {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin-top: 15px;
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
}
|
||||
.error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
.success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Тест улучшений Telegram</h1>
|
||||
|
||||
<div class="container">
|
||||
<h2>1. Получение статуса пользователей</h2>
|
||||
<div class="form-group">
|
||||
<label for="token1">JWT Token:</label>
|
||||
<input type="text" id="token1" placeholder="Введите JWT токен">
|
||||
</div>
|
||||
<button onclick="testUsersStatus()">Получить статус пользователей</button>
|
||||
<div id="result1" class="result" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>2. Получение информации о пользователе по ID</h2>
|
||||
<div class="form-group">
|
||||
<label for="token2">JWT Token:</label>
|
||||
<input type="text" id="token2" placeholder="Введите JWT токен">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="userId">ID пользователя:</label>
|
||||
<input type="number" id="userId" placeholder="Введите ID пользователя">
|
||||
</div>
|
||||
<button onclick="testUserInfo()">Получить информацию о пользователе</button>
|
||||
<div id="result2" class="result" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>3. Получение количества непрочитанных сообщений</h2>
|
||||
<div class="form-group">
|
||||
<label for="token3">JWT Token:</label>
|
||||
<input type="text" id="token3" placeholder="Введите JWT токен">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="contactId">ID контакта:</label>
|
||||
<input type="number" id="contactId" placeholder="Введите ID контакта">
|
||||
</div>
|
||||
<button onclick="testUnreadCount()">Получить количество непрочитанных сообщений</button>
|
||||
<div id="result3" class="result" style="display: none;"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showResult(elementId, data, isError = false) {
|
||||
const element = document.getElementById(elementId);
|
||||
element.style.display = 'block';
|
||||
element.className = `result ${isError ? 'error' : 'success'}`;
|
||||
element.textContent = JSON.stringify(data, null, 2);
|
||||
}
|
||||
|
||||
async function testUsersStatus() {
|
||||
const token = document.getElementById('token1').value;
|
||||
if (!token) {
|
||||
showResult('result1', { error: 'Введите JWT токен' }, true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/users/status', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
showResult('result1', data);
|
||||
} else {
|
||||
showResult('result1', data, true);
|
||||
}
|
||||
} catch (error) {
|
||||
showResult('result1', { error: error.message }, true);
|
||||
}
|
||||
}
|
||||
|
||||
async function testUserInfo() {
|
||||
const token = document.getElementById('token2').value;
|
||||
const userId = document.getElementById('userId').value;
|
||||
|
||||
if (!token || !userId) {
|
||||
showResult('result2', { error: 'Введите JWT токен и ID пользователя' }, true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/users/${userId}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
showResult('result2', data);
|
||||
} else {
|
||||
showResult('result2', data, true);
|
||||
}
|
||||
} catch (error) {
|
||||
showResult('result2', { error: error.message }, true);
|
||||
}
|
||||
}
|
||||
|
||||
async function testUnreadCount() {
|
||||
const token = document.getElementById('token3').value;
|
||||
const contactId = document.getElementById('contactId').value;
|
||||
|
||||
if (!token || !contactId) {
|
||||
showResult('result3', { error: 'Введите JWT токен и ID контакта' }, true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/messages-read/${contactId}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
showResult('result3', data);
|
||||
} else {
|
||||
showResult('result3', data, true);
|
||||
}
|
||||
} catch (error) {
|
||||
showResult('result3', { error: error.message }, true);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,154 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Тест Telegram Status API</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.user-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
margin: 5px 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
background: #e5e7eb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
}
|
||||
.online-indicator {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
background: #10b981;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
.status {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
}
|
||||
.status.online {
|
||||
color: #10b981;
|
||||
font-weight: 600;
|
||||
}
|
||||
.error {
|
||||
color: #dc2626;
|
||||
padding: 10px;
|
||||
background: #fef2f2;
|
||||
border-radius: 8px;
|
||||
}
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
background: #0084ff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
margin: 10px 0;
|
||||
}
|
||||
button:hover {
|
||||
background: #0066cc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Тест Telegram Status API</h1>
|
||||
|
||||
<div>
|
||||
<label for="token">JWT Token:</label><br>
|
||||
<input type="text" id="token" placeholder="Введите JWT токен" style="width: 100%; padding: 10px; margin: 10px 0;">
|
||||
<br>
|
||||
<button onclick="testAPI()">Тестировать API</button>
|
||||
<button onclick="clearResults()">Очистить результаты</button>
|
||||
</div>
|
||||
|
||||
<div id="results"></div>
|
||||
|
||||
<script>
|
||||
async function testAPI() {
|
||||
const token = document.getElementById('token').value;
|
||||
const resultsDiv = document.getElementById('results');
|
||||
|
||||
if (!token) {
|
||||
resultsDiv.innerHTML = '<div class="error">Введите JWT токен</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
resultsDiv.innerHTML = '<div>Загрузка...</div>';
|
||||
|
||||
const response = await fetch('/api/users/status', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
||||
}
|
||||
|
||||
const users = await response.json();
|
||||
|
||||
let html = '<h2>Результат:</h2>';
|
||||
html += `<p>Найдено пользователей: ${users.length}</p>`;
|
||||
|
||||
users.forEach(user => {
|
||||
const isOnline = user.isOnline;
|
||||
const lastSeen = user.lastSeen;
|
||||
|
||||
let statusText = isOnline ? 'Онлайн' : 'Офлайн';
|
||||
if (!isOnline && lastSeen) {
|
||||
statusText = `Был(а) ${new Date(lastSeen).toLocaleString('ru-RU')}`;
|
||||
}
|
||||
|
||||
html += `
|
||||
<div class="user-item">
|
||||
<div class="avatar">
|
||||
${user.firstName?.[0] || ''}${user.lastName?.[0] || ''}
|
||||
${isOnline ? '<div class="online-indicator"></div>' : ''}
|
||||
</div>
|
||||
<div>
|
||||
<div><strong>${user.firstName} ${user.lastName}</strong></div>
|
||||
<div class="status ${isOnline ? 'online' : ''}">${statusText}</div>
|
||||
<div style="font-size: 12px; color: #999;">
|
||||
ID: ${user.id} | Online: ${isOnline} | LastSeen: ${lastSeen || 'N/A'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
resultsDiv.innerHTML = html;
|
||||
|
||||
} catch (error) {
|
||||
resultsDiv.innerHTML = `<div class="error">Ошибка: ${error.message}</div>`;
|
||||
console.error('API Error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function clearResults() {
|
||||
document.getElementById('results').innerHTML = '';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user