From c2c1f1c56d533fbfc44b353b9346363e9a99ba38 Mon Sep 17 00:00:00 2001 From: quilin Date: Thu, 11 Dec 2025 21:05:43 +0100 Subject: [PATCH] [DM.Forum] Likes for comments and topics --- .../src/api/requests/forumApi.ts | 4 +- .../src/components/likes/DmLike.vue | 56 +++++++++ .../src/components/ui-kit/DmIconButton.vue | 29 +++-- .../DM.Web.Modern.Temp/src/stores/fora.ts | 10 ++ .../src/views/pages/forum/ForumTopic.vue | 14 ++- .../src/views/pages/forum/TopicsList.vue | 24 ++-- .../src/views/pages/topic/TopicComment.vue | 115 +++++++++++------- .../src/views/pages/topic/TopicPage.vue | 31 ++++- 8 files changed, 207 insertions(+), 76 deletions(-) create mode 100644 frontend/DM.Web.Modern.Temp/src/components/likes/DmLike.vue diff --git a/frontend/DM.Web.Modern.Temp/src/api/requests/forumApi.ts b/frontend/DM.Web.Modern.Temp/src/api/requests/forumApi.ts index 0815cd6e..4f49d71d 100644 --- a/frontend/DM.Web.Modern.Temp/src/api/requests/forumApi.ts +++ b/frontend/DM.Web.Modern.Temp/src/api/requests/forumApi.ts @@ -86,11 +86,11 @@ export default new (class ForumApi { return Api.delete(`forum/comments/${id}`); } - public getCommentForUpdate(id: CommentId) { + public getComment(id: CommentId, renderMode?: BbRenderMode) { return Api.get>( `forum/comments/${id}`, undefined, - BbRenderMode.Bb, + renderMode, ); } diff --git a/frontend/DM.Web.Modern.Temp/src/components/likes/DmLike.vue b/frontend/DM.Web.Modern.Temp/src/components/likes/DmLike.vue new file mode 100644 index 00000000..d3b2308c --- /dev/null +++ b/frontend/DM.Web.Modern.Temp/src/components/likes/DmLike.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/frontend/DM.Web.Modern.Temp/src/components/ui-kit/DmIconButton.vue b/frontend/DM.Web.Modern.Temp/src/components/ui-kit/DmIconButton.vue index 129e843a..d194873f 100644 --- a/frontend/DM.Web.Modern.Temp/src/components/ui-kit/DmIconButton.vue +++ b/frontend/DM.Web.Modern.Temp/src/components/ui-kit/DmIconButton.vue @@ -4,6 +4,7 @@ import { IconType } from "@/components/ui-kit/iconType"; defineProps<{ icon: IconType; loading?: boolean; + disabled?: boolean; type?: "reset" | "submit" | "button"; }>(); @@ -11,9 +12,14 @@ defineProps<{ @@ -22,26 +28,31 @@ defineProps<{ @use "@/assets/styles/Themes" @use "@/assets/styles/Layout" -.icon-button +.icon_button +Layout.square(Variables.$grid-step * 5) + display: inline-block padding: Variables.$tiny + width: initial + min-width: Variables.$grid-step * 5 border: none +Themes.theme(background-color, Themes.$background) +Themes.theme(color, Themes.$active-text) - font-size: Variables.$font-size + font-family: "PT Sans", sans-serif line-height: 1 text-align: center border-radius: Variables.$medium - cursor: pointer + cursor: default - &:hover - +Themes.theme(background-color, Themes.$panel-background-hover) - +Themes.theme(color, Themes.$active-text-hover) + &.icon_button-active + cursor: pointer + &:hover + +Themes.theme(background-color, Themes.$panel-background-hover) + +Themes.theme(color, Themes.$active-text-hover) - &.loading + &.icon_button-loading background-position: center center background-image: url('@/assets/images/loader.gif') background-size: Variables.$medium diff --git a/frontend/DM.Web.Modern.Temp/src/stores/fora.ts b/frontend/DM.Web.Modern.Temp/src/stores/fora.ts index d7e34694..ab8d388d 100644 --- a/frontend/DM.Web.Modern.Temp/src/stores/fora.ts +++ b/frontend/DM.Web.Modern.Temp/src/stores/fora.ts @@ -2,6 +2,7 @@ import { defineStore } from "pinia"; import { ref } from "vue"; import type { Comment, + CommentId, Forum, ForumId, Topic, @@ -106,6 +107,14 @@ export const useForumStore = defineStore("fora", () => { }); comments.value = data; } + async function reloadComment(id: CommentId) { + if (!selectedTopic.value || !comments.value) return; + + const commentIndex = comments.value.resources.findIndex((c) => c.id === id); + if (commentIndex === -1) return; + const { data } = await forumApi.getComment(id); + comments.value.resources[commentIndex] = data!.resource; + } async function createComment(comment: Post) { const result = await forumApi.createComment( selectedTopic.value!.id, @@ -137,6 +146,7 @@ export const useForumStore = defineStore("fora", () => { selectedTopic, fetchComments, reloadComments, + reloadComment, createComment, comments, }; diff --git a/frontend/DM.Web.Modern.Temp/src/views/pages/forum/ForumTopic.vue b/frontend/DM.Web.Modern.Temp/src/views/pages/forum/ForumTopic.vue index e9714ed4..ae0d73cf 100644 --- a/frontend/DM.Web.Modern.Temp/src/views/pages/forum/ForumTopic.vue +++ b/frontend/DM.Web.Modern.Temp/src/views/pages/forum/ForumTopic.vue @@ -15,7 +15,7 @@ const topicDescription = computed(() => {
{ : topic.commentsCount || undefined, }, }" - class="topics-list_row-title" + class="topics_list-row_title" > @@ -42,12 +42,13 @@ const topicDescription = computed(() => {
-
+
{{ topic.commentsCount }} - (+{{ topic.unreadCommentsCount }})
+
{{ topic.likes.length }}
- + diff --git a/frontend/DM.Web.Modern.Temp/src/views/pages/forum/TopicsList.vue b/frontend/DM.Web.Modern.Temp/src/views/pages/forum/TopicsList.vue index 8d7427c0..432ef88e 100644 --- a/frontend/DM.Web.Modern.Temp/src/views/pages/forum/TopicsList.vue +++ b/frontend/DM.Web.Modern.Temp/src/views/pages/forum/TopicsList.vue @@ -17,13 +17,16 @@ const { topics, attachedTopics } = storeToRefs(useForumStore()); :to="{ name: 'forum', params: route.params }" /> -
+
Тема
Дата
Автор
-
+
+
+ +
Последнее сообщение
@@ -37,7 +40,7 @@ const { topics, attachedTopics } = storeToRefs(useForumStore()); Еще не создано ни одной темы (); const commentActions = computed(() => { @@ -44,7 +46,7 @@ const text = ref(null); const initializeEditMode = async () => { if (text.value === null) { loading.value = true; - const { data } = await forumApi.getCommentForUpdate(comment.id); + const { data } = await forumApi.getComment(comment.id, BbRenderMode.Bb); text.value = data!.resource.text; loading.value = false; } @@ -63,47 +65,68 @@ const removeComment = async () => { loading.value = false; await reloadComments(); }; + +const canLike = computed( + () => user.value! && user.value.login !== comment.author.login, +); +const liked = computed(() => + comment.likes.some((u) => u.login === user.value?.login), +); +const like = async () => { + await forumApi.postCommentLike(comment.id); + await reloadComment(comment.id); +}; +const unlike = async () => { + await forumApi.deleteCommentLike(comment.id); + await reloadComment(comment.id); +}; @@ -184,6 +201,8 @@ const removeTopic = async () => { position: relative .topic-actions + display: flex + gap: Variables.$tiny position: absolute bottom: 0 right: 0