wip
This commit is contained in:
@@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
|
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
|
||||||
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
||||||
<MkAvatar :class="$style.avatar" :user="appearNote.user" :link="!mock" :preview="!mock"/>
|
<MkAvatar :class="$style.avatar" :user="appearNote.user" :link="!mock" :preview="!mock" :style="{ viewTransitionName: transitionName }"/>
|
||||||
<div :class="$style.main">
|
<div :class="$style.main">
|
||||||
<MkNoteHeader :note="appearNote" :mini="true"/>
|
<MkNoteHeader :note="appearNote" :mini="true"/>
|
||||||
<MkInstanceTicker v-if="showTicker" :host="appearNote.user.host" :instance="appearNote.user.instance"/>
|
<MkInstanceTicker v-if="showTicker" :host="appearNote.user.host" :instance="appearNote.user.instance"/>
|
||||||
@@ -223,6 +223,7 @@ import { focusPrev, focusNext } from '@/utility/focus.js';
|
|||||||
import { getAppearNote } from '@/utility/get-appear-note.js';
|
import { getAppearNote } from '@/utility/get-appear-note.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import { getPluginHandlers } from '@/plugin.js';
|
import { getPluginHandlers } from '@/plugin.js';
|
||||||
|
import { prepareViewTransition } from '@/page.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
note: Misskey.entities.Note;
|
note: Misskey.entities.Note;
|
||||||
@@ -235,6 +236,8 @@ const props = withDefaults(defineProps<{
|
|||||||
|
|
||||||
provide('mock', props.mock);
|
provide('mock', props.mock);
|
||||||
|
|
||||||
|
const transitionName = prepareViewTransition('note-noteDetailed', props.note.id).avatar;
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: 'reaction', emoji: string): void;
|
(ev: 'reaction', emoji: string): void;
|
||||||
(ev: 'removeReaction', emoji: string): void;
|
(ev: 'removeReaction', emoji: string): void;
|
||||||
@@ -852,6 +855,8 @@ function emitUpdReaction(emoji: string, delta: number) {
|
|||||||
position: sticky !important;
|
position: sticky !important;
|
||||||
top: calc(22px + var(--MI-stickyTop, 0px));
|
top: calc(22px + var(--MI-stickyTop, 0px));
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
||||||
|
contain: paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
|
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
:exclude="pageCacheController"
|
:exclude="pageCacheController"
|
||||||
>
|
>
|
||||||
<Suspense :timeout="0">
|
<Suspense :timeout="0">
|
||||||
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/>
|
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)" :style="{ viewTransitionName: viewId }"/>
|
||||||
|
|
||||||
<template #fallback>
|
<template #fallback>
|
||||||
<MkLoading/>
|
<MkLoading/>
|
||||||
@@ -41,7 +41,8 @@ if (router == null) {
|
|||||||
const currentDepth = inject(DI.routerCurrentDepth, 0);
|
const currentDepth = inject(DI.routerCurrentDepth, 0);
|
||||||
provide(DI.routerCurrentDepth, currentDepth + 1);
|
provide(DI.routerCurrentDepth, currentDepth + 1);
|
||||||
|
|
||||||
provide(DI.viewId, uuid());
|
const viewId = uuid();
|
||||||
|
provide(DI.viewId, viewId);
|
||||||
|
|
||||||
const viewTransitionId = ref(uuid());
|
const viewTransitionId = ref(uuid());
|
||||||
provide(DI.viewTransitionId, viewTransitionId);
|
provide(DI.viewTransitionId, viewTransitionId);
|
||||||
@@ -70,10 +71,11 @@ async function onChange({ resolved, key: newKey }) {
|
|||||||
if (current == null || 'redirect' in current.route) return;
|
if (current == null || 'redirect' in current.route) return;
|
||||||
|
|
||||||
viewTransitionId.value = uuid();
|
viewTransitionId.value = uuid();
|
||||||
await new Promise(resolve => setTimeout(resolve, 100));
|
await nextTick();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
console.log('onChange', viewTransitionId.value);
|
console.log('onChange', viewTransitionId.value);
|
||||||
document.startViewTransition(() => new Promise((res) => {
|
document.startViewTransition(() => new Promise((res) => {
|
||||||
|
console.log('startViewTransition', viewTransitionId.value);
|
||||||
currentPageComponent.value = current.route.component;
|
currentPageComponent.value = current.route.component;
|
||||||
currentPageProps.value = current.props;
|
currentPageProps.value = current.props;
|
||||||
key.value = newKey + JSON.stringify(Object.fromEntries(current.props));
|
key.value = newKey + JSON.stringify(Object.fromEntries(current.props));
|
||||||
@@ -117,3 +119,31 @@ onBeforeUnmount(() => {
|
|||||||
router.removeListener('change', onChange);
|
router.removeListener('change', onChange);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@keyframes fade-in {
|
||||||
|
from { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-out {
|
||||||
|
to { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-from-right {
|
||||||
|
from { transform: translateX(300px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-to-left {
|
||||||
|
to { transform: translateX(-300px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-old(v-bind(viewId)) {
|
||||||
|
animation: 90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
|
||||||
|
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-new(v-bind(viewId)) {
|
||||||
|
animation: 210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
|
||||||
|
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@@ -4,8 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { inject, isRef, onActivated, onBeforeUnmount, provide, ref, toValue, watch } from 'vue';
|
import { computed, inject, isRef, onActivated, onBeforeUnmount, provide, ref, toValue, watch } from 'vue';
|
||||||
import type { MaybeRefOrGetter, Ref } from 'vue';
|
import type { MaybeRefOrGetter, Ref } from 'vue';
|
||||||
|
import { DI } from '@/di.js';
|
||||||
|
|
||||||
export type PageMetadata = {
|
export type PageMetadata = {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -69,3 +70,12 @@ export const injectReactiveMetadata = (): Ref<PageMetadata | null> => {
|
|||||||
const metadataRef = getMetadata();
|
const metadataRef = getMetadata();
|
||||||
return isRef(metadataRef) ? metadataRef : ref(null);
|
return isRef(metadataRef) ? metadataRef : ref(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function prepareViewTransition(type: string, id: string) {
|
||||||
|
const viewId = inject(DI.viewId);
|
||||||
|
const viewTransitionId = inject(DI.viewTransitionId);
|
||||||
|
return {
|
||||||
|
avatar: computed(() => 'adsfsdfsfg' + viewId + viewTransitionId.value + id),
|
||||||
|
//avatar: computed(() => 'adsfsdfsfg' + id),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@@ -8,7 +8,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||||
<MkSpacer :contentMax="800">
|
<MkSpacer :contentMax="800">
|
||||||
<div>
|
<div>
|
||||||
<Transition :name="prefer.s.animation ? 'fade' : ''" mode="out-in">
|
|
||||||
<div v-if="note">
|
<div v-if="note">
|
||||||
<div v-if="showNext" class="_margin">
|
<div v-if="showNext" class="_margin">
|
||||||
<MkNotes class="" :pagination="showNext === 'channel' ? nextChannelPagination : nextUserPagination" :noGap="true" :disableAutoLoad="true"/>
|
<MkNotes class="" :pagination="showNext === 'channel' ? nextChannelPagination : nextUserPagination" :noGap="true" :disableAutoLoad="true"/>
|
||||||
@@ -41,7 +40,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</div>
|
</div>
|
||||||
<MkError v-else-if="error" @retry="fetchNote()"/>
|
<MkError v-else-if="error" @retry="fetchNote()"/>
|
||||||
<MkLoading v-else/>
|
<MkLoading v-else/>
|
||||||
</Transition>
|
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</MkStickyContainer>
|
||||||
|
Reference in New Issue
Block a user