mirror of
https://github.com/hotomoe/hotomoe
synced 2024-11-24 23:26:17 +09:00
parent
0a6e237d09
commit
b250456814
@ -73,6 +73,7 @@ You should also include the user name that made the change.
|
|||||||
- AVIF support @tamaina
|
- AVIF support @tamaina
|
||||||
- Add Cloudflare Turnstile CAPTCHA support @CyberRex0
|
- Add Cloudflare Turnstile CAPTCHA support @CyberRex0
|
||||||
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはインスタンスの招待コードを発行できるように
|
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはインスタンスの招待コードを発行できるように
|
||||||
|
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはカスタム絵文字の追加、編集、削除を行えるように
|
||||||
- Server: signToActivityPubGet is set to true by default @syuilo
|
- Server: signToActivityPubGet is set to true by default @syuilo
|
||||||
- Server: improve syslog performance @syuilo
|
- Server: improve syslog performance @syuilo
|
||||||
- Server: Use undici instead of node-fetch and got @tamaina
|
- Server: Use undici instead of node-fetch and got @tamaina
|
||||||
|
@ -931,6 +931,7 @@ undefined: "未定義"
|
|||||||
assign: "アサイン"
|
assign: "アサイン"
|
||||||
unassign: "アサインを解除"
|
unassign: "アサインを解除"
|
||||||
color: "色"
|
color: "色"
|
||||||
|
manageCustomEmojis: "カスタム絵文字の管理"
|
||||||
|
|
||||||
_role:
|
_role:
|
||||||
new: "ロールの作成"
|
new: "ロールの作成"
|
||||||
@ -958,6 +959,7 @@ _role:
|
|||||||
ltlAvailable: "ローカルタイムラインの閲覧"
|
ltlAvailable: "ローカルタイムラインの閲覧"
|
||||||
canPublicNote: "パブリック投稿の許可"
|
canPublicNote: "パブリック投稿の許可"
|
||||||
canInvite: "インスタンス招待コードの発行"
|
canInvite: "インスタンス招待コードの発行"
|
||||||
|
canManageCustomEmojis: "カスタム絵文字の管理"
|
||||||
driveCapacity: "ドライブ容量"
|
driveCapacity: "ドライブ容量"
|
||||||
antennaMax: "アンテナの作成可能数"
|
antennaMax: "アンテナの作成可能数"
|
||||||
_condition:
|
_condition:
|
||||||
|
@ -17,6 +17,7 @@ export type RoleOptions = {
|
|||||||
ltlAvailable: boolean;
|
ltlAvailable: boolean;
|
||||||
canPublicNote: boolean;
|
canPublicNote: boolean;
|
||||||
canInvite: boolean;
|
canInvite: boolean;
|
||||||
|
canManageCustomEmojis: boolean;
|
||||||
driveCapacityMb: number;
|
driveCapacityMb: number;
|
||||||
antennaLimit: number;
|
antennaLimit: number;
|
||||||
};
|
};
|
||||||
@ -26,6 +27,7 @@ export const DEFAULT_ROLE: RoleOptions = {
|
|||||||
ltlAvailable: true,
|
ltlAvailable: true,
|
||||||
canPublicNote: true,
|
canPublicNote: true,
|
||||||
canInvite: false,
|
canInvite: false,
|
||||||
|
canManageCustomEmojis: false,
|
||||||
driveCapacityMb: 100,
|
driveCapacityMb: 100,
|
||||||
antennaLimit: 5,
|
antennaLimit: 5,
|
||||||
};
|
};
|
||||||
@ -182,6 +184,7 @@ export class RoleService implements OnApplicationShutdown {
|
|||||||
ltlAvailable: getOptionValues('ltlAvailable').some(x => x === true),
|
ltlAvailable: getOptionValues('ltlAvailable').some(x => x === true),
|
||||||
canPublicNote: getOptionValues('canPublicNote').some(x => x === true),
|
canPublicNote: getOptionValues('canPublicNote').some(x => x === true),
|
||||||
canInvite: getOptionValues('canInvite').some(x => x === true),
|
canInvite: getOptionValues('canInvite').some(x => x === true),
|
||||||
|
canManageCustomEmojis: getOptionValues('canManageCustomEmojis').some(x => x === true),
|
||||||
driveCapacityMb: Math.max(...getOptionValues('driveCapacityMb')),
|
driveCapacityMb: Math.max(...getOptionValues('driveCapacityMb')),
|
||||||
antennaLimit: Math.max(...getOptionValues('antennaLimit')),
|
antennaLimit: Math.max(...getOptionValues('antennaLimit')),
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -14,7 +14,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
noSuchFile: {
|
noSuchFile: {
|
||||||
|
@ -14,7 +14,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
noSuchEmoji: {
|
noSuchEmoji: {
|
||||||
|
@ -9,7 +9,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -10,7 +10,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
noSuchEmoji: {
|
noSuchEmoji: {
|
||||||
|
@ -5,7 +5,7 @@ import { QueueService } from '@/core/QueueService.js';
|
|||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
@ -11,7 +11,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
@ -8,7 +8,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -8,7 +8,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -8,7 +8,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
|
@ -9,7 +9,7 @@ export const meta = {
|
|||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireRoleOption: 'canManageCustomEmojis',
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
noSuchEmoji: {
|
noSuchEmoji: {
|
||||||
|
@ -90,6 +90,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>{{ i18n.ts._role._options.canManageCustomEmojis }}</template>
|
||||||
|
<template #suffix>{{ options_canManageCustomEmojis_useDefault ? i18n.ts._role.useBaseValue : (options_canManageCustomEmojis_value ? i18n.ts.yes : i18n.ts.no) }}</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSwitch v-model="options_canManageCustomEmojis_useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkSwitch v-model="options_canManageCustomEmojis_value" :disabled="options_canManageCustomEmojis_useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||||
<template #suffix>{{ options_driveCapacityMb_useDefault ? i18n.ts._role.useBaseValue : (options_driveCapacityMb_value + 'MB') }}</template>
|
<template #suffix>{{ options_driveCapacityMb_useDefault ? i18n.ts._role.useBaseValue : (options_driveCapacityMb_value + 'MB') }}</template>
|
||||||
@ -175,6 +188,8 @@ let options_canPublicNote_useDefault = $ref(role?.options?.canPublicNote?.useDef
|
|||||||
let options_canPublicNote_value = $ref(role?.options?.canPublicNote?.value ?? false);
|
let options_canPublicNote_value = $ref(role?.options?.canPublicNote?.value ?? false);
|
||||||
let options_canInvite_useDefault = $ref(role?.options?.canInvite?.useDefault ?? true);
|
let options_canInvite_useDefault = $ref(role?.options?.canInvite?.useDefault ?? true);
|
||||||
let options_canInvite_value = $ref(role?.options?.canInvite?.value ?? false);
|
let options_canInvite_value = $ref(role?.options?.canInvite?.value ?? false);
|
||||||
|
let options_canManageCustomEmojis_useDefault = $ref(role?.options?.canManageCustomEmojis?.useDefault ?? true);
|
||||||
|
let options_canManageCustomEmojis_value = $ref(role?.options?.canManageCustomEmojis?.value ?? false);
|
||||||
let options_driveCapacityMb_useDefault = $ref(role?.options?.driveCapacityMb?.useDefault ?? true);
|
let options_driveCapacityMb_useDefault = $ref(role?.options?.driveCapacityMb?.useDefault ?? true);
|
||||||
let options_driveCapacityMb_value = $ref(role?.options?.driveCapacityMb?.value ?? 0);
|
let options_driveCapacityMb_value = $ref(role?.options?.driveCapacityMb?.value ?? 0);
|
||||||
let options_antennaLimit_useDefault = $ref(role?.options?.antennaLimit?.useDefault ?? true);
|
let options_antennaLimit_useDefault = $ref(role?.options?.antennaLimit?.useDefault ?? true);
|
||||||
@ -192,6 +207,7 @@ function getOptions() {
|
|||||||
ltlAvailable: { useDefault: options_ltlAvailable_useDefault, value: options_ltlAvailable_value },
|
ltlAvailable: { useDefault: options_ltlAvailable_useDefault, value: options_ltlAvailable_value },
|
||||||
canPublicNote: { useDefault: options_canPublicNote_useDefault, value: options_canPublicNote_value },
|
canPublicNote: { useDefault: options_canPublicNote_useDefault, value: options_canPublicNote_value },
|
||||||
canInvite: { useDefault: options_canInvite_useDefault, value: options_canInvite_value },
|
canInvite: { useDefault: options_canInvite_useDefault, value: options_canInvite_value },
|
||||||
|
canManageCustomEmojis: { useDefault: options_canManageCustomEmojis_useDefault, value: options_canManageCustomEmojis_value },
|
||||||
driveCapacityMb: { useDefault: options_driveCapacityMb_useDefault, value: options_driveCapacityMb_value },
|
driveCapacityMb: { useDefault: options_driveCapacityMb_useDefault, value: options_driveCapacityMb_value },
|
||||||
antennaLimit: { useDefault: options_antennaLimit_useDefault, value: options_antennaLimit_value },
|
antennaLimit: { useDefault: options_antennaLimit_useDefault, value: options_antennaLimit_value },
|
||||||
};
|
};
|
||||||
|
@ -40,6 +40,14 @@
|
|||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>{{ i18n.ts._role._options.canManageCustomEmojis }}</template>
|
||||||
|
<template #suffix>{{ options_canManageCustomEmojis ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||||
|
<MkSwitch v-model="options_canManageCustomEmojis">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||||
<template #suffix>{{ options_driveCapacityMb }}MB</template>
|
<template #suffix>{{ options_driveCapacityMb }}MB</template>
|
||||||
@ -90,6 +98,7 @@ let options_gtlAvailable = $ref(instance.baseRole.gtlAvailable);
|
|||||||
let options_ltlAvailable = $ref(instance.baseRole.ltlAvailable);
|
let options_ltlAvailable = $ref(instance.baseRole.ltlAvailable);
|
||||||
let options_canPublicNote = $ref(instance.baseRole.canPublicNote);
|
let options_canPublicNote = $ref(instance.baseRole.canPublicNote);
|
||||||
let options_canInvite = $ref(instance.baseRole.canInvite);
|
let options_canInvite = $ref(instance.baseRole.canInvite);
|
||||||
|
let options_canManageCustomEmojis = $ref(instance.baseRole.canManageCustomEmojis);
|
||||||
let options_driveCapacityMb = $ref(instance.baseRole.driveCapacityMb);
|
let options_driveCapacityMb = $ref(instance.baseRole.driveCapacityMb);
|
||||||
let options_antennaLimit = $ref(instance.baseRole.antennaLimit);
|
let options_antennaLimit = $ref(instance.baseRole.antennaLimit);
|
||||||
|
|
||||||
@ -100,6 +109,7 @@ async function updateBaseRole() {
|
|||||||
ltlAvailable: options_ltlAvailable,
|
ltlAvailable: options_ltlAvailable,
|
||||||
canPublicNote: options_canPublicNote,
|
canPublicNote: options_canPublicNote,
|
||||||
canInvite: options_canInvite,
|
canInvite: options_canInvite,
|
||||||
|
canManageCustomEmojis: options_canManageCustomEmojis,
|
||||||
driveCapacityMb: options_driveCapacityMb,
|
driveCapacityMb: options_driveCapacityMb,
|
||||||
antennaLimit: options_antennaLimit,
|
antennaLimit: options_antennaLimit,
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<MkStickyContainer>
|
<MkStickyContainer>
|
||||||
<template #header><XHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||||
<MkSpacer :content-max="900">
|
<MkSpacer :content-max="900">
|
||||||
<div class="ogwlenmc">
|
<div class="ogwlenmc">
|
||||||
<div v-if="tab === 'local'" class="local">
|
<div v-if="tab === 'local'" class="local">
|
||||||
@ -69,7 +69,6 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, defineAsyncComponent, defineComponent, ref, shallowRef } from 'vue';
|
import { computed, defineAsyncComponent, defineComponent, ref, shallowRef } from 'vue';
|
||||||
import XHeader from './_header_.vue';
|
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkInput from '@/components/MkInput.vue';
|
import MkInput from '@/components/MkInput.vue';
|
||||||
import MkPagination from '@/components/MkPagination.vue';
|
import MkPagination from '@/components/MkPagination.vue';
|
@ -305,6 +305,9 @@ export const routes = [{
|
|||||||
}, {
|
}, {
|
||||||
path: '/channels',
|
path: '/channels',
|
||||||
component: page(() => import('./pages/channels.vue')),
|
component: page(() => import('./pages/channels.vue')),
|
||||||
|
}, {
|
||||||
|
path: '/custom-emojis-manager',
|
||||||
|
component: page(() => import('./pages/custom-emojis-manager.vue')),
|
||||||
}, {
|
}, {
|
||||||
path: '/registry/keys/system/:path(*)?',
|
path: '/registry/keys/system/:path(*)?',
|
||||||
component: page(() => import('./pages/registry.keys.vue')),
|
component: page(() => import('./pages/registry.keys.vue')),
|
||||||
@ -331,7 +334,7 @@ export const routes = [{
|
|||||||
}, {
|
}, {
|
||||||
path: '/emojis',
|
path: '/emojis',
|
||||||
name: 'emojis',
|
name: 'emojis',
|
||||||
component: page(() => import('./pages/admin/emojis.vue')),
|
component: page(() => import('./pages/custom-emojis-manager.vue')),
|
||||||
}, {
|
}, {
|
||||||
path: '/queue',
|
path: '/queue',
|
||||||
name: 'queue',
|
name: 'queue',
|
||||||
|
@ -47,7 +47,7 @@ export function openInstanceMenu(ev: MouseEvent) {
|
|||||||
to: '/clicker',
|
to: '/clicker',
|
||||||
text: '🍪👈',
|
text: '🍪👈',
|
||||||
icon: 'ti ti-cookie',
|
icon: 'ti ti-cookie',
|
||||||
}, ($i && ($i.isRoot || $i.role.canInvite) && instance.disableRegistration) ? {
|
}, ($i && ($i.isAdmin || $i.role.canInvite) && instance.disableRegistration) ? {
|
||||||
text: i18n.ts.invite,
|
text: i18n.ts.invite,
|
||||||
icon: 'ti ti-user-plus',
|
icon: 'ti ti-user-plus',
|
||||||
action: () => {
|
action: () => {
|
||||||
@ -63,6 +63,11 @@ export function openInstanceMenu(ev: MouseEvent) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
} : undefined, ($i && ($i.isAdmin || $i.role.canManageCustomEmojis)) ? {
|
||||||
|
type: 'link',
|
||||||
|
to: '/custom-emojis-manager',
|
||||||
|
text: i18n.ts.manageCustomEmojis,
|
||||||
|
icon: 'ti ti-icons',
|
||||||
} : undefined],
|
} : undefined],
|
||||||
}, null, {
|
}, null, {
|
||||||
text: i18n.ts.help,
|
text: i18n.ts.help,
|
||||||
|
Loading…
Reference in New Issue
Block a user