change reactions logic

This commit is contained in:
2025-07-08 14:55:20 +03:00
parent f437caf35b
commit 376fcb8556
3 changed files with 51 additions and 21 deletions

3
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.env .env
.env.local .env.local
node_modules node_modules
package-lock.json

View File

@@ -10,16 +10,17 @@
}, },
"dependencies": { "dependencies": {
"axios": "^1.6.2", "axios": "^1.6.2",
"bcrypt": "^5.1.1",
"cheerio": "^1.0.0-rc.12",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"express": "^4.18.2", "express": "^4.18.2",
"bcrypt": "^5.1.1",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"mongodb": "^6.5.0", "mongodb": "^6.5.0",
"node-fetch": "^2.7.0",
"nodemailer": "^6.9.9", "nodemailer": "^6.9.9",
"uuid": "^9.0.0",
"cheerio": "^1.0.0-rc.12",
"swagger-jsdoc": "^6.2.8", "swagger-jsdoc": "^6.2.8",
"uuid": "^9.0.0",
"vercel": "^39.3.0" "vercel": "^39.3.0"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,21 +1,53 @@
const { Router } = require('express'); const { Router } = require('express');
const { getDb } = require('../db'); const { getDb } = require('../db');
const authRequired = require('../middleware/auth'); const authRequired = require('../middleware/auth');
const fetch = require('node-fetch');
const router = Router(); const router = Router();
router.use(authRequired);
const CUB_API_URL = 'https://cub.rip/api'; const CUB_API_URL = 'https://cub.rip/api';
const VALID_REACTIONS = ['fire', 'nice', 'think', 'bore', 'shit']; const VALID_REACTIONS = ['fire', 'nice', 'think', 'bore', 'shit'];
// --- PUBLIC ROUTE ---
// Получить общее количество реакций для медиа
router.get('/counts/:mediaType/:mediaId', async (req, res) => {
try {
const { mediaType, mediaId } = req.params;
const cubId = `${mediaType}_${mediaId}`;
const response = await fetch(`${CUB_API_URL}/reactions/get/${cubId}`);
if (!response.ok) {
// Если CUB API возвращает ошибку, считаем, что реакций нет
console.error(`CUB API error for ${cubId}:`, response.statusText);
return res.json({ total: 0 });
}
const data = await response.json();
if (!data.secuses || !Array.isArray(data.result)) {
return res.json({ total: 0 });
}
const total = data.result.reduce((sum, reaction) => sum + (reaction.counter || 0), 0);
res.json({ total });
} catch (err) {
console.error('Get total reactions error:', err);
res.status(500).json({ error: 'Failed to get total reactions' });
}
});
// --- AUTH REQUIRED ROUTES ---
router.use(authRequired);
// Получить реакцию текущего пользователя для медиа // Получить реакцию текущего пользователя для медиа
router.get('/:mediaId', async (req, res) => { router.get('/:mediaType/:mediaId', async (req, res) => {
try { try {
const db = await getDb(); const db = await getDb();
const { mediaId } = req.params; const { mediaType, mediaId } = req.params;
const userId = req.user.id; const userId = req.user.id;
const reaction = await db.collection('reactions').findOne({ userId, mediaId }); const reaction = await db.collection('reactions').findOne({ userId, mediaId, mediaType });
res.json(reaction); res.json(reaction);
} catch (err) { } catch (err) {
console.error('Get user reaction error:', err); console.error('Get user reaction error:', err);
@@ -27,47 +59,43 @@ router.get('/:mediaId', async (req, res) => {
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
try { try {
const db = await getDb(); const db = await getDb();
const { mediaId, type } = req.body; const { mediaId, mediaType, type } = req.body;
const userId = req.user.id; const userId = req.user.id;
if (!mediaId || !type) { if (!mediaId || !mediaType || !type) {
return res.status(400).json({ error: 'mediaId and type are required' }); return res.status(400).json({ error: 'mediaId, mediaType, and type are required' });
} }
if (!VALID_REACTIONS.includes(type)) { if (!VALID_REACTIONS.includes(type)) {
return res.status(400).json({ error: 'Invalid reaction type' }); return res.status(400).json({ error: 'Invalid reaction type' });
} }
const existingReaction = await db.collection('reactions').findOne({ userId, mediaId }); const cubId = `${mediaType}_${mediaId}`;
const existingReaction = await db.collection('reactions').findOne({ userId, mediaId, mediaType });
if (existingReaction) { if (existingReaction) {
// Если реакция та же - удаляем (пользователь "отжал" кнопку)
if (existingReaction.type === type) { if (existingReaction.type === type) {
await db.collection('reactions').deleteOne({ _id: existingReaction._id }); await db.collection('reactions').deleteOne({ _id: existingReaction._id });
// Не вызываем CUB API, так как у него нет эндпоинта для удаления
return res.status(204).send(); return res.status(204).send();
} else { } else {
// Если реакция другая - обновляем
await db.collection('reactions').updateOne( await db.collection('reactions').updateOne(
{ _id: existingReaction._id }, { _id: existingReaction._id },
{ $set: { type, createdAt: new Date() } } { $set: { type, createdAt: new Date() } }
); );
// Вызываем CUB API для новой реакции await fetch(`${CUB_API_URL}/reactions/add/${cubId}/${type}`);
await fetch(`${CUB_API_URL}/reactions/add/${mediaId}/${type}`);
const updatedReaction = await db.collection('reactions').findOne({ _id: existingReaction._id }); const updatedReaction = await db.collection('reactions').findOne({ _id: existingReaction._id });
return res.json(updatedReaction); return res.json(updatedReaction);
} }
} else { } else {
// Если реакции нет - создаем новую
const newReaction = { const newReaction = {
userId, userId,
mediaId, mediaId,
mediaType,
type, type,
createdAt: new Date() createdAt: new Date()
}; };
const result = await db.collection('reactions').insertOne(newReaction); const result = await db.collection('reactions').insertOne(newReaction);
// Вызываем CUB API await fetch(`${CUB_API_URL}/reactions/add/${cubId}/${type}`);
await fetch(`${CUB_API_URL}/reactions/add/${mediaId}/${type}`);
const insertedDoc = await db.collection('reactions').findOne({ _id: result.insertedId }); const insertedDoc = await db.collection('reactions').findOne({ _id: result.insertedId });
return res.status(201).json(insertedDoc); return res.status(201).json(insertedDoc);