diff options
Diffstat (limited to 'packages')
11 files changed, 369 insertions, 123 deletions
diff --git a/packages/backend/src/server/api/endpoints/admin/avatar-decorations/create.ts b/packages/backend/src/server/api/endpoints/admin/avatar-decorations/create.ts index fd21309818..87d80cbe80 100644 --- a/packages/backend/src/server/api/endpoints/admin/avatar-decorations/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/avatar-decorations/create.ts @@ -6,6 +6,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { AvatarDecorationService } from '@/core/AvatarDecorationService.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['admin'], @@ -13,6 +14,49 @@ export const meta = { requireCredential: true, requireRolePolicy: 'canManageAvatarDecorations', kind: 'write:admin:avatar-decorations', + + res: { + type: 'object', + optional: false, nullable: false, + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + createdAt: { + type: 'string', + optional: false, nullable: false, + format: 'date-time', + }, + updatedAt: { + type: 'string', + optional: false, nullable: true, + format: 'date-time', + }, + name: { + type: 'string', + optional: false, nullable: false, + }, + description: { + type: 'string', + optional: false, nullable: false, + }, + url: { + type: 'string', + optional: false, nullable: false, + }, + roleIdsThatCanBeUsedThisDecoration: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + }, + }, + }, } as const; export const paramDef = { @@ -32,14 +76,25 @@ export const paramDef = { export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export constructor( private avatarDecorationService: AvatarDecorationService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { - await this.avatarDecorationService.create({ + const created = await this.avatarDecorationService.create({ name: ps.name, description: ps.description, url: ps.url, roleIdsThatCanBeUsedThisDecoration: ps.roleIdsThatCanBeUsedThisDecoration, }, me); + + return { + id: created.id, + createdAt: this.idService.parse(created.id).date.toISOString(), + updatedAt: null, + name: created.name, + description: created.description, + url: created.url, + roleIdsThatCanBeUsedThisDecoration: created.roleIdsThatCanBeUsedThisDecoration, + }; }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts b/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts index aee90023e1..d785f085ac 100644 --- a/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts @@ -4,10 +4,7 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import type { AnnouncementsRepository, AnnouncementReadsRepository } from '@/models/_.js'; -import type { MiAnnouncement } from '@/models/Announcement.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { QueryService } from '@/core/QueryService.js'; import { DI } from '@/di-symbols.js'; import { IdService } from '@/core/IdService.js'; import { AvatarDecorationService } from '@/core/AvatarDecorationService.js'; diff --git a/packages/frontend/src/pages/avatar-decoration-edit-dialog.vue b/packages/frontend/src/pages/avatar-decoration-edit-dialog.vue new file mode 100644 index 0000000000..a834f1c5fd --- /dev/null +++ b/packages/frontend/src/pages/avatar-decoration-edit-dialog.vue @@ -0,0 +1,220 @@ +<!-- +SPDX-FileCopyrightText: syuilo and misskey-project +SPDX-License-Identifier: AGPL-3.0-only +--> + +<template> +<MkWindow + ref="windowEl" + :initialWidth="400" + :initialHeight="500" + :canResize="true" + @close="windowEl?.close()" + @closed="emit('closed')" +> + <template v-if="avatarDecoration" #header>{{ avatarDecoration.name }}</template> + <template v-else #header>New decoration</template> + + <div style="display: flex; flex-direction: column; min-height: 100%;"> + <MkSpacer :marginMin="20" :marginMax="28" style="flex-grow: 1;"> + <div class="_gaps_m"> + <div :class="$style.preview"> + <div :class="[$style.previewItem, $style.light]"> + <MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="url != '' ? [{ url }] : []" forceShowDecoration/> + </div> + <div :class="[$style.previewItem, $style.dark]"> + <MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="url != '' ? [{ url }] : []" forceShowDecoration/> + </div> + </div> + <MkInput v-model="name"> + <template #label>{{ i18n.ts.name }}</template> + </MkInput> + <MkInput v-model="url"> + <template #label>{{ i18n.ts.imageUrl }}</template> + </MkInput> + <MkTextarea v-model="description"> + <template #label>{{ i18n.ts.description }}</template> + </MkTextarea> + <MkFolder> + <template #label>{{ i18n.ts.availableRoles }}</template> + <template #suffix>{{ rolesThatCanBeUsedThisDecoration.length === 0 ? i18n.ts.all : rolesThatCanBeUsedThisDecoration.length }}</template> + + <div class="_gaps"> + <MkButton rounded @click="addRole"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton> + + <div v-for="role in rolesThatCanBeUsedThisDecoration" :key="role.id" :class="$style.roleItem"> + <MkRolePreview :class="$style.role" :role="role" :forModeration="true" :detailed="false" style="pointer-events: none;"/> + <button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="removeRole(role, $event)"><i class="ti ti-x"></i></button> + <button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ti ti-ban"></i></button> + </div> + </div> + </MkFolder> + <MkButton v-if="avatarDecoration" danger @click="del()"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton> + </div> + </MkSpacer> + <div :class="$style.footer"> + <MkButton primary rounded style="margin: 0 auto;" @click="done"><i class="ti ti-check"></i> {{ props.avatarDecoration ? i18n.ts.update : i18n.ts.create }}</MkButton> + </div> + </div> +</MkWindow> +</template> + +<script lang="ts" setup> +import { computed, watch, ref } from 'vue'; +import * as Misskey from 'misskey-js'; +import MkWindow from '@/components/MkWindow.vue'; +import MkButton from '@/components/MkButton.vue'; +import MkInput from '@/components/MkInput.vue'; +import MkInfo from '@/components/MkInfo.vue'; +import MkFolder from '@/components/MkFolder.vue'; +import * as os from '@/os.js'; +import { misskeyApi } from '@/scripts/misskey-api.js'; +import { i18n } from '@/i18n.js'; +import MkSwitch from '@/components/MkSwitch.vue'; +import MkRolePreview from '@/components/MkRolePreview.vue'; +import MkTextarea from '@/components/MkTextarea.vue'; +import { signinRequired } from '@/account.js'; + +const $i = signinRequired(); + +const props = defineProps<{ + avatarDecoration?: any, +}>(); + +const emit = defineEmits<{ + (ev: 'done', v: { deleted?: boolean; updated?: any; created?: any }): void, + (ev: 'closed'): void +}>(); + +const windowEl = ref<InstanceType<typeof MkWindow> | null>(null); +const url = ref<string>(props.avatarDecoration ? props.avatarDecoration.url : ''); +const name = ref<string>(props.avatarDecoration ? props.avatarDecoration.name : ''); +const description = ref<string>(props.avatarDecoration ? props.avatarDecoration.description : ''); +const roleIdsThatCanBeUsedThisDecoration = ref(props.avatarDecoration ? props.avatarDecoration.roleIdsThatCanBeUsedThisDecoration : []); +const rolesThatCanBeUsedThisDecoration = ref<Misskey.entities.Role[]>([]); + +watch(roleIdsThatCanBeUsedThisDecoration, async () => { + rolesThatCanBeUsedThisDecoration.value = (await Promise.all(roleIdsThatCanBeUsedThisDecoration.value.map((id) => misskeyApi('admin/roles/show', { roleId: id }).catch(() => null)))).filter(x => x != null); +}, { immediate: true }); + +async function addRole() { + const roles = await misskeyApi('admin/roles/list'); + const currentRoleIds = rolesThatCanBeUsedThisDecoration.value.map(x => x.id); + + const { canceled, result: role } = await os.select({ + items: roles.filter(r => r.isPublic).filter(r => !currentRoleIds.includes(r.id)).map(r => ({ text: r.name, value: r })), + }); + if (canceled || role == null) return; + + rolesThatCanBeUsedThisDecoration.value.push(role); +} + +async function removeRole(role, ev) { + rolesThatCanBeUsedThisDecoration.value = rolesThatCanBeUsedThisDecoration.value.filter(x => x.id !== role.id); +} + +async function done() { + const params = { + url: url.value, + name: name.value, + description: description.value, + roleIdsThatCanBeUsedThisDecoration: rolesThatCanBeUsedThisDecoration.value.map(x => x.id), + }; + + if (props.avatarDecoration) { + await os.apiWithDialog('admin/avatar-decorations/update', { + id: props.avatarDecoration.id, + ...params, + }); + + emit('done', { + updated: { + id: props.avatarDecoration.id, + ...params, + }, + }); + + windowEl.value?.close(); + } else { + const created = await os.apiWithDialog('admin/avatar-decorations/create', params); + + emit('done', { + created: created, + }); + + windowEl.value?.close(); + } +} + +async function del() { + const { canceled } = await os.confirm({ + type: 'warning', + text: i18n.tsx.removeAreYouSure({ x: name.value }), + }); + if (canceled) return; + + misskeyApi('admin/avatar-decorations/delete', { + id: props.avatarDecoration.id, + }).then(() => { + emit('done', { + deleted: true, + }); + windowEl.value?.close(); + }); +} +</script> + +<style lang="scss" module> +.preview { + display: grid; + place-items: center; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr; + gap: var(--MI-margin); +} + +.previewItem { + width: 100%; + height: 100%; + min-height: 160px; + display: flex; + align-items: center; + justify-content: center; + border-radius: var(--MI-radius); + + &.light { + background: #eee; + } + + &.dark { + background: #222; + } +} + +.roleItem { + display: flex; +} + +.role { + flex: 1; +} + +.roleUnassign { + width: 32px; + height: 32px; + margin-left: 8px; + align-self: center; +} + +.footer { + position: sticky; + z-index: 10000; + bottom: 0; + left: 0; + padding: 12px; + border-top: solid 0.5px var(--MI_THEME-divider); + background: var(--MI_THEME-acrylicBg); + -webkit-backdrop-filter: var(--MI-blur, blur(15px)); + backdrop-filter: var(--MI-blur, blur(15px)); +} +</style> diff --git a/packages/frontend/src/pages/avatar-decorations.vue b/packages/frontend/src/pages/avatar-decorations.vue index b97e7c0eea..a5cafb1678 100644 --- a/packages/frontend/src/pages/avatar-decorations.vue +++ b/packages/frontend/src/pages/avatar-decorations.vue @@ -5,92 +5,38 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <MkStickyContainer> - <template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template> + <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> <MkSpacer :contentMax="900"> <div class="_gaps"> - <MkFolder v-for="avatarDecoration in avatarDecorations" :key="avatarDecoration.id ?? avatarDecoration._id" :defaultOpen="avatarDecoration.id == null"> - <template #label>{{ avatarDecoration.name }}</template> - <template #caption>{{ avatarDecoration.description }}</template> - - <div :class="$style.editorRoot"> - <div :class="$style.editorWrapper"> - <div :class="$style.preview"> - <div :class="[$style.previewItem, $style.light]"> - <MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[avatarDecoration]" forceShowDecoration/> - </div> - <div :class="[$style.previewItem, $style.dark]"> - <MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[avatarDecoration]" forceShowDecoration/> - </div> - </div> - <div class="_gaps_m"> - <MkInput v-model="avatarDecoration.name"> - <template #label>{{ i18n.ts.name }}</template> - </MkInput> - <MkTextarea v-model="avatarDecoration.description"> - <template #label>{{ i18n.ts.description }}</template> - </MkTextarea> - <MkInput v-model="avatarDecoration.url"> - <template #label>{{ i18n.ts.imageUrl }}</template> - </MkInput> - <div class="_buttons"> - <MkButton inline primary @click="save(avatarDecoration)"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton> - <MkButton v-if="avatarDecoration.id != null" inline danger @click="del(avatarDecoration)"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton> - </div> - </div> - </div> + <div :class="$style.decorations"> + <div + v-for="avatarDecoration in avatarDecorations" + :key="avatarDecoration.id" + v-panel + :class="$style.decoration" + @click="edit(avatarDecoration)" + > + <div :class="$style.decorationName"><MkCondensedLine :minScale="0.5">{{ avatarDecoration.name }}</MkCondensedLine></div> + <MkAvatar style="width: 60px; height: 60px;" :user="$i" :decorations="[{ url: avatarDecoration.url }]" forceShowDecoration/> </div> - </MkFolder> + </div> </div> </MkSpacer> </MkStickyContainer> </template> <script lang="ts" setup> -import { ref, computed } from 'vue'; +import { ref, computed, defineAsyncComponent } from 'vue'; import * as Misskey from 'misskey-js'; -import MkButton from '@/components/MkButton.vue'; -import MkInput from '@/components/MkInput.vue'; -import MkTextarea from '@/components/MkTextarea.vue'; import { signinRequired } from '@/account.js'; import * as os from '@/os.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; -import MkFolder from '@/components/MkFolder.vue'; - -const avatarDecorations = ref<Misskey.entities.AdminAvatarDecorationsListResponse>([]); const $i = signinRequired(); -function add() { - avatarDecorations.value.unshift({ - _id: Math.random().toString(36), - id: null, - name: '', - description: '', - url: '', - }); -} - -function del(avatarDecoration) { - os.confirm({ - type: 'warning', - text: i18n.tsx.deleteAreYouSure({ x: avatarDecoration.name }), - }).then(({ canceled }) => { - if (canceled) return; - avatarDecorations.value = avatarDecorations.value.filter(x => x !== avatarDecoration); - misskeyApi('admin/avatar-decorations/delete', avatarDecoration); - }); -} - -async function save(avatarDecoration) { - if (avatarDecoration.id == null) { - await os.apiWithDialog('admin/avatar-decorations/create', avatarDecoration); - load(); - } else { - os.apiWithDialog('admin/avatar-decorations/update', avatarDecoration); - } -} +const avatarDecorations = ref<Misskey.entities.AdminAvatarDecorationsListResponse>([]); function load() { misskeyApi('admin/avatar-decorations/list').then(_avatarDecorations => { @@ -100,6 +46,37 @@ function load() { load(); +async function add(ev: MouseEvent) { + const { dispose } = os.popup(defineAsyncComponent(() => import('./avatar-decoration-edit-dialog.vue')), { + }, { + done: result => { + if (result.created) { + avatarDecorations.value.unshift(result.created); + } + }, + closed: () => dispose(), + }); +} + +function edit(avatarDecoration) { + const { dispose } = os.popup(defineAsyncComponent(() => import('./avatar-decoration-edit-dialog.vue')), { + avatarDecoration: avatarDecoration, + }, { + done: result => { + if (result.updated) { + const index = avatarDecorations.value.findIndex(x => x.id === avatarDecoration.id); + avatarDecorations.value[index] = { + ...avatarDecorations.value[index], + ...result.updated, + }; + } else if (result.deleted) { + avatarDecorations.value = avatarDecorations.value.filter(x => x.id !== avatarDecoration.id); + } + }, + closed: () => dispose(), + }); +} + const headerActions = computed(() => [{ asFullButton: true, icon: 'ti ti-plus', @@ -116,53 +93,26 @@ definePageMetadata(() => ({ </script> <style lang="scss" module> -.editorRoot { - container: editor / inline-size; -} - -.editorWrapper { +.decorations { display: grid; - grid-template-columns: 1fr; - grid-template-rows: auto auto; - gap: var(--MI-margin); + grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); + grid-gap: 12px; } -.preview { - display: grid; - place-items: center; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr; - gap: var(--MI-margin); -} - -.previewItem { - width: 100%; - height: 100%; - min-height: 160px; - display: flex; - align-items: center; - justify-content: center; - border-radius: var(--MI-radius); - - &.light { - background: #eee; - } - - &.dark { - background: #222; - } +.decoration { + cursor: pointer; + padding: 16px 16px 28px 16px; + border-radius: 8px; + text-align: center; + font-size: 90%; + overflow: clip; + contain: content; } -@container editor (min-width: 600px) { - .editorWrapper { - grid-template-columns: 200px 1fr; - grid-template-rows: 1fr; - gap: calc(var(--MI-margin) * 2); - } - - .preview { - grid-template-columns: 1fr; - grid-template-rows: 1fr 1fr; - } +.decorationName { + position: relative; + z-index: 10; + font-weight: bold; + margin-bottom: 20px; } </style> diff --git a/packages/frontend/src/pages/emoji-edit-dialog.vue b/packages/frontend/src/pages/emoji-edit-dialog.vue index 969aa6bbf7..3b3f41d9b1 100644 --- a/packages/frontend/src/pages/emoji-edit-dialog.vue +++ b/packages/frontend/src/pages/emoji-edit-dialog.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only ref="windowEl" :initialWidth="400" :initialHeight="500" - :canResize="false" + :canResize="true" @close="windowEl.close()" @closed="$emit('closed')" > diff --git a/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue b/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue index f72a0b9383..3c9914b4e2 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue @@ -10,12 +10,12 @@ SPDX-License-Identifier: AGPL-3.0-only > <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/> - <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="locked" :class="$style.lock" class="ti ti-lock"></i> </div> </template> <script lang="ts" setup> -import { } from 'vue'; +import { computed } from 'vue'; import { signinRequired } from '@/account.js'; const $i = signinRequired(); @@ -37,6 +37,8 @@ const props = defineProps<{ const emit = defineEmits<{ (ev: 'click'): void; }>(); + +const locked = computed(() => props.decoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => props.decoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))); </script> <style lang="scss" module> @@ -67,5 +69,6 @@ const emit = defineEmits<{ position: absolute; bottom: 12px; right: 12px; + color: var(--MI_THEME-warn); } </style> diff --git a/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue b/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue index 853e536ea3..aa899ac649 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue @@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.footer" class="_buttonsCenter"> <MkButton v-if="usingIndex != null" primary rounded @click="update"><i class="ti ti-check"></i> {{ i18n.ts.update }}</MkButton> <MkButton v-if="usingIndex != null" rounded @click="detach"><i class="ti ti-x"></i> {{ i18n.ts.detach }}</MkButton> - <MkButton v-else :disabled="exceeded" primary rounded @click="attach"><i class="ti ti-check"></i> {{ i18n.ts.attach }}</MkButton> + <MkButton v-else :disabled="exceeded || locked" primary rounded @click="attach"><i class="ti ti-check"></i> {{ i18n.ts.attach }}</MkButton> </div> </div> </MkModalWindow> @@ -61,6 +61,7 @@ const props = defineProps<{ id: string; url: string; name: string; + roleIdsThatCanBeUsedThisDecoration: string[]; }; }>(); @@ -83,6 +84,7 @@ const emit = defineEmits<{ const dialog = shallowRef<InstanceType<typeof MkModalWindow>>(); const exceeded = computed(() => ($i.policies.avatarDecorationLimit - $i.avatarDecorations.length) <= 0); +const locked = computed(() => props.decoration.roleIdsThatCanBeUsedThisDecoration.length > 0 && !$i.roles.some(r => props.decoration.roleIdsThatCanBeUsedThisDecoration.includes(r.id))); 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 offsetX = ref((props.usingIndex != null ? $i.avatarDecorations[props.usingIndex].offsetX : null) ?? 0); diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index 61de8b8c7e..061b533b72 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -122,6 +122,9 @@ type AdminAnnouncementsUpdateRequest = operations['admin___announcements___updat type AdminAvatarDecorationsCreateRequest = operations['admin___avatar-decorations___create']['requestBody']['content']['application/json']; // @public (undocumented) +type AdminAvatarDecorationsCreateResponse = operations['admin___avatar-decorations___create']['responses']['200']['content']['application/json']; + +// @public (undocumented) type AdminAvatarDecorationsDeleteRequest = operations['admin___avatar-decorations___delete']['requestBody']['content']['application/json']; // @public (undocumented) @@ -1253,6 +1256,7 @@ declare namespace entities { AdminAnnouncementsListResponse, AdminAnnouncementsUpdateRequest, AdminAvatarDecorationsCreateRequest, + AdminAvatarDecorationsCreateResponse, AdminAvatarDecorationsDeleteRequest, AdminAvatarDecorationsListRequest, AdminAvatarDecorationsListResponse, diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index d0367d8496..5e6bc0a99c 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -31,6 +31,7 @@ import type { AdminAnnouncementsListResponse, AdminAnnouncementsUpdateRequest, AdminAvatarDecorationsCreateRequest, + AdminAvatarDecorationsCreateResponse, AdminAvatarDecorationsDeleteRequest, AdminAvatarDecorationsListRequest, AdminAvatarDecorationsListResponse, @@ -597,7 +598,7 @@ export type Endpoints = { 'admin/announcements/delete': { req: AdminAnnouncementsDeleteRequest; res: EmptyResponse }; 'admin/announcements/list': { req: AdminAnnouncementsListRequest; res: AdminAnnouncementsListResponse }; 'admin/announcements/update': { req: AdminAnnouncementsUpdateRequest; res: EmptyResponse }; - 'admin/avatar-decorations/create': { req: AdminAvatarDecorationsCreateRequest; res: EmptyResponse }; + 'admin/avatar-decorations/create': { req: AdminAvatarDecorationsCreateRequest; res: AdminAvatarDecorationsCreateResponse }; 'admin/avatar-decorations/delete': { req: AdminAvatarDecorationsDeleteRequest; res: EmptyResponse }; 'admin/avatar-decorations/list': { req: AdminAvatarDecorationsListRequest; res: AdminAvatarDecorationsListResponse }; 'admin/avatar-decorations/update': { req: AdminAvatarDecorationsUpdateRequest; res: EmptyResponse }; diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index ced87c4c7e..f3ddf64481 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -34,6 +34,7 @@ export type AdminAnnouncementsListRequest = operations['admin___announcements___ export type AdminAnnouncementsListResponse = operations['admin___announcements___list']['responses']['200']['content']['application/json']; export type AdminAnnouncementsUpdateRequest = operations['admin___announcements___update']['requestBody']['content']['application/json']; export type AdminAvatarDecorationsCreateRequest = operations['admin___avatar-decorations___create']['requestBody']['content']['application/json']; +export type AdminAvatarDecorationsCreateResponse = operations['admin___avatar-decorations___create']['responses']['200']['content']['application/json']; export type AdminAvatarDecorationsDeleteRequest = operations['admin___avatar-decorations___delete']['requestBody']['content']['application/json']; export type AdminAvatarDecorationsListRequest = operations['admin___avatar-decorations___list']['requestBody']['content']['application/json']; export type AdminAvatarDecorationsListResponse = operations['admin___avatar-decorations___list']['responses']['200']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 560960f018..a5333d4f93 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -6324,9 +6324,22 @@ export type operations = { }; }; responses: { - /** @description OK (without any results) */ - 204: { - content: never; + /** @description OK (with results) */ + 200: { + content: { + 'application/json': { + /** Format: id */ + id: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string | null; + name: string; + description: string; + url: string; + roleIdsThatCanBeUsedThisDecoration: string[]; + }; + }; }; /** @description Client error */ 400: { |