Merge branch 'feature/emoji-packs-pagination' into 'develop'

Implement emoji packs pagination

Closes #118

See merge request pleroma/admin-fe!137
This commit is contained in:
Angelina Filippova 2020-06-25 23:07:59 +00:00
commit f1a9d1726a
10 changed files with 264 additions and 129 deletions

View file

@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- On Reports page add links to reported account and the author of the report - On Reports page add links to reported account and the author of the report
- In Notes add link to the note author's profile page - In Notes add link to the note author's profile page
- In Moderation log add link to the actor's profile page - In Moderation log add link to the actor's profile page
- Support pagination of local emoji packs and files
- Adds MRF Activity Expiration setting - Adds MRF Activity Expiration setting
### Changed ### Changed

View file

@ -37,10 +37,9 @@ export async function createPack(host, token, packName) {
export async function deleteEmojiFile(packName, shortcode, host, token) { export async function deleteEmojiFile(packName, shortcode, host, token) {
return await request({ return await request({
baseURL: baseName(host), baseURL: baseName(host),
url: `/api/pleroma/emoji/packs/${packName}/files`, url: `/api/pleroma/emoji/packs/${packName}/files?shortcode=${shortcode}`,
method: 'delete', method: 'delete',
headers: authHeaders(token), headers: authHeaders(token)
data: { shortcode }
}) })
} }
@ -53,25 +52,23 @@ export async function deletePack(host, token, packName) {
}) })
} }
export async function downloadFrom(host, instance, packName, as, token) { export async function downloadFrom(instanceAddress, packName, as, host, token) {
if (as.trim() === '') {
as = null
}
return await request({ return await request({
baseURL: baseName(host), baseURL: baseName(host),
url: '/api/pleroma/emoji/packs/download', url: '/api/pleroma/emoji/packs/download',
method: 'post', method: 'post',
headers: authHeaders(token), headers: authHeaders(token),
data: { url: baseName(instance), name: packName, as }, data: as.trim() === ''
? { url: baseName(instanceAddress), name: packName }
: { url: baseName(instanceAddress), name: packName, as },
timeout: 0 timeout: 0
}) })
} }
export async function fetchPack(packName, host, token) { export async function fetchPack(packName, page, pageSize, host, token) {
return await request({ return await request({
baseURL: baseName(host), baseURL: baseName(host),
url: `/api/pleroma/emoji/packs/${packName}`, url: `/api/pleroma/emoji/packs/${packName}?page=${page}&page_size=${pageSize}`,
method: 'get', method: 'get',
headers: authHeaders(token) headers: authHeaders(token)
}) })
@ -86,11 +83,12 @@ export async function importFromFS(host, token) {
}) })
} }
export async function listPacks(host) { export async function listPacks(page, pageSize, host, token) {
return await request({ return await request({
baseURL: baseName(host), baseURL: baseName(host),
url: `/api/pleroma/emoji/packs/`, url: `/api/pleroma/emoji/packs?page=${page}&page_size=${pageSize}`,
method: 'get' method: 'get',
headers: authHeaders(token)
}) })
} }

View file

@ -475,6 +475,7 @@ export default {
specifyShortcode: 'Specify a custom shortcode', specifyShortcode: 'Specify a custom shortcode',
specifyFilename: 'Specify a custom filename', specifyFilename: 'Specify a custom filename',
copy: 'Copy', copy: 'Copy',
copyToLocalPack: 'Copy to local pack' copyToLocalPack: 'Copy to local pack',
emptyPack: 'This emoji pack is empty'
} }
} }

View file

@ -1,9 +1,11 @@
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import app from './modules/app' import app from './modules/app'
import emojiPacks from './modules/emojiPacks'
import errorLog from './modules/errorLog' import errorLog from './modules/errorLog'
import moderationLog from './modules/moderationLog' import getters from './getters'
import invites from './modules/invites' import invites from './modules/invites'
import moderationLog from './modules/moderationLog'
import peers from './modules/peers' import peers from './modules/peers'
import permission from './modules/permission' import permission from './modules/permission'
import relays from './modules/relays' import relays from './modules/relays'
@ -14,8 +16,6 @@ import tagsView from './modules/tagsView'
import user from './modules/user' import user from './modules/user'
import userProfile from './modules/userProfile' import userProfile from './modules/userProfile'
import users from './modules/users' import users from './modules/users'
import getters from './getters'
import emojiPacks from './modules/emojiPacks.js'
Vue.use(Vuex) Vue.use(Vuex)
@ -23,6 +23,7 @@ const store = new Vuex.Store({
modules: { modules: {
app, app,
errorLog, errorLog,
emojiPacks,
moderationLog, moderationLog,
invites, invites,
peers, peers,
@ -34,8 +35,7 @@ const store = new Vuex.Store({
tagsView, tagsView,
user, user,
userProfile, userProfile,
users, users
emojiPacks
}, },
getters getters
}) })

View file

@ -4,6 +4,7 @@ import {
deleteEmojiFile, deleteEmojiFile,
deletePack, deletePack,
downloadFrom, downloadFrom,
fetchPack,
importFromFS, importFromFS,
listPacks, listPacks,
listRemotePacks, listRemotePacks,
@ -16,20 +17,41 @@ import { Message } from 'element-ui'
import Vue from 'vue' import Vue from 'vue'
const packs = { const emojiPacks = {
state: { state: {
activeCollapseItems: [], activeTab: '',
currentFilesPage: 1,
currentPage: 1,
filesPageSize: 30,
localPackFilesCount: 0,
localPacks: {}, localPacks: {},
localPacksCount: 0,
pageSize: 50,
remoteInstance: '', remoteInstance: '',
remotePacks: {} remotePacks: {}
}, },
mutations: { mutations: {
SET_ACTIVE_COLLAPSE_ITEMS: (state, items) => { SET_ACTIVE_TAB: (state, tab) => {
state.activeCollapseItems = items state.activeTab = tab
},
SET_FILES_COUNT: (state, count) => {
state.localPackFilesCount = count
},
SET_FILES_PAGE: (state, page) => {
state.currentFilesPage = page
}, },
SET_LOCAL_PACKS: (state, packs) => { SET_LOCAL_PACKS: (state, packs) => {
state.localPacks = packs state.localPacks = packs
}, },
SET_LOCAL_PACKS_COUNT: (state, count) => {
state.localPacksCount = count
},
SET_PACK_FILES: (state, { name, files }) => {
state.localPacks = { ...state.localPacks, [name]: { ...state.localPacks[name], files }}
},
SET_PAGE: (state, page) => {
state.currentPage = page
},
SET_REMOTE_INSTANCE: (state, name) => { SET_REMOTE_INSTANCE: (state, name) => {
state.remoteInstance = name state.remoteInstance = name
}, },
@ -67,10 +89,12 @@ const packs = {
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: result.data }) commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: result.data })
}, },
async DeleteEmojiFile({ commit, getters }, { packName, shortcode }) { async DeleteEmojiFile({ commit, dispatch, getters, state }, { packName, shortcode }) {
let result const { [shortcode]: value, ...updatedPackFiles } = state.localPacks[packName].files
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: updatedPackFiles })
try { try {
result = await deleteEmojiFile(packName, shortcode, getters.authHost, getters.token) await deleteEmojiFile(packName, shortcode, getters.authHost, getters.token)
} catch (_e) { } catch (_e) {
return return
} }
@ -79,8 +103,11 @@ const packs = {
type: 'success', type: 'success',
duration: 5 * 1000 duration: 5 * 1000
}) })
if (Object.keys(updatedPackFiles).length === 0 && state.currentFilesPage > 1) {
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: result.data }) dispatch('FetchSinglePack', { name: packName, page: state.currentFilesPage - 1 })
} else {
dispatch('FetchSinglePack', { name: packName, page: state.currentFilesPage })
}
}, },
async CreatePack({ getters }, { name }) { async CreatePack({ getters }, { name }) {
await createPack(getters.authHost, getters.token, name) await createPack(getters.authHost, getters.token, name)
@ -89,7 +116,7 @@ const packs = {
await deletePack(getters.authHost, getters.token, name) await deletePack(getters.authHost, getters.token, name)
}, },
async DownloadFrom({ getters }, { instanceAddress, packName, as }) { async DownloadFrom({ getters }, { instanceAddress, packName, as }) {
const result = await downloadFrom(getters.authHost, instanceAddress, packName, as, getters.token) const result = await downloadFrom(instanceAddress, packName, as, getters.authHost, getters.token)
if (result.data === 'ok') { if (result.data === 'ok') {
Message({ Message({
@ -99,6 +126,25 @@ const packs = {
}) })
} }
}, },
async FetchLocalEmojiPacks({ commit, getters, state }, page) {
const { data } = await listPacks(page, state.pageSize, getters.authHost, getters.token)
const { packs, count } = data
const updatedPacks = Object.keys(packs).reduce((acc, packName) => {
const { files, ...pack } = packs[packName]
acc[packName] = pack
return acc
}, {})
commit('SET_LOCAL_PACKS', updatedPacks)
commit('SET_LOCAL_PACKS_COUNT', count)
commit('SET_PAGE', page)
},
async FetchSinglePack({ getters, commit, state }, { name, page }) {
const { data } = await fetchPack(name, page, state.filesPageSize, getters.authHost, getters.token)
const { files, files_count } = data
commit('SET_PACK_FILES', { name, files })
commit('SET_FILES_COUNT', files_count)
commit('SET_FILES_PAGE', page)
},
async ImportFromFS({ getters }) { async ImportFromFS({ getters }) {
const result = await importFromFS(getters.authHost, getters.token) const result = await importFromFS(getters.authHost, getters.token)
@ -136,12 +182,8 @@ const packs = {
commit('UPDATE_LOCAL_PACK_PACK', { name: packName, pack: result.data }) commit('UPDATE_LOCAL_PACK_PACK', { name: packName, pack: result.data })
} }
}, },
SetActiveCollapseItems({ commit, state }, activeItems) { SetActiveTab({ commit }, activeTab) {
commit('SET_ACTIVE_COLLAPSE_ITEMS', activeItems) commit('SET_ACTIVE_TAB', activeTab)
},
async SetLocalEmojiPacks({ commit, getters }) {
const { data } = await listPacks(getters.authHost)
commit('SET_LOCAL_PACKS', data)
}, },
async SetRemoteEmojiPacks({ commit, getters }, { remoteInstance }) { async SetRemoteEmojiPacks({ commit, getters }, { remoteInstance }) {
const { data } = await listRemotePacks(getters.authHost, getters.token, remoteInstance) const { data } = await listRemotePacks(getters.authHost, getters.token, remoteInstance)
@ -152,10 +194,19 @@ const packs = {
SetRemoteInstance({ commit }, instance) { SetRemoteInstance({ commit }, instance) {
commit('SET_REMOTE_INSTANCE', instance) commit('SET_REMOTE_INSTANCE', instance)
}, },
async UpdateEmojiFile({ commit, getters }, { packName, shortcode, newShortcode, newFilename, force }) { async UpdateEmojiFile({ commit, dispatch, getters, state }, { packName, shortcode, newShortcode, newFilename, force }) {
let result const updatedPackFiles = Object.keys(state.localPacks[packName].files).reduce((acc, el) => {
if (el === shortcode) {
acc[newShortcode] = newFilename
} else {
acc[el] = state.localPacks[packName].files[el]
}
return acc
}, {})
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: updatedPackFiles })
try { try {
result = await updateEmojiFile(packName, shortcode, newShortcode, newFilename, force, getters.authHost, getters.token) await updateEmojiFile(packName, shortcode, newShortcode, newFilename, force, getters.authHost, getters.token)
} catch (_e) { } catch (_e) {
return return
} }
@ -165,7 +216,7 @@ const packs = {
duration: 5 * 1000 duration: 5 * 1000
}) })
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: result.data }) dispatch('FetchSinglePack', { name: packName, page: state.currentFilesPage })
}, },
async UpdateLocalPackVal({ commit }, args) { async UpdateLocalPackVal({ commit }, args) {
commit('UPDATE_LOCAL_PACK_VAL', args) commit('UPDATE_LOCAL_PACK_VAL', args)
@ -173,4 +224,4 @@ const packs = {
} }
} }
export default packs export default emojiPacks

View file

@ -38,19 +38,32 @@
</el-link> </el-link>
</div> </div>
</div> </div>
<el-collapse v-model="showPackContent" class="contents-collapse"> <el-collapse v-model="showPackContent" class="contents-collapse" @change="handleChange($event, name)">
<el-collapse-item v-if="isLocal" :title=" $t('emoji.addNewEmoji')" name="addEmoji" class="no-background"> <el-collapse-item v-if="isLocal" :title=" $t('emoji.addNewEmoji')" name="addEmoji" class="no-background">
<new-emoji-uploader :pack-name="name"/> <new-emoji-uploader :pack-name="name"/>
</el-collapse-item> </el-collapse-item>
<el-collapse-item v-if="pack.files.length > 0" :title=" $t('emoji.manageEmoji')" name="manageEmoji" class="no-background"> <el-collapse-item :title=" $t('emoji.manageEmoji')" name="manageEmoji" class="no-background">
<single-emoji-editor <div v-if="pack.files && Object.keys(pack.files).length > 0">
v-for="[shortcode, file] in pack.files" <single-emoji-editor
:key="shortcode" v-for="(file, shortcode) in pack.files"
:host="host" :key="shortcode"
:pack-name="name" :host="host"
:shortcode="shortcode" :pack-name="name"
:file="file" :shortcode="shortcode"
:is-local="isLocal" /> :file="file"
:is-local="isLocal" />
</div>
<span v-else class="expl">{{ $t('emoji.emptyPack') }}</span>
<div class="files-pagination">
<el-pagination
:total="localPackFilesCount"
:current-page="currentFilesPage"
:page-size="pageSize"
hide-on-single-page
layout="prev, pager, next"
@current-change="handleFilesPageChange"
/>
</div>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
</el-collapse-item> </el-collapse-item>
@ -86,6 +99,12 @@ export default {
} }
}, },
computed: { computed: {
currentFilesPage() {
return this.$store.state.emojiPacks.currentFilesPage
},
currentPage() {
return this.$store.state.emojiPacks.currentPage
},
isMobile() { isMobile() {
return this.$store.state.app.device === 'mobile' return this.$store.state.app.device === 'mobile'
}, },
@ -101,6 +120,12 @@ export default {
return '155px' return '155px'
} }
}, },
localPackFilesCount() {
return this.$store.state.emojiPacks.localPackFilesCount
},
pageSize() {
return this.$store.state.emojiPacks.filesPageSize
},
share: { share: {
get() { return this.pack.pack['share-files'] }, get() { return this.pack.pack['share-files'] },
set(value) { set(value) {
@ -159,6 +184,9 @@ export default {
} }
}, },
methods: { methods: {
collapse() {
this.showPackContent = []
},
deletePack() { deletePack() {
this.$confirm('This will delete the pack, are you sure?', 'Warning', { this.$confirm('This will delete the pack, are you sure?', 'Warning', {
confirmButtonText: 'Yes, delete the pack', confirmButtonText: 'Yes, delete the pack',
@ -167,9 +195,24 @@ export default {
}).then(() => { }).then(() => {
this.$store.dispatch('DeletePack', { name: this.name }) this.$store.dispatch('DeletePack', { name: this.name })
.then(() => this.$store.dispatch('ReloadEmoji')) .then(() => this.$store.dispatch('ReloadEmoji'))
.then(() => this.$store.dispatch('SetLocalEmojiPacks')) .then(() => {
const { [this.name]: value, ...updatedPacks } = this.$store.state.emojiPacks.localPacks
if (Object.keys(updatedPacks).length === 0 && this.currentPage > 1) {
this.$store.dispatch('FetchLocalEmojiPacks', this.currentPage - 1)
} else {
this.$store.dispatch('FetchLocalEmojiPacks', this.currentPage)
}
})
}).catch(() => {}) }).catch(() => {})
}, },
handleChange(openTabs, name) {
if (openTabs.includes('manageEmoji')) {
this.$store.dispatch('FetchSinglePack', { name, page: 1 })
}
},
handleFilesPageChange(page) {
this.$store.dispatch('FetchSinglePack', { name: this.name, page })
},
savePackMetadata() { savePackMetadata() {
this.$store.dispatch('SavePackMetadata', { packName: this.name }) this.$store.dispatch('SavePackMetadata', { packName: this.name })
} }
@ -217,6 +260,10 @@ export default {
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
.files-pagination {
margin: 25px 0;
text-align: center;
}
.has-background .el-collapse-item__header { .has-background .el-collapse-item__header {
background: #f6f6f6; background: #f6f6f6;
} }

View file

@ -24,7 +24,7 @@
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-link <el-link
v-if="pack.pack['can-download']" v-if="pack.pack['can-download'] && pack.pack['fallback-src']"
:href="pack.pack['fallback-src']" :href="pack.pack['fallback-src']"
:underline="false" :underline="false"
type="primary" type="primary"
@ -34,15 +34,18 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-collapse v-model="showPackContent" class="contents-collapse"> <el-collapse v-model="showPackContent" class="contents-collapse">
<el-collapse-item v-if="pack.files.length > 0" :title=" $t('emoji.manageEmoji')" name="manageEmoji" class="no-background"> <el-collapse-item :title=" $t('emoji.manageEmoji')" name="manageEmoji" class="no-background">
<single-emoji-editor <div v-if="pack.files && Object.keys(pack.files).length > 0">
v-for="[shortcode, file] in pack.files" <single-emoji-editor
:key="shortcode" v-for="(file, shortcode) in pack.files"
:host="host" :key="shortcode"
:pack-name="name" :host="host"
:shortcode="shortcode" :pack-name="name"
:file="file" :shortcode="shortcode"
:is-local="isLocal" /> :file="file"
:is-local="isLocal" />
</div>
<span v-else class="expl">{{ $t('emoji.emptyPack') }}</span>
</el-collapse-item> </el-collapse-item>
<el-collapse-item :title=" $t('emoji.downloadPack')" name="downloadPack" class="no-background"> <el-collapse-item :title=" $t('emoji.downloadPack')" name="downloadPack" class="no-background">
<p> <p>
@ -92,6 +95,9 @@ export default {
} }
}, },
computed: { computed: {
currentPage() {
return this.$store.state.emojiPacks.currentPage
},
isDesktop() { isDesktop() {
return this.$store.state.app.device === 'desktop' return this.$store.state.app.device === 'desktop'
}, },
@ -111,7 +117,7 @@ export default {
} }
}, },
loadRemotePack() { loadRemotePack() {
return this.$store.state.emojiPacks.activeCollapseItems.includes(this.name) return this.$store.state.emojiPacks.activeTab === this.name
}, },
remoteInstanceAddress() { remoteInstanceAddress() {
return this.$store.state.emojiPacks.remoteInstance return this.$store.state.emojiPacks.remoteInstance
@ -179,7 +185,7 @@ export default {
'DownloadFrom', 'DownloadFrom',
{ instanceAddress: this.remoteInstanceAddress, packName: this.name, as: this.downloadSharedAs } { instanceAddress: this.remoteInstanceAddress, packName: this.name, as: this.downloadSharedAs }
).then(() => this.$store.dispatch('ReloadEmoji')) ).then(() => this.$store.dispatch('ReloadEmoji'))
.then(() => this.$store.dispatch('SetLocalEmojiPacks')) .then(() => this.$store.dispatch('FetchLocalEmojiPacks', this.currentPage))
} }
} }
} }

View file

@ -103,7 +103,7 @@ export default {
return this.$store.state.emojiPacks.localPacks return this.$store.state.emojiPacks.localPacks
}, },
remoteInstance() { remoteInstance() {
return new URL(this.$store.state.emojiPacks.remoteInstance).host return this.$store.state.emojiPacks.remoteInstance
} }
}, },
methods: { methods: {

View file

@ -6,56 +6,72 @@
</div> </div>
<div class="emoji-header-container"> <div class="emoji-header-container">
<div class="emoji-packs-header-button-container"> <div class="emoji-packs-header-button-container">
<el-button type="primary" class="reload-emoji-button" @click="reloadEmoji">{{ $t('emoji.reloadEmoji') }}</el-button> <el-button class="reload-emoji-button" @click="reloadEmoji">{{ $t('emoji.reloadEmoji') }}</el-button>
<el-tooltip :content="$t('emoji.importEmojiTooltip')" effects="dark" placement="bottom" popper-class="import-pack-button"> <el-tooltip :content="$t('emoji.importEmojiTooltip')" effects="dark" placement="bottom" popper-class="import-pack-button">
<el-button type="primary" @click="importFromFS"> <el-button @click="importFromFS">
{{ $t('emoji.importPacks') }} {{ $t('emoji.importPacks') }}
</el-button> </el-button>
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<el-divider class="divider"/> <el-tabs v-model="activeTab" type="card" class="emoji-packs-tabs">
<el-form :label-width="labelWidth" class="emoji-packs-form"> <el-tab-pane :label="$t('emoji.localPacks')" name="local">
<el-form-item :label="$t('emoji.localPacks')"> <el-form :label-width="labelWidth" class="emoji-packs-form">
<el-button type="primary" @click="refreshLocalPacks">{{ $t('emoji.refreshLocalPacks') }}</el-button> <el-form-item :label="$t('emoji.localPacks')">
</el-form-item> <el-button @click="refreshLocalPacks">{{ $t('emoji.refreshLocalPacks') }}</el-button>
<el-form-item :label="$t('emoji.createLocalPack')"> </el-form-item>
<div class="create-pack"> <el-form-item :label="$t('emoji.createLocalPack')">
<el-input v-model="newPackName" :placeholder="$t('users.name')" /> <div class="create-pack">
<el-button <el-input v-model="newPackName" :placeholder="$t('users.name')" />
:disabled="newPackName.trim() === ''" <el-button
class="create-pack-button" :disabled="newPackName.trim() === ''"
@click="createLocalPack"> class="create-pack-button"
{{ $t('users.create') }} @click="createLocalPack">
</el-button> {{ $t('users.create') }}
</el-button>
</div>
</el-form-item>
<el-form-item v-if="Object.keys(localPacks).length > 0" :label="$t('emoji.packs')">
<el-collapse v-for="(pack, name) in localPacks" :key="name" v-model="activeLocalPack" accordion @change="setActiveTab">
<local-emoji-pack ref="localEmojiPack" :name="name" :pack="pack" :host="$store.getters.authHost" :is-local="true" />
</el-collapse>
</el-form-item>
</el-form>
<div class="pagination">
<el-pagination
:total="localPacksCount"
:current-page="currentPage"
:page-size="pageSize"
hide-on-single-page
layout="prev, pager, next"
@current-change="handlePageChange"
/>
</div> </div>
</el-form-item> </el-tab-pane>
<el-form-item v-if="Object.keys(localPacks).length > 0" :label="$t('emoji.packs')"> <el-tab-pane :label="$t('emoji.remotePacks')" name="remote">
<el-collapse v-for="(pack, name) in localPacks" :key="name" v-model="activeLocalPack"> <el-form :label-width="labelWidth" class="emoji-packs-form">
<local-emoji-pack :name="name" :pack="sortPack(pack)" :host="$store.getters.authHost" :is-local="true" /> <el-form-item :label="$t('emoji.remotePacks')">
</el-collapse> <div class="create-pack">
</el-form-item> <el-input
<el-divider class="divider"/> v-model="remoteInstanceAddress"
<el-form-item :label="$t('emoji.remotePacks')"> :placeholder="$t('emoji.remoteInstanceAddress')" />
<div class="create-pack"> <el-button
<el-input v-loading.fullscreen.lock="fullscreenLoading"
v-model="remoteInstanceAddress" :disabled="remoteInstanceAddress.trim() === ''"
:placeholder="$t('emoji.remoteInstanceAddress')" /> class="create-pack-button"
<el-button @click="refreshRemotePacks">
v-loading.fullscreen.lock="fullscreenLoading" {{ $t('emoji.refreshRemote') }}
:disabled="remoteInstanceAddress.trim() === ''" </el-button>
class="create-pack-button" </div>
@click="refreshRemotePacks"> </el-form-item>
{{ $t('emoji.refreshRemote') }} <el-form-item v-if="Object.keys(remotePacks).length > 0" :label="$t('emoji.packs')">
</el-button> <el-collapse v-for="(pack, name) in remotePacks" :key="name" v-model="activeRemotePack" accordion @change="setActiveTab">
</div> <remote-emoji-pack :name="name" :pack="pack" :host="$store.getters.authHost" :is-local="false" />
</el-form-item> </el-collapse>
<el-form-item v-if="Object.keys(remotePacks).length > 0" :label="$t('emoji.packs')"> </el-form-item>
<el-collapse v-for="(pack, name) in remotePacks" :key="name" v-model="activeRemotePack" @change="setActiveCollapseItems"> </el-form>
<remote-emoji-pack :name="name" :pack="sortPack(pack)" :host="$store.getters.authHost" :is-local="false" /> </el-tab-pane>
</el-collapse> </el-tabs>
</el-form-item>
</el-form>
</div> </div>
</template> </template>
@ -69,6 +85,7 @@ export default {
components: { LocalEmojiPack, RebootButton, RemoteEmojiPack }, components: { LocalEmojiPack, RebootButton, RemoteEmojiPack },
data() { data() {
return { return {
activeTab: 'local',
newPackName: '', newPackName: '',
activeLocalPack: [], activeLocalPack: [],
activeRemotePack: [], activeRemotePack: [],
@ -76,6 +93,9 @@ export default {
} }
}, },
computed: { computed: {
currentPage() {
return this.$store.state.emojiPacks.currentPage
},
isMobile() { isMobile() {
return this.$store.state.app.device === 'mobile' return this.$store.state.app.device === 'mobile'
}, },
@ -88,12 +108,18 @@ export default {
} else if (this.isTablet) { } else if (this.isTablet) {
return '180px' return '180px'
} else { } else {
return '240px' return '200px'
} }
}, },
localPacks() { localPacks() {
return this.$store.state.emojiPacks.localPacks return this.$store.state.emojiPacks.localPacks
}, },
localPacksCount() {
return this.$store.state.emojiPacks.localPacksCount
},
pageSize() {
return this.$store.state.emojiPacks.pageSize
},
remoteInstanceAddress: { remoteInstanceAddress: {
get() { get() {
return this.$store.state.emojiPacks.remoteInstance return this.$store.state.emojiPacks.remoteInstance
@ -117,25 +143,23 @@ export default {
.then(() => { .then(() => {
this.newPackName = '' this.newPackName = ''
this.$store.dispatch('SetLocalEmojiPacks') this.$store.dispatch('FetchLocalEmojiPacks', this.currentPage)
this.$store.dispatch('ReloadEmoji') this.$store.dispatch('ReloadEmoji')
}) })
}, },
handlePageChange(page) {
this.$store.dispatch('FetchLocalEmojiPacks', page)
},
importFromFS() { importFromFS() {
this.$store.dispatch('ImportFromFS') this.$store.dispatch('ImportFromFS')
.then(() => { .then(() => {
this.$store.dispatch('SetLocalEmojiPacks') this.$store.dispatch('FetchLocalEmojiPacks', this.currentPage)
this.$store.dispatch('ReloadEmoji') this.$store.dispatch('ReloadEmoji')
}) })
}, },
sortPack(pack) {
const orderedFiles = Object.keys(pack.files).sort((a, b) => a.localeCompare(b))
.map(key => [key, pack.files[key]])
return { ...pack, files: orderedFiles }
},
refreshLocalPacks() { refreshLocalPacks() {
try { try {
this.$store.dispatch('SetLocalEmojiPacks') this.$store.dispatch('FetchLocalEmojiPacks', this.currentPage)
} catch (e) { } catch (e) {
return return
} }
@ -160,15 +184,22 @@ export default {
message: i18n.t('emoji.reloaded') message: i18n.t('emoji.reloaded')
}) })
}, },
setActiveCollapseItems(activeItems) { setActiveTab(activeTab) {
const items = Array.isArray(activeItems) ? activeItems : [activeItems] this.$refs.localEmojiPack.forEach(el => el.collapse())
this.$store.dispatch('SetActiveCollapseItems', items) this.$store.dispatch('SetActiveTab', activeTab)
} }
} }
} }
</script> </script>
<style rel='stylesheet/scss' lang='scss'> <style rel='stylesheet/scss' lang='scss'>
.create-pack {
display: flex;
justify-content: space-between
}
.create-pack-button {
margin-left: 10px;
}
.emoji-header-container { .emoji-header-container {
display: flex; display: flex;
align-items: center; align-items: center;
@ -178,15 +209,8 @@ export default {
.emoji-packs-header-button-container { .emoji-packs-header-button-container {
display: flex; display: flex;
} }
.create-pack {
display: flex;
justify-content: space-between
}
.create-pack-button {
margin-left: 10px;
}
.emoji-packs-form { .emoji-packs-form {
margin: 0 30px; margin-top: 15px;
} }
.emoji-packs-header { .emoji-packs-header {
display: flex; display: flex;
@ -194,6 +218,9 @@ export default {
justify-content: space-between; justify-content: space-between;
margin: 10px 15px 15px 15px; margin: 10px 15px 15px 15px;
} }
.emoji-packs-tabs {
margin: 0 15px 15px 15px;
}
.import-pack-button { .import-pack-button {
margin-left: 10px; margin-left: 10px;
width: 30%; width: 30%;
@ -208,6 +235,10 @@ h1 {
border: 1px solid #eee; border: 1px solid #eee;
margin-bottom: 22px; margin-bottom: 22px;
} }
.pagination {
margin: 25px 0;
text-align: center;
}
.reboot-button { .reboot-button {
padding: 10px; padding: 10px;
margin: 0; margin: 0;

View file

@ -95,7 +95,7 @@
:total="usersCount" :total="usersCount"
:current-page="currentPage" :current-page="currentPage"
:page-size="pageSize" :page-size="pageSize"
background hide-on-single-page
layout="prev, pager, next" layout="prev, pager, next"
@current-change="handlePageChange" @current-change="handlePageChange"
/> />