logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: f8e1d5e3e0600a0a113ee40787b7589b61c2654f
parent 4451cccb3c1244a179b9f5017e6a4536eb5456f1
Author: Ekaterina Vaartis <vaartis@kotobank.ch>
Date:   Sun,  7 Jan 2024 14:28:34 +0300

Remote pack download, localization

Diffstat:

Msrc/components/settings_modal/admin_tabs/emoji_tab.js80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/components/settings_modal/admin_tabs/emoji_tab.vue208+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/i18n/en.json30+++++++++++++++++++++++++++++-
Msrc/services/api/api.service.js16+++++++---------
4 files changed, 250 insertions(+), 84 deletions(-)

diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js @@ -24,13 +24,16 @@ const EmojiTab = { data () { return { - knownPacks: { }, + knownLocalPacks: { }, + knownRemotePacks: { }, editedParts: { }, editedMetadata: { }, packName: '', newPackName: '', deleteModalVisible: false, - newEmojiUpload: clone(newEmojiUploadBase) + newEmojiUpload: clone(newEmojiUploadBase), + remotePackInstance: '', + remotePackDownloadAs: '' } }, @@ -44,6 +47,17 @@ const EmojiTab = { } return this.editedMetadata[this.packName] + }, + knownPacks () { + // Copy the object itself but not the children, so they are still passed by reference and modified + const result = clone(this.knownLocalPacks) + for (const instName in this.knownRemotePacks) { + for (const instPack in this.knownRemotePacks[instName]) { + result[`${instPack}@${instName}`] = this.knownRemotePacks[instName][instPack] + } + } + + return result } }, @@ -55,7 +69,12 @@ const EmojiTab = { this.$store.state.api.backendInteractor.importEmojiFromFS() }, emojiAddr (name) { - return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}` + if (this.pack.remote !== undefined) { + // Remote pack + return `${this.pack.remote.instance}/emoji/${encodeURIComponent(this.pack.remote.baseName)}/${name}` + } else { + return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}` + } }, uploadEmoji () { @@ -193,15 +212,64 @@ const EmojiTab = { return } - this.knownPacks = packData.packs - for (const name of Object.keys(this.knownPacks)) { + this.knownLocalPacks = packData.packs + for (const name of Object.keys(this.knownLocalPacks)) { this.sortPackFiles(name) } }) }, + listRemotePacks () { + this.$store.state.api.backendInteractor.listRemoteEmojiPacks({ instance: this.remotePackInstance }) + .then(data => data.json()) + .then(packData => { + if (packData.error !== undefined) { + this.displayError(packData.error) + return + } + + let inst = this.remotePackInstance + if (!inst.startsWith('http')) { inst = 'https://' + inst } + const instUrl = new URL(inst) + inst = instUrl.host + + for (const packName in packData.packs) { + packData.packs[packName].remote = { + baseName: packName, + instance: instUrl.origin + } + } + + this.knownRemotePacks[inst] = packData.packs + + this.$refs.remotePackPopover.hidePopover() + }) + }, + downloadRemotePack () { + if (this.remotePackDownloadAs.trim() === '') { + this.remotePackDownloadAs = this.pack.remote.baseName + } + + this.$store.state.api.backendInteractor.downloadRemoteEmojiPack({ + instance: this.pack.remote.instance, packName: this.pack.remote.baseName, as: this.remotePackDownloadAs + }) + .then(data => data.json()) + .then(resp => { + if (resp === 'ok') { + this.$refs.dlPackPopover.hidePopover() + + return this.refreshPackList() + } else { + this.displayError(resp.error) + return Promise.reject(resp) + } + }).then(done => { + this.packName = this.remotePackDownloadAs + this.remotePackDownloadAs = '' + }) + }, displayError (msg) { this.$store.dispatch('pushGlobalNotice', { - messageKey: 'upload.error.message', + messageKey: 'admin_dash.emoji.error', messageArgs: [msg], level: 'error' }) diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.vue b/src/components/settings_modal/admin_tabs/emoji_tab.vue @@ -27,7 +27,7 @@ class="button button-default btn" type="button" @click="$refs.createPackPopover.showPopover"> - Create pack + {{ $t('admin_dash.emoji.create_pack') }} </button> <Popover ref="createPackPopover" @@ -38,37 +38,46 @@ :offset="{ y: 5 }" > <template #content> - <input v-model="newPackName" placeholder="New pack name"> + <input v-model="newPackName" :placeholder="$t('admin_dash.emoji.new_pack_name')"> <button class="button button-default btn emoji-tab-popover-button" type="button" @click="createEmojiPack"> - Create + {{ $t('admin_dash.emoji.create') }} </button> </template> </Popover> <button class="button button-default btn" - :disabled="packName == ''" type="button" - @click="deleteModalVisible = true"> - Delete pack + @click="$refs.remotePackPopover.showPopover"> + {{ $t('admin_dash.emoji.remote_packs') }} + + <Popover + ref="remotePackPopover" + trigger="click" + placement="bottom" + bound-to-selector=".emoji-tab" + :bound-to="{ x: 'container' }" + :offset="{ y: 5 }" + > + <template #content> + <input v-model="remotePackInstance" :placeholder="$t('admin_dash.emoji.remote_pack_instance')"> + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + @click="listRemotePacks"> + {{ $t('admin_dash.emoji.do_list') }} + </button> + </template> + </Popover> </button> - <ConfirmModal - v-if="deleteModalVisible" - title="Delete?" - :cancel-text="$t('status.delete_confirm_cancel_button')" - :confirm-text="$t('status.delete_confirm_accept_button')" - @cancelled="deleteModalVisible = false" - @accepted="deleteEmojiPack" > - Are you sure you want to delete <i>{{ packName }}</i>? - </ConfirmModal> </li> <li> <Select class="form-control" v-model="packName"> - <option value="" disabled hidden>Emoji pack</option> + <option value="" disabled hidden>{{ $t('admin_dash.emoji.emoji_pack') }}</option> <option v-for="(pack, listPackName) in knownPacks" :label="listPackName" :key="listPackName"> {{ listPackName }} </option> @@ -81,33 +90,38 @@ <ul class="setting-list"> <li> <div> - Description + {{ $t('admin_dash.emoji.description') }} <ModifiedIndicator :changed="metaEdited('description')" /> </div> <textarea v-model="packMeta.description" + :disabled="pack.remote !== undefined" class="bio resize-height" /> </li> <li> <div> - Homepage + {{ $t('admin_dash.emoji.homepage') }} <ModifiedIndicator :changed="metaEdited('homepage')" /> </div> - <input class="emoji-info-input" v-model="packMeta.homepage"> + <input + class="emoji-info-input" v-model="packMeta.homepage" + :disabled="pack.remote !== undefined"> </li> <li> <div> - Fallback source + {{ $t('admin_dash.emoji.fallback_src') }} <ModifiedIndicator :changed="metaEdited('fallback-src')" /> </div> - <input class="emoji-info-input" v-model="packMeta['fallback-src']"> + <input class="emoji-info-input" v-model="packMeta['fallback-src']" :disabled="pack.remote !== undefined"> </li> <li> - <div>Fallback SHA256</div> + <div>{{ $t('admin_dash.emoji.fallback_sha256') }}</div> <input :disabled="true" class="emoji-info-input" v-model="packMeta['fallback-src-sha256']"> </li> <li> - <Checkbox v-model="packMeta['share-files']">Share</Checkbox> + <Checkbox :disabled="pack.remote !== undefined" v-model="packMeta['share-files']"> + {{ $t('admin_dash.emoji.share') }} + </Checkbox> <ModifiedIndicator :changed="metaEdited('share-files')" /> </li> @@ -115,64 +129,122 @@ <button class="button button-default btn" type="button" + v-if="pack.remote === undefined" @click="savePackMetadata"> - Save + {{ $t('admin_dash.emoji.save') }} </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> + <button + class="button button-default btn" + type="button" + v-if="pack.remote === undefined" + @click="$refs.addEmojiPopover.showPopover"> + {{ $t('admin_dash.emoji.add_file') }} + + <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>{{ $t('admin_dash.emoji.adding_new') }}</h3> <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> + <input + type="file" + class="emoji-tab-popover-input emoji-tab-popover-file" + @change="newEmojiUpload.upload = $event.target.files" + > </div> - </div> - </template> - </Popover> + <div> + <div> + <input class="emoji-data-input emoji-tab-popover-input" + v-model="newEmojiUpload.shortcode" + :placeholder="$t('admin_dash.emoji.new_shortcode')"> + <input class="emoji-data-input emoji-tab-popover-input" + v-model="newEmojiUpload.file" + :placeholder="$t('admin_dash.emoji.new_filename')"> + + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + :disabled="this.newEmojiUpload.upload.length == 0" + @click="uploadEmoji"> + {{ $t('admin_dash.emoji.save') }} + </button> + </div> + </div> + </template> + </Popover> + </button> + <button class="button button-default btn" + v-if="pack.remote === undefined" type="button" - @click="$refs.addEmojiPopover.showPopover"> - Add file + @click="deleteModalVisible = true"> + {{ $t('admin_dash.emoji.delete_pack') }} + + <ConfirmModal + v-if="deleteModalVisible" + :title="$t('admin_dash.emoji.delete_title')" + :cancel-text="$t('status.delete_confirm_cancel_button')" + :confirm-text="$t('status.delete_confirm_accept_button')" + @cancelled="deleteModalVisible = false" + @accepted="deleteEmojiPack" > + {{ $t('admin_dash.emoji.delete_confirm', packName) }} + </ConfirmModal> + </button> + + <button + class="button button-default btn" + type="button" + v-if="pack.remote !== undefined" + @click="$refs.dlPackPopover.showPopover"> + {{ $t('admin_dash.emoji.download_pack') }} + + <Popover + ref="dlPackPopover" + 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>{{ $t('admin_dash.emoji.downloading_pack', [packName]) }}</h3> + <div> + <div> + <input class="emoji-data-input emoji-tab-popover-input" + v-model="remotePackDownloadAs" + :placeholder="$t('admin_dash.emoji.download_as_name')"> + + <button + class="button button-default btn emoji-tab-popover-button" + type="button" + @click="downloadRemotePack"> + {{ $t('admin_dash.emoji.download') }} + </button> + </div> + </div> + </template> + </Popover> </button> </li> </ul> </div> - <h2>Files</h2> + <h2>{{ $t('admin_dash.emoji.files') }}</h2> <div class="emoji-list" v-if="pack"> <Popover v-for="(file, shortcode) in pack.files" :key="shortcode" trigger="click" + :disabled="pack.remote !== undefined" placement="top" :class="{'emoji-unsaved': editedParts[packName] !== undefined && editedParts[packName][shortcode] !== undefined}" popover-class="emoji-tab-edit-popover popover-default" @@ -183,7 +255,7 @@ > <template #content> <h3> - Editing <i>{{ shortcode }}</i> + {{ $t('admin_dash.emoji.editing', [shortcode]) }} </h3> <div v-if="editedParts[packName] !== undefined && editedParts[packName][shortcode] !== undefined"> <input class="emoji-data-input" @@ -195,22 +267,22 @@ class="button button-default btn emoji-tab-popover-button" type="button" @click="saveEditedEmoji(shortcode)"> - Save + {{ $t('admin_dash.emoji.save') }} </button> <button class="button button-default btn emoji-tab-popover-button" type="button" @click="editedParts[packName][shortcode].deleteModalVisible = true"> - Delete + {{ $t('admin_dash.emoji.delete') }} </button> <ConfirmModal v-if="editedParts[packName][shortcode].deleteModalVisible" - title="Delete?" + :title="$t('admin_dash.emoji.delete_title')" :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>? + {{ $t('admin_dash.emoji.delete_confirm', shortcode) }} </ConfirmModal> </div> </template> diff --git a/src/i18n/en.json b/src/i18n/en.json @@ -935,7 +935,35 @@ }, "emoji": { "reload": "Reload emoji", - "importFS": "Import emoji from filesystem" + "importFS": "Import emoji from filesystem", + "error": "Error: {0}", + "create_pack": "Create pack", + "delete_pack": "Delete pack", + "new_pack_name": "New pack name", + "create": "Create", + "remote_packs": "Remote packs", + "do_list": "List", + "remote_pack_instance": "Remote pack instance", + "emoji_pack": "Emoji pack", + "description": "Description", + "homepage": "Homepage", + "fallback_src": "Fallback source", + "fallback_sha256": "Fallback SHA256", + "share": "Share", + "save": "Save", + "delete": "Delete", + "add_file": "Add file", + "adding_new": "Adding new emoji", + "new_shortcode": "Shortcode, leave blank to infer", + "new_filename": "Filename, leave blank infer", + "delete_confirm": "Are you sure you want to delete {0}?", + "download_pack": "Download pack", + "downloading_pack": "Downloading {0}", + "download": "Download", + "download_as_name": "New name, leave blank to reuse", + "files": "Files", + "editing": "Editing {0}", + "delete_title": "Delete?" }, "temp_overrides": { ":pleroma": { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js @@ -1817,28 +1817,26 @@ const listEmojiPacks = () => { } const listRemoteEmojiPacks = ({ instance }) => { + if (!instance.startsWith('http')) { + instance = 'https://' + instance + } + return fetch( - PLEROMA_EMOJI_PACKS_LS_REMOTE_URL, + PLEROMA_EMOJI_PACKS_LS_REMOTE_URL(instance, 1, 25), { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ instance_address: instance }) + headers: { 'Content-Type': 'application/json' } } ) } const downloadRemoteEmojiPack = ({ instance, packName, as }) => { - if (as.trim() === '') { - as = null - } - return fetch( PLEROMA_EMOJI_PACKS_DL_REMOTE_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - instance_address: instance, pack_name: packName, as + url: instance, name: packName, as }) } )