From 03b072b894b6be5ca8b94bb0ab73134705b45145 Mon Sep 17 00:00:00 2001 From: syuilo <syuilotan@yahoo.co.jp> Date: Sat, 14 Nov 2020 14:32:01 +0900 Subject: [PATCH] Resolve #6704 --- locales/ja-JP.yml | 1 + src/client/components/emoji-picker.vue | 9 ++-- src/client/os.ts | 5 +- src/client/pages/settings/reaction.vue | 72 +++++++++++++++++++------- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 6dcae50182..62da82b91c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -214,6 +214,7 @@ imageUrl: "画像URL" remove: "削除" removed: "削除しました" removeAreYouSure: "「{x}」を削除しますか?" +resetAreYouSure: "リセットしますか?" saved: "保存しました" messaging: "チャット" upload: "アップロード" diff --git a/src/client/components/emoji-picker.vue b/src/client/components/emoji-picker.vue index 5d60f2eb51..5cfd97e374 100644 --- a/src/client/components/emoji-picker.vue +++ b/src/client/components/emoji-picker.vue @@ -30,7 +30,7 @@ </section> <div class="index"> - <section> + <section v-if="showPinned"> <div> <button v-for="emoji in pinned" class="_button" @@ -109,8 +109,9 @@ export default defineComponent({ src: { required: false }, - overridePinned: { - required: false + showPinned: { + required: false, + default: true }, compact: { required: false @@ -123,7 +124,7 @@ export default defineComponent({ return { emojilist: markRaw(emojilist), getStaticImageUrl, - pinned: this.overridePinned || this.$store.state.settings.reactions, + pinned: this.$store.state.settings.reactions, customEmojiCategories: this.$store.getters['instance/emojiCategories'], customEmojis: this.$store.state.instance.meta.emojis, visibleCategories: {}, diff --git a/src/client/os.ts b/src/client/os.ts index e917f8a4a3..88d445ebac 100644 --- a/src/client/os.ts +++ b/src/client/os.ts @@ -275,10 +275,11 @@ export async function selectDriveFolder(multiple: boolean) { }); } -export async function pickEmoji(src?: HTMLElement) { +export async function pickEmoji(src?: HTMLElement, opts) { return new Promise((resolve, reject) => { popup(import('@/components/emoji-picker.vue'), { - src + src, + ...opts }, { done: emoji => { resolve(emoji); diff --git a/src/client/pages/settings/reaction.vue b/src/client/pages/settings/reaction.vue index 52b9f3260b..ad8430c2f7 100644 --- a/src/client/pages/settings/reaction.vue +++ b/src/client/pages/settings/reaction.vue @@ -3,15 +3,20 @@ <div class="_card"> <div class="_title"><Fa :icon="faLaugh"/> {{ $t('reaction') }}</div> <div class="_content"> - <MkInput v-model:value="reactions" style="font-family: 'Segoe UI Emoji', 'Noto Color Emoji', Roboto, HelveticaNeue, Arial, sans-serif"> - {{ $t('reaction') }}<template #desc>{{ $t('reactionSettingDescription') }} <button class="_textButton" @click="chooseEmoji">{{ $t('chooseEmoji') }}</button></template> - </MkInput> - <MkButton inline @click="setDefault"><Fa :icon="faUndo"/> {{ $t('default') }}</MkButton> + <XDraggable class="zoaiodol" :list="reactions" animation="150" delay="100" delay-on-touch-only="true"> + <button class="_button item" v-for="reaction in reactions" :key="reaction" @click="remove(reaction, $event)"> + <MkEmoji :emoji="reaction" :normal="true"/> + </button> + <template #footer> + <button>a</button> + </template> + </XDraggable> + <div class="_caption" style="padding: 8px;">{{ $t('reactionSettingDescription') }} <button class="_textButton" @click="chooseEmoji">{{ $t('chooseEmoji') }}</button></div> <MkSwitch v-model:value="useFullReactionPicker">{{ $t('useFullReactionPicker') }}</MkSwitch> </div> <div class="_footer"> - <MkButton @click="save()" primary inline :disabled="!changed"><Fa :icon="faSave"/> {{ $t('save') }}</MkButton> <MkButton inline @click="preview"><Fa :icon="faEye"/> {{ $t('preview') }}</MkButton> + <MkButton inline @click="setDefault"><Fa :icon="faUndo"/> {{ $t('default') }}</MkButton> </div> </div> </div> @@ -21,6 +26,7 @@ import { defineComponent } from 'vue'; import { faLaugh, faSave, faEye } from '@fortawesome/free-regular-svg-icons'; import { faUndo } from '@fortawesome/free-solid-svg-icons'; +import { VueDraggableNext } from 'vue-draggable-next'; import MkInput from '@/components/ui/input.vue'; import MkButton from '@/components/ui/button.vue'; import MkSwitch from '@/components/ui/switch.vue'; @@ -33,6 +39,7 @@ export default defineComponent({ MkInput, MkButton, MkSwitch, + XDraggable: VueDraggableNext, }, emits: ['info'], @@ -43,17 +50,12 @@ export default defineComponent({ title: this.$t('reaction'), icon: faLaugh }, - reactions: this.$store.state.settings.reactions.join(''), - changed: false, + reactions: JSON.parse(JSON.stringify(this.$store.state.settings.reactions)), faLaugh, faSave, faEye, faUndo } }, computed: { - splited(): any { - return this.reactions.match(emojiRegexWithCustom); - }, - useFullReactionPicker: { get() { return this.$store.state.device.useFullReactionPicker; }, set(value) { this.$store.commit('device/set', { key: 'useFullReactionPicker', value: value }); } @@ -63,7 +65,7 @@ export default defineComponent({ watch: { reactions: { handler() { - this.changed = true; + this.save(); }, deep: true } @@ -75,27 +77,59 @@ export default defineComponent({ methods: { save() { - this.$store.dispatch('settings/set', { key: 'reactions', value: this.splited }); - this.changed = false; + this.$store.dispatch('settings/set', { key: 'reactions', value: this.reactions }); + }, + + remove(reaction, ev) { + os.modalMenu([{ + text: this.$t('remove'), + action: () => { + this.reactions = this.reactions.filter(x => x !== reaction) + } + }], ev.currentTarget || ev.target); }, preview(ev) { os.popup(import('@/components/emoji-picker.vue'), { - overridePinned: this.splited, compact: !this.$store.state.device.useFullReactionPicker, src: ev.currentTarget || ev.target, }, {}, 'closed'); }, - setDefault() { - this.reactions = defaultSettings.reactions.join(''); + async setDefault() { + const { canceled } = await os.dialog({ + type: 'warning', + text: this.$t('resetAreYouSure'), + showCancelButton: true + }); + if (canceled) return; + + this.reactions = JSON.parse(JSON.stringify(defaultSettings.reactions)); }, chooseEmoji(ev) { - os.pickEmoji(ev.currentTarget || ev.target).then(emoji => { - this.reactions += emoji; + os.pickEmoji(ev.currentTarget || ev.target, { + showPinned: false + }).then(emoji => { + if (!this.reactions.includes(emoji)) { + this.reactions.push(emoji); + } }); } } }); </script> + +<style lang="scss" scoped> +.zoaiodol { + border: solid 1px var(--divider); + border-radius: var(--radius); + padding: 16px; + + > .item { + display: inline-block; + padding: 8px; + cursor: move; + } +} +</style>