experimental still emoji
This commit is contained in:
parent
32d1a0e181
commit
8e1182651a
4 changed files with 96 additions and 6 deletions
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
// TODO Copypaste from Status, should unify it somehow
|
// TODO Copypaste from Status, should unify it somehow
|
||||||
.Notification {
|
.Notification {
|
||||||
|
&:hover {
|
||||||
|
--_still-image-img-visibility: visible;
|
||||||
|
--_still-image-canvas-visibility: hidden;
|
||||||
|
--_still-image-label-visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
&.-muted {
|
&.-muted {
|
||||||
padding: 0.25em 0.6em;
|
padding: 0.25em 0.6em;
|
||||||
height: 1.2em;
|
height: 1.2em;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import Vue from 'vue'
|
||||||
import Attachment from '../attachment/attachment.vue'
|
import Attachment from '../attachment/attachment.vue'
|
||||||
|
import StillImage from '../still-image/still-image.vue'
|
||||||
import Poll from '../poll/poll.vue'
|
import Poll from '../poll/poll.vue'
|
||||||
import Gallery from '../gallery/gallery.vue'
|
import Gallery from '../gallery/gallery.vue'
|
||||||
import LinkPreview from '../link-preview/link-preview.vue'
|
import LinkPreview from '../link-preview/link-preview.vue'
|
||||||
|
@ -40,10 +42,24 @@ const StatusContent = {
|
||||||
showingTall: this.fullContent || (this.inConversation && this.focused),
|
showingTall: this.fullContent || (this.inConversation && this.focused),
|
||||||
showingLongSubject: false,
|
showingLongSubject: false,
|
||||||
// not as computed because it sets the initial state which will be changed later
|
// not as computed because it sets the initial state which will be changed later
|
||||||
expandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject
|
expandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject,
|
||||||
|
stillImages: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updated () {
|
||||||
|
this.patchEmoji()
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.patchEmoji()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.stillImages.forEach(vm => vm.$destroy())
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
stopGifs () {
|
||||||
|
return this.$store.getters.mergedConfig.stopGifs
|
||||||
|
},
|
||||||
localCollapseSubjectDefault () {
|
localCollapseSubjectDefault () {
|
||||||
return this.mergedConfig.collapseMessageWithSubject
|
return this.mergedConfig.collapseMessageWithSubject
|
||||||
},
|
},
|
||||||
|
@ -167,6 +183,43 @@ const StatusContent = {
|
||||||
LinkPreview
|
LinkPreview
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
patchEmoji () {
|
||||||
|
[this.$refs.subject, this.$refs.content].forEach(el => {
|
||||||
|
if (!el) return
|
||||||
|
const imgs = el.querySelectorAll('*:not(.still-image) > img')
|
||||||
|
|
||||||
|
imgs.forEach((img, i) => {
|
||||||
|
// extract relevant info from image
|
||||||
|
// TODO do a better job at "cloning" node and splicing it into a span
|
||||||
|
const { src, title, className } = img
|
||||||
|
// Outer placeholder, thing that will contain stillimage
|
||||||
|
const placeholder = document.createElement('span')
|
||||||
|
// Inner placeholder, this will be REPLACED by stillimage
|
||||||
|
const placeholderInner = document.createElement('span')
|
||||||
|
// Use special classname for emoji, just to be safe
|
||||||
|
placeholder.className = className === 'emoji' ? '__pleromafe_emoji' : 'emoji'
|
||||||
|
// Overall it seems to be easier to use a wrapper and add stuff to it
|
||||||
|
// than to add stuff to component (how??)
|
||||||
|
placeholder.title = title
|
||||||
|
// Insert inner into outer
|
||||||
|
placeholder.appendChild(placeholderInner)
|
||||||
|
// put our placeholder before the image
|
||||||
|
img.parentNode.insertBefore(placeholder, img)
|
||||||
|
|
||||||
|
// Render StillImage into placeholder
|
||||||
|
const opts = {
|
||||||
|
el: placeholder,
|
||||||
|
props: { src }
|
||||||
|
}
|
||||||
|
const vm = new Vue({ el: placeholderInner, render: h => h(StillImage, opts)})
|
||||||
|
this.stillImages.push(vm)
|
||||||
|
|
||||||
|
if (img.className === 'emoji') {
|
||||||
|
img.className = img.className + ' __pleromafe_emoji_orig'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
linkClicked (event) {
|
linkClicked (event) {
|
||||||
const target = event.target.closest('.status-content a')
|
const target = event.target.closest('.status-content a')
|
||||||
if (target) {
|
if (target) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<div class="StatusContent">
|
<div class="StatusContent" :class="{'-stop-gifs': stopGifs}">
|
||||||
<slot name="header" />
|
<slot name="header" />
|
||||||
<div
|
<div
|
||||||
v-if="status.summary_html"
|
v-if="status.summary_html"
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
<div
|
<div
|
||||||
class="media-body summary"
|
class="media-body summary"
|
||||||
@click.prevent="linkClicked"
|
@click.prevent="linkClicked"
|
||||||
|
ref="subject"
|
||||||
v-html="status.summary_html"
|
v-html="status.summary_html"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
:class="{ 'single-line': singleLine }"
|
:class="{ 'single-line': singleLine }"
|
||||||
class="status-content media-body"
|
class="status-content media-body"
|
||||||
@click.prevent="linkClicked"
|
@click.prevent="linkClicked"
|
||||||
|
ref="content"
|
||||||
v-html="postBodyHtml"
|
v-html="postBodyHtml"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
@ -140,6 +142,22 @@ $status-margin: 0.75em;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
--_still-image-img-visibility: visible;
|
||||||
|
--_still-image-canvas-visibility: hidden;
|
||||||
|
--_still-image-label-visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.-stop-gifs {
|
||||||
|
.__pleromafe_emoji {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.__pleromafe_emoji_orig {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.status-content-wrapper {
|
.status-content-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -192,11 +210,21 @@ $status-margin: 0.75em;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
|
|
||||||
&.emoji {
|
&.emoji {
|
||||||
width: 32px;
|
width: var(--big-emoji-size, 32px);
|
||||||
height: 32px;
|
height: var(--big-emoji-size, 32px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.__pleromafe_emoji {
|
||||||
|
display: none; // overriden elsewhere (in the beginning of css file)
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 400px;
|
||||||
|
vertical-align: middle;
|
||||||
|
object-fit: contain;
|
||||||
|
width: var(--big-emoji-size, 32px);
|
||||||
|
height: var(--big-emoji-size, 32px);
|
||||||
|
}
|
||||||
|
|
||||||
.summary-wrapper {
|
.summary-wrapper {
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
const StillImage = {
|
const StillImage = {
|
||||||
props: [
|
props: [
|
||||||
'src',
|
'src',
|
||||||
|
@ -8,8 +10,9 @@ const StillImage = {
|
||||||
'alt'
|
'alt'
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
|
console.log('test', this.$store === undefined)
|
||||||
return {
|
return {
|
||||||
stopGifs: this.$store.getters.mergedConfig.stopGifs
|
stopGifs: this.$store === undefined ? true : this.$store.getters.mergedConfig.stopGifs
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -36,4 +39,4 @@ const StillImage = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default StillImage
|
export default Vue.component('still-image', StillImage)
|
||||||
|
|
Loading…
Reference in a new issue