Add events tab to user details page
This commit is contained in:
parent
9ac5053a0e
commit
753cef9413
|
@ -35,7 +35,7 @@ export const meta = {
|
||||||
message: 'Invalid Parameter',
|
message: 'Invalid Parameter',
|
||||||
code: 'INVALID_PARAM',
|
code: 'INVALID_PARAM',
|
||||||
id: 'e70903d3-0aa2-44d5-a955-4de5723c603d',
|
id: 'e70903d3-0aa2-44d5-a955-4de5723c603d',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export const paramDef = {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
description: 'The local host is represented with `null`.',
|
description: 'The local host is represented with `null`.',
|
||||||
},
|
},
|
||||||
users: { type: 'array', nullable: true, items: { type: 'object', format: 'misskey:id' } },
|
users: { type: 'array', nullable: true, items: { type: 'string', format: 'misskey:id' } },
|
||||||
sinceDate: { type: 'integer', nullable: true },
|
sinceDate: { type: 'integer', nullable: true },
|
||||||
untilDate: { type: 'integer', nullable: true },
|
untilDate: { type: 'integer', nullable: true },
|
||||||
filters: {
|
filters: {
|
||||||
|
@ -109,15 +109,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.sinceDate && ps.untilDate && ps.sinceDate > ps.untilDate) throw new ApiError(meta.errors.invalidParam);
|
if (ps.sinceDate && ps.untilDate && ps.sinceDate > ps.untilDate) throw new ApiError(meta.errors.invalidParam);
|
||||||
|
|
||||||
|
if (ps.sinceDate || ps.sortBy !== 'createdAt') {
|
||||||
const sinceDate = ps.sinceDate ? new Date(ps.sinceDate) : new Date();
|
const sinceDate = ps.sinceDate ? new Date(ps.sinceDate) : new Date();
|
||||||
query.andWhere('event.start > :sinceDate', { sinceDate: sinceDate })
|
query.andWhere('event.start > :sinceDate', { sinceDate: sinceDate })
|
||||||
.andWhere('(event.end IS NULL OR event.end > :sinceDate)', { sinceDate: sinceDate });
|
.andWhere('(event.end IS NULL OR event.end > :sinceDate)', { sinceDate: sinceDate });
|
||||||
|
}
|
||||||
|
|
||||||
if (ps.untilDate) {
|
if (ps.untilDate) {
|
||||||
query.andWhere('event.start < :untilDate', { untilDate: new Date(ps.untilDate) });
|
query.andWhere('event.start < :untilDate', { untilDate: new Date(ps.untilDate) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps.sortBy === 'createdAt') {
|
if (ps.sortBy === 'createdAt') {
|
||||||
query.orderBy('note.createdAt', 'ASC');
|
query.orderBy('note.createdAt', 'DESC');
|
||||||
} else {
|
} else {
|
||||||
query.orderBy('event.start', 'ASC');
|
query.orderBy('event.start', 'ASC');
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div>Start: {{ note.event!.start }}</div>
|
<div>Start: {{ note.event!.start }}</div>
|
||||||
<div v-if="!!note.event!.end">End: {{ note.event!.end }}</div>
|
<div v-if="!!note.event!.end">End: {{ note.event!.end }}</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="k in Object.keys(note.event!.metadata)">
|
<li v-for="k in Object.keys(note.event!.metadata)" :key="k">
|
||||||
{{ k }}: {{ note.event!.metadata[k] }}
|
{{ k }}: {{ note.event!.metadata[k] }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<template>
|
||||||
|
<MkSpacer :content-max="800" style="padding-top: 0">
|
||||||
|
<MkStickyContainer>
|
||||||
|
<template #header>
|
||||||
|
<MkTab v-model="include" :class="$style.tab">
|
||||||
|
<option :value="null">{{ i18n.ts.events || 'Events' }}</option>
|
||||||
|
<option value="upcoming">{{ i18n.ts.upcomingEvents || 'Upcoming' }}</option>
|
||||||
|
</MkTab>
|
||||||
|
</template>
|
||||||
|
<MkNotes :no-gap="true" :pagination="pagination" :class="$style.tl"/>
|
||||||
|
</MkStickyContainer>
|
||||||
|
</MkSpacer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import * as misskey from 'misskey-js';
|
||||||
|
import MkNotes from '@/components/MkNotes.vue';
|
||||||
|
import MkTab from '@/components/MkTab.vue';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
user: misskey.entities.UserDetailed;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const include = ref<string | null>(null);
|
||||||
|
|
||||||
|
const pagination = {
|
||||||
|
endpoint: 'notes/events/search' as const,
|
||||||
|
limit: 10,
|
||||||
|
params: computed(() => ({
|
||||||
|
users: [props.user.id],
|
||||||
|
sortBy: include.value === 'upcoming' ? 'startDate' : 'createdAt',
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.tab {
|
||||||
|
margin: calc(var(--margin) / 2) 0;
|
||||||
|
padding: calc(var(--margin) / 2) 0;
|
||||||
|
background: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tl {
|
||||||
|
background: var(--bg);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
overflow: clip;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -5,7 +5,8 @@
|
||||||
<Transition name="fade" mode="out-in">
|
<Transition name="fade" mode="out-in">
|
||||||
<div v-if="user">
|
<div v-if="user">
|
||||||
<XHome v-if="tab === 'home'" :user="user"/>
|
<XHome v-if="tab === 'home'" :user="user"/>
|
||||||
<XTimeline v-else-if="tab === 'notes'" :user="user" />
|
<XTimeline v-else-if="tab === 'notes'" :user="user"/>
|
||||||
|
<XEvent v-else-if="tab === 'events'" :user="user"/>
|
||||||
<XActivity v-else-if="tab === 'activity'" :user="user"/>
|
<XActivity v-else-if="tab === 'activity'" :user="user"/>
|
||||||
<XAchievements v-else-if="tab === 'achievements'" :user="user"/>
|
<XAchievements v-else-if="tab === 'achievements'" :user="user"/>
|
||||||
<XReactions v-else-if="tab === 'reactions'" :user="user"/>
|
<XReactions v-else-if="tab === 'reactions'" :user="user"/>
|
||||||
|
@ -32,6 +33,7 @@ import { $i } from '@/account';
|
||||||
|
|
||||||
const XHome = defineAsyncComponent(() => import('./home.vue'));
|
const XHome = defineAsyncComponent(() => import('./home.vue'));
|
||||||
const XTimeline = defineAsyncComponent(() => import('./index.timeline.vue'));
|
const XTimeline = defineAsyncComponent(() => import('./index.timeline.vue'));
|
||||||
|
const XEvent = defineAsyncComponent(() => import('./events.vue'));
|
||||||
const XActivity = defineAsyncComponent(() => import('./activity.vue'));
|
const XActivity = defineAsyncComponent(() => import('./activity.vue'));
|
||||||
const XAchievements = defineAsyncComponent(() => import('./achievements.vue'));
|
const XAchievements = defineAsyncComponent(() => import('./achievements.vue'));
|
||||||
const XReactions = defineAsyncComponent(() => import('./reactions.vue'));
|
const XReactions = defineAsyncComponent(() => import('./reactions.vue'));
|
||||||
|
@ -74,6 +76,10 @@ const headerTabs = $computed(() => user ? [{
|
||||||
key: 'notes',
|
key: 'notes',
|
||||||
title: i18n.ts.notes,
|
title: i18n.ts.notes,
|
||||||
icon: 'ti ti-pencil',
|
icon: 'ti ti-pencil',
|
||||||
|
}, {
|
||||||
|
key: 'events',
|
||||||
|
title: 'Events', //i18n.ts.events,
|
||||||
|
icon: 'ti ti-calendar',
|
||||||
}, {
|
}, {
|
||||||
key: 'activity',
|
key: 'activity',
|
||||||
title: i18n.ts.activity,
|
title: i18n.ts.activity,
|
||||||
|
|
Loading…
Reference in New Issue