From 605756d42589a100135a8570c4613162a2902459 Mon Sep 17 00:00:00 2001
From: Esurio/1673beta <60435625+1673beta@users.noreply.github.com>
Date: Mon, 27 Jan 2025 09:03:52 +0900
Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E3=83=AD=E3=83=BC=E3=83=AB?=
 =?UTF-8?q?=E4=BD=9C=E6=88=90=E7=94=BB=E9=9D=A2=E3=81=A7=E8=A8=AD=E5=AE=9A?=
 =?UTF-8?q?=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=A2=E3=82=A4=E3=82=B3=E3=83=B3?=
 =?UTF-8?q?=E3=83=87=E3=82=B3=E3=83=AC=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3?=
 =?UTF-8?q?=E3=81=AE=E6=9C=80=E5=A4=A7=E5=80=A4=E3=82=9216=E3=81=AB?=
 =?UTF-8?q?=E3=81=99=E3=82=8B=20(#15352)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* fix(frontend): アイコンデコレーションの17以上の数値が入力された際16にしてAPIリクエストを送信するように

* Update CHANGELOG

---------

Co-authored-by: Esurio <esurio@esurio1673.net>
---
 CHANGELOG.md                                       |  1 +
 packages/frontend/src/pages/admin/roles.editor.vue | 10 ++++++++--
 packages/frontend/src/pages/admin/roles.vue        | 13 ++++++++++++-
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 59fd861ec4..03c9d8ea84 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -49,6 +49,7 @@
 - Fix: 非ログイン時のサーバー概要画面のメニューボタンが押せないことがあるのを修正  
   (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/656)
 - Fix: URLにはじめから`#pswp`が含まれている場合に画像ビューワーがブラウザの戻るボタンで閉じられない問題を修正
+- Fix: ロール作成画面で設定できるアイコンデコレーションの最大取付個数を16に制限
 
 ### Server
 - Enhance: pg_bigmが利用できるよう、ノートの検索をILIKE演算子でなくLIKE演算子でLOWER()をかけたテキストに対して行うように
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index ae01432d0c..d05f52334e 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -582,7 +582,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkSwitch v-model="role.policies.avatarDecorationLimit.useDefault" :readonly="readonly">
 						<template #label>{{ i18n.ts._role.useBaseValue }}</template>
 					</MkSwitch>
-					<MkInput v-model="role.policies.avatarDecorationLimit.value" type="number" :min="0">
+					<MkInput v-model="role.policies.avatarDecorationLimit.value" type="number" :min="0" :max="16" @update:modelValue="updateAvatarDecorationLimit">
 						<template #label>{{ i18n.ts._role._options.avatarDecorationLimit }}</template>
 					</MkInput>
 					<MkRange v-model="role.policies.avatarDecorationLimit.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 : ''">
@@ -698,6 +698,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <script lang="ts" setup>
 import { watch, ref, computed } from 'vue';
 import { throttle } from 'throttle-debounce';
+import { ROLE_POLICIES } from '@@/js/const.js';
 import RolesEditorFormula from './RolesEditorFormula.vue';
 import MkInput from '@/components/MkInput.vue';
 import MkColorInput from '@/components/MkColorInput.vue';
@@ -708,7 +709,6 @@ import MkSwitch from '@/components/MkSwitch.vue';
 import MkRange from '@/components/MkRange.vue';
 import FormSlot from '@/components/form/slot.vue';
 import { i18n } from '@/i18n.js';
-import { ROLE_POLICIES } from '@@/js/const.js';
 import { instance } from '@/instance.js';
 import { deepClone } from '@/scripts/clone.js';
 
@@ -734,6 +734,12 @@ for (const ROLE_POLICY of ROLE_POLICIES) {
 	}
 }
 
+function updateAvatarDecorationLimit(value: string | number) {
+	const numValue = Number(value);
+	const limited = Math.min(16, Math.max(0, numValue));
+	role.value.policies.avatarDecorationLimit.value = limited;
+}
+
 const rolePermission = computed({
 	get: () => role.value.isAdministrator ? 'administrator' : role.value.isModerator ? 'moderator' : 'normal',
 	set: (val) => {
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index b1cbdad137..782c1256de 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -213,7 +213,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<MkFolder v-if="matchQuery([i18n.ts._role._options.avatarDecorationLimit, 'avatarDecorationLimit'])">
 							<template #label>{{ i18n.ts._role._options.avatarDecorationLimit }}</template>
 							<template #suffix>{{ policies.avatarDecorationLimit }}</template>
-							<MkInput v-model="policies.avatarDecorationLimit" type="number" :min="0">
+							<MkInput v-model="avatarDecorationLimit" type="number" :min="0" :max="16" @update:modelValue="updateAvatarDecorationLimit">
 							</MkInput>
 						</MkFolder>
 
@@ -307,6 +307,17 @@ for (const ROLE_POLICY of ROLE_POLICIES) {
 	policies[ROLE_POLICY] = instance.policies[ROLE_POLICY];
 }
 
+const avatarDecorationLimit = computed({
+	get: () => Math.min(16, Math.max(0, policies.avatarDecorationLimit)),
+	set: (value) => {
+		policies.avatarDecorationLimit = Math.min(Number(value), 16);
+	},
+});
+
+function updateAvatarDecorationLimit(value: string | number) {
+	avatarDecorationLimit.value = Number(value);
+}
+
 function matchQuery(keywords: string[]): boolean {
 	if (baseRoleQ.value.trim().length === 0) return true;
 	return keywords.some(keyword => keyword.toLowerCase().includes(baseRoleQ.value.toLowerCase()));
-- 
GitLab