This commit is contained in:
syuilo 2025-05-03 14:24:17 +09:00
parent 80703d1563
commit 77d4acfd32
7 changed files with 94 additions and 20 deletions

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkPagination ref="pagingComponent" :pagination="pagination" :disableAutoLoad="disableAutoLoad">
<MkPagination ref="pagingComponent" :pagination="pagination" :disableAutoLoad="disableAutoLoad" :pullToRefresh="pullToRefresh">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" draggable="false"/>
@ -35,11 +35,14 @@ import MkPagination from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';
const props = defineProps<{
const props = withDefaults(defineProps<{
pagination: Paging;
noGap?: boolean;
disableAutoLoad?: boolean;
}>();
pullToRefresh?: boolean;
}>(), {
pullToRefresh: true,
});
const pagingComponent = useTemplateRef('pagingComponent');

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<component :is="prefer.s.enablePullToRefresh ? MkPullToRefresh : 'div'" :refresher="() => paginator.reload()">
<component :is="prefer.s.enablePullToRefresh && pullToRefresh ? MkPullToRefresh : 'div'" :refresher="() => paginator.reload()">
<Transition
:enterActiveClass="prefer.s.animation ? $style.transition_fade_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_fade_leaveActive : ''"
@ -59,8 +59,10 @@ const props = withDefaults(defineProps<{
pagination: PagingCtx;
disableAutoLoad?: boolean;
displayLimit?: number;
pullToRefresh?: boolean;
}>(), {
displayLimit: 20,
pullToRefresh: true,
});
const paginator = usePagination({

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div ref="rootEl">
<div ref="rootEl" :class="isPulling ? $style.isPulling : null">
<div v-if="isPulling" :class="$style.frame" :style="`--frame-min-height: ${pullDistance / (PULL_BRAKE_BASE + (pullDistance / PULL_BRAKE_FACTOR))}px;`">
<div :class="$style.frameContent">
<MkLoading v-if="isRefreshing" :class="$style.loader" :em="true"/>
@ -216,6 +216,10 @@ onUnmounted(() => {
</script>
<style lang="scss" module>
.isPulling {
will-change: contents;
}
.frame {
position: relative;
overflow: clip;

View File

@ -4,15 +4,15 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div class="_spacer" style="--MI_SPACER-w: 1100px;">
<div :class="$style.root">
<MkPagination v-slot="{items}" :pagination="pagination">
<div :class="$style.stream">
<MkNoteMediaGrid v-for="note in items" :note="note" square/>
</div>
</MkPagination>
</div>
<div class="_spacer" style="--MI_SPACER-w: 1100px;">
<div :class="$style.root">
<MkPagination v-slot="{items}" :pagination="pagination">
<div :class="$style.stream">
<MkNoteMediaGrid v-for="note in items" :note="note" square/>
</div>
</MkPagination>
</div>
</div>
</template>
<script lang="ts" setup>

View File

@ -8,12 +8,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #header>
<MkTab v-model="tab" :class="$style.tab">
<option value="featured">{{ i18n.ts.featured }}</option>
<option :value="null">{{ i18n.ts.notes }}</option>
<option value="notes">{{ i18n.ts.notes }}</option>
<option value="all">{{ i18n.ts.all }}</option>
<option value="files">{{ i18n.ts.withFiles }}</option>
</MkTab>
</template>
<MkNotesTimeline :noGap="true" :pagination="pagination" :class="$style.tl"/>
<MkNotesTimeline :key="tab" :noGap="true" :pagination="pagination" :pullToRefresh="false" :class="$style.tl"/>
</MkStickyContainer>
</template>
@ -28,7 +28,7 @@ const props = defineProps<{
user: Misskey.entities.UserDetailed;
}>();
const tab = ref<string | null>('all');
const tab = ref<string>('all');
const pagination = computed(() => tab.value === 'featured' ? {
endpoint: 'users/featured-notes' as const,

View File

@ -7,9 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<PageWithHeader v-model:tab="tab" :tabs="headerTabs" :actions="headerActions" :swipable="true">
<div v-if="user">
<XHome v-if="tab === 'home'" :user="user" @unfoldFiles="() => { tab = 'files'; }"/>
<div v-else-if="tab === 'notes'" class="_spacer" style="--MI_SPACER-w: 800px;">
<XTimeline :user="user"/>
</div>
<XNotes v-else-if="tab === 'notes'" :user="user"/>
<XFiles v-else-if="tab === 'files'" :user="user"/>
<XActivity v-else-if="tab === 'activity'" :user="user"/>
<XAchievements v-else-if="tab === 'achievements'" :user="user"/>
@ -37,7 +35,7 @@ import { $i } from '@/i.js';
import { serverContext, assertServerContext } from '@/server-context.js';
const XHome = defineAsyncComponent(() => import('./home.vue'));
const XTimeline = defineAsyncComponent(() => import('./index.timeline.vue'));
const XNotes = defineAsyncComponent(() => import('./notes.vue'));
const XFiles = defineAsyncComponent(() => import('./files.vue'));
const XActivity = defineAsyncComponent(() => import('./activity.vue'));
const XAchievements = defineAsyncComponent(() => import('./achievements.vue'));

View File

@ -0,0 +1,67 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div class="_spacer" style="--MI_SPACER-w: 800px;">
<div :class="$style.root">
<MkStickyContainer>
<template #header>
<MkTab v-model="tab" :class="$style.tab">
<option value="featured">{{ i18n.ts.featured }}</option>
<option value="notes">{{ i18n.ts.notes }}</option>
<option value="all">{{ i18n.ts.all }}</option>
<option value="files">{{ i18n.ts.withFiles }}</option>
</MkTab>
</template>
<MkNotesTimeline :key="tab" :noGap="true" :pagination="pagination" :class="$style.tl"/>
</MkStickyContainer>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import * as Misskey from 'misskey-js';
import MkNotesTimeline from '@/components/MkNotesTimeline.vue';
import MkTab from '@/components/MkTab.vue';
import { i18n } from '@/i18n.js';
const props = defineProps<{
user: Misskey.entities.UserDetailed;
}>();
const tab = ref<string>('all');
const pagination = computed(() => tab.value === 'featured' ? {
endpoint: 'users/featured-notes' as const,
limit: 10,
params: {
userId: props.user.id,
},
} : {
endpoint: 'users/notes' as const,
limit: 10,
params: {
userId: props.user.id,
withRenotes: tab.value === 'all',
withReplies: tab.value === 'all',
withChannelNotes: tab.value === 'all',
withFiles: tab.value === 'files',
},
});
</script>
<style lang="scss" module>
.tab {
padding: calc(var(--MI-margin) / 2) 0;
background: var(--MI_THEME-bg);
}
.tl {
background: var(--MI_THEME-bg);
border-radius: var(--MI-radius);
overflow: clip;
}
</style>