Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions frontend/DM.Web.Modern.Temp/src/api/requests/forumApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Envelope<Comment>>(
`forum/comments/${id}`,
undefined,
BbRenderMode.Bb,
renderMode,
);
}

Expand Down
56 changes: 56 additions & 0 deletions frontend/DM.Web.Modern.Temp/src/components/likes/DmLike.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { IconType } from "@/components/ui-kit/iconType";
import { computed } from "vue";
import type { Served } from "@/api/models";
import type { User } from "@/api/models/community";
import DmIconButton from "@/components/ui-kit/DmIconButton.vue";
import DmIcon from "@/components/ui-kit/DmIcon.vue";

interface Likeable {
likes: Served<User[]>;
author: Served<User>;
}

const props = defineProps<{
entity: Likeable;
user: User | null;
}>();
const emit = defineEmits(["liked", "unliked"]);

const canInteract = computed(
() => !!props.user && props.user.login !== props.entity.author.login,
);
const userLiked = computed(() =>
props.entity.likes.some((liker) => liker.login === props.user?.login),
);
</script>

<template>
<dm-icon-button v-show="canInteract || entity.likes.length"
:class="['like', canInteract && 'like-likeable', userLiked && 'like-liked']"
:icon="IconType.Like"
:disabled="!canInteract"
@click="emit(userLiked ? 'unliked' : 'liked')"
>
<template v-if="entity.likes.length">
<span class="like-counter">{{ entity.likes.length }}</span>
</template>
</dm-icon-button>
</template>

<style scoped lang="sass">
@use "@/assets/styles/Variables"

.like
opacity: 0.7
cursor: default

&.like-likeable
cursor: pointer
&:hover, &.like-liked
opacity: 1

.like-counter
display: inline-block
margin-left: Variables.$tiny
</style>
29 changes: 20 additions & 9 deletions frontend/DM.Web.Modern.Temp/src/components/ui-kit/DmIconButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@ import { IconType } from "@/components/ui-kit/iconType";
defineProps<{
icon: IconType;
loading?: boolean;
disabled?: boolean;
type?: "reset" | "submit" | "button";
}>();
</script>

<template>
<button
:type="type ?? 'button'"
:class="['icon-button', loading && 'loading']"
:disabled="disabled"
:class="[
'icon_button',
loading && 'icon_button-loading',
!disabled && 'icon_button-active',
]"
>
<dm-icon :font="icon" />
<dm-icon :font="icon" /><slot />
</button>
</template>

Expand All @@ -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
Expand Down
10 changes: 10 additions & 0 deletions frontend/DM.Web.Modern.Temp/src/stores/fora.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineStore } from "pinia";
import { ref } from "vue";
import type {
Comment,
CommentId,
Forum,
ForumId,
Topic,
Expand Down Expand Up @@ -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<Comment>) {
const result = await forumApi.createComment(
selectedTopic.value!.id,
Expand Down Expand Up @@ -137,6 +146,7 @@ export const useForumStore = defineStore("fora", () => {
selectedTopic,
fetchComments,
reloadComments,
reloadComment,
createComment,
comments,
};
Expand Down
14 changes: 9 additions & 5 deletions frontend/DM.Web.Modern.Temp/src/views/pages/forum/ForumTopic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const topicDescription = computed(() => {
<div
:key="topic.id"
:class="{
'topics-list_row': true,
'topics_list-row': true,
closed: topic.closed,
attached: topic.attached,
}"
Expand All @@ -31,7 +31,7 @@ const topicDescription = computed(() => {
: topic.commentsCount || undefined,
},
}"
class="topics-list_row-title"
class="topics_list-row_title"
>
<dm-icon v-if="topic.attached" :font="IconType.Pinned" />
<dm-icon v-if="topic.closed" :font="IconType.Closed" />
Expand All @@ -42,12 +42,13 @@ const topicDescription = computed(() => {
</router-link>
<div><human-date :date="topic.created!" format="DD.MM.YYYY" /></div>
<div><user-link :user="topic.author!" /></div>
<div>
<div class="topics_list-counter">
{{ topic.commentsCount }}
<span class="topics-list_row-unread" v-if="topic.unreadCommentsCount"
<span class="topics_list-row_unread" v-if="topic.unreadCommentsCount"
>(+{{ topic.unreadCommentsCount }})</span
>
</div>
<div class="topics_list-counter">{{ topic.likes.length }}</div>
<div>
<template v-if="topic.lastComment">
<user-link :user="topic.lastComment.author" />,
Expand All @@ -64,4 +65,7 @@ const topicDescription = computed(() => {
</div>
</template>

<style scoped lang="sass"></style>
<style scoped lang="sass">
.topics_list-counter
text-align: center
</style>
24 changes: 15 additions & 9 deletions frontend/DM.Web.Modern.Temp/src/views/pages/forum/TopicsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ const { topics, attachedTopics } = storeToRefs(useForumStore());
:to="{ name: 'forum', params: route.params }"
/>

<div class="topics-list_header">
<div class="topics_list-header">
<div>Тема</div>
<div>Дата</div>
<div>Автор</div>
<div>
<div class="topics_list-counter">
<dm-icon :font="IconType.CommentsNoUnread" />
</div>
<div class="topics_list-counter">
<dm-icon :font="IconType.Like" />
</div>
<div>Последнее сообщение</div>
</div>

Expand All @@ -37,7 +40,7 @@ const { topics, attachedTopics } = storeToRefs(useForumStore());
<dm-loader v-if="!topics || attachedTopics === null" :big="true" />
<secondary-text
v-else-if="topics.resources.length + attachedTopics.length === 0"
class="topics-list_none"
class="topics_list-none"
>Еще не создано ни одной темы</secondary-text
>
<forum-topic
Expand All @@ -52,12 +55,15 @@ const { topics, attachedTopics } = storeToRefs(useForumStore());
@use "@/assets/styles/Variables"
@use "@/assets/styles/Themes"
@use "@/assets/styles/Grid"
$grid-template: [title] 40% [date] 12% [author] 14% [count] auto [lastComment] 26%
$grid-template: [title] 35% [date] 12% [author] 14% [count] 1fr [likes] 1fr [lastComment] 26%

.topics-list_header
.topics_list-header
+Grid.grid-head($grid-template)

.topics-list_row
.topics_list-counter
text-align: center

.topics_list-row
+Grid.grid($grid-template)
&:hover
+Themes.theme(background-color, Themes.$panel-background-hover)
Expand All @@ -66,16 +72,16 @@ $grid-template: [title] 40% [date] 12% [author] 14% [count] auto [lastComment] 2
&.attached
opacity: initial

.topics-list_row-title
.topics_list-row_title
display: block
position: relative
& .attached
font-weight: bold

.topics-list_row-unread
.topics_list-row_unread
font-weight: bold

.topics-list_none
.topics_list-none
display: block
margin: Variables.$medium 0
text-align: center
Expand Down
Loading