mirror of
https://github.com/Radiquum/AniX.git
synced 2025-04-07 00:34:41 +00:00
feat: add comment voting
This commit is contained in:
parent
b5520cb06c
commit
fc1d3d26f6
3 changed files with 106 additions and 14 deletions
6
TODO.md
6
TODO.md
|
@ -60,8 +60,8 @@
|
||||||
- [ ] Переход на страницу пользователя оставившего комментарий
|
- [ ] Переход на страницу пользователя оставившего комментарий
|
||||||
- [ ] Отправление комментариев
|
- [ ] Отправление комментариев
|
||||||
- [ ] Отправление ответов
|
- [ ] Отправление ответов
|
||||||
- [ ] Оценка комментариев
|
- [X] Оценка комментариев
|
||||||
- [ ] Метка комментариев как споилер
|
- [ ] Метка комментариев как спойлер
|
||||||
- [X] Сохранение эпизода в историю просмотров
|
- [X] Сохранение эпизода в историю просмотров
|
||||||
- [X] Добавление \ Удаление аниме в\из списков закладок и избранных
|
- [X] Добавление \ Удаление аниме в\из списков закладок и избранных
|
||||||
- [X] Связанные релизы
|
- [X] Связанные релизы
|
||||||
|
@ -83,4 +83,4 @@
|
||||||
|
|
||||||
- [ ] документация API Anixart
|
- [ ] документация API Anixart
|
||||||
- [ ] Уведомление о том что мы не связаны с аниксарт при первом открытии
|
- [ ] Уведомление о том что мы не связаны с аниксарт при первом открытии
|
||||||
- [ ] Использование PWA
|
- [X] Использование PWA
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { unixToDate } from "#/api/utils";
|
import { unixToDate } from "#/api/utils";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { ENDPOINTS } from "#/api/config";
|
import { ENDPOINTS } from "#/api/config";
|
||||||
|
import { Button } from "flowbite-react";
|
||||||
|
|
||||||
export const CommentsComment = (props: {
|
export const CommentsComment = (props: {
|
||||||
profile: { login: string; avatar: string; id: number };
|
profile: { login: string; avatar: string; id: number };
|
||||||
|
@ -8,17 +9,24 @@ export const CommentsComment = (props: {
|
||||||
id: number;
|
id: number;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
message: string;
|
message: string;
|
||||||
likes: number;
|
|
||||||
reply_count: number;
|
reply_count: number;
|
||||||
|
likes_count: number;
|
||||||
|
vote: number;
|
||||||
};
|
};
|
||||||
isSubComment?: boolean;
|
isSubComment?: boolean;
|
||||||
|
token: string | null;
|
||||||
}) => {
|
}) => {
|
||||||
const [replies, setReplies] = useState([]);
|
const [replies, setReplies] = useState([]);
|
||||||
|
const [likes, setLikes] = useState(props.comment.likes_count);
|
||||||
|
const [vote, setVote] = useState(props.comment.vote);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function _fetchReplies() {
|
async function _fetchReplies() {
|
||||||
await fetch(
|
let url = `${ENDPOINTS.release.info}/comment/replies/${props.comment.id}/0?sort=2`;
|
||||||
`${ENDPOINTS.release.info}/comment/replies/${props.comment.id}/0?sort=2`
|
if (props.token) {
|
||||||
)
|
url += `&token=${props.token}`;
|
||||||
|
}
|
||||||
|
await fetch(url)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setReplies(data.content);
|
setReplies(data.content);
|
||||||
|
@ -29,6 +37,44 @@ export const CommentsComment = (props: {
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
async function _sendVote(action: number) {
|
||||||
|
if (props.token) {
|
||||||
|
let url = `${ENDPOINTS.release.info}/comment/vote/${props.comment.id}/${action}?token=${props.token}`;
|
||||||
|
fetch(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make it readable
|
||||||
|
function _updateVote(action: string) {
|
||||||
|
if (action === "like" && vote == 0) {
|
||||||
|
setVote(2);
|
||||||
|
setLikes(likes + 1);
|
||||||
|
_sendVote(2);
|
||||||
|
} else if (action === "dislike" && vote == 0) {
|
||||||
|
setVote(1);
|
||||||
|
setLikes(likes - 1);
|
||||||
|
_sendVote(1);
|
||||||
|
} else if (action === "like" && vote == 1) {
|
||||||
|
setVote(2);
|
||||||
|
setLikes(likes + 2);
|
||||||
|
_sendVote(2);
|
||||||
|
} else if (action === "dislike" && vote == 2) {
|
||||||
|
setVote(1);
|
||||||
|
setLikes(likes - 2);
|
||||||
|
_sendVote(1);
|
||||||
|
} else {
|
||||||
|
setVote(0);
|
||||||
|
_sendVote(0);
|
||||||
|
if (action === "dislike" && vote == 1) {
|
||||||
|
setLikes(likes + 1);
|
||||||
|
} else if (action === "like" && vote == 2) {
|
||||||
|
setLikes(likes - 1);
|
||||||
|
} else {
|
||||||
|
setLikes(props.comment.likes_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className="p-6 text-sm bg-white rounded-lg sm:text-base dark:bg-gray-900">
|
<article className="p-6 text-sm bg-white rounded-lg sm:text-base dark:bg-gray-900">
|
||||||
<footer className="flex items-center justify-between mb-2">
|
<footer className="flex items-center justify-between mb-2">
|
||||||
|
@ -54,7 +100,7 @@ export const CommentsComment = (props: {
|
||||||
<p className="text-gray-500 whitespace-pre-wrap dark:text-gray-400">
|
<p className="text-gray-500 whitespace-pre-wrap dark:text-gray-400">
|
||||||
{props.comment.message}
|
{props.comment.message}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center mt-4 space-x-4">
|
<div className="flex items-center justify-between mt-4 space-x-4">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="flex items-center text-sm font-medium text-gray-500 hover:underline dark:text-gray-400"
|
className="flex items-center text-sm font-medium text-gray-500 hover:underline dark:text-gray-400"
|
||||||
|
@ -76,6 +122,51 @@ export const CommentsComment = (props: {
|
||||||
</svg>
|
</svg>
|
||||||
Ответить
|
Ответить
|
||||||
</button>
|
</button>
|
||||||
|
<div className="flex items-center">
|
||||||
|
{props.token && (
|
||||||
|
<Button
|
||||||
|
color="inline"
|
||||||
|
onClick={() => {
|
||||||
|
_updateVote("dislike");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={`w-6 h-6 iconify mdi--dislike ${
|
||||||
|
vote == 1
|
||||||
|
? "text-red-500 dark:text-red-400"
|
||||||
|
: "text-gray-500 dark:text-gray-400"
|
||||||
|
}`}
|
||||||
|
></span>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<p
|
||||||
|
className={`text-sm font-medium ${
|
||||||
|
likes > 0
|
||||||
|
? "text-green-500 dark:text-green-400"
|
||||||
|
: likes < 0
|
||||||
|
? "text-red-500 dark:text-red-400"
|
||||||
|
: "text-gray-500 dark:text-gray-400"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{likes}
|
||||||
|
</p>
|
||||||
|
{props.token && (
|
||||||
|
<Button
|
||||||
|
color="inline"
|
||||||
|
onClick={() => {
|
||||||
|
_updateVote("like");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={`w-6 h-6 iconify mdi--like ${
|
||||||
|
vote == 2
|
||||||
|
? "text-green-500 dark:text-green-400"
|
||||||
|
: "text-gray-500 dark:text-gray-400"
|
||||||
|
}`}
|
||||||
|
></span>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{replies.length > 0 &&
|
{replies.length > 0 &&
|
||||||
replies.map((comment: any) => (
|
replies.map((comment: any) => (
|
||||||
|
@ -86,10 +177,12 @@ export const CommentsComment = (props: {
|
||||||
id: comment.id,
|
id: comment.id,
|
||||||
timestamp: comment.timestamp,
|
timestamp: comment.timestamp,
|
||||||
message: comment.message,
|
message: comment.message,
|
||||||
likes: comment.likes_count,
|
|
||||||
reply_count: comment.reply_count,
|
reply_count: comment.reply_count,
|
||||||
|
likes_count: comment.likes_count,
|
||||||
|
vote: comment.vote,
|
||||||
}}
|
}}
|
||||||
isSubComment={true}
|
isSubComment={true}
|
||||||
|
token={props.token}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -37,10 +37,7 @@ export const CommentsMain = (props: {
|
||||||
required
|
required
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button type="submit" color="blue">
|
||||||
type="submit"
|
|
||||||
color="blue"
|
|
||||||
>
|
|
||||||
Оставить комментарий
|
Оставить комментарий
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -53,9 +50,11 @@ export const CommentsMain = (props: {
|
||||||
id: comment.id,
|
id: comment.id,
|
||||||
timestamp: comment.timestamp,
|
timestamp: comment.timestamp,
|
||||||
message: comment.message,
|
message: comment.message,
|
||||||
likes: comment.likes_count,
|
|
||||||
reply_count: comment.reply_count,
|
reply_count: comment.reply_count,
|
||||||
|
likes_count: comment.likes_count,
|
||||||
|
vote: comment.vote,
|
||||||
}}
|
}}
|
||||||
|
token={props.token}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue