From dd3c8631bf0ec21735d97c41e9e64d0d05643dbc Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Tue, 17 Nov 2020 17:46:26 +0200 Subject: store failed experiment --- src/components/emoji_input/emoji_input.js | 37 ++++++++++++++++++------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'src/components/emoji_input/emoji_input.js') diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index 87303d08..7fe25ff4 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -114,7 +114,8 @@ const EmojiInput = { showPicker: false, temporarilyHideSuggestions: false, keepOpen: false, - disableClickOutside: false + disableClickOutside: false, + suggestions: [] } }, components: { @@ -124,21 +125,6 @@ const EmojiInput = { padEmoji () { return this.$store.getters.mergedConfig.padEmoji }, - suggestions () { - const firstchar = this.textAtCaret.charAt(0) - if (this.textAtCaret === firstchar) { return [] } - const matchedSuggestions = this.suggest(this.textAtCaret) - if (matchedSuggestions.length <= 0) { - return [] - } - return take(matchedSuggestions, 5) - .map(({ imageUrl, ...rest }, index) => ({ - ...rest, - // eslint-disable-next-line camelcase - img: imageUrl || '', - highlighted: index === this.highlighted - })) - }, showSuggestions () { return this.focused && this.suggestions && @@ -187,7 +173,25 @@ const EmojiInput = { }, watch: { showSuggestions: function (newValue) { + console.log('showSuggestions watch', newValue, this.suggestions) this.$emit('shown', newValue) + }, + textAtCaret: async function (textAtCaret) { + const firstchar = textAtCaret.charAt(0) + this.suggestions = [] + if (textAtCaret === firstchar) return + const matchedSuggestions = await this.suggest(textAtCaret) + // Async, cancel if textAtCaret has been updated while waiting + if (this.textAtCaret !== textAtCaret) return + if (matchedSuggestions.length <= 0) return + this.suggestions = take(matchedSuggestions, 10) + .map(({ imageUrl, ...rest }, index) => ({ + ...rest, + // eslint-disable-next-line camelcase + img: imageUrl || '', + highlighted: index === this.highlighted + })) + this.scrollIntoView() } }, methods: { @@ -341,6 +345,7 @@ const EmojiInput = { const { offsetHeight } = this.input.elm const { picker } = this.$refs const pickerBottom = picker.$el.getBoundingClientRect().bottom + console.log('setting bottom', pickerBottom > window.innerHeight) if (pickerBottom > window.innerHeight) { picker.$el.style.top = 'auto' picker.$el.style.bottom = offsetHeight + 'px' -- cgit v1.2.3-70-g09d2 From 0f386ccbc7115fd1d74615377beca9982dec00bf Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Wed, 18 Nov 2020 18:43:24 +0200 Subject: use users state + fetching with delay --- src/components/emoji_input/emoji_input.js | 8 +++---- src/components/emoji_input/suggestor.js | 28 +++++++++++++++------- .../post_status_form/post_status_form.js | 2 +- src/components/settings_modal/tabs/profile_tab.js | 8 ++----- 4 files changed, 27 insertions(+), 19 deletions(-) (limited to 'src/components/emoji_input/emoji_input.js') diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index 7fe25ff4..16243a56 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -173,7 +173,6 @@ const EmojiInput = { }, watch: { showSuggestions: function (newValue) { - console.log('showSuggestions watch', newValue, this.suggestions) this.$emit('shown', newValue) }, textAtCaret: async function (textAtCaret) { @@ -184,14 +183,16 @@ const EmojiInput = { // Async, cancel if textAtCaret has been updated while waiting if (this.textAtCaret !== textAtCaret) return if (matchedSuggestions.length <= 0) return - this.suggestions = take(matchedSuggestions, 10) + this.suggestions = take(matchedSuggestions, 5) .map(({ imageUrl, ...rest }, index) => ({ ...rest, // eslint-disable-next-line camelcase img: imageUrl || '', highlighted: index === this.highlighted })) - this.scrollIntoView() + }, + suggestions (newValue) { + this.$nextTick(this.resize) } }, methods: { @@ -345,7 +346,6 @@ const EmojiInput = { const { offsetHeight } = this.input.elm const { picker } = this.$refs const pickerBottom = picker.$el.getBoundingClientRect().bottom - console.log('setting bottom', pickerBottom > window.innerHeight) if (pickerBottom > window.innerHeight) { picker.$el.style.top = 'auto' picker.$el.style.bottom = offsetHeight + 'px' diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js index 9bf53183..0d268f85 100644 --- a/src/components/emoji_input/suggestor.js +++ b/src/components/emoji_input/suggestor.js @@ -12,13 +12,13 @@ export default data => { const emojiCurry = suggestEmoji(data.emoji) - const usersCurry = suggestUsers(data.dispatch) + const usersCurry = data.store && suggestUsers(data.store) return input => { const firstChar = input[0] if (firstChar === ':' && data.emoji) { return emojiCurry(input) } - if (firstChar === '@' && data.dispatch) { + if (firstChar === '@' && usersCurry) { return usersCurry(input) } return [] @@ -56,18 +56,24 @@ export const suggestEmoji = emojis => input => { }) } -export const suggestUsers = (dispatch) => { +export const suggestUsers = ({ dispatch, state }) => { let suggestions = [] let previousQuery = '' let timeout = null + let cancelUserSearch = null - const userSearch = (query) => dispatch('searchUsers', { query, saveUsers: false }) + const userSearch = (query) => dispatch('searchUsers', { query }) const debounceUserSearch = (query) => { + cancelUserSearch && cancelUserSearch() return new Promise((resolve, reject) => { clearTimeout(timeout) timeout = setTimeout(() => { userSearch(query).then(resolve).catch(reject) }, 300) + cancelUserSearch = () => { + clearTimeout(timeout) + resolve([]) + } }) } @@ -77,9 +83,15 @@ export const suggestUsers = (dispatch) => { suggestions = [] previousQuery = noPrefix - const users = await debounceUserSearch(noPrefix) + // Fetch more and wait, don't fetch if there's the 2nd @ because + // the backend user search can't deal with it. + // Reference semantics make it so that we get the updated data after + // the await. + if (!noPrefix.includes('@')) { + await debounceUserSearch(noPrefix) + } - const newUsers = users.filter( + const newSuggestions = state.users.users.filter( user => user.screen_name.toLowerCase().startsWith(noPrefix) || user.name.toLowerCase().startsWith(noPrefix) @@ -114,9 +126,9 @@ export const suggestUsers = (dispatch) => { imageUrl: profile_image_url_original, replacement: '@' + screen_name + ' ' })) + /* eslint-enable camelcase */ - suggestions = newUsers || [] + suggestions = newSuggestions || [] return suggestions - /* eslint-enable camelcase */ } } diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index e38f1c0c..4148381c 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -159,7 +159,7 @@ const PostStatusForm = { ...this.$store.state.instance.emoji, ...this.$store.state.instance.customEmoji ], - dispatch: this.$store.dispatch + store: this.$store }) }, emojiSuggestor () { diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js index a3e4feaf..a4fed629 100644 --- a/src/components/settings_modal/tabs/profile_tab.js +++ b/src/components/settings_modal/tabs/profile_tab.js @@ -68,8 +68,7 @@ const ProfileTab = { ...this.$store.state.instance.emoji, ...this.$store.state.instance.customEmoji ], - users: this.$store.state.users.users, - updateUsersList: (query) => this.$store.dispatch('searchUsers', { query }) + store: this.$store }) }, emojiSuggestor () { @@ -79,10 +78,7 @@ const ProfileTab = { ] }) }, userSuggestor () { - return suggestor({ - users: this.$store.state.users.users, - updateUsersList: (query) => this.$store.dispatch('searchUsers', { query }) - }) + return suggestor({ store: this.$store }) }, fieldsLimits () { return this.$store.state.instance.fieldsLimits -- cgit v1.2.3-70-g09d2 From 1495db084ae49cc5133678d61e19d90333cbe31d Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Thu, 19 Nov 2020 11:37:06 +0200 Subject: fix keyboard highlight --- src/components/emoji_input/emoji_input.js | 5 ++--- src/components/emoji_input/emoji_input.vue | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/components/emoji_input/emoji_input.js') diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index 16243a56..d32e19bf 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -184,11 +184,10 @@ const EmojiInput = { if (this.textAtCaret !== textAtCaret) return if (matchedSuggestions.length <= 0) return this.suggestions = take(matchedSuggestions, 5) - .map(({ imageUrl, ...rest }, index) => ({ + .map(({ imageUrl, ...rest }) => ({ ...rest, // eslint-disable-next-line camelcase - img: imageUrl || '', - highlighted: index === this.highlighted + img: imageUrl || '' })) }, suggestions (newValue) { diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue index 224e72cf..107e16c1 100644 --- a/src/components/emoji_input/emoji_input.vue +++ b/src/components/emoji_input/emoji_input.vue @@ -37,7 +37,7 @@ v-for="(suggestion, index) in suggestions" :key="index" class="autocomplete-item" - :class="{ highlighted: suggestion.highlighted }" + :class="{ highlighted: index === highlighted }" @click.stop.prevent="onClick($event, suggestion)" > -- cgit v1.2.3-70-g09d2 From 419df9d44673bf1abe3cda7ba6cafee9dd6eaba4 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Thu, 19 Nov 2020 12:35:21 +0200 Subject: update some documentation --- src/components/emoji_input/emoji_input.js | 12 ++++++------ src/components/emoji_input/suggestor.js | 8 ++------ 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src/components/emoji_input/emoji_input.js') diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index d32e19bf..3deeb6c8 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -175,13 +175,13 @@ const EmojiInput = { showSuggestions: function (newValue) { this.$emit('shown', newValue) }, - textAtCaret: async function (textAtCaret) { - const firstchar = textAtCaret.charAt(0) + textAtCaret: async function (newWord) { + const firstchar = newWord.charAt(0) this.suggestions = [] - if (textAtCaret === firstchar) return - const matchedSuggestions = await this.suggest(textAtCaret) - // Async, cancel if textAtCaret has been updated while waiting - if (this.textAtCaret !== textAtCaret) return + if (newWord === firstchar) return + const matchedSuggestions = await this.suggest(newWord) + // Async: cancel if textAtCaret has changed during wait + if (this.textAtCaret !== newWord) return if (matchedSuggestions.length <= 0) return this.suggestions = take(matchedSuggestions, 5) .map(({ imageUrl, ...rest }) => ({ diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js index 0d268f85..14a2b41e 100644 --- a/src/components/emoji_input/suggestor.js +++ b/src/components/emoji_input/suggestor.js @@ -57,6 +57,8 @@ export const suggestEmoji = emojis => input => { } export const suggestUsers = ({ dispatch, state }) => { + // Keep some persistent values in closure, most importantly for the + // custom debounce to work. Lodash debounce does not return a promise. let suggestions = [] let previousQuery = '' let timeout = null @@ -66,7 +68,6 @@ export const suggestUsers = ({ dispatch, state }) => { const debounceUserSearch = (query) => { cancelUserSearch && cancelUserSearch() return new Promise((resolve, reject) => { - clearTimeout(timeout) timeout = setTimeout(() => { userSearch(query).then(resolve).catch(reject) }, 300) @@ -95,11 +96,6 @@ export const suggestUsers = ({ dispatch, state }) => { user => user.screen_name.toLowerCase().startsWith(noPrefix) || user.name.toLowerCase().startsWith(noPrefix) - - /* taking only 20 results so that sorting is a bit cheaper, we display - * only 5 anyway. could be inaccurate, but we ideally we should query - * backend anyway - */ ).slice(0, 20).sort((a, b) => { let aScore = 0 let bScore = 0 -- cgit v1.2.3-70-g09d2 From e6e3b752d65fe2038a1b42ef9ddae8c21bf1cad2 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Fri, 27 Nov 2020 15:51:58 +0200 Subject: review fixes --- src/components/emoji_input/emoji_input.js | 1 - src/modules/users.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/components/emoji_input/emoji_input.js') diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index 3deeb6c8..2068a598 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -186,7 +186,6 @@ const EmojiInput = { this.suggestions = take(matchedSuggestions, 5) .map(({ imageUrl, ...rest }) => ({ ...rest, - // eslint-disable-next-line camelcase img: imageUrl || '' })) }, diff --git a/src/modules/users.js b/src/modules/users.js index 4bdf3360..655db4c7 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -442,10 +442,10 @@ const users = { store.commit('setUserForNotification', notification) }) }, - searchUsers ({ rootState, commit }, { query, saveUsers = true }) { + searchUsers ({ rootState, commit }, { query }) { return rootState.api.backendInteractor.searchUsers({ query }) .then((users) => { - if (saveUsers) commit('addNewUsers', users) + commit('addNewUsers', users) return users }) }, -- cgit v1.2.3-70-g09d2