This commit is contained in:
samunohito 2024-01-20 17:01:45 +09:00
parent 0283142d0e
commit 5012cff445
14 changed files with 223 additions and 18 deletions

View File

@ -25,10 +25,19 @@ export const meta = {
type: 'array',
optional: false, nullable: false,
items: {
anyOf: [
{
type: 'object',
optional: false, nullable: false,
ref: 'EmojiSimple',
},
{
type: 'object',
optional: false, nullable: false,
ref: 'EmojiDetailed',
},
],
},
},
},
},
@ -37,6 +46,10 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
detail: {
type: 'boolean',
nullable: true,
},
},
required: [],
} as const;
@ -61,7 +74,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
});
return {
emojis: await this.emojiEntityService.packSimpleMany(emojis),
emojis: ps.detail
? await this.emojiEntityService.packDetailedMany(emojis)
: await this.emojiEntityService.packSimpleMany(emojis),
};
});
}

View File

@ -20,7 +20,7 @@
"@discordapp/twemoji": "15.0.2",
"@github/webauthn-json": "2.1.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@misskey-dev/browser-image-resizer": "2.2.1-misskey.10",
"@misskey-dev/browser-image-resizer": "workspace:*",
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-replace": "5.0.5",
"@rollup/pluginutils": "5.1.0",
@ -96,6 +96,7 @@
"@storybook/vue3": "7.6.5",
"@storybook/vue3-vite": "7.6.5",
"@testing-library/vue": "8.0.1",
"@types/blueimp-load-image": "^5.16.6",
"@types/escape-regexp": "0.0.3",
"@types/estree": "1.0.5",
"@types/matter-js": "0.19.5",
@ -112,6 +113,9 @@
"@vitest/coverage-v8": "0.34.6",
"@vue/runtime-core": "3.4.3",
"acorn": "8.11.2",
"ag-grid-community": "^31.0.2",
"ag-grid-vue3": "^31.0.2",
"blueimp-load-image": "^5.16.0",
"cross-env": "7.0.3",
"cypress": "13.6.1",
"eslint": "8.56.0",

View File

@ -18,6 +18,10 @@ const page = (loader: AsyncComponentLoader<any>) => defineAsyncComponent({
const routes = [{
path: '/@:initUser/pages/:initPageName/view-source',
component: page(() => import('@/pages/page-editor/page-editor.vue')),
}, {
path: '/emojis2',
name: 'emojis2',
component: page(() => import('@/pages/admin/custom-emojis-grid.vue')),
}, {
path: '/@:username/pages/:pageName',
component: page(() => import('@/pages/page.vue')),
@ -355,6 +359,10 @@ const routes = [{
path: '/emojis',
name: 'emojis',
component: page(() => import('@/pages/custom-emojis-manager.vue')),
}, {
path: '/emojis2',
name: 'emojis2',
component: page(() => import('@/pages/admin/custom-emojis-grid.vue')),
}, {
path: '/avatar-decorations',
name: 'avatarDecorations',

View File

@ -371,10 +371,7 @@ onBeforeUnmount(() => {
}
});
const headerActions = computed(() => []);
const headerTabs = computed(() => []);
ex;
definePageMetadata({
title: i18n.ts.aboutMisskey,
icon: null,

View File

@ -0,0 +1,29 @@
<template>
<div :class="$style.root">
<img :src="emojiUrl" :alt="emojiName"/>
</div>
</template>
<script setup lang="ts">
import { CellClassParams } from 'ag-grid-community';
import { computed } from 'vue';
import { GridItem } from '@/pages/admin/custom-emojis-grid.impl.js';
const props = defineProps<{
params: CellClassParams<GridItem, string>
}>();
const emojiUrl = computed(() => props.params.data?.url);
const emojiName = computed(() => props.params.data?.name);
console.log({ url: emojiUrl.value, name: emojiName.value });
</script>
<style lang="scss" module>
.root {
display: inline-flex;
align-items: stretch;
}
</style>

View File

@ -0,0 +1,11 @@
export type GridItem = {
id?: string;
aliases: string;
name: string;
category: string;
license: string;
isSensitive: boolean;
localOnly: boolean;
roleIdsThatCanBeUsedThisEmojiAsReaction: string;
url: string;
};

View File

@ -0,0 +1,90 @@
<template>
<div>
<MkStickyContainer>
<template #header>
<MkPageHeader/>
</template>
<MkSpacer :contentMax="900">
<div class="_gaps">
<AgGridVue
:rowData="gridItems"
:columnDefs="colDefs"
style="height: 500px"
class="ag-theme-quartz"
>
</AgGridVue>
</div>
</MkSpacer>
</MkStickyContainer>
</div>
</template>
<script lang="ts">
import { markRaw, onMounted, ref, watch } from 'vue';
import 'ag-grid-community/styles/ag-grid.css'; // Core CSS
import * as Misskey from 'misskey-js';
import { AgGridVue } from 'ag-grid-vue3';
import { ColDef } from 'ag-grid-community';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { GridItem } from '@/pages/admin/custom-emojis-grid.impl.js';
import CustomEmojiGridItem from '@/pages/admin/custom-emojis-grid-item.vue';
// eslint-disable-next-line import/no-default-export
export default {
components: {
AgGridVue,
// eslint-disable-next-line vue/no-unused-components
CustomEmojiGridItem,
},
setup() {
const colDefs = markRaw<ColDef[]>([
{ field: 'img', cellRenderer: CustomEmojiGridItem },
{ field: 'name' },
{ field: 'category' },
{ field: 'aliases' },
{ field: 'license' },
{ field: 'isSensitive' },
{ field: 'localOnly' },
{ field: 'roleIdsThatCanBeUsedThisEmojiAsReaction' },
]);
const customEmojis = ref<Misskey.entities.EmojiDetailed[]>([]);
const gridItems = ref<GridItem[]>([]);
const refreshCustomEmojis = async () => {
customEmojis.value = await misskeyApi('emojis', { detail: true }).then(it => it.emojis);
};
const refreshGridItems = () => {
gridItems.value = customEmojis.value.map(it => ({
id: it.id,
aliases: it.aliases.join(', '),
name: it.name,
category: it.category ?? '',
license: it.license ?? '',
isSensitive: it.isSensitive,
localOnly: it.localOnly,
roleIdsThatCanBeUsedThisEmojiAsReaction: it.roleIdsThatCanBeUsedThisEmojiAsReaction.join(', '),
url: it.url,
}));
};
watch(customEmojis, refreshGridItems);
onMounted(async () => {
await refreshCustomEmojis();
refreshGridItems();
});
return {
colDefs,
customEmojis,
gridItems,
};
},
};
</script>
<style scoped lang="scss">
</style>

View File

@ -1005,6 +1005,9 @@ type EmojiResponse = operations['emoji']['responses']['200']['content']['applica
// @public (undocumented)
type EmojiSimple = components['schemas']['EmojiSimple'];
// @public (undocumented)
type EmojisRequest = operations['emojis']['requestBody']['content']['application/json'];
// @public (undocumented)
type EmojisResponse = operations['emojis']['responses']['200']['content']['application/json'];
@ -1046,6 +1049,26 @@ export type Endpoints = Overwrite<Endpoints_2, {
};
};
};
'emojis': {
req: EmojisRequest;
res: {
$switch: {
$cases: [
[
{
detail: true;
},
{
emojis: EmojiDetailed[];
}
]
];
$default: {
emojis: EmojiSimple[];
};
};
};
};
'signup': {
req: SignupRequest;
res: SignupResponse;
@ -1445,6 +1468,7 @@ declare namespace entities {
InviteLimitResponse,
MetaRequest,
MetaResponse,
EmojisRequest,
EmojisResponse,
EmojiRequest,
EmojiResponse,

View File

@ -1,6 +1,6 @@
import { Endpoints as Gen } from './autogen/endpoint';
import { UserDetailed } from './autogen/models';
import { UsersShowRequest } from './autogen/entities';
import { EmojiDetailed, EmojiSimple, UserDetailed } from './autogen/models';
import { EmojisRequest, UsersShowRequest } from './autogen/entities';
import {
SigninRequest,
SigninResponse,
@ -64,6 +64,24 @@ export type Endpoints = Overwrite<
};
};
},
'emojis': {
req: EmojisRequest;
res: {
$switch: {
$cases: [[
{
detail: true;
},
{
emojis: EmojiDetailed[]
}
]];
$default: {
emojis: EmojiSimple[]
}
};
}
},
// api.jsonには載せないものなのでここで定義
'signup': {
req: SignupRequest;

View File

@ -1,6 +1,6 @@
/*
* version: 2023.12.2
* generatedAt: 2024-01-13T04:31:38.782Z
* generatedAt: 2024-01-20T01:07:44.539Z
*/
import type { SwitchCaseResponseType } from '../api.js';

View File

@ -1,6 +1,6 @@
/*
* version: 2023.12.2
* generatedAt: 2024-01-13T04:31:38.778Z
* generatedAt: 2024-01-20T01:07:44.537Z
*/
import type {
@ -366,6 +366,7 @@ import type {
InviteLimitResponse,
MetaRequest,
MetaResponse,
EmojisRequest,
EmojisResponse,
EmojiRequest,
EmojiResponse,
@ -793,7 +794,7 @@ export type Endpoints = {
'invite/list': { req: InviteListRequest; res: InviteListResponse };
'invite/limit': { req: EmptyRequest; res: InviteLimitResponse };
'meta': { req: MetaRequest; res: MetaResponse };
'emojis': { req: EmptyRequest; res: EmojisResponse };
'emojis': { req: EmojisRequest; res: EmojisResponse };
'emoji': { req: EmojiRequest; res: EmojiResponse };
'miauth/gen-token': { req: MiauthGenTokenRequest; res: MiauthGenTokenResponse };
'mute/create': { req: MuteCreateRequest; res: EmptyResponse };

View File

@ -1,6 +1,6 @@
/*
* version: 2023.12.2
* generatedAt: 2024-01-13T04:31:38.775Z
* generatedAt: 2024-01-20T01:07:44.535Z
*/
import { operations } from './types.js';
@ -368,6 +368,7 @@ export type InviteListResponse = operations['invite/list']['responses']['200']['
export type InviteLimitResponse = operations['invite/limit']['responses']['200']['content']['application/json'];
export type MetaRequest = operations['meta']['requestBody']['content']['application/json'];
export type MetaResponse = operations['meta']['responses']['200']['content']['application/json'];
export type EmojisRequest = operations['emojis']['requestBody']['content']['application/json'];
export type EmojisResponse = operations['emojis']['responses']['200']['content']['application/json'];
export type EmojiRequest = operations['emoji']['requestBody']['content']['application/json'];
export type EmojiResponse = operations['emoji']['responses']['200']['content']['application/json'];

View File

@ -1,6 +1,6 @@
/*
* version: 2023.12.2
* generatedAt: 2024-01-13T04:31:38.773Z
* generatedAt: 2024-01-20T01:07:44.534Z
*/
import { components } from './types.js';

View File

@ -3,7 +3,7 @@
/*
* version: 2023.12.2
* generatedAt: 2024-01-13T04:31:38.633Z
* generatedAt: 2024-01-20T01:07:44.458Z
*/
/**
@ -18896,12 +18896,19 @@ export type operations = {
* **Credential required**: *No*
*/
emojis: {
requestBody: {
content: {
'application/json': {
detail?: boolean | null;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': {
emojis: components['schemas']['EmojiSimple'][];
emojis: (components['schemas']['EmojiSimple'] | components['schemas']['EmojiDetailed'])[];
};
};
};