Merge pull request #914 from h3poteto/refactor/new-toot
refactor: Move logics to vuex store in new toot
This commit is contained in:
commit
50948a03c3
|
@ -22,7 +22,8 @@
|
|||
maxlength="420"
|
||||
class="image-description"
|
||||
:placeholder="$t('modals.new_toot.description')"
|
||||
v-model="mediaDescriptions[media.id]"
|
||||
:value="mediaDescriptions[media.id]"
|
||||
@input="updateDescription(media.id, $event.target.value)"
|
||||
v-shortkey="{ left: ['arrowleft'], right: ['arrowright'] }"
|
||||
@shortkey="handleDescriptionKey"
|
||||
role="textbox"
|
||||
|
@ -119,6 +120,7 @@ import { mapState, mapGetters } from 'vuex'
|
|||
import { clipboard } from 'electron'
|
||||
import Visibility from '~/src/constants/visibility'
|
||||
import Status from './NewToot/Status'
|
||||
import { NewTootTootLength, NewTootAttachLength, NewTootModalOpen, NewTootBlockSubmit } from '@/errors/validations'
|
||||
|
||||
export default {
|
||||
name: 'new-toot',
|
||||
|
@ -128,7 +130,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
status: '',
|
||||
mediaDescriptions: {},
|
||||
spoiler: '',
|
||||
showContentWarning: false,
|
||||
visibilityList: Visibility
|
||||
|
@ -145,6 +146,7 @@ export default {
|
|||
},
|
||||
attachedMedias: state => state.attachedMedias,
|
||||
attachedMediaId: state => state.attachedMediaId,
|
||||
mediaDescriptions: state => state.mediaDescriptions,
|
||||
blockSubmit: state => state.blockSubmit,
|
||||
visibility: state => state.visibility,
|
||||
sensitive: state => state.sensitive,
|
||||
|
@ -210,57 +212,36 @@ export default {
|
|||
this.$store.dispatch('TimelineSpace/Modals/NewToot/closeModal')
|
||||
},
|
||||
async toot() {
|
||||
if (!this.newTootModal) {
|
||||
return
|
||||
}
|
||||
if (this.status.length < 1 || this.status.length > this.tootMax) {
|
||||
return this.$message({
|
||||
message: this.$t('validation.new_toot.toot_length', { min: 1, max: this.tootMax }),
|
||||
type: 'error'
|
||||
})
|
||||
}
|
||||
const visibilityKey = Object.keys(Visibility).find(key => {
|
||||
return Visibility[key].value === this.visibility
|
||||
})
|
||||
let form = {
|
||||
const form = {
|
||||
status: this.status,
|
||||
visibility: Visibility[visibilityKey].key,
|
||||
sensitive: this.sensitive,
|
||||
spoiler_text: this.spoiler
|
||||
spoiler: this.spoiler
|
||||
}
|
||||
if (this.replyToId !== null) {
|
||||
form = Object.assign(form, {
|
||||
in_reply_to_id: this.replyToId
|
||||
})
|
||||
}
|
||||
if (this.attachedMedias.length > 0) {
|
||||
if (this.attachedMedias.length > 4) {
|
||||
return this.$message({
|
||||
|
||||
try {
|
||||
await this.$store.dispatch('TimelineSpace/Modals/NewToot/postToot', form)
|
||||
this.$store.dispatch('TimelineSpace/Modals/NewToot/updateHashtags', status.tags)
|
||||
this.close()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
if (err instanceof NewTootTootLength) {
|
||||
this.$message({
|
||||
message: this.$t('validation.new_toot.toot_length', { min: 1, max: this.tootMax }),
|
||||
type: 'error'
|
||||
})
|
||||
} else if (err instanceof NewTootAttachLength) {
|
||||
this.$message({
|
||||
message: this.$t('validation.new_toot.attach_length', { max: 4 }),
|
||||
type: 'error'
|
||||
})
|
||||
}
|
||||
form = Object.assign(form, {
|
||||
media_ids: this.attachedMedias.map(m => {
|
||||
return m.id
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const status = await this.$store
|
||||
.dispatch('TimelineSpace/Modals/NewToot/updateMedia', this.mediaDescriptions)
|
||||
.then(() => {
|
||||
return this.$store.dispatch('TimelineSpace/Modals/NewToot/postToot', form)
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
} else if (err instanceof NewTootModalOpen || err instanceof NewTootBlockSubmit) {
|
||||
// Nothing
|
||||
} else {
|
||||
this.$message({
|
||||
message: this.$t('message.toot_error'),
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
this.$store.dispatch('TimelineSpace/Modals/NewToot/updateHashtags', status.tags)
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
selectImage() {
|
||||
this.$refs.image.click()
|
||||
|
@ -305,8 +286,7 @@ export default {
|
|||
})
|
||||
},
|
||||
removeAttachment(media) {
|
||||
this.$store.commit('TimelineSpace/Modals/NewToot/removeMedia', media)
|
||||
delete this.mediaDescriptions[media.id]
|
||||
this.$store.dispatch('TimelineSpace/Modals/NewToot/removeMedia', media)
|
||||
},
|
||||
changeVisibility(level) {
|
||||
this.$store.commit('TimelineSpace/Modals/NewToot/changeVisibilityValue', level)
|
||||
|
@ -340,6 +320,9 @@ export default {
|
|||
default:
|
||||
return true
|
||||
}
|
||||
},
|
||||
updateDescription(id, value) {
|
||||
this.$store.commit('TimelineSpace/Modals/NewToot/updateMediaDescription', { id: id, description: value })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
export class NewTootModalOpen extends Error {}
|
||||
|
||||
export class NewTootBlockSubmit extends Error {}
|
||||
|
||||
export class NewTootTootLength extends Error {}
|
||||
|
||||
export class NewTootAttachLength extends Error {}
|
||||
|
||||
export class NewTootMediaDescription extends Error {}
|
||||
|
||||
export class NewTootUnknownType extends Error {}
|
||||
|
||||
export class AuthenticationError extends Error {}
|
|
@ -5,6 +5,20 @@ import TootStatus, { StatusState } from './NewToot/Status'
|
|||
import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
import AxiosLoading from '@/utils/axiosLoading'
|
||||
import {
|
||||
NewTootModalOpen,
|
||||
NewTootBlockSubmit,
|
||||
NewTootTootLength,
|
||||
NewTootAttachLength,
|
||||
NewTootMediaDescription,
|
||||
NewTootUnknownType,
|
||||
AuthenticationError
|
||||
} from '@/errors/validations'
|
||||
|
||||
type MediaDescription = {
|
||||
id: number
|
||||
description: string
|
||||
}
|
||||
|
||||
export interface NewTootState {
|
||||
modalOpen: boolean
|
||||
|
@ -13,6 +27,7 @@ export interface NewTootState {
|
|||
replyToMessage: Status | null
|
||||
blockSubmit: boolean
|
||||
attachedMedias: Array<Attachment>
|
||||
mediaDescriptions: { [key: number]: string | null }
|
||||
visibility: number
|
||||
sensitive: boolean
|
||||
attachedMediaId: number
|
||||
|
@ -32,6 +47,7 @@ const state = (): NewTootState => ({
|
|||
replyToMessage: null,
|
||||
blockSubmit: false,
|
||||
attachedMedias: [],
|
||||
mediaDescriptions: {},
|
||||
visibility: Visibility.Public.value,
|
||||
sensitive: false,
|
||||
attachedMediaId: 0,
|
||||
|
@ -49,6 +65,9 @@ export const MUTATION_TYPES = {
|
|||
APPEND_ATTACHED_MEDIAS: 'appendAttachedMedias',
|
||||
CLEAR_ATTACHED_MEDIAS: 'clearAttachedMedias',
|
||||
REMOVE_MEDIA: 'removeMedia',
|
||||
UPDATE_MEDIA_DESCRIPTION: 'updateMediaDescription',
|
||||
CLEAR_MEDIA_DESCRIPTIONS: 'clearMediaDescriptions',
|
||||
REMOVE_MEDIA_DESCRIPTION: 'removeMediaDescription',
|
||||
CHANGE_VISIBILITY_VALUE: 'changeVisibilityValue',
|
||||
CHANGE_SENSITIVE: 'changeSensitive',
|
||||
UPDATE_MEDIA_ID: 'updateMediaId',
|
||||
|
@ -82,6 +101,17 @@ const mutations: MutationTree<NewTootState> = {
|
|||
[MUTATION_TYPES.REMOVE_MEDIA]: (state, media: Attachment) => {
|
||||
state.attachedMedias = state.attachedMedias.filter(m => m.id !== media.id)
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_MEDIA_DESCRIPTION]: (state, value: MediaDescription) => {
|
||||
state.mediaDescriptions[value.id] = value.description
|
||||
},
|
||||
[MUTATION_TYPES.CLEAR_MEDIA_DESCRIPTIONS]: state => {
|
||||
state.mediaDescriptions = {}
|
||||
},
|
||||
[MUTATION_TYPES.REMOVE_MEDIA_DESCRIPTION]: (state, id: number) => {
|
||||
const descriptions = state.mediaDescriptions
|
||||
delete descriptions[id]
|
||||
state.mediaDescriptions = descriptions
|
||||
},
|
||||
/**
|
||||
* changeVisibilityValue
|
||||
* Update visibility using direct value
|
||||
|
@ -118,26 +148,74 @@ const actions: ActionTree<NewTootState, RootState> = {
|
|||
commit(MUTATION_TYPES.CHANGE_LOADING, false)
|
||||
})
|
||||
},
|
||||
updateMedia: async ({ rootState }, media: Attachment) => {
|
||||
updateMedia: async ({ rootState }, mediaDescription: MediaDescription) => {
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
const client = new Mastodon(rootState.TimelineSpace.account.accessToken, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||
const attachments = Object.keys(media).map(async id => {
|
||||
return client.put<Attachment>(`/media/${id}`, { description: media[id] })
|
||||
const attachments = Object.keys(mediaDescription).map(async id => {
|
||||
if (mediaDescription[id] !== null) {
|
||||
return client.put<Attachment>(`/media/${id}`, { description: mediaDescription[id] })
|
||||
} else {
|
||||
return Promise.resolve({})
|
||||
}
|
||||
})
|
||||
return Promise.all(attachments).catch(err => {
|
||||
console.error(err)
|
||||
throw err
|
||||
})
|
||||
},
|
||||
postToot: async ({ state, commit, rootState }, form) => {
|
||||
postToot: async ({ state, commit, rootState, dispatch }, { status, spoiler }): Promise<Status> => {
|
||||
if (!state.modalOpen) {
|
||||
throw new NewTootModalOpen()
|
||||
}
|
||||
|
||||
if (status.length < 1 || status.length > rootState.TimelineSpace.tootMax) {
|
||||
throw new NewTootTootLength()
|
||||
}
|
||||
|
||||
const visibilityKey: string | undefined = Object.keys(Visibility).find(key => {
|
||||
return Visibility[key].value === state.visibility
|
||||
})
|
||||
let specifiedVisibility: string = Visibility.Public.key
|
||||
if (visibilityKey !== undefined) {
|
||||
specifiedVisibility = Visibility[visibilityKey].key
|
||||
}
|
||||
let form = {
|
||||
status: status,
|
||||
visibility: specifiedVisibility,
|
||||
sensitive: state.sensitive,
|
||||
spoiler_text: spoiler
|
||||
}
|
||||
|
||||
if (state.replyToMessage !== null) {
|
||||
form = Object.assign(form, {
|
||||
in_reply_to_id: state.replyToMessage.id
|
||||
})
|
||||
}
|
||||
|
||||
if (rootState.TimelineSpace.account.accessToken === undefined || rootState.TimelineSpace.account.accessToken === null) {
|
||||
throw new AuthenticationError()
|
||||
}
|
||||
if (state.blockSubmit) {
|
||||
return
|
||||
throw new NewTootBlockSubmit()
|
||||
}
|
||||
|
||||
if (state.attachedMedias.length > 0) {
|
||||
if (state.attachedMedias.length > 4) {
|
||||
throw new NewTootAttachLength()
|
||||
}
|
||||
form = Object.assign(form, {
|
||||
media_ids: state.attachedMedias.map(m => {
|
||||
return m.id
|
||||
})
|
||||
})
|
||||
// Update media descriptions
|
||||
await dispatch('updateMedia', state.mediaDescriptions).catch(_ => {
|
||||
throw new NewTootMediaDescription()
|
||||
})
|
||||
}
|
||||
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, true)
|
||||
const client = new Mastodon(rootState.TimelineSpace.account.accessToken, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||
return client
|
||||
|
@ -182,6 +260,7 @@ const actions: ActionTree<NewTootState, RootState> = {
|
|||
commit(MUTATION_TYPES.SET_REPLY_TO, null)
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
|
||||
commit(MUTATION_TYPES.CLEAR_ATTACHED_MEDIAS)
|
||||
commit(MUTATION_TYPES.CLEAR_MEDIA_DESCRIPTIONS)
|
||||
commit(MUTATION_TYPES.CHANGE_SENSITIVE, false)
|
||||
commit(MUTATION_TYPES.CHANGE_VISIBILITY_VALUE, Visibility.Public.value)
|
||||
},
|
||||
|
@ -197,7 +276,7 @@ const actions: ActionTree<NewTootState, RootState> = {
|
|||
.post<Attachment>('/media', formData)
|
||||
.then(res => {
|
||||
commit(MUTATION_TYPES.CHANGE_BLOCK_SUBMIT, false)
|
||||
if (res.data.type === 'unknown') throw new UnknownTypeError()
|
||||
if (res.data.type === 'unknown') throw new NewTootUnknownType()
|
||||
commit(MUTATION_TYPES.APPEND_ATTACHED_MEDIAS, res.data)
|
||||
return res.data
|
||||
})
|
||||
|
@ -210,9 +289,17 @@ const actions: ActionTree<NewTootState, RootState> = {
|
|||
incrementMediaId: ({ commit, state }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_MEDIA_ID, state.attachedMediaId + 1)
|
||||
},
|
||||
decrementMediaId: ({ commit, state }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_MEDIA_ID, state.attachedMediaId - 1)
|
||||
},
|
||||
resetMediaId: ({ commit }) => {
|
||||
commit(MUTATION_TYPES.UPDATE_MEDIA_ID, 0)
|
||||
},
|
||||
removeMedia: ({ commit, dispatch }, media: Attachment) => {
|
||||
commit(MUTATION_TYPES.REMOVE_MEDIA, media)
|
||||
commit(MUTATION_TYPES.REMOVE_MEDIA_DESCRIPTION, media.id)
|
||||
dispatch('decrementMediaId')
|
||||
},
|
||||
updateHashtags: ({ commit, state }, tags: Array<Tag>) => {
|
||||
if (state.pinedHashtag && tags.length > 0) {
|
||||
commit(MUTATION_TYPES.UPDATE_HASHTAGS, tags)
|
||||
|
@ -250,6 +337,3 @@ const NewToot: Module<NewTootState, RootState> = {
|
|||
}
|
||||
|
||||
export default NewToot
|
||||
|
||||
class AuthenticationError {}
|
||||
class UnknownTypeError {}
|
||||
|
|
Loading…
Reference in New Issue