summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2021-02-27 19:53:20 +0900
committersyuilo <syuilotan@yahoo.co.jp>2021-02-27 19:53:20 +0900
commit21e1906fbf393b82c04d86cd93cc6628ebdfd902 (patch)
treeb9c92207102fe2aa766813bc8e6c0bd2051d2874 /src
parentrefactoring (diff)
downloadsharkey-21e1906fbf393b82c04d86cd93cc6628ebdfd902.tar.gz
sharkey-21e1906fbf393b82c04d86cd93cc6628ebdfd902.tar.bz2
sharkey-21e1906fbf393b82c04d86cd93cc6628ebdfd902.zip
Resolve #7264
Diffstat (limited to 'src')
-rw-r--r--src/client/components/emoji-picker.section.vue52
-rw-r--r--src/client/components/emoji-picker.vue179
-rw-r--r--src/client/instance.ts10
3 files changed, 143 insertions, 98 deletions
diff --git a/src/client/components/emoji-picker.section.vue b/src/client/components/emoji-picker.section.vue
new file mode 100644
index 0000000000..a12493ce0d
--- /dev/null
+++ b/src/client/components/emoji-picker.section.vue
@@ -0,0 +1,52 @@
+<template>
+<section>
+ <header class="_acrylic" @click="shown = !shown">
+ <Fa :icon="shown ? faChevronDown : faChevronUp" :key="shown" fixed-width class="toggle"/> <slot></slot> ({{ emojis.length }})
+ </header>
+ <div v-if="shown">
+ <button v-for="emoji in emojis"
+ class="_button"
+ @click="chosen(emoji, $event)"
+ :key="emoji"
+ >
+ <MkEmoji :emoji="emoji" :normal="true"/>
+ </button>
+ </div>
+</section>
+</template>
+
+<script lang="ts">
+import { defineComponent, markRaw } from 'vue';
+import { faChevronUp, faChevronDown } from '@fortawesome/free-solid-svg-icons';
+import { getStaticImageUrl } from '@/scripts/get-static-image-url';
+
+export default defineComponent({
+ props: {
+ emojis: {
+ required: true,
+ },
+ initialShown: {
+ required: false
+ }
+ },
+
+ emits: ['chosen'],
+
+ data() {
+ return {
+ getStaticImageUrl,
+ shown: this.initialShown,
+ faChevronUp, faChevronDown,
+ };
+ },
+
+ methods: {
+ chosen(emoji: any, ev) {
+ this.$parent.chosen(emoji, ev);
+ },
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/src/client/components/emoji-picker.vue b/src/client/components/emoji-picker.vue
index 93530e16c8..b11f0a62fa 100644
--- a/src/client/components/emoji-picker.vue
+++ b/src/client/components/emoji-picker.vue
@@ -28,7 +28,7 @@
</div>
</section>
- <div class="index">
+ <div class="index" v-if="tab === 'index'">
<section v-if="showPinned">
<div>
<button v-for="emoji in pinned"
@@ -53,37 +53,31 @@
</button>
</div>
</section>
-
- <div class="arrow"><Fa :icon="faChevronDown"/></div>
</div>
-
- <section v-for="category in customEmojiCategories" :key="'custom:' + category" class="custom">
- <header class="_acrylic" v-appear="() => visibleCategories[category] = true">{{ category || $ts.other }}</header>
- <div v-if="visibleCategories[category]">
- <button v-for="emoji in customEmojis.filter(e => e.category === category)"
- class="_button"
- :title="emoji.name"
- @click="chosen(emoji, $event)"
- :key="emoji.name"
- >
- <img :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
- </button>
- </div>
- </section>
-
- <section v-for="category in categories" :key="category.name" class="unicode">
- <header class="_acrylic" v-appear="() => category.isActive = true"><Fa :icon="category.icon" fixed-width/> {{ category.name }}</header>
- <div v-if="category.isActive">
- <button v-for="emoji in emojilist.filter(e => e.category === category.name)"
- class="_button"
- :title="emoji.name"
- @click="chosen(emoji, $event)"
- :key="emoji.name"
- >
- <MkEmoji :emoji="emoji.char"/>
- </button>
- </div>
- </section>
+ <div v-appear="() => showingCustomEmojis = true">
+ <header class="_acrylic">{{ $ts.customEmojis }}</header>
+ <template v-if="showingCustomEmojis">
+ <XSection v-for="category in customEmojiCategories" :key="'custom:' + category" :initial-shown="false" :emojis="customEmojis.filter(e => e.category === category).map(e => ':' + e.name + ':')">{{ category || $ts.other }}</XSection>
+ </template>
+ </div>
+ <div v-appear="() => showingEmojis = true">
+ <header class="_acrylic">{{ $ts.emoji }}</header>
+ <template v-if="showingEmojis">
+ <XSection v-for="category in categories" :emojis="emojilist.filter(e => e.category === category).map(e => e.char)">{{ category }}</XSection>
+ </template>
+ </div>
+ <div v-appear="() => showingTags = true">
+ <header class="_acrylic">{{ $ts.tags }}</header>
+ <template v-if="showingTags">
+ <XSection v-for="tag in emojiTags" :emojis="customEmojis.filter(e => e.aliases.includes(tag)).map(e => ':' + e.name + ':')">{{ tag }}</XSection>
+ </template>
+ </div>
+ </div>
+ <div class="tabs">
+ <button class="_button tab" :class="{ active: tab === 'index' }" @click="tab = 'index'"><Fa :icon="faAsterisk" fixed-width/></button>
+ <button class="_button tab" :class="{ active: tab === 'custom' }" @click="tab = 'custom'"><Fa :icon="faLaugh" fixed-width/></button>
+ <button class="_button tab" :class="{ active: tab === 'unicode' }" @click="tab = 'unicode'"><Fa :icon="faLeaf" fixed-width/></button>
+ <button class="_button tab" :class="{ active: tab === 'tags' }" @click="tab = 'tags'"><Fa :icon="faHashtag" fixed-width/></button>
</div>
</div>
</template>
@@ -92,15 +86,20 @@
import { defineComponent, markRaw } from 'vue';
import { emojilist } from '../../misc/emojilist';
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
-import { faAsterisk, faLeaf, faUtensils, faFutbol, faCity, faDice, faGlobe, faClock, faUser, faChevronDown } from '@fortawesome/free-solid-svg-icons';
+import { faAsterisk, faLeaf, faUtensils, faFutbol, faCity, faDice, faGlobe, faClock, faUser, faChevronDown, faShapes, faBicycle, faHashtag } from '@fortawesome/free-solid-svg-icons';
import { faHeart, faFlag, faLaugh } from '@fortawesome/free-regular-svg-icons';
import Particle from '@/components/particle.vue';
import * as os from '@/os';
import { isDeviceTouch } from '@/scripts/is-device-touch';
import { isMobile } from '@/scripts/is-mobile';
-import { emojiCategories } from '@/instance';
+import { emojiCategories, emojiTags } from '@/instance';
+import XSection from './emoji-picker.section.vue';
export default defineComponent({
+ components: {
+ XSection
+ },
+
props: {
showPinned: {
required: false,
@@ -122,50 +121,17 @@ export default defineComponent({
height: this.asReactionPicker ? this.$store.state.reactionPickerHeight : 2,
big: this.asReactionPicker ? isDeviceTouch : false,
customEmojiCategories: emojiCategories,
+ emojiTags,
customEmojis: this.$instance.emojis,
- visibleCategories: {},
q: null,
searchResultCustom: [],
searchResultUnicode: [],
- faGlobe, faClock, faChevronDown,
- categories: [{
- name: 'face',
- icon: faLaugh,
- isActive: false
- }, {
- name: 'people',
- icon: faUser,
- isActive: false
- }, {
- name: 'animals_and_nature',
- icon: faLeaf,
- isActive: false
- }, {
- name: 'food_and_drink',
- icon: faUtensils,
- isActive: false
- }, {
- name: 'activity',
- icon: faFutbol,
- isActive: false
- }, {
- name: 'travel_and_places',
- icon: faCity,
- isActive: false
- }, {
- name: 'objects',
- icon: faDice,
- isActive: false
- }, {
- name: 'symbols',
- icon: faHeart,
- isActive: false
- }, {
- name: 'flags',
- icon: faFlag,
- isActive: false
- }],
- faAsterisk
+ tab: 'index',
+ showingCustomEmojis: false,
+ showingEmojis: false,
+ showingTags: false,
+ categories: ['face', 'people', 'animals_and_nature', 'food_and_drink', 'activity', 'travel_and_places', 'objects', 'symbols', 'flags'],
+ faGlobe, faClock, faChevronDown, faAsterisk, faLaugh, faUtensils, faLeaf, faShapes, faBicycle, faHashtag,
};
},
@@ -342,7 +308,7 @@ export default defineComponent({
let recents = this.$store.state.recentlyUsedEmojis;
recents = recents.filter((e: any) => e !== key);
recents.unshift(key);
- this.$store.set('recentlyUsedEmojis', recents.splice(0, 16));
+ this.$store.set('recentlyUsedEmojis', recents.splice(0, 32));
}
},
@@ -434,6 +400,22 @@ export default defineComponent({
}
}
+ > .tabs {
+ display: flex;
+ display: none;
+
+ > .tab {
+ flex: 1;
+ height: 38px;
+ border-top: solid 1px var(--divider);
+
+ &.active {
+ border-top: solid 1px var(--accent);
+ color: var(--accent);
+ }
+ }
+ }
+
> .emojis {
height: var(--height);
overflow-y: auto;
@@ -445,34 +427,43 @@ export default defineComponent({
display: none;
}
- > .index {
- min-height: var(--height);
- position: relative;
- border-bottom: solid 1px var(--divider);
-
- > .arrow {
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- padding: 16px 0;
- text-align: center;
- opacity: 0.5;
- pointer-events: none;
+ > div {
+ &:not(.index) {
+ padding: 4px 0 8px 0;
+ border-top: solid 1px var(--divider);
+ }
+
+ > header {
+ /*position: sticky;
+ top: 0;
+ left: 0;*/
+ height: 32px;
+ line-height: 32px;
+ z-index: 2;
+ padding: 0 8px;
+ font-size: 12px;
}
}
- section {
+ ::v-deep(section) {
> header {
position: sticky;
top: 0;
left: 0;
+ height: 32px;
+ line-height: 32px;
z-index: 1;
- padding: 8px;
+ padding: 0 8px;
font-size: 12px;
+ cursor: pointer;
+
+ &:hover {
+ color: var(--accent);
+ }
}
> div {
+ position: relative;
padding: $pad;
> button {
@@ -512,14 +503,6 @@ export default defineComponent({
display: none;
}
}
-
- &.unicode {
- min-height: 384px;
- }
-
- &.custom {
- min-height: 64px;
- }
}
}
}
diff --git a/src/client/instance.ts b/src/client/instance.ts
index 89c0368599..bd6b1bd571 100644
--- a/src/client/instance.ts
+++ b/src/client/instance.ts
@@ -37,6 +37,16 @@ export const emojiCategories = computed(() => {
return Array.from(categories);
});
+export const emojiTags = computed(() => {
+ const tags = new Set();
+ for (const emoji of instance.emojis) {
+ for (const tag of emoji.aliases) {
+ tags.add(tag);
+ }
+ }
+ return Array.from(tags);
+});
+
// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {