diff options
| author | CenTdemeern1 <timo.herngreen@gmail.com> | 2024-10-02 23:49:30 +0200 |
|---|---|---|
| committer | CenTdemeern1 <timo.herngreen@gmail.com> | 2024-10-02 23:49:30 +0200 |
| commit | 28aa99b2737fd3d66f8c438477c96aa94b0059ed (patch) | |
| tree | ff687fd19300d0ac62461c4bc19d7dba13451566 | |
| parent | merge: Merge stable into develop (!636) (diff) | |
| download | sharkey-28aa99b2737fd3d66f8c438477c96aa94b0059ed.tar.gz sharkey-28aa99b2737fd3d66f8c438477c96aa94b0059ed.tar.bz2 sharkey-28aa99b2737fd3d66f8c438477c96aa94b0059ed.zip | |
Implement "Show Below Avatar" for Avatar Decorations
9 files changed, 42 insertions, 14 deletions
diff --git a/locales/en-US.yml b/locales/en-US.yml index 6d24bb5b41..2d3c5c53b6 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1277,6 +1277,7 @@ detach: "Remove" detachAll: "Remove All" angle: "Angle" flip: "Flip" +showBelowAvatar: "Show Below Avatar" showAvatarDecorations: "Show avatar decorations" releaseToRefresh: "Release to refresh" refreshing: "Refreshing..." diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 2b1c4d5c63..40830f86b4 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -525,6 +525,7 @@ export class UserEntityService implements OnModuleInit { flipH: ud.flipH || undefined, offsetX: ud.offsetX || undefined, offsetY: ud.offsetY || undefined, + showBelow: ud.showBelow || undefined, url: decorations.find(d => d.id === ud.id)!.url, }))) : [], isBot: user.isBot, diff --git a/packages/backend/src/models/User.ts b/packages/backend/src/models/User.ts index b0910133c9..cbebd0102d 100644 --- a/packages/backend/src/models/User.ts +++ b/packages/backend/src/models/User.ts @@ -170,6 +170,7 @@ export class MiUser { flipH?: boolean; offsetX?: number; offsetY?: number; + showBelow?: boolean; }[]; @Index() diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index 33a3efd453..249b9bba38 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -104,6 +104,10 @@ export const packedUserLiteSchema = { type: 'number', nullable: false, optional: true, }, + showBelow: { + type: 'boolean', + nullable: false, optional: true, + }, }, }, }, diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 6cc22e7994..f9b8061249 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -159,6 +159,7 @@ export const paramDef = { 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 }, + showBelow: { type: 'boolean', nullable: true }, }, required: ['id'], } }, @@ -417,6 +418,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- flipH: d.flipH ?? false, offsetX: d.offsetX ?? 0, offsetY: d.offsetY ?? 0, + showBelow: d.showBelow ?? false, })); } diff --git a/packages/frontend/src/components/global/MkAvatar.vue b/packages/frontend/src/components/global/MkAvatar.vue index de62fe12a9..ce6985d907 100644 --- a/packages/frontend/src/components/global/MkAvatar.vue +++ b/packages/frontend/src/components/global/MkAvatar.vue @@ -7,6 +7,20 @@ SPDX-License-Identifier: AGPL-3.0-only <component :is="link ? MkA : 'span'" v-user-preview="preview ? user.id : undefined" v-bind="bound" class="_noSelect" :class="[$style.root, { [$style.animation]: animation, [$style.cat]: user.isCat, [$style.square]: squareAvatars }]" :style="{ color }" :title="acct(user)" @click="onClick"> <MkImgWithBlurhash :class="$style.inner" :src="url" :hash="user.avatarBlurhash" :cover="true" :onlyAvgColor="true"/> <MkUserOnlineIndicator v-if="indicator" :class="$style.indicator" :user="user"/> + <template v-if="showDecoration"> + <img + v-for="decoration in decorations ?? user.avatarDecorations" + :class="[$style.decoration]" + :src="getDecorationUrl(decoration)" + :style="{ + rotate: getDecorationAngle(decoration), + scale: getDecorationScale(decoration), + translate: getDecorationOffset(decoration), + zIndex: getDecorationZIndex(decoration), + }" + alt="" + > + </template> <div v-if="user.isCat" :class="[$style.ears]"> <div :class="$style.earLeft"> <div v-if="false" :class="$style.layer"> @@ -23,19 +37,6 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </div> </div> - <template v-if="showDecoration"> - <img - v-for="decoration in decorations ?? user.avatarDecorations" - :class="[$style.decoration]" - :src="getDecorationUrl(decoration)" - :style="{ - rotate: getDecorationAngle(decoration), - scale: getDecorationScale(decoration), - translate: getDecorationOffset(decoration), - }" - alt="" - > - </template> </component> </template> @@ -113,6 +114,11 @@ function getDecorationOffset(decoration: Omit<Misskey.entities.UserDetailed['ava return offsetX === 0 && offsetY === 0 ? undefined : `${offsetX * 100}% ${offsetY * 100}%`; } +function getDecorationZIndex(decoration: Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'>) { + const zIndex = decoration.showBelow ? 0 : 1; + return zIndex === 1 ? undefined : `${zIndex}`; +} + const color = ref<string | undefined>(); watch(() => props.user.avatarBlurhash, () => { diff --git a/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue b/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue index 0767fa7864..9f7852a71d 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue @@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only @click="emit('click')" > <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, offsetX, offsetY }]" forceShowDecoration/> + <MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[{ url: decoration.url, angle, flipH, offsetX, offsetY, showBelow }]" 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> </div> </template> @@ -32,6 +32,7 @@ const props = defineProps<{ flipH?: boolean; offsetX?: number; offsetY?: number; + showBelow?: boolean; }>(); const emit = defineEmits<{ diff --git a/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue b/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue index ce1d4e48d8..400b365ca6 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue @@ -29,6 +29,9 @@ SPDX-License-Identifier: AGPL-3.0-only <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="showBelow"> + <template #label>{{ i18n.ts.showBelowAvatar }}</template> + </MkSwitch> <MkSwitch v-model="flipH"> <template #label>{{ i18n.ts.flip }}</template> </MkSwitch> @@ -71,12 +74,14 @@ const emit = defineEmits<{ flipH: boolean; offsetX: number; offsetY: number; + showBelow: boolean; }): void; (ev: 'update', payload: { angle: number; flipH: boolean; offsetX: number; offsetY: number; + showBelow: boolean; }): void; (ev: 'detach'): void; }>(); @@ -87,6 +92,7 @@ const angle = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIn 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 showBelow = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].showBelow : null) ?? false); const decorationsForPreview = computed(() => { const decoration = { @@ -96,6 +102,7 @@ const decorationsForPreview = computed(() => { flipH: flipH.value, offsetX: offsetX.value, offsetY: offsetY.value, + showBelow: showBelow.value, }; const decorations = [...$i.avatarDecorations]; if (props.usingIndex != null) { @@ -116,6 +123,7 @@ async function update() { flipH: flipH.value, offsetX: offsetX.value, offsetY: offsetY.value, + showBelow: showBelow.value, }); dialog.value.close(); } @@ -126,6 +134,7 @@ async function attach() { flipH: flipH.value, offsetX: offsetX.value, offsetY: offsetY.value, + showBelow: showBelow.value, }); dialog.value.close(); } diff --git a/packages/frontend/src/pages/settings/avatar-decoration.vue b/packages/frontend/src/pages/settings/avatar-decoration.vue index 77229d3349..5324a6b7f7 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.vue @@ -21,6 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only :flipH="avatarDecoration.flipH" :offsetX="avatarDecoration.offsetX" :offsetY="avatarDecoration.offsetY" + :showBelow="avatarDecoration.showBelow" :active="true" @click="openDecoration(avatarDecoration, i)" /> @@ -78,6 +79,7 @@ function openDecoration(avatarDecoration, index?: number) { flipH: payload.flipH, offsetX: payload.offsetX, offsetY: payload.offsetY, + showBelow: payload.showBelow, }; const update = [...$i.avatarDecorations, decoration]; await os.apiWithDialog('i/update', { @@ -92,6 +94,7 @@ function openDecoration(avatarDecoration, index?: number) { flipH: payload.flipH, offsetX: payload.offsetX, offsetY: payload.offsetY, + showBelow: payload.showBelow, }; const update = [...$i.avatarDecorations]; update[index] = decoration; |