From 9146bee7aa7229f041bcc77814d9fa40809329a6 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 8 Sep 2019 21:18:05 +0300 Subject: better hitbox for status emoji --- test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js index 20e03cb0..24aef5cd 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -323,9 +323,9 @@ describe('API Entities normalizer', () => { describe('MastoAPI emoji adder', () => { const emojis = makeMockEmojiMasto() - const imageHtml = 'image' + const imageHtml = 'image' .replace(/"/g, '\'') - const thinkHtml = 'thinking' + const thinkHtml = 'thinking' .replace(/"/g, '\'') it('correctly replaces shortcodes in supplied string', () => { -- cgit v1.2.3-70-g09d2 From 0d8b68632b02565e5ba7a833e91e41daabb4a1dc Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 12 Sep 2019 19:15:22 +0300 Subject: Remove emoji zoom --- src/components/emoji_picker/emoji_picker.js | 7 ------- src/components/emoji_picker/emoji_picker.scss | 19 ------------------- src/components/emoji_picker/emoji_picker.vue | 20 ++------------------ src/components/status/status.vue | 19 ------------------- .../entity_normalizer/entity_normalizer.service.js | 2 +- .../entity_normalizer/entity_normalizer.spec.js | 4 ++-- 6 files changed, 5 insertions(+), 66 deletions(-) (limited to 'test') diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index d9d41bf6..bce5026e 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -17,7 +17,6 @@ const EmojiPicker = { keyword: '', activeGroup: 'custom', showingStickers: false, - zoomEmoji: false, spamMode: false } }, @@ -61,12 +60,6 @@ const EmojiPicker = { }, onStickerUploadFailed (e) { this.$emit('sticker-upload-failed', e) - }, - setZoomEmoji (e, emoji) { - this.zoomEmoji = emoji - const { x, y } = e.target.getBoundingClientRect() - this.$refs['zoom-portal'].style.left = (x - 32) + 'px' - this.$refs['zoom-portal'].style.top = (y - 32) + 'px' } }, watch: { diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index 7e76aa52..472db35b 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -10,21 +10,6 @@ margin: 0 !important; z-index: 1; - .zoom-portal { - position: fixed; - pointer-events: none; - width: 96px; - height: 96px; - font-size: 96px; - line-height: 96px; - z-index: 10; - img { - object-fit: contain; - width: 100%; - height: 100%; - } - } - .spam-mode { padding: 7px; line-height: normal; @@ -150,10 +135,6 @@ cursor: pointer; - &:hover { - opacity: 0 - } - img { object-fit: contain; max-width: 100%; diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 1c91c8b7..901520aa 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -65,16 +65,12 @@ :title="emoji.displayText" class="emoji-item" @click.stop.prevent="onEmoji(emoji)" - @mouseenter="setZoomEmoji($event, emoji)" - @mouseleave="setZoomEmoji($event, false)" > - - {{ emoji.replacement }} - + {{ emoji.replacement }} + > @@ -99,18 +95,6 @@ /> -
- - - {{ zoomEmoji.replacement }} - - - -
diff --git a/src/components/status/status.vue b/src/components/status/status.vue index a0756ae4..771615f3 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -696,22 +696,6 @@ $status-margin: 0.75em; line-height: 1.4em; white-space: pre-wrap; - .emoji-container { - display: inline-block; - width: 32px; - height: 32px; - z-index: 1; - - &:hover { - z-index: 2; - - .emoji { - transform: scale(3); - z-index: 2; - } - } - } - img, video { max-width: 100%; max-height: 400px; @@ -721,9 +705,6 @@ $status-margin: 0.75em; &.emoji { width: 32px; height: 32px; - transition: transform 200ms; - transform: scale(1); - pointer-events: none; } } diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 17b4a6e0..6cc1851d 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -194,7 +194,7 @@ export const addEmojis = (string, emojis) => { return emojis.reduce((acc, emoji) => { return acc.replace( new RegExp(`:${emoji.shortcode}:`, 'g'), - `${emoji.shortcode}` + `${emoji.shortcode}` ) }, string) } diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js index 24aef5cd..20e03cb0 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -323,9 +323,9 @@ describe('API Entities normalizer', () => { describe('MastoAPI emoji adder', () => { const emojis = makeMockEmojiMasto() - const imageHtml = 'image' + const imageHtml = 'image' .replace(/"/g, '\'') - const thinkHtml = 'thinking' + const thinkHtml = 'thinking' .replace(/"/g, '\'') it('correctly replaces shortcodes in supplied string', () => { -- cgit v1.2.3-70-g09d2 From db961af3c8ee11823a4b33c3127635c280996183 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 15 Sep 2019 16:01:57 +0300 Subject: unit test for emoji input, for now covering only insertion mechanism --- test/unit/specs/components/emoji_input.spec.js | 122 +++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 test/unit/specs/components/emoji_input.spec.js (limited to 'test') diff --git a/test/unit/specs/components/emoji_input.spec.js b/test/unit/specs/components/emoji_input.spec.js new file mode 100644 index 00000000..5f24331a --- /dev/null +++ b/test/unit/specs/components/emoji_input.spec.js @@ -0,0 +1,122 @@ +import { shallowMount, createLocalVue } from '@vue/test-utils' +import EmojiInput from 'src/components/emoji_input/emoji_input.vue' + +const generateInput = (value) => { + const localVue = createLocalVue() + localVue.directive('click-outside', () => {}) + const wrapper = shallowMount(EmojiInput, { + propsData: { + suggest: () => [], + enableEmojiPicker: true, + value + }, + slots: { + default: '' + }, + localVue + }) + return [wrapper, localVue] +} + +describe('EmojiInput', () => { + describe('insertion mechanism', () => { + it('inserts string at the end with trailing space', () => { + const initialString = 'Testing' + const [wrapper] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: initialString.length }) + wrapper.vm.insert({ insertion: '(test)', spamMode: false }) + expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') + }) + + it('inserts string at the end with trailing space (source has a trailing space)', () => { + const initialString = 'Testing ' + const [wrapper] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: initialString.length }) + wrapper.vm.insert({ insertion: '(test)', spamMode: false }) + expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') + }) + + it('inserts string at the begginning without leading space', () => { + const initialString = 'Testing' + const [wrapper] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: 0 }) + wrapper.vm.insert({ insertion: '(test)', spamMode: false }) + expect(wrapper.emitted().input[0][0]).to.eql('(test) Testing') + }) + + it('inserts string between words without creating extra spaces', () => { + const initialString = 'Spurdo Sparde' + const [wrapper] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: 6 }) + wrapper.vm.insert({ insertion: ':ebin:', spamMode: false }) + expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') + }) + + it('inserts string between words without creating extra spaces (other caret)', () => { + const initialString = 'Spurdo Sparde' + const [wrapper] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: 7 }) + wrapper.vm.insert({ insertion: ':ebin:', spamMode: false }) + expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') + }) + + it('inserts string without any padding in spam mode', () => { + const initialString = 'Eat some spam!' + const [wrapper] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: initialString.length }) + wrapper.vm.insert({ insertion: ':spam:', spamMode: true }) + expect(wrapper.emitted().input[0][0]).to.eql('Eat some spam!:spam:') + }) + + it('correctly sets caret after insertion at beginning', (done) => { + const initialString = '1234' + const [wrapper, vue] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: 0 }) + wrapper.vm.insert({ insertion: '1234', spamMode: false }) + vue.nextTick(() => { + expect(wrapper.vm.caret).to.eql(5) + done() + }) + }) + + it('correctly sets caret after insertion at end', (done) => { + const initialString = '1234' + const [wrapper, vue] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: initialString.length }) + wrapper.vm.insert({ insertion: '1234', spamMode: false }) + vue.nextTick(() => { + expect(wrapper.vm.caret).to.eql(10) + done() + }) + }) + + it('correctly sets caret after insertion in spam mode', (done) => { + const initialString = '1234' + const [wrapper, vue] = generateInput(initialString) + const input = wrapper.find('input') + input.setValue(initialString) + wrapper.setData({ caret: initialString.length }) + wrapper.vm.insert({ insertion: '1234', spamMode: true }) + vue.nextTick(() => { + expect(wrapper.vm.caret).to.eql(8) + done() + }) + }) + }) +}) -- cgit v1.2.3-70-g09d2 From 7b4cb387345c0e278a6cfe5bbff5265c09281567 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 23 Sep 2019 20:29:01 +0300 Subject: split spam mode into two separate options (one in settings page) --- src/components/emoji_input/emoji_input.js | 15 +++++++++------ src/components/emoji_picker/emoji_picker.js | 4 ++-- src/components/emoji_picker/emoji_picker.scss | 4 ++-- src/components/emoji_picker/emoji_picker.vue | 12 ++++++------ src/components/settings/settings.js | 4 ++++ src/components/settings/settings.vue | 8 ++++++++ src/i18n/en.json | 3 ++- src/modules/config.js | 1 + test/unit/specs/components/emoji_input.spec.js | 18 +++++++++--------- 9 files changed, 43 insertions(+), 26 deletions(-) (limited to 'test') diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index 86ff9707..5f90d7f4 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -89,7 +89,7 @@ const EmojiInput = { blurTimeout: null, showPicker: false, temporarilyHideSuggestions: false, - spamMode: false, + keepOpen: false, disableClickOutside: false } }, @@ -97,6 +97,9 @@ const EmojiInput = { EmojiPicker }, computed: { + padEmoji () { + return this.$store.state.config.padEmoji + }, suggestions () { const firstchar = this.textAtCaret.charAt(0) if (this.textAtCaret === firstchar) { return [] } @@ -176,7 +179,7 @@ const EmojiInput = { this.$emit('input', newValue) this.caret = 0 }, - insert ({ insertion, spamMode }) { + insert ({ insertion, keepOpen }) { const before = this.value.substring(0, this.caret) || '' const after = this.value.substring(this.caret) || '' @@ -195,8 +198,8 @@ const EmojiInput = { * them, masto seem to be rendering :emoji::emoji: correctly now so why not */ const isSpaceRegex = /\s/ - const spaceBefore = !isSpaceRegex.exec(before.slice(-1)) && before.length && !spamMode > 0 ? ' ' : '' - const spaceAfter = !isSpaceRegex.exec(after[0]) && !spamMode ? ' ' : '' + const spaceBefore = !isSpaceRegex.exec(before.slice(-1)) && before.length && this.padEmoji > 0 ? ' ' : '' + const spaceAfter = !isSpaceRegex.exec(after[0]) && this.padEmoji ? ' ' : '' const newValue = [ before, @@ -205,7 +208,7 @@ const EmojiInput = { spaceAfter, after ].join('') - this.spamMode = spamMode + this.keepOpen = keepOpen this.$emit('input', newValue) const position = this.caret + (insertion + spaceAfter + spaceBefore).length @@ -283,7 +286,7 @@ const EmojiInput = { this.blurTimeout = null } - if (!this.spamMode) { + if (!this.keepOpen) { this.showPicker = false } this.focused = true diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index cb93f0c1..824412dd 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -18,7 +18,7 @@ const EmojiPicker = { activeGroup: 'custom', showingStickers: false, groupsScrolledClass: 'scrolled-top', - spamMode: false + keepOpen: false } }, components: { @@ -27,7 +27,7 @@ const EmojiPicker = { methods: { onEmoji (emoji) { const value = emoji.imageUrl ? `:${emoji.displayText}:` : emoji.replacement - this.$emit('emoji', { insertion: value, spamMode: this.spamMode }) + this.$emit('emoji', { insertion: value, keepOpen: this.keepOpen }) }, highlight (key) { const ref = this.$refs['group-' + key] diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index 09438898..b0ed00e9 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -10,11 +10,11 @@ margin: 0 !important; z-index: 1; - .spam-mode { + .keep-open { padding: 7px; line-height: normal; } - .spam-mode-label { + .keep-open-label { padding: 0 7px; display: flex; } diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index b32d0862..6c43dd97 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -76,16 +76,16 @@
-
diff --git a/src/i18n/en.json b/src/i18n/en.json index 7676e7a8..20d4ed22 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -109,7 +109,7 @@ "emoji": { "stickers": "Stickers", "emoji": "Emoji", - "spam": "Keep picker open, don't separate emoji with spaces", + "keep_open": "Keep picker open", "search_emoji": "Search for an emoji", "add_emoji": "Insert emoji", "custom": "Custom emoji", @@ -232,6 +232,7 @@ "delete_account_error": "There was an issue deleting your account. If this persists please contact your instance administrator.", "delete_account_instructions": "Type your password in the input below to confirm account deletion.", "avatar_size_instruction": "The recommended minimum size for avatar images is 150x150 pixels.", + "pad_emoji": "Pad emoji with spaces when adding from picker", "export_theme": "Save preset", "filtering": "Filtering", "filtering_explanation": "All statuses containing these words will be muted, one per line", diff --git a/src/modules/config.js b/src/modules/config.js index 2bfad8f6..cf04d14f 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -7,6 +7,7 @@ const defaultState = { colors: {}, hideMutedPosts: undefined, // instance default collapseMessageWithSubject: undefined, // instance default + padEmoji: true, hideAttachments: false, hideAttachmentsInConv: false, maxThumbnails: 16, diff --git a/test/unit/specs/components/emoji_input.spec.js b/test/unit/specs/components/emoji_input.spec.js index 5f24331a..13a59961 100644 --- a/test/unit/specs/components/emoji_input.spec.js +++ b/test/unit/specs/components/emoji_input.spec.js @@ -26,7 +26,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: initialString.length }) - wrapper.vm.insert({ insertion: '(test)', spamMode: false }) + wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') }) @@ -36,7 +36,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: initialString.length }) - wrapper.vm.insert({ insertion: '(test)', spamMode: false }) + wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) expect(wrapper.emitted().input[0][0]).to.eql('Testing (test) ') }) @@ -46,7 +46,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: 0 }) - wrapper.vm.insert({ insertion: '(test)', spamMode: false }) + wrapper.vm.insert({ insertion: '(test)', keepOpen: false }) expect(wrapper.emitted().input[0][0]).to.eql('(test) Testing') }) @@ -56,7 +56,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: 6 }) - wrapper.vm.insert({ insertion: ':ebin:', spamMode: false }) + wrapper.vm.insert({ insertion: ':ebin:', keepOpen: false }) expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') }) @@ -66,7 +66,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: 7 }) - wrapper.vm.insert({ insertion: ':ebin:', spamMode: false }) + wrapper.vm.insert({ insertion: ':ebin:', keepOpen: false }) expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') }) @@ -76,7 +76,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: initialString.length }) - wrapper.vm.insert({ insertion: ':spam:', spamMode: true }) + wrapper.vm.insert({ insertion: ':spam:', keepOpen: true }) expect(wrapper.emitted().input[0][0]).to.eql('Eat some spam!:spam:') }) @@ -86,7 +86,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: 0 }) - wrapper.vm.insert({ insertion: '1234', spamMode: false }) + wrapper.vm.insert({ insertion: '1234', keepOpen: false }) vue.nextTick(() => { expect(wrapper.vm.caret).to.eql(5) done() @@ -99,7 +99,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: initialString.length }) - wrapper.vm.insert({ insertion: '1234', spamMode: false }) + wrapper.vm.insert({ insertion: '1234', keepOpen: false }) vue.nextTick(() => { expect(wrapper.vm.caret).to.eql(10) done() @@ -112,7 +112,7 @@ describe('EmojiInput', () => { const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: initialString.length }) - wrapper.vm.insert({ insertion: '1234', spamMode: true }) + wrapper.vm.insert({ insertion: '1234', keepOpen: true }) vue.nextTick(() => { expect(wrapper.vm.caret).to.eql(8) done() -- cgit v1.2.3-70-g09d2 From 836cb817d18f5e3ee6dab446633b8e05733c2a3a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 25 Sep 2019 20:54:07 +0300 Subject: fix tests --- test/unit/specs/components/emoji_input.spec.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/unit/specs/components/emoji_input.spec.js b/test/unit/specs/components/emoji_input.spec.js index 13a59961..368d623d 100644 --- a/test/unit/specs/components/emoji_input.spec.js +++ b/test/unit/specs/components/emoji_input.spec.js @@ -1,7 +1,7 @@ import { shallowMount, createLocalVue } from '@vue/test-utils' import EmojiInput from 'src/components/emoji_input/emoji_input.vue' -const generateInput = (value) => { +const generateInput = (value, padEmoji = true) => { const localVue = createLocalVue() localVue.directive('click-outside', () => {}) const wrapper = shallowMount(EmojiInput, { @@ -10,6 +10,15 @@ const generateInput = (value) => { enableEmojiPicker: true, value }, + mocks: { + $store: { + state: { + config: { + padEmoji + } + } + } + }, slots: { default: '' }, @@ -70,13 +79,13 @@ describe('EmojiInput', () => { expect(wrapper.emitted().input[0][0]).to.eql('Spurdo :ebin: Sparde') }) - it('inserts string without any padding in spam mode', () => { + it('inserts string without any padding if padEmoji setting is set to false', () => { const initialString = 'Eat some spam!' - const [wrapper] = generateInput(initialString) + const [wrapper] = generateInput(initialString, false) const input = wrapper.find('input') input.setValue(initialString) - wrapper.setData({ caret: initialString.length }) - wrapper.vm.insert({ insertion: ':spam:', keepOpen: true }) + wrapper.setData({ caret: initialString.length, keepOpen: false }) + wrapper.vm.insert({ insertion: ':spam:' }) expect(wrapper.emitted().input[0][0]).to.eql('Eat some spam!:spam:') }) @@ -106,13 +115,13 @@ describe('EmojiInput', () => { }) }) - it('correctly sets caret after insertion in spam mode', (done) => { + it('correctly sets caret after insertion if padEmoji setting is set to false', (done) => { const initialString = '1234' - const [wrapper, vue] = generateInput(initialString) + const [wrapper, vue] = generateInput(initialString, false) const input = wrapper.find('input') input.setValue(initialString) wrapper.setData({ caret: initialString.length }) - wrapper.vm.insert({ insertion: '1234', keepOpen: true }) + wrapper.vm.insert({ insertion: '1234', keepOpen: false }) vue.nextTick(() => { expect(wrapper.vm.caret).to.eql(8) done() -- cgit v1.2.3-70-g09d2