From e104ac0e6bacb449d52ec3f8782790f8e80e5581 Mon Sep 17 00:00:00 2001 From: AkiraFukushima Date: Mon, 12 Nov 2018 22:07:13 +0900 Subject: [PATCH 1/2] Change suggestion logic for performance --- .../TimelineSpace/Modals/NewToot/Status.vue | 71 +++++++++---------- src/renderer/utils/suggestText.js | 4 +- 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/renderer/components/TimelineSpace/Modals/NewToot/Status.vue b/src/renderer/components/TimelineSpace/Modals/NewToot/Status.vue index 95237537..6cd39cd2 100644 --- a/src/renderer/components/TimelineSpace/Modals/NewToot/Status.vue +++ b/src/renderer/components/TimelineSpace/Modals/NewToot/Status.vue @@ -132,35 +132,38 @@ export default { } }, methods: { - startSuggest (e) { + async startSuggest (e) { const currentValue = e.target.value // Start suggest after user stop writing - setTimeout(() => { + setTimeout(async () => { if (currentValue === this.status) { - this.suggest(e) + await this.suggest(e) } - }, 500) + }, 700) }, async suggest (e) { - const emoji = this.suggestEmoji(e) - if (emoji) { - return true - } - const ac = await this.suggestAccount(e) - if (ac) { - return true - } - const tag = await this.suggestHashtag(e) - return tag - }, - async suggestAccount (e) { // e.target.sectionStart: Cursor position // e.target.value: current value of the textarea - const [start, word] = suggestText(e.target.value, e.target.selectionStart, '@') + const [start, word] = suggestText(e.target.value, e.target.selectionStart) if (!start || !word) { this.closeSuggest() return false } + switch (word.charAt(0)) { + case ':': + await this.suggestEmoji(start, word) + return true + case '@': + await this.suggestAccount(start, word) + return true + case '#': + await this.suggestHashtag(start, word) + return true + default: + return false + } + }, + async suggestAccount (start, word) { try { await this.$store.dispatch('TimelineSpace/Modals/NewToot/Status/searchAccount', word) this.openSuggest = true @@ -173,12 +176,7 @@ export default { return false } }, - async suggestHashtag (e) { - const [start, word] = suggestText(e.target.value, e.target.selectionStart, '#') - if (!start || !word) { - this.closeSuggest() - return false - } + async suggestHashtag (start, word) { try { await this.$store.dispatch('TimelineSpace/Modals/NewToot/Status/searchHashtag', word) this.openSuggest = true @@ -191,14 +189,7 @@ export default { return false } }, - suggestEmoji (e) { - // e.target.sectionStart: Cursor position - // e.target.value: current value of the textarea - const [start, word] = suggestText(e.target.value, e.target.selectionStart, ':') - if (!start || !word) { - this.closeSuggest() - return false - } + suggestEmoji (start, word) { // Find native emojis const filteredEmojiName = emojilib.ordered.filter(emoji => `:${emoji}`.includes(word)) const filteredNativeEmoji = filteredEmojiName.map((name) => { @@ -218,18 +209,20 @@ export default { return (array.findIndex(ar => e.name === ar.name) === i) }) } else { - this.openSuggest = false + this.closeSuggest() } return true }, closeSuggest () { - this.openSuggest = false - this.startIndex = null - this.matchWord = null - this.highlightedIndex = 0 - this.filteredSuggestion = [] - this.$store.commit('TimelineSpace/Modals/NewToot/Status/clearFilteredAccounts') - this.$store.commit('TimelineSpace/Modals/NewToot/Status/clearFilteredHashtags') + if (this.openSuggest) { + this.openSuggest = false + this.startIndex = null + this.matchWord = null + this.highlightedIndex = 0 + this.filteredSuggestion = [] + this.$store.commit('TimelineSpace/Modals/NewToot/Status/clearFilteredAccounts') + this.$store.commit('TimelineSpace/Modals/NewToot/Status/clearFilteredHashtags') + } }, suggestHighlight (index) { if (index < 0) { diff --git a/src/renderer/utils/suggestText.js b/src/renderer/utils/suggestText.js index 2f7dd800..a1e42526 100644 --- a/src/renderer/utils/suggestText.js +++ b/src/renderer/utils/suggestText.js @@ -1,5 +1,5 @@ // https://github.com/tootsuite/mastodon/blob/master/app/javascript/mastodon/components/autosuggest_textarea.js -const textAtCursorMatch = (str, cursorPosition, separator = '@') => { +const textAtCursorMatch = (str, cursorPosition, separators = ['@', '#', ':']) => { let word let left = str.slice(0, cursorPosition).search(/\S+$/) @@ -11,7 +11,7 @@ const textAtCursorMatch = (str, cursorPosition, separator = '@') => { word = str.slice(left, right + cursorPosition) } - if (!word || word.trim().length < 3 || [separator].indexOf(word[0]) === -1) { + if (!word || word.trim().length < 3 || separators.indexOf(word[0]) === -1) { return [null, null] } From 60406740dc2eb79e13e7efbefb9169ec44821712 Mon Sep 17 00:00:00 2001 From: AkiraFukushima Date: Mon, 12 Nov 2018 22:18:33 +0900 Subject: [PATCH 2/2] Remove status and spoiler text from state for performance --- .../TimelineSpace/Modals/NewToot.vue | 21 +++++-------------- .../store/TimelineSpace/Modals/NewToot.js | 19 +++++++---------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/renderer/components/TimelineSpace/Modals/NewToot.vue b/src/renderer/components/TimelineSpace/Modals/NewToot.vue index 6fb1a3d5..2d189403 100644 --- a/src/renderer/components/TimelineSpace/Modals/NewToot.vue +++ b/src/renderer/components/TimelineSpace/Modals/NewToot.vue @@ -92,6 +92,8 @@ export default { }, data () { return { + status: '', + spoiler: '', showContentWarning: false, visibilityList: Visibility } @@ -110,6 +112,7 @@ export default { blockSubmit: state => state.blockSubmit, visibility: state => state.visibility, sensitive: state => state.sensitive, + initialStatus: state => state.initialStatus, visibilityIcon: (state) => { switch (state.visibility) { case Visibility.Public.value: @@ -143,22 +146,6 @@ export default { } } }, - status: { - get () { - return this.$store.state.TimelineSpace.Modals.NewToot.status - }, - set (value) { - this.$store.commit('TimelineSpace/Modals/NewToot/updateStatus', value) - } - }, - spoiler: { - get () { - return this.$store.state.TimelineSpace.Modals.NewToot.spoiler - }, - set (value) { - this.$store.commit('TimelineSpace/Modals/NewToot/updateSpoiler', value) - } - }, pinedHashtag: { get () { return this.$store.state.TimelineSpace.Modals.NewToot.pinedHashtag @@ -172,6 +159,8 @@ export default { newTootModal: function (newState, oldState) { if (!oldState && newState) { this.showContentWarning = false + this.spoiler = '' + this.status = this.initialStatus } } }, diff --git a/src/renderer/store/TimelineSpace/Modals/NewToot.js b/src/renderer/store/TimelineSpace/Modals/NewToot.js index 916fd402..f2b88c97 100644 --- a/src/renderer/store/TimelineSpace/Modals/NewToot.js +++ b/src/renderer/store/TimelineSpace/Modals/NewToot.js @@ -10,13 +10,12 @@ const NewToot = { }, state: { modalOpen: false, - status: '', + initialStatus: '', replyToMessage: null, blockSubmit: false, attachedMedias: [], visibility: Visibility.Public.value, sensitive: false, - spoiler: '', attachedMediaId: 0, pinedHashtag: false, hashtags: [] @@ -28,8 +27,8 @@ const NewToot = { setReplyTo (state, message) { state.replyToMessage = message }, - updateStatus (state, status) { - state.status = status + updateInitialStatus (state, status) { + state.initialStatus = status }, changeBlockSubmit (state, value) { state.blockSubmit = value @@ -55,9 +54,6 @@ const NewToot = { changeSensitive (state, value) { state.sensitive = value }, - updateSpoiler (state, value) { - state.spoiler = value - }, updateMediaId (state, value) { state.attachedMediaId = value }, @@ -93,8 +89,8 @@ const NewToot = { const mentionAccounts = [message.account.acct].concat(message.mentions.map(a => a.acct)) .filter((a, i, self) => self.indexOf(a) === i) .filter((a) => a !== rootState.TimelineSpace.account.username) + commit('updateInitialStatus', `${mentionAccounts.map(m => `@${m}`).join(' ')} `) commit('changeModal', true) - commit('updateStatus', `${mentionAccounts.map(m => `@${m}`).join(' ')} `) let value = Visibility.Public.value Object.keys(Visibility).map((key, index) => { const target = Visibility[key] @@ -105,20 +101,19 @@ const NewToot = { commit('changeVisibilityValue', value) }, openModal ({ dispatch, commit, state, rootState }) { - commit('changeModal', true) if (!state.replyToMessage && state.pinedHashtag) { - commit('updateStatus', state.hashtags.map(t => ` #${t.name}`).join()) + commit('updateInitialStatus', state.hashtags.map(t => ` #${t.name}`).join()) } + commit('changeModal', true) dispatch('fetchVisibility') }, closeModal ({ commit }) { commit('changeModal', false) - commit('updateStatus', '') + commit('updateInitialStatus', '') commit('setReplyTo', null) commit('changeBlockSubmit', false) commit('clearAttachedMedias') commit('changeSensitive', false) - commit('updateSpoiler', '') commit('changeVisibilityValue', Visibility.Public.value) }, uploadImage ({ state, commit, rootState }, image) {