-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
503 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
<template> | ||
<ToLoading v-model="loading" :title="loadingTitle" /> | ||
<v-app-bar> | ||
<template #prepend> | ||
<div class="post-topic-top" v-if="topicInfo"> | ||
<img :src="topicInfo.topic.cover" alt="cover" /> | ||
<div class="post-topic-info"> | ||
<span>{{ topicInfo.topic.name }}({{ topic }})</span> | ||
<span>{{ topicInfo.topic.desc }}</span> | ||
</div> | ||
</div> | ||
</template> | ||
<template #extension> | ||
<TGameNav :model-value="curGid" v-if="curGid !== 0" /> | ||
</template> | ||
<div class="post-topic-switch"> | ||
<v-select | ||
v-model="curGame" | ||
class="post-switch-item" | ||
:items="topicInfo?.game_info_list" | ||
item-title="name" | ||
:item-value="(item) => item" | ||
variant="outlined" | ||
label="分区" | ||
/> | ||
<v-select | ||
v-model="curSortType" | ||
class="post-switch-item" | ||
:items="sortOrderList" | ||
item-title="text" | ||
item-value="value" | ||
variant="outlined" | ||
label="排序" | ||
/> | ||
<v-text-field | ||
v-model="search" | ||
class="post-switch-item" | ||
append-inner-icon="mdi-magnify" | ||
label="请输入帖子 ID 或搜索词" | ||
variant="outlined" | ||
:single-line="true" | ||
:hide-details="true" | ||
@click:append="searchPost" | ||
@keyup.enter="searchPost" | ||
/> | ||
<v-btn :rounded="true" class="post-fresh-btn" @click="freshPostData()"> | ||
<v-icon>mdi-refresh</v-icon> | ||
<span>刷新</span> | ||
</v-btn> | ||
</div> | ||
</v-app-bar> | ||
<div class="post-topic-grid"> | ||
<div v-for="post in posts" :key="post.post.post_id"> | ||
<TPostCard :model-value="post" v-if="post" /> | ||
</div> | ||
</div> | ||
<div class="load-more"> | ||
<v-btn class="post-topic-btn" :rounded="true" @click="freshPostData()"> | ||
已加载:{{ posts.length }},加载更多 | ||
</v-btn> | ||
</div> | ||
<ToPostSearch :gid="curGid.toString()" v-model="showSearch" :keyword="search" /> | ||
</template> | ||
<script lang="ts" setup> | ||
import { onMounted, ref, toRaw, watch } from "vue"; | ||
import { useRoute } from "vue-router"; | ||
import showSnackbar from "../../components/func/snackbar.js"; | ||
import TGameNav from "../../components/main/t-gamenav.vue"; | ||
import TPostCard from "../../components/main/t-postcard.vue"; | ||
import ToLoading from "../../components/overlay/to-loading.vue"; | ||
import ToPostSearch from "../../components/post/to-postSearch.vue"; | ||
import Mys from "../../plugins/Mys/index.js"; | ||
import { createPost } from "../../utils/TGWindow.js"; | ||
const gid = <string>useRoute().params.gid; | ||
const topic = <string>useRoute().params.topic; | ||
const loading = ref<boolean>(false); | ||
const loadingTitle = ref<string>(""); | ||
const showSearch = ref<boolean>(false); | ||
const curGid = ref<number>(Number(gid)); | ||
const curSortType = ref<0 | 1 | 2>(0); | ||
const search = ref<string>(""); | ||
const topicInfo = ref<TGApp.Plugins.Mys.Topic.InfoData>(); | ||
const posts = ref<TGApp.Plugins.Mys.Post.FullData[]>([]); | ||
const lastPostId = ref<string>(); | ||
const isLastPage = ref<boolean>(false); | ||
const curGame = ref<TGApp.Plugins.Mys.Topic.GameInfo>(); | ||
type SortSelect = { text: string; value: number }; | ||
// todo 根据实际情况修改 | ||
const sortOrderList: SortSelect[] = [ | ||
{ text: "默认排序", value: 0 }, | ||
{ text: "按时间排序", value: 1 }, | ||
{ text: "按热度排序", value: 2 }, | ||
]; | ||
onMounted(async () => await firstLoad()); | ||
watch( | ||
() => curGame.value, | ||
async () => await firstLoad(), | ||
); | ||
watch( | ||
() => curSortType.value, | ||
async () => await firstLoad(), | ||
); | ||
async function firstLoad(): Promise<void> { | ||
loading.value = true; | ||
loadingTitle.value = `正在加载话题${topic}信息`; | ||
const info = await Mys.Post.getTopicFullInfo(gid, topic); | ||
if ("retcode" in info) { | ||
showSnackbar.error(`[${info.retcode}] ${info.message}`); | ||
loading.value = false; | ||
return; | ||
} | ||
topicInfo.value = info; | ||
if (curGame.value === undefined) { | ||
curGame.value = toRaw(info.game_info_list.find((i) => i.id === curGid.value)); | ||
} | ||
if (curGame.value === undefined) curGame.value = info.game_info_list[0]; | ||
loadingTitle.value = `正在加载${curGame.value.name}帖子列表`; | ||
const postList = await Mys.Post.getTopicPostList(gid, topic); | ||
if ("retcode" in postList) { | ||
showSnackbar.error(`[${postList.retcode}] ${postList.message}`); | ||
loading.value = false; | ||
return; | ||
} | ||
isLastPage.value = postList.is_last; | ||
lastPostId.value = postList.last_id; | ||
posts.value = postList.posts; | ||
loading.value = false; | ||
showSnackbar.success(`加载了 ${postList.posts.length} 条帖子`); | ||
} | ||
async function freshPostData(): Promise<void> { | ||
if (isLastPage.value) { | ||
showSnackbar.warn("已经到底了"); | ||
return; | ||
} | ||
loading.value = true; | ||
loadingTitle.value = "正在加载帖子列表"; | ||
const postList = await Mys.Post.getTopicPostList(gid, topic, curSortType.value, lastPostId.value); | ||
if ("retcode" in postList) { | ||
showSnackbar.error(`[${postList.retcode}] ${postList.message}`); | ||
loading.value = false; | ||
return; | ||
} | ||
isLastPage.value = postList.is_last; | ||
lastPostId.value = postList.last_id; | ||
posts.value = posts.value.concat(postList.posts); | ||
loading.value = false; | ||
showSnackbar.success(`加载了 ${postList.posts.length} 条帖子`); | ||
} | ||
function searchPost(): void { | ||
if (search.value === "") { | ||
showSnackbar.warn("请输入搜索内容"); | ||
return; | ||
} | ||
const numCheck = Number(search.value); | ||
if (isNaN(numCheck)) showSearch.value = true; | ||
else createPost(search.value); | ||
} | ||
</script> | ||
<style lang="css" scoped> | ||
.post-topic-top { | ||
display: flex; | ||
overflow: hidden; | ||
align-items: center; | ||
justify-content: center; | ||
padding-right: 5px; | ||
border-radius: 5px; | ||
background: var(--box-bg-2); | ||
gap: 5px; | ||
img { | ||
width: 64px; | ||
height: 64px; | ||
} | ||
.post-topic-info { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 5px; | ||
:first-child { | ||
color: var(--common-text-title); | ||
font-family: var(--font-title); | ||
font-size: 20px; | ||
} | ||
} | ||
} | ||
.post-topic-switch { | ||
display: flex; | ||
align-items: flex-end; | ||
justify-content: center; | ||
margin: 0 10px; | ||
gap: 10px; | ||
} | ||
.post-switch-item { | ||
width: 250px; | ||
height: 50px; | ||
} | ||
.post-fresh-btn { | ||
height: 40px; | ||
background: var(--btn-bg-1); | ||
color: var(--btn-text-1); | ||
font-family: var(--font-title); | ||
} | ||
.dark .post-fresh-btn { | ||
border: 1px solid var(--common-shadow-2); | ||
} | ||
.post-topic-grid { | ||
display: grid; | ||
padding: 5px; | ||
font-family: var(--font-title); | ||
grid-gap: 10px; | ||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); | ||
} | ||
.load-more { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
margin: 10px; | ||
font-family: var(--font-title); | ||
transition: all 0.3s linear; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.