summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/SkUserRecentNotes.vue
blob: b66a33f644ee9b995beb341cd8cef55d0a5ee0ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<!--
SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
SPDX-License-Identifier: AGPL-3.0-only
-->

<template>
<MkPullToRefresh :refresher="() => reload()">
	<div v-if="user" :class="$style.userInfo">
		<MkUserInfo :class="$style.userInfo" class="user" :user="user"/>
		<MkNotes :noGap="true" :pagination="pagination"/>
	</div>
	<div v-else-if="loadError" :class="$style.panel">{{ loadError }}</div>
	<MkLoading v-else-if="userId"/>
</MkPullToRefresh>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import * as Misskey from 'misskey-js';
import type { Ref } from 'vue';
import type { Paging } from '@/components/MkPagination.vue';
import MkLoading from '@/components/global/MkLoading.vue';
import MkNotes from '@/components/MkNotes.vue';
import MkUserInfo from '@/components/MkUserInfo.vue';
import MkPullToRefresh from '@/components/MkPullToRefresh.vue';
import { misskeyApi } from '@/utility/misskey-api.js';

const props = defineProps<{
	userId: string;
	withNonPublic: boolean;
	withQuotes: boolean;
	withReplies: boolean;
	withBots: boolean;
	onlyFiles: boolean;
}>();

const loadError: Ref<string | null> = ref(null);
const user: Ref<Misskey.entities.UserDetailed | null> = ref(null);

const pagination: Paging<'users/notes'> = {
	endpoint: 'users/notes' as const,
	limit: 10,
	params: computed(() => ({
		userId: props.userId,
		withNonPublic: props.withNonPublic,
		withRenotes: false,
		withQuotes: props.withQuotes,
		withReplies: props.withReplies,
		withRepliesToSelf: props.withReplies,
		withFiles: props.onlyFiles,
		allowPartial: true,
	})),
};

defineExpose({
	reload,
	user,
});

async function reload(): Promise<void> {
	loadError.value = null;
	user.value = null;

	await Promise
		.all([
			// We need a User entity, but the pagination returns only UserLite.
			// An additional request is needed to "upgrade" the object.
			misskeyApi('users/show', { userId: props.userId }),

			// Wait for 1 second to match the animation effects in MkSwiper, MkPullToRefresh, and MkPagination.
			// Otherwise, the page appears to load "backwards".
			new Promise(resolve => window.setTimeout(resolve, 1000)),
		])
		.then(([u]) => user.value = u)
		.catch(error => {
			console.error('Error fetching user info', error);

			loadError.value =
				typeof(error) === 'string'
					? String(error)
					: JSON.stringify(error);
		});
}

watch(() => props.userId, async () => {
	await reload();
});

onMounted(async () => {
	await reload();
});

</script>

<style lang="scss" module>

.panel {
	background: var(--MI_THEME-panel);
}

.userInfo {
	margin-bottom: 12px;
}

@container (min-width: 750px) {
	.userInfo {
		margin-bottom: 24px;
	}
}

</style>