feat: save scroll positions between home timelines
This commit is contained in:
parent
9990cc9a44
commit
94fd53b8cb
4 changed files with 35 additions and 17 deletions
|
@ -35,13 +35,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
import { ref, onActivated, onDeactivated, nextTick } 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 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 { getScrollPosition, scroll } from "@/scripts/scroll";
|
||||||
|
|
||||||
const tlEl = ref<HTMLElement>();
|
const tlEl = ref<HTMLElement>();
|
||||||
|
|
||||||
|
@ -60,6 +60,18 @@ defineExpose({
|
||||||
pagingComponent,
|
pagingComponent,
|
||||||
scrollTop,
|
scrollTop,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let scrollContainer = $ref(tlEl.value);
|
||||||
|
let scrollPos = $ref(0);
|
||||||
|
|
||||||
|
onDeactivated(() => {
|
||||||
|
scrollPos = getScrollPosition( scrollContainer );
|
||||||
|
})
|
||||||
|
onActivated(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
scroll(scrollContainer, { top: scrollPos, behavior: "instant" });
|
||||||
|
})
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch, computed, provide, onUnmounted } from "vue";
|
import { computed, provide, onUnmounted } from "vue";
|
||||||
import XNotes from "@/components/MkNotes.vue";
|
import XNotes from "@/components/MkNotes.vue";
|
||||||
import MkInfo from "@/components/MkInfo.vue";
|
import MkInfo from "@/components/MkInfo.vue";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
active: tab.key != null && tab.key === props.tab,
|
active: tab.key != null && tab.key === props.tab,
|
||||||
}"
|
}"
|
||||||
@mousedown="(ev) => onTabMousedown(tab, ev)"
|
@mousedown="(ev) => onTabMousedown(tab, ev)"
|
||||||
@click="(ev) => onTabClick(tab, ev)"
|
@click.stop="(ev) => onTabClick(tab, ev)"
|
||||||
>
|
>
|
||||||
<i v-if="tab.icon" class="icon" :class="tab.icon"></i>
|
<i v-if="tab.icon" class="icon" :class="tab.icon"></i>
|
||||||
<span class="title">{{ tab.title }}</span>
|
<span class="title">{{ tab.title }}</span>
|
||||||
|
@ -227,6 +227,9 @@ const onClick = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
function onTabMousedown(tab: Tab, ev: MouseEvent): void {
|
function onTabMousedown(tab: Tab, ev: MouseEvent): void {
|
||||||
|
if (tab.key != null && tab.key === props.tab) {
|
||||||
|
scrollToTop(el, { behavior: "smooth" });
|
||||||
|
}
|
||||||
// ユーザビリティの観点からmousedown時にはonClickは呼ばない
|
// ユーザビリティの観点からmousedown時にはonClickは呼ばない
|
||||||
if (tab.key) {
|
if (tab.key) {
|
||||||
emit("update:tab", tab.key);
|
emit("update:tab", tab.key);
|
||||||
|
|
|
@ -31,9 +31,7 @@
|
||||||
:touch-angle="25"
|
:touch-angle="25"
|
||||||
:threshold="10"
|
:threshold="10"
|
||||||
:centeredSlides="true"
|
:centeredSlides="true"
|
||||||
:modules="[Virtual]"
|
|
||||||
:space-between="20"
|
:space-between="20"
|
||||||
:virtual="true"
|
|
||||||
:allow-touch-move="
|
:allow-touch-move="
|
||||||
defaultStore.state.swipeOnMobile &&
|
defaultStore.state.swipeOnMobile &&
|
||||||
(deviceKind !== 'desktop' ||
|
(deviceKind !== 'desktop' ||
|
||||||
|
@ -45,16 +43,18 @@
|
||||||
<swiper-slide
|
<swiper-slide
|
||||||
v-for="index in timelines"
|
v-for="index in timelines"
|
||||||
:key="index"
|
:key="index"
|
||||||
:virtual-index="index"
|
v-slot="{ isActive }"
|
||||||
>
|
>
|
||||||
<XTimeline
|
<KeepAlive>
|
||||||
v-if="index == timelines[swiperRef.activeIndex]"
|
<XTimeline
|
||||||
ref="tl"
|
v-if="isActive"
|
||||||
:key="src"
|
ref="tl"
|
||||||
class="tl"
|
:key="src"
|
||||||
:src="src"
|
class="tl"
|
||||||
:sound="true"
|
:src="src"
|
||||||
/>
|
:sound="true"
|
||||||
|
/>
|
||||||
|
</KeepAlive>
|
||||||
</swiper-slide>
|
</swiper-slide>
|
||||||
</swiper>
|
</swiper>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,8 +64,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, onMounted } from "vue";
|
import { computed, ref, onMounted, onUnmounted } from "vue";
|
||||||
import { Virtual } from "swiper/modules";
|
|
||||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||||
import XTutorial from "@/components/MkTutorialDialog.vue";
|
import XTutorial from "@/components/MkTutorialDialog.vue";
|
||||||
import XTimeline from "@/components/MkTimeline.vue";
|
import XTimeline from "@/components/MkTimeline.vue";
|
||||||
|
@ -302,6 +301,10 @@ function syncSlide(index) {
|
||||||
swiperRef.slideTo(index);
|
swiperRef.slideTo(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
console.log("The timelines page has been unmounted");
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
syncSlide(timelines.indexOf(swiperRef.activeIndex));
|
syncSlide(timelines.indexOf(swiperRef.activeIndex));
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue