summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/global
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2025-04-29 15:37:43 -0400
committerHazelnoot <acomputerdog@gmail.com>2025-04-29 15:54:11 -0400
commit9c301fa5aac7e339a2b41feab8d0d247a60f50aa (patch)
tree26e1423620a2811a5e9372bcee6858851d9fad3e /packages/frontend/src/components/global
parentalign `docker_example.yml` with `example.yml` (diff)
parentchore: follow up on fixing Chromatic CI diff strategy (#15912) (diff)
downloadsharkey-9c301fa5aac7e339a2b41feab8d0d247a60f50aa.tar.gz
sharkey-9c301fa5aac7e339a2b41feab8d0d247a60f50aa.tar.bz2
sharkey-9c301fa5aac7e339a2b41feab8d0d247a60f50aa.zip
Merge branch 'misskey-develop' into merge/2025-03-24
# Conflicts: # .github/workflows/api-misskey-js.yml # .github/workflows/changelog-check.yml # .github/workflows/check-misskey-js-autogen.yml # .github/workflows/get-api-diff.yml # .github/workflows/lint.yml # .github/workflows/locale.yml # .github/workflows/on-release-created.yml # .github/workflows/storybook.yml # .github/workflows/test-backend.yml # .github/workflows/test-federation.yml # .github/workflows/test-frontend.yml # .github/workflows/test-misskey-js.yml # .github/workflows/test-production.yml # .github/workflows/validate-api-json.yml # package.json # packages/backend/package.json # packages/backend/src/server/api/ApiCallService.ts # packages/backend/src/server/api/endpoints/drive/files/create.ts # packages/frontend-shared/js/url.ts # packages/frontend/package.json # packages/frontend/src/components/MkFileCaptionEditWindow.vue # packages/frontend/src/components/MkInfo.vue # packages/frontend/src/components/MkLink.vue # packages/frontend/src/components/MkNote.vue # packages/frontend/src/components/MkNotes.vue # packages/frontend/src/components/MkPageWindow.vue # packages/frontend/src/components/MkReactionsViewer.vue # packages/frontend/src/components/MkTimeline.vue # packages/frontend/src/components/MkUrlPreview.vue # packages/frontend/src/components/MkUserPopup.vue # packages/frontend/src/components/global/MkPageHeader.vue # packages/frontend/src/components/global/MkUrl.vue # packages/frontend/src/components/global/PageWithHeader.vue # packages/frontend/src/pages/about-misskey.vue # packages/frontend/src/pages/announcements.vue # packages/frontend/src/pages/antenna-timeline.vue # packages/frontend/src/pages/channel.vue # packages/frontend/src/pages/instance-info.vue # packages/frontend/src/pages/note.vue # packages/frontend/src/pages/page.vue # packages/frontend/src/pages/role.vue # packages/frontend/src/pages/tag.vue # packages/frontend/src/pages/timeline.vue # packages/frontend/src/pages/user-list-timeline.vue # packages/frontend/src/pages/user/followers.vue # packages/frontend/src/pages/user/following.vue # packages/frontend/src/pages/user/home.vue # packages/frontend/src/pages/user/index.vue # packages/frontend/src/ui/deck.vue # packages/misskey-js/generator/package.json # pnpm-lock.yaml # scripts/changelog-checker/package-lock.json # scripts/changelog-checker/package.json
Diffstat (limited to 'packages/frontend/src/components/global')
-rw-r--r--packages/frontend/src/components/global/MkPageHeader.vue27
-rw-r--r--packages/frontend/src/components/global/MkSpacer.vue58
-rw-r--r--packages/frontend/src/components/global/PageWithHeader.vue47
-rw-r--r--packages/frontend/src/components/global/RouterView.vue46
4 files changed, 48 insertions, 130 deletions
diff --git a/packages/frontend/src/components/global/MkPageHeader.vue b/packages/frontend/src/components/global/MkPageHeader.vue
index 42bb49e8d9..c939f0b44e 100644
--- a/packages/frontend/src/components/global/MkPageHeader.vue
+++ b/packages/frontend/src/components/global/MkPageHeader.vue
@@ -49,19 +49,12 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</template>
-<script lang="ts" setup>
-import { onMounted, onUnmounted, ref, inject, useTemplateRef, computed } from 'vue';
-import { scrollToTop } from '@@/js/scroll.js';
-import XTabs from './MkPageHeader.tabs.vue';
-import type { Tab } from './MkPageHeader.tabs.vue';
+<script lang="ts">
import type { PageHeaderItem } from '@/types/page-header.js';
import type { PageMetadata } from '@/page.js';
-import { globalEvents } from '@/events.js';
-import { openAccountMenu as openAccountMenu_ } from '@/accounts.js';
-import { $i } from '@/i.js';
-import { DI } from '@/di.js';
+import type { Tab } from './MkPageHeader.tabs.vue';
-const props = withDefaults(defineProps<{
+export type PageHeaderProps = {
overridePageMetadata?: PageMetadata;
tabs?: Tab[];
tab?: string;
@@ -70,7 +63,19 @@ const props = withDefaults(defineProps<{
hideTitle?: boolean;
displayMyAvatar?: boolean;
displayBackButton?: boolean;
-}>(), {
+};
+</script>
+
+<script lang="ts" setup>
+import { onMounted, onUnmounted, ref, inject, useTemplateRef, computed } from 'vue';
+import { scrollToTop } from '@@/js/scroll.js';
+import XTabs from './MkPageHeader.tabs.vue';
+import { globalEvents } from '@/events.js';
+import { openAccountMenu as openAccountMenu_ } from '@/accounts.js';
+import { $i } from '@/i.js';
+import { DI } from '@/di.js';
+
+const props = withDefaults(defineProps<PageHeaderProps>(), {
tabs: () => ([] as Tab[]),
});
diff --git a/packages/frontend/src/components/global/MkSpacer.vue b/packages/frontend/src/components/global/MkSpacer.vue
deleted file mode 100644
index c3bc37cb92..0000000000
--- a/packages/frontend/src/components/global/MkSpacer.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<!--
-SPDX-FileCopyrightText: syuilo and misskey-project
-SPDX-License-Identifier: AGPL-3.0-only
--->
-
-<template>
-<div :class="[$style.root, { [$style.rootMin]: forceSpacerMin }]">
- <div :class="$style.content">
- <slot></slot>
- </div>
-</div>
-</template>
-
-<script lang="ts" setup>
-import { inject } from 'vue';
-import { deviceKind } from '@/utility/device-kind.js';
-import { DI } from '@/di.js';
-
-const props = withDefaults(defineProps<{
- contentMax?: number | null;
- marginMin?: number;
- marginMax?: number;
-}>(), {
- contentMax: null,
- marginMin: 12,
- marginMax: 24,
-});
-
-const forceSpacerMin = inject(DI.forceSpacerMin, false) || deviceKind === 'smartphone';
-</script>
-
-<style lang="scss" module>
-.root {
- box-sizing: border-box;
- width: 100%;
-}
-.rootMin {
- padding: v-bind('props.marginMin + "px"') !important;
-}
-
-.content {
- margin: 0 auto;
- max-width: v-bind('props.contentMax + "px"');
- container-type: inline-size;
-}
-
-@container (max-width: 450px) {
- .root {
- padding: v-bind('props.marginMin + "px"');
- }
-}
-
-@container (min-width: 451px) {
- .root {
- padding: v-bind('props.marginMax + "px"');
- }
-}
-</style>
diff --git a/packages/frontend/src/components/global/PageWithHeader.vue b/packages/frontend/src/components/global/PageWithHeader.vue
index 85e61fd532..58c222038a 100644
--- a/packages/frontend/src/components/global/PageWithHeader.vue
+++ b/packages/frontend/src/components/global/PageWithHeader.vue
@@ -6,9 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div ref="rootEl" :class="[$style.root, reversed ? '_pageScrollableReversed' : '_pageScrollable']">
<MkStickyContainer>
- <template #header><MkPageHeader v-model:tab="tab" :actions="actions" :tabs="tabs" :displayBackButton="displayBackButton"/></template>
+ <template #header><MkPageHeader v-model:tab="tab" v-bind="pageHeaderProps"/></template>
<div :class="$style.body">
- <slot></slot>
+ <MkSwiper v-if="swipable && (props.tabs?.length ?? 1) > 1" v-model:tab="tab" :class="$style.swiper" :tabs="props.tabs">
+ <slot></slot>
+ </MkSwiper>
+ <slot v-else></slot>
</div>
<template #footer><slot name="footer"></slot></template>
</MkStickyContainer>
@@ -16,22 +19,24 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
-import { useTemplateRef } from 'vue';
+import { computed, useTemplateRef } from 'vue';
import { scrollInContainer } from '@@/js/scroll.js';
-import type { PageHeaderItem } from '@/types/page-header.js';
-import type { Tab } from './MkPageHeader.tabs.vue';
+import type { PageHeaderProps } from './MkPageHeader.vue';
import { useScrollPositionKeeper } from '@/use/use-scroll-position-keeper.js';
+import MkSwiper from '@/components/MkSwiper.vue';
+import { useRouter } from '@/router.js';
-const props = withDefaults(defineProps<{
- tabs?: Tab[];
- actions?: PageHeaderItem[] | null;
- thin?: boolean;
- hideTitle?: boolean;
- displayMyAvatar?: boolean;
+const props = withDefaults(defineProps<PageHeaderProps & {
reversed?: boolean;
- displayBackButton?: boolean;
+ swipable?: boolean;
}>(), {
- tabs: () => ([] as Tab[]),
+ reversed: false,
+ swipable: true,
+});
+
+const pageHeaderProps = computed(() => {
+ const { reversed, ...rest } = props;
+ return rest;
});
const tab = defineModel<string>('tab');
@@ -39,10 +44,18 @@ const rootEl = useTemplateRef('rootEl');
useScrollPositionKeeper(rootEl);
+const router = useRouter();
+
+router.useListener('same', () => {
+ scrollToTop();
+});
+
+function scrollToTop() {
+ if (rootEl.value) scrollInContainer(rootEl.value, { top: 0, behavior: 'smooth' });
+}
+
defineExpose({
- scrollToTop: () => {
- if (rootEl.value) scrollInContainer(rootEl.value, { top: 0, behavior: 'smooth' });
- },
+ scrollToTop,
});
</script>
@@ -51,7 +64,7 @@ defineExpose({
}
-.body {
+.body, .swiper {
min-height: calc(100cqh - (var(--MI-stickyTop, 0px) + var(--MI-stickyBottom, 0px)));
}
</style>
diff --git a/packages/frontend/src/components/global/RouterView.vue b/packages/frontend/src/components/global/RouterView.vue
index 78ac6900a3..27f7b18559 100644
--- a/packages/frontend/src/components/global/RouterView.vue
+++ b/packages/frontend/src/components/global/RouterView.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
-<div ref="rootEl" class="_pageContainer" :class="$style.root">
+<div class="_pageContainer" :class="$style.root">
<KeepAlive :max="prefer.s.numberOfPageCache">
<Suspense :timeout="0">
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/>
@@ -42,37 +42,6 @@ provide(DI.viewId, viewId);
const currentDepth = inject(DI.routerCurrentDepth, 0);
provide(DI.routerCurrentDepth, currentDepth + 1);
-const rootEl = useTemplateRef('rootEl');
-onMounted(() => {
- if (prefer.s.animation) {
- rootEl.value.style.viewTransitionName = viewId; // view-transition-nameにcss varが使えないっぽいため直接代入
- }
-});
-
-// view-transition-newなどの<pt-name-selector>にはcss varが使えず、v-bindできないため直接スタイルを生成
-const viewTransitionStylesTag = window.document.createElement('style');
-viewTransitionStylesTag.textContent = `
-@keyframes ${viewId}-old {
- to { transform: scale(0.95); opacity: 0; }
-}
-
-@keyframes ${viewId}-new {
- from { transform: scale(0.95); opacity: 0; }
-}
-
-::view-transition-old(${viewId}) {
- animation-duration: 0.2s;
- animation-name: ${viewId}-old;
-}
-
-::view-transition-new(${viewId}) {
- animation-duration: 0.2s;
- animation-name: ${viewId}-new;
-}
-`;
-
-window.document.head.appendChild(viewTransitionStylesTag);
-
const current = router.current!;
const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage);
const currentPageProps = ref(current.props);
@@ -90,18 +59,7 @@ router.useListener('change', ({ resolved }) => {
currentRoutePath = resolved.route.path;
}
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- if (prefer.s.animation && window.document.startViewTransition) {
- window.document.startViewTransition(() => new Promise((res) => {
- _();
- nextTick(() => {
- res();
- //setTimeout(res, 100);
- });
- }));
- } else {
- _();
- }
+ _();
});
</script>