[client] Move timeline to vue-virtual-scroller

This commit is contained in:
Laura Hausmann 2023-11-22 20:43:51 +01:00
parent 3cb46cd6fc
commit 61df9f65f9
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
14 changed files with 335 additions and 129 deletions

79
.pnp.cjs generated
View file

@ -8446,6 +8446,7 @@ const RAW_RUNTIME_STATE =
["vue-isyourpasswordsafe", "npm:2.0.0"],\ ["vue-isyourpasswordsafe", "npm:2.0.0"],\
["vue-plyr", "npm:7.0.0"],\ ["vue-plyr", "npm:7.0.0"],\
["vue-prism-editor", "virtual:658502eb4296e93abedc18b6aa9b26978f434f08d98e21ebb0e725354b8bb54b62db9c4a1893e460c694ff7500ff5cbafa4457b0dfd26b5838868666c861e990#npm:2.0.0-alpha.2"],\ ["vue-prism-editor", "virtual:658502eb4296e93abedc18b6aa9b26978f434f08d98e21ebb0e725354b8bb54b62db9c4a1893e460c694ff7500ff5cbafa4457b0dfd26b5838868666c861e990#npm:2.0.0-alpha.2"],\
["vue-virtual-scroller", "virtual:658502eb4296e93abedc18b6aa9b26978f434f08d98e21ebb0e725354b8bb54b62db9c4a1893e460c694ff7500ff5cbafa4457b0dfd26b5838868666c861e990#npm:2.0.0-beta.8"],\
["vuedraggable", "virtual:658502eb4296e93abedc18b6aa9b26978f434f08d98e21ebb0e725354b8bb54b62db9c4a1893e460c694ff7500ff5cbafa4457b0dfd26b5838868666c861e990#npm:4.1.0"]\ ["vuedraggable", "virtual:658502eb4296e93abedc18b6aa9b26978f434f08d98e21ebb0e725354b8bb54b62db9c4a1893e460c694ff7500ff5cbafa4457b0dfd26b5838868666c861e990#npm:4.1.0"]\
],\ ],\
"linkType": "SOFT"\ "linkType": "SOFT"\
@ -17837,6 +17838,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
]],\ ]],\
["mitt", [\
["npm:2.1.0", {\
"packageLocation": "./.yarn/cache/mitt-npm-2.1.0-77f3c96db4-d4087f8678.zip/node_modules/mitt/",\
"packageDependencies": [\
["mitt", "npm:2.1.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["mixin-deep", [\ ["mixin-deep", [\
["npm:1.3.2", {\ ["npm:1.3.2", {\
"packageLocation": "./.yarn/cache/mixin-deep-npm-1.3.2-29b528e571-820d5a51fc.zip/node_modules/mixin-deep/",\ "packageLocation": "./.yarn/cache/mixin-deep-npm-1.3.2-29b528e571-820d5a51fc.zip/node_modules/mixin-deep/",\
@ -24912,6 +24922,28 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
]],\ ]],\
["vue-observe-visibility", [\
["npm:2.0.0-alpha.1", {\
"packageLocation": "./.yarn/cache/vue-observe-visibility-npm-2.0.0-alpha.1-2336a276e1-251948d4bd.zip/node_modules/vue-observe-visibility/",\
"packageDependencies": [\
["vue-observe-visibility", "npm:2.0.0-alpha.1"]\
],\
"linkType": "SOFT"\
}],\
["virtual:1ff70a214f776664ffdd69e6c80dedbacd96b8cdab401980bd5ea13591b1cea0033ea9ca782fc6be0c2a7cbd792aa0bd2ba47d82b6b45a27a55d439ae67b26e0#npm:2.0.0-alpha.1", {\
"packageLocation": "./.yarn/__virtual__/vue-observe-visibility-virtual-38a3aa5843/0/cache/vue-observe-visibility-npm-2.0.0-alpha.1-2336a276e1-251948d4bd.zip/node_modules/vue-observe-visibility/",\
"packageDependencies": [\
["vue-observe-visibility", "virtual:1ff70a214f776664ffdd69e6c80dedbacd96b8cdab401980bd5ea13591b1cea0033ea9ca782fc6be0c2a7cbd792aa0bd2ba47d82b6b45a27a55d439ae67b26e0#npm:2.0.0-alpha.1"],\
["@types/vue", null],\
["vue", "npm:3.3.4"]\
],\
"packagePeers": [\
"@types/vue",\
"vue"\
],\
"linkType": "HARD"\
}]\
]],\
["vue-plyr", [\ ["vue-plyr", [\
["npm:7.0.0", {\ ["npm:7.0.0", {\
"packageLocation": "./.yarn/cache/vue-plyr-npm-7.0.0-aab8325658-09f1cdd290.zip/node_modules/vue-plyr/",\ "packageLocation": "./.yarn/cache/vue-plyr-npm-7.0.0-aab8325658-09f1cdd290.zip/node_modules/vue-plyr/",\
@ -24945,6 +24977,53 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
]],\ ]],\
["vue-resize", [\
["npm:2.0.0-alpha.1", {\
"packageLocation": "./.yarn/cache/vue-resize-npm-2.0.0-alpha.1-b3eb21b45c-d6e66472cd.zip/node_modules/vue-resize/",\
"packageDependencies": [\
["vue-resize", "npm:2.0.0-alpha.1"]\
],\
"linkType": "SOFT"\
}],\
["virtual:1ff70a214f776664ffdd69e6c80dedbacd96b8cdab401980bd5ea13591b1cea0033ea9ca782fc6be0c2a7cbd792aa0bd2ba47d82b6b45a27a55d439ae67b26e0#npm:2.0.0-alpha.1", {\
"packageLocation": "./.yarn/__virtual__/vue-resize-virtual-7d46fa71e5/0/cache/vue-resize-npm-2.0.0-alpha.1-b3eb21b45c-d6e66472cd.zip/node_modules/vue-resize/",\
"packageDependencies": [\
["vue-resize", "virtual:1ff70a214f776664ffdd69e6c80dedbacd96b8cdab401980bd5ea13591b1cea0033ea9ca782fc6be0c2a7cbd792aa0bd2ba47d82b6b45a27a55d439ae67b26e0#npm:2.0.0-alpha.1"],\
["@types/vue", null],\
["vue", "npm:3.3.4"]\
],\
"packagePeers": [\
"@types/vue",\
"vue"\
],\
"linkType": "HARD"\
}]\
]],\
["vue-virtual-scroller", [\
["npm:2.0.0-beta.8", {\
"packageLocation": "./.yarn/cache/vue-virtual-scroller-npm-2.0.0-beta.8-02cf134969-78047d2281.zip/node_modules/vue-virtual-scroller/",\
"packageDependencies": [\
["vue-virtual-scroller", "npm:2.0.0-beta.8"]\
],\
"linkType": "SOFT"\
}],\
["virtual:658502eb4296e93abedc18b6aa9b26978f434f08d98e21ebb0e725354b8bb54b62db9c4a1893e460c694ff7500ff5cbafa4457b0dfd26b5838868666c861e990#npm:2.0.0-beta.8", {\
"packageLocation": "./.yarn/__virtual__/vue-virtual-scroller-virtual-1ff70a214f/0/cache/vue-virtual-scroller-npm-2.0.0-beta.8-02cf134969-78047d2281.zip/node_modules/vue-virtual-scroller/",\
"packageDependencies": [\
["vue-virtual-scroller", "virtual:658502eb4296e93abedc18b6aa9b26978f434f08d98e21ebb0e725354b8bb54b62db9c4a1893e460c694ff7500ff5cbafa4457b0dfd26b5838868666c861e990#npm:2.0.0-beta.8"],\
["@types/vue", null],\
["mitt", "npm:2.1.0"],\
["vue", "npm:3.3.4"],\
["vue-observe-visibility", "virtual:1ff70a214f776664ffdd69e6c80dedbacd96b8cdab401980bd5ea13591b1cea0033ea9ca782fc6be0c2a7cbd792aa0bd2ba47d82b6b45a27a55d439ae67b26e0#npm:2.0.0-alpha.1"],\
["vue-resize", "virtual:1ff70a214f776664ffdd69e6c80dedbacd96b8cdab401980bd5ea13591b1cea0033ea9ca782fc6be0c2a7cbd792aa0bd2ba47d82b6b45a27a55d439ae67b26e0#npm:2.0.0-alpha.1"]\
],\
"packagePeers": [\
"@types/vue",\
"vue"\
],\
"linkType": "HARD"\
}]\
]],\
["vuedraggable", [\ ["vuedraggable", [\
["npm:4.1.0", {\ ["npm:4.1.0", {\
"packageLocation": "./.yarn/cache/vuedraggable-npm-4.1.0-785593d488-87d4faba83.zip/node_modules/vuedraggable/",\ "packageLocation": "./.yarn/cache/vuedraggable-npm-4.1.0-785593d488-87d4faba83.zip/node_modules/vuedraggable/",\

BIN
.yarn/cache/mitt-npm-2.1.0-77f3c96db4-d4087f8678.zip (Stored with Git LFS) vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
.yarn/cache/vue-resize-npm-2.0.0-alpha.1-b3eb21b45c-d6e66472cd.zip (Stored with Git LFS) vendored Normal file

Binary file not shown.

Binary file not shown.

View file

@ -98,6 +98,7 @@
"vue-isyourpasswordsafe": "^2.0.0", "vue-isyourpasswordsafe": "^2.0.0",
"vue-plyr": "^7.0.0", "vue-plyr": "^7.0.0",
"vue-prism-editor": "2.0.0-alpha.2", "vue-prism-editor": "2.0.0-alpha.2",
"vue-virtual-scroller": "next",
"vuedraggable": "next" "vuedraggable": "next"
}, },
"dependencies": { "dependencies": {

View file

@ -15,6 +15,7 @@
:class="{ cover }" :class="{ cover }"
:style="{ 'object-fit': cover ? 'cover' : null }" :style="{ 'object-fit': cover ? 'cover' : null }"
loading="lazy" loading="lazy"
decoding="async"
@load="onLoad" @load="onLoad"
/> />
</template> </template>

View file

@ -7,7 +7,7 @@
:to="url" :to="url"
@click.stop @click.stop
> >
<img class="icon" :src="`/avatar/@${username}@${host}`" alt="" /> <img class="icon" :src="`/avatar/@${username}@${host}`" alt="" loading="lazy" decoding="async" />
<span class="main"> <span class="main">
<span class="username">@{{ username }}</span> <span class="username">@{{ username }}</span>
<span <span

View file

@ -12,22 +12,31 @@
</template> </template>
<template #default="{ items: notes }"> <template #default="{ items: notes }">
<div class="giivymft" :class="{ noGap }" ref="tlEl"> <div class="notes-wrapper" :class="{ noGap }" ref="tlEl">
<XList <DynamicScroller
ref="notes" page-mode
v-slot="{ item: note }" v-slot="{ item: note, index, active }"
:items="notes" :items="notes"
:direction="pagination.reversed ? 'up' : 'down'" :min-item-size="10"
:reversed="pagination.reversed" :buffer="200"
:no-gap="noGap" :class="{ noGap }"
class="notes" listClass="notes"
itemClass="note"
> >
<DynamicScrollerItem
:key="index"
:item="note"
:active="active"
:data-index="index"
>
<div class="note-wrapper">
<XNote <XNote
:key="note._featuredId_ || note._prId_ || note.id" :key="note._featuredId_ || note._prId_ || note.id"
class="qtqtichx"
:note="note" :note="note"
/> />
</XList> </div>
</DynamicScrollerItem>
</DynamicScroller>
</div> </div>
</template> </template>
</MkPagination> </MkPagination>
@ -37,11 +46,12 @@
import { ref } from "vue"; import { ref } from "vue";
import type { Paging } from "@/components/MkPagination.vue"; import type { Paging } from "@/components/MkPagination.vue";
import XNote from "@/components/MkNote.vue"; import XNote from "@/components/MkNote.vue";
import XList from "@/components/MkDateSeparatedList.vue";
import MkPagination from "@/components/MkPagination.vue"; import MkPagination from "@/components/MkPagination.vue";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { scroll } from "@/scripts/scroll"; import { scroll } from "@/scripts/scroll";
import { instance } from "@/instance"; import { instance } from "@/instance";
import { DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const tlEl = ref<HTMLElement>(); const tlEl = ref<HTMLElement>();
@ -60,23 +70,91 @@ defineExpose({
pagingComponent, pagingComponent,
scrollTop, scrollTop,
}); });
setInterval(() => {
if (!tlEl.value) return;
const viewport = document.documentElement.clientHeight;
const left = document.documentElement.scrollHeight - document.documentElement.scrollTop;
if (left <= viewport * 3) pagingComponent.value.fetchMore();
}, 100);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.giivymft { .notes-wrapper {
&.noGap { &.noGap {
> .notes { :deep(.notes) {
background: var(--panel) !important; background: var(--panel) !important;
border-radius: var(--radius); border-radius: var(--radius);
} }
} }
&:not(.noGap) { &:not(.noGap) {
> .notes { :deep(.notes) .note .note-wrapper > div {
.qtqtichx {
background: var(--panel); background: var(--panel);
border-radius: var(--radius); border-radius: var(--radius);
} }
} }
:deep(.notes) {
.note .note-container:empty {
display: none;
}
.note .note-wrapper {
padding-bottom: var(--margin);
}
> .separator {
text-align: center;
> .date {
display: inline-block;
position: relative;
margin: 0;
padding: 0 16px;
line-height: 32px;
text-align: center;
font-size: 12px;
color: var(--dateLabelFg);
> span {
&:first-child {
margin-right: 8px;
> .icon {
margin-right: 8px;
}
}
&:last-child {
margin-left: 8px;
> .icon {
margin-left: 8px;
}
}
}
}
}
&.noGap {
> * {
margin: 0 !important;
border: none;
border-radius: 0;
box-shadow: none;
&:first-child {
border-radius: var(--radius) var(--radius) 0 0;
}
&:last-child {
border-radius: 0 0 var(--radius) var(--radius);
}
&:not(:last-child) {
border-bottom: solid 0.5px var(--divider);
}
}
}
} }
} }
</style> </style>

View file

@ -41,13 +41,11 @@
key="_more_" key="_more_"
class="cxiknjgy _gap" class="cxiknjgy _gap"
> >
<div
v-appear="$store.state.enableInfiniteScroll && !disableAutoLoad ? fetchMore : null"
/>
<MkButton <MkButton
v-if="!moreFetching" v-if="!moreFetching && !$store.state.enableInfiniteScroll && !disableAutoLoad"
v-appear="
$store.state.enableInfiniteScroll && !disableAutoLoad
? fetchMore
: null
"
class="button" class="button"
:disabled="moreFetching" :disabled="moreFetching"
:style="{ cursor: moreFetching ? 'wait' : 'pointer' }" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"
@ -109,7 +107,7 @@ export type Paging<
offsetMode?: boolean; offsetMode?: boolean;
}; };
const SECOND_FETCH_LIMIT = 30; const SECOND_FETCH_LIMIT = 15;
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
@ -118,7 +116,7 @@ const props = withDefaults(
displayLimit?: number; displayLimit?: number;
}>(), }>(),
{ {
displayLimit: 30, displayLimit: 15,
}, },
); );
@ -498,6 +496,7 @@ defineExpose({
append, append,
removeItem, removeItem,
updateItem, updateItem,
fetchMore,
}); });
</script> </script>

View file

@ -1,8 +1,4 @@
<template> <template>
<transition
:name="defaultStore.state.animation ? 'zoom' : ''"
mode="out-in"
>
<!-- v-if="!fetching" for now, I think there's something <!-- v-if="!fetching" for now, I think there's something
weird w/ some links stuck loading (?) --> weird w/ some links stuck loading (?) -->
<article v-if="!fetching" class="url-preview" @click.stop> <article v-if="!fetching" class="url-preview" @click.stop>
@ -17,7 +13,7 @@
}" }"
> >
<div v-if="thumbnail" class="thumbnail"> <div v-if="thumbnail" class="thumbnail">
<img :src="thumbnail" loading="lazy" /> <img :src="thumbnail" loading="lazy" decoding="async" />
<button <button
v-if="tweetId" v-if="tweetId"
class="_button" class="_button"
@ -95,7 +91,6 @@
@click.stop @click.stop
></iframe> ></iframe>
</article> </article>
</transition>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>

View file

@ -8,7 +8,7 @@
:title="acct(user)" :title="acct(user)"
@click="onClick" @click="onClick"
> >
<img class="inner" :src="url" decoding="async" /> <img class="inner" :src="url" loading="lazy" decoding="async" />
<MkUserOnlineIndicator <MkUserOnlineIndicator
v-if="showIndicator && user.instance == null" v-if="showIndicator && user.instance == null"
class="indicator" class="indicator"
@ -26,7 +26,7 @@
:target="target" :target="target"
@click.stop @click.stop
> >
<img class="inner" :src="url" decoding="async" /> <img class="inner" :src="url" loading="lazy" decoding="async" />
<MkUserOnlineIndicator <MkUserOnlineIndicator
v-if="showIndicator && user.instance == null" v-if="showIndicator && user.instance == null"
class="indicator" class="indicator"

View file

@ -7,6 +7,7 @@
:alt="alt" :alt="alt"
:title="alt" :title="alt"
decoding="async" decoding="async"
loading="lazy"
/> />
<img <img
v-else-if="char && !useOsNativeEmojis" v-else-if="char && !useOsNativeEmojis"
@ -15,6 +16,7 @@
:alt="alt" :alt="alt"
:title="alt" :title="alt"
decoding="async" decoding="async"
loading="lazy"
/> />
<span v-else-if="char && useOsNativeEmojis">{{ char }}</span> <span v-else-if="char && useOsNativeEmojis">{{ char }}</span>
<span v-else>{{ emoji }}</span> <span v-else>{{ emoji }}</span>

View file

@ -6604,6 +6604,7 @@ __metadata:
vue-isyourpasswordsafe: "npm:^2.0.0" vue-isyourpasswordsafe: "npm:^2.0.0"
vue-plyr: "npm:^7.0.0" vue-plyr: "npm:^7.0.0"
vue-prism-editor: "npm:2.0.0-alpha.2" vue-prism-editor: "npm:2.0.0-alpha.2"
vue-virtual-scroller: "npm:next"
vuedraggable: "npm:next" vuedraggable: "npm:next"
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -14692,6 +14693,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mitt@npm:^2.1.0":
version: 2.1.0
resolution: "mitt@npm:2.1.0"
checksum: d4087f8678ef9de18af10171ed39c14fc9282532f9104b522265e4a206f81630767bce5e3ae2405e9d863d7f6a7f3095f738c33c55c06872ed25978f1c8ea9f3
languageName: node
linkType: hard
"mixin-deep@npm:^1.2.0": "mixin-deep@npm:^1.2.0":
version: 1.3.2 version: 1.3.2
resolution: "mixin-deep@npm:1.3.2" resolution: "mixin-deep@npm:1.3.2"
@ -20955,6 +20963,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vue-observe-visibility@npm:^2.0.0-alpha.1":
version: 2.0.0-alpha.1
resolution: "vue-observe-visibility@npm:2.0.0-alpha.1"
peerDependencies:
vue: ^3.0.0
checksum: 251948d4bdcc67e134962a754fcf10407add5ca1f6093a931f94081f0a434603a24175a0ae0fa147766e4a487f7e733f68558d245989f081dd29ea1e68f5fa57
languageName: node
linkType: hard
"vue-plyr@npm:^7.0.0": "vue-plyr@npm:^7.0.0":
version: 7.0.0 version: 7.0.0
resolution: "vue-plyr@npm:7.0.0" resolution: "vue-plyr@npm:7.0.0"
@ -20974,6 +20991,28 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vue-resize@npm:^2.0.0-alpha.1":
version: 2.0.0-alpha.1
resolution: "vue-resize@npm:2.0.0-alpha.1"
peerDependencies:
vue: ^3.0.0
checksum: d6e66472cd312b256fb277d1f7fc1b19f1faa45b1d8ea32bb473130a9075f5b2b0aa9efb3ad3f9492e88f6def65f8c93bc64b7cb818147ca6522e95981cb90ef
languageName: node
linkType: hard
"vue-virtual-scroller@npm:next":
version: 2.0.0-beta.8
resolution: "vue-virtual-scroller@npm:2.0.0-beta.8"
dependencies:
mitt: "npm:^2.1.0"
vue-observe-visibility: "npm:^2.0.0-alpha.1"
vue-resize: "npm:^2.0.0-alpha.1"
peerDependencies:
vue: ^3.2.0
checksum: 78047d2281dd133b63cc317d69e7a098088fb0fdfad386f2455aa791f3666f4dc7c9787e8beede7ec2113d46831d8cc89da63a61c9a9f59b09f2da0e8f4f96bb
languageName: node
linkType: hard
"vue@npm:3.3.4": "vue@npm:3.3.4":
version: 3.3.4 version: 3.3.4
resolution: "vue@npm:3.3.4" resolution: "vue@npm:3.3.4"