Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
017e905
implement SkTransitionGroup to dynamically switch between TransitionG…
warriordog May 29, 2025
8028c4e
use SkTransitionGroup for all dynamic TransitionGroup components
warriordog May 29, 2025
14bd7f5
fix use of :key on "more" slot in MkReactionsViewer
warriordog May 29, 2025
0299e64
use SkTransitionGroup in all locations that hardcode use of Transitio…
warriordog May 29, 2025
d7428a1
fix :animate condition in MkImgWithBlurhash
warriordog May 29, 2025
48b37e0
refactor: move to global
kakkokari-gtyih May 30, 2025
f56afe8
refactor
kakkokari-gtyih May 30, 2025
01c79e0
migrate rest of the components
kakkokari-gtyih May 30, 2025
87b6b7d
remove unused imports
kakkokari-gtyih May 30, 2025
1f9712a
fix
kakkokari-gtyih May 30, 2025
686aa1d
Update MkReactionsViewer.vue
kakkokari-gtyih May 30, 2025
83449f7
revert changes to MkImgWithBlurhash to fix CSS issue
warriordog May 30, 2025
292d079
Merge branch 'fix-dynamic-transition-group' of https://github.com/kak…
kakkokari-gtyih May 31, 2025
742d19b
Merge branch 'develop' into fix-dynamic-transition-group
kakkokari-gtyih Jul 3, 2025
1fcf428
Merge remote-tracking branch 'msky/develop' into fix-dynamic-transiti…
kakkokari-gtyih Aug 22, 2025
8ef45bb
Merge branch 'develop' into fix-dynamic-transition-group
kakkokari-gtyih Jan 14, 2026
1552a58
Merge branch 'develop' into fix-dynamic-transition-group
kakkokari-gtyih Jan 22, 2026
11fb1fb
Update MkTransitionGroup.vue
kakkokari-gtyih Jan 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions packages/frontend/src/components/MkDrive.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</template>

<TransitionGroup
<MkTransitionGroup
tag="div"
:enterActiveClass="prefer.s.animation ? $style.transition_files_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_files_leaveActive : ''"
:enterFromClass="prefer.s.animation ? $style.transition_files_enterFrom : ''"
:leaveToClass="prefer.s.animation ? $style.transition_files_leaveTo : ''"
:moveClass="prefer.s.animation ? $style.transition_files_move : ''"
:enterActiveClass="$style.transition_files_enterActive"
:leaveActiveClass="$style.transition_files_leaveActive"
:enterFromClass="$style.transition_files_enterFrom"
:leaveToClass="$style.transition_files_leaveTo"
:moveClass="$style.transition_files_move"
:class="$style.files"
>
<XFile
Expand All @@ -108,17 +108,17 @@ SPDX-License-Identifier: AGPL-3.0-only
@dragstart="onFileDragstart(file, $event)"
@dragend="isDragSource = false"
/>
</TransitionGroup>
</MkTransitionGroup>
</MkStickyContainer>
</template>
<TransitionGroup
<MkTransitionGroup
v-else
tag="div"
:enterActiveClass="prefer.s.animation ? $style.transition_files_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_files_leaveActive : ''"
:enterFromClass="prefer.s.animation ? $style.transition_files_enterFrom : ''"
:leaveToClass="prefer.s.animation ? $style.transition_files_leaveTo : ''"
:moveClass="prefer.s.animation ? $style.transition_files_move : ''"
:enterActiveClass="$style.transition_files_enterActive"
:leaveActiveClass="$style.transition_files_leaveActive"
:enterFromClass="$style.transition_files_enterFrom"
:leaveToClass="$style.transition_files_leaveTo"
:moveClass="$style.transition_files_move"
:class="$style.files"
>
<XFile
Expand All @@ -130,7 +130,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@dragstart="onFileDragstart(file, $event)"
@dragend="isDragSource = false"
/>
</TransitionGroup>
</MkTransitionGroup>

<MkButton
v-show="canFetchFiles"
Expand Down Expand Up @@ -162,7 +162,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { nextTick, onActivated, onBeforeUnmount, onMounted, ref, useTemplateRef, watch, computed, TransitionGroup, markRaw } from 'vue';
import { nextTick, onActivated, onBeforeUnmount, onMounted, ref, useTemplateRef, watch, computed, markRaw } from 'vue';
import * as Misskey from 'misskey-js';
import MkButton from './MkButton.vue';
import type { MenuItem } from '@/types/menu.js';
Expand Down
8 changes: 3 additions & 5 deletions packages/frontend/src/components/MkReactionsViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->

<template>
<component
:is="prefer.s.animation ? TransitionGroup : 'div'"
<MkTransitionGroup
:enterActiveClass="$style.transition_x_enterActive"
:leaveActiveClass="$style.transition_x_leaveActive"
:enterFromClass="$style.transition_x_enterFrom"
Expand All @@ -24,14 +23,13 @@ SPDX-License-Identifier: AGPL-3.0-only
:myReaction="props.myReaction"
@reactionToggled="onMockToggleReaction"
/>
<slot v-if="hasMoreReactions" name="more"></slot>
</component>
<slot v-if="hasMoreReactions" :key="'$more'" name="more"></slot>
</MkTransitionGroup>
</template>

<script lang="ts" setup>
import * as Misskey from 'misskey-js';
import { inject, watch, ref } from 'vue';
import { TransitionGroup } from 'vue';
import { isSupportedEmoji } from '@@/js/emojilist.js';
import XReaction from '@/components/MkReactionsViewer.reaction.vue';
import { $i } from '@/i.js';
Expand Down
7 changes: 3 additions & 4 deletions packages/frontend/src/components/MkStreamingNotesTimeline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.newBg2"></div>
<button class="_button" :class="$style.newButton" @click="releaseQueue()"><i class="ti ti-circle-arrow-up"></i> {{ i18n.ts.newNote }}</button>
</div>
<component
:is="prefer.s.animation ? TransitionGroup : 'div'"
<MkTransitionGroup
:class="$style.notes"
:enterActiveClass="$style.transition_x_enterActive"
:leaveActiveClass="$style.transition_x_leaveActive"
Expand All @@ -46,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<MkNote v-else :class="$style.note" :note="note" :withHardMute="true" :data-scroll-anchor="note.id"/>
</template>
</component>
</MkTransitionGroup>
<button v-show="paginator.canFetchOlder.value" key="_more_" v-appear="prefer.s.enableInfiniteScroll ? paginator.fetchOlder : null" :disabled="paginator.fetchingOlder.value" class="_button" :class="$style.more" @click="paginator.fetchOlder">
<div v-if="!paginator.fetchingOlder.value">{{ i18n.ts.loadMore }}</div>
<MkLoading v-else :inline="true"/>
Expand All @@ -56,7 +55,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { computed, watch, onUnmounted, provide, useTemplateRef, TransitionGroup, onMounted, shallowRef, ref, markRaw } from 'vue';
import { computed, watch, onUnmounted, provide, useTemplateRef, onMounted, shallowRef, ref, markRaw } from 'vue';
import * as Misskey from 'misskey-js';
import { useInterval } from '@@/js/use-interval.js';
import { useDocumentVisibility } from '@@/js/use-document-visibility.js';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>

<div v-else ref="rootEl">
<component
:is="prefer.s.animation ? TransitionGroup : 'div'" :class="[$style.notifications]"
<MkTransitionGroup
:class="[$style.notifications]"
:enterActiveClass="$style.transition_x_enterActive"
:leaveActiveClass="$style.transition_x_leaveActive"
:enterFromClass="$style.transition_x_enterFrom"
Expand All @@ -32,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkNote v-if="['reply', 'quote', 'mention'].includes(notification.type) && 'note' in notification" :class="$style.content" :note="notification.note" :withHardMute="true"/>
<XNotification v-else :class="$style.content" :notification="notification" :withTime="true" :full="true"/>
</div>
</component>
</MkTransitionGroup>
<button v-show="paginator.canFetchOlder.value" key="_more_" v-appear="prefer.s.enableInfiniteScroll ? paginator.fetchOlder : null" :disabled="paginator.fetchingOlder.value" class="_button" :class="$style.more" @click="paginator.fetchOlder">
<div v-if="!paginator.fetchingOlder.value">{{ i18n.ts.loadMore }}</div>
<MkLoading v-else/>
Expand All @@ -42,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { onUnmounted, onMounted, computed, useTemplateRef, TransitionGroup, markRaw, watch } from 'vue';
import { onUnmounted, onMounted, computed, useTemplateRef, markRaw, watch } from 'vue';
import * as Misskey from 'misskey-js';
import { notificationTypes } from 'misskey-js';
import { useInterval } from '@@/js/use-interval.js';
Expand Down
39 changes: 39 additions & 0 deletions packages/frontend/src/components/global/MkTransitionGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->

<template>
<TransitionGroup v-if="animate ?? prefer.s.animation" v-bind="props" :class="props.class">
<slot></slot>
</TransitionGroup>
<component :is="tag" v-else :class="props.class">
<slot></slot>
</component>
</template>

<script setup lang="ts">
import type { TransitionGroupProps, HTMLAttributes } from 'vue';
import { prefer } from '@/preferences.js';

// This can be an inline type, but pulling it out makes TS errors clearer.
interface MkTransitionGroupProps extends TransitionGroupProps {
/**
* Override CSS styles for the TransitionGroup or native element.
*/
class?: HTMLAttributes['class'];

/**
* If true, will render a TransitionGroup.
* If false, will render a native element.
* If null or undefined (default), will respect the value of prefer.s.animation.
*/
animate?: boolean | null;
}

const props = withDefaults(defineProps<MkTransitionGroupProps>(), {
tag: 'div',
class: undefined,
animate: undefined,
});
</script>
14 changes: 7 additions & 7 deletions packages/frontend/src/components/global/StackingRouterView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
-->

<template>
<TransitionGroup
:enterActiveClass="prefer.s.animation ? $style.transition_x_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_x_leaveActive : ''"
:enterFromClass="prefer.s.animation ? $style.transition_x_enterFrom : ''"
:leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''"
:moveClass="prefer.s.animation ? $style.transition_x_move : ''"
<MkTransitionGroup
:enterActiveClass="$style.transition_x_enterActive"
:leaveActiveClass="$style.transition_x_leaveActive"
:enterFromClass="$style.transition_x_enterFrom"
:leaveToClass="$style.transition_x_leaveTo"
:moveClass="$style.transition_x_move"
:duration="200"
tag="div" :class="$style.tabs"
>
Expand Down Expand Up @@ -37,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
</div>
</TransitionGroup>
</MkTransitionGroup>
</template>

<script lang="ts" setup>
Expand Down
3 changes: 3 additions & 0 deletions packages/frontend/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import MkLazy from './global/MkLazy.vue';
import MkResult from './global/MkResult.vue';
import MkSystemIcon from './global/MkSystemIcon.vue';
import MkTip from './global/MkTip.vue';
import MkTransitionGroup from './global/MkTransitionGroup.vue';
import PageWithHeader from './global/PageWithHeader.vue';
import PageWithAnimBg from './global/PageWithAnimBg.vue';
import SearchMarker from './global/SearchMarker.vue';
Expand Down Expand Up @@ -69,6 +70,7 @@ export const components = {
MkResult: MkResult,
MkSystemIcon: MkSystemIcon,
MkTip: MkTip,
MkTransitionGroup: MkTransitionGroup,
PageWithHeader: PageWithHeader,
PageWithAnimBg: PageWithAnimBg,
SearchMarker: SearchMarker,
Expand Down Expand Up @@ -104,6 +106,7 @@ declare module 'vue' {
MkResult: typeof MkResult;
MkSystemIcon: typeof MkSystemIcon;
MkTip: typeof MkTip;
MkTransitionGroup: typeof MkTransitionGroup;
PageWithHeader: typeof PageWithHeader;
PageWithAnimBg: typeof PageWithAnimBg;
SearchMarker: typeof SearchMarker;
Expand Down
14 changes: 7 additions & 7 deletions packages/frontend/src/pages/chat/XMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkA v-if="isSearchResult && 'toRoom' in message && message.toRoom != null" :to="`/chat/room/${message.toRoomId}`">{{ message.toRoom.name }}</MkA>
<MkA v-if="isSearchResult && 'toUser' in message && message.toUser != null && isMe" :to="`/chat/user/${message.toUserId}`">@{{ message.toUser.username }}</MkA>
</div>
<TransitionGroup
:enterActiveClass="prefer.s.animation ? $style.transition_reaction_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_reaction_leaveActive : ''"
:enterFromClass="prefer.s.animation ? $style.transition_reaction_enterFrom : ''"
:leaveToClass="prefer.s.animation ? $style.transition_reaction_leaveTo : ''"
:moveClass="prefer.s.animation ? $style.transition_reaction_move : ''"
<MkTransitionGroup
:enterActiveClass="$style.transition_reaction_enterActive"
:leaveActiveClass="$style.transition_reaction_leaveActive"
:enterFromClass="$style.transition_reaction_enterFrom"
:leaveToClass="$style.transition_reaction_leaveTo"
:moveClass="$style.transition_reaction_move"
tag="div" :class="$style.reactions"
>
<div v-for="record in message.reactions" :key="record.reaction + record.user.id" :class="[$style.reaction, record.user.id === $i.id ? $style.reactionMy : null]" @click="onReactionClick(record)">
Expand All @@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.reactionIcon"
/>
</div>
</TransitionGroup>
</MkTransitionGroup>
</div>
</div>
</template>
Expand Down
15 changes: 7 additions & 8 deletions packages/frontend/src/pages/chat/room.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton :class="$style.more" :wait="moreFetching" primary rounded @click="fetchMore">{{ i18n.ts.loadMore }}</MkButton>
</div>

<TransitionGroup
:enterActiveClass="prefer.s.animation ? $style.transition_x_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_x_leaveActive : ''"
:enterFromClass="prefer.s.animation ? $style.transition_x_enterFrom : ''"
:leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''"
:moveClass="prefer.s.animation ? $style.transition_x_move : ''"
<MkTransitionGroup
:enterActiveClass="$style.transition_x_enterActive"
:leaveActiveClass="$style.transition_x_leaveActive"
:enterFromClass="$style.transition_x_enterFrom"
:leaveToClass="$style.transition_x_leaveTo"
:moveClass="$style.transition_x_move"
tag="div" class="_gaps"
>
<template v-for="item in timeline.toReversed()" :key="item.id">
Expand All @@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span>{{ item.prevText }} <i class="ti ti-chevron-down"></i></span>
</div>
</template>
</TransitionGroup>
</MkTransitionGroup>
</div>

<div v-if="user && (!user.canChat || user.host !== null)">
Expand Down Expand Up @@ -105,7 +105,6 @@ import { i18n } from '@/i18n.js';
import { ensureSignin } from '@/i.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import { definePage } from '@/page.js';
import { prefer } from '@/preferences.js';
import MkButton from '@/components/MkButton.vue';
import { useRouter } from '@/router.js';
import { useMutationObserver } from '@/composables/use-mutation-observer.js';
Expand Down
7 changes: 3 additions & 4 deletions packages/frontend/src/ui/_common_/common.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only
v-on="popup.events"
/>

<component
:is="prefer.s.animation ? TransitionGroup : 'div'"
<MkTransitionGroup
tag="div"
:class="[$style.notifications, {
[$style.notificationsPosition_leftTop]: prefer.s.notificationPosition === 'leftTop',
Expand All @@ -85,7 +84,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-for="notification in notifications" :key="notification.id" :class="$style.notification">
<XNotification :notification="notification"/>
</div>
</component>
</MkTransitionGroup>

<XStreamIndicator/>

Expand All @@ -102,7 +101,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>

<script lang="ts" setup>
import { defineAsyncComponent, ref, TransitionGroup } from 'vue';
import { defineAsyncComponent, ref } from 'vue';
import * as Misskey from 'misskey-js';
import { swInject } from './sw-inject.js';
import XNotification from './notification.vue';
Expand Down
5 changes: 2 additions & 3 deletions packages/frontend/src/widgets/WidgetFederation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only

<div class="wbrkwalb">
<MkLoading v-if="fetching"/>
<TransitionGroup v-else tag="div" :name="prefer.s.animation ? 'chart' : ''" class="instances">
<MkTransitionGroup v-else tag="div" name="chart" class="instances">
<div v-for="(instance, i) in instances" :key="instance.id" class="instance">
<img :src="getInstanceIcon(instance)" alt=""/>
<div class="body">
Expand All @@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<MkMiniChart class="chart" :src="charts[i].requests.received"/>
</div>
</TransitionGroup>
</MkTransitionGroup>
</div>
</MkContainer>
</template>
Expand All @@ -36,7 +36,6 @@ import MkMiniChart from '@/components/MkMiniChart.vue';
import { misskeyApi, misskeyApiGet } from '@/utility/misskey-api.js';
import { i18n } from '@/i18n.js';
import { getProxiedImageUrlNullable } from '@/utility/media-proxy.js';
import { prefer } from '@/preferences.js';

const name = 'federation';

Expand Down
5 changes: 2 additions & 3 deletions packages/frontend/src/widgets/WidgetTrends.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ SPDX-License-Identifier: AGPL-3.0-only

<div class="wbrkwala">
<MkLoading v-if="fetching"/>
<TransitionGroup v-else tag="div" :name="prefer.s.animation ? 'chart' : ''" class="tags">
<MkTransitionGroup v-else tag="div" name="chart" class="tags">
<div v-for="stat in stats" :key="stat.tag">
<div class="tag">
<MkA class="a" :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</MkA>
<p>{{ i18n.tsx.nUsersMentioned({ n: stat.usersCount }) }}</p>
</div>
<MkMiniChart class="chart" :src="stat.chart"/>
</div>
</TransitionGroup>
</MkTransitionGroup>
</div>
</MkContainer>
</template>
Expand All @@ -34,7 +34,6 @@ import MkContainer from '@/components/MkContainer.vue';
import MkMiniChart from '@/components/MkMiniChart.vue';
import { misskeyApiGet } from '@/utility/misskey-api.js';
import { i18n } from '@/i18n.js';
import { prefer } from '@/preferences.js';

const name = 'trends';

Expand Down
Loading