enhance: improve avatar decoration

This commit is contained in:
syuilo
2023-10-22 13:02:24 +09:00
parent 69795e74bf
commit 4eaa02d25f
13 changed files with 230 additions and 26 deletions

View File

@@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class AvatarDecoration21697941908548 {
name = 'AvatarDecoration21697941908548'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarDecorations"`);
await queryRunner.query(`ALTER TABLE "user" ADD "avatarDecorations" jsonb NOT NULL DEFAULT '[]'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarDecorations"`);
await queryRunner.query(`ALTER TABLE "user" ADD "avatarDecorations" character varying(512) array NOT NULL DEFAULT '{}'`);
}
}

View File

@@ -338,9 +338,11 @@ export class UserEntityService implements OnModuleInit {
host: user.host,
avatarUrl: user.avatarUrl ?? this.getIdenticonUrl(user),
avatarBlurhash: user.avatarBlurhash,
avatarDecorations: user.avatarDecorations.length > 0 ? this.avatarDecorationService.getAll().then(decorations => decorations.filter(decoration => user.avatarDecorations.includes(decoration.id)).map(decoration => ({
id: decoration.id,
url: decoration.url,
avatarDecorations: user.avatarDecorations.length > 0 ? this.avatarDecorationService.getAll().then(decorations => user.avatarDecorations.filter(ud => decorations.some(d => d.id === ud.id)).map(ud => ({
id: ud.id,
angle: ud.angle || undefined,
flipH: ud.flipH || undefined,
url: decorations.find(d => d.id === ud.id)!.url,
}))) : [],
isBot: user.isBot,
isCat: user.isCat,

View File

@@ -138,10 +138,14 @@ export class MiUser {
})
public bannerBlurhash: string | null;
@Column('varchar', {
length: 512, array: true, default: '{}',
@Column('jsonb', {
default: [],
})
public avatarDecorations: string[];
public avatarDecorations: {
id: string;
angle: number;
flipH: boolean;
}[];
@Index()
@Column('varchar', {

View File

@@ -54,6 +54,14 @@ export const packedUserLiteSchema = {
format: 'url',
nullable: false, optional: false,
},
angle: {
type: 'number',
nullable: false, optional: true,
},
flipH: {
type: 'boolean',
nullable: false, optional: true,
},
},
},
},

View File

@@ -133,7 +133,13 @@ export const paramDef = {
lang: { type: 'string', enum: [null, ...Object.keys(langmap)] as string[], nullable: true },
avatarId: { type: 'string', format: 'misskey:id', nullable: true },
avatarDecorations: { type: 'array', maxItems: 1, items: {
type: 'string',
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
angle: { type: 'number', nullable: true, maximum: 0.5, minimum: -0.5 },
flipH: { type: 'boolean', nullable: true },
},
required: ['id'],
} },
bannerId: { type: 'string', format: 'misskey:id', nullable: true },
fields: {
@@ -309,7 +315,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
.filter(d => d.roleIdsThatCanBeUsedThisDecoration.filter(roleId => allRoles.some(r => r.id === roleId)).length === 0 || myRoles.some(r => d.roleIdsThatCanBeUsedThisDecoration.includes(r.id)))
.map(d => d.id);
updates.avatarDecorations = ps.avatarDecorations.filter(id => decorationIds.includes(id));
updates.avatarDecorations = ps.avatarDecorations.filter(d => decorationIds.includes(d.id)).map(d => ({
id: d.id,
angle: d.angle ?? 0,
flipH: d.flipH ?? false,
}));
}
if (ps.pinnedPageId) {