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:
commit
6edb0534fd
@ -125,7 +125,8 @@
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"js"
|
||||
"js",
|
||||
"json"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"@/router": "<rootDir>/spec/mock/router.ts",
|
||||
|
@ -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
|
||||
}
|
||||
])
|
||||
})
|
||||
|
@ -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', () => {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user