✨ Comments
This commit is contained in:
20
pkg/views/src/components/posts/CommentContent.vue
Normal file
20
pkg/views/src/components/posts/CommentContent.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<article class="prose prose-comment" v-html="parseContent(props.item.content)" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import dompurify from "dompurify";
|
||||
import { parse } from "marked";
|
||||
|
||||
const props = defineProps<{ item: any }>();
|
||||
|
||||
function parseContent(src: string): string {
|
||||
return dompurify().sanitize(parse(src) as string);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.prose.prose-comment p {
|
||||
margin: 0 !important;
|
||||
}
|
||||
</style>
|
@ -1,60 +1,61 @@
|
||||
<template>
|
||||
<v-card :loading="props.loading">
|
||||
<template #text>
|
||||
<div class="flex gap-3">
|
||||
<div>
|
||||
<v-avatar
|
||||
color="grey-lighten-2"
|
||||
icon="mdi-account-circle"
|
||||
class="rounded-card"
|
||||
:src="props.item?.author.avatar"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<div>
|
||||
<v-avatar
|
||||
color="grey-lighten-2"
|
||||
icon="mdi-account-circle"
|
||||
class="rounded-card"
|
||||
:src="props.item?.author.avatar"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow-1">
|
||||
<div class="font-bold">{{ props.item?.author.nick }}</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="font-bold">{{ props.item?.author.nick }}</div>
|
||||
|
||||
<div v-if="props.item?.model_type === 'article'" class="text-xs text-grey-darken-4 mb-2">Published an
|
||||
article
|
||||
</div>
|
||||
|
||||
<component :is="renderer[props.item?.model_type]" v-bind="props" />
|
||||
|
||||
<post-reaction
|
||||
size="small"
|
||||
:item="props.item"
|
||||
:model="props.item?.model_type ? props.item?.model_type + 's' : 'articles'"
|
||||
:reactions="props.item?.reaction_list ?? {}"
|
||||
@update="updateReactions"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="props.item?.model_type === 'article'" class="text-xs text-grey-darken-4 mb-2">
|
||||
Published an article
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
|
||||
<component :is="renderer[props.item?.model_type]" v-bind="props" />
|
||||
|
||||
<post-reaction
|
||||
size="small"
|
||||
:item="props.item"
|
||||
:model="props.item?.model_type ? props.item?.model_type + 's' : 'articles'"
|
||||
:reactions="props.item?.reaction_list ?? {}"
|
||||
@update="updateReactions"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Component } from "vue";
|
||||
import ArticleContent from "@/components/posts/ArticleContent.vue";
|
||||
import MomentContent from "@/components/posts/MomentContent.vue";
|
||||
import PostReaction from "@/components/posts/PostReaction.vue";
|
||||
import type { Component } from "vue"
|
||||
import ArticleContent from "@/components/posts/ArticleContent.vue"
|
||||
import MomentContent from "@/components/posts/MomentContent.vue"
|
||||
import CommentContent from "@/components/posts/CommentContent.vue"
|
||||
import PostReaction from "@/components/posts/PostReaction.vue"
|
||||
|
||||
const props = defineProps<{ item: any, brief?: boolean, loading?: boolean }>();
|
||||
const emits = defineEmits(["update:item"]);
|
||||
const props = defineProps<{ item: any; brief?: boolean }>()
|
||||
const emits = defineEmits(["update:item"])
|
||||
|
||||
const renderer: { [id: string]: Component } = {
|
||||
article: ArticleContent,
|
||||
moment: MomentContent
|
||||
};
|
||||
moment: MomentContent,
|
||||
comment: CommentContent
|
||||
}
|
||||
|
||||
function updateReactions(symbol: string, num: number) {
|
||||
const item = JSON.parse(JSON.stringify(props.item));
|
||||
if (item.reaction_list.hasOwnProperty(symbol)) {
|
||||
item.reaction_list[symbol] += num;
|
||||
} else {
|
||||
item.reaction_list[symbol] = num;
|
||||
const item = JSON.parse(JSON.stringify(props.item))
|
||||
if (item.reaction_list == null) {
|
||||
item.reaction_list = {}
|
||||
}
|
||||
emits("update:item", item);
|
||||
if (item.reaction_list.hasOwnProperty(symbol)) {
|
||||
item.reaction_list[symbol] += num
|
||||
} else {
|
||||
item.reaction_list[symbol] = num
|
||||
}
|
||||
emits("update:item", item)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -7,7 +7,11 @@
|
||||
<v-infinite-scroll :items="props.posts" :onLoad="props.loader">
|
||||
<template v-for="(item, idx) in props.posts" :key="item">
|
||||
<div class="mb-3 px-1">
|
||||
<post-item brief :item="item" @update:item="val => updateItem(idx, val)" />
|
||||
<v-card>
|
||||
<template #text>
|
||||
<post-item brief :item="item" @update:item="val => updateItem(idx, val)" />
|
||||
</template>
|
||||
</v-card>
|
||||
</div>
|
||||
</template>
|
||||
</v-infinite-scroll>
|
||||
|
@ -43,7 +43,7 @@ const emits = defineEmits(["update"]);
|
||||
const props = defineProps<{
|
||||
size?: string,
|
||||
readonly?: boolean,
|
||||
model: string,
|
||||
model: any,
|
||||
item: any,
|
||||
reactions: { [id: string]: number }
|
||||
}>();
|
||||
@ -63,7 +63,7 @@ const status = reactive({ added: false, removed: false });
|
||||
const error = ref<string | null>(null);
|
||||
|
||||
async function reactPost(symbol: string, attitude: number) {
|
||||
const res = await request(`/api/${props.model}/${props.item?.id}/react`, {
|
||||
const res = await request(`/api/p/${props.model}/${props.item?.id}/react`, {
|
||||
method: "POST",
|
||||
headers: { "Authorization": `Bearer ${getAtk()}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ symbol, attitude })
|
||||
|
Reference in New Issue
Block a user