diff options
| author | mei23 <m@m544.net> | 2018-10-31 04:59:01 +0900 |
|---|---|---|
| committer | mei23 <m@m544.net> | 2018-10-31 04:59:01 +0900 |
| commit | 560bb6538413a1e969a1177a739b18bfa91391e3 (patch) | |
| tree | 49b9612d3810f56aa9813c9567f41c67a96cfa13 /src | |
| parent | Implement /api/v1/instance (#3045) (diff) | |
| download | misskey-560bb6538413a1e969a1177a739b18bfa91391e3.tar.gz misskey-560bb6538413a1e969a1177a739b18bfa91391e3.tar.bz2 misskey-560bb6538413a1e969a1177a739b18bfa91391e3.zip | |
blockings list
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/app/desktop/views/components/settings.blocking.vue | 31 | ||||
| -rw-r--r-- | src/client/app/desktop/views/components/settings.vue | 10 | ||||
| -rw-r--r-- | src/server/api/endpoints/blocking/list.ts | 59 |
3 files changed, 100 insertions, 0 deletions
diff --git a/src/client/app/desktop/views/components/settings.blocking.vue b/src/client/app/desktop/views/components/settings.blocking.vue new file mode 100644 index 0000000000..43e4bf9209 --- /dev/null +++ b/src/client/app/desktop/views/components/settings.blocking.vue @@ -0,0 +1,31 @@ +<template> +<div> + <div class="none ui info" v-if="!fetching && users.length == 0"> + <p>%fa:info-circle%%i18n:@no-users%</p> + </div> + <div class="users" v-if="users.length != 0"> + <div v-for="user in users" :key="user.id"> + <p><b>{{ user | userName }}</b> @{{ user | acct }}</p> + </div> + </div> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; + +export default Vue.extend({ + data() { + return { + fetching: true, + users: [] + }; + }, + mounted() { + (this as any).api('blocking/list').then(x => { + this.users = x.users; + this.fetching = false; + }); + } +}); +</script> diff --git a/src/client/app/desktop/views/components/settings.vue b/src/client/app/desktop/views/components/settings.vue index b5c02e486e..e77320bef3 100644 --- a/src/client/app/desktop/views/components/settings.vue +++ b/src/client/app/desktop/views/components/settings.vue @@ -8,6 +8,7 @@ <p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'">%fa:cloud .fw%%i18n:common.drive%</p> <p :class="{ active: page == 'hashtags' }" @mousedown="page = 'hashtags'">%fa:hashtag .fw%%i18n:@tags%</p> <p :class="{ active: page == 'mute' }" @mousedown="page = 'mute'">%fa:ban .fw%%i18n:@mute%</p> + <p :class="{ active: page == 'blocking' }" @mousedown="page = 'blocking'">%fa:ban .fw%%i18n:@blocking%</p> <p :class="{ active: page == 'apps' }" @mousedown="page = 'apps'">%fa:puzzle-piece .fw%%i18n:@apps%</p> <p :class="{ active: page == 'security' }" @mousedown="page = 'security'">%fa:unlock-alt .fw%%i18n:@security%</p> <p :class="{ active: page == 'api' }" @mousedown="page = 'api'">%fa:key .fw%API</p> @@ -207,6 +208,13 @@ </section> </ui-card> + <ui-card class="blocking" v-show="page == 'blocking'"> + <div slot="title">%fa:ban% %i18n:@blocking%</div> + <section> + <x-blocking/> + </section> + </ui-card> + <ui-card class="apps" v-show="page == 'apps'"> <div slot="title">%fa:puzzle-piece% %i18n:@apps%</div> <section> @@ -290,6 +298,7 @@ <script lang="ts"> import Vue from 'vue'; import XMute from './settings.mute.vue'; +import XBlocking from './settings.blocking.vue'; import XPassword from './settings.password.vue'; import X2fa from './settings.2fa.vue'; import XApps from './settings.apps.vue'; @@ -301,6 +310,7 @@ import checkForUpdate from '../../../common/scripts/check-for-update'; export default Vue.extend({ components: { XMute, + XBlocking, XPassword, X2fa, XApps, diff --git a/src/server/api/endpoints/blocking/list.ts b/src/server/api/endpoints/blocking/list.ts new file mode 100644 index 0000000000..ba1c77d2c7 --- /dev/null +++ b/src/server/api/endpoints/blocking/list.ts @@ -0,0 +1,59 @@ +import $ from 'cafy'; import ID from '../../../../misc/cafy-id'; +import Blocking from '../../../../models/blocking'; +import { pack, ILocalUser } from '../../../../models/user'; + +export const meta = { + desc: { + 'ja-JP': 'ブロックしているユーザー一覧を取得します。', + 'en-US': 'Get blocking users.' + }, + + requireCredential: true, + + kind: 'following-read' +}; + +export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { + // Get 'limit' parameter + const [limit = 30, limitErr] = $.num.optional.range(1, 100).get(params.limit); + if (limitErr) return rej('invalid limit param'); + + // Get 'cursor' parameter + const [cursor = null, cursorErr] = $.type(ID).optional.get(params.cursor); + if (cursorErr) return rej('invalid cursor param'); + + // Construct query + const query = { + blockerId: me._id + } as any; + + // カーソルが指定されている場合 + if (cursor) { + query._id = { + $lt: cursor + }; + } + + // Get blockings + const blockings = await Blocking + .find(query, { + limit: limit + 1, + sort: { _id: -1 } + }); + + // 「次のページ」があるかどうか + const inStock = blockings.length === limit + 1; + if (inStock) { + blockings.pop(); + } + + // Serialize + const users = await Promise.all(blockings.map(async m => + await pack(m.blockeeId, me, { detail: true }))); + + // Response + res({ + users: users, + next: inStock ? blockings[blockings.length - 1]._id : null, + }); +}); |