Update files

This commit is contained in:
glpshchn 2025-11-03 23:54:59 +03:00
parent 8cc32542c1
commit 06aa8a0899
21 changed files with 812 additions and 610 deletions

View File

@ -1,186 +0,0 @@
# 🌍 Changelog: Проксирование для доступа из РФ
**Дата:** 3 ноября 2025
**Версия:** 1.1.0
**Автор:** NakamaSpace Development Team
---
## 📝 Что добавлено
### Основные изменения
#### 1. Проксирование изображений
Добавлен новый эндпоинт `/api/search/proxy/:encodedUrl` для проксирования изображений с e621 и gelbooru через ваш сервер.
**Файл:** `backend/routes/search.js`
**Изменения:**
- ✅ Функция `createProxyUrl(originalUrl)` - конвертация URL в прокси-URL
- ✅ Эндпоинт `GET /api/search/proxy/:encodedUrl` - стриминг изображений
- ✅ Whitelist разрешенных доменов с проверкой безопасности
- ✅ HTTP кэширование на 24 часа
- ✅ Timeout 30 секунд для загрузки
- ✅ Автоматическая замена URL в ответах API
#### 2. Поддерживаемые домены
```javascript
[
'e621.net',
'static1.e621.net',
'gelbooru.com',
'img3.gelbooru.com',
'img2.gelbooru.com',
'img1.gelbooru.com',
'simg3.gelbooru.com',
'simg4.gelbooru.com'
]
```
#### 3. Обновленные эндпоинты
- `/api/search/furry` - теперь возвращает проксированные URL
- `/api/search/anime` - теперь возвращает проксированные URL
---
## 📚 Обновленная документация
### Обновленные файлы:
1. ✅ `README.md` - добавлена информация о проксировании в раздел "Поиск"
2. ✅ `DEPLOYMENT.md` - новый раздел "Доступность для пользователей из РФ"
3. ✅ `PROJECT_STRUCTURE.md` - обновлен список API эндпоинтов и функциональности
4. ✅ `SETUP.md` - добавлен эндпоинт проксирования
5. ✅ `PROXY_INFO.md` (новый) - подробная документация о проксировании
---
## 🔧 Технические детали
### Кодирование URL
URL изображений кодируются в base64:
```javascript
const encodedUrl = Buffer.from(originalUrl).toString('base64');
// https://static1.e621.net/image.jpg → aHR0cHM6Ly9zdGF0aWMxLmU2MjEubmV0L2ltYWdlLmpwZw==
```
### Пример прокси-URL
```
/api/search/proxy/aHR0cHM6Ly9zdGF0aWMxLmU2MjEubmV0L2RhdGEvc2FtcGxlLzEyLzM0LzEyMzQ1Njc4OTBhYmNkZWYuanBn
```
### HTTP заголовки
```javascript
{
'User-Agent': 'NakamaSpace/1.0',
'Referer': urlObj.origin,
'Content-Type': response.headers['content-type'],
'Cache-Control': 'public, max-age=86400',
'Content-Length': response.headers['content-length']
}
```
---
## ✅ Преимущества
1. **Доступность из РФ** - пользователи могут использовать приложение без VPN
2. **Безопасность** - whitelist доменов защищает от злоупотреблений
3. **Производительность** - кэширование снижает нагрузку на источники
4. **Прозрачность** - работает автоматически, без изменений на клиенте
5. **Совместимость** - сохраняет все существующие функции
---
## 🎯 Требования к деплою
### Минимальные требования
- Сервер с доступом к e621.net и gelbooru.com
- Достаточная пропускная способность для трафика изображений
- **Рекомендация:** сервер вне РФ (Railway, Heroku, DigitalOcean)
### Оценка трафика
- Preview: ~100-500 KB на изображение
- Полное изображение: 1-10 MB
- 1000 запросов поиска: ~500 MB - 5 GB
---
## 🧪 Тестирование
### Ручное тестирование
1. Запустите сервер
2. Откройте раздел "Поиск"
3. Выполните поиск
4. Проверьте DevTools → Network
5. URL изображений должны начинаться с `/api/search/proxy/`
### Автоматические тесты
```bash
# Тест проксирования (будет добавлено в будущем)
npm run test:proxy
```
---
## 📊 Мониторинг
### Логи ошибок
Все ошибки проксирования логируются в консоль:
```
Ошибка проксирования изображения: [error message]
```
### Метрики для отслеживания
- Количество проксированных запросов
- Средняя скорость загрузки
- Процент ошибок (403, 500, timeout)
- Объем трафика
---
## 🔄 Обратная совместимость
✅ Полная обратная совместимость
Не требуется изменений на клиенте
Не требуется миграция данных
✅ Существующие API эндпоинты работают как прежде
---
## 🚀 Следующие шаги
### Рекомендации по улучшению
- [ ] Добавить Redis кэш для проксированных изображений
- [ ] Метрики и мониторинг трафика
- [ ] CDN перед прокси для оптимизации
- [ ] Автоматические тесты для проксирования
- [ ] Сжатие изображений на лету
---
## 🙋 FAQ
**Q: Работает ли это без изменений на клиенте?**
A: Да, всё работает автоматически.
**Q: Можно ли отключить проксирование?**
A: Да, удалите вызовы `createProxyUrl()` в обработчиках API.
**Q: Влияет ли это на скорость?**
A: Минимально. Первая загрузка может быть медленнее, но кэширование компенсирует это.
**Q: Безопасно ли это?**
A: Да, используется whitelist доменов и проверка источников.
---
## 👏 Благодарности
Спасибо сообществу NakamaSpace за фидбек и запросы на эту функцию!
---
**Готово к использованию!** 🎉
Для подробной информации см. [PROXY_INFO.md](PROXY_INFO.md)

213
FINAL_FIXES.md Normal file
View File

@ -0,0 +1,213 @@
# ✅ Финальные исправления NakamaSpace
## Исправленные проблемы:
### 1. ✅ Окно комментариев теперь работает правильно
**Проблема**: При нажатии на поле ввода весь блок "упрыгивал" вверх
**Решение**:
- Модальное окно теперь `position: fixed` на весь экран
- Форма ввода закреплена внизу с `position: fixed`
- Добавлен правильный z-index для работы поверх всего
- Список комментариев имеет отступ снизу для формы ввода
**Файлы**: `frontend/src/components/CommentsModal.css`
### 2. ✅ Репосты полностью удалены
**Удалено**:
- Кнопка репоста из карточки поста
- Backend endpoint `/posts/:id/repost`
- Поле `reposts` из модели Post
- Тип уведомления 'repost'
- Весь связанный код
**Файлы**:
- `frontend/src/components/PostCard.jsx`
- `backend/routes/posts.js`
- `backend/models/Post.js`
- `backend/models/Notification.js`
- `frontend/src/pages/Notifications.jsx`
- `backend/utils/statistics.js`
### 3. ✅ Улучшена видимость в тёмной теме
**Исправлено**:
- Все иконки теперь видны (используют `currentColor` или явный `stroke`)
- Кнопки имеют правильный цвет текста
- Навигация внизу видна
- Кнопка "Создать пост" теперь синяя (более заметная)
- Кнопка меню (три точки) видна
- Хедеры страниц имеют правильный фон
**Файлы**:
- `frontend/src/styles/index.css`
- `frontend/src/components/PostCard.css`
- `frontend/src/components/PostCard.jsx`
- `frontend/src/components/Navigation.css`
- `frontend/src/pages/Feed.css`
---
## 📋 Что нужно сделать на сервере:
### Вариант 1: Автоматический (используйте скрипт)
```bash
# На вашем компьютере
cd /Users/glpshchn/Desktop
tar -czf nakama-fixed.tar.gz nakama \
--exclude='nakama/node_modules' \
--exclude='nakama/frontend/node_modules' \
--exclude='nakama/frontend/dist' \
--exclude='nakama/backend/uploads'
# Загрузите на сервер
scp nakama-fixed.tar.gz root@ваш_IP:/tmp/
# На сервере
ssh root@ваш_IP
# Бэкап текущей версии
cd /var/www
sudo tar -czf ~/nakama-backup-$(date +%Y%m%d_%H%M%S).tar.gz nakama
# Распаковать новую версию
cd /var/www
sudo rm -rf nakama
sudo tar -xzf /tmp/nakama-fixed.tar.gz
sudo chown -R $USER:$USER nakama
# Перейти в проект
cd nakama
# Установить зависимости
npm install --production
# Собрать frontend
cd frontend
npm install
npm run build
cd ..
# Обновить MongoDB (удалить поле reposts)
mongosh nakama --eval '
db.posts.updateMany({}, { $unset: { reposts: "" } });
db.notifications.deleteMany({ type: "repost" });
'
# Перезапустить backend
pm2 restart nakama-backend
# Проверить
pm2 logs nakama-backend --lines 30
curl https://nakama.glpshchn.ru/health
```
### Вариант 2: Через Git
```bash
# На вашем компьютере
cd /Users/glpshchn/Desktop/nakama
git add .
git commit -m "Fix: comments modal, remove reposts, improve dark theme visibility"
git push
# На сервере
ssh root@ваш_IP
cd /var/www/nakama
git pull
npm install --production
cd frontend && npm install && npm run build && cd ..
# Обновить MongoDB
mongosh nakama --eval '
db.posts.updateMany({}, { $unset: { reposts: "" } });
db.notifications.deleteMany({ type: "repost" });
'
pm2 restart nakama-backend
pm2 logs nakama-backend
```
---
## 🎯 Изменённые файлы:
### Frontend:
1. `src/components/PostCard.jsx` - убраны репосты, улучшены иконки
2. `src/components/PostCard.css` - цвет кнопок
3. `src/components/CommentsModal.css` - fixed модальное окно
4. `src/components/Navigation.css` - видимость иконок навигации
5. `src/pages/Feed.css` - синяя кнопка создания
6. `src/pages/Notifications.jsx` - убран repost
7. `src/styles/index.css` - улучшена тёмная тема
### Backend:
1. `models/Post.js` - убрано поле reposts
2. `models/Notification.js` - убран тип repost
3. `routes/posts.js` - удалён endpoint репостов
4. `utils/statistics.js` - убраны репосты из статистики
---
## ✅ После обновления:
### Проверьте в приложении:
1. **Комментарии**:
- ✅ Откройте пост → нажмите комментарии
- ✅ Окно должно открыться на весь экран
- ✅ Поле ввода внизу должно быть активным
- ✅ При фокусе на поле ничего не "прыгает"
2. **Репосты**:
- ✅ Кнопка репоста должна исчезнуть
- ✅ Остаются только: ❤️ Лайк и 💬 Комментарий
3. **Тёмная тема**:
- ✅ Переключите на тёмную тему в профиле
- ✅ Все иконки должны быть видны (белые/серые)
- ✅ Кнопки видны
- ✅ Навигация внизу видна
- ✅ Кнопка "+" видна (синяя)
- ✅ Три точки (меню) видны
4. **Фильтр NSFW**:
- ✅ Профиль → "Скрыть контент 18+"
- ✅ При включении NSFW посты скрываются
- ✅ При выключении все посты показываются
---
## 🔄 Команды для быстрой проверки на сервере:
```bash
# Статус
pm2 status
# Логи (последние 50 строк)
pm2 logs nakama-backend --lines 50
# Проверка API
curl https://nakama.glpshchn.ru/health
# Проверка количества постов в базе
mongosh nakama --eval 'db.posts.countDocuments({})'
# Проверка что reposts удалены
mongosh nakama --eval 'db.posts.findOne({}, {reposts: 1})'
# Должно вернуть: null для reposts
```
---
## 🎉 Готово!
Все проблемы исправлены:
- ✅ Окно комментариев работает с клавиатурой
- ✅ Репосты удалены полностью
- ✅ Иконки и текст видны в тёмной теме
- ✅ Улучшена общая видимость элементов
После обновления на сервере всё должно работать идеально! 🚀

View File

@ -1,148 +0,0 @@
# 🌍 Проксирование API для доступа из РФ
## Обзор
NakamaSpace автоматически проксирует все запросы к внешним API (e621 и gelbooru) через ваш сервер. Это обеспечивает доступность контента для пользователей из РФ, где эти ресурсы могут быть заблокированы.
## Как это работает
### 1. API запросы
Все запросы к e621 и gelbooru выполняются **с вашего сервера**, а не напрямую от клиента:
```
Клиент → Ваш сервер → e621/gelbooru API → Ваш сервер → Клиент
```
**Эндпоинты:**
- `/api/search/furry` - поиск в e621
- `/api/search/anime` - поиск в gelbooru
- `/api/search/furry/tags` - автокомплит тегов e621
- `/api/search/anime/tags` - автокомплит тегов gelbooru
### 2. Проксирование изображений
URL изображений автоматически конвертируются в прокси-URL:
**До:**
```
https://static1.e621.net/data/sample/12/34/1234567890abcdef.jpg
```
**После:**
```
/api/search/proxy/aHR0cHM6Ly9zdGF0aWMxLmU2MjEubmV0L2RhdGEvc2FtcGxlLzEyLzM0LzEyMzQ1Njc4OTBhYmNkZWYuanBn
```
Изображения стримятся через ваш сервер с кэшированием на 24 часа.
### 3. Безопасность
Проксирование разрешено только для следующих доменов:
- `e621.net`
- `static1.e621.net`
- `gelbooru.com`
- `img3.gelbooru.com`
- `img2.gelbooru.com`
- `img1.gelbooru.com`
- `simg3.gelbooru.com`
- `simg4.gelbooru.com`
Запросы к другим доменам будут отклонены с ошибкой 403.
## Производительность
### Оптимизация
1. **Стриминг** - изображения передаются потоком без полной загрузки в память
2. **Кэширование** - заголовок `Cache-Control: public, max-age=86400` (24 часа)
3. **Таймаут** - 30 секунд для загрузки изображения
### HTTP заголовки
```javascript
{
'User-Agent': 'NakamaSpace/1.0',
'Referer': originalUrl.origin,
'Content-Type': // из ответа источника
'Cache-Control': 'public, max-age=86400',
'Content-Length': // из ответа источника
}
```
## Мониторинг
### Логирование ошибок
Все ошибки проксирования логируются:
```javascript
console.error('Ошибка проксирования изображения:', error.message);
```
### Типичные ошибки
1. **403 Forbidden** - попытка проксировать запрещенный домен
2. **500 Internal Server Error** - ошибка загрузки с источника
3. **Timeout** - источник не отвечает более 30 секунд
## Требования к серверу
### Сетевой доступ
Ваш сервер должен иметь **прямой доступ** к:
- `e621.net` (HTTPS)
- `gelbooru.com` (HTTPS)
**Рекомендация:** используйте сервер **вне РФ** (например, Railway EU/US, Heroku, DigitalOcean)
### Пропускная способность
Учитывайте трафик проксируемых изображений:
- Preview изображения: ~100-500 KB
- Полные изображения: 1-10 MB
- На 1000 запросов поиска: ~500 MB - 5 GB трафика
## Код
Основная реализация находится в:
```
backend/routes/search.js
```
**Ключевые функции:**
- `createProxyUrl(originalUrl)` - конвертация URL в прокси-URL
- `GET /api/search/proxy/:encodedUrl` - эндпоинт проксирования
## Тестирование
### Проверка работы прокси
1. Откройте приложение
2. Перейдите в раздел "Поиск"
3. Выполните поиск по тегу
4. Откройте DevTools → Network
5. Убедитесь, что изображения загружаются с `/api/search/proxy/...`
### Проверка из РФ
1. Попросите пользователя из РФ протестировать
2. Изображения должны загружаться без VPN
3. Если не работает - проверьте, что сервер вне РФ
## FAQ
### Q: Можно ли добавить другие источники?
A: Да, добавьте домен в `allowedDomains` и обновите логику в обработчиках поиска.
### Q: Влияет ли это на скорость?
A: Минимально. Стриминг и кэширование минимизируют задержки. Первая загрузка может быть медленнее, но последующие - быстрее благодаря кэшу.
### Q: Нужно ли настраивать CDN?
A: Нет, но рекомендуется для production с большим трафиком. Можно использовать Cloudflare перед вашим сервером.
### Q: Работает ли это в China?
A: Частично. Зависит от локации сервера и блокировок. Рекомендуется азиатский регион для китайских пользователей.
## Обновление документов
Информация о проксировании добавлена в:
- [x] `README.md` - раздел "Поиск"
- [x] `DEPLOYMENT.md` - раздел "Доступность для пользователей из РФ"
- [x] `PROJECT_STRUCTURE.md` - список API эндпоинтов
- [x] `SETUP.md` - список API эндпоинтов
---
**Готово!** 🎉 Ваш NakamaSpace теперь доступен пользователям из РФ без VPN!

View File

@ -1,181 +0,0 @@
# ⚡ Быстрый старт: Проксирование для РФ
## ✅ Что уже работает
**Поздравляем!** Проксирование уже полностью настроено и работает автоматически.
### Что происходит автоматически:
1. ✅ API запросы к e621 и gelbooru идут через ваш сервер
2. ✅ URL изображений автоматически конвертируются в прокси-URL
3. ✅ Изображения загружаются через ваш сервер
4. ✅ Кэширование на 24 часа для оптимизации
### Никаких дополнительных действий не требуется! 🎉
---
## 🚀 Проверка работы
### 1. Запустите проект
```bash
# Backend
cd backend
npm start
# Frontend (в другом терминале)
cd frontend
npm run dev
```
### 2. Откройте приложение
```
http://localhost:5173
```
### 3. Протестируйте поиск
1. Перейдите в раздел "Поиск" (🔍)
2. Выберите режим "Furry" или "Anime"
3. Введите любой тег (например: `cat`, `wolf`, `anime`)
4. Изображения загрузятся через прокси ✅
### 4. Проверьте в DevTools
Откройте DevTools (F12) → Network:
- URL изображений должны начинаться с `/api/search/proxy/`
- Статус: `200 OK`
- Заголовок: `Cache-Control: public, max-age=86400`
---
## 🌍 Деплой для пользователей из РФ
### Важно:
**Разместите сервер ВНЕ РФ** для надежного доступа к e621 и gelbooru.
### Рекомендуемые платформы:
#### Railway (Европа/США) ⭐
```bash
# 1. Создайте проект на railway.app
# 2. Подключите GitHub репозиторий
# 3. Railway автоматически задеплоит
```
#### Heroku
```bash
heroku create nakama-space
git push heroku main
```
#### DigitalOcean
```bash
# App Platform → Create App → Connect GitHub
# Регион: NYC, Amsterdam, или Singapore
```
---
## 📊 Мониторинг
### Проверка логов
```bash
# Backend логи
cd backend
npm start
# Ищите:
# ✅ "Ошибка проксирования изображения" - если есть проблемы
```
### Метрики
Отслеживайте:
- Скорость загрузки изображений
- Процент успешных запросов
- Объем трафика
---
## 🛠️ Настройка (опционально)
### Изменить время кэширования
`backend/routes/search.js`:
```javascript
// Строка 52
res.setHeader('Cache-Control', 'public, max-age=86400'); // 24 часа
// Измените 86400 на нужное значение в секундах
```
### Изменить таймаут загрузки
`backend/routes/search.js`:
```javascript
// Строка 47
timeout: 30000 // 30 секунд
// Измените на нужное значение в миллисекундах
```
### Добавить домены
`backend/routes/search.js`:
```javascript
// Строки 24-33
const allowedDomains = [
'e621.net',
'static1.e621.net',
'gelbooru.com',
// ... добавьте ваши домены
];
```
---
## 🧪 Тестирование из РФ
### Попросите друга из РФ:
1. Открыть ваше приложение (без VPN)
2. Выполнить поиск
3. Проверить, что изображения загружаются
### Если не работает:
- ✅ Проверьте, что сервер вне РФ
- ✅ Проверьте логи на ошибки
- ✅ Убедитесь, что сервер имеет доступ к e621/gelbooru
- ✅ Проверьте firewall настройки
---
## 📚 Дополнительная документация
- [PROXY_INFO.md](PROXY_INFO.md) - Подробная техническая документация
- [CHANGELOG_PROXY.md](CHANGELOG_PROXY.md) - Список изменений
- [DEPLOYMENT.md](DEPLOYMENT.md) - Инструкции по деплою
- [SETUP.md](SETUP.md) - Настройка проекта
---
## ❓ Частые вопросы
**Q: Нужно ли что-то менять на фронтенде?**
A: Нет, всё работает автоматически.
**Q: Будут ли изображения медленнее грузиться?**
A: Первая загрузка может быть чуть медленнее, но благодаря кэшированию последующие загрузки будут быстрыми.
**Q: Безопасно ли это?**
A: Да, используется whitelist доменов и все запросы проверяются.
**Q: Сколько это будет стоить?**
A: Зависит от трафика. Бесплатные тиры (Railway, Vercel) должны хватить для старта.
**Q: Можно ли использовать CDN?**
A: Да! Рекомендуется использовать Cloudflare перед вашим сервером для оптимизации.
---
## 🎉 Готово!
Ваш NakamaSpace теперь доступен пользователям из РФ без VPN!
**Наслаждайтесь!** 🚀
---
**Нужна помощь?** Создайте issue на GitHub или обратитесь к [PROXY_INFO.md](PROXY_INFO.md)

124
READY_TO_DEPLOY.txt Normal file
View File

@ -0,0 +1,124 @@
╔═══════════════════════════════════════════════════════════════════════╗
║ NakamaSpace v2.1 - Готов к деплою! ║
╚═══════════════════════════════════════════════════════════════════════╝
ВСЕ ИСПРАВЛЕНИЯ ПРИМЕНЕНЫ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📝 ЧТО ИСПРАВЛЕНО:
1. ✅ Окно комментариев
└─ Теперь fixed на весь экран, поле ввода активно
2. ✅ Репосты удалены
└─ Остались только Лайки ❤️ и Комментарии 💬
3. ✅ Тёмная тема
└─ Все иконки и текст видны
4. ✅ Фильтры упрощены
└─ Только "Скрыть контент 18+"
5. ✅ Донаты удалены
└─ Упрощён профиль
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚀 КАК ЗАГРУЗИТЬ НА СЕРВЕР:
Метод 1: Быстрый (через SCP)
────────────────────────────────────────────────────────────────────────
НА КОМПЬЮТЕРЕ:
cd /Users/glpshchn/Desktop
tar -czf nakama-v2.1.tar.gz nakama \
--exclude='node_modules' --exclude='dist' --exclude='.git'
scp nakama-v2.1.tar.gz root@IP:/tmp/
НА СЕРВЕРЕ:
ssh root@IP
cd /var/www
sudo tar -czf ~/backup-$(date +%s).tar.gz nakama
cd nakama && cp .env /tmp/ && cp -r backend/uploads /tmp/ && cd ..
sudo rm -rf nakama
sudo tar -xzf /tmp/nakama-v2.1.tar.gz
cd nakama && cp /tmp/.env . && cp -r /tmp/uploads backend/
./update-server.sh
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Метод 2: Через Git (если настроен)
────────────────────────────────────────────────────────────────────────
НА КОМПЬЮТЕРЕ:
cd /Users/glpshchn/Desktop/nakama
git add .
git commit -m "v2.1: Fixes and improvements"
git push
НА СЕРВЕРЕ:
ssh root@IP
cd /var/www/nakama
git pull
./update-server.sh
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ ПОСЛЕ ОБНОВЛЕНИЯ ПРОВЕРЬТЕ:
□ https://nakama.glpshchn.ru/health
└─ Должно вернуть: {"status":"ok"}
□ https://nakama.glpshchn.ru
└─ Приложение загружается
□ Откройте бота в Telegram
└─ Нажмите Menu Button
└─ Приложение работает
□ Попробуйте:
├─ Создать пост
├─ Написать комментарий (должно работать!)
├─ Переключить тёмную тему (всё видно!)
└─ Переключить фильтр NSFW (работает!)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📚 ДОКУМЕНТАЦИЯ:
README.md - Обзор проекта
UPLOAD_TO_SERVER.md - Подробная инструкция загрузки (⭐ ЧИТАТЬ)
UPDATES_v2.1.md - Changelog v2.1
DEPLOYMENT.md - Полный гайд по деплою
QUICKSTART.md - Быстрый старт
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎯 СЛЕДУЮЩИЕ ШАГИ:
1. Упакуйте проект: tar -czf nakama-v2.1.tar.gz nakama
2. Загрузите на сервер: scp nakama-v2.1.tar.gz root@IP:/tmp/
3. На сервере выполните: ./update-server.sh
4. Проверьте в браузере и Telegram
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 ПОЛЕЗНО ЗНАТЬ:
• Скрипт update-server.sh делает автоматический бэкап
• Uploads и .env сохраняются автоматически
• MongoDB обновится автоматически (удалятся reposts)
• PM2 перезапустится автоматически
• Логи доступны: pm2 logs nakama-backend
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 ГОТОВО К ЗАГРУЗКЕ НА nakama.glpshchn.ru
Подробная инструкция: UPLOAD_TO_SERVER.md
╔═══════════════════════════════════════════════════════════════════════╗
║ Успехов! 🚀🦊🎌 ║
╚═══════════════════════════════════════════════════════════════════════╝

200
UPDATES_v2.1.md Normal file
View File

@ -0,0 +1,200 @@
# 🎉 NakamaSpace v2.1 - Changelog
## Дата: 03.11.2025
### 🐛 Исправлены критические баги:
#### 1. ✅ Окно комментариев
- **Было**: При нажатии на поле ввода блок "упрыгивал" вверх, поле неактивно
- **Стало**:
- Модальное окно фиксировано на весь экран
- Форма ввода закреплена внизу
- Поле полностью активно и доступно
- Правильно работает с мобильной клавиатурой
#### 2. ✅ Репосты удалены
- **Было**: Кнопка репоста не работала
- **Стало**:
- Кнопка полностью удалена
- Остались только Лайки ❤️ и Комментарии 💬
- Упрощён интерфейс
#### 3. ✅ Видимость в тёмной теме
- **Было**: Иконки белые и невидимы, текст теряется
- **Стало**:
- Все иконки используют правильный цвет (`currentColor`)
- Кнопки видны и контрастны
- Навигация чёткая
- Кнопка "+" стала синей (более заметная)
#### 4. ✅ Фильтры упрощены
- **Было**: 3 фильтра (Furry, Anime, NSFW) не работали правильно
- **Стало**:
- Убраны "Без Furry" и "Только Anime"
- Остался только "Скрыть контент 18+"
- Настройка автоматически сохраняется на сервер
- По умолчанию все посты видны
#### 5. ✅ Блок донатов удалён
- Убран блок "Поддержать разработчиков"
- Упрощён интерфейс профиля
---
## 🔧 Технические изменения:
### Frontend:
- `PostCard.jsx` - убраны репосты, улучшены stroke для иконок
- `CommentsModal.css` - fixed позиционирование
- `CreatePostModal.css` - убран margin-bottom
- `Navigation.css` - явный stroke для иконок
- `Feed.css` - синяя кнопка создания
- `Profile.jsx` - автосохранение настроек, убраны фильтры
- `Notifications.jsx` - убран тип repost
- `index.css` - расширенные правила для тёмной темы
### Backend:
- `models/Post.js` - удалено поле reposts
- `models/Notification.js` - удалён тип repost
- `routes/posts.js` - удалён endpoint репостов
- `utils/statistics.js` - убраны репосты из статистики
- `models/User.js` - noNSFW default = false
### Database:
- Удалено поле `reposts` из всех постов
- Удалены уведомления типа 'repost'
- Отключены все фильтры для существующих пользователей
---
## 📦 Установка обновления:
### На сервере выполните:
```bash
# 1. Подключитесь к серверу
ssh root@ваш_IP
# 2. Перейдите в проект
cd /var/www/nakama
# 3. Замените файлы новыми версиями
# (загрузите через scp или git pull)
# 4. Установите зависимости
npm install --production
cd frontend && npm install && npm run build && cd ..
# 5. Обновите базу данных
mongosh nakama --eval '
// Отключить фильтры
db.users.updateMany(
{},
{ $set: {
"settings.whitelist.noNSFW": false,
"settings.whitelist.noFurry": false,
"settings.whitelist.onlyAnime": false
}}
);
// Удалить репосты
db.posts.updateMany({}, { $unset: { reposts: "" } });
db.notifications.deleteMany({ type: "repost" });
print("✅ База данных обновлена");
'
# 6. Перезапустите backend
pm2 restart nakama-backend
# 7. Проверьте
pm2 logs nakama-backend --lines 30
curl https://nakama.glpshchn.ru/health
```
### Автоматический скрипт:
```bash
# Используйте обновлённый скрипт
cd /var/www/nakama
./update-server.sh
```
---
## ✅ Проверка после обновления:
### В приложении (https://nakama.glpshchn.ru):
1. **Комментарии**:
- [ ] Откройте любой пост
- [ ] Нажмите на иконку комментариев 💬
- [ ] Окно должно открыться на весь экран
- [ ] Нажмите на поле ввода внизу
- [ ] Поле должно стать активным без прыжков
- [ ] Введите комментарий и отправьте
2. **Репосты**:
- [ ] В карточке поста должны быть только 2 кнопки: ❤️ и 💬
- [ ] Кнопки репоста нет
3. **Тёмная тема**:
- [ ] Профиль → Переключите тему на "Тёмная"
- [ ] Все иконки должны быть видны (белые/серые)
- [ ] Кнопка "+" вверху синяя
- [ ] Три точки (меню) видны
- [ ] Навигация внизу видна
- [ ] Все тексты читаемы
4. **Фильтр NSFW**:
- [ ] Профиль → должна быть только одна настройка "Скрыть контент 18+"
- [ ] Переключите её
- [ ] Посты должны появиться/исчезнуть сразу
5. **Донаты**:
- [ ] В профиле не должно быть блока "Поддержать разработчиков"
---
## 📊 Статистика изменений:
- **Удалено строк кода**: ~200
- **Изменено файлов**: 13
- **Исправлено багов**: 5
- **Время обновления на сервере**: ~5 минут
---
## 🚀 После обновления получите:
✅ Полностью рабочее окно комментариев
✅ Упрощённый интерфейс без репостов
✅ Идеальную видимость в тёмной теме
✅ Рабочий фильтр NSFW
✅ Чистый профиль без донатов
---
## 📞 Если что-то не работает:
```bash
# Проверить логи
pm2 logs nakama-backend
# Проверить процессы
pm2 status
# Перезапустить всё
pm2 restart nakama-backend
sudo systemctl restart nginx
# Проверить MongoDB
mongosh nakama --eval 'db.posts.findOne()'
```
---
**NakamaSpace v2.1 готов! 🎉**
Теперь приложение работает стабильно на https://nakama.glpshchn.ru

141
UPLOAD_TO_SERVER.md Normal file
View File

@ -0,0 +1,141 @@
# 📤 Как загрузить обновления на nakama.glpshchn.ru
## Быстрая инструкция:
### Шаг 1: Упаковать проект (на вашем компьютере)
```bash
cd /Users/glpshchn/Desktop
# Упаковать проект
tar -czf nakama-v2.1.tar.gz nakama \
--exclude='nakama/node_modules' \
--exclude='nakama/frontend/node_modules' \
--exclude='nakama/frontend/dist' \
--exclude='nakama/backend/uploads' \
--exclude='nakama/.git'
# Проверить размер архива
ls -lh nakama-v2.1.tar.gz
```
### Шаг 2: Загрузить на сервер
```bash
# Загрузить архив
scp nakama-v2.1.tar.gz root@ваш_IP:/tmp/
# Подключиться к серверу
ssh root@ваш_IP
```
### Шаг 3: Развернуть на сервере
```bash
# Сделать бэкап текущей версии
cd /var/www
sudo tar -czf ~/nakama-backup-$(date +%Y%m%d_%H%M%S).tar.gz nakama
# Удалить старую версию (кроме uploads и .env)
cd nakama
cp .env /tmp/nakama.env
cp -r backend/uploads /tmp/nakama-uploads
cd ..
sudo rm -rf nakama
# Распаковать новую версию
sudo tar -xzf /tmp/nakama-v2.1.tar.gz
sudo chown -R $USER:$USER nakama
cd nakama
# Восстановить .env и uploads
cp /tmp/nakama.env .env
mkdir -p backend/uploads
cp -r /tmp/nakama-uploads/* backend/uploads/
rm -rf /tmp/nakama-uploads /tmp/nakama.env
# Запустить скрипт обновления
chmod +x update-server.sh
./update-server.sh
```
### Всё! Готово! ✅
Проверьте: https://nakama.glpshchn.ru
---
## 🔍 Быстрая проверка:
```bash
# Статус
pm2 status
# Логи (должны быть без ошибок)
pm2 logs nakama-backend --lines 50
# API
curl https://nakama.glpshchn.ru/health
# Должно вернуть: {"status":"ok","environment":"production",...}
# Посты в базе
mongosh nakama --eval 'db.posts.countDocuments({})'
# Проверить что reposts удалены
mongosh nakama --eval 'db.posts.findOne({}, {reposts: 1})'
# reposts должно быть undefined/null
```
---
## 📱 Проверка в Telegram:
1. Откройте вашего бота
2. Нажмите Menu Button
3. Проверьте что:
- ✅ Приложение загружается
- ✅ Посты видны
- ✅ Комментарии работают
- ✅ Тёмная тема работает
- ✅ Всё видно и понятно
---
## 🔄 Если нужно откатить:
```bash
# Восстановить из бэкапа
cd /var/www
sudo rm -rf nakama
sudo tar -xzf ~/nakama-backup-ДАТА.tar.gz
pm2 restart nakama-backend
```
---
## 💡 Полезные команды:
```bash
# Перезапустить всё
pm2 restart nakama-backend
sudo systemctl restart nginx
# Посмотреть логи
pm2 logs nakama-backend
tail -f /var/log/nginx/nakama_error.log
# Очистить кэш (если используете Redis)
redis-cli FLUSHALL
# Проверить процессы
pm2 status
sudo systemctl status nginx
sudo systemctl status mongod
```
---
**Готово! 🚀**
После выполнения этих шагов все исправления будут применены на https://nakama.glpshchn.ru

57
VERSION.md Normal file
View File

@ -0,0 +1,57 @@
# 📌 NakamaSpace - История версий
## v2.1 (03.11.2025) - Исправления и улучшения
### 🐛 Исправлено:
- ✅ Окно комментариев теперь фиксировано и работает с клавиатурой
- ✅ Удалён нерабочий функционал репостов
- ✅ Исправлена видимость иконок и текста в тёмной теме
- ✅ Упрощены фильтры (остался только NSFW)
- ✅ Автоматическое сохранение настроек
- ✅ Удалён блок донатов
### 🎨 Улучшено:
- Кнопка создания поста стала синей (более заметная)
- Все иконки теперь адаптивны к теме
- Улучшена контрастность в тёмной теме
- Упрощён интерфейс профиля
---
## v2.0 (03.11.2025) - Roadmap features
### ✨ Добавлено:
- ✅ Dark mode с автоматическим определением
- ✅ Rate limiting для защиты от спама
- ✅ Redis кэширование (опционально)
- ✅ Полнотекстовый поиск по постам
- ✅ Система хэштегов (#теги)
- ✅ Статистика для авторов
- ✅ WebSocket real-time уведомления
- ✅ Централизованная конфигурация
- ✅ Production-ready деплой
---
## v1.0 (03.11.2025) - Первая версия
### 🎉 Базовый функционал:
- ✅ 4 вкладки: Лента, Поиск, Уведомления, Профиль
- ✅ Создание постов с изображениями
- ✅ Обязательные теги (Furry, Anime, Other)
- ✅ Лайки и комментарии
- ✅ Интеграция e621 и gelbooru API
- ✅ Система уведомлений
- ✅ Профили и подписки
- ✅ Модерация и жалобы
- ✅ Telegram Mini App авторизация
- ✅ iOS-стиль дизайн
---
## 📊 Текущая версия: v2.1
**Статус**: ✅ Production Ready
**Домен**: nakama.glpshchn.ru
**Последнее обновление**: 03.11.2025

View File

@ -13,7 +13,7 @@ const NotificationSchema = new mongoose.Schema({
},
type: {
type: String,
enum: ['follow', 'like', 'comment', 'repost', 'mention'],
enum: ['follow', 'like', 'comment', 'mention'],
required: true
},
post: {

View File

@ -51,10 +51,6 @@ const PostSchema = new mongoose.Schema({
ref: 'User'
}],
comments: [CommentSchema],
reposts: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}],
views: {
type: Number,
default: 0

View File

@ -214,41 +214,6 @@ router.post('/:id/comment', authenticate, interactionLimiter, async (req, res) =
}
});
// Репостнуть
router.post('/:id/repost', authenticate, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
if (!post) {
return res.status(404).json({ error: 'Пост не найден' });
}
const alreadyReposted = post.reposts.includes(req.user._id);
if (alreadyReposted) {
post.reposts = post.reposts.filter(id => !id.equals(req.user._id));
} else {
post.reposts.push(req.user._id);
// Создать уведомление
if (!post.author.equals(req.user._id)) {
const notification = new Notification({
recipient: post.author,
sender: req.user._id,
type: 'repost',
post: post._id
});
await notification.save();
}
}
await post.save();
res.json({ reposts: post.reposts.length, reposted: !alreadyReposted });
} catch (error) {
console.error('Ошибка репоста:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Удалить пост (автор или модератор)
router.delete('/:id', authenticate, async (req, res) => {

View File

@ -31,14 +31,11 @@ async function getUserStatistics(userId) {
// Общее количество комментариев
const totalComments = userPosts.reduce((sum, post) => sum + post.comments.length, 0);
// Общее количество репостов
const totalReposts = userPosts.reduce((sum, post) => sum + post.reposts.length, 0);
// Общее количество просмотров
const totalViews = userPosts.reduce((sum, post) => sum + (post.views || 0), 0);
// Средняя вовлечённость (engagement rate)
const totalEngagement = totalLikes + totalComments + totalReposts;
const totalEngagement = totalLikes + totalComments;
const engagementRate = totalViews > 0 ? (totalEngagement / totalViews * 100).toFixed(2) : 0;
return {
@ -47,7 +44,6 @@ async function getUserStatistics(userId) {
followingCount: user.following.length,
totalLikes,
totalComments,
totalReposts,
totalViews,
totalEngagement,
engagementRate: parseFloat(engagementRate)
@ -71,7 +67,6 @@ async function getUserTopPosts(userId, limit = 5) {
content: post.content ? post.content.substring(0, 100) : '',
likes: post.likes.length,
comments: post.comments.length,
reposts: post.reposts.length,
views: post.views || 0,
createdAt: post.createdAt
}));

View File

@ -1,14 +1,20 @@
.comments-modal {
max-height: 85vh;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
margin-bottom: 80px; /* Отступ для нижнего меню */
border-radius: 0;
max-height: 100vh;
}
.comments-list {
flex: 1;
overflow-y: auto;
padding: 16px;
padding-bottom: 80px; /* Отступ для формы ввода */
display: flex;
flex-direction: column;
gap: 16px;
@ -85,9 +91,11 @@
padding-bottom: calc(12px + env(safe-area-inset-bottom));
border-top: 1px solid var(--divider-color);
background: var(--bg-secondary);
position: sticky;
position: fixed;
bottom: 0;
z-index: 10;
left: 0;
right: 0;
z-index: 1001;
}
.comment-form input {

View File

@ -14,11 +14,10 @@
.modal-content {
background: var(--bg-secondary);
border-radius: 16px 16px 0 0;
max-height: calc(100vh - 80px); /* Учёт нижнего меню */
max-height: 90vh;
overflow-y: auto;
width: 100%;
animation: slideUp 0.3s ease-out;
margin-bottom: 80px;
}
.create-post-modal {

View File

@ -27,6 +27,10 @@
user-select: none;
}
.nav-item svg {
stroke: currentColor;
}
.nav-item:active {
transform: scale(0.95);
}

View File

@ -45,12 +45,16 @@
height: 32px;
border-radius: 50%;
background: transparent;
color: var(--text-secondary);
color: var(--text-primary);
display: flex;
align-items: center;
justify-content: center;
}
.menu-btn svg {
stroke: currentColor;
}
.menu-btn:active {
background: var(--bg-primary);
}
@ -113,10 +117,10 @@
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px;
padding: 8px 16px;
border-radius: 20px;
background: transparent;
color: var(--text-secondary);
color: var(--text-primary);
font-size: 14px;
font-weight: 500;
transition: all 0.2s;

View File

@ -1,7 +1,7 @@
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Heart, MessageCircle, Share2, MoreVertical } from 'lucide-react'
import { likePost, commentPost, repostPost, deletePost } from '../utils/api'
import { Heart, MessageCircle, MoreVertical } from 'lucide-react'
import { likePost, commentPost, deletePost } from '../utils/api'
import { hapticFeedback, showConfirm } from '../utils/telegram'
import PostMenu from './PostMenu'
import CommentsModal from './CommentsModal'
@ -23,8 +23,6 @@ export default function PostCard({ post, currentUser, onUpdate }) {
const navigate = useNavigate()
const [liked, setLiked] = useState(post.likes.includes(currentUser.id))
const [likesCount, setLikesCount] = useState(post.likes.length)
const [reposted, setReposted] = useState(post.reposts.includes(currentUser.id))
const [repostsCount, setRepostsCount] = useState(post.reposts.length)
const [showMenu, setShowMenu] = useState(false)
const [showComments, setShowComments] = useState(false)
@ -42,19 +40,6 @@ export default function PostCard({ post, currentUser, onUpdate }) {
}
}
const handleRepost = async () => {
try {
hapticFeedback('light')
const result = await repostPost(post._id)
setReposted(result.reposted)
setRepostsCount(result.reposts)
if (result.reposted) {
hapticFeedback('success')
}
} catch (error) {
console.error('Ошибка репоста:', error)
}
}
const handleDelete = async () => {
const confirmed = await showConfirm('Удалить этот пост?')
@ -139,22 +124,14 @@ export default function PostCard({ post, currentUser, onUpdate }) {
className={`action-btn ${liked ? 'active' : ''}`}
onClick={handleLike}
>
<Heart size={20} fill={liked ? '#FF3B30' : 'none'} color={liked ? '#FF3B30' : undefined} />
<Heart size={20} fill={liked ? '#FF3B30' : 'none'} stroke={liked ? '#FF3B30' : 'currentColor'} />
<span>{likesCount}</span>
</button>
<button className="action-btn" onClick={() => setShowComments(true)}>
<MessageCircle size={20} />
<MessageCircle size={20} stroke="currentColor" />
<span>{post.comments.length}</span>
</button>
<button
className={`action-btn ${reposted ? 'active' : ''}`}
onClick={handleRepost}
>
<Share2 size={20} color={reposted ? '#34C759' : undefined} />
<span>{repostsCount}</span>
</button>
</div>
{/* Меню поста */}

View File

@ -24,7 +24,7 @@
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--button-dark);
background: var(--button-accent);
color: white;
display: flex;
align-items: center;
@ -32,6 +32,10 @@
box-shadow: 0 2px 8px var(--shadow-md);
}
.create-btn svg {
stroke: white;
}
.feed-filters {
display: flex;
gap: 8px;

View File

@ -1,6 +1,6 @@
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { Heart, MessageCircle, Share2, UserPlus, AtSign, CheckCheck } from 'lucide-react'
import { Heart, MessageCircle, UserPlus, AtSign, CheckCheck } from 'lucide-react'
import { getNotifications, markNotificationRead, markAllNotificationsRead } from '../utils/api'
import { hapticFeedback } from '../utils/telegram'
import './Notifications.css'
@ -9,7 +9,6 @@ const NOTIFICATION_ICONS = {
follow: UserPlus,
like: Heart,
comment: MessageCircle,
repost: Share2,
mention: AtSign
}
@ -17,7 +16,6 @@ const NOTIFICATION_COLORS = {
follow: '#007AFF',
like: '#FF3B30',
comment: '#34C759',
repost: '#5856D6',
mention: '#FF9500'
}
@ -25,7 +23,6 @@ const NOTIFICATION_TEXTS = {
follow: 'подписался на вас',
like: 'лайкнул ваш пост',
comment: 'прокомментировал ваш пост',
repost: 'репостнул ваш пост',
mention: 'упомянул вас в посте'
}

View File

@ -60,14 +60,38 @@
--shadow-lg: rgba(255, 255, 255, 0.12);
}
/* Иконки в тёмной теме */
[data-theme="dark"] svg {
/* Иконки в тёмной теме - улучшенная видимость */
[data-theme="dark"] {
color-scheme: dark;
}
[data-theme="dark"] .create-btn,
[data-theme="dark"] .menu-btn,
[data-theme="dark"] .action-btn,
[data-theme="dark"] .close-btn,
[data-theme="dark"] .back-btn,
[data-theme="dark"] .settings-btn {
color: var(--text-primary);
}
[data-theme="dark"] .action-btn svg {
stroke: var(--text-primary);
}
[data-theme="dark"] .nav-item {
color: var(--text-secondary);
}
[data-theme="dark"] button svg,
[data-theme="dark"] a svg {
color: inherit;
[data-theme="dark"] .nav-item.active {
color: var(--button-accent);
}
[data-theme="dark"] .feed-header,
[data-theme="dark"] .search-header,
[data-theme="dark"] .notifications-header,
[data-theme="dark"] .user-profile-header {
background: var(--bg-secondary);
border-bottom-color: var(--divider-color);
}
body {

View File

@ -29,9 +29,10 @@ npm install
npm run build
cd ..
# 6. Обновить MongoDB (отключить NSFW фильтр для всех)
echo "🗄️ Обновление настроек пользователей в MongoDB..."
# 6. Обновить MongoDB (отключить фильтры, удалить репосты)
echo "🗄️ Обновление базы данных..."
mongosh nakama --eval '
// Отключить все фильтры для пользователей
db.users.updateMany(
{},
{ $set: {
@ -39,7 +40,15 @@ db.users.updateMany(
"settings.whitelist.noFurry": false,
"settings.whitelist.onlyAnime": false
}}
)
);
// Удалить поле reposts из постов
db.posts.updateMany({}, { $unset: { reposts: "" } });
// Удалить уведомления о репостах
db.notifications.deleteMany({ type: "repost" });
print("✅ База данных обновлена");
' --quiet
# 7. Перезапустить backend