Skip to content

Commit

Permalink
Fix: [Client][Panel/Twitter] タイムラインの仮想スクロールを Virtua に置き換え、スクロールのガタ付きと…
Browse files Browse the repository at this point in the history
…バグっぽい挙動を改善

こちらはこちらで更新がすぐに反映されない問題はあるが…
  • Loading branch information
tsukumijima committed Jan 27, 2025
1 parent ce2b4ef commit 704b20f
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 42 deletions.
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"seamless-scroll-polyfill": "^2.3.4",
"swiper": "^11.1.11",
"tslib": "^2.7.0",
"virtua": "^0.39.3",
"vue": "^3.4.38",
"vue-router": "^4.4.3",
"vue-virtual-scroller": "^2.0.0-beta.8",
Expand Down
1 change: 1 addition & 0 deletions client/src/components/Watch/Panel/Twitter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ export default defineComponent({
&.watch-panel__content--active .tab-container .tab-content--active {
opacity: 1;
visibility: visible;
z-index: 10;
@media (hover: none) {
content-visibility: auto;
}
Expand Down
49 changes: 28 additions & 21 deletions client/src/components/Watch/Panel/Twitter/Search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,19 @@
label="リツイートを表示する"
/>
</div>
<DynamicScroller ref="scroller" class="search-tweets" :direction="'vertical'" :items="timelineItems"
:min-item-size="80" :buffer="400" v-show="timelineItems.length > 0">
<template v-slot="{item, active}">
<DynamicScrollerItem
:item="item"
:active="active"
:size-dependencies="item.type === 'tweet_block' ? item.tweets.map(t => [t.text, t.image_urls, t.movie_url]).flat() : []">
<template v-if="item.type === 'tweet_block'">
<Tweet v-for="tweet in item.tweets" :key="tweet.id" :tweet="tweet" />
</template>
<button v-else class="load-more-button" @click="handleLoadMore(item)" :disabled="isFetching">
<div class="load-more-button__content">
<Icon icon="ic:round-refresh" width="20" :class="isFetching ? 'animate-spin' : ''" class="mr-2" />
ツイートをさらに表示
</div>
</button>
</DynamicScrollerItem>
</template>
</DynamicScroller>
<div class="search-announce" v-show="timelineItems.length === 0">
<VirtuaList ref="scroller" class="search-tweets" :data="flattenedItems" #default="{ item }"
v-show="flattenedItems.length > 0">
<div class="search-item">
<Tweet v-if="'text' in item" :tweet="item" />
<button v-else class="load-more-button" @click="handleLoadMore(item)" :disabled="isFetching">
<div class="load-more-button__content">
<Icon icon="ic:round-refresh" width="20" :class="isFetching ? 'animate-spin' : ''" class="mr-2" />
ツイートをさらに表示
</div>
</button>
</div>
</VirtuaList>
<div class="search-announce" v-show="flattenedItems.length === 0">
<div class="search-announce__heading">まだツイートがありません。</div>
<div class="search-announce__text">
<p class="mt-0 mb-0">右上の更新ボタンを押すと、最新の<br>ツイート検索結果を時系列で表示できます。</p>
Expand All @@ -62,7 +55,8 @@
<script lang="ts" setup>
import { storeToRefs } from 'pinia';
import { ref, watch, onMounted, nextTick } from 'vue';
import { VList as VirtuaList } from 'virtua/vue';
import { ref, watch, onMounted, nextTick, computed } from 'vue';
import Tweet from '@/components/Watch/Panel/Twitter/Tweet.vue';
import Message from '@/message';
Expand Down Expand Up @@ -101,6 +95,19 @@ const scroller = ref<any>(null);
// 表示する最大ツイート数
const MAX_TWEETS = 1000;
// フラットな構造の配列を生成する computed プロパティ
const flattenedItems = computed(() => {
const items: (ITweet | ILoadMoreItem)[] = [];
for (const item of timelineItems.value) {
if (item.type === 'tweet_block') {
items.push(...item.tweets);
} else {
items.push(item);
}
}
return items;
});
const getTotalTweetCount = () => {
return timelineItems.value.reduce((count, item) => {
if (item.type === 'tweet_block') {
Expand Down
49 changes: 28 additions & 21 deletions client/src/components/Watch/Panel/Twitter/Timeline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,19 @@
label="リツイートを表示する"
/>
</div>
<DynamicScroller ref="scroller" class="timeline-tweets" :direction="'vertical'" :items="timelineItems"
:min-item-size="80" :buffer="400" v-show="timelineItems.length > 0">
<template v-slot="{item, active}">
<DynamicScrollerItem
:item="item"
:active="active"
:size-dependencies="item.type === 'tweet_block' ? item.tweets.map(t => [t.text, t.image_urls, t.movie_url]).flat() : []">
<template v-if="item.type === 'tweet_block'">
<Tweet v-for="tweet in item.tweets" :key="tweet.id" :tweet="tweet" />
</template>
<button v-else class="load-more-button" @click="handleLoadMore(item)" :disabled="isFetching">
<div class="load-more-button__content">
<Icon icon="ic:round-refresh" width="20" :class="isFetching ? 'animate-spin' : ''" class="mr-2" />
ツイートをさらに表示
</div>
</button>
</DynamicScrollerItem>
</template>
</DynamicScroller>
<div class="timeline-announce" v-show="timelineItems.length === 0">
<VirtuaList ref="scroller" class="timeline-tweets" :data="flattenedItems" #default="{ item }"
v-show="flattenedItems.length > 0">
<div class="timeline-item">
<Tweet v-if="'text' in item" :tweet="item" />
<button v-else class="load-more-button" @click="handleLoadMore(item)" :disabled="isFetching">
<div class="load-more-button__content">
<Icon icon="ic:round-refresh" width="20" :class="isFetching ? 'animate-spin' : ''" class="mr-2" />
ツイートをさらに表示
</div>
</button>
</div>
</VirtuaList>
<div class="timeline-announce" v-show="flattenedItems.length === 0">
<div class="timeline-announce__heading">まだツイートがありません。</div>
<div class="timeline-announce__text">
<p class="mt-0 mb-0">右上の更新ボタンを押すと、最新の<br>ホームタイムラインを時系列で表示できます。</p>
Expand All @@ -52,7 +45,8 @@

<script lang="ts" setup>
import { storeToRefs } from 'pinia';
import { ref, onMounted, watch, nextTick } from 'vue';
import { VList as VirtuaList } from 'virtua/vue';
import { ref, onMounted, watch, nextTick, computed } from 'vue';
import Tweet from '@/components/Watch/Panel/Twitter/Tweet.vue';
import Message from '@/message';
Expand Down Expand Up @@ -89,6 +83,19 @@ const scroller = ref<any>(null);
// 表示する最大ツイート数
const MAX_TWEETS = 1000;
// フラットな構造の配列を生成する computed プロパティ
const flattenedItems = computed(() => {
const items: (ITweet | ILoadMoreItem)[] = [];
for (const item of timelineItems.value) {
if (item.type === 'tweet_block') {
items.push(...item.tweets);
} else {
items.push(item);
}
}
return items;
});
const getTotalTweetCount = () => {
return timelineItems.value.reduce((count, item) => {
if (item.type === 'tweet_block') {
Expand Down
5 changes: 5 additions & 0 deletions client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5040,6 +5040,11 @@ vary@^1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==

virtua@^0.39.3:
version "0.39.3"
resolved "https://registry.yarnpkg.com/virtua/-/virtua-0.39.3.tgz#6c7389b993a305516f361107849cfa73c2816f66"
integrity sha512-Ep3aiJXSGPm1UUniThr5mGDfG0upAleP7pqQs5mvvCgM1wPhII1ZKa7eNCWAJRLkC+InpXKokKozyaaj/aMYOQ==

vite-plugin-comlink@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/vite-plugin-comlink/-/vite-plugin-comlink-5.1.0.tgz#c0c563b6d1f414a0ed7afb41b9c3cbf4542a6afe"
Expand Down

0 comments on commit 704b20f

Please sign in to comment.