summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2025-07-12 15:13:35 +0900
committersyuilo <4439005+syuilo@users.noreply.github.com>2025-07-12 15:13:35 +0900
commit5ecaf5095ecd4678dd3e05abcc5b0781f6fddb93 (patch)
treef4cfde51470eab18fa7356f831c807a7e26621f8 /packages
parentNew Crowdin updates (#16258) (diff)
downloadmisskey-5ecaf5095ecd4678dd3e05abcc5b0781f6fddb93.tar.gz
misskey-5ecaf5095ecd4678dd3e05abcc5b0781f6fddb93.tar.bz2
misskey-5ecaf5095ecd4678dd3e05abcc5b0781f6fddb93.zip
enhance: ウォーターマーク機能をロールで制御可能に
Diffstat (limited to 'packages')
-rw-r--r--packages/backend/src/core/RoleService.ts3
-rw-r--r--packages/backend/src/models/json-schema/role.ts4
-rw-r--r--packages/frontend-shared/js/const.ts1
-rw-r--r--packages/frontend/src/composables/use-uploader.ts7
-rw-r--r--packages/frontend/src/pages/admin/roles.editor.vue20
-rw-r--r--packages/frontend/src/pages/admin/roles.vue8
-rw-r--r--packages/frontend/src/pages/settings/drive.vue2
-rw-r--r--packages/misskey-js/src/autogen/types.ts1
8 files changed, 43 insertions, 3 deletions
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index 314f7e221a..cddfc0094e 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -67,6 +67,7 @@ export type RolePolicies = {
chatAvailability: 'available' | 'readonly' | 'unavailable';
uploadableFileTypes: string[];
noteDraftLimit: number;
+ watermarkAvailable: boolean;
};
export const DEFAULT_POLICIES: RolePolicies = {
@@ -111,6 +112,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
'audio/*',
],
noteDraftLimit: 10,
+ watermarkAvailable: true,
};
@Injectable()
@@ -433,6 +435,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
return [...set];
}),
noteDraftLimit: calc('noteDraftLimit', vs => Math.max(...vs)),
+ watermarkAvailable: calc('watermarkAvailable', vs => vs.some(v => v === true)),
};
}
diff --git a/packages/backend/src/models/json-schema/role.ts b/packages/backend/src/models/json-schema/role.ts
index a3f679129d..c9cdbd5d89 100644
--- a/packages/backend/src/models/json-schema/role.ts
+++ b/packages/backend/src/models/json-schema/role.ts
@@ -313,6 +313,10 @@ export const packedRolePoliciesSchema = {
type: 'integer',
optional: false, nullable: false,
},
+ watermarkAvailable: {
+ type: 'boolean',
+ optional: false, nullable: false,
+ },
},
} as const;
diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts
index 4498a5e2b2..5c33c38f44 100644
--- a/packages/frontend-shared/js/const.ts
+++ b/packages/frontend-shared/js/const.ts
@@ -112,6 +112,7 @@ export const ROLE_POLICIES = [
'chatAvailability',
'uploadableFileTypes',
'noteDraftLimit',
+ 'watermarkAvailable',
] as const;
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime'];
diff --git a/packages/frontend/src/composables/use-uploader.ts b/packages/frontend/src/composables/use-uploader.ts
index 6f4ed81f82..826d8c5203 100644
--- a/packages/frontend/src/composables/use-uploader.ts
+++ b/packages/frontend/src/composables/use-uploader.ts
@@ -104,6 +104,8 @@ export function useUploader(options: {
multiple?: boolean;
features?: UploaderFeatures;
} = {}) {
+ const $i = ensureSignin();
+
const events = new EventEmitter<{
'itemUploaded': (ctx: { item: UploaderItem; }) => void;
}>();
@@ -132,7 +134,7 @@ export function useUploader(options: {
uploaded: null,
uploadFailed: false,
compressionLevel: prefer.s.defaultImageCompressionLevel,
- watermarkPresetId: uploaderFeatures.value.watermark ? prefer.s.defaultWatermarkPresetId : null,
+ watermarkPresetId: uploaderFeatures.value.watermark && $i.policies.watermarkAvailable ? prefer.s.defaultWatermarkPresetId : null,
file: markRaw(file),
});
const reactiveItem = items.value.at(-1)!;
@@ -264,6 +266,7 @@ export function useUploader(options: {
if (
uploaderFeatures.value.watermark &&
+ $i.policies.watermarkAvailable &&
WATERMARK_SUPPORTED_TYPES.includes(item.file.type) &&
!item.preprocessing &&
!item.uploading &&
@@ -500,7 +503,7 @@ export function useUploader(options: {
let preprocessedFile: Blob | File = item.file;
- const needsWatermark = item.watermarkPresetId != null && WATERMARK_SUPPORTED_TYPES.includes(preprocessedFile.type);
+ const needsWatermark = item.watermarkPresetId != null && WATERMARK_SUPPORTED_TYPES.includes(preprocessedFile.type) && $i.policies.watermarkAvailable;
const preset = prefer.s.watermarkPresets.find(p => p.id === item.watermarkPresetId);
if (needsWatermark && preset != null) {
const canvas = window.document.createElement('canvas');
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index a266e1df6f..c172e22688 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -780,6 +780,26 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkRange>
</div>
</MkFolder>
+
+ <MkFolder v-if="matchQuery([i18n.ts._role._options.watermarkAvailable, 'watermarkAvailable'])">
+ <template #label>{{ i18n.ts._role._options.watermarkAvailable }}</template>
+ <template #suffix>
+ <span v-if="role.policies.watermarkAvailable.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
+ <span v-else>{{ role.policies.watermarkAvailable.value ? i18n.ts.yes : i18n.ts.no }}</span>
+ <span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.watermarkAvailable)"></i></span>
+ </template>
+ <div class="_gaps">
+ <MkSwitch v-model="role.policies.watermarkAvailable.useDefault" :readonly="readonly">
+ <template #label>{{ i18n.ts._role.useBaseValue }}</template>
+ </MkSwitch>
+ <MkSwitch v-model="role.policies.watermarkAvailable.value" :disabled="role.policies.watermarkAvailable.useDefault" :readonly="readonly">
+ <template #label>{{ i18n.ts.enable }}</template>
+ </MkSwitch>
+ <MkRange v-model="role.policies.watermarkAvailable.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
+ <template #label>{{ i18n.ts._role.priority }}</template>
+ </MkRange>
+ </div>
+ </MkFolder>
</div>
</FormSlot>
</div>
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index dee0fb1e5c..e78a4bbc11 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -291,6 +291,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInput v-model="policies.noteDraftLimit" type="number" :min="0">
</MkInput>
</MkFolder>
+
+ <MkFolder v-if="matchQuery([i18n.ts._role._options.watermarkAvailable, 'watermarkAvailable'])">
+ <template #label>{{ i18n.ts._role._options.watermarkAvailable }}</template>
+ <template #suffix>{{ policies.watermarkAvailable ? i18n.ts.yes : i18n.ts.no }}</template>
+ <MkSwitch v-model="policies.watermarkAvailable">
+ <template #label>{{ i18n.ts.enable }}</template>
+ </MkSwitch>
+ </MkFolder>
</div>
</MkFolder>
<MkButton primary rounded @click="create"><i class="ti ti-plus"></i> {{ i18n.ts._role.new }}</MkButton>
diff --git a/packages/frontend/src/pages/settings/drive.vue b/packages/frontend/src/pages/settings/drive.vue
index 0614b1242b..1b99f6dea5 100644
--- a/packages/frontend/src/pages/settings/drive.vue
+++ b/packages/frontend/src/pages/settings/drive.vue
@@ -87,7 +87,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_gaps_m">
<SearchMarker :keywords="['watermark', 'credit']">
- <MkFolder>
+ <MkFolder v-if="$i.policies.watermarkAvailable">
<template #icon><i class="ti ti-copyright"></i></template>
<template #label><SearchLabel>{{ i18n.ts.watermark }}</SearchLabel></template>
<template #caption>{{ i18n.ts._watermarkEditor.tip }}</template>
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index df6a22ec41..51e4b4f45d 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -5225,6 +5225,7 @@ export type components = {
/** @enum {string} */
chatAvailability: 'available' | 'readonly' | 'unavailable';
noteDraftLimit: number;
+ watermarkAvailable: boolean;
};
ReversiGameLite: {
/** Format: id */