summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/MkTimeline.vue
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/MkTimeline.vue
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/MkTimeline.vue')
-rw-r--r--packages/frontend/src/components/MkTimeline.vue110
1 files changed, 95 insertions, 15 deletions
diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue
index 7b740167ec..32b2e1ae11 100644
--- a/packages/frontend/src/components/MkTimeline.vue
+++ b/packages/frontend/src/components/MkTimeline.vue
@@ -5,29 +5,55 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<MkPullToRefresh ref="prComponent" :refresher="() => reloadTimeline()">
- <MkNotes
- v-if="paginationQuery"
- ref="tlComponent"
- :pagination="paginationQuery"
- :noGap="!prefer.s.showGapBetweenNotesInTimeline"
- @queue="emit('queue', $event)"
- @status="prComponent?.setDisabled($event)"
- />
+ <MkPagination v-if="paginationQuery" ref="pagingComponent" :pagination="paginationQuery" @queue="emit('queue', $event)" @status="prComponent?.setDisabled($event)">
+ <template #empty>
+ <div class="_fullinfo">
+ <img :src="infoImageUrl" draggable="false"/>
+ <div>{{ i18n.ts.noNotes }}</div>
+ </div>
+ </template>
+
+ <template #default="{ items: notes }">
+ <component
+ :is="prefer.s.animation ? TransitionGroup : 'div'"
+ :class="[$style.root, { [$style.noGap]: noGap, '_gaps': !noGap, [$style.reverse]: paginationQuery.reversed }]"
+ :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"
+ >
+ <template v-for="(note, i) in notes" :key="note.id">
+ <div v-if="note._shouldInsertAd_" :class="[$style.noteWithAd, { '_gaps': !noGap }]" :data-scroll-anchor="note.id">
+ <MkNote :class="$style.note" :note="note" :withHardMute="true"/>
+ <div :class="$style.ad">
+ <MkAd :preferForms="['horizontal', 'horizontal-big']"/>
+ </div>
+ </div>
+ <MkNote v-else :class="$style.note" :note="note" :withHardMute="true" :data-scroll-anchor="note.id"/>
+ </template>
+ </component>
+ </template>
+ </MkPagination>
</MkPullToRefresh>
</template>
<script lang="ts" setup>
-import { computed, watch, onUnmounted, provide, useTemplateRef } from 'vue';
+import { computed, watch, onUnmounted, provide, useTemplateRef, TransitionGroup } from 'vue';
import * as Misskey from 'misskey-js';
import type { BasicTimelineType } from '@/timelines.js';
import type { Paging } from '@/components/MkPagination.vue';
-import MkNotes from '@/components/MkNotes.vue';
import MkPullToRefresh from '@/components/MkPullToRefresh.vue';
import { useStream } from '@/stream.js';
import * as sound from '@/utility/sound.js';
import { $i } from '@/i.js';
import { instance } from '@/instance.js';
import { prefer } from '@/preferences.js';
+import MkNote from '@/components/MkNote.vue';
+import MkPagination from '@/components/MkPagination.vue';
+import { i18n } from '@/i18n.js';
+import { infoImageUrl } from '@/instance.js';
const props = withDefaults(defineProps<{
src: BasicTimelineType | 'mentions' | 'directs' | 'list' | 'antenna' | 'channel' | 'role';
@@ -71,12 +97,12 @@ type TimelineQueryType = {
};
const prComponent = useTemplateRef('prComponent');
-const tlComponent = useTemplateRef('tlComponent');
+const pagingComponent = useTemplateRef('pagingComponent');
let tlNotesCount = 0;
function prepend(note: Misskey.entities.Note) {
- if (tlComponent.value == null) return;
+ if (pagingComponent.value == null) return;
tlNotesCount++;
@@ -84,7 +110,7 @@ function prepend(note: Misskey.entities.Note) {
note._shouldInsertAd_ = true;
}
- tlComponent.value.pagingComponent?.prepend(note);
+ pagingComponent.value.prepend(note);
emit('note');
@@ -96,6 +122,7 @@ function prepend(note: Misskey.entities.Note) {
let connection: Misskey.ChannelConnection | null = null;
let connection2: Misskey.ChannelConnection | null = null;
let paginationQuery: Paging | null = null;
+const noGap = !prefer.s.showGapBetweenNotesInTimeline;
const stream = useStream();
@@ -290,11 +317,11 @@ onUnmounted(() => {
function reloadTimeline() {
return new Promise<void>((res) => {
- if (tlComponent.value == null) return;
+ if (pagingComponent.value == null) return;
tlNotesCount = 0;
- tlComponent.value.pagingComponent?.reload().then(() => {
+ pagingComponent.value.reload().then(() => {
res();
});
});
@@ -304,3 +331,56 @@ defineExpose({
reloadTimeline,
});
</script>
+
+<style lang="scss" module>
+.transition_x_move,
+.transition_x_enterActive,
+.transition_x_leaveActive {
+ transition: opacity 0.3s cubic-bezier(0,.5,.5,1), transform 0.3s cubic-bezier(0,.5,.5,1) !important;
+}
+.transition_x_enterFrom,
+.transition_x_leaveTo {
+ opacity: 0;
+ transform: translateY(-50%);
+}
+.transition_x_leaveActive {
+ position: absolute;
+}
+
+.reverse {
+ display: flex;
+ flex-direction: column-reverse;
+}
+
+.root {
+ container-type: inline-size;
+
+ &.noGap {
+ background: var(--MI_THEME-panel);
+
+ .note {
+ border-bottom: solid 0.5px var(--MI_THEME-divider);
+ }
+
+ .ad {
+ padding: 8px;
+ background-size: auto auto;
+ background-image: repeating-linear-gradient(45deg, transparent, transparent 8px, var(--MI_THEME-bg) 8px, var(--MI_THEME-bg) 14px);
+ border-bottom: solid 0.5px var(--MI_THEME-divider);
+ }
+ }
+
+ &:not(.noGap) {
+ background: var(--MI_THEME-bg);
+
+ .note {
+ background: var(--MI_THEME-panel);
+ border-radius: var(--MI-radius);
+ }
+ }
+}
+
+.ad:empty {
+ display: none;
+}
+</style>