♻️ Refactor post list
This commit is contained in:
parent
4a51a85d9c
commit
2b9601640b
@ -27,7 +27,7 @@
|
||||
</article>
|
||||
|
||||
<v-card v-if="post.body?.attachments?.length > 0" class="mb-5">
|
||||
<attachment-carousel :attachments="post.body?.attachments" />
|
||||
<attachment-carousel :no-clickable-attachment="props.noClickableAttachment" :attachments="post.body?.attachments" />
|
||||
</v-card>
|
||||
|
||||
<div class="text-sm flex flex-col">
|
||||
@ -53,6 +53,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ post: any, forceShowContent?: boolean }>()
|
||||
const props = defineProps<{ post: any, forceShowContent?: boolean, noClickableAttachment?: boolean }>()
|
||||
const config = useRuntimeConfig()
|
||||
</script>
|
||||
|
40
components/PostList.vue
Normal file
40
components/PostList.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<v-infinite-scroll :items="posts" :onLoad="loadPost">
|
||||
<template v-for="item in posts" :key="item">
|
||||
<post-item :post="item" no-clickable-attachment />
|
||||
</template>
|
||||
</v-infinite-scroll>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ author?: string, realmId?: number }>()
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const posts = ref<any[]>([])
|
||||
|
||||
async function loadPost({ done }: any) {
|
||||
const searchQueries = new URLSearchParams({
|
||||
take: (10).toString(),
|
||||
offset: posts.value.length.toString(),
|
||||
})
|
||||
|
||||
if (props.author) {
|
||||
searchQueries.set("author", props.author)
|
||||
}
|
||||
if (props.realmId) {
|
||||
searchQueries.set("realmId", props.realmId.toString())
|
||||
}
|
||||
|
||||
const res = await fetch(`${config.public.solarNetworkApi}/cgi/interactive/posts?` + searchQueries)
|
||||
const result = await res.json()
|
||||
|
||||
if (result.data.length > 0) {
|
||||
posts.value.push(...result.data)
|
||||
done("ok")
|
||||
} else {
|
||||
done("empty")
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
32
components/PostReplyList.vue
Normal file
32
components/PostReplyList.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<v-infinite-scroll :items="posts" :onLoad="loadPost">
|
||||
<template v-for="item in posts" :key="item">
|
||||
<post-item :post="item" no-clickable-attachment />
|
||||
</template>
|
||||
</v-infinite-scroll>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ postId: number }>()
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const posts = ref<any[]>([])
|
||||
|
||||
async function loadPost({ done }: any) {
|
||||
const searchQueries = new URLSearchParams({
|
||||
take: (10).toString(),
|
||||
offset: posts.value.length.toString(),
|
||||
})
|
||||
|
||||
const res = await fetch(`${config.public.solarNetworkApi}/cgi/interactive/posts/${props.postId}/replies?` + searchQueries)
|
||||
const result = await res.json()
|
||||
|
||||
if (result.data.length > 0) {
|
||||
posts.value.push(...result.data)
|
||||
done("ok")
|
||||
} else {
|
||||
done("empty")
|
||||
}
|
||||
}
|
||||
</script>
|
@ -7,13 +7,19 @@
|
||||
height="auto"
|
||||
>
|
||||
<v-carousel-item v-for="item in metadata" class="fill-height">
|
||||
<attachment-renderer :item="item" />
|
||||
<nuxt-link v-if="item.mimetype.split('/')[0] == 'image' && !props.noClickableAttachment"
|
||||
:to="`/gallery/${item.id}`">
|
||||
<attachment-renderer :item="item" />
|
||||
</nuxt-link>
|
||||
<div v-else>
|
||||
<attachment-renderer :item="item" />
|
||||
</div>
|
||||
</v-carousel-item>
|
||||
</v-carousel>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ attachments: number[] }>()
|
||||
const props = defineProps<{ attachments: number[], noClickableAttachment?: boolean }>()
|
||||
const emits = defineEmits(["update:metadata"])
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
|
@ -20,7 +20,7 @@
|
||||
<v-img v-else-if="item.mimetype.split('/')[0] == 'image'" :src="getAttachmentUrl(item.id)" :alt="item.alt"
|
||||
class="w-full h-full" cover />
|
||||
<video v-else-if="item.mimetype.split('/')[0] == 'video'" :src="getAttachmentUrl(item.id)" class="w-full h-full"
|
||||
controls />
|
||||
controls @click.stop />
|
||||
<v-sheet v-else color="rgba(0, 0, 0, .4)" height="calc(100% + 24px)" class="p-5">
|
||||
<v-row class="fill-height" align="center" justify="center">
|
||||
<v-col class="text-center">
|
||||
|
@ -6,6 +6,8 @@
|
||||
"navActivityCaption": "Explore our official recent activities.",
|
||||
"navGallery": "Gallery",
|
||||
"navGalleryCaption": "Explore files that uploaded by Solar Network users.",
|
||||
"navPosts": "Posts",
|
||||
"navPostsCaption": "Explore posts that posted by Solar Network users.",
|
||||
"indexIntroduce": "An energetic software company that create wonderful software which everyone love.",
|
||||
"indexProductListHint": "See some of our products just there",
|
||||
"indexActivities": "Activities",
|
||||
@ -54,5 +56,7 @@
|
||||
"callbackHint": "You need to sign in before access that page. After you signed in, you will be redirected to:",
|
||||
"lastUpdatedAt": "Last updated at {0}",
|
||||
"learnMore": "Learn more",
|
||||
"open": "Open"
|
||||
"open": "Open",
|
||||
"postReplies": "Replies",
|
||||
"postRepliesCaption": "All replies of this post"
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
"navActivityCaption": "了解我们官方近期的活动。",
|
||||
"navGallery": "相簿",
|
||||
"navGalleryCaption": "探索整个 Solar Network 上的文件。",
|
||||
"navPosts": "帖子",
|
||||
"navPostsCaption": "探索整个 Solar Network 上的帖子。",
|
||||
"indexIntroduce": "一家充满活力的软件公司,创造了人人喜爱的精彩软件。",
|
||||
"indexProductListHint": "在这里看看我们的一些产品",
|
||||
"indexActivities": "动态",
|
||||
@ -54,5 +56,7 @@
|
||||
"approve": "批准",
|
||||
"lastUpdatedAt": "最后更新于 {0}",
|
||||
"learnMore": "了解更多",
|
||||
"open": "打开"
|
||||
"open": "打开",
|
||||
"postReplies": "回复",
|
||||
"postRepliesCaption": "该帖子的全部回复"
|
||||
}
|
||||
|
@ -5,11 +5,7 @@
|
||||
<span>{{ t("navActivityCaption") }}</span>
|
||||
</div>
|
||||
|
||||
<v-infinite-scroll :items="items" :onLoad="load">
|
||||
<template v-for="item in items" :key="item">
|
||||
<post-item :post="item" />
|
||||
</template>
|
||||
</v-infinite-scroll>
|
||||
<post-list :realm-id="config.public.solarRealmId" />
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
@ -29,17 +25,6 @@ useSeoMeta({
|
||||
})
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const items = ref<any[]>([])
|
||||
|
||||
async function load({ done }: any) {
|
||||
const res = await fetch(`${config.public.solarNetworkApi}/cgi/interactive/posts?take=10&offset=${items.value.length}&realmId=${config.public.solarRealmId}`)
|
||||
const result = await res.json()
|
||||
|
||||
items.value.push(...result.data)
|
||||
|
||||
done("ok")
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -45,10 +45,16 @@
|
||||
<span v-for="tag in post.tags">#{{ tag.alias }}</span>
|
||||
</div>
|
||||
|
||||
<div class="text-xs text-grey flex flex-col">
|
||||
<div class="text-xs text-grey flex flex-col mb-5">
|
||||
<span>Solar Network Post Web Preview</span>
|
||||
<span>To get full view of this post, open it on <a class="underline" :href="externalOpenLink">Solian</a></span>
|
||||
</div>
|
||||
|
||||
<div v-if="post.metric.reply_count" class="mb-5">
|
||||
<v-card variant="outlined" :title="t('postReplies')" :subtitle="t('postRepliesCaption')">
|
||||
<post-reply-list class="mt-[-20px] mx-[-1ch] mb-3" :post-id="post.id" />
|
||||
</v-card>
|
||||
</div>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
@ -60,6 +66,8 @@ const attachments = ref<any[]>([])
|
||||
const firstImage = ref<string | null>()
|
||||
const firstVideo = ref<string | null>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const { data: post } = await useFetch<any>(`${config.public.solarNetworkApi}/cgi/interactive/posts/${route.params.id}`)
|
||||
|
||||
if (!post.value) {
|
||||
|
32
pages/posts/index.vue
Normal file
32
pages/posts/index.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<v-container class="content-container mx-auto">
|
||||
<div class="my-3 mx-[3.5ch]">
|
||||
<h1 class="text-2xl">{{ t("navPosts") }}</h1>
|
||||
<span>{{ t("navPostsCaption") }}</span>
|
||||
</div>
|
||||
|
||||
<post-list />
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { t } = useI18n()
|
||||
|
||||
useHead({
|
||||
title: t("navActivity"),
|
||||
})
|
||||
|
||||
useSeoMeta({
|
||||
title: t("navActivity"),
|
||||
ogTitle: t("navActivity"),
|
||||
description: t("navActivityCaption"),
|
||||
ogDescription: t("navActivityCaption"),
|
||||
ogType: "website",
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.content-container {
|
||||
max-width: 70ch !important;
|
||||
}
|
||||
</style>
|
@ -24,11 +24,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-infinite-scroll :items="posts" :onLoad="loadPost">
|
||||
<template v-for="item in posts" :key="item">
|
||||
<post-item :post="item" />
|
||||
</template>
|
||||
</v-infinite-scroll>
|
||||
<post-list v-if="account" :author="account.name" />
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user