parent
d2204fd5c8
commit
d1807ee5dc
|
@ -73,8 +73,9 @@ You should also include the user name that made the change.
|
|||
- Push notification of Antenna note @tamaina
|
||||
- AVIF support @tamaina
|
||||
- Add Cloudflare Turnstile CAPTCHA support @CyberRex0
|
||||
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはインスタンスの招待コードを発行できるように
|
||||
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはカスタム絵文字の追加、編集、削除を行えるように
|
||||
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはインスタンスの招待コードを発行できるように @syuilo
|
||||
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはカスタム絵文字の追加、編集、削除を行えるように @syuilo
|
||||
- ハードワードミュートの最大文字数を設定可能に @syuilo
|
||||
- Server: signToActivityPubGet is set to true by default @syuilo
|
||||
- Server: improve syslog performance @syuilo
|
||||
- Server: Use undici instead of node-fetch and got @tamaina
|
||||
|
|
|
@ -962,6 +962,7 @@ _role:
|
|||
canManageCustomEmojis: "カスタム絵文字の管理"
|
||||
driveCapacity: "ドライブ容量"
|
||||
antennaMax: "アンテナの作成可能数"
|
||||
wordMuteMax: "ワードミュートの最大文字数"
|
||||
_condition:
|
||||
isLocal: "ローカルユーザー"
|
||||
isRemote: "リモートユーザー"
|
||||
|
|
|
@ -20,6 +20,7 @@ export type RoleOptions = {
|
|||
canManageCustomEmojis: boolean;
|
||||
driveCapacityMb: number;
|
||||
antennaLimit: number;
|
||||
wordMuteLimit: number;
|
||||
};
|
||||
|
||||
export const DEFAULT_ROLE: RoleOptions = {
|
||||
|
@ -30,6 +31,7 @@ export const DEFAULT_ROLE: RoleOptions = {
|
|||
canManageCustomEmojis: false,
|
||||
driveCapacityMb: 100,
|
||||
antennaLimit: 5,
|
||||
wordMuteLimit: 200,
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
|
@ -187,6 +189,7 @@ export class RoleService implements OnApplicationShutdown {
|
|||
canManageCustomEmojis: getOptionValues('canManageCustomEmojis').some(x => x === true),
|
||||
driveCapacityMb: Math.max(...getOptionValues('driveCapacityMb')),
|
||||
antennaLimit: Math.max(...getOptionValues('antennaLimit')),
|
||||
wordMuteLimit: Math.max(...getOptionValues('wordMuteLimit')),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import { UserFollowingService } from '@/core/UserFollowingService.js';
|
|||
import { AccountUpdateService } from '@/core/AccountUpdateService.js';
|
||||
import { HashtagService } from '@/core/HashtagService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
export const meta = {
|
||||
|
@ -62,6 +63,12 @@ export const meta = {
|
|||
code: 'INVALID_REGEXP',
|
||||
id: '0d786918-10df-41cd-8f33-8dec7d9a89a5',
|
||||
},
|
||||
|
||||
tooManyMutedWords: {
|
||||
message: 'Too many muted words.',
|
||||
code: 'TOO_MANY_MUTED_WORDS',
|
||||
id: '010665b1-a211-42d2-bc64-8f6609d79785',
|
||||
},
|
||||
},
|
||||
|
||||
res: {
|
||||
|
@ -144,6 +151,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
private userFollowingService: UserFollowingService,
|
||||
private accountUpdateService: AccountUpdateService,
|
||||
private hashtagService: HashtagService,
|
||||
private roleService: RoleService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, _user, token) => {
|
||||
const user = await this.usersRepository.findOneByOrFail({ id: _user.id });
|
||||
|
@ -163,6 +171,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||
if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
|
||||
if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
|
||||
if (ps.mutedWords !== undefined) {
|
||||
// TODO: ちゃんと数える
|
||||
const length = JSON.stringify(ps.mutedWords).length;
|
||||
if (length > (await this.roleService.getUserRoleOptions(user.id)).antennaLimit) {
|
||||
throw new ApiError(meta.errors.tooManyMutedWords);
|
||||
}
|
||||
|
||||
// validate regular expression syntax
|
||||
ps.mutedWords.filter(x => !Array.isArray(x)).forEach(x => {
|
||||
const regexp = x.match(/^\/(.+)\/(.*)$/);
|
||||
|
|
|
@ -127,6 +127,19 @@
|
|||
</MkInput>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder>
|
||||
<template #label>{{ i18n.ts._role._options.wordMuteMax }}</template>
|
||||
<template #suffix>{{ options_wordMuteLimit_useDefault ? i18n.ts._role.useBaseValue : (options_wordMuteLimit_value) }}</template>
|
||||
<div class="_gaps">
|
||||
<MkSwitch v-model="options_wordMuteLimit_useDefault" :readonly="readonly">
|
||||
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||
</MkSwitch>
|
||||
<MkInput v-model="options_wordMuteLimit_value" :disabled="options_wordMuteLimit_useDefault" type="number" :readonly="readonly">
|
||||
<template #suffix>chars</template>
|
||||
</MkInput>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</div>
|
||||
</FormSlot>
|
||||
|
||||
|
@ -194,6 +207,8 @@ let options_driveCapacityMb_useDefault = $ref(role?.options?.driveCapacityMb?.us
|
|||
let options_driveCapacityMb_value = $ref(role?.options?.driveCapacityMb?.value ?? 0);
|
||||
let options_antennaLimit_useDefault = $ref(role?.options?.antennaLimit?.useDefault ?? true);
|
||||
let options_antennaLimit_value = $ref(role?.options?.antennaLimit?.value ?? 0);
|
||||
let options_wordMuteLimit_useDefault = $ref(role?.options?.wordMuteLimit?.useDefault ?? true);
|
||||
let options_wordMuteLimit_value = $ref(role?.options?.wordMuteLimit?.value ?? 0);
|
||||
|
||||
if (_DEV_) {
|
||||
watch($$(condFormula), () => {
|
||||
|
@ -210,6 +225,7 @@ function getOptions() {
|
|||
canManageCustomEmojis: { useDefault: options_canManageCustomEmojis_useDefault, value: options_canManageCustomEmojis_value },
|
||||
driveCapacityMb: { useDefault: options_driveCapacityMb_useDefault, value: options_driveCapacityMb_value },
|
||||
antennaLimit: { useDefault: options_antennaLimit_useDefault, value: options_antennaLimit_value },
|
||||
wordMuteLimit: { useDefault: options_wordMuteLimit_useDefault, value: options_wordMuteLimit_value },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,15 @@
|
|||
<MkInput v-model="options_antennaLimit" type="number">
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder>
|
||||
<template #label>{{ i18n.ts._role._options.wordMuteMax }}</template>
|
||||
<template #suffix>{{ options_wordMuteLimit }}</template>
|
||||
<MkInput v-model="options_wordMuteLimit" type="number">
|
||||
<template #suffix>chars</template>
|
||||
</MkInput>
|
||||
</MkFolder>
|
||||
|
||||
<MkButton primary rounded @click="updateBaseRole">{{ i18n.ts.save }}</MkButton>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
@ -101,6 +110,7 @@ let options_canInvite = $ref(instance.baseRole.canInvite);
|
|||
let options_canManageCustomEmojis = $ref(instance.baseRole.canManageCustomEmojis);
|
||||
let options_driveCapacityMb = $ref(instance.baseRole.driveCapacityMb);
|
||||
let options_antennaLimit = $ref(instance.baseRole.antennaLimit);
|
||||
let options_wordMuteLimit = $ref(instance.baseRole.wordMuteLimit);
|
||||
|
||||
async function updateBaseRole() {
|
||||
await os.apiWithDialog('admin/roles/update-default-role-override', {
|
||||
|
@ -112,6 +122,7 @@ async function updateBaseRole() {
|
|||
canManageCustomEmojis: options_canManageCustomEmojis,
|
||||
driveCapacityMb: options_driveCapacityMb,
|
||||
antennaLimit: options_antennaLimit,
|
||||
wordMuteLimit: options_wordMuteLimit,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue