This commit is contained in:
syuilo 2020-11-29 12:34:39 +09:00
parent 9bf5dc67f5
commit 17d62b689d
6 changed files with 215 additions and 4 deletions

View file

@ -0,0 +1,57 @@
<template>
<div>
<MkPagination :pagination="pagination" #default="{items}" ref="list">
<MkA v-for="item in items" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _vMargin">
<b>{{ item.name }}</b>
<div v-if="item.description" class="description">{{ item.description }}</div>
</MkA>
</MkPagination>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import MkPagination from '@/components/ui/pagination.vue';
import { userPage, acct } from '../../filters/user';
export default defineComponent({
components: {
MkPagination,
},
props: {
user: {
type: Object,
required: true
},
},
data() {
return {
pagination: {
endpoint: 'users/clips',
limit: 20,
params: {
userId: this.user.id,
}
},
};
},
watch: {
user() {
this.$refs.list.reload();
}
},
methods: {
userPage,
acct
}
});
</script>
<style lang="scss" scoped>
</style>

View file

@ -60,12 +60,15 @@
<div class="main"> <div class="main">
<div class="nav _vMargin"> <div class="nav _vMargin">
<MkA :to="userPage(user)" :class="{ active: page === 'index' }" class="link"> <MkA :to="userPage(user)" :class="{ active: page === 'index' }" class="link">
<Fa :icon="faCommentAlt" class="icon"/>
<span>{{ $t('notes') }}</span> <span>{{ $t('notes') }}</span>
</MkA> </MkA>
<MkA :to="userPage(user, 'clips')" :class="{ active: page === 'clips' }" class="link"> <MkA :to="userPage(user, 'clips')" :class="{ active: page === 'clips' }" class="link">
<Fa :icon="faPaperclip" class="icon"/>
<span>{{ $t('clips') }}</span> <span>{{ $t('clips') }}</span>
</MkA> </MkA>
<MkA :to="userPage(user, 'pages')" :class="{ active: page === 'pages' }" class="link"> <MkA :to="userPage(user, 'pages')" :class="{ active: page === 'pages' }" class="link">
<Fa :icon="faFileAlt" class="icon"/>
<span>{{ $t('pages') }}</span> <span>{{ $t('pages') }}</span>
</MkA> </MkA>
<div class="actions"> <div class="actions">
@ -83,6 +86,8 @@
</template> </template>
<XFollowList v-else-if="page === 'following'" type="following" :user="user" class="_vMargin"/> <XFollowList v-else-if="page === 'following'" type="following" :user="user" class="_vMargin"/>
<XFollowList v-else-if="page === 'followers'" type="followers" :user="user" class="_vMargin"/> <XFollowList v-else-if="page === 'followers'" type="followers" :user="user" class="_vMargin"/>
<XClips v-else-if="page === 'clips'" :user="user" class="_vMargin"/>
<XPages v-else-if="page === 'pages'" :user="user" class="_vMargin"/>
</div> </div>
</div> </div>
</div> </div>
@ -193,8 +198,8 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, defineAsyncComponent, computed } from 'vue'; import { defineComponent, defineAsyncComponent, computed } from 'vue';
import { faExclamationTriangle, faEllipsisH, faRobot, faLock, faBookmark, faChartBar, faImage, faBirthdayCake, faMapMarker } from '@fortawesome/free-solid-svg-icons'; import { faExclamationTriangle, faEllipsisH, faRobot, faLock, faBookmark, faChartBar, faImage, faBirthdayCake, faMapMarker, faPaperclip, faFileAlt } from '@fortawesome/free-solid-svg-icons';
import { faCalendarAlt, faBookmark as farBookmark } from '@fortawesome/free-regular-svg-icons'; import { faCalendarAlt, faBookmark as farBookmark, faCommentAlt } from '@fortawesome/free-regular-svg-icons';
import * as age from 's-age'; import * as age from 's-age';
import XUserTimeline from './index.timeline.vue'; import XUserTimeline from './index.timeline.vue';
import XNote from '@/components/note.vue'; import XNote from '@/components/note.vue';
@ -221,6 +226,8 @@ export default defineComponent({
MkFolder, MkFolder,
MkTab, MkTab,
XFollowList: defineAsyncComponent(() => import('./follow-list.vue')), XFollowList: defineAsyncComponent(() => import('./follow-list.vue')),
XClips: defineAsyncComponent(() => import('./clips.vue')),
XPages: defineAsyncComponent(() => import('./pages.vue')),
XPhotos: defineAsyncComponent(() => import('./index.photos.vue')), XPhotos: defineAsyncComponent(() => import('./index.photos.vue')),
XActivity: defineAsyncComponent(() => import('./index.activity.vue')), XActivity: defineAsyncComponent(() => import('./index.activity.vue')),
}, },
@ -251,7 +258,7 @@ export default defineComponent({
error: null, error: null,
parallaxAnimationId: null, parallaxAnimationId: null,
narrow: null, narrow: null,
faExclamationTriangle, faEllipsisH, faRobot, faLock, faBookmark, farBookmark, faChartBar, faImage, faBirthdayCake, faMapMarker, faCalendarAlt faExclamationTriangle, faEllipsisH, faRobot, faLock, faBookmark, farBookmark, faChartBar, faImage, faBirthdayCake, faMapMarker, faCalendarAlt, faCommentAlt, faPaperclip, faFileAlt,
}; };
}, },
@ -471,7 +478,8 @@ export default defineComponent({
display: flex; display: flex;
align-items: center; align-items: center;
margin-top: var(--margin); margin-top: var(--margin);
font-size: 120%; //font-size: 120%;
font-weight: bold;
> .link { > .link {
display: inline-block; display: inline-block;
@ -479,6 +487,10 @@ export default defineComponent({
text-align: center; text-align: center;
border-bottom: solid 3px transparent; border-bottom: solid 3px transparent;
&:hover {
text-decoration: none;
}
&.active { &.active {
color: var(--accent); color: var(--accent);
border-bottom-color: var(--accent); border-bottom-color: var(--accent);

View file

@ -0,0 +1,56 @@
<template>
<div>
<MkPagination :pagination="pagination" #default="{items}" ref="list">
<MkPagePreview v-for="page in items" :page="page" :key="page.id" class="_vMargin"/>
</MkPagination>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import MkPagePreview from '@/components/page-preview.vue';
import MkPagination from '@/components/ui/pagination.vue';
import { userPage, acct } from '../../filters/user';
export default defineComponent({
components: {
MkPagination,
MkPagePreview,
},
props: {
user: {
type: Object,
required: true
},
},
data() {
return {
pagination: {
endpoint: 'users/pages',
limit: 20,
params: {
userId: this.user.id,
}
},
};
},
watch: {
user() {
this.$refs.list.reload();
}
},
methods: {
userPage,
acct
}
});
</script>
<style lang="scss" scoped>
</style>

View file

@ -24,6 +24,12 @@ export class ClipRepository extends Repository<Clip> {
isPublic: clip.isPublic, isPublic: clip.isPublic,
}); });
} }
public packMany(
clips: Clip[],
) {
return Promise.all(clips.map(x => this.pack(x)));
}
} }
export const packedClipSchema = { export const packedClipSchema = {

View file

@ -0,0 +1,40 @@
import $ from 'cafy';
import { ID } from '../../../../misc/cafy-id';
import define from '../../define';
import { Clips } from '../../../../models';
import { makePaginationQuery } from '../../common/make-pagination-query';
export const meta = {
tags: ['users', 'clips'],
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
}
};
export default define(meta, async (ps, user) => {
const query = makePaginationQuery(Clips.createQueryBuilder('clip'), ps.sinceId, ps.untilId)
.andWhere(`clip.userId = :userId`, { userId: ps.userId })
.andWhere('clip.isPublic = true');
const clips = await query
.take(ps.limit!)
.getMany();
return await Clips.packMany(clips);
});

View file

@ -0,0 +1,40 @@
import $ from 'cafy';
import { ID } from '../../../../misc/cafy-id';
import define from '../../define';
import { Pages } from '../../../../models';
import { makePaginationQuery } from '../../common/make-pagination-query';
export const meta = {
tags: ['users', 'pages'],
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
}
};
export default define(meta, async (ps, user) => {
const query = makePaginationQuery(Pages.createQueryBuilder('page'), ps.sinceId, ps.untilId)
.andWhere(`page.userId = :userId`, { userId: ps.userId })
.andWhere('page.visibility = \'public\'');
const pages = await query
.take(ps.limit!)
.getMany();
return await Pages.packMany(pages);
});