mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-04-02 06:45:08 +08:00
✨ 获取用户关注动态
This commit is contained in:
@@ -76,7 +76,7 @@
|
||||
:title="`频道: ${card.forum.name}`"
|
||||
@click="toForum(card.forum)"
|
||||
>
|
||||
<img :src="card.forum.icon" :alt="card.forum.name" />
|
||||
<img v-if="card.forum.icon !== ''" :src="card.forum.icon" :alt="card.forum.name" />
|
||||
<span>{{ card.forum.name }}</span>
|
||||
</div>
|
||||
<v-checkbox-btn
|
||||
|
||||
@@ -154,6 +154,11 @@
|
||||
<img src="/source/UI/posts.webp" alt="collect" class="side-icon-menu" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
<v-list-item class="side-item-menu" title="关注" @click="showFollow = true">
|
||||
<template #prepend>
|
||||
<img src="/platforms/mhy/mys.webp" alt="follow" class="side-icon-menu" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-list-item
|
||||
@@ -172,13 +177,15 @@
|
||||
</div>
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
<vp-overlay-follow v-model="showFollow" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import VpOverlayFollow from "@comp/viewPost/vp-overlay-follow.vue";
|
||||
import { event, webviewWindow } from "@tauri-apps/api";
|
||||
import type { Event, UnlistenFn } from "@tauri-apps/api/event";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed, onMounted, onUnmounted } from "vue";
|
||||
import { computed, onMounted, onUnmounted, ref } from "vue";
|
||||
|
||||
import { useAppStore } from "@/store/modules/app.js";
|
||||
import { useUserStore } from "@/store/modules/user.js";
|
||||
@@ -189,6 +196,7 @@ const { briefInfo } = storeToRefs(useUserStore());
|
||||
let themeListener: UnlistenFn | null = null;
|
||||
// @ts-expect-error The import.meta meta-property is not allowed in files which will build into CommonJS output.
|
||||
const isDevEnv = import.meta.env.MODE === "development";
|
||||
const showFollow = ref<boolean>();
|
||||
const rail = computed<boolean>({
|
||||
get: () => sidebar.value.collapse,
|
||||
set: (v) => (sidebar.value.collapse = v),
|
||||
|
||||
157
src/components/viewPost/vp-overlay-follow.vue
Normal file
157
src/components/viewPost/vp-overlay-follow.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<TOverlay v-model="visible">
|
||||
<div class="vp-of-box">
|
||||
<div class="vo-of-top">
|
||||
<div class="vo-oft-left">
|
||||
<img src="/platforms/mhy/mys.webp" alt="icon" />
|
||||
<span>关注动态</span>
|
||||
</div>
|
||||
<div class="vo-oft-right">已加载:{{ posts.length }}条</div>
|
||||
</div>
|
||||
<div class="vo-of-actions">
|
||||
<v-btn class="vo-of-btn" @click="loadMore(true)" :loading="loading">刷新</v-btn>
|
||||
<v-btn class="vo-of-btn" @click="loadMore()" :loading="loading">加载更多</v-btn>
|
||||
</div>
|
||||
<div class="vp-of-list">
|
||||
<TPostcard
|
||||
class="vp-of-list-item"
|
||||
v-for="(item, index) in posts"
|
||||
:key="index"
|
||||
:model-value="item"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</TOverlay>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TOverlay from "@comp/app/t-overlay.vue";
|
||||
import TPostcard from "@comp/app/t-postcard.vue";
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { ref, shallowRef, watch } from "vue";
|
||||
|
||||
import { useUserStore } from "@/store/modules/user.js";
|
||||
import painterReq from "@/web/request/painterReq.js";
|
||||
|
||||
const { cookie } = storeToRefs(useUserStore());
|
||||
const visible = defineModel<boolean>();
|
||||
const offset = ref<number>();
|
||||
const isLast = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
const posts = shallowRef<Array<TGApp.BBS.Post.FullData>>([]);
|
||||
|
||||
watch(
|
||||
() => visible.value,
|
||||
async () => {
|
||||
if (visible.value) await loadMore();
|
||||
},
|
||||
);
|
||||
|
||||
async function loadMore(refresh: boolean = false): Promise<void> {
|
||||
if (loading.value) return;
|
||||
if (refresh) offset.value = undefined;
|
||||
if (!cookie.value) {
|
||||
showSnackbar.warn("请登录后再试");
|
||||
visible.value = false;
|
||||
return;
|
||||
}
|
||||
if (isLast.value) {
|
||||
showSnackbar.warn("没有更多了");
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
const resp = await painterReq.follow(cookie.value, offset.value);
|
||||
if ("retcode" in resp) {
|
||||
showSnackbar.warn(`[${resp.retcode}] ${resp.message}`);
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
offset.value = resp.next_offset;
|
||||
isLast.value = resp.is_last;
|
||||
if (refresh) posts.value = resp.list;
|
||||
else posts.value = posts.value.concat(resp.list);
|
||||
loading.value = false;
|
||||
showSnackbar.success(`成功加载${resp.list.length}条数据`);
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.vp-of-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 400px;
|
||||
height: 500px;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
background-color: var(--box-bg-1);
|
||||
row-gap: 8px;
|
||||
}
|
||||
|
||||
.vo-of-top {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.vo-oft-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
color: var(--common-text-title);
|
||||
font-family: var(--font-title);
|
||||
font-size: 20px;
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.vo-oft-right {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.vo-of-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
.vo-of-btn {
|
||||
border-radius: 8px;
|
||||
background: var(--tgc-btn-1);
|
||||
color: var(--btn-text);
|
||||
font-family: var(--font-title);
|
||||
}
|
||||
|
||||
.dark .vo-of-btn {
|
||||
border: 1px solid var(--common-shadow-2);
|
||||
}
|
||||
|
||||
.vp-of-list {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
padding-right: 8px;
|
||||
padding-bottom: 8px;
|
||||
overflow-y: auto;
|
||||
row-gap: 10px;
|
||||
}
|
||||
|
||||
.vp-of-list-item {
|
||||
height: fit-content;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -122,7 +122,7 @@ async function getTimelineList(
|
||||
cookie: TGApp.App.Account.Cookie,
|
||||
offset?: number,
|
||||
): Promise<TGApp.BBS.Response.Base | TGApp.BBS.Post.FollowPostRes> {
|
||||
let param: Record<string, number> = { gids: 2, size: 20 };
|
||||
let param: Record<string, number> = { gids: 0, size: 20 };
|
||||
if (offset) param = { ...param, offset };
|
||||
const ck = { ltoken: cookie.ltoken, ltuid: cookie.ltuid };
|
||||
const header = getRequestHeader(ck, "GET", param, "X4", true);
|
||||
|
||||
Reference in New Issue
Block a user