logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe
commit: e4b2fdf1240571f1a3d4be743d73d2b8207b7ba6
parent: 214dd1f6d14073c26316bf5344f03b4b6af999b2
Author: lambda <pleromagit@rogerbraun.net>
Date:   Tue,  3 Apr 2018 09:14:42 +0000

Merge branch 'stillGifs' into 'develop'

Still gifs

See merge request pleroma/pleroma-fe!193

Diffstat:

Msrc/components/attachment/attachment.js4++++
Msrc/components/attachment/attachment.vue7++++++-
Msrc/components/notifications/notifications.js3++-
Msrc/components/notifications/notifications.scss22+++++++++++++++++++++-
Msrc/components/notifications/notifications.vue2+-
Msrc/components/settings/settings.js6+++++-
Msrc/components/settings/settings.vue8++++++--
Msrc/components/status/status.js4+++-
Msrc/components/status/status.vue34+++++++++++++++++++++++++++-------
Asrc/components/still-image/still-image.js26++++++++++++++++++++++++++
Asrc/components/still-image/still-image.vue62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/user_card_content/user_card_content.js4++++
Msrc/components/user_card_content/user_card_content.vue17+++++++++++++++--
Msrc/i18n/messages.js2++
14 files changed, 184 insertions(+), 17 deletions(-)

diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js @@ -1,3 +1,4 @@ +import StillImage from '../still-image/still-image.vue' import nsfwImage from '../../assets/nsfw.png' import fileTypeService from '../../services/file_type/file_type.service.js' @@ -16,6 +17,9 @@ const Attachment = { img: document.createElement('img') } }, + components: { + StillImage + }, computed: { type () { return fileTypeService.fileType(this.attachment.mimetype) diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue @@ -8,7 +8,7 @@ </div> <a v-if="type === 'image' && !hidden" class="image-attachment" :href="attachment.url" target="_blank"> - <img class="base03-border" referrerpolicy="no-referrer" :src="attachment.large_thumb_url || attachment.url"/> + <StillImage class="base03-border" referrerpolicy="no-referrer" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/> </a> <video class="base03" v-if="type === 'video' && !hidden" :src="attachment.url" controls loop></video> @@ -126,6 +126,11 @@ display: flex; flex: 1; + .still-image { + width: 100%; + height: 100%; + } + img { object-fit: contain; width: 100%; diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js @@ -1,4 +1,5 @@ import Status from '../status/status.vue' +import StillImage from '../still-image/still-image.vue' import { sortBy, take, filter } from 'lodash' @@ -31,7 +32,7 @@ const Notifications = { } }, components: { - Status + Status, StillImage }, watch: { unseenCount (count) { diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss @@ -88,10 +88,26 @@ } .avatar { - padding-top: 0.3em; + margin-top: 0.3em; width: 32px; height: 32px; border-radius: 50%; + overflow: hidden; + line-height: 0; + + &.animated::before { + display: none; + } + + } + + &:hover .animated.avatar { + canvas { + display: none; + } + img { + visibility: visible; + } } &:last-child { @@ -104,6 +120,10 @@ max-height: 12em; overflow-y: hidden; //text-overflow: ellipsis; + + img { + object-fit: contain; + } } .notification-gradient { diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue @@ -10,7 +10,7 @@ <div v-for="notification in visibleNotifications" :key="notification" class="notification" :class='{"unseen": !notification.seen}'> <div> <a :href="notification.action.user.statusnet_profile_url" target="_blank"> - <img class='avatar' :src="notification.action.user.profile_image_url_original"> + <StillImage class='avatar' :src="notification.action.user.profile_image_url_original"/> </a> </div> <div class='text' style="width: 100%;"> diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js @@ -10,7 +10,8 @@ const settings = { muteWordsString: this.$store.state.config.muteWords.join('\n'), autoLoadLocal: this.$store.state.config.autoLoad, streamingLocal: this.$store.state.config.streaming, - hoverPreviewLocal: this.$store.state.config.hoverPreview + hoverPreviewLocal: this.$store.state.config.hoverPreview, + stopGifs: this.$store.state.config.stopGifs } }, components: { @@ -43,6 +44,9 @@ const settings = { muteWordsString (value) { value = filter(value.split('\n'), (word) => trim(word).length > 0) this.$store.dispatch('setOption', { name: 'muteWords', value }) + }, + stopGifs (value) { + this.$store.dispatch('setOption', { name: 'stopGifs', value }) } } } diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue @@ -29,8 +29,8 @@ <label for="hideNsfw">{{$t('settings.nsfw_clickthrough')}}</label> </li> <li> - <input type="checkbox" id="autoLoad" v-model="autoLoadLocal"> - <label for="autoLoad">{{$t('settings.autoload')}}</label> + <input type="checkbox" id="autoload" v-model="autoloadlocal"> + <label for="autoload">{{$t('settings.autoload')}}</label> </li> <li> <input type="checkbox" id="streaming" v-model="streamingLocal"> @@ -40,6 +40,10 @@ <input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal"> <label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label> </li> + <li> + <input type="checkbox" id="stopGifs" v-model="stopGifs"> + <label for="stopGifs">{{$t('settings.stop_gifs')}}</label> + </li> </ul> </div> </div> diff --git a/src/components/status/status.js b/src/components/status/status.js @@ -4,6 +4,7 @@ import RetweetButton from '../retweet_button/retweet_button.vue' import DeleteButton from '../delete_button/delete_button.vue' import PostStatusForm from '../post_status_form/post_status_form.vue' import UserCardContent from '../user_card_content/user_card_content.vue' +import StillImage from '../still-image/still-image.vue' import { filter, find } from 'lodash' const Status = { @@ -76,7 +77,8 @@ const Status = { RetweetButton, DeleteButton, PostStatusForm, - UserCardContent + UserCardContent, + StillImage }, methods: { linkClicked ({target}) { diff --git a/src/components/status/status.vue b/src/components/status/status.vue @@ -34,8 +34,8 @@ <div class="media status container"> <div class="media-left"> <a :href="status.user.statusnet_profile_url"> - <img @click.prevent="toggleUserExpanded" :class="{retweeted: retweet}" class='avatar' :src="status.user.profile_image_url_original"> - <img v-if="retweet" class='avatar-retweeter' :src="statusoid.user.profile_image_url_original"></img> + <StillImage @click.native.prevent="toggleUserExpanded" :class="{retweeted: retweet}" class='avatar' :src="status.user.profile_image_url_original"/> + <StillImage v-if="retweet" class='avatar avatar-retweeter' :src="statusoid.user.profile_image_url_original"/> </a> </div> <div class="media-body"> @@ -84,7 +84,7 @@ </div> <div class="status-preview base00-background base03-border" v-if="showPreview && preview"> - <img class="avatar" :src="preview.user.profile_image_url_original"> + <StillImage class="avatar" :src="preview.user.profile_image_url_original"/> <div class="text"> <h4> {{ preview.user.name }} @@ -146,6 +146,7 @@ box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); margin-top: 0.5em; margin-left: 1em; + z-index: 50; .avatar { flex-shrink: 0; @@ -264,9 +265,8 @@ .media-left { margin: 0.2em 0.3em 0 0; - img { + .avatar { float: right; - border-radius: 5px; } } @@ -330,6 +330,17 @@ .status .avatar { width: 48px; height: 48px; + border-radius: 5px; + overflow: hidden; + + img { + width: 100%; + height: 100%; + } + + &.animated::before { + display: none; + } &.retweeted { width: 40px; @@ -339,7 +350,16 @@ } } - .status img.avatar-retweeter { + .status:hover .animated.avatar { + canvas { + display: none; + } + img { + visibility: visible; + } + } + + .status .avatar-retweeter { width: 24px; height: 24px; position: absolute; @@ -413,7 +433,7 @@ } } - .status img.avatar-retweeter { + .status .avatar-retweeter { width: 22px; height: 22px; position: absolute; diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js @@ -0,0 +1,26 @@ +const StillImage = { + props: [ + 'src', + 'referrerpolicy', + 'mimetype' + ], + data () { + return { + stopGifs: this.$store.state.config.stopGifs + } + }, + computed: { + animated () { + return this.stopGifs && (this.mimetype === 'image/gif' || this.src.endsWith('.gif')) + } + }, + methods: { + onLoad () { + const canvas = this.$refs.canvas + if (!canvas) return + canvas.getContext('2d').drawImage(this.$refs.src, 1, 1, canvas.width, canvas.height) + } + } +} + +export default StillImage diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue @@ -0,0 +1,62 @@ +<template> + <div class='still-image' :class='{ animated: animated }' > + <canvas ref="canvas" v-if="animated"></canvas> + <img ref="src" :src="src" :referrerpolicy="referrerpolicy" v-on:load="onLoad"/> + </div> +</template> + +<script src="./still-image.js"></script> + +<style lang="scss"> +@import '../../_variables.scss'; +.still-image { + position: relative; + line-height: 0; + overflow: hidden; + + &:hover canvas { + display: none; + } + + img { + width: 100%; + height: 100% + } + + &.animated { + &:hover::before, + img { + visibility: hidden; + } + + &:hover img { + visibility: visible + } + + &::before { + content: 'gif'; + position: absolute; + line-height: 10px; + font-size: 10px; + top: 5px; + left: 5px; + background: rgba(127,127,127,.5); + color: #FFF; + display: block; + padding: 2px 4px; + border-radius: 3px; + z-index: 2; + } + } + + canvas { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + } +} +</style> diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js @@ -1,3 +1,4 @@ +import StillImage from '../still-image/still-image.vue' import { hex2rgb } from '../../services/color_convert/color_convert.js' export default { @@ -35,6 +36,9 @@ export default { return Math.round(this.user.statuses_count / days) } }, + components: { + StillImage + }, methods: { followUser () { const store = this.$store diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue @@ -7,7 +7,7 @@ </router-link> <div class='container'> <router-link :to="{ name: 'user-profile', params: { id: user.id } }"> - <img :src="user.profile_image_url_original"> + <StillImage class="avatar" :src="user.profile_image_url_original"/> </router-link> <span class="glyphicon glyphicon-user"></span> <div class="name-and-screen-name"> @@ -135,13 +135,26 @@ overflow: hidden; } - img { + .avatar { border-radius: 5px; flex: 1 0 100%; width: 56px; height: 56px; box-shadow: 0px 1px 8px rgba(0,0,0,0.75); object-fit: cover; + + &.animated::before { + display: none; + } + } + + &:hover .animated.avatar { + canvas { + display: none; + } + img { + visibility: visible; + } } text-shadow: 0px 1px 1.5px rgba(0, 0, 0, 1.0); diff --git a/src/i18n/messages.js b/src/i18n/messages.js @@ -249,6 +249,7 @@ const en = { hide_attachments_in_tl: 'Hide attachments in timeline', hide_attachments_in_convo: 'Hide attachments in conversations', nsfw_clickthrough: 'Enable clickthrough NSFW attachment hiding', + stop_gifs: 'Play-on-hover GIFs', autoload: 'Enable automatic loading when scrolled to the bottom', streaming: 'Enable automatic streaming of new posts when scrolled to the top', reply_link_preview: 'Enable reply-link preview on mouse hover', @@ -1103,6 +1104,7 @@ const ru = { attachments: 'Вложения', hide_attachments_in_tl: 'Прятать вложения в ленте', hide_attachments_in_convo: 'Прятать вложения в разговорах', + stop_gifs: 'Проигрывать GIF анимации только при наведении', nsfw_clickthrough: 'Включить скрытие NSFW вложений', autoload: 'Включить автоматическую загрузку при прокрутке вниз', streaming: 'Включить автоматическую загрузку новых сообщений при прокрутке вверх',