logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: f9c85c0c491fa800054250a814978e6f8fcc439a
parent 6391a6a4ead068455a5b23d7d11ce0cdf2ec87ea
Author: Ekaterina Vaartis <vaartis@kotobank.ch>
Date:   Thu, 21 Dec 2023 00:16:16 +0300

Initial incomplete admin emoji settings implementation

Diffstat:

Asrc/components/settings_modal/admin_tabs/emoji_tab.js62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/settings_modal/admin_tabs/emoji_tab.scss24++++++++++++++++++++++++
Asrc/components/settings_modal/admin_tabs/emoji_tab.vue93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/settings_modal/settings_modal_admin_content.js4+++-
Msrc/components/settings_modal/settings_modal_admin_content.vue8++++++++
Msrc/i18n/en.json7++++++-
Msrc/services/api/api.service.js108++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
7 files changed, 303 insertions(+), 3 deletions(-)

diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js @@ -0,0 +1,62 @@ +import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' +import StringSetting from '../helpers/string_setting.vue' +import Checkbox from 'components/checkbox/checkbox.vue' +import StillImage from 'components/still-image/still-image.vue' + +const EmojiTab = { + components: { + TabSwitcher, + StringSetting, + Checkbox, + StillImage + }, + + data () { + return { + knownPacks: { }, + editedParts: { } + } + }, + + methods: { + reloadEmoji () { + this.$store.state.api.backendInteractor.reloadEmoji() + }, + importFromFS () { + this.$store.state.api.backendInteractor.importEmojiFromFS() + }, + emojiAddr (packName, name) { + return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(packName)}/${name}` + }, + editEmoji (packName, shortcode) { + if (this.editedParts[packName] === undefined) { this.editedParts[packName] = {} } + + this.editedParts[packName][shortcode] = { + shortcode, file: this.knownPacks[packName].files[shortcode] + } + }, + saveEditedEmoji (packName, shortcode) { + const edited = this.editedParts[packName][shortcode] + + this.$store.state.api.backendInteractor.updateEmojiFile( + { 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 => { + this.knownPacks[packName].files = resp + delete this.editedParts[packName][shortcode] + }) + } + }, + + mounted () { + this.$store.state.api.backendInteractor.listEmojiPacks() + .then(data => data.json()) + .then(packData => { + this.knownPacks = packData.packs + console.log(this.knownPacks) + }) + } +} + +export default EmojiTab diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.scss b/src/components/settings_modal/admin_tabs/emoji_tab.scss @@ -0,0 +1,24 @@ +.emoji-tab { + .btn-group .btn { + margin-left: 0.5em; + } + + .pack-info-wrapper { + margin-top: 1em; + } + + .emoji-info-input { + width: 100%; + } + + .emoji-data-input { + width: 40%; + margin-left: 0.5em; + margin-right: 0.5em; + } + + .emoji { + width: 32px; + height: 32px; + } +} diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.vue b/src/components/settings_modal/admin_tabs/emoji_tab.vue @@ -0,0 +1,93 @@ +<template> + <div + class="emoji-tab" + :label="$t('admin_dash.tabs.emoji')" + > + <div class="setting-item"> + <h2>{{ $t('admin_dash.tabs.emoji') }}</h2> + + <span class="btn-group"> + <button + class="button button-default btn" + type="button" + @click="reloadEmoji"> + {{ $t('admin_dash.emoji.reload') }} + </button> + <button + class="button button-default btn" + type="button" + @click="importFromFS"> + {{ $t('admin_dash.emoji.importFS') }} + </button> + </span> + + <tab-switcher :scrollable-tabs="true" v-if="Object.keys(knownPacks).length > 0"> + <div v-for="(pack, packName) in knownPacks" :label="packName" :key="packName"> + <div class="pack-info-wrapper"> + <ul class="setting-list"> + <li> + <div>Description</div> + <textarea + v-model="pack.pack.description" + class="bio resize-height" /> + </li> + <li> + <div>Homepage</div> + <input class="emoji-info-input" v-model="pack.pack.homepage"> + </li> + <li> + <div>Fallback source</div> + <input class="emoji-info-input" v-model="pack.pack['fallback-src']"> + </li> + <li> + <Checkbox v-model="pack.pack['can-download']">Downloadable</Checkbox> + </li> + </ul> + </div> + + <h2>Files</h2> + + <ul class="setting-list"> + <li v-for="(file, shortcode) in pack.files" :key="shortcode"> + <StillImage + class="emoji img" + :src="emojiAddr(packName, file)" + :title="`:${shortcode}:`" + :alt="`:${shortcode}:`" + /> + + <template v-if="editedParts[packName] !== undefined && editedParts[packName][shortcode] !== undefined"> + <input class="emoji-data-input" + v-model="editedParts[packName][shortcode].shortcode"> + <input class="emoji-data-input" + v-model="editedParts[packName][shortcode].file"> + + <button + class="button button-default btn" + type="button" + @click="saveEditedEmoji(packName, shortcode)"> + Save + </button> + </template> + <template v-else> + <input disabled class="emoji-data-input" :value="shortcode"> + <input disabled class="emoji-data-input" :value="file"> + + <button + class="button button-default btn" + type="button" + @click="editEmoji(packName, shortcode)"> + Edit + </button> + </template> + </li> + </ul> + </div> + </tab-switcher> + </div> + </div> +</template> + +<script src="./emoji_tab.js"></script> + +<style lang="scss" src="./emoji_tab.scss"></style> diff --git a/src/components/settings_modal/settings_modal_admin_content.js b/src/components/settings_modal/settings_modal_admin_content.js @@ -3,6 +3,7 @@ import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import InstanceTab from './admin_tabs/instance_tab.vue' import LimitsTab from './admin_tabs/limits_tab.vue' import FrontendsTab from './admin_tabs/frontends_tab.vue' +import EmojiTab from './admin_tabs/emoji_tab.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -33,7 +34,8 @@ const SettingsModalAdminContent = { InstanceTab, LimitsTab, - FrontendsTab + FrontendsTab, + EmojiTab }, computed: { user () { diff --git a/src/components/settings_modal/settings_modal_admin_content.vue b/src/components/settings_modal/settings_modal_admin_content.vue @@ -60,6 +60,14 @@ > <FrontendsTab /> </div> + + <div + :label="$t('admin_dash.tabs.emoji')" + icon="laptop-code" + data-tab-name="emoji" + > + <EmojiTab /> + </div> </tab-switcher> </template> diff --git a/src/i18n/en.json b/src/i18n/en.json @@ -877,7 +877,8 @@ "nodb": "No DB Config", "instance": "Instance", "limits": "Limits", - "frontends": "Front-ends" + "frontends": "Front-ends", + "emoji": "Emoji" }, "nodb": { "heading": "Database config is disabled", @@ -931,6 +932,10 @@ "failure_installing_frontend": "Failed to install frontend {version}: {reason}", "success_installing_frontend": "Frontend {version} successfully installed" }, + "emoji": { + "reload": "Reload emoji", + "importFS": "Import emoji from filesystem" + }, "temp_overrides": { ":pleroma": { ":instance": { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js @@ -114,6 +114,15 @@ const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions' const PLEROMA_ADMIN_FRONTENDS_URL = '/api/pleroma/admin/frontends' const PLEROMA_ADMIN_FRONTENDS_INSTALL_URL = '/api/pleroma/admin/frontends/install' +const PLEROMA_EMOJI_RELOAD_URL = '/api/pleroma/admin/reload_emoji' +const PLEROMA_EMOJI_IMPORT_FS_URL = '/api/pleroma/emoji/packs/import' +const PLEROMA_EMOJI_PACKS_URL = (page, pageSize) => `/api/pleroma/emoji/packs?page=${page}&page_size=${pageSize}` +const PLEROMA_EMOJI_PACK_URL = (name) => `/api/pleroma/emoji/pack?name=${name}` +const PLEROMA_EMOJI_PACKS_DL_REMOTE_URL = '/api/pleroma/emoji/packs/download' +const PLEROMA_EMOJI_PACKS_LS_REMOTE_URL = + (url, page, pageSize) => `/api/pleroma/emoji/packs/remote?url=${url}&page=${page}&page_size=${pageSize}` +const PLEROMA_EMOJI_UPDATE_FILE_URL = (name) => `/api/pleroma/emoji/packs/files?name=${name}` + const oldfetch = window.fetch const fetch = (url, options) => { @@ -1787,6 +1796,92 @@ const fetchScrobbles = ({ accountId, limit = 1 }) => { }) } +const deleteEmojiPack = ({ name }) => { + return fetch(PLEROMA_EMOJI_PACK_URL(name), { method: 'DELETE' }) +} + +const reloadEmoji = () => { + return fetch(PLEROMA_EMOJI_RELOAD_URL, { method: 'POST' }) +} + +const importEmojiFromFS = () => { + return fetch(PLEROMA_EMOJI_IMPORT_FS_URL) +} + +const createEmojiPack = ({ name }) => { + return fetch(PLEROMA_EMOJI_PACK_URL(name), { method: 'PUT' }) +} + +const listEmojiPacks = () => { + return fetch(PLEROMA_EMOJI_PACKS_URL(1, 25)) +} + +const listRemoteEmojiPacks = ({ instance }) => { + return fetch( + PLEROMA_EMOJI_PACKS_LS_REMOTE_URL, + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ instance_address: instance }) + } + ) +} + +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 + }) + } + ) +} + +const saveEmojiPackMetadata = ({ name, newData }) => { + return fetch( + PLEROMA_EMOJI_PACK_URL(name), + { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, new_data: newData }) + } + ) +} + +const addNewEmojiFile = ({ packName, file, shortcode, filename }) => { + const data = new FormData() + if (filename.trim() !== '') { data.set('filename', filename) } + if (shortcode.trim() !== '') { data.set('shortcode', shortcode) } + data.set('file', file) + + return fetch( + PLEROMA_EMOJI_UPDATE_FILE_URL(packName), + { method: 'POST', data } + ) +} + +const updateEmojiFile = ({ packName, shortcode, newShortcode, newFilename, force }) => { + return fetch( + PLEROMA_EMOJI_UPDATE_FILE_URL(packName), + { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ shortcode, new_shortcode: newShortcode, new_filename: newFilename, force }) + } + ) +} + +const deleteEmojiFile = ({ packName, shortcode }) => { + return fetch(`${PLEROMA_EMOJI_UPDATE_FILE_URL(packName)}&shortcode=${shortcode}`, { method: 'DELETE' }) +} + const apiService = { verifyCredentials, fetchTimeline, @@ -1906,7 +2001,18 @@ const apiService = { fetchInstanceConfigDescriptions, fetchAvailableFrontends, pushInstanceDBConfig, - installFrontend + installFrontend, + importEmojiFromFS, + reloadEmoji, + listEmojiPacks, + createEmojiPack, + deleteEmojiPack, + saveEmojiPackMetadata, + addNewEmojiFile, + updateEmojiFile, + deleteEmojiFile, + listRemoteEmojiPacks, + downloadRemoteEmojiPack } export default apiService