parent
756e4eaeec
commit
8e6da3a0d9
|
@ -338,6 +338,7 @@ auth/views/index.vue:
|
|||
sign-in: "サインインしてください"
|
||||
|
||||
common/views/pages/explore.vue:
|
||||
pinned-users: "ピン留めされたユーザー"
|
||||
popular-users: "人気のユーザー"
|
||||
recently-updated-users: "最近投稿したユーザー"
|
||||
recently-registered-users: "新規ユーザー"
|
||||
|
@ -1262,7 +1263,7 @@ admin/views/instance.vue:
|
|||
invite: "招待"
|
||||
save: "保存"
|
||||
saved: "保存しました"
|
||||
user-recommendation-config: "おすすめユーザー"
|
||||
pinned-users: "ピン留めユーザー"
|
||||
email-config: "メールサーバーの設定"
|
||||
email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。"
|
||||
enable-email: "メール配信を有効にする"
|
||||
|
|
13
migration/1557476068003-PinnedUsers.ts
Normal file
13
migration/1557476068003-PinnedUsers.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class PinnedUsers1557476068003 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedUsers" character varying(256) array NOT NULL DEFAULT '{}'::varchar[]`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedUsers"`);
|
||||
}
|
||||
|
||||
}
|
|
@ -82,6 +82,14 @@
|
|||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title>{{ $t('pinned-users') }}</template>
|
||||
<section>
|
||||
<ui-textarea v-model="pinnedUsers"></ui-textarea>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title>{{ $t('invite') }}</template>
|
||||
<section>
|
||||
|
@ -190,6 +198,7 @@ export default Vue.extend({
|
|||
enableServiceWorker: false,
|
||||
swPublicKey: null,
|
||||
swPrivateKey: null,
|
||||
pinnedUsers: [],
|
||||
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt
|
||||
};
|
||||
},
|
||||
|
@ -239,6 +248,7 @@ export default Vue.extend({
|
|||
this.enableServiceWorker = meta.enableServiceWorker;
|
||||
this.swPublicKey = meta.swPublickey;
|
||||
this.swPrivateKey = meta.swPrivateKey;
|
||||
this.pinnedUsers = meta.pinnedUsers.join('\n');
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -297,7 +307,8 @@ export default Vue.extend({
|
|||
smtpPass: this.smtpAuth ? this.smtpPass : '',
|
||||
enableServiceWorker: this.enableServiceWorker,
|
||||
swPublicKey: this.swPublicKey,
|
||||
swPrivateKey: this.swPrivateKey
|
||||
swPrivateKey: this.swPrivateKey,
|
||||
pinnedUsers: this.pinnedUsers.split('\n')
|
||||
}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
</mk-user-list>
|
||||
|
||||
<template v-if="tag == null">
|
||||
<mk-user-list :make-promise="pinnedUsers">
|
||||
<fa :icon="faBookmark" fixed-width/>{{ $t('pinned-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :make-promise="popularUsers">
|
||||
<fa :icon="faChartLine" fixed-width/>{{ $t('popular-users') }}
|
||||
</mk-user-list>
|
||||
|
@ -57,6 +60,7 @@ export default Vue.extend({
|
|||
|
||||
data() {
|
||||
return {
|
||||
pinnedUsers: () => this.$root.api('pinned-users'),
|
||||
popularUsers: () => this.$root.api('users', {
|
||||
state: 'alive',
|
||||
origin: 'local',
|
||||
|
|
|
@ -69,6 +69,11 @@ export class Meta {
|
|||
})
|
||||
public langs: string[];
|
||||
|
||||
@Column('varchar', {
|
||||
length: 256, array: true, default: '{}'
|
||||
})
|
||||
public pinnedUsers: string[];
|
||||
|
||||
@Column('varchar', {
|
||||
length: 256, array: true, default: '{}'
|
||||
})
|
||||
|
|
|
@ -56,6 +56,13 @@ export const meta = {
|
|||
}
|
||||
},
|
||||
|
||||
pinnedUsers: {
|
||||
validator: $.optional.nullable.arr($.str),
|
||||
desc: {
|
||||
'ja-JP': 'ピン留めユーザー'
|
||||
}
|
||||
},
|
||||
|
||||
hiddenTags: {
|
||||
validator: $.optional.nullable.arr($.str),
|
||||
desc: {
|
||||
|
@ -353,6 +360,10 @@ export default define(meta, async (ps) => {
|
|||
set.useStarForReactionFallback = ps.useStarForReactionFallback;
|
||||
}
|
||||
|
||||
if (Array.isArray(ps.pinnedUsers)) {
|
||||
set.pinnedUsers = ps.pinnedUsers;
|
||||
}
|
||||
|
||||
if (Array.isArray(ps.hiddenTags)) {
|
||||
set.hiddenTags = ps.hiddenTags;
|
||||
}
|
||||
|
|
|
@ -160,6 +160,7 @@ export default define(meta, async (ps, me) => {
|
|||
|
||||
if (me && (me.isAdmin || me.isModerator)) {
|
||||
response.useStarForReactionFallback = instance.useStarForReactionFallback;
|
||||
response.pinnedUsers = instance.pinnedUsers;
|
||||
response.hiddenTags = instance.hiddenTags;
|
||||
response.recaptchaSecretKey = instance.recaptchaSecretKey;
|
||||
response.proxyAccount = instance.proxyAccount;
|
||||
|
|
33
src/server/api/endpoints/pinned-users.ts
Normal file
33
src/server/api/endpoints/pinned-users.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import define from '../define';
|
||||
import { Users } from '../../../models';
|
||||
import { types, bool } from '../../../misc/schema';
|
||||
import { fetchMeta } from '../../../misc/fetch-meta';
|
||||
import parseAcct from '../../../misc/acct/parse';
|
||||
import { User } from '../../../models/entities/user';
|
||||
|
||||
export const meta = {
|
||||
tags: ['users'],
|
||||
|
||||
requireCredential: false,
|
||||
|
||||
params: {
|
||||
},
|
||||
|
||||
res: {
|
||||
type: types.array,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
items: {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
ref: 'User',
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
const meta = await fetchMeta();
|
||||
|
||||
const users = await Promise.all(meta.pinnedUsers.map(acct => Users.findOne(parseAcct(acct))));
|
||||
|
||||
return await Users.packMany(users.filter(x => x !== undefined) as User[], me, { detail: true });
|
||||
});
|
Loading…
Reference in a new issue