mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-10-26 19:14:12 +00:00 
			
		
		
		
	enhance: アイコンデコレーションの位置を微調整できるように
This commit is contained in:
		
							parent
							
								
									239507d7d6
								
							
						
					
					
						commit
						417852779f
					
				
					 8 changed files with 45 additions and 3 deletions
				
			
		|  | @ -31,6 +31,7 @@ | ||||||
| - Feat: モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能を追加 (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/e0eb5a752f6e5616d6312bb7c9790302f9dbff83) | - Feat: モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能を追加 (cherry-pick from https://github.com/TeamNijimiss/misskey/commit/e0eb5a752f6e5616d6312bb7c9790302f9dbff83) | ||||||
| - Feat: TL上からノートが見えなくなるワードミュートであるハードミュートを追加 | - Feat: TL上からノートが見えなくなるワードミュートであるハードミュートを追加 | ||||||
| - Enhance: アイコンデコレーションを複数設定できるように | - Enhance: アイコンデコレーションを複数設定できるように | ||||||
|  | - Enhance: アイコンデコレーションの位置を微調整できるように | ||||||
| - Fix: MFM `$[unixtime ]` に不正な値を入力した際に発生する各種エラーを修正 | - Fix: MFM `$[unixtime ]` に不正な値を入力した際に発生する各種エラーを修正 | ||||||
| 
 | 
 | ||||||
| ### Client | ### Client | ||||||
|  |  | ||||||
|  | @ -362,6 +362,8 @@ export class UserEntityService implements OnModuleInit { | ||||||
| 				id: ud.id, | 				id: ud.id, | ||||||
| 				angle: ud.angle || undefined, | 				angle: ud.angle || undefined, | ||||||
| 				flipH: ud.flipH || undefined, | 				flipH: ud.flipH || undefined, | ||||||
|  | 				offsetX: ud.offsetX || undefined, | ||||||
|  | 				offsetY: ud.offsetY || undefined, | ||||||
| 				url: decorations.find(d => d.id === ud.id)!.url, | 				url: decorations.find(d => d.id === ud.id)!.url, | ||||||
| 			}))) : [], | 			}))) : [], | ||||||
| 			isBot: user.isBot, | 			isBot: user.isBot, | ||||||
|  |  | ||||||
|  | @ -143,8 +143,10 @@ export class MiUser { | ||||||
| 	}) | 	}) | ||||||
| 	public avatarDecorations: { | 	public avatarDecorations: { | ||||||
| 		id: string; | 		id: string; | ||||||
| 		angle: number; | 		angle?: number; | ||||||
| 		flipH: boolean; | 		flipH?: boolean; | ||||||
|  | 		offsetX?: number; | ||||||
|  | 		offsetY?: number; | ||||||
| 	}[]; | 	}[]; | ||||||
| 
 | 
 | ||||||
| 	@Index() | 	@Index() | ||||||
|  |  | ||||||
|  | @ -143,6 +143,8 @@ export const paramDef = { | ||||||
| 				id: { type: 'string', format: 'misskey:id' }, | 				id: { type: 'string', format: 'misskey:id' }, | ||||||
| 				angle: { type: 'number', nullable: true, maximum: 0.5, minimum: -0.5 }, | 				angle: { type: 'number', nullable: true, maximum: 0.5, minimum: -0.5 }, | ||||||
| 				flipH: { type: 'boolean', nullable: true }, | 				flipH: { type: 'boolean', nullable: true }, | ||||||
|  | 				offsetX: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 }, | ||||||
|  | 				offsetY: { type: 'number', nullable: true, maximum: 0.25, minimum: -0.25 }, | ||||||
| 			}, | 			}, | ||||||
| 			required: ['id'], | 			required: ['id'], | ||||||
| 		} }, | 		} }, | ||||||
|  | @ -341,6 +343,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- | ||||||
| 					id: d.id, | 					id: d.id, | ||||||
| 					angle: d.angle ?? 0, | 					angle: d.angle ?? 0, | ||||||
| 					flipH: d.flipH ?? false, | 					flipH: d.flipH ?? false, | ||||||
|  | 					offsetX: d.offsetX ?? 0, | ||||||
|  | 					offsetY: d.offsetY ?? 0, | ||||||
| 				})); | 				})); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,6 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only | ||||||
| 			:style="{ | 			:style="{ | ||||||
| 				rotate: getDecorationAngle(decoration), | 				rotate: getDecorationAngle(decoration), | ||||||
| 				scale: getDecorationScale(decoration), | 				scale: getDecorationScale(decoration), | ||||||
|  | 				translate: getDecorationOffset(decoration), | ||||||
| 			}" | 			}" | ||||||
| 			alt="" | 			alt="" | ||||||
| 		> | 		> | ||||||
|  | @ -99,6 +100,12 @@ function getDecorationScale(decoration: Omit<Misskey.entities.UserDetailed['avat | ||||||
| 	return scaleX === 1 ? undefined : `${scaleX} 1`; | 	return scaleX === 1 ? undefined : `${scaleX} 1`; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function getDecorationOffset(decoration: Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'>) { | ||||||
|  | 	const offsetX = decoration.offsetX ?? 0; | ||||||
|  | 	const offsetY = decoration.offsetY ?? 0; | ||||||
|  | 	return offsetX === 0 && offsetY === 0 ? undefined : `${offsetX * 100}% ${offsetY * 100}%`; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| const color = ref<string | undefined>(); | const color = ref<string | undefined>(); | ||||||
| 
 | 
 | ||||||
| watch(() => props.user.avatarBlurhash, () => { | watch(() => props.user.avatarBlurhash, () => { | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only | ||||||
| 	@click="emit('click')" | 	@click="emit('click')" | ||||||
| > | > | ||||||
| 	<div :class="$style.name"><MkCondensedLine :minScale="0.5">{{ decoration.name }}</MkCondensedLine></div> | 	<div :class="$style.name"><MkCondensedLine :minScale="0.5">{{ decoration.name }}</MkCondensedLine></div> | ||||||
| 	<MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[{ url: decoration.url, angle, flipH }]" forceShowDecoration/> | 	<MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[{ url: decoration.url, angle, flipH, offsetX, offsetY }]" forceShowDecoration/> | ||||||
| 	<i v-if="decoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => decoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))" :class="$style.lock" class="ti ti-lock"></i> | 	<i v-if="decoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => decoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))" :class="$style.lock" class="ti ti-lock"></i> | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
|  | @ -28,6 +28,8 @@ const props = defineProps<{ | ||||||
| 	}; | 	}; | ||||||
| 	angle?: number; | 	angle?: number; | ||||||
| 	flipH?: boolean; | 	flipH?: boolean; | ||||||
|  | 	offsetX?: number; | ||||||
|  | 	offsetY?: number; | ||||||
| }>(); | }>(); | ||||||
| 
 | 
 | ||||||
| const emit = defineEmits<{ | const emit = defineEmits<{ | ||||||
|  |  | ||||||
|  | @ -23,6 +23,12 @@ SPDX-License-Identifier: AGPL-3.0-only | ||||||
| 				<MkRange v-model="angle" continuousUpdate :min="-0.5" :max="0.5" :step="0.025" :textConverter="(v) => `${Math.floor(v * 360)}°`"> | 				<MkRange v-model="angle" continuousUpdate :min="-0.5" :max="0.5" :step="0.025" :textConverter="(v) => `${Math.floor(v * 360)}°`"> | ||||||
| 					<template #label>{{ i18n.ts.angle }}</template> | 					<template #label>{{ i18n.ts.angle }}</template> | ||||||
| 				</MkRange> | 				</MkRange> | ||||||
|  | 				<MkRange v-model="offsetX" continuousUpdate :min="-0.25" :max="0.25" :step="0.025" :textConverter="(v) => `${Math.floor(v * 100)}%`"> | ||||||
|  | 					<template #label>X {{ i18n.ts.position }}</template> | ||||||
|  | 				</MkRange> | ||||||
|  | 				<MkRange v-model="offsetY" continuousUpdate :min="-0.25" :max="0.25" :step="0.025" :textConverter="(v) => `${Math.floor(v * 100)}%`"> | ||||||
|  | 					<template #label>Y {{ i18n.ts.position }}</template> | ||||||
|  | 				</MkRange> | ||||||
| 				<MkSwitch v-model="flipH"> | 				<MkSwitch v-model="flipH"> | ||||||
| 					<template #label>{{ i18n.ts.flip }}</template> | 					<template #label>{{ i18n.ts.flip }}</template> | ||||||
| 				</MkSwitch> | 				</MkSwitch> | ||||||
|  | @ -64,10 +70,14 @@ const emit = defineEmits<{ | ||||||
| 	(ev: 'attach', payload: { | 	(ev: 'attach', payload: { | ||||||
| 		angle: number; | 		angle: number; | ||||||
| 		flipH: boolean; | 		flipH: boolean; | ||||||
|  | 		offsetX: number; | ||||||
|  | 		offsetY: number; | ||||||
| 	}): void; | 	}): void; | ||||||
| 	(ev: 'update', payload: { | 	(ev: 'update', payload: { | ||||||
| 		angle: number; | 		angle: number; | ||||||
| 		flipH: boolean; | 		flipH: boolean; | ||||||
|  | 		offsetX: number; | ||||||
|  | 		offsetY: number; | ||||||
| 	}): void; | 	}): void; | ||||||
| 	(ev: 'detach'): void; | 	(ev: 'detach'): void; | ||||||
| }>(); | }>(); | ||||||
|  | @ -76,6 +86,8 @@ const dialog = shallowRef<InstanceType<typeof MkModalWindow>>(); | ||||||
| const exceeded = computed(() => ($i.policies.avatarDecorationLimit - $i.avatarDecorations.length) <= 0); | const exceeded = computed(() => ($i.policies.avatarDecorationLimit - $i.avatarDecorations.length) <= 0); | ||||||
| const angle = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].angle : null) ?? 0); | const angle = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].angle : null) ?? 0); | ||||||
| const flipH = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].flipH : null) ?? false); | const flipH = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].flipH : null) ?? false); | ||||||
|  | const offsetX = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].offsetX : null) ?? 0); | ||||||
|  | const offsetY = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].offsetY : null) ?? 0); | ||||||
| 
 | 
 | ||||||
| const decorationsForPreview = computed(() => { | const decorationsForPreview = computed(() => { | ||||||
| 	const decoration = { | 	const decoration = { | ||||||
|  | @ -83,6 +95,8 @@ const decorationsForPreview = computed(() => { | ||||||
| 		url: props.decoration.url, | 		url: props.decoration.url, | ||||||
| 		angle: angle.value, | 		angle: angle.value, | ||||||
| 		flipH: flipH.value, | 		flipH: flipH.value, | ||||||
|  | 		offsetX: offsetX.value, | ||||||
|  | 		offsetY: offsetY.value, | ||||||
| 	}; | 	}; | ||||||
| 	const decorations = [...$i.avatarDecorations]; | 	const decorations = [...$i.avatarDecorations]; | ||||||
| 	if (props.usingIndex != null) { | 	if (props.usingIndex != null) { | ||||||
|  | @ -101,6 +115,8 @@ async function update() { | ||||||
| 	emit('update', { | 	emit('update', { | ||||||
| 		angle: angle.value, | 		angle: angle.value, | ||||||
| 		flipH: flipH.value, | 		flipH: flipH.value, | ||||||
|  | 		offsetX: offsetX.value, | ||||||
|  | 		offsetY: offsetY.value, | ||||||
| 	}); | 	}); | ||||||
| 	dialog.value.close(); | 	dialog.value.close(); | ||||||
| } | } | ||||||
|  | @ -109,6 +125,8 @@ async function attach() { | ||||||
| 	emit('attach', { | 	emit('attach', { | ||||||
| 		angle: angle.value, | 		angle: angle.value, | ||||||
| 		flipH: flipH.value, | 		flipH: flipH.value, | ||||||
|  | 		offsetX: offsetX.value, | ||||||
|  | 		offsetY: offsetY.value, | ||||||
| 	}); | 	}); | ||||||
| 	dialog.value.close(); | 	dialog.value.close(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -16,6 +16,8 @@ SPDX-License-Identifier: AGPL-3.0-only | ||||||
| 				:decoration="avatarDecorations.find(d => d.id === avatarDecoration.id)" | 				:decoration="avatarDecorations.find(d => d.id === avatarDecoration.id)" | ||||||
| 				:angle="avatarDecoration.angle" | 				:angle="avatarDecoration.angle" | ||||||
| 				:flipH="avatarDecoration.flipH" | 				:flipH="avatarDecoration.flipH" | ||||||
|  | 				:offsetX="avatarDecoration.offsetX" | ||||||
|  | 				:offsetY="avatarDecoration.offsetY" | ||||||
| 				:active="true" | 				:active="true" | ||||||
| 				@click="openDecoration(avatarDecoration, i)" | 				@click="openDecoration(avatarDecoration, i)" | ||||||
| 			/> | 			/> | ||||||
|  | @ -66,6 +68,8 @@ function openDecoration(avatarDecoration, index?: number) { | ||||||
| 				id: avatarDecoration.id, | 				id: avatarDecoration.id, | ||||||
| 				angle: payload.angle, | 				angle: payload.angle, | ||||||
| 				flipH: payload.flipH, | 				flipH: payload.flipH, | ||||||
|  | 				offsetX: payload.offsetX, | ||||||
|  | 				offsetY: payload.offsetY, | ||||||
| 			}; | 			}; | ||||||
| 			const update = [...$i.avatarDecorations, decoration]; | 			const update = [...$i.avatarDecorations, decoration]; | ||||||
| 			await os.apiWithDialog('i/update', { | 			await os.apiWithDialog('i/update', { | ||||||
|  | @ -78,6 +82,8 @@ function openDecoration(avatarDecoration, index?: number) { | ||||||
| 				id: avatarDecoration.id, | 				id: avatarDecoration.id, | ||||||
| 				angle: payload.angle, | 				angle: payload.angle, | ||||||
| 				flipH: payload.flipH, | 				flipH: payload.flipH, | ||||||
|  | 				offsetX: payload.offsetX, | ||||||
|  | 				offsetY: payload.offsetY, | ||||||
| 			}; | 			}; | ||||||
| 			const update = [...$i.avatarDecorations]; | 			const update = [...$i.avatarDecorations]; | ||||||
| 			update[index] = decoration; | 			update[index] = decoration; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue