Allow copying emoji from posts
This commit is contained in:
parent
ec635426c3
commit
04c180e0d9
4 changed files with 189 additions and 3 deletions
|
|
@ -2,7 +2,7 @@ import { unescape, flattenDeep } from 'lodash'
|
|||
import { getTagName, processTextForEmoji, getAttrs } from 'src/services/html_converter/utility.service.js'
|
||||
import { convertHtmlToTree } from 'src/services/html_converter/html_tree_converter.service.js'
|
||||
import { convertHtmlToLines } from 'src/services/html_converter/html_line_converter.service.js'
|
||||
import StillImage from 'src/components/still-image/still-image.vue'
|
||||
import StillImageEmojiPopover from 'src/components/still-image/still-image-emoji-popover.vue'
|
||||
import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
|
||||
import { MENTIONS_LIMIT } from 'src/components/mentions_line/mentions_line.js'
|
||||
import HashtagLink from 'src/components/hashtag_link/hashtag_link.vue'
|
||||
|
|
@ -162,9 +162,10 @@ export default {
|
|||
item,
|
||||
this.emoji,
|
||||
({ shortcode, url }) => {
|
||||
return <StillImage
|
||||
return <StillImageEmojiPopover
|
||||
class="emoji img"
|
||||
src={url}
|
||||
shortcode={shortcode}
|
||||
title={`:${shortcode}:`}
|
||||
alt={`:${shortcode}:`}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ export default {
|
|||
height: 32px;
|
||||
}
|
||||
|
||||
.SelectComponent {
|
||||
.Select {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
|
|
|||
184
src/components/still-image/still-image-emoji-popover.vue
Normal file
184
src/components/still-image/still-image-emoji-popover.vue
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
<template>
|
||||
<Popover
|
||||
ref="emojiPopover"
|
||||
trigger="click"
|
||||
placement="top"
|
||||
bound-to-selector=".status-container"
|
||||
:bound-to="{ x: 'container' }"
|
||||
:offset="{ y: 10 }"
|
||||
@show="fetchEmojiPacksIfAdmin"
|
||||
>
|
||||
<template #trigger>
|
||||
<StillImage v-bind="$attrs" />
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="emoji-popover">
|
||||
<h3>{{ $attrs.title }}</h3>
|
||||
|
||||
<div class="emoji-popover-centered">
|
||||
<StillImage
|
||||
class="emoji"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="isUserAdmin">
|
||||
<button
|
||||
class="button button-default btn emoji-popover-button"
|
||||
type="button"
|
||||
@click="copyToLocalPack"
|
||||
:disabled="packName == ''"
|
||||
>
|
||||
{{ $t('admin_dash.emoji.copy_to_pack') }}
|
||||
</button>
|
||||
|
||||
<SelectComponent
|
||||
v-model="packName"
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
disabled
|
||||
hidden
|
||||
>
|
||||
{{ $t('admin_dash.emoji.emoji_pack') }}
|
||||
</option>
|
||||
<option
|
||||
v-for="(pack, listPackName) in knownLocalPacks"
|
||||
:key="listPackName"
|
||||
:label="listPackName"
|
||||
>
|
||||
{{ listPackName }}
|
||||
</option>
|
||||
</SelectComponent>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { assign } from 'lodash'
|
||||
|
||||
import StillImage from "./still-image.vue"
|
||||
import Popover from 'components/popover/popover.vue'
|
||||
import SelectComponent from 'components/select/select.vue'
|
||||
import { useInterfaceStore } from 'src/stores/interface'
|
||||
|
||||
export default {
|
||||
components: { StillImage, Popover, SelectComponent },
|
||||
data() {
|
||||
return {
|
||||
knownLocalPacks: { },
|
||||
packName: ""
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isUserAdmin () {
|
||||
return this.$store.state.users.currentUser.rights.admin
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
displayError (msg) {
|
||||
useInterfaceStore().pushGlobalNotice({
|
||||
messageKey: 'admin_dash.emoji.error',
|
||||
messageArgs: [msg],
|
||||
level: 'error'
|
||||
})
|
||||
},
|
||||
copyToLocalPack() {
|
||||
console.log(this.packName)
|
||||
|
||||
this.$store.state.api.backendInteractor.addNewEmojiFile({
|
||||
packName: this.packName,
|
||||
file: this.$attrs.src,
|
||||
shortcode: this.$attrs.shortcode,
|
||||
filename: ""
|
||||
}).then(resp => resp.json()).then(resp => {
|
||||
if (resp.error !== undefined) {
|
||||
this.displayError(resp.error)
|
||||
return
|
||||
}
|
||||
|
||||
this.$refs.emojiPopover.hidePopover()
|
||||
this.packName = ''
|
||||
})
|
||||
},
|
||||
|
||||
// Copied from emoji_tab.js
|
||||
loadPacksPaginated (listFunction) {
|
||||
const pageSize = 25
|
||||
const allPacks = {}
|
||||
|
||||
return listFunction({ instance: this.$store.state.instance.server, page: 1, pageSize: 0 })
|
||||
.then(data => data.json())
|
||||
.then(data => {
|
||||
if (data.error !== undefined) { return Promise.reject(data.error) }
|
||||
|
||||
let resultingPromise = Promise.resolve({})
|
||||
for (let i = 0; i < Math.ceil(data.count / pageSize); i++) {
|
||||
resultingPromise = resultingPromise.then(() => listFunction({ instance: this.$store.state.instance.server, page: i, pageSize })
|
||||
).then(data => data.json()).then(pageData => {
|
||||
if (pageData.error !== undefined) { return Promise.reject(pageData.error) }
|
||||
|
||||
assign(allPacks, pageData.packs)
|
||||
})
|
||||
}
|
||||
|
||||
return resultingPromise
|
||||
})
|
||||
.then(() => allPacks)
|
||||
.catch(data => {
|
||||
this.displayError(data)
|
||||
})
|
||||
},
|
||||
fetchEmojiPacksIfAdmin() {
|
||||
if (!this.isUserAdmin) return
|
||||
|
||||
this.loadPacksPaginated(this.$store.state.api.backendInteractor.listEmojiPacks)
|
||||
.then(allPacks => {
|
||||
this.knownLocalPacks = allPacks
|
||||
|
||||
for (const name of Object.keys(this.knownLocalPacks)) {
|
||||
this.sortPackFiles(name)
|
||||
}
|
||||
})
|
||||
},
|
||||
sortPackFiles (nameOfPack) {
|
||||
// Sort by key
|
||||
const sorted = Object.keys(this.knownLocalPacks[nameOfPack].files).sort().reduce((acc, key) => {
|
||||
if (key.length === 0) return acc
|
||||
acc[key] = this.knownLocalPacks[nameOfPack].files[key]
|
||||
return acc
|
||||
}, {})
|
||||
this.knownLocalPacks[nameOfPack].files = sorted
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.emoji-popover {
|
||||
margin: 0 0.5em 0.5em 0.5em;
|
||||
text-align: center;
|
||||
|
||||
.emoji {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.emoji-popover-centered {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.emoji-popover-button {
|
||||
width: 100%;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.Select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1219,6 +1219,7 @@
|
|||
"editing": "Editing {0}",
|
||||
"copying": "Copying {0}",
|
||||
"copy_to": "Copy to",
|
||||
"copy_to_pack": "Copy to local pack",
|
||||
"delete_title": "Delete?",
|
||||
"metadata_changed": "Metadata different from saved",
|
||||
"emoji_changed": "Unsaved emoji file changes, check highlighted emoji",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue