1
0
mirror of https://github.com/h3poteto/whalebird-desktop synced 2025-02-02 18:36:56 +01:00

Merge pull request #994 from h3poteto/iss-985

refs #985 Move suggest logic to vuex
This commit is contained in:
AkiraFukushima 2019-08-07 23:22:51 +09:00 committed by GitHub
commit 6edb0534fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 95 deletions

View File

@ -125,7 +125,8 @@
"jest": {
"moduleFileExtensions": [
"ts",
"js"
"js",
"json"
],
"moduleNameMapper": {
"@/router": "<rootDir>/spec/mock/router.ts",

View File

@ -241,12 +241,16 @@ describe('TimelineSpace', () => {
await store.dispatch('TimelineSpace/fetchEmojis', {})
expect(store.state.TimelineSpace.emojis).toEqual([
{
image: 'http://example.com/emacs',
name: ':emacs:'
shortcode: 'emacs',
url: 'http://example.com/emacs',
static_url: 'http://example.com/emacs',
visible_in_picker: true
},
{
image: 'http://example.com/ruby',
name: ':ruby:'
shortcode: 'ruby',
url: 'http://example.com/ruby',
static_url: 'http://example.com/ruby',
visible_in_picker: true
}
])
})

View File

@ -1,5 +1,4 @@
import TimelineSpace, { TimelineSpaceState, blankAccount, MUTATION_TYPES } from '~/src/renderer/store/TimelineSpace'
import { Emoji } from 'megalodon'
import unreadSettings from '~/src/constants/unreadNotification'
describe('TimelineSpace', () => {
@ -21,34 +20,6 @@ describe('TimelineSpace', () => {
}
})
describe('updateEmojis', () => {
it('should be updated', () => {
const emacsEmoji: Emoji = {
shortcode: 'emacs',
url: 'http://example.com/emacs',
static_url: 'http://example.com/emacs',
visible_in_picker: true
}
const rubyEmoji: Emoji = {
shortcode: 'ruby',
url: 'http://example.com/ruby',
static_url: 'http://example.com/ruby',
visible_in_picker: true
}
TimelineSpace.mutations![MUTATION_TYPES.UPDATE_EMOJIS](state, [emacsEmoji, rubyEmoji])
expect(state.emojis).toEqual([
{
image: 'http://example.com/emacs',
name: ':emacs:'
},
{
image: 'http://example.com/ruby',
name: ':ruby:'
}
])
})
})
describe('updateTootMax', () => {
describe('value is null', () => {
it('should be updated with 500', () => {

View File

@ -51,10 +51,9 @@
<script>
import { mapState, mapGetters } from 'vuex'
import emojilib from 'emojilib'
import { Picker } from 'emoji-mart-vue'
import ClickOutside from 'vue-click-outside'
import suggestText from '../../../../utils/suggestText'
import suggestText from '@/utils/suggestText'
export default {
name: 'status',
@ -84,9 +83,6 @@ export default {
}
},
computed: {
...mapState({
customEmojis: state => state.TimelineSpace.emojis
}),
...mapState('TimelineSpace/Modals/NewToot/Status', {
filteredAccounts: state => state.filteredAccounts,
filteredHashtags: state => state.filteredHashtags,
@ -162,11 +158,7 @@ export default {
},
async suggestAccount(start, word) {
try {
await this.$store.dispatch('TimelineSpace/Modals/NewToot/Status/searchAccount', word)
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeOpenSuggest', true)
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeStartIndex', start)
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeMatchWord', word)
this.$store.commit('TimelineSpace/Modasl/NewToot/Status/filteredSuggestionFromAccounts')
await this.$store.dispatch('TimelineSpace/Modals/NewToot/Status/suggestAccount', { word: word, start: start })
return true
} catch (err) {
console.log(err)
@ -183,41 +175,18 @@ export default {
}
},
suggestEmoji(start, word) {
// Find native emojis
const filteredEmojiName = emojilib.ordered.filter(emoji => `:${emoji}`.includes(word))
const filteredNativeEmoji = filteredEmojiName.map(name => {
return {
name: `:${name}:`,
code: emojilib.lib[name].char
}
})
// Find custom emojis
const filteredCustomEmoji = this.customEmojis.filter(emoji => emoji.name.includes(word))
const filtered = filteredNativeEmoji.concat(filteredCustomEmoji)
if (filtered.length > 0) {
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeOpenSuggest', true)
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeStartIndex', start)
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeMatchWord', word)
this.$store.commit(
'TimelineSpace/Modals/NewToot/Status/changeFilteredSuggestion',
filtered.filter((e, i, array) => {
return array.findIndex(ar => e.name === ar.name) === i
})
)
} else {
try {
this.$store.dispatch('TimelineSpace/Modals/NewToot/Status/suggestEmoji', { word: word, start: start })
return true
} catch (err) {
this.closeSuggest()
return false
}
return true
},
closeSuggest() {
if (this.openSuggest) {
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeOpenSuggest', false)
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeStartIndex', null)
this.$store.commit('TimelineSpace/Modals/NewToot/Status/changeMatchWord', null)
this.$store.dispatch('TimelineSpace/Modals/NewToot/Status/closeSuggest')
this.highlightedIndex = 0
this.$store.commit('TimelineSpace/Modals/NewToot/Status/clearFilteredSuggestion')
this.$store.commit('TimelineSpace/Modals/NewToot/Status/clearFilteredAccounts')
this.$store.commit('TimelineSpace/Modals/NewToot/Status/clearFilteredHashtags')
}
},
suggestHighlight(index) {

View File

@ -12,16 +12,11 @@ import { UnreadNotification } from '~/src/types/unreadNotification'
import { AccountLoadError } from '@/errors/load'
import { TimelineFetchError } from '@/errors/fetch'
type MyEmoji = {
name: string
image: string
}
export type TimelineSpaceState = {
account: LocalAccount
bindingAccount: LocalAccount | null
loading: boolean
emojis: Array<MyEmoji>
emojis: Array<Emoji>
tootMax: number
unreadNotification: UnreadNotification
pleroma: boolean
@ -76,12 +71,7 @@ const mutations: MutationTree<TimelineSpaceState> = {
state.loading = value
},
[MUTATION_TYPES.UPDATE_EMOJIS]: (state, emojis: Array<Emoji>) => {
state.emojis = emojis.map(e => {
return {
name: `:${e.shortcode}:`,
image: e.url
}
})
state.emojis = emojis
},
[MUTATION_TYPES.UPDATE_TOOT_MAX]: (state, value: number | null) => {
if (value) {

View File

@ -1,4 +1,5 @@
import { ipcRenderer } from 'electron'
import emojilib from 'emojilib'
import Mastodon, { Account, Tag, Response, Results } from 'megalodon'
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
import { RootState } from '@/store/index'
@ -6,29 +7,34 @@ import { LocalTag } from '~/src/types/localTag'
type Suggest = {
name: string
image: string | null
image?: string | null
code?: string | null
}
type SuggestAccount = Suggest
type SuggestHashtag = Suggest
type SuggestEmoji = Suggest
export type StatusState = {
filteredSuggestion: Array<Suggest>
filteredAccounts: Array<SuggestAccount>
filteredHashtags: Array<SuggestHashtag>
filteredEmojis: Array<SuggestEmoji>
openSuggest: boolean
startIndex: number | null
matchWord: string | null
filteredSuggestion: Array<Suggest>
}
const state = (): StatusState => ({
filteredSuggestion: [],
filteredAccounts: [],
filteredHashtags: [],
filteredEmojis: [],
openSuggest: false,
startIndex: null,
matchWord: null,
filteredSuggestion: []
matchWord: null
})
export const MUTATION_TYPES = {
@ -36,13 +42,15 @@ export const MUTATION_TYPES = {
CLEAR_FILTERED_ACCOUNTS: 'clearFilteredAccounts',
APPEND_FILTERED_HASHTAGS: 'appendFilteredHashtags',
CLEAR_FILTERED_HASHTAGS: 'clearFilteredHashtags',
UPDATE_FILTERED_EMOJIS: 'updateFilteredEmojis',
CLEAR_FILTERED_EMOJIS: 'clearFilteredEmojis',
CHANGE_OPEN_SUGGEST: 'changeOpenSuggest',
CHANGE_START_INDEX: 'changeStartIndex',
CHANGE_MATCH_WORD: 'changeMatchWord',
FILTERED_SUGGESTION_FROM_HASHTAGS: 'filteredSuggestionFromHashtags',
FILTERED_SUGGESTION_FROM_ACCOUNTS: 'filteredSuggestionFromAccounts',
CLEAR_FILTERED_SUGGESTION: 'clearFilteredSuggestion',
CHANGE_FILTERED_SUGGESTION: 'changeFilteredSuggestion'
FILTERED_SUGGESTION_FROM_EMOJIS: 'filteredSuggestionFromEmojis',
CLEAR_FILTERED_SUGGESTION: 'clearFilteredSuggestion'
}
const mutations: MutationTree<StatusState> = {
@ -65,6 +73,9 @@ const mutations: MutationTree<StatusState> = {
[MUTATION_TYPES.CLEAR_FILTERED_HASHTAGS]: state => {
state.filteredHashtags = []
},
[MUTATION_TYPES.UPDATE_FILTERED_EMOJIS]: (state, emojis: Array<SuggestEmoji>) => {
state.filteredEmojis = emojis
},
[MUTATION_TYPES.CHANGE_OPEN_SUGGEST]: (state, value: boolean) => {
state.openSuggest = value
},
@ -80,11 +91,11 @@ const mutations: MutationTree<StatusState> = {
[MUTATION_TYPES.FILTERED_SUGGESTION_FROM_ACCOUNTS]: state => {
state.filteredSuggestion = state.filteredAccounts
},
[MUTATION_TYPES.FILTERED_SUGGESTION_FROM_EMOJIS]: state => {
state.filteredSuggestion = state.filteredEmojis
},
[MUTATION_TYPES.CLEAR_FILTERED_SUGGESTION]: state => {
state.filteredSuggestion = []
},
[MUTATION_TYPES.CHANGE_FILTERED_SUGGESTION]: (state, suggestion: Array<Suggest>) => {
state.filteredSuggestion = suggestion
}
}
@ -94,11 +105,18 @@ type WordStart = {
}
const actions: ActionTree<StatusState, RootState> = {
searchAccount: async ({ commit, rootState }, word: string) => {
suggestAccount: async ({ commit, rootState }, wordStart: WordStart) => {
commit(MUTATION_TYPES.CLEAR_FILTERED_ACCOUNTS)
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_ACCOUNTS)
const { word, start } = wordStart
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
const res: Response<Results> = await client.get<Results>('/search', { q: word, resolve: false })
commit(MUTATION_TYPES.UPDATE_FILTERED_ACCOUNTS, res.data.accounts)
if (res.data.accounts.length === 0) throw new Error('Empty')
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, true)
commit(MUTATION_TYPES.CHANGE_START_INDEX, start)
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, word)
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_ACCOUNTS)
return res.data.accounts
},
suggestHashtag: async ({ commit, rootState }, wordStart: WordStart) => {
@ -134,12 +152,59 @@ const actions: ActionTree<StatusState, RootState> = {
return res.data.hashtags
}
await Promise.all([searchCache(), searchAPI()])
},
suggestEmoji: ({ commit, rootState }, wordStart: WordStart) => {
const { word, start } = wordStart
// Find native emojis
const filteredEmojiName: Array<string> = emojilib.ordered.filter((emoji: string) => `:${emoji}:`.includes(word))
const filteredNativeEmoji: Array<SuggestEmoji> = filteredEmojiName.map((name: string) => {
return {
name: `:${name}:`,
code: emojilib.lib[name].char
}
})
// Find custom emojis
const filteredCustomEmoji: Array<Suggest> = rootState.TimelineSpace.emojis
.map(emoji => {
return {
name: `:${emoji.shortcode}:`,
image: emoji.url
}
})
.filter(emoji => emoji.name.includes(word))
const filtered: Array<SuggestEmoji> = filteredNativeEmoji.concat(filteredCustomEmoji)
if (filtered.length === 0) throw new Error('Empty')
commit(
MUTATION_TYPES.UPDATE_FILTERED_EMOJIS,
filtered.filter((e, i, array) => {
return array.findIndex(ar => e.name === ar.name) === i
})
)
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, true)
commit(MUTATION_TYPES.CHANGE_START_INDEX, start)
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, word)
commit(MUTATION_TYPES.FILTERED_SUGGESTION_FROM_EMOJIS)
return filtered
},
closeSuggest: ({ commit }) => {
commit(MUTATION_TYPES.CHANGE_OPEN_SUGGEST, false)
commit(MUTATION_TYPES.CHANGE_START_INDEX, null)
commit(MUTATION_TYPES.CHANGE_MATCH_WORD, null)
commit(MUTATION_TYPES.CLEAR_FILTERED_SUGGESTION)
commit(MUTATION_TYPES.CLEAR_FILTERED_ACCOUNTS)
commit(MUTATION_TYPES.CLEAR_FILTERED_HASHTAGS)
}
}
const getters: GetterTree<StatusState, RootState> = {
pickerEmojis: (_state, _getters, rootState) => {
return rootState.TimelineSpace.emojis
.map(emoji => {
return {
name: `:${emoji.shortcode}:`,
image: emoji.url
}
})
.filter((e, i, array) => {
return array.findIndex(ar => e.name === ar.name) === i
})