Error handling, uploading/deleting new emojis, sorting

This commit is contained in:
Ekaterina Vaartis 2024-01-07 12:26:40 +03:00
parent 091532d577
commit 4451cccb3c
4 changed files with 164 additions and 12 deletions

View File

@ -8,6 +8,8 @@ import Popover from 'components/popover/popover.vue'
import ConfirmModal from 'components/confirm_modal/confirm_modal.vue' import ConfirmModal from 'components/confirm_modal/confirm_modal.vue'
import ModifiedIndicator from '../helpers/modified_indicator.vue' import ModifiedIndicator from '../helpers/modified_indicator.vue'
const newEmojiUploadBase = { shortcode: '', file: '', upload: [] }
const EmojiTab = { const EmojiTab = {
components: { components: {
TabSwitcher, TabSwitcher,
@ -27,7 +29,8 @@ const EmojiTab = {
editedMetadata: { }, editedMetadata: { },
packName: '', packName: '',
newPackName: '', newPackName: '',
deleteModalVisible: false deleteModalVisible: false,
newEmojiUpload: clone(newEmojiUploadBase)
} }
}, },
@ -37,7 +40,7 @@ const EmojiTab = {
}, },
packMeta () { packMeta () {
if (this.editedMetadata[this.packName] === undefined) { if (this.editedMetadata[this.packName] === undefined) {
this.editedMetadata[this.packName] = clone(this.knownPacks[this.packName].pack) this.editedMetadata[this.packName] = clone(this.pack.pack)
} }
return this.editedMetadata[this.packName] return this.editedMetadata[this.packName]
@ -55,6 +58,27 @@ const EmojiTab = {
return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}` return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}`
}, },
uploadEmoji () {
this.$refs.addEmojiPopover.hidePopover()
this.$store.state.api.backendInteractor.addNewEmojiFile({
packName: this.packName,
file: this.newEmojiUpload.upload[0],
shortcode: this.newEmojiUpload.shortcode,
filename: this.newEmojiUpload.file
}).then(resp => resp.json()).then(resp => {
if (resp.error !== undefined) {
this.displayError(resp.error)
return
}
this.pack.files = resp
this.sortPackFiles(this.packName)
this.newEmojiUpload = clone(newEmojiUploadBase)
})
},
createEmojiPack () { createEmojiPack () {
this.$store.state.api.backendInteractor.createEmojiPack( this.$store.state.api.backendInteractor.createEmojiPack(
{ name: this.newPackName } { name: this.newPackName }
@ -62,6 +86,7 @@ const EmojiTab = {
if (resp === 'ok') { if (resp === 'ok') {
return this.refreshPackList() return this.refreshPackList()
} else { } else {
this.displayError(resp.error)
return Promise.reject(resp) return Promise.reject(resp)
} }
}).then(done => { }).then(done => {
@ -78,6 +103,7 @@ const EmojiTab = {
if (resp === 'ok') { if (resp === 'ok') {
return this.refreshPackList() return this.refreshPackList()
} else { } else {
this.displayError(resp.error)
return Promise.reject(resp) return Promise.reject(resp)
} }
}).then(done => { }).then(done => {
@ -96,6 +122,11 @@ const EmojiTab = {
this.$store.state.api.backendInteractor.saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta }).then( this.$store.state.api.backendInteractor.saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta }).then(
resp => resp.json() resp => resp.json()
).then(resp => { ).then(resp => {
if (resp.error !== undefined) {
this.displayError(resp.error)
return
}
// Update actual pack data // Update actual pack data
this.pack.pack = resp this.pack.pack = resp
// Delete edited pack data, should auto-update itself // Delete edited pack data, should auto-update itself
@ -108,28 +139,81 @@ const EmojiTab = {
if (this.editedParts[this.packName][shortcode] === undefined) { if (this.editedParts[this.packName][shortcode] === undefined) {
this.editedParts[this.packName][shortcode] = { this.editedParts[this.packName][shortcode] = {
shortcode, file: this.knownPacks[this.packName].files[shortcode] shortcode, file: this.pack.files[shortcode]
} }
} }
}, },
deleteEmoji (shortcode) {
this.editedParts[this.packName][shortcode].deleteModalVisible = false
this.$store.state.api.backendInteractor.deleteEmojiFile(
{ packName: this.packName, shortcode }
).then(resp => resp.json()).then(resp => {
if (resp.error !== undefined) {
this.displayError(resp.error)
return
}
this.pack.files = resp
delete this.editedParts[this.packName][shortcode]
this.sortPackFiles(this.packName)
})
},
saveEditedEmoji (shortcode) { saveEditedEmoji (shortcode) {
const edited = this.editedParts[this.packName][shortcode] const edited = this.editedParts[this.packName][shortcode]
if (edited.shortcode === shortcode && edited.file === this.pack.files[shortcode]) {
delete this.editedParts[this.packName][shortcode]
return
}
this.$store.state.api.backendInteractor.updateEmojiFile( this.$store.state.api.backendInteractor.updateEmojiFile(
{ packName: this.packName, shortcode, newShortcode: edited.shortcode, newFilename: edited.file, force: false } { packName: this.packName, shortcode, newShortcode: edited.shortcode, newFilename: edited.file, force: false }
).then(resp =>
resp.ok ? resp.json() : resp.text().then(respText => Promise.reject(respText))
).then(resp => { ).then(resp => {
this.knownPacks[this.packName].files = resp if (resp.error !== undefined) {
this.displayError(resp.error)
return Promise.reject(resp.error)
}
return resp.json()
}).then(resp => {
this.pack.files = resp
delete this.editedParts[this.packName][shortcode] delete this.editedParts[this.packName][shortcode]
this.sortPackFiles(this.packName)
}) })
}, },
refreshPackList () { refreshPackList () {
return this.$store.state.api.backendInteractor.listEmojiPacks() return this.$store.state.api.backendInteractor.listEmojiPacks()
.then(data => data.json()) .then(data => data.json())
.then(packData => { .then(packData => {
if (packData.error !== undefined) {
this.displayError(packData.error)
return
}
this.knownPacks = packData.packs this.knownPacks = packData.packs
for (const name of Object.keys(this.knownPacks)) {
this.sortPackFiles(name)
}
}) })
},
displayError (msg) {
this.$store.dispatch('pushGlobalNotice', {
messageKey: 'upload.error.message',
messageArgs: [msg],
level: 'error'
})
},
sortPackFiles (nameOfPack) {
// Sort by key
const sorted = Object.keys(this.knownPacks[nameOfPack].files).sort().reduce((acc, key) => {
if (key.length === 0) return acc
acc[key] = this.knownPacks[nameOfPack].files[key]
return acc
}, {})
this.knownPacks[nameOfPack].files = sorted
} }
}, },

View File

@ -25,7 +25,7 @@
} }
.emoji-unsaved { .emoji-unsaved {
box-shadow: 2px 3px 5px var(--cBlue, $fallback--cBlue); box-shadow: 0 3px 5px var(--cBlue, $fallback--cBlue);
} }
.emoji-list { .emoji-list {
@ -44,3 +44,12 @@
.emoji-tab-popover-button { .emoji-tab-popover-button {
margin-left: 0.5em; margin-left: 0.5em;
} }
.emoji-tab-popover-input {
width: 20em;
margin-bottom: 0.5em;
&:not(:first-child) {
margin-left: 0.5em;
}
}

View File

@ -22,7 +22,7 @@
</button> </button>
</li> </li>
<li class="setting-item btn-group"> <li class="btn-group setting-item">
<button <button
class="button button-default btn" class="button button-default btn"
type="button" type="button"
@ -62,7 +62,7 @@
:confirm-text="$t('status.delete_confirm_accept_button')" :confirm-text="$t('status.delete_confirm_accept_button')"
@cancelled="deleteModalVisible = false" @cancelled="deleteModalVisible = false"
@accepted="deleteEmojiPack" > @accepted="deleteEmojiPack" >
Are you sure you want to delete {{ packName }}? Are you sure you want to delete <i>{{ packName }}</i>?
</ConfirmModal> </ConfirmModal>
</li> </li>
@ -111,13 +111,58 @@
<ModifiedIndicator :changed="metaEdited('share-files')" /> <ModifiedIndicator :changed="metaEdited('share-files')" />
</li> </li>
<li> <li class="btn-group">
<button <button
class="button button-default btn" class="button button-default btn"
type="button" type="button"
@click="savePackMetadata"> @click="savePackMetadata">
Save Save
</button> </button>
<Popover
ref="addEmojiPopover"
trigger="click"
placement="bottom"
bound-to-selector=".emoji-tab"
popover-class="emoji-tab-edit-popover popover-default"
:bound-to="{ x: 'container' }"
:offset="{ y: 5 }"
>
<template #content>
<h3>Adding new emoji</h3>
<div>
<input
type="file"
class="emoji-tab-popover-input emoji-tab-popover-file"
@change="newEmojiUpload.upload = $event.target.files"
>
</div>
<div>
<div>
<input class="emoji-data-input emoji-tab-popover-input"
v-model="newEmojiUpload.shortcode"
placeholder="Shortcode, leave blank to infer">
<input class="emoji-data-input emoji-tab-popover-input"
v-model="newEmojiUpload.file"
placeholder="Filename, leave blank infer">
<button
class="button button-default btn emoji-tab-popover-button"
type="button"
:disabled="this.newEmojiUpload.upload.length == 0"
@click="uploadEmoji">
Save
</button>
</div>
</div>
</template>
</Popover>
<button
class="button button-default btn"
type="button"
@click="$refs.addEmojiPopover.showPopover">
Add file
</button>
</li> </li>
</ul> </ul>
</div> </div>
@ -152,7 +197,21 @@
@click="saveEditedEmoji(shortcode)"> @click="saveEditedEmoji(shortcode)">
Save Save
</button> </button>
<button
class="button button-default btn emoji-tab-popover-button"
type="button"
@click="editedParts[packName][shortcode].deleteModalVisible = true">
Delete
</button>
<ConfirmModal
v-if="editedParts[packName][shortcode].deleteModalVisible"
title="Delete?"
:cancel-text="$t('status.delete_confirm_cancel_button')"
:confirm-text="$t('status.delete_confirm_accept_button')"
@cancelled="editedParts[packName][shortcode].deleteModalVisible = false"
@accepted="deleteEmoji(shortcode)" >
Are you sure you want to delete <i>{{ shortcode }}</i>?
</ConfirmModal>
</div> </div>
</template> </template>
<template #trigger> <template #trigger>

View File

@ -1863,7 +1863,7 @@ const addNewEmojiFile = ({ packName, file, shortcode, filename }) => {
return fetch( return fetch(
PLEROMA_EMOJI_UPDATE_FILE_URL(packName), PLEROMA_EMOJI_UPDATE_FILE_URL(packName),
{ method: 'POST', data } { method: 'POST', body: data }
) )
} }