Fix mobile scroll jump, add comments, rename to Котограм
This commit is contained in:
@@ -62,6 +62,16 @@ export async function initDb(): Promise<SqlJsDatabase> {
|
||||
)
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS comments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
cat_id INTEGER NOT NULL REFERENCES cats(id) ON DELETE CASCADE,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
text TEXT NOT NULL,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
)
|
||||
`);
|
||||
|
||||
saveDb();
|
||||
return db;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import authRoutes from './routes/auth.js';
|
||||
import catRoutes from './routes/cats.js';
|
||||
import likeRoutes from './routes/likes.js';
|
||||
import adminRoutes from './routes/admin.js';
|
||||
import commentRoutes from './routes/comments.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -25,14 +26,15 @@ async function main() {
|
||||
app.use('/api/auth', authRoutes);
|
||||
app.use('/api/cats', catRoutes);
|
||||
app.use('/api/likes', likeRoutes);
|
||||
app.use('/api/admin', adminRoutes);
|
||||
app.use('/api/comments', commentRoutes);
|
||||
app.use('/api/admin', adminRoutes);
|
||||
|
||||
app.get('/api/health', (_req, res) => {
|
||||
res.json({ status: 'ok' });
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Catstagram server running on http://localhost:${PORT}`);
|
||||
console.log(`Котограм server running on http://localhost:${PORT}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ router.get('/', (req: AuthRequest, res: Response) => {
|
||||
const cats = queryAll(
|
||||
`SELECT c.id, c.image_url, c.caption, c.created_at, c.user_id,
|
||||
u.username, u.points AS user_points,
|
||||
(SELECT COUNT(*) FROM likes WHERE cat_id = c.id) AS likes_count
|
||||
(SELECT COUNT(*) FROM likes WHERE cat_id = c.id) AS likes_count,
|
||||
(SELECT COUNT(*) FROM comments WHERE cat_id = c.id) AS comments_count
|
||||
FROM cats c
|
||||
JOIN users u ON u.id = c.user_id
|
||||
ORDER BY c.created_at DESC
|
||||
@@ -55,7 +56,8 @@ router.get('/user/:userId', (req: AuthRequest, res: Response) => {
|
||||
const cats = queryAll(
|
||||
`SELECT c.id, c.image_url, c.caption, c.created_at, c.user_id,
|
||||
u.username, u.points AS user_points,
|
||||
(SELECT COUNT(*) FROM likes WHERE cat_id = c.id) AS likes_count
|
||||
(SELECT COUNT(*) FROM likes WHERE cat_id = c.id) AS likes_count,
|
||||
(SELECT COUNT(*) FROM comments WHERE cat_id = c.id) AS comments_count
|
||||
FROM cats c
|
||||
JOIN users u ON u.id = c.user_id
|
||||
WHERE c.user_id = ?
|
||||
@@ -70,7 +72,8 @@ router.get('/:id', (req: AuthRequest, res: Response) => {
|
||||
const cat = queryOne(
|
||||
`SELECT c.id, c.image_url, c.caption, c.created_at, c.user_id,
|
||||
u.username, u.points AS user_points,
|
||||
(SELECT COUNT(*) FROM likes WHERE cat_id = c.id) AS likes_count
|
||||
(SELECT COUNT(*) FROM likes WHERE cat_id = c.id) AS likes_count,
|
||||
(SELECT COUNT(*) FROM comments WHERE cat_id = c.id) AS comments_count
|
||||
FROM cats c
|
||||
JOIN users u ON u.id = c.user_id
|
||||
WHERE c.id = ?`,
|
||||
@@ -104,7 +107,8 @@ router.post('/', authMiddleware, upload.single('image'), (req: AuthRequest, res:
|
||||
const cat = queryOne(
|
||||
`SELECT c.id, c.image_url, c.caption, c.created_at, c.user_id,
|
||||
u.username, u.points AS user_points,
|
||||
0 AS likes_count
|
||||
0 AS likes_count,
|
||||
0 AS comments_count
|
||||
FROM cats c
|
||||
JOIN users u ON u.id = c.user_id
|
||||
WHERE c.id = (SELECT MAX(id) FROM cats WHERE user_id = ?)`,
|
||||
@@ -125,6 +129,7 @@ router.delete('/:id', authMiddleware, (req: AuthRequest, res: Response) => {
|
||||
return;
|
||||
}
|
||||
|
||||
execute('DELETE FROM comments WHERE cat_id = ?', [req.params.id]);
|
||||
execute('DELETE FROM likes WHERE cat_id = ?', [req.params.id]);
|
||||
execute('DELETE FROM cats WHERE id = ?', [req.params.id]);
|
||||
res.json({ ok: true });
|
||||
|
||||
74
server/src/routes/comments.ts
Normal file
74
server/src/routes/comments.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { Router, Response } from 'express';
|
||||
import { queryAll, queryOne, execute } from '../db';
|
||||
import { authMiddleware, AuthRequest } from '../middleware/auth.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/:catId', (req: AuthRequest, res: Response) => {
|
||||
const catId = parseInt(req.params.catId);
|
||||
const comments = queryAll(
|
||||
`SELECT c.id, c.text, c.created_at, c.user_id, u.username
|
||||
FROM comments c
|
||||
JOIN users u ON u.id = c.user_id
|
||||
WHERE c.cat_id = ?
|
||||
ORDER BY c.created_at ASC`,
|
||||
[catId]
|
||||
);
|
||||
res.json({ comments });
|
||||
});
|
||||
|
||||
router.post('/:catId', authMiddleware, (req: AuthRequest, res: Response) => {
|
||||
const catId = parseInt(req.params.catId);
|
||||
const userId = req.userId!;
|
||||
const text = (req.body.text || '').trim();
|
||||
|
||||
if (!text) {
|
||||
res.status(400).json({ error: 'Комментарий не может быть пустым' });
|
||||
return;
|
||||
}
|
||||
if (text.length > 500) {
|
||||
res.status(400).json({ error: 'Комментарий слишком длинный' });
|
||||
return;
|
||||
}
|
||||
|
||||
const cat = queryOne('SELECT id FROM cats WHERE id = ?', [catId]);
|
||||
if (!cat) {
|
||||
res.status(404).json({ error: 'Пост не найден' });
|
||||
return;
|
||||
}
|
||||
|
||||
const result = execute(
|
||||
'INSERT INTO comments (cat_id, user_id, text) VALUES (?, ?, ?)',
|
||||
[catId, userId, text]
|
||||
);
|
||||
|
||||
const comment = queryOne(
|
||||
`SELECT c.id, c.text, c.created_at, c.user_id, u.username
|
||||
FROM comments c
|
||||
JOIN users u ON u.id = c.user_id
|
||||
WHERE c.id = ?`,
|
||||
[result.lastInsertRowid]
|
||||
);
|
||||
|
||||
res.status(201).json({ comment });
|
||||
});
|
||||
|
||||
router.delete('/:commentId', authMiddleware, (req: AuthRequest, res: Response) => {
|
||||
const commentId = parseInt(req.params.commentId);
|
||||
const comment = queryOne('SELECT user_id FROM comments WHERE id = ?', [commentId]);
|
||||
|
||||
if (!comment) {
|
||||
res.status(404).json({ error: 'Комментарий не найден' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (comment.user_id !== req.userId && !req.isAdmin) {
|
||||
res.status(403).json({ error: 'Нельзя удалить чужой комментарий' });
|
||||
return;
|
||||
}
|
||||
|
||||
execute('DELETE FROM comments WHERE id = ?', [commentId]);
|
||||
res.json({ ok: true });
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user