Improve emoji-picker (#5515)
* Improve emoji-picker * remove unimplanted translation * カテゴリのサジェスト * use unique
This commit is contained in:
		
							parent
							
								
									97b6af62fe
								
							
						
					
					
						commit
						4c6c06c80a
					
				
					 11 changed files with 169 additions and 32 deletions
				
			
		|  | @ -673,7 +673,9 @@ common/views/components/reaction-picker.vue: | ||||||
|   input-reaction-placeholder: "または絵文字を入力" |   input-reaction-placeholder: "または絵文字を入力" | ||||||
| 
 | 
 | ||||||
| common/views/components/emoji-picker.vue: | common/views/components/emoji-picker.vue: | ||||||
|  |   recent-emoji: "最近使った絵文字" | ||||||
|   custom-emoji: "カスタム絵文字" |   custom-emoji: "カスタム絵文字" | ||||||
|  |   no-category: "カテゴリなし" | ||||||
|   people: "人" |   people: "人" | ||||||
|   animals-and-nature: "動物&自然" |   animals-and-nature: "動物&自然" | ||||||
|   food-and-drink: "食べ物&飲み物" |   food-and-drink: "食べ物&飲み物" | ||||||
|  | @ -1591,6 +1593,7 @@ admin/views/emoji.vue: | ||||||
|     title: "絵文字の登録" |     title: "絵文字の登録" | ||||||
|     name: "絵文字名" |     name: "絵文字名" | ||||||
|     name-desc: "a~z 0~9 _ の文字が使えます。" |     name-desc: "a~z 0~9 _ の文字が使えます。" | ||||||
|  |     category: "カテゴリ" | ||||||
|     aliases: "エイリアス" |     aliases: "エイリアス" | ||||||
|     aliases-desc: "スペースで区切って複数設定できます。" |     aliases-desc: "スペースで区切って複数設定できます。" | ||||||
|     url: "絵文字画像URL" |     url: "絵文字画像URL" | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								migration/1571220798684-CustomEmojiCategory.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								migration/1571220798684-CustomEmojiCategory.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | import {MigrationInterface, QueryRunner} from "typeorm"; | ||||||
|  | 
 | ||||||
|  | export class CustomEmojiCategory1571220798684 implements MigrationInterface { | ||||||
|  | 
 | ||||||
|  |     public async up(queryRunner: QueryRunner): Promise<any> { | ||||||
|  |         await queryRunner.query(`ALTER TABLE "emoji" ADD "category" character varying(128)`, undefined); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public async down(queryRunner: QueryRunner): Promise<any> { | ||||||
|  |         await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "category"`, undefined); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -8,6 +8,9 @@ | ||||||
| 					<span>{{ $t('add-emoji.name') }}</span> | 					<span>{{ $t('add-emoji.name') }}</span> | ||||||
| 					<template #desc>{{ $t('add-emoji.name-desc') }}</template> | 					<template #desc>{{ $t('add-emoji.name-desc') }}</template> | ||||||
| 				</ui-input> | 				</ui-input> | ||||||
|  | 				<ui-input v-model="category" :datalist="categoryList"> | ||||||
|  | 					<span>{{ $t('add-emoji.category') }}</span> | ||||||
|  | 				</ui-input> | ||||||
| 				<ui-input v-model="aliases"> | 				<ui-input v-model="aliases"> | ||||||
| 					<span>{{ $t('add-emoji.aliases') }}</span> | 					<span>{{ $t('add-emoji.aliases') }}</span> | ||||||
| 					<template #desc>{{ $t('add-emoji.aliases-desc') }}</template> | 					<template #desc>{{ $t('add-emoji.aliases-desc') }}</template> | ||||||
|  | @ -24,7 +27,7 @@ | ||||||
| 
 | 
 | ||||||
| 	<ui-card> | 	<ui-card> | ||||||
| 		<template #title><fa :icon="faGrin"/> {{ $t('emojis.title') }}</template> | 		<template #title><fa :icon="faGrin"/> {{ $t('emojis.title') }}</template> | ||||||
| 		<section v-for="emoji in emojis" class="oryfrbft"> | 		<section v-for="emoji in emojis" :key="emoji.name" class="oryfrbft"> | ||||||
| 			<div> | 			<div> | ||||||
| 				<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/> | 				<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/> | ||||||
| 			</div> | 			</div> | ||||||
|  | @ -33,6 +36,9 @@ | ||||||
| 					<ui-input v-model="emoji.name"> | 					<ui-input v-model="emoji.name"> | ||||||
| 						<span>{{ $t('add-emoji.name') }}</span> | 						<span>{{ $t('add-emoji.name') }}</span> | ||||||
| 					</ui-input> | 					</ui-input> | ||||||
|  | 					<ui-input v-model="emoji.category" :datalist="categoryList"> | ||||||
|  | 						<span>{{ $t('add-emoji.category') }}</span> | ||||||
|  | 					</ui-input> | ||||||
| 					<ui-input v-model="emoji.aliases"> | 					<ui-input v-model="emoji.aliases"> | ||||||
| 						<span>{{ $t('add-emoji.aliases') }}</span> | 						<span>{{ $t('add-emoji.aliases') }}</span> | ||||||
| 					</ui-input> | 					</ui-input> | ||||||
|  | @ -55,12 +61,14 @@ | ||||||
| import Vue from 'vue'; | import Vue from 'vue'; | ||||||
| import i18n from '../../i18n'; | import i18n from '../../i18n'; | ||||||
| import { faGrin } from '@fortawesome/free-regular-svg-icons'; | import { faGrin } from '@fortawesome/free-regular-svg-icons'; | ||||||
|  | import { unique } from '../../../../prelude/array'; | ||||||
| 
 | 
 | ||||||
| export default Vue.extend({ | export default Vue.extend({ | ||||||
| 	i18n: i18n('admin/views/emoji.vue'), | 	i18n: i18n('admin/views/emoji.vue'), | ||||||
| 	data() { | 	data() { | ||||||
| 		return { | 		return { | ||||||
| 			name: '', | 			name: '', | ||||||
|  | 			category: '', | ||||||
| 			url: '', | 			url: '', | ||||||
| 			aliases: '', | 			aliases: '', | ||||||
| 			emojis: [], | 			emojis: [], | ||||||
|  | @ -72,10 +80,17 @@ export default Vue.extend({ | ||||||
| 		this.fetchEmojis(); | 		this.fetchEmojis(); | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	computed: { | ||||||
|  | 		categoryList() { | ||||||
|  | 			return unique(this.emojis.map((x: any) => x.category || '').filter((x: string) => x !== '')); | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
| 		add() { | 		add() { | ||||||
| 			this.$root.api('admin/emoji/add', { | 			this.$root.api('admin/emoji/add', { | ||||||
| 				name: this.name, | 				name: this.name, | ||||||
|  | 				category: this.category, | ||||||
| 				url: this.url, | 				url: this.url, | ||||||
| 				aliases: this.aliases.split(' ').filter(x => x.length > 0) | 				aliases: this.aliases.split(' ').filter(x => x.length > 0) | ||||||
| 			}).then(() => { | 			}).then(() => { | ||||||
|  | @ -94,7 +109,6 @@ export default Vue.extend({ | ||||||
| 
 | 
 | ||||||
| 		fetchEmojis() { | 		fetchEmojis() { | ||||||
| 			this.$root.api('admin/emoji/list').then(emojis => { | 			this.$root.api('admin/emoji/list').then(emojis => { | ||||||
| 				emojis.reverse(); |  | ||||||
| 				for (const e of emojis) { | 				for (const e of emojis) { | ||||||
| 					e.aliases = (e.aliases || []).join(' '); | 					e.aliases = (e.aliases || []).join(' '); | ||||||
| 				} | 				} | ||||||
|  | @ -106,6 +120,7 @@ export default Vue.extend({ | ||||||
| 			this.$root.api('admin/emoji/update', { | 			this.$root.api('admin/emoji/update', { | ||||||
| 				id: emoji.id, | 				id: emoji.id, | ||||||
| 				name: emoji.name, | 				name: emoji.name, | ||||||
|  | 				category: emoji.category, | ||||||
| 				url: emoji.url, | 				url: emoji.url, | ||||||
| 				aliases: emoji.aliases.split(' ').filter(x => x.length > 0) | 				aliases: emoji.aliases.split(' ').filter(x => x.length > 0) | ||||||
| 			}).then(() => { | 			}).then(() => { | ||||||
|  |  | ||||||
|  | @ -11,25 +11,46 @@ | ||||||
| 		</button> | 		</button> | ||||||
| 	</header> | 	</header> | ||||||
| 	<div class="emojis"> | 	<div class="emojis"> | ||||||
| 		<header><fa :icon="categories.find(x => x.isActive).icon" fixed-width/> {{ categories.find(x => x.isActive).text }}</header> | 		<template v-if="categories[0].isActive"> | ||||||
| 		<div v-if="categories.find(x => x.isActive).name"> | 			<header class="category"><fa :icon="faHistory" fixed-width/> {{ $t('recent-emoji') }}</header> | ||||||
| 			<button v-for="emoji in emojilist.filter(e => e.category === categories.find(x => x.isActive).name)" | 			<div class="list"> | ||||||
| 				:title="emoji.name" | 				<button v-for="(emoji, i) in ($store.state.device.recentEmojis || [])" | ||||||
| 				@click="chosen(emoji.char)" | 					:title="emoji.name" | ||||||
| 				:key="emoji.name" | 					@click="chosen(emoji)" | ||||||
| 			> | 					:key="i" | ||||||
| 				<mk-emoji :emoji="emoji.char"/> | 				> | ||||||
| 			</button> | 					<mk-emoji v-if="emoji.char != null" :emoji="emoji.char"/> | ||||||
| 		</div> | 					<img v-else :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/> | ||||||
| 		<div v-else> | 				</button> | ||||||
| 			<button v-for="emoji in customEmojis" | 			</div> | ||||||
| 				:title="emoji.name" | 		</template> | ||||||
| 				@click="chosen(`:${emoji.name}:`)" | 
 | ||||||
| 				:key="emoji.name" | 		<header class="category"><fa :icon="categories.find(x => x.isActive).icon" fixed-width/> {{ categories.find(x => x.isActive).text }}</header> | ||||||
| 			> | 		<template v-if="categories.find(x => x.isActive).name"> | ||||||
| 				<img :src="emoji.url" :alt="emoji.name"/> | 			<div class="list"> | ||||||
| 			</button> | 				<button v-for="emoji in emojilist.filter(e => e.category === categories.find(x => x.isActive).name)" | ||||||
| 		</div> | 					:title="emoji.name" | ||||||
|  | 					@click="chosen(emoji)" | ||||||
|  | 					:key="emoji.name" | ||||||
|  | 				> | ||||||
|  | 					<mk-emoji :emoji="emoji.char"/> | ||||||
|  | 				</button> | ||||||
|  | 			</div> | ||||||
|  | 		</template> | ||||||
|  | 		<template v-else> | ||||||
|  | 			<div v-for="(key, i) in Object.keys(customEmojis)" :key="i"> | ||||||
|  | 				<header class="sub">{{ key || $t('no-category') }}</header> | ||||||
|  | 				<div class="list"> | ||||||
|  | 					<button v-for="emoji in customEmojis[key]" | ||||||
|  | 						:title="emoji.name" | ||||||
|  | 						@click="chosen(emoji)" | ||||||
|  | 						:key="emoji.name" | ||||||
|  | 					> | ||||||
|  | 						<img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/> | ||||||
|  | 					</button> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
|  | 		</template> | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
|  | @ -38,8 +59,10 @@ | ||||||
| import Vue from 'vue'; | import Vue from 'vue'; | ||||||
| import i18n from '../../../i18n'; | import i18n from '../../../i18n'; | ||||||
| import { emojilist } from '../../../../../misc/emojilist'; | import { emojilist } from '../../../../../misc/emojilist'; | ||||||
| import { faAsterisk, faLeaf, faUtensils, faFutbol, faCity, faDice } from '@fortawesome/free-solid-svg-icons'; | import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url'; | ||||||
|  | import { faAsterisk, faLeaf, faUtensils, faFutbol, faCity, faDice, faGlobe, faHistory } from '@fortawesome/free-solid-svg-icons'; | ||||||
| import { faHeart, faFlag } from '@fortawesome/free-regular-svg-icons'; | import { faHeart, faFlag } from '@fortawesome/free-regular-svg-icons'; | ||||||
|  | import { groupByX } from '../../../../../prelude/array'; | ||||||
| 
 | 
 | ||||||
| export default Vue.extend({ | export default Vue.extend({ | ||||||
| 	i18n: i18n('common/views/components/emoji-picker.vue'), | 	i18n: i18n('common/views/components/emoji-picker.vue'), | ||||||
|  | @ -47,7 +70,9 @@ export default Vue.extend({ | ||||||
| 	data() { | 	data() { | ||||||
| 		return { | 		return { | ||||||
| 			emojilist, | 			emojilist, | ||||||
| 			customEmojis: [], | 			getStaticImageUrl, | ||||||
|  | 			customEmojis: {}, | ||||||
|  | 			faGlobe, faHistory, | ||||||
| 			categories: [{ | 			categories: [{ | ||||||
| 				text: this.$t('custom-emoji'), | 				text: this.$t('custom-emoji'), | ||||||
| 				icon: faAsterisk, | 				icon: faAsterisk, | ||||||
|  | @ -97,18 +122,43 @@ export default Vue.extend({ | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	created() { | 	created() { | ||||||
| 		this.customEmojis = (this.$root.getMetaSync() || { emojis: [] }).emojis || []; | 		let local = (this.$root.getMetaSync() || { emojis: [] }).emojis || []; | ||||||
|  | 		local = groupByX(local, (x: any) => x.category || ''); | ||||||
|  | 		this.customEmojis = local; | ||||||
|  | 
 | ||||||
|  | 		if (this.$store.state.device.activeEmojiCategoryName) { | ||||||
|  | 			this.goCategory(this.$store.state.device.activeEmojiCategoryName); | ||||||
|  | 		} | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
| 		go(category) { | 		go(category: any) { | ||||||
|  | 			this.goCategory(category.name); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		goCategory(name: string) { | ||||||
|  | 			let matched = false; | ||||||
| 			for (const c of this.categories) { | 			for (const c of this.categories) { | ||||||
| 				c.isActive = c.name === category.name; | 				c.isActive = c.name === name; | ||||||
|  | 				if (c.isActive) { | ||||||
|  | 					matched = true; | ||||||
|  | 					this.$store.commit('device/set', { key: 'activeEmojiCategoryName', value: c.name }); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if (!matched) { | ||||||
|  | 				this.categories[0].isActive = true; | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		chosen(emoji) { | 		chosen(emoji: any) { | ||||||
| 			this.$emit('chosen', emoji); | 			const getKey = (emoji: any) => emoji.char || `:${emoji.name}:`; | ||||||
|  | 
 | ||||||
|  | 			let recents = this.$store.state.device.recentEmojis || []; | ||||||
|  | 			recents = recents.filter((e: any) => getKey(e) !== getKey(emoji)); | ||||||
|  | 			recents.unshift(emoji) | ||||||
|  | 			this.$store.commit('device/set', { key: 'recentEmojis', value: recents.splice(0, 16) }); | ||||||
|  | 
 | ||||||
|  | 			this.$emit('chosen', getKey(emoji)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|  | @ -142,7 +192,7 @@ export default Vue.extend({ | ||||||
| 		overflow-y auto | 		overflow-y auto | ||||||
| 		overflow-x hidden | 		overflow-x hidden | ||||||
| 
 | 
 | ||||||
| 		> header | 		> header.category | ||||||
| 			position sticky | 			position sticky | ||||||
| 			top 0 | 			top 0 | ||||||
| 			left 0 | 			left 0 | ||||||
|  | @ -152,7 +202,12 @@ export default Vue.extend({ | ||||||
| 			color var(--text) | 			color var(--text) | ||||||
| 			font-size 12px | 			font-size 12px | ||||||
| 
 | 
 | ||||||
| 		> div | 		>>> header.sub | ||||||
|  | 			padding 4px 8px | ||||||
|  | 			color var(--text) | ||||||
|  | 			font-size 12px | ||||||
|  | 
 | ||||||
|  | 		>>> div.list | ||||||
| 			display grid | 			display grid | ||||||
| 			grid-template-columns 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr | 			grid-template-columns 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr | ||||||
| 			gap 4px | 			gap 4px | ||||||
|  | @ -180,6 +235,7 @@ export default Vue.extend({ | ||||||
| 					left 0 | 					left 0 | ||||||
| 					width 100% | 					width 100% | ||||||
| 					height 100% | 					height 100% | ||||||
|  | 					object-fit contain | ||||||
| 					font-size 28px | 					font-size 28px | ||||||
| 					transition transform 0.2s ease | 					transition transform 0.2s ease | ||||||
| 					pointer-events none | 					pointer-events none | ||||||
|  |  | ||||||
|  | @ -79,6 +79,8 @@ const defaultDeviceSettings = { | ||||||
| 	enableMobileQuickNotificationView: false, | 	enableMobileQuickNotificationView: false, | ||||||
| 	roomGraphicsQuality: 'medium', | 	roomGraphicsQuality: 'medium', | ||||||
| 	roomUseOrthographicCamera: true, | 	roomUseOrthographicCamera: true, | ||||||
|  | 	activeEmojiCategoryName: undefined, | ||||||
|  | 	recentEmojis: [], | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default (os: MiOS) => new Vuex.Store({ | export default (os: MiOS) => new Vuex.Store({ | ||||||
|  |  | ||||||
|  | @ -24,6 +24,11 @@ export class Emoji { | ||||||
| 	}) | 	}) | ||||||
| 	public host: string | null; | 	public host: string | null; | ||||||
| 
 | 
 | ||||||
|  | 	@Column('varchar', { | ||||||
|  | 		length: 128, nullable: true | ||||||
|  | 	}) | ||||||
|  | 	public category: string | null; | ||||||
|  | 
 | ||||||
| 	@Column('varchar', { | 	@Column('varchar', { | ||||||
| 		length: 512, | 		length: 512, | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | @ -84,6 +84,19 @@ export function groupOn<T, S>(f: (x: T) => S, xs: T[]): T[][] { | ||||||
| 	return groupBy((a, b) => f(a) === f(b), xs); | 	return groupBy((a, b) => f(a) === f(b), xs); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export function groupByX<T>(collections: T[], keySelector: (x: T) => string) { | ||||||
|  | 	return collections.reduce((obj: Record<string, T[]>, item: T) => { | ||||||
|  | 		const key = keySelector(item); | ||||||
|  | 		if (!obj.hasOwnProperty(key)) { | ||||||
|  | 			obj[key] = []; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		obj[key].push(item); | ||||||
|  | 
 | ||||||
|  | 		return obj; | ||||||
|  | 	}, {}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Compare two arrays by lexicographical order |  * Compare two arrays by lexicographical order | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | @ -26,6 +26,10 @@ export const meta = { | ||||||
| 			validator: $.str.min(1) | 			validator: $.str.min(1) | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  | 		category: { | ||||||
|  | 			validator: $.optional.str | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
| 		aliases: { | 		aliases: { | ||||||
| 			validator: $.optional.arr($.str.min(1)), | 			validator: $.optional.arr($.str.min(1)), | ||||||
| 			default: [] as string[] | 			default: [] as string[] | ||||||
|  | @ -52,6 +56,7 @@ export default define(meta, async (ps, me) => { | ||||||
| 		id: genId(), | 		id: genId(), | ||||||
| 		updatedAt: new Date(), | 		updatedAt: new Date(), | ||||||
| 		name: ps.name, | 		name: ps.name, | ||||||
|  | 		category: ps.category, | ||||||
| 		host: null, | 		host: null, | ||||||
| 		aliases: ps.aliases, | 		aliases: ps.aliases, | ||||||
| 		url: ps.url, | 		url: ps.url, | ||||||
|  |  | ||||||
|  | @ -23,12 +23,19 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| export default define(meta, async (ps) => { | export default define(meta, async (ps) => { | ||||||
| 	const emojis = await Emojis.find({ | 	const emojis = await Emojis.find({ | ||||||
| 		host: toPunyNullable(ps.host) | 		where: { | ||||||
|  | 			host: toPunyNullable(ps.host) | ||||||
|  | 		}, | ||||||
|  | 		order: { | ||||||
|  | 			category: 'ASC', | ||||||
|  | 			name: 'ASC' | ||||||
|  | 		} | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
| 	return emojis.map(e => ({ | 	return emojis.map(e => ({ | ||||||
| 		id: e.id, | 		id: e.id, | ||||||
| 		name: e.name, | 		name: e.name, | ||||||
|  | 		category: e.category, | ||||||
| 		aliases: e.aliases, | 		aliases: e.aliases, | ||||||
| 		host: e.host, | 		host: e.host, | ||||||
| 		url: e.url | 		url: e.url | ||||||
|  |  | ||||||
|  | @ -25,6 +25,10 @@ export const meta = { | ||||||
| 			validator: $.str | 			validator: $.str | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  | 		category: { | ||||||
|  | 			validator: $.optional.str | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
| 		url: { | 		url: { | ||||||
| 			validator: $.str | 			validator: $.str | ||||||
| 		}, | 		}, | ||||||
|  | @ -53,6 +57,7 @@ export default define(meta, async (ps) => { | ||||||
| 	await Emojis.update(emoji.id, { | 	await Emojis.update(emoji.id, { | ||||||
| 		updatedAt: new Date(), | 		updatedAt: new Date(), | ||||||
| 		name: ps.name, | 		name: ps.name, | ||||||
|  | 		category: ps.category, | ||||||
| 		aliases: ps.aliases, | 		aliases: ps.aliases, | ||||||
| 		url: ps.url, | 		url: ps.url, | ||||||
| 		type, | 		type, | ||||||
|  |  | ||||||
|  | @ -96,7 +96,19 @@ export const meta = { | ||||||
| export default define(meta, async (ps, me) => { | export default define(meta, async (ps, me) => { | ||||||
| 	const instance = await fetchMeta(true); | 	const instance = await fetchMeta(true); | ||||||
| 
 | 
 | ||||||
| 	const emojis = await Emojis.find({ where: { host: null }, cache: { id: 'meta_emojis', milliseconds: 3600000 } }); // 1 hour
 | 	const emojis = await Emojis.find({ | ||||||
|  | 		where: { | ||||||
|  | 			host: null | ||||||
|  | 		}, | ||||||
|  | 		order: { | ||||||
|  | 			category: 'ASC', | ||||||
|  | 			name: 'ASC' | ||||||
|  | 		}, | ||||||
|  | 		cache: { | ||||||
|  | 			id: 'meta_emojis', | ||||||
|  | 			milliseconds: 3600000	// 1 hour
 | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
| 
 | 
 | ||||||
| 	const response: any = { | 	const response: any = { | ||||||
| 		maintainerName: instance.maintainerName, | 		maintainerName: instance.maintainerName, | ||||||
|  | @ -144,6 +156,7 @@ export default define(meta, async (ps, me) => { | ||||||
| 			id: e.id, | 			id: e.id, | ||||||
| 			aliases: e.aliases, | 			aliases: e.aliases, | ||||||
| 			name: e.name, | 			name: e.name, | ||||||
|  | 			category: e.category, | ||||||
| 			url: e.url, | 			url: e.url, | ||||||
| 		})), | 		})), | ||||||
| 		enableEmail: instance.enableEmail, | 		enableEmail: instance.enableEmail, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue