From 376fcb8556253c6b3137f63dff34df5d984dd1d8 Mon Sep 17 00:00:00 2001 From: Foxix Date: Tue, 8 Jul 2025 14:55:20 +0300 Subject: [PATCH] change reactions logic --- .gitignore | 3 +- package.json | 7 +++-- src/routes/reactions.js | 62 ++++++++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 8c94612..3c2e151 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env .env.local -node_modules \ No newline at end of file +node_modules +package-lock.json \ No newline at end of file diff --git a/package.json b/package.json index da92a3d..269e5e3 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,17 @@ }, "dependencies": { "axios": "^1.6.2", + "bcrypt": "^5.1.1", + "cheerio": "^1.0.0-rc.12", "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", - "bcrypt": "^5.1.1", "jsonwebtoken": "^9.0.2", "mongodb": "^6.5.0", + "node-fetch": "^2.7.0", "nodemailer": "^6.9.9", - "uuid": "^9.0.0", - "cheerio": "^1.0.0-rc.12", "swagger-jsdoc": "^6.2.8", + "uuid": "^9.0.0", "vercel": "^39.3.0" }, "devDependencies": { diff --git a/src/routes/reactions.js b/src/routes/reactions.js index ca83113..7404710 100644 --- a/src/routes/reactions.js +++ b/src/routes/reactions.js @@ -1,21 +1,53 @@ const { Router } = require('express'); const { getDb } = require('../db'); const authRequired = require('../middleware/auth'); +const fetch = require('node-fetch'); const router = Router(); -router.use(authRequired); const CUB_API_URL = 'https://cub.rip/api'; 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 { const db = await getDb(); - const { mediaId } = req.params; + const { mediaType, mediaId } = req.params; 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); } catch (err) { console.error('Get user reaction error:', err); @@ -27,47 +59,43 @@ router.get('/:mediaId', async (req, res) => { router.post('/', async (req, res) => { try { const db = await getDb(); - const { mediaId, type } = req.body; + const { mediaId, mediaType, type } = req.body; const userId = req.user.id; - if (!mediaId || !type) { - return res.status(400).json({ error: 'mediaId and type are required' }); + if (!mediaId || !mediaType || !type) { + return res.status(400).json({ error: 'mediaId, mediaType, and type are required' }); } if (!VALID_REACTIONS.includes(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.type === type) { await db.collection('reactions').deleteOne({ _id: existingReaction._id }); - // Не вызываем CUB API, так как у него нет эндпоинта для удаления return res.status(204).send(); } else { - // Если реакция другая - обновляем await db.collection('reactions').updateOne( { _id: existingReaction._id }, { $set: { type, createdAt: new Date() } } ); - // Вызываем CUB API для новой реакции - await fetch(`${CUB_API_URL}/reactions/add/${mediaId}/${type}`); + await fetch(`${CUB_API_URL}/reactions/add/${cubId}/${type}`); const updatedReaction = await db.collection('reactions').findOne({ _id: existingReaction._id }); return res.json(updatedReaction); } } else { - // Если реакции нет - создаем новую const newReaction = { userId, mediaId, + mediaType, type, createdAt: new Date() }; const result = await db.collection('reactions').insertOne(newReaction); - // Вызываем CUB API - await fetch(`${CUB_API_URL}/reactions/add/${mediaId}/${type}`); + await fetch(`${CUB_API_URL}/reactions/add/${cubId}/${type}`); const insertedDoc = await db.collection('reactions').findOne({ _id: result.insertedId }); return res.status(201).json(insertedDoc);