Error handling, uploading/deleting new emojis, sorting
This commit is contained in:
parent
091532d577
commit
4451cccb3c
|
@ -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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue