Initial incomplete admin emoji settings implementation
This commit is contained in:
parent
6391a6a4ea
commit
f9c85c0c49
62
src/components/settings_modal/admin_tabs/emoji_tab.js
Normal file
62
src/components/settings_modal/admin_tabs/emoji_tab.js
Normal file
@ -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
|
24
src/components/settings_modal/admin_tabs/emoji_tab.scss
Normal file
24
src/components/settings_modal/admin_tabs/emoji_tab.scss
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
93
src/components/settings_modal/admin_tabs/emoji_tab.vue
Normal file
93
src/components/settings_modal/admin_tabs/emoji_tab.vue
Normal file
@ -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>
|
@ -3,6 +3,7 @@ import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
|
|||||||
import InstanceTab from './admin_tabs/instance_tab.vue'
|
import InstanceTab from './admin_tabs/instance_tab.vue'
|
||||||
import LimitsTab from './admin_tabs/limits_tab.vue'
|
import LimitsTab from './admin_tabs/limits_tab.vue'
|
||||||
import FrontendsTab from './admin_tabs/frontends_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 { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
@ -33,7 +34,8 @@ const SettingsModalAdminContent = {
|
|||||||
|
|
||||||
InstanceTab,
|
InstanceTab,
|
||||||
LimitsTab,
|
LimitsTab,
|
||||||
FrontendsTab
|
FrontendsTab,
|
||||||
|
EmojiTab
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
user () {
|
user () {
|
||||||
|
@ -60,6 +60,14 @@
|
|||||||
>
|
>
|
||||||
<FrontendsTab />
|
<FrontendsTab />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
:label="$t('admin_dash.tabs.emoji')"
|
||||||
|
icon="laptop-code"
|
||||||
|
data-tab-name="emoji"
|
||||||
|
>
|
||||||
|
<EmojiTab />
|
||||||
|
</div>
|
||||||
</tab-switcher>
|
</tab-switcher>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -877,7 +877,8 @@
|
|||||||
"nodb": "No DB Config",
|
"nodb": "No DB Config",
|
||||||
"instance": "Instance",
|
"instance": "Instance",
|
||||||
"limits": "Limits",
|
"limits": "Limits",
|
||||||
"frontends": "Front-ends"
|
"frontends": "Front-ends",
|
||||||
|
"emoji": "Emoji"
|
||||||
},
|
},
|
||||||
"nodb": {
|
"nodb": {
|
||||||
"heading": "Database config is disabled",
|
"heading": "Database config is disabled",
|
||||||
@ -931,6 +932,10 @@
|
|||||||
"failure_installing_frontend": "Failed to install frontend {version}: {reason}",
|
"failure_installing_frontend": "Failed to install frontend {version}: {reason}",
|
||||||
"success_installing_frontend": "Frontend {version} successfully installed"
|
"success_installing_frontend": "Frontend {version} successfully installed"
|
||||||
},
|
},
|
||||||
|
"emoji": {
|
||||||
|
"reload": "Reload emoji",
|
||||||
|
"importFS": "Import emoji from filesystem"
|
||||||
|
},
|
||||||
"temp_overrides": {
|
"temp_overrides": {
|
||||||
":pleroma": {
|
":pleroma": {
|
||||||
":instance": {
|
":instance": {
|
||||||
|
@ -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_URL = '/api/pleroma/admin/frontends'
|
||||||
const PLEROMA_ADMIN_FRONTENDS_INSTALL_URL = '/api/pleroma/admin/frontends/install'
|
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 oldfetch = window.fetch
|
||||||
|
|
||||||
const fetch = (url, options) => {
|
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 = {
|
const apiService = {
|
||||||
verifyCredentials,
|
verifyCredentials,
|
||||||
fetchTimeline,
|
fetchTimeline,
|
||||||
@ -1906,7 +2001,18 @@ const apiService = {
|
|||||||
fetchInstanceConfigDescriptions,
|
fetchInstanceConfigDescriptions,
|
||||||
fetchAvailableFrontends,
|
fetchAvailableFrontends,
|
||||||
pushInstanceDBConfig,
|
pushInstanceDBConfig,
|
||||||
installFrontend
|
installFrontend,
|
||||||
|
importEmojiFromFS,
|
||||||
|
reloadEmoji,
|
||||||
|
listEmojiPacks,
|
||||||
|
createEmojiPack,
|
||||||
|
deleteEmojiPack,
|
||||||
|
saveEmojiPackMetadata,
|
||||||
|
addNewEmojiFile,
|
||||||
|
updateEmojiFile,
|
||||||
|
deleteEmojiFile,
|
||||||
|
listRemoteEmojiPacks,
|
||||||
|
downloadRemoteEmojiPack
|
||||||
}
|
}
|
||||||
|
|
||||||
export default apiService
|
export default apiService
|
||||||
|
Loading…
Reference in New Issue
Block a user