summaryrefslogtreecommitdiff
path: root/packages/frontend/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2023-01-09 15:50:25 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2023-01-09 15:50:25 +0900
commit462acc9eee3f89a926fd4b46ffed0b066519759b (patch)
tree3e8df5e6f490966c078fce12fd2d89f1385f58c0 /packages/frontend/src
parentfix(server): アンテナタイムライン(ストリーミング)が、... (diff)
downloadmisskey-462acc9eee3f89a926fd4b46ffed0b066519759b.tar.gz
misskey-462acc9eee3f89a926fd4b46ffed0b066519759b.tar.bz2
misskey-462acc9eee3f89a926fd4b46ffed0b066519759b.zip
カスタム絵文字一覧情報をmetaから分離
Diffstat (limited to 'packages/frontend/src')
-rw-r--r--packages/frontend/src/components/MkAutocomplete.vue5
-rw-r--r--packages/frontend/src/components/MkEmojiPicker.vue9
-rw-r--r--packages/frontend/src/custom-emojis.ts48
-rw-r--r--packages/frontend/src/instance.ts24
-rw-r--r--packages/frontend/src/local-storage.ts2
-rw-r--r--packages/frontend/src/pages/about.emojis.vue87
-rw-r--r--packages/frontend/src/pages/admin/emoji-edit-dialog.vue4
-rw-r--r--packages/frontend/src/pages/admin/overview.stats.vue5
-rw-r--r--packages/frontend/src/pages/mfm-cheat-sheet.vue5
-rw-r--r--packages/frontend/src/pages/settings/index.vue2
10 files changed, 106 insertions, 85 deletions
diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index 8ed60bc5dc..0d0c5edbae 100644
--- a/packages/frontend/src/components/MkAutocomplete.vue
+++ b/packages/frontend/src/components/MkAutocomplete.vue
@@ -47,6 +47,9 @@ import { emojilist } from '@/scripts/emojilist';
import { instance } from '@/instance';
import { i18n } from '@/i18n';
import { miLocalStorage } from '@/local-storage';
+import { getCustomEmojis } from '@/custom-emojis';
+
+const customEmojis = await getCustomEmojis();
type EmojiDef = {
emoji: string;
@@ -86,7 +89,6 @@ for (const x of lib) {
emjdb.sort((a, b) => a.name.length - b.name.length);
//#region Construct Emoji DB
-const customEmojis = instance.emojis;
const emojiDefinitions: EmojiDef[] = [];
for (const x of customEmojis) {
@@ -117,7 +119,6 @@ export default {
emojiDb,
emojiDefinitions,
emojilist,
- customEmojis,
};
</script>
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index f3b3ac0b50..8df01f6c25 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -6,7 +6,7 @@
<div v-if="searchResultCustom.length > 0" class="body">
<button
v-for="emoji in searchResultCustom"
- :key="emoji.id"
+ :key="emoji.name"
class="_button item"
:title="emoji.name"
tabindex="0"
@@ -85,9 +85,10 @@ import MkRippleEffect from '@/components/MkRippleEffect.vue';
import * as os from '@/os';
import { isTouchUsing } from '@/scripts/touch';
import { deviceKind } from '@/scripts/device-kind';
-import { emojiCategories, instance } from '@/instance';
+import { instance } from '@/instance';
import { i18n } from '@/i18n';
import { defaultStore } from '@/store';
+import { getCustomEmojiCategories, getCustomEmojis } from '@/custom-emojis';
const props = withDefaults(defineProps<{
showPinned?: boolean;
@@ -103,6 +104,7 @@ const emit = defineEmits<{
(ev: 'chosen', v: string): void;
}>();
+const customEmojis = await getCustomEmojis();
const search = shallowRef<HTMLInputElement>();
const emojis = shallowRef<HTMLDivElement>();
@@ -118,8 +120,7 @@ const {
const size = computed(() => props.asReactionPicker ? reactionPickerSize.value : 1);
const width = computed(() => props.asReactionPicker ? reactionPickerWidth.value : 3);
const height = computed(() => props.asReactionPicker ? reactionPickerHeight.value : 2);
-const customEmojiCategories = emojiCategories;
-const customEmojis = instance.emojis;
+const customEmojiCategories = await getCustomEmojiCategories();
const q = ref<string>('');
const searchResultCustom = ref<Misskey.entities.CustomEmoji[]>([]);
const searchResultUnicode = ref<UnicodeEmojiDef[]>([]);
diff --git a/packages/frontend/src/custom-emojis.ts b/packages/frontend/src/custom-emojis.ts
new file mode 100644
index 0000000000..2a52753f84
--- /dev/null
+++ b/packages/frontend/src/custom-emojis.ts
@@ -0,0 +1,48 @@
+import { api } from './os';
+import { miLocalStorage } from './local-storage';
+
+const storageCache = miLocalStorage.getItem('emojis');
+let cached = storageCache ? JSON.parse(storageCache) : null;
+export async function getCustomEmojis() {
+ const now = Date.now();
+ const lastFetchedAt = miLocalStorage.getItem('lastEmojisFetchedAt');
+ if (cached && lastFetchedAt && (now - parseInt(lastFetchedAt)) < 1000 * 60 * 60) return cached;
+
+ const res = await api('emojis', {});
+
+ cached = res.emojis;
+ miLocalStorage.setItem('emojis', JSON.stringify(cached));
+ miLocalStorage.setItem('lastEmojisFetchedAt', now.toString());
+}
+
+let cachedCategories;
+export async function getCustomEmojiCategories() {
+ if (cachedCategories) return cachedCategories;
+
+ const customEmojis = await getCustomEmojis();
+
+ const categories = new Set();
+ for (const emoji of customEmojis) {
+ categories.add(emoji.category);
+ }
+ const res = Array.from(categories);
+ cachedCategories = res;
+ return res;
+}
+
+let cachedTags;
+export async function getCustomEmojiTags() {
+ if (cachedTags) return cachedTags;
+
+ const customEmojis = await getCustomEmojis();
+
+ const tags = new Set();
+ for (const emoji of customEmojis) {
+ for (const tag of emoji.aliases) {
+ tags.add(tag);
+ }
+ }
+ const res = Array.from(tags);
+ cachedTags = res;
+ return res;
+}
diff --git a/packages/frontend/src/instance.ts b/packages/frontend/src/instance.ts
index 82d3e7aea2..08dbd9737c 100644
--- a/packages/frontend/src/instance.ts
+++ b/packages/frontend/src/instance.ts
@@ -5,11 +5,11 @@ import { miLocalStorage } from './local-storage';
// TODO: 他のタブと永続化されたstateを同期
-const instanceData = miLocalStorage.getItem('instance');
+const cached = miLocalStorage.getItem('instance');
// TODO: instanceをリアクティブにするかは再考の余地あり
-export const instance: Misskey.entities.InstanceMetadata = reactive(instanceData ? JSON.parse(instanceData) : {
+export const instance: Misskey.entities.InstanceMetadata = reactive(cached ? JSON.parse(cached) : {
// TODO: set default values
});
@@ -24,23 +24,3 @@ export async function fetchInstance() {
miLocalStorage.setItem('instance', JSON.stringify(instance));
}
-
-export const emojiCategories = computed(() => {
- if (instance.emojis == null) return [];
- const categories = new Set();
- for (const emoji of instance.emojis) {
- categories.add(emoji.category);
- }
- return Array.from(categories);
-});
-
-export const emojiTags = computed(() => {
- if (instance.emojis == null) return [];
- const tags = new Set();
- for (const emoji of instance.emojis) {
- for (const tag of emoji.aliases) {
- tags.add(tag);
- }
- }
- return Array.from(tags);
-});
diff --git a/packages/frontend/src/local-storage.ts b/packages/frontend/src/local-storage.ts
index 50e28d621f..bb8192e980 100644
--- a/packages/frontend/src/local-storage.ts
+++ b/packages/frontend/src/local-storage.ts
@@ -2,6 +2,8 @@ type Keys =
'v' |
'lastVersion' |
'instance' |
+ 'emojis' | // TODO: indexed db
+ 'lastEmojisFetchedAt' |
'account' |
'accounts' |
'latestDonationInfoShownAt' |
diff --git a/packages/frontend/src/pages/about.emojis.vue b/packages/frontend/src/pages/about.emojis.vue
index e15a2b1bdf..acf6237c87 100644
--- a/packages/frontend/src/pages/about.emojis.vue
+++ b/packages/frontend/src/pages/about.emojis.vue
@@ -7,7 +7,7 @@
<!-- たくさんあると邪魔
<div class="tags">
- <span class="tag _button" v-for="tag in tags" :class="{ active: selectedTags.has(tag) }" @click="toggleTag(tag)">{{ tag }}</span>
+ <span class="tag _button" v-for="tag in customEmojiTags" :class="{ active: selectedTags.has(tag) }" @click="toggleTag(tag)">{{ tag }}</span>
</div>
-->
</div>
@@ -28,8 +28,8 @@
</div>
</template>
-<script lang="ts">
-import { defineComponent, computed } from 'vue';
+<script lang="ts" setup>
+import { defineComponent, computed, watch } from 'vue';
import XEmoji from './emojis.emoji.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
@@ -37,62 +37,43 @@ import MkSelect from '@/components/MkSelect.vue';
import MkFoldableSection from '@/components/MkFoldableSection.vue';
import MkTab from '@/components/MkTab.vue';
import * as os from '@/os';
-import { emojiCategories, emojiTags } from '@/instance';
+import { getCustomEmojis, getCustomEmojiCategories, getCustomEmojiTags } from '@/custom-emojis';
-export default defineComponent({
- components: {
- MkButton,
- MkInput,
- MkSelect,
- MkFoldableSection,
- MkTab,
- XEmoji,
- },
+const customEmojis = await getCustomEmojis();
+const customEmojiCategories = await getCustomEmojiCategories();
+const customEmojiTags = await getCustomEmojiTags();
+let q = $ref('');
+let searchEmojis = $ref(null);
+let selectedTags = $ref(new Set());
- data() {
- return {
- q: '',
- customEmojiCategories: emojiCategories,
- customEmojis: this.$instance.emojis,
- tags: emojiTags,
- selectedTags: new Set(),
- searchEmojis: null,
- };
- },
-
- watch: {
- q() { this.search(); },
- selectedTags: {
- handler() {
- this.search();
- },
- deep: true,
- },
- },
+function search() {
+ if ((q === '' || q == null) && selectedTags.size === 0) {
+ searchEmojis = null;
+ return;
+ }
- methods: {
- search() {
- if ((this.q === '' || this.q == null) && this.selectedTags.size === 0) {
- this.searchEmojis = null;
- return;
- }
+ if (selectedTags.size === 0) {
+ searchEmojis = customEmojis.filter(emoji => emoji.name.includes(q) || emoji.aliases.includes(q));
+ } else {
+ searchEmojis = customEmojis.filter(emoji => (emoji.name.includes(q) || emoji.aliases.includes(q)) && [...selectedTags].every(t => emoji.aliases.includes(t)));
+ }
+}
- if (this.selectedTags.size === 0) {
- this.searchEmojis = this.customEmojis.filter(emoji => emoji.name.includes(this.q) || emoji.aliases.includes(this.q));
- } else {
- this.searchEmojis = this.customEmojis.filter(emoji => (emoji.name.includes(this.q) || emoji.aliases.includes(this.q)) && [...this.selectedTags].every(t => emoji.aliases.includes(t)));
- }
- },
+function toggleTag(tag) {
+ if (selectedTags.has(tag)) {
+ selectedTags.delete(tag);
+ } else {
+ selectedTags.add(tag);
+ }
+}
- toggleTag(tag) {
- if (this.selectedTags.has(tag)) {
- this.selectedTags.delete(tag);
- } else {
- this.selectedTags.add(tag);
- }
- },
- },
+watch($$(q), () => {
+ search();
});
+
+watch($$(selectedTags), () => {
+ search();
+}, { deep: true });
</script>
<style lang="scss" scoped>
diff --git a/packages/frontend/src/pages/admin/emoji-edit-dialog.vue b/packages/frontend/src/pages/admin/emoji-edit-dialog.vue
index c0a997d7b4..0b6a5e1557 100644
--- a/packages/frontend/src/pages/admin/emoji-edit-dialog.vue
+++ b/packages/frontend/src/pages/admin/emoji-edit-dialog.vue
@@ -36,7 +36,7 @@ import MkInput from '@/components/MkInput.vue';
import * as os from '@/os';
import { unique } from '@/scripts/array';
import { i18n } from '@/i18n';
-import { emojiCategories } from '@/instance';
+import { getCustomEmojiCategories } from '@/custom-emojis';
const props = defineProps<{
emoji: any,
@@ -46,7 +46,7 @@ let dialog = $ref(null);
let name: string = $ref(props.emoji.name);
let category: string = $ref(props.emoji.category);
let aliases: string = $ref(props.emoji.aliases.join(' '));
-let categories: string[] = $ref(emojiCategories);
+const categories = await getCustomEmojiCategories();
const emit = defineEmits<{
(ev: 'done', v: { deleted?: boolean, updated?: any }): void,
diff --git a/packages/frontend/src/pages/admin/overview.stats.vue b/packages/frontend/src/pages/admin/overview.stats.vue
index 43a735cbf9..08f31676f3 100644
--- a/packages/frontend/src/pages/admin/overview.stats.vue
+++ b/packages/frontend/src/pages/admin/overview.stats.vue
@@ -36,7 +36,7 @@
<div class="icon"><i class="ti ti-icons"></i></div>
<div class="body">
<div class="value">
- <MkNumber :value="$instance.emojis.length" style="margin-right: 0.5em;"/>
+ <MkNumber :value="customEmojis.length" style="margin-right: 0.5em;"/>
</div>
<div class="label">Custom emojis</div>
</div>
@@ -63,6 +63,9 @@ import number from '@/filters/number';
import MkNumberDiff from '@/components/MkNumberDiff.vue';
import MkNumber from '@/components/MkNumber.vue';
import { i18n } from '@/i18n';
+import { getCustomEmojis } from '@/custom-emojis';
+
+const customEmojis = await getCustomEmojis();
let stats: any = $ref(null);
let usersComparedToThePrevDay = $ref<number>();
diff --git a/packages/frontend/src/pages/mfm-cheat-sheet.vue b/packages/frontend/src/pages/mfm-cheat-sheet.vue
index 697a692743..f49b6959c8 100644
--- a/packages/frontend/src/pages/mfm-cheat-sheet.vue
+++ b/packages/frontend/src/pages/mfm-cheat-sheet.vue
@@ -317,12 +317,15 @@ import MkTextarea from '@/components/MkTextarea.vue';
import { definePageMetadata } from '@/scripts/page-metadata';
import { i18n } from '@/i18n';
import { instance } from '@/instance';
+import { getCustomEmojis } from '@/custom-emojis';
+
+const customEmojis = await getCustomEmojis();
let preview_mention = $ref('@example');
let preview_hashtag = $ref('#test');
let preview_url = $ref('https://example.com');
let preview_link = $ref(`[${i18n.ts._mfm.dummy}](https://example.com)`);
-let preview_emoji = $ref(instance.emojis.length ? `:${instance.emojis[0].name}:` : ':emojiname:');
+let preview_emoji = $ref(customEmojis.length ? `:${customEmojis[0].name}:` : ':emojiname:');
let preview_bold = $ref(`**${i18n.ts._mfm.dummy}**`);
let preview_small = $ref(`<small>${i18n.ts._mfm.dummy}</small>`);
let preview_center = $ref(`<center>${i18n.ts._mfm.dummy}</center>`);
diff --git a/packages/frontend/src/pages/settings/index.vue b/packages/frontend/src/pages/settings/index.vue
index 3468d44e00..e1e050ee70 100644
--- a/packages/frontend/src/pages/settings/index.vue
+++ b/packages/frontend/src/pages/settings/index.vue
@@ -183,6 +183,8 @@ const menuDef = computed(() => [{
action: () => {
miLocalStorage.removeItem('locale');
miLocalStorage.removeItem('theme');
+ miLocalStorage.removeItem('emojis');
+ miLocalStorage.removeItem('lastEmojisFetchedAt');
unisonReload();
},
}, {