From 2841de76cf1a9891864362f6af291af28878c6d4 Mon Sep 17 00:00:00 2001 From: vaartis Date: Mon, 23 Sep 2019 18:42:18 +0000 Subject: [PATCH] Add configuration for sharing emoji packs --- CHANGELOG.md | 6 + README.md | 3 +- build/webpack.dev.conf.js | 2 +- src/api/emoji_packs.js | 147 ++++++++++++ src/lang/en.js | 3 +- src/router/index.js | 15 ++ src/store/index.js | 4 +- src/store/modules/emoji_packs.js | 129 +++++++++++ src/utils/request.js | 4 +- .../emoji-packs/components/EmojiPack.vue | 218 ++++++++++++++++++ .../components/NewEmojiUploader.vue | 93 ++++++++ .../components/PropertyEditingRow.vue | 27 +++ .../components/SingleEmojiEditor.vue | 175 ++++++++++++++ src/views/emoji-packs/index.vue | 151 ++++++++++++ 14 files changed, 971 insertions(+), 6 deletions(-) create mode 100644 src/api/emoji_packs.js create mode 100644 src/store/modules/emoji_packs.js create mode 100644 src/views/emoji-packs/components/EmojiPack.vue create mode 100644 src/views/emoji-packs/components/NewEmojiUploader.vue create mode 100644 src/views/emoji-packs/components/PropertyEditingRow.vue create mode 100644 src/views/emoji-packs/components/SingleEmojiEditor.vue create mode 100644 src/views/emoji-packs/index.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e672e1f..73e40d47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## Unreleased + +### Added + +- Emoji pack configuration + ## [1.1.0] - 2019-09-15 ### Added diff --git a/README.md b/README.md index 1dc6db0c..72c81829 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ To compile everything for production run `yarn build:prod`. #### Disabling features -You can disable certain AdminFE features, like reports or settings by modifying `config/prod.env.js` env variable `DISABLED_FEATURES`, e.g. if you want to compile AdminFE without "Settings" you'll need to set it to: `DISABLED_FEATURES: '["settings"]'`. +You can disable certain AdminFE features, like reports or settings by modifying `config/prod.env.js` env variable `DISABLED_FEATURES`, e.g. if you want to compile AdminFE without "Settings" you'll need to set it to: `DISABLED_FEATURES: '["settings"]'`, +to disable emoji pack settings add `"emoji-packs"` to the list. ## Changelog diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js index fb90173a..1b6d4d75 100644 --- a/build/webpack.dev.conf.js +++ b/build/webpack.dev.conf.js @@ -48,7 +48,7 @@ const devWebpackConfig = merge(baseWebpackConfig, { poll: config.dev.poll }, headers: { - 'content-security-policy': "base-uri 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; manifest-src 'self'; script-src 'self';" + 'content-security-policy': "base-uri 'self'; frame-ancestors 'none'; img-src 'self' data: https: http:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; manifest-src 'self'; script-src 'self';" } }, plugins: [ diff --git a/src/api/emoji_packs.js b/src/api/emoji_packs.js new file mode 100644 index 00000000..086c329f --- /dev/null +++ b/src/api/emoji_packs.js @@ -0,0 +1,147 @@ +import request from '@/utils/request' +import { getToken } from '@/utils/auth' +import { baseName } from './utils' + +import _ from 'lodash' + +export async function deletePack(host, token, name) { + return await request({ + baseURL: baseName(host), + url: `/api/pleroma/emoji/packs/${name}`, + method: 'delete', + headers: authHeaders(token) + }) +} + +export async function reloadEmoji(host, token) { + return await request({ + baseURL: baseName(host), + url: '/api/pleroma/admin/reload_emoji', + method: 'post', + headers: authHeaders(token) + }) +} + +export async function importFromFS(host, token) { + return await request({ + baseURL: baseName(host), + url: '/api/pleroma/emoji/packs/import_from_fs', + method: 'post', + headers: authHeaders(token) + }) +} + +export async function createPack(host, token, name) { + return await request({ + baseURL: baseName(host), + url: `/api/pleroma/emoji/packs/${name}`, + method: 'put', + headers: authHeaders(token) + }) +} + +export async function listPacks(host) { + return await request({ + baseURL: baseName(host), + url: `/api/pleroma/emoji/packs/`, + method: 'get' + }) +} + +export async function downloadFrom(host, instance_address, pack_name, as, token) { + if (as.trim() === '') { + as = null + } + + return await request({ + baseURL: baseName(host), + url: '/api/pleroma/emoji/packs/download_from', + method: 'post', + headers: authHeaders(token), + data: { instance_address, pack_name, as }, + timeout: 0 + }) +} + +export async function savePackMetadata(host, token, name, new_data) { + return await request({ + baseURL: baseName(host), + url: `/api/pleroma/emoji/packs/${name}/update_metadata`, + method: 'post', + headers: authHeaders(token), + data: { name, new_data }, + timeout: 0 // This might take a long time + }) +} + +function fileUpdateFormData(d) { + const data = new FormData() + + _.each(d, (v, k) => { + data.set(k, v) + }) + + return data +} + +export async function updatePackFile(host, token, args) { + let data = null + + switch (args.action) { + case 'add': { + const { shortcode, file, fileName } = args + + data = fileUpdateFormData({ + action: 'add', + shortcode: shortcode, + file: file + }) + if (fileName.trim() !== '') { + data.set('filename', fileName) + } + + break + } + + case 'update': { + const { oldName, newName, newFilename } = args + + data = fileUpdateFormData({ + action: 'update', + shortcode: oldName, + new_shortcode: newName, + new_filename: newFilename + }) + + break + } + + case 'remove': { + const { name } = args + data = fileUpdateFormData({ + action: 'remove', + shortcode: name + }) + + break + } + } + + const { packName } = args + + return await request({ + baseURL: baseName(host), + url: `/api/pleroma/emoji/packs/${packName}/update_file`, + method: 'post', + headers: authHeaders(token), + data: data, + timeout: 0 + }) +} + +export function addressOfEmojiInPack(host, packName, name) { + // This needs http because hackney on the BE does not understand URLs with just "//" + return `http://${baseName(host)}/emoji/${packName}/${name}` +} + +const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {} diff --git a/src/lang/en.js b/src/lang/en.js index e21edbce..0f1e4bbc 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -66,7 +66,8 @@ export default { externalLink: 'External Link', users: 'Users', reports: 'Reports', - settings: 'Settings' + settings: 'Settings', + 'emoji-packs': 'Emoji packs' }, navbar: { logOut: 'Log Out', diff --git a/src/router/index.js b/src/router/index.js index 90db3fd3..9070b14f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -35,6 +35,20 @@ const reports = { ] } +const emojiPacksDisabled = disabledFeatures.includes('emoji-packs') +const emojiPacks = { + path: '/emoji-packs', + component: Layout, + children: [ + { + path: 'index', + component: () => import('@/views/emoji-packs/index'), + name: 'Emoji packs', + meta: { title: 'emoji-packs', icon: 'settings', noCache: true } + } + ] +} + export const constantRouterMap = [ { path: '/redirect', @@ -100,6 +114,7 @@ export const asyncRouterMap = [ }, ...(settingsDisabled ? [] : [settings]), ...(reportsDisabled ? [] : [reports]), + ...(emojiPacksDisabled ? [] : [emojiPacks]), { path: '/users/:id', component: Layout, diff --git a/src/store/index.js b/src/store/index.js index 161a87d6..c3d1eb78 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -10,6 +10,7 @@ import user from './modules/user' import userProfile from './modules/userProfile' import users from './modules/users' import getters from './getters' +import emoji_packs from './modules/emoji_packs.js' Vue.use(Vuex) @@ -23,7 +24,8 @@ const store = new Vuex.Store({ tagsView, user, userProfile, - users + users, + emoji_packs }, getters }) diff --git a/src/store/modules/emoji_packs.js b/src/store/modules/emoji_packs.js new file mode 100644 index 00000000..20dacf3a --- /dev/null +++ b/src/store/modules/emoji_packs.js @@ -0,0 +1,129 @@ +import { listPacks, + downloadFrom, + reloadEmoji, + createPack, + deletePack, + savePackMetadata, + importFromFS, + updatePackFile } from '@/api/emoji_packs' + +import { Message } from 'element-ui' + +import Vue from 'vue' + +const packs = { + state: { + localPacks: {}, + remotePacks: {} + }, + mutations: { + SET_LOCAL_PACKS: (state, packs) => { + state.localPacks = packs + }, + SET_REMOTE_PACKS: (state, packs) => { + state.remotePacks = packs + }, + + UPDATE_LOCAL_PACK_VAL: (state, { name, key, value }) => { + Vue.set(state.localPacks[name]['pack'], key, value) + }, + + UPDATE_LOCAL_PACK_PACK: (state, { name, pack }) => { + state.localPacks[name]['pack'] = pack + }, + + UPDATE_LOCAL_PACK_FILES: (state, { name, files }) => { + // Use vue.set in case "files" was null + Vue.set( + state.localPacks[name], + 'files', + files + ) + } + }, + actions: { + async SetLocalEmojiPacks({ commit, getters, state }) { + const { data } = await listPacks(getters.authHost) + commit('SET_LOCAL_PACKS', data) + }, + async SetRemoteEmojiPacks({ commit, getters, state }, { remoteInstance }) { + const { data } = await listPacks(remoteInstance) + commit('SET_REMOTE_PACKS', data) + }, + async DownloadFrom({ commit, getters, state }, { instanceAddress, packName, as }) { + const result = await downloadFrom(getters.authHost, instanceAddress, packName, as, getters.token) + + if (result.data === 'ok') { + Message({ + message: `Successfully downloaded ${packName}`, + type: 'success', + duration: 5 * 1000 + }) + } + }, + async ReloadEmoji({ commit, getters, state }) { + await reloadEmoji(getters.authHost, getters.token) + }, + async ImportFromFS({ commit, getters, state }) { + const result = await importFromFS(getters.authHost, getters.token) + + if (result.status === 200) { + const message = result.data.length > 0 ? `Successfully imported ${result.data}` : 'No new packs to import' + + Message({ + message, + type: 'success', + duration: 5 * 1000 + }) + } + }, + async DeletePack({ commit, getters, state }, { name }) { + await deletePack(getters.authHost, getters.token, name) + }, + async CreatePack({ commit, getters, state }, { name }) { + await createPack(getters.authHost, getters.token, name) + }, + + async UpdateLocalPackVal({ commit, getters, state }, args) { + commit('UPDATE_LOCAL_PACK_VAL', args) + }, + + async SavePackMetadata({ commit, getters, state }, { packName }) { + const result = + await savePackMetadata( + getters.authHost, + getters.token, + packName, + state.localPacks[packName]['pack'] + ) + + if (result.status === 200) { + Message({ + message: `Successfully updated ${packName} metadata`, + type: 'success', + duration: 5 * 1000 + }) + + commit('UPDATE_LOCAL_PACK_PACK', { name: packName, pack: result.data }) + } + }, + + async UpdateAndSavePackFile({ commit, getters, state }, args) { + const result = await updatePackFile(getters.authHost, getters.token, args) + + if (result.status === 200) { + const { packName } = args + + Message({ + message: `Successfully updated ${packName} files`, + type: 'success', + duration: 5 * 1000 + }) + + commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: result.data }) + } + } + } +} + +export default packs diff --git a/src/utils/request.js b/src/utils/request.js index df87a046..7e9acc1e 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -10,9 +10,9 @@ const service = axios.create({ service.interceptors.response.use( response => response, error => { - console.log('err' + error) + console.log('Error ' + error) Message({ - message: error.message, + message: `${error.message} - ${error.response.data}`, type: 'error', duration: 5 * 1000 }) diff --git a/src/views/emoji-packs/components/EmojiPack.vue b/src/views/emoji-packs/components/EmojiPack.vue new file mode 100644 index 00000000..d29ea9b2 --- /dev/null +++ b/src/views/emoji-packs/components/EmojiPack.vue @@ -0,0 +1,218 @@ + + + + + diff --git a/src/views/emoji-packs/components/NewEmojiUploader.vue b/src/views/emoji-packs/components/NewEmojiUploader.vue new file mode 100644 index 00000000..d62011de --- /dev/null +++ b/src/views/emoji-packs/components/NewEmojiUploader.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/views/emoji-packs/components/PropertyEditingRow.vue b/src/views/emoji-packs/components/PropertyEditingRow.vue new file mode 100644 index 00000000..8696e06a --- /dev/null +++ b/src/views/emoji-packs/components/PropertyEditingRow.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/views/emoji-packs/components/SingleEmojiEditor.vue b/src/views/emoji-packs/components/SingleEmojiEditor.vue new file mode 100644 index 00000000..e5d7b01b --- /dev/null +++ b/src/views/emoji-packs/components/SingleEmojiEditor.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/src/views/emoji-packs/index.vue b/src/views/emoji-packs/index.vue new file mode 100644 index 00000000..eb64fbed --- /dev/null +++ b/src/views/emoji-packs/index.vue @@ -0,0 +1,151 @@ + + + + +