This commit is contained in:
syuilo 2021-04-14 15:41:08 +09:00
parent 4c545fbba5
commit 91643db0a4
3 changed files with 61 additions and 7 deletions

View file

@ -9,7 +9,7 @@ import { defineComponent } from 'vue';
import { faExpandAlt, faColumns, faExternalLinkAlt, faLink, faWindowMaximize } from '@fortawesome/free-solid-svg-icons';
import * as os from '@client/os';
import copyToClipboard from '@client/scripts/copy-to-clipboard';
import { router } from '@client/router';
import { router, setNavigationInfo } from '@client/router';
import { url } from '@client/config';
import { popout } from '@client/scripts/popout';
import { ColdDeviceStorage } from '@client/store';
@ -130,6 +130,10 @@ export default defineComponent({
if (this.$router.currentRoute.value.path === this.to) {
window.scroll({ top: 0, behavior: 'smooth' });
} else {
setNavigationInfo({
from: this.$router.currentRoute.value.path,
to: this.to
});
this.$router.push(this.to);
}
}

View file

@ -1,4 +1,4 @@
import { defineAsyncComponent, markRaw } from 'vue';
import { defineAsyncComponent, markRaw, ref } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import MkLoading from '@client/pages/_loading_.vue';
import MkError from '@client/pages/_error_.vue';
@ -13,6 +13,16 @@ const page = (path: string) => defineAsyncComponent({
let indexScrollPos = 0;
export const navigationInfo = ref(null);
export function setNavigationInfo(info) {
navigationInfo.value = info;
}
window.addEventListener('popstate', (event) => {
console.log('popstate');
navigationInfo.value = null;
});
export const router = createRouter({
history: createWebHistory(),
routes: [
@ -88,7 +98,7 @@ export const router = createRouter({
// 通常の使い方をすると scroll メソッドの behavior を設定できないため、自前で window.scroll するようにする
scrollBehavior(to) {
window._scroll = () => { // さらにHacky
if (to.name === 'index') {
if (location.pathname === '/') {
window.scroll({ top: indexScrollPos, behavior: 'instant' });
const i = setInterval(() => {
window.scroll({ top: indexScrollPos, behavior: 'instant' });
@ -103,11 +113,11 @@ export const router = createRouter({
}
});
router.afterEach((to, from) => {
if (from.name === 'index') {
export function saveScrollPosition() {
if (navigationInfo.value?.from === '/') {
indexScrollPos = window.scrollY;
}
});
}
export function resolve(path: string) {
const resolved = router.resolve(path);

View file

@ -11,7 +11,7 @@
</header>
<div class="content" :class="{ _flat_: !fullView }">
<router-view v-slot="{ Component }">
<transition :name="$store.state.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
<transition :name="$store.state.animation && navigationInfo ? 'page' : ''" @before-enter="saveScrollPosition" @enter="onTransition">
<keep-alive :include="['timeline']">
<component :is="Component" :ref="changePage"/>
</keep-alive>
@ -64,6 +64,7 @@ import XHeader from './_common_/header.vue';
import * as os from '@client/os';
import { sidebarDef } from '@client/sidebar';
import * as symbols from '@client/symbols';
import { saveScrollPosition, navigationInfo } from '@client/router';
const DESKTOP_THRESHOLD = 1100;
const MOBILE_THRESHOLD = 600;
@ -85,6 +86,7 @@ export default defineComponent({
isDesktop: window.innerWidth >= DESKTOP_THRESHOLD,
widgetsShowing: false,
fullView: false,
navigationInfo,
wallpaper: localStorage.getItem('wallpaper') != null,
faLayerGroup, faBars, faBell, faHome, faCircle, faPencilAlt,
};
@ -152,6 +154,10 @@ export default defineComponent({
this.$refs.drawerNav.show();
},
saveScrollPosition() {
saveScrollPosition();
},
onTransition() {
if (window._scroll) window._scroll();
},
@ -215,6 +221,39 @@ export default defineComponent({
opacity: 0;
}
.page-enter-active {
position: absolute;
top: 0;
z-index: 1;
width: 100%;
opacity: 1;
transform: translateX(0);
transition: transform 500ms cubic-bezier(0.23, 1, 0.32, 1), opacity 500ms cubic-bezier(0.23, 1, 0.32, 1);
}
.page-leave-active {
opacity: 1;
transform: translateX(0);
transition: transform 500ms cubic-bezier(0.23, 1, 0.32, 1), opacity 500ms cubic-bezier(0.23, 1, 0.32, 1);
}
.page-enter-from {
//opacity: 0;
transform: translateX(128px);
/* iOSはoverflow: clipをサポートしていない */
@supports (-webkit-touch-callout: none) {
transform: translateX(0);
}
}
.page-leave-active {
opacity: 0;
transform: translateX(-64px);
/* iOSはoverflow: clipをサポートしていない */
@supports (-webkit-touch-callout: none) {
transform: translateX(0);
}
}
.mk-app {
$header-height: 50px;
$ui-font-size: 1em;
@ -294,6 +333,7 @@ export default defineComponent({
}
> .content {
position: relative;
background: var(--bg);
--stickyTop: #{$header-height};
}