From f9c85c0c491fa800054250a814978e6f8fcc439a Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Thu, 21 Dec 2023 00:16:16 +0300 Subject: Initial incomplete admin emoji settings implementation --- src/services/api/api.service.js | 108 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) (limited to 'src/services/api/api.service.js') diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index bde2e163..4d8fdae2 100644 --- 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 -- cgit v1.2.3-70-g09d2 From 091532d577ae9a23f7a43f681bfd344f040c7738 Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Sun, 7 Jan 2024 02:45:49 +0300 Subject: Editing emojis in popover, pack creation/deletion Also fixed some API calls since they weren't working apparently --- .../settings_modal/admin_tabs/emoji_tab.js | 117 ++++++++++-- .../settings_modal/admin_tabs/emoji_tab.scss | 22 +++ .../settings_modal/admin_tabs/emoji_tab.vue | 206 ++++++++++++++------- .../settings_modal_admin_content.vue | 2 +- src/services/api/api.service.js | 14 +- 5 files changed, 272 insertions(+), 89 deletions(-) (limited to 'src/services/api/api.service.js') diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js index f9d3b24e..874d1c3b 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.js +++ b/src/components/settings_modal/admin_tabs/emoji_tab.js @@ -1,20 +1,46 @@ +import { clone } from 'lodash' 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' +import Select from 'components/select/select.vue' +import Popover from 'components/popover/popover.vue' +import ConfirmModal from 'components/confirm_modal/confirm_modal.vue' +import ModifiedIndicator from '../helpers/modified_indicator.vue' const EmojiTab = { components: { TabSwitcher, StringSetting, Checkbox, - StillImage + StillImage, + Select, + Popover, + ConfirmModal, + ModifiedIndicator }, data () { return { knownPacks: { }, - editedParts: { } + editedParts: { }, + editedMetadata: { }, + packName: '', + newPackName: '', + deleteModalVisible: false + } + }, + + computed: { + pack () { + return this.packName !== '' ? this.knownPacks[this.packName] : undefined + }, + packMeta () { + if (this.editedMetadata[this.packName] === undefined) { + this.editedMetadata[this.packName] = clone(this.knownPacks[this.packName].pack) + } + + return this.editedMetadata[this.packName] } }, @@ -25,37 +51,90 @@ const EmojiTab = { importFromFS () { this.$store.state.api.backendInteractor.importEmojiFromFS() }, - emojiAddr (packName, name) { - return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(packName)}/${name}` + emojiAddr (name) { + return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}` }, - editEmoji (packName, shortcode) { - if (this.editedParts[packName] === undefined) { this.editedParts[packName] = {} } - this.editedParts[packName][shortcode] = { - shortcode, file: this.knownPacks[packName].files[shortcode] + createEmojiPack () { + this.$store.state.api.backendInteractor.createEmojiPack( + { name: this.newPackName } + ).then(resp => resp.json()).then(resp => { + if (resp === 'ok') { + return this.refreshPackList() + } else { + return Promise.reject(resp) + } + }).then(done => { + this.$refs.createPackPopover.hidePopover() + + this.packName = this.newPackName + this.newPackName = '' + }) + }, + deleteEmojiPack () { + this.$store.state.api.backendInteractor.deleteEmojiPack( + { name: this.packName } + ).then(resp => resp.json()).then(resp => { + if (resp === 'ok') { + return this.refreshPackList() + } else { + return Promise.reject(resp) + } + }).then(done => { + delete this.editedMetadata[this.packName] + delete this.editedParts[this.packName] + + this.deleteModalVisible = false + this.packName = '' + }) + }, + + metaEdited (prop) { + return this.pack && this.packMeta[prop] !== this.pack.pack[prop] + }, + savePackMetadata () { + this.$store.state.api.backendInteractor.saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta }).then( + resp => resp.json() + ).then(resp => { + // Update actual pack data + this.pack.pack = resp + // Delete edited pack data, should auto-update itself + delete this.editedMetadata[this.packName] + }) + }, + + editEmoji (shortcode) { + if (this.editedParts[this.packName] === undefined) { this.editedParts[this.packName] = {} } + + if (this.editedParts[this.packName][shortcode] === undefined) { + this.editedParts[this.packName][shortcode] = { + shortcode, file: this.knownPacks[this.packName].files[shortcode] + } } }, - saveEditedEmoji (packName, shortcode) { - const edited = this.editedParts[packName][shortcode] + saveEditedEmoji (shortcode) { + const edited = this.editedParts[this.packName][shortcode] this.$store.state.api.backendInteractor.updateEmojiFile( - { 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 => { - this.knownPacks[packName].files = resp - delete this.editedParts[packName][shortcode] + this.knownPacks[this.packName].files = resp + delete this.editedParts[this.packName][shortcode] }) + }, + refreshPackList () { + return this.$store.state.api.backendInteractor.listEmojiPacks() + .then(data => data.json()) + .then(packData => { + this.knownPacks = packData.packs + }) } }, mounted () { - this.$store.state.api.backendInteractor.listEmojiPacks() - .then(data => data.json()) - .then(packData => { - this.knownPacks = packData.packs - console.log(this.knownPacks) - }) + this.refreshPackList() } } diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.scss b/src/components/settings_modal/admin_tabs/emoji_tab.scss index 397580af..89bf2f7f 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.scss +++ b/src/components/settings_modal/admin_tabs/emoji_tab.scss @@ -1,3 +1,5 @@ +@import "src/variables"; + .emoji-tab { .btn-group .btn { margin-left: 0.5em; @@ -21,4 +23,24 @@ width: 32px; height: 32px; } + + .emoji-unsaved { + box-shadow: 2px 3px 5px var(--cBlue, $fallback--cBlue); + } + + .emoji-list { + display: flex; + flex-wrap: wrap; + gap: 1em 1em; + } +} + +.emoji-tab-edit-popover { + padding-left: 0.5em; + padding-right: 0.5em; + padding-bottom: 0.5em; +} + +.emoji-tab-popover-button { + margin-left: 0.5em; } diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.vue b/src/components/settings_modal/admin_tabs/emoji_tab.vue index 699e4afe..534f881a 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.vue +++ b/src/components/settings_modal/admin_tabs/emoji_tab.vue @@ -6,84 +6,166 @@

{{ $t('admin_dash.tabs.emoji') }}

- - - - +
    +
  • + + +
  • - -
    -
    -
      -
    • -
      Description
      -