多分動くと思うからリリースしようぜ
This commit is contained in:
parent
68b48bc16f
commit
2a9ddf2bc8
|
@ -1076,11 +1076,11 @@ export interface Locale {
|
||||||
"hiddenTagsDescription": string;
|
"hiddenTagsDescription": string;
|
||||||
"notesSearchNotAvailable": string;
|
"notesSearchNotAvailable": string;
|
||||||
"license": string;
|
"license": string;
|
||||||
"draft": string;
|
|
||||||
"undrafted": string;
|
|
||||||
"requestPending": string;
|
"requestPending": string;
|
||||||
"approval": string;
|
"approval": string;
|
||||||
"requestingEmojis": string;
|
"requestingEmojis": string;
|
||||||
|
"draft": string;
|
||||||
|
"undrafted": string;
|
||||||
"unfavoriteConfirm": string;
|
"unfavoriteConfirm": string;
|
||||||
"myClips": string;
|
"myClips": string;
|
||||||
"drivecleaner": string;
|
"drivecleaner": string;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "2023.12.0",
|
"version": "2023.12.0-PrisMisskey.1",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
export class Requestemoji1703294653915 {
|
||||||
|
name = 'Requestemoji1703294653915'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" ADD "requestEmojiAllOk" boolean NOT NULL DEFAULT false`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "requestEmojiAllOk"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -549,4 +549,9 @@ export class MiMeta {
|
||||||
default: 0,
|
default: 0,
|
||||||
})
|
})
|
||||||
public notesPerOneAd: number;
|
public notesPerOneAd: number;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public requestEmojiAllOk: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
|
||||||
import type { DriveFilesRepository } from '@/models/_.js';
|
|
||||||
import { DI } from '@/di-symbols.js';
|
|
||||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
|
||||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
|
||||||
import { ApiError } from '../../../error.js';
|
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
|
||||||
import {DriveService} from "@/core/DriveService.js";
|
|
||||||
export const meta = {
|
|
||||||
tags: ['admin'],
|
|
||||||
|
|
||||||
requireCredential: true,
|
|
||||||
requireRolePolicy: 'canRequestCustomEmojis',
|
|
||||||
|
|
||||||
errors: {
|
|
||||||
noSuchFile: {
|
|
||||||
message: 'No such file.',
|
|
||||||
code: 'NO_SUCH_FILE',
|
|
||||||
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const paramDef = {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' },
|
|
||||||
category: {
|
|
||||||
type: 'string',
|
|
||||||
nullable: true,
|
|
||||||
description: 'Use `null` to reset the category.',
|
|
||||||
},
|
|
||||||
aliases: { type: 'array', items: {
|
|
||||||
type: 'string',
|
|
||||||
} },
|
|
||||||
license: { type: 'string', nullable: true },
|
|
||||||
fileId: { type: 'string', format: 'misskey:id' },
|
|
||||||
isSensitive: { type: 'boolean' },
|
|
||||||
localOnly: { type: 'boolean' },
|
|
||||||
isNotifyIsHome: { type: 'boolean', default: false },
|
|
||||||
},
|
|
||||||
required: ['name', 'fileId'],
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
// TODO: ロジックをサービスに切り出す
|
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
|
||||||
@Injectable()
|
|
||||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@Inject(DI.driveFilesRepository)
|
|
||||||
private driveFilesRepository: DriveFilesRepository,
|
|
||||||
private metaService: MetaService,
|
|
||||||
private customEmojiService: CustomEmojiService,
|
|
||||||
private moderationLogService: ModerationLogService,
|
|
||||||
private driveService: DriveService,
|
|
||||||
) {
|
|
||||||
super(meta, paramDef, async (ps, me) => {
|
|
||||||
let driveFile;
|
|
||||||
let tmp = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
|
|
||||||
if (tmp == null) throw new ApiError(meta.errors.noSuchFile);
|
|
||||||
|
|
||||||
try {
|
|
||||||
driveFile = await this.driveService.uploadFromUrl({ url: tmp.url , user: null, force: true });
|
|
||||||
} catch (e) {
|
|
||||||
throw new ApiError();
|
|
||||||
}
|
|
||||||
|
|
||||||
const emoji = await this.customEmojiService.add({
|
|
||||||
driveFile,
|
|
||||||
name: ps.name,
|
|
||||||
category: ps.category ?? null,
|
|
||||||
aliases: ps.aliases ?? [],
|
|
||||||
license: ps.license ?? null,
|
|
||||||
host: null,
|
|
||||||
draft: false,
|
|
||||||
isSensitive: ps.isSensitive ?? false,
|
|
||||||
localOnly: ps.localOnly ?? false,
|
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: [],
|
|
||||||
});
|
|
||||||
const {ApiBase,EmojiBotToken,DiscordWebhookUrl} = (await this.metaService.fetch())
|
|
||||||
|
|
||||||
if (EmojiBotToken){
|
|
||||||
const data_Miss = {
|
|
||||||
'i': EmojiBotToken,
|
|
||||||
'visibility': ps.isNotifyIsHome ? 'home' : 'public',
|
|
||||||
'text':
|
|
||||||
'絵文字名 : :' + ps.name + ':\n' +
|
|
||||||
'カテゴリ : ' + ps.category + '\n' +
|
|
||||||
'ライセンス : ' + ps.license + '\n' +
|
|
||||||
'タグ : ' + ps.aliases + '\n' +
|
|
||||||
'追加したユーザー : ' + '@' + me.username + '\n'
|
|
||||||
};
|
|
||||||
await fetch(ApiBase+'/notes/create', {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body:JSON.stringify( data_Miss)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DiscordWebhookUrl){
|
|
||||||
const data_disc = {"username": "絵文字追加通知ちゃん",
|
|
||||||
'content':
|
|
||||||
'絵文字名 : :'+ ps.name +':\n' +
|
|
||||||
'カテゴリ : ' + ps.category + '\n'+
|
|
||||||
'ライセンス : '+ ps.license + '\n'+
|
|
||||||
'タグ : '+ps.aliases+ '\n'+
|
|
||||||
'追加したユーザー : ' + '@'+me.username + '\n'
|
|
||||||
}
|
|
||||||
await fetch(DiscordWebhookUrl, {
|
|
||||||
'method':'post',
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data_disc),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: emoji.id,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,6 +5,8 @@ import { DI } from '@/di-symbols.js';
|
||||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||||
import { ApiError } from '../../../error.js';
|
import { ApiError } from '../../../error.js';
|
||||||
|
import {MetaService} from "@/core/MetaService.js";
|
||||||
|
import {DriveService} from "@/core/DriveService.js";
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
@ -54,9 +56,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.driveFilesRepository)
|
@Inject(DI.driveFilesRepository)
|
||||||
private driveFilesRepository: DriveFilesRepository,
|
private driveFilesRepository: DriveFilesRepository,
|
||||||
|
private metaService: MetaService,
|
||||||
private customEmojiService: CustomEmojiService,
|
private customEmojiService: CustomEmojiService,
|
||||||
|
private driveService: DriveService,
|
||||||
private moderationLogService: ModerationLogService,
|
private moderationLogService: ModerationLogService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
@ -64,25 +66,81 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
const isRequestDuplicate = await this.customEmojiService.checkRequestDuplicate(ps.name);
|
const isRequestDuplicate = await this.customEmojiService.checkRequestDuplicate(ps.name);
|
||||||
|
|
||||||
if (isDuplicate || isRequestDuplicate) throw new ApiError(meta.errors.duplicateName);
|
if (isDuplicate || isRequestDuplicate) throw new ApiError(meta.errors.duplicateName);
|
||||||
const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
|
let driveFile;
|
||||||
|
driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
|
||||||
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
|
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
|
||||||
|
|
||||||
const emoji = await this.customEmojiService.request({
|
if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
|
||||||
driveFile,
|
const {ApiBase,EmojiBotToken,DiscordWebhookUrl,requestEmojiAllOk} = (await this.metaService.fetch())
|
||||||
name: ps.name,
|
let emoji;
|
||||||
category: ps.category ?? null,
|
if (requestEmojiAllOk){
|
||||||
aliases: ps.aliases ?? [],
|
emoji = await this.customEmojiService.add({
|
||||||
license: ps.license ?? null,
|
driveFile,
|
||||||
isSensitive: ps.isSensitive ?? false,
|
name: ps.name,
|
||||||
localOnly: ps.localOnly ?? false,
|
category: ps.category ?? null,
|
||||||
});
|
aliases: ps.aliases ?? [],
|
||||||
|
license: ps.license ?? null,
|
||||||
|
host: null,
|
||||||
|
draft: false,
|
||||||
|
isSensitive: ps.isSensitive ?? false,
|
||||||
|
localOnly: ps.localOnly ?? false,
|
||||||
|
roleIdsThatCanBeUsedThisEmojiAsReaction: [],
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
emoji = await this.customEmojiService.request({
|
||||||
|
driveFile,
|
||||||
|
name: ps.name,
|
||||||
|
category: ps.category ?? null,
|
||||||
|
aliases: ps.aliases ?? [],
|
||||||
|
license: ps.license ?? null,
|
||||||
|
isSensitive: ps.isSensitive ?? false,
|
||||||
|
localOnly: ps.localOnly ?? false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
await this.moderationLogService.log(me, 'addCustomEmoji', {
|
await this.moderationLogService.log(me, 'addCustomEmoji', {
|
||||||
emojiId: emoji.id,
|
emojiId: emoji.id,
|
||||||
emoji: emoji,
|
emoji: emoji,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (EmojiBotToken){
|
||||||
|
const data_Miss = {
|
||||||
|
'i': EmojiBotToken,
|
||||||
|
'visibility': ps.isNotifyIsHome ? 'home' : 'public',
|
||||||
|
'text':
|
||||||
|
'絵文字名 : :' + ps.name + ':\n' +
|
||||||
|
'カテゴリ : ' + ps.category + '\n' +
|
||||||
|
'ライセンス : ' + ps.license + '\n' +
|
||||||
|
'タグ : ' + ps.aliases + '\n' +
|
||||||
|
'追加したユーザー : ' + '@' + me.username + '\n'
|
||||||
|
};
|
||||||
|
await fetch(ApiBase+'/notes/create', {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body:JSON.stringify( data_Miss)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DiscordWebhookUrl){
|
||||||
|
const data_disc = {"username": "絵文字追加通知ちゃん",
|
||||||
|
'content':
|
||||||
|
'絵文字名 : :'+ ps.name +':\n' +
|
||||||
|
'カテゴリ : ' + ps.category + '\n'+
|
||||||
|
'ライセンス : '+ ps.license + '\n'+
|
||||||
|
'タグ : '+ps.aliases+ '\n'+
|
||||||
|
'追加したユーザー : ' + '@'+me.username + '\n'
|
||||||
|
}
|
||||||
|
await fetch(DiscordWebhookUrl, {
|
||||||
|
'method':'post',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data_disc),
|
||||||
|
})
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
id: emoji.id,
|
id: emoji.id,
|
||||||
};
|
};
|
||||||
|
|
|
@ -455,6 +455,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
turnstileSiteKey: instance.turnstileSiteKey,
|
turnstileSiteKey: instance.turnstileSiteKey,
|
||||||
swPublickey: instance.swPublicKey,
|
swPublickey: instance.swPublicKey,
|
||||||
themeColor: instance.themeColor,
|
themeColor: instance.themeColor,
|
||||||
|
requestEmojiAllOk: instance.requestEmojiAllOk,
|
||||||
mascotImageUrl: instance.mascotImageUrl,
|
mascotImageUrl: instance.mascotImageUrl,
|
||||||
bannerUrl: instance.bannerUrl,
|
bannerUrl: instance.bannerUrl,
|
||||||
serverErrorImageUrl: instance.serverErrorImageUrl,
|
serverErrorImageUrl: instance.serverErrorImageUrl,
|
||||||
|
|
|
@ -103,6 +103,7 @@ export const paramDef = {
|
||||||
privacyPolicyUrl: { type: 'string', nullable: true },
|
privacyPolicyUrl: { type: 'string', nullable: true },
|
||||||
useObjectStorage: { type: 'boolean' },
|
useObjectStorage: { type: 'boolean' },
|
||||||
objectStorageBaseUrl: { type: 'string', nullable: true },
|
objectStorageBaseUrl: { type: 'string', nullable: true },
|
||||||
|
requestEmojiAllOk: { type: 'boolean', nullable: true },
|
||||||
objectStorageBucket: { type: 'string', nullable: true },
|
objectStorageBucket: { type: 'string', nullable: true },
|
||||||
objectStoragePrefix: { type: 'string', nullable: true },
|
objectStoragePrefix: { type: 'string', nullable: true },
|
||||||
objectStorageEndpoint: { type: 'string', nullable: true },
|
objectStorageEndpoint: { type: 'string', nullable: true },
|
||||||
|
@ -221,6 +222,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
set.infoImageUrl = ps.infoImageUrl;
|
set.infoImageUrl = ps.infoImageUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.requestEmojiAllOk !== undefined) {
|
||||||
|
set.requestEmojiAllOk = ps.requestEmojiAllOk;
|
||||||
|
}
|
||||||
if (ps.notFoundImageUrl !== undefined) {
|
if (ps.notFoundImageUrl !== undefined) {
|
||||||
set.notFoundImageUrl = ps.notFoundImageUrl;
|
set.notFoundImageUrl = ps.notFoundImageUrl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,214 +0,0 @@
|
||||||
<template>
|
|
||||||
<MkPagination ref="emojisDraftPaginationComponent" :pagination="paginationDraft">
|
|
||||||
<template #empty><span>{{ i18n.ts.noCustomEmojis }}</span></template>
|
|
||||||
<template #default="{items}">
|
|
||||||
<div class="ldhfsamy">
|
|
||||||
<template v-for="emoji in items" :key="emoji.id">
|
|
||||||
<div class="emoji _panel">
|
|
||||||
<div class="img">
|
|
||||||
<div class="imgLight"><img :src="emoji.url" :alt="emoji.name"/></div>
|
|
||||||
<div class="imgDark"><img :src="emoji.url" :alt="emoji.name"/></div>
|
|
||||||
</div>
|
|
||||||
<div class="info">
|
|
||||||
<div class="name">{{ i18n.ts.name }}: {{ emoji.name }}</div>
|
|
||||||
<div class="category">{{ i18n.ts.category }}:{{ emoji.category }}</div>
|
|
||||||
<div class="aliases">{{ i18n.ts.tags }}:{{ emoji.aliases.join(' ') }}</div>
|
|
||||||
<div class="license">{{ i18n.ts.license }}:{{ emoji.license }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="edit-button">
|
|
||||||
<MkButton primary class="edit" @click="editDraft(emoji)">
|
|
||||||
{{ i18n.ts.edit }}
|
|
||||||
</MkButton>
|
|
||||||
<MkButton class="draft" @click="undrafted(emoji)">
|
|
||||||
{{ i18n.ts.undrafted }}
|
|
||||||
</MkButton>
|
|
||||||
<MkButton danger class="delete" @click="deleteDraft(emoji)">
|
|
||||||
{{ i18n.ts.delete }}
|
|
||||||
</MkButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</MkPagination>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { computed, defineAsyncComponent, ref, shallowRef } from 'vue';
|
|
||||||
import MkPagination from '@/components/MkPagination.vue';
|
|
||||||
import * as os from '@/os';
|
|
||||||
import { i18n } from '@/i18n';
|
|
||||||
import MkButton from '@/components/MkButton.vue';
|
|
||||||
|
|
||||||
const emojisDraftPaginationComponent = shallowRef<InstanceType<typeof MkPagination>>();
|
|
||||||
|
|
||||||
const query = ref(null);
|
|
||||||
|
|
||||||
const paginationDraft = {
|
|
||||||
endpoint: 'admin/emoji/list' as const,
|
|
||||||
limit: 30,
|
|
||||||
params: computed(() => ({
|
|
||||||
query: (query.value && query.value !== '') ? query.value : null,
|
|
||||||
draft: true,
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
|
|
||||||
const editDraft = (emoji) => {
|
|
||||||
os.popup(defineAsyncComponent(() => import('@/components/MkEmojiEditDialog.vue')), {
|
|
||||||
emoji: emoji,
|
|
||||||
isRequest: false,
|
|
||||||
}, {
|
|
||||||
done: result => {
|
|
||||||
if (result.updated) {
|
|
||||||
emojisDraftPaginationComponent.value.updateItem(result.updated.id, (oldEmoji: any) => ({
|
|
||||||
...oldEmoji,
|
|
||||||
...result.updated,
|
|
||||||
}));
|
|
||||||
emojisDraftPaginationComponent.value.reload();
|
|
||||||
} else if (result.deleted) {
|
|
||||||
emojisDraftPaginationComponent.value.removeItem((item) => item.id === emoji.id);
|
|
||||||
emojisDraftPaginationComponent.value.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}, 'closed');
|
|
||||||
};
|
|
||||||
|
|
||||||
async function undrafted(emoji) {
|
|
||||||
const { canceled } = await os.confirm({
|
|
||||||
type: 'warning',
|
|
||||||
text: i18n.t('undraftAreYouSure', { x: emoji.name }),
|
|
||||||
});
|
|
||||||
if (canceled) return;
|
|
||||||
|
|
||||||
await os.api('admin/emoji/update', {
|
|
||||||
id: emoji.id,
|
|
||||||
name: emoji.name,
|
|
||||||
category: emoji.category,
|
|
||||||
aliases: emoji.aliases,
|
|
||||||
license: emoji.license,
|
|
||||||
draft: false,
|
|
||||||
isSensitive: emoji.isSensitive,
|
|
||||||
localOnly: emoji.localOnly,
|
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
|
||||||
});
|
|
||||||
|
|
||||||
emojisDraftPaginationComponent.value.removeItem((item) => item.id === emoji.id);
|
|
||||||
emojisDraftPaginationComponent.value.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteDraft(emoji) {
|
|
||||||
const { canceled } = await os.confirm({
|
|
||||||
type: 'warning',
|
|
||||||
text: i18n.t('removeAreYouSure', { x: emoji.name }),
|
|
||||||
});
|
|
||||||
if (canceled) return;
|
|
||||||
|
|
||||||
os.api('admin/emoji/delete', {
|
|
||||||
id: emoji.id,
|
|
||||||
}).then(() => {
|
|
||||||
emojisDraftPaginationComponent.value.removeItem((item) => item.id === emoji.id);
|
|
||||||
emojisDraftPaginationComponent.value.reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.empty {
|
|
||||||
margin: var(--margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ldhfsamy {
|
|
||||||
> .emoji {
|
|
||||||
align-items: center;
|
|
||||||
padding: 11px;
|
|
||||||
text-align: left;
|
|
||||||
border: solid 1px var(--panel);
|
|
||||||
margin: 10px;
|
|
||||||
|
|
||||||
> .img {
|
|
||||||
display: grid;
|
|
||||||
grid-row: 1;
|
|
||||||
grid-column: 1/ span 2;
|
|
||||||
grid-template-columns: 50% 50%;
|
|
||||||
place-content: center;
|
|
||||||
place-items: center;
|
|
||||||
|
|
||||||
> .imgLight {
|
|
||||||
display: grid;
|
|
||||||
grid-column: 1;
|
|
||||||
background-color: #fff;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
> img {
|
|
||||||
max-height: 64px;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .imgDark {
|
|
||||||
display: grid;
|
|
||||||
grid-column: 2;
|
|
||||||
background-color: #000;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
> img {
|
|
||||||
max-height: 64px;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .info {
|
|
||||||
display: grid;
|
|
||||||
grid-row: 2;
|
|
||||||
grid-template-rows: 30px 30px 30px;
|
|
||||||
|
|
||||||
> .name {
|
|
||||||
grid-row: 1;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .category {
|
|
||||||
grid-row: 2;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .aliases {
|
|
||||||
grid-row: 3;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .license {
|
|
||||||
grid-row: 4;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .edit-button {
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: 42px;
|
|
||||||
margin-top: 6px;
|
|
||||||
|
|
||||||
> .edit {
|
|
||||||
grid-row: 1;
|
|
||||||
width: 100%;
|
|
||||||
margin: 6px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .draft {
|
|
||||||
grid-row: 2;
|
|
||||||
width: 100%;
|
|
||||||
margin: 6px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .delete {
|
|
||||||
grid-row: 3;
|
|
||||||
width: 100%;
|
|
||||||
margin: 6px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -48,8 +48,8 @@ import MkButton from '@/components/MkButton.vue';
|
||||||
import MkInput from '@/components/MkInput.vue';
|
import MkInput from '@/components/MkInput.vue';
|
||||||
import MkPagination from '@/components/MkPagination.vue';
|
import MkPagination from '@/components/MkPagination.vue';
|
||||||
import MkSwitch from '@/components/MkSwitch.vue';
|
import MkSwitch from '@/components/MkSwitch.vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os.js';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
||||||
const emojisPaginationComponent = shallowRef<InstanceType<typeof MkPagination>>();
|
const emojisPaginationComponent = shallowRef<InstanceType<typeof MkPagination>>();
|
||||||
|
|
||||||
|
@ -96,13 +96,6 @@ const setlocalOnlyBulk = async () => {
|
||||||
});
|
});
|
||||||
emojisPaginationComponent.value.reload();
|
emojisPaginationComponent.value.reload();
|
||||||
};
|
};
|
||||||
const selectAll = () => {
|
|
||||||
if (selectedEmojis.value.length > 0) {
|
|
||||||
selectedEmojis.value = [];
|
|
||||||
} else {
|
|
||||||
selectedEmojis.value = Array.from(emojisPaginationComponent.value.items.values(), item => item.id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const toggleSelect = (emoji) => {
|
const toggleSelect = (emoji) => {
|
||||||
|
|
|
@ -63,8 +63,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkInfo warn>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn }}</MkInfo>
|
<MkInfo warn>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn }}</MkInfo>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<MkSwitch v-model="isSensitive">isSensitive</MkSwitch>
|
|
||||||
<MkSwitch v-model="localOnly">{{ i18n.ts.localOnly }}</MkSwitch>
|
|
||||||
<MkSwitch v-model="isSensitive">{{ i18n.ts.isSensitive }}</MkSwitch>
|
<MkSwitch v-model="isSensitive">{{ i18n.ts.isSensitive }}</MkSwitch>
|
||||||
<MkSwitch v-model="localOnly">{{ i18n.ts.localOnly }}</MkSwitch>
|
<MkSwitch v-model="localOnly">{{ i18n.ts.localOnly }}</MkSwitch>
|
||||||
<MkSwitch v-model="isNotifyIsHome">
|
<MkSwitch v-model="isNotifyIsHome">
|
||||||
|
@ -86,7 +84,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, watch } from 'vue';
|
import {computed, ref, watch} from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { DriveFile } from 'misskey-js/built/entities.js';
|
import { DriveFile } from 'misskey-js/built/entities.js';
|
||||||
import MkModalWindow from '@/components/MkModalWindow.vue';
|
import MkModalWindow from '@/components/MkModalWindow.vue';
|
||||||
|
@ -106,25 +104,24 @@ const props = defineProps<{
|
||||||
isRequest: boolean,
|
isRequest: boolean,
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
let dialog = $ref(null);
|
let dialog = ref(null);
|
||||||
let name: string = $ref(props.emoji ? props.emoji.name : '');
|
let name = ref(props.emoji ? props.emoji.name : '');
|
||||||
let category: string = $ref(props.emoji ? props.emoji.category : '');
|
let category = ref(props.emoji ? props.emoji.category : '');
|
||||||
let aliases: string = $ref(props.emoji ? props.emoji.aliases.join(' ') : '');
|
let aliases = ref(props.emoji ? props.emoji.aliases.join(' ') : '');
|
||||||
let license: string = $ref(props.emoji ? (props.emoji.license ?? '') : '');
|
let license = ref(props.emoji ? (props.emoji.license ?? '') : '');
|
||||||
let isSensitive = $ref(props.emoji ? props.emoji.isSensitive : false);
|
let isSensitive = ref(props.emoji ? props.emoji.isSensitive : false);
|
||||||
let localOnly = $ref(props.emoji ? props.emoji.localOnly : false);
|
let localOnly = ref(props.emoji ? props.emoji.localOnly : false);
|
||||||
let roleIdsThatCanBeUsedThisEmojiAsReaction = $ref((props.emoji && props.emoji.roleIdsThatCanBeUsedThisEmojiAsReaction) ? props.emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : []);
|
let roleIdsThatCanBeUsedThisEmojiAsReaction = ref((props.emoji && props.emoji.roleIdsThatCanBeUsedThisEmojiAsReaction) ? props.emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : []);
|
||||||
let rolesThatCanBeUsedThisEmojiAsReaction = $ref([]);
|
let rolesThatCanBeUsedThisEmojiAsReaction = ref([]);
|
||||||
let file = $ref<Misskey.entities.DriveFile>();
|
let file = ref<Misskey.entities.DriveFile>();
|
||||||
let chooseFile: DriveFile|null = $ref(null);
|
let isRequest = ref(props.isRequest ?? false);
|
||||||
let isRequest = $ref(props.isRequest ?? false);
|
watch((roleIdsThatCanBeUsedThisEmojiAsReaction), async () => {
|
||||||
watch($$(roleIdsThatCanBeUsedThisEmojiAsReaction), async () => {
|
rolesThatCanBeUsedThisEmojiAsReaction.value = (await Promise.all(roleIdsThatCanBeUsedThisEmojiAsReaction.value.map((id) => os.api('admin/roles/show', { roleId: id }).catch(() => null)))).filter(x => x != null);
|
||||||
rolesThatCanBeUsedThisEmojiAsReaction = (await Promise.all(roleIdsThatCanBeUsedThisEmojiAsReaction.map((id) => os.api('admin/roles/show', { roleId: id }).catch(() => null)))).filter(x => x != null);
|
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
const isNotifyIsHome = ref(props.emoji ? props.emoji.isNotifyIsHome : false);
|
||||||
const imgUrl = computed(() => file ? file.url : props.emoji && !isRequest ? `/emoji/${props.emoji.name}.webp` : props.emoji && props.emoji.url ? props.emoji.url : null);
|
const imgUrl = computed(() => file.value ? file.value.url : props.emoji && !isRequest.value ? `/emoji/${props.emoji.name}.webp` : props.emoji && props.emoji.url ? props.emoji.url : null);
|
||||||
const validation = computed(() => {
|
const validation = computed(() => {
|
||||||
return name.match(/^[a-zA-Z0-9_]+$/) && imgUrl.value != null;
|
return name.value.match(/^[a-zA-Z0-9_]+$/) && imgUrl.value != null;
|
||||||
});
|
});
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: 'done', v: { deleted?: boolean; updated?: any; created?: any }): void,
|
(ev: 'done', v: { deleted?: boolean; updated?: any; created?: any }): void,
|
||||||
|
@ -132,45 +129,44 @@ const emit = defineEmits<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
async function changeImage(ev) {
|
async function changeImage(ev) {
|
||||||
file = await selectFile(ev.currentTarget ?? ev.target, null);
|
file.value = await selectFile(ev.currentTarget ?? ev.target, null);
|
||||||
const candidate = file.name.replace(/\.(.+)$/, '');
|
const candidate = file.value.name.replace(/\.(.+)$/, '');
|
||||||
if (candidate.match(/^[a-z0-9_]+$/)) {
|
if (candidate.match(/^[a-z0-9_]+$/)) {
|
||||||
name = candidate;
|
name.value = candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addRole() {
|
async function addRole() {
|
||||||
const roles = await os.api('admin/roles/list');
|
const roles = await os.api('admin/roles/list');
|
||||||
const currentRoleIds = rolesThatCanBeUsedThisEmojiAsReaction.map(x => x.id);
|
const currentRoleIds = rolesThatCanBeUsedThisEmojiAsReaction.value.map(x => x.id);
|
||||||
|
|
||||||
const { canceled, result: role } = await os.select({
|
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 })),
|
items: roles.filter(r => r.isPublic).filter(r => !currentRoleIds.includes(r.id)).map(r => ({ text: r.name, value: r })),
|
||||||
});
|
});
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
|
|
||||||
rolesThatCanBeUsedThisEmojiAsReaction.push(role);
|
rolesThatCanBeUsedThisEmojiAsReaction.value.push(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeRole(role, ev) {
|
async function removeRole(role, ev) {
|
||||||
rolesThatCanBeUsedThisEmojiAsReaction = rolesThatCanBeUsedThisEmojiAsReaction.filter(x => x.id !== role.id);
|
rolesThatCanBeUsedThisEmojiAsReaction.value = rolesThatCanBeUsedThisEmojiAsReaction.value.filter(x => x.id !== role.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function done() {
|
async function done() {
|
||||||
const params = {
|
const params = {
|
||||||
name,
|
name: name.value,
|
||||||
category: category === '' ? null : category,
|
category: category.value === '' ? null : category.value,
|
||||||
aliases: aliases.replace(' ', ' ').split(' ').filter(x => x !== ''),
|
aliases: aliases.value.replace(' ', ' ').split(' ').filter(x => x !== ''),
|
||||||
license: license === '' ? null : license,
|
license: license.value === '' ? null : license.value,
|
||||||
Request: isRequest,
|
Request: isRequest.value,
|
||||||
isSensitive,
|
isSensitive: isSensitive.value,
|
||||||
localOnly,
|
localOnly: localOnly.value,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: rolesThatCanBeUsedThisEmojiAsReaction.map(x => x.id),
|
roleIdsThatCanBeUsedThisEmojiAsReaction: rolesThatCanBeUsedThisEmojiAsReaction.value.map(x => x.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (file) {
|
|
||||||
params.fileId = file.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (file.value) {
|
||||||
|
params.fileId = file.value.id;
|
||||||
|
}
|
||||||
if (props.emoji) {
|
if (props.emoji) {
|
||||||
if (isRequest) {
|
if (isRequest) {
|
||||||
await os.apiWithDialog('admin/emoji/update-request', {
|
await os.apiWithDialog('admin/emoji/update-request', {
|
||||||
|
@ -191,7 +187,7 @@ async function done() {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
dialog.close();
|
dialog.value.close();
|
||||||
} else {
|
} else {
|
||||||
const created = isRequest
|
const created = isRequest
|
||||||
? await os.apiWithDialog('admin/emoji/add-request', params)
|
? await os.apiWithDialog('admin/emoji/add-request', params)
|
||||||
|
@ -201,7 +197,7 @@ async function done() {
|
||||||
created: created,
|
created: created,
|
||||||
});
|
});
|
||||||
|
|
||||||
dialog.close();
|
dialog.value.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +214,7 @@ async function del() {
|
||||||
emit('done', {
|
emit('done', {
|
||||||
deleted: true,
|
deleted: true,
|
||||||
});
|
});
|
||||||
dialog.close();
|
dialog.value.close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -244,7 +244,6 @@ if (darkMode.value && gamingMode.value == true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(darkMode, () => {
|
watch(darkMode, () => {
|
||||||
console.log(gaming)
|
|
||||||
if (darkMode.value && gamingMode.value == true) {
|
if (darkMode.value && gamingMode.value == true) {
|
||||||
gaming.value = 'dark';
|
gaming.value = 'dark';
|
||||||
} else if (!darkMode.value && gamingMode.value == true) {
|
} else if (!darkMode.value && gamingMode.value == true) {
|
||||||
|
|
|
@ -32,8 +32,6 @@ import XButton from '@/components/MkSwitch.button.vue';
|
||||||
import {defaultStore} from "@/store.js";
|
import {defaultStore} from "@/store.js";
|
||||||
const gamingType = computed(defaultStore.makeGetterSetter('gamingType'));
|
const gamingType = computed(defaultStore.makeGetterSetter('gamingType'));
|
||||||
|
|
||||||
console.log(gamingType.value)
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: boolean | Ref<boolean>;
|
modelValue: boolean | Ref<boolean>;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|
|
@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||||
<MkSpacer v-if="tab === 'emojis'" :contentMax="1000" :marginMin="20">
|
<MkSpacer v-if="tab === 'emojis'" :contentMax="1000" :marginMin="20">
|
||||||
<MkButton v-if="$i && ($i.isModerator || $i.policies.canManageCustomEmojis)" primary link to="/custom-emojis-manager">{{ i18n.ts.manageCustomEmojis }}</MkButton>
|
<MkButton v-if="$i && ($i.isModerator || $i.policies.canManageCustomEmojis)" primary link to="/custom-emojis-manager">{{ i18n.ts.manageCustomEmojis }}</MkButton>
|
||||||
<MkButton v-if="$i && (!$i.isModerator && $i.policies.canRequestCustomEmojis)" primary @click="edit">{{ i18n.ts.requestCustomEmojis }}</MkButton>
|
<MkButton v-if="$i && (!$i.isModerator || $i.policies.canRequestCustomEmojis)" primary @click="edit">{{ i18n.ts.requestCustomEmojis }}</MkButton>
|
||||||
|
|
||||||
<div class="query" style="margin-top: 10px;">
|
<div class="query" style="margin-top: 10px;">
|
||||||
<MkInput v-model="q" class="" :placeholder="i18n.ts.search" autocapitalize="off">
|
<MkInput v-model="q" class="" :placeholder="i18n.ts.search" autocapitalize="off">
|
||||||
|
@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { watch, defineAsyncComponent, ref } from 'vue';
|
import {watch, defineAsyncComponent, ref, computed} from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import XEmoji from './emojis.emoji.vue';
|
import XEmoji from './emojis.emoji.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
|
@ -57,10 +57,10 @@ import * as os from '@/os';
|
||||||
import { $i } from '@/account.js';
|
import { $i } from '@/account.js';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
|
|
||||||
let tab = $ref('emojis');
|
let tab = ref('emojis');
|
||||||
const headerActions = $computed(() => []);
|
const headerActions = computed(() => []);
|
||||||
|
|
||||||
const headerTabs = $computed(() => [{
|
const headerTabs = computed(() => [{
|
||||||
key: 'emojis',
|
key: 'emojis',
|
||||||
title: i18n.ts.list,
|
title: i18n.ts.list,
|
||||||
}, {
|
}, {
|
||||||
|
@ -70,29 +70,29 @@ const headerTabs = $computed(() => [{
|
||||||
|
|
||||||
definePageMetadata(ref({}));
|
definePageMetadata(ref({}));
|
||||||
|
|
||||||
let q = $ref('');
|
let q = ref('');
|
||||||
let searchEmojis = $ref<Misskey.entities.CustomEmoji[]>(null);
|
let searchEmojis = ref<Misskey.entities.CustomEmoji[]>(null);
|
||||||
let selectedTags = $ref(new Set());
|
let selectedTags = ref(new Set());
|
||||||
const requestEmojis = await os.apiGet('emoji-requests');
|
const requestEmojis = await os.apiGet('emoji-requests');
|
||||||
|
|
||||||
function search() {
|
function search() {
|
||||||
if ((q === '' || q == null) && selectedTags.size === 0) {
|
if ((q.value === '' || q.value == null) && selectedTags.value.size === 0) {
|
||||||
searchEmojis = null;
|
searchEmojis.value = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedTags.size === 0) {
|
if (selectedTags.value.size === 0) {
|
||||||
const queryarry = q.match(/\:([a-z0-9_]*)\:/g);
|
const queryarry = q.value.match(/\:([a-z0-9_]*)\:/g);
|
||||||
|
|
||||||
if (queryarry) {
|
if (queryarry) {
|
||||||
searchEmojis = customEmojis.value.filter(emoji =>
|
searchEmojis.value = customEmojis.value.filter(emoji =>
|
||||||
queryarry.includes(`:${emoji.name}:`),
|
queryarry.includes(`:${emoji.name}:`),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
searchEmojis = customEmojis.value.filter(emoji => emoji.name.includes(q) || emoji.aliases.includes(q));
|
searchEmojis.value = customEmojis.value.filter(emoji => emoji.name.includes(q.value) || emoji.aliases.includes(q));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
searchEmojis = customEmojis.value.filter(emoji => (emoji.name.includes(q) || emoji.aliases.includes(q)) && [...selectedTags].every(t => emoji.aliases.includes(t)));
|
searchEmojis.value = customEmojis.value.filter(emoji => (emoji.name.includes(q.value) || emoji.aliases.includes(q)) && [...selectedTags].every(t => emoji.aliases.includes(t)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,11 +106,11 @@ const edit = () => {
|
||||||
}, 'closed');
|
}, 'closed');
|
||||||
};
|
};
|
||||||
|
|
||||||
watch($$(q), () => {
|
watch((q), () => {
|
||||||
search();
|
search();
|
||||||
});
|
});
|
||||||
|
|
||||||
watch($$(selectedTags), () => {
|
watch((selectedTags), () => {
|
||||||
search();
|
search();
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template #prefix><i class="ti ti-key"></i></template>
|
<template #prefix><i class="ti ti-key"></i></template>
|
||||||
<template #label>ApiBase</template>
|
<template #label>ApiBase</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
|
<MkSwitch v-model="requestEmojiAllOk">
|
||||||
|
絵文字の申請全部許可
|
||||||
|
</MkSwitch>
|
||||||
</div>
|
</div>
|
||||||
</FormSuspense>
|
</FormSuspense>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
|
@ -69,6 +72,7 @@ const enableServerMachineStats = ref<boolean>(false);
|
||||||
const enableIdenticonGeneration = ref<boolean>(false);
|
const enableIdenticonGeneration = ref<boolean>(false);
|
||||||
const enableChartsForRemoteUser = ref<boolean>(false);
|
const enableChartsForRemoteUser = ref<boolean>(false);
|
||||||
const enableChartsForFederatedInstances = ref<boolean>(false);
|
const enableChartsForFederatedInstances = ref<boolean>(false);
|
||||||
|
const requestEmojiAllOk = ref(false)
|
||||||
let DiscordWebhookUrl = ref(null);
|
let DiscordWebhookUrl = ref(null);
|
||||||
let EmojiBotToken= ref(null);
|
let EmojiBotToken= ref(null);
|
||||||
let ApiBase= ref(null)
|
let ApiBase= ref(null)
|
||||||
|
@ -78,6 +82,7 @@ async function init() {
|
||||||
enableIdenticonGeneration.value = meta.enableIdenticonGeneration;
|
enableIdenticonGeneration.value = meta.enableIdenticonGeneration;
|
||||||
enableChartsForRemoteUser.value = meta.enableChartsForRemoteUser;
|
enableChartsForRemoteUser.value = meta.enableChartsForRemoteUser;
|
||||||
enableChartsForFederatedInstances.value = meta.enableChartsForFederatedInstances;
|
enableChartsForFederatedInstances.value = meta.enableChartsForFederatedInstances;
|
||||||
|
requestEmojiAllOk.value = meta.requestEmojiAllOk;
|
||||||
DiscordWebhookUrl.value = meta.DiscordWebhookUrl;
|
DiscordWebhookUrl.value = meta.DiscordWebhookUrl;
|
||||||
EmojiBotToken.value = meta.EmojiBotToken;
|
EmojiBotToken.value = meta.EmojiBotToken;
|
||||||
ApiBase.value = meta.ApiBase;
|
ApiBase.value = meta.ApiBase;
|
||||||
|
@ -88,6 +93,7 @@ function save() {
|
||||||
enableServerMachineStats: enableServerMachineStats.value,
|
enableServerMachineStats: enableServerMachineStats.value,
|
||||||
enableIdenticonGeneration: enableIdenticonGeneration.value,
|
enableIdenticonGeneration: enableIdenticonGeneration.value,
|
||||||
enableChartsForRemoteUser: enableChartsForRemoteUser.value,
|
enableChartsForRemoteUser: enableChartsForRemoteUser.value,
|
||||||
|
requestEmojiAllOk: requestEmojiAllOk.value,
|
||||||
enableChartsForFederatedInstances: enableChartsForFederatedInstances.value,
|
enableChartsForFederatedInstances: enableChartsForFederatedInstances.value,
|
||||||
DiscordWebhookUrl:DiscordWebhookUrl.value,
|
DiscordWebhookUrl:DiscordWebhookUrl.value,
|
||||||
EmojiBotToken:EmojiBotToken.value,
|
EmojiBotToken:EmojiBotToken.value,
|
||||||
|
|
|
@ -37,7 +37,7 @@ import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
const tab = ref('request');
|
const tab = ref('request');
|
||||||
|
|
||||||
const add = async (ev: MouseEvent) => {
|
const add = async (ev: MouseEvent) => {
|
||||||
os.popup(defineAsyncComponent(() => import('./emoji-edit-dialog.vue')), {
|
os.popup(defineAsyncComponent(() => import('../components/MkEmojiEditDialog.vue')), {
|
||||||
}, {
|
}, {
|
||||||
done: result => {
|
done: result => {
|
||||||
//TODO: emitにして追加を反映
|
//TODO: emitにして追加を反映
|
||||||
|
@ -91,7 +91,7 @@ const menu = (ev: MouseEvent) => {
|
||||||
}], ev.currentTarget ?? ev.target);
|
}], ev.currentTarget ?? ev.target);
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerActions = $computed(() => [{
|
const headerActions = computed(() => [{
|
||||||
asFullButton: true,
|
asFullButton: true,
|
||||||
icon: 'ti ti-plus',
|
icon: 'ti ti-plus',
|
||||||
text: i18n.ts.addEmoji,
|
text: i18n.ts.addEmoji,
|
||||||
|
@ -101,7 +101,7 @@ const headerActions = $computed(() => [{
|
||||||
handler: menu,
|
handler: menu,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
const headerTabs = $computed(() => [{
|
const headerTabs = computed(() => [{
|
||||||
key: 'request',
|
key: 'request',
|
||||||
title: i18n.ts.requestingEmojis,
|
title: i18n.ts.requestingEmojis,
|
||||||
}, {
|
}, {
|
||||||
|
|
Loading…
Reference in New Issue