Update files
This commit is contained in:
parent
8cc32542c1
commit
06aa8a0899
|
|
@ -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)
|
||||
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Готово!
|
||||
|
||||
Все проблемы исправлены:
|
||||
- ✅ Окно комментариев работает с клавиатурой
|
||||
- ✅ Репосты удалены полностью
|
||||
- ✅ Иконки и текст видны в тёмной теме
|
||||
- ✅ Улучшена общая видимость элементов
|
||||
|
||||
После обновления на сервере всё должно работать идеально! 🚀
|
||||
|
||||
148
PROXY_INFO.md
148
PROXY_INFO.md
|
|
@ -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!
|
||||
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
╔═══════════════════════════════════════════════════════════════════════╗
|
||||
║ Успехов! 🚀🦊🎌 ║
|
||||
╚═══════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
user-select: none;
|
||||
}
|
||||
|
||||
.nav-item svg {
|
||||
stroke: currentColor;
|
||||
}
|
||||
|
||||
.nav-item:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
{/* Меню поста */}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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: 'упомянул вас в посте'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue