Update PostContent, TimelineStatus and PhotoPresenter components to support filters

pull/5928/head
Daniel Supernault 7 months ago
parent f0b1a8eaae
commit 7d6f7c48ef
No known key found for this signature in database
GPG Key ID: 23740873EE6F76A1

@ -10,46 +10,77 @@
@follow="follow"
@unfollow="unfollow" />
<post-content
:profile="profile"
:status="shadowStatus" />
<template v-if="!isFiltered || (isFiltered && filterType === 'blur')">
<post-content
:profile="profile"
:status="shadowStatus"
:is-filtered="isFiltered"
:filters="filters"
/>
<post-reactions
v-if="reactionBar"
:status="shadowStatus"
:profile="profile"
:admin="admin"
v-on:like="like"
v-on:unlike="unlike"
v-on:share="shareStatus"
v-on:unshare="unshareStatus"
v-on:likes-modal="showLikes"
v-on:shares-modal="showShares"
v-on:toggle-comments="showComments"
v-on:bookmark="handleBookmark"
v-on:mod-tools="openModTools" />
<div v-if="showCommentDrawer" class="card-footer rounded-bottom border-0" style="background: rgba(0,0,0,0.02);z-index: 3;">
<comment-drawer
<post-reactions
v-if="reactionBar"
:status="shadowStatus"
:profile="profile"
v-on:handle-report="handleReport"
v-on:counter-change="counterChange"
v-on:show-likes="showCommentLikes"
v-on:follow="follow"
v-on:unfollow="unfollow" />
</div>
:admin="admin"
@like="like"
@unlike="unlike"
@share="shareStatus"
@unshare="unshareStatus"
@likes-modal="showLikes"
@shares-modal="showShares"
@toggle-comments="showComments"
@bookmark="handleBookmark"
@mod-tools="openModTools" />
<div v-if="showCommentDrawer" class="card-footer rounded-bottom border-0" style="background: rgba(0,0,0,0.02);z-index: 3;">
<comment-drawer
:status="shadowStatus"
:profile="profile"
@handle-report="handleReport"
@counter-change="counterChange"
@show-likes="showCommentLikes"
@follow="follow"
@unfollow="unfollow" />
</div>
</template>
<template v-else>
<div class="card shadow-none mx-3 border-0">
<div class="card-body bg-warning-light p-3">
<div class="d-flex justify-content-center align-items-center">
<i class="fas fa-exclamation-triangle text-warning mr-2" aria-hidden="true"></i>
<h5 class="card-title mb-0">Filtered</h5>
</div>
<p class="card-text mt-2 text-center">
Hidden because it contains the following filtered keywords:
<span v-for="term in filteredTerms" class="badge badge-warning mr-1">{{ term }}</span>
</p>
<button class="btn btn-primary rounded-pill btn-block" @click="showHiddenStatus()">
<i class="fas fa-eye mr-1"></i> Show
</button>
</div>
</div>
</template>
</div>
</div>
</template>
<script type="text/javascript">
import CommentDrawer from './post/CommentDrawer.vue';
import PostHeader from './post/PostHeader.vue';
import PostContent from './post/PostContent.vue';
import PostReactions from './post/PostReactions.vue';
import CommentDrawer from "./post/CommentDrawer.vue";
import PostHeader from "./post/PostHeader.vue";
import PostContent from "./post/PostContent.vue";
import PostReactions from "./post/PostReactions.vue";
export default {
components: {
"comment-drawer": CommentDrawer,
"post-content": PostContent,
"post-header": PostHeader,
"post-reactions": PostReactions
},
props: {
status: {
type: Object
@ -60,8 +91,8 @@
},
reactionBar: {
type: Boolean,
default: true
type: Boolean,
default: true
},
useDropdownMenu: {
@ -70,13 +101,6 @@
}
},
components: {
"comment-drawer": CommentDrawer,
"post-content": PostContent,
"post-header": PostHeader,
"post-reactions": PostReactions
},
data() {
return {
key: 1,
@ -87,23 +111,12 @@
isBookmarking: false,
owner: false,
admin: false,
license: false
}
},
mounted() {
this.license = this.shadowStatus.media_attachments && this.shadowStatus.media_attachments.length ?
this.shadowStatus
.media_attachments
.filter(m => m.hasOwnProperty('license') && m.license && m.license.hasOwnProperty('id'))
.map(m => m.license)[0] : false;
this.admin = window._sharedData.user.is_admin;
this.owner = this.shadowStatus.account.id == window._sharedData.user.id;
if(this.shadowStatus.reply_count && this.autoloadComments && this.shadowStatus.comments_disabled === false) {
setTimeout(() => {
this.showCommentDrawer = true;
}, 1000);
}
license: false,
isFiltered: false,
filterType: undefined,
filters: [],
filteredTerms: []
};
},
computed: {
@ -128,7 +141,7 @@
newReactions: {
get() {
return this.$store.state.newReactions;
},
}
},
isReblog: {
@ -150,35 +163,25 @@
}
},
watch: {
status: {
deep: true,
immediate: true,
handler: function(o, n) {
this.isBookmarking = false;
}
},
},
methods: {
openMenu() {
this.$emit('menu');
this.$emit("menu");
},
like() {
this.$emit('like');
this.$emit("like");
},
unlike() {
this.$emit('unlike');
this.$emit("unlike");
},
showLikes() {
this.$emit('likes-modal');
this.$emit("likes-modal");
},
showShares() {
this.$emit('shares-modal');
this.$emit("shares-modal");
},
showComments() {
@ -195,47 +198,47 @@
navigator.share({
url: this.status.url
})
.then(() => console.log('Share was successful.'))
.catch((error) => console.log('Sharing failed', error));
.then(() => console.log("Share was successful."))
.catch((error) => console.log("Sharing failed", error));
} else {
swal('Not supported', 'Your current device does not support native sharing.', 'error');
swal("Not supported", "Your current device does not support native sharing.", "error");
}
},
counterChange(type) {
this.$emit('counter-change', type);
this.$emit("counter-change", type);
},
showCommentLikes(post) {
this.$emit('comment-likes-modal', post);
this.$emit("comment-likes-modal", post);
},
shareStatus() {
this.$emit('share');
this.$emit("share");
},
unshareStatus() {
this.$emit('unshare');
this.$emit("unshare");
},
handleReport(post) {
this.$emit('handle-report', post);
this.$emit("handle-report", post);
},
follow() {
this.$emit('follow');
this.$emit("follow");
},
unfollow() {
this.$emit('unfollow');
this.$emit("unfollow");
},
handleReblog() {
this.isReblogging = true;
if(this.status.reblogged) {
this.$emit('unshare');
if (this.status.reblogged) {
this.$emit("unshare");
} else {
this.$emit('share');
this.$emit("share");
}
setTimeout(() => {
@ -246,7 +249,7 @@
handleBookmark() {
event.currentTarget.blur();
this.isBookmarking = true;
this.$emit('bookmark');
this.$emit("bookmark");
setTimeout(() => {
this.isBookmarking = false;
@ -254,7 +257,7 @@
},
getStatusAvatar() {
if(window._sharedData.user.id == this.status.account.id) {
if (window._sharedData.user.id == this.status.account.id) {
return window._sharedData.user.avatar;
}
@ -262,10 +265,73 @@
},
openModTools() {
this.$emit('mod-tools');
this.$emit("mod-tools");
},
applyStatusFilters() {
const filterTypes = this.status.filtered.map(f => f.filter.filter_action);
if (filterTypes.includes("warn")) {
this.applyWarnStatusFilter();
return;
}
if (filterTypes.includes("blur")) {
this.applyBlurStatusFilter();
return;
}
},
applyWarnStatusFilter() {
this.isFiltered = true;
this.filterType = "warn";
this.filters = this.status.filtered;
this.filteredTerms = this.status.filtered.map(f => f.keyword_matches).flat(1);
},
applyBlurStatusFilter() {
this.isFiltered = true;
this.filterType = "blur";
this.filters = this.status.filtered;
this.filteredTerms = this.status.filtered.map(f => f.keyword_matches).flat(1);
},
showHiddenStatus() {
this.isFiltered = false;
this.filterType = null;
this.filters = [];
this.filteredTerms = [];
}
},
mounted() {
this.license = this.shadowStatus.media_attachments && this.shadowStatus.media_attachments.length ?
this.shadowStatus
.media_attachments
.filter(m => m.hasOwnProperty("license") && m.license && m.license.hasOwnProperty("id"))
.map(m => m.license)[0] : false;
this.admin = window._sharedData.user.is_admin;
this.owner = this.shadowStatus.account.id == window._sharedData.user.id;
if (this.shadowStatus.reply_count && this.autoloadComments && this.shadowStatus.comments_disabled === false) {
setTimeout(() => {
this.showCommentDrawer = true;
}, 1000);
}
if (this.status.filtered && this.status.filtered.length) {
this.applyStatusFilters();
}
},
watch: {
status: {
deep: true,
immediate: true,
handler: function(o, n) {
this.isBookmarking = false;
}
}
}
}
};
</script>
<style lang="scss">

@ -1,128 +1,129 @@
<template>
<div class="timeline-status-component-content">
<div v-if="status.pf_type === 'poll'" class="postPresenterContainer" style="background: #000;">
</div>
<div v-else-if="!fixedHeight" class="postPresenterContainer" style="background: #000;">
<div v-if="status.pf_type === 'photo'" class="w-100">
<photo-presenter
:status="status"
v-on:lightbox="toggleLightbox"
v-on:togglecw="status.sensitive = false"/>
</div>
<div v-else-if="status.pf_type === 'video'" class="w-100">
<video-player :status="status" :fixedHeight="fixedHeight" v-on:togglecw="status.sensitive = false" />
</div>
<div v-else-if="status.pf_type === 'photo:album'" class="w-100">
<photo-album-presenter :status="status" v-on:lightbox="toggleLightbox" v-on:togglecw="status.sensitive = false"></photo-album-presenter>
</div>
<div v-else-if="status.pf_type === 'video:album'" class="w-100">
<video-album-presenter :status="status" v-on:togglecw="status.sensitive = false"></video-album-presenter>
</div>
<div v-else-if="status.pf_type === 'photo:video:album'" class="w-100">
<mixed-album-presenter :status="status" v-on:lightbox="toggleLightbox" v-on:togglecw="status.sensitive = false"></mixed-album-presenter>
</div>
</div>
<div v-else class="card-body p-0">
<div v-if="status.pf_type === 'photo'" :class="{ fixedHeight: fixedHeight }">
<div v-if="status.sensitive == true" class="content-label-wrapper">
<div class="text-light content-label">
<p class="text-center">
<i class="far fa-eye-slash fa-2x"></i>
</p>
<p class="h4 font-weight-bold text-center">
{{ $t('common.sensitiveContent') }}
</p>
<p class="text-center py-2 content-label-text">
{{ status.spoiler_text ? status.spoiler_text : $t('common.sensitiveContentWarning') }}
</p>
<p class="mb-0">
<button class="btn btn-outline-light btn-block btn-sm font-weight-bold" @click="toggleContentWarning()">See Post</button>
</p>
</div>
<blur-hash-image
width="32"
height="32"
:punch="1"
class="blurhash-wrapper"
:hash="status.media_attachments[0].blurhash"
/>
</div>
<div
v-else
@click.prevent="toggleLightbox"
class="content-label-wrapper"
style="position: relative;width:100%;height: 400px;overflow: hidden;z-index:1"
>
<img
<div class="timeline-status-component-content">
<div v-if="status.pf_type === 'poll'" class="postPresenterContainer" style="background: #000;">
</div>
<div v-else-if="!fixedHeight" class="postPresenterContainer" style="background: #000;">
<div v-if="status.pf_type === 'photo'" class="w-100">
<photo-presenter
:status="status"
:is-filtered="isFiltered"
@lightbox="toggleLightbox"
@togglecw="toggleContentWarning" />
</div>
<div v-else-if="status.pf_type === 'video'" class="w-100">
<video-player
:status="statusRender"
:fixed-height="fixedHeight"
@togglecw="toggleContentWarning" />
</div>
<div v-else-if="status.pf_type === 'photo:album'" class="w-100">
<photo-album-presenter
:status="status"
@lightbox="toggleLightbox"
@togglecw="toggleContentWarning" />
</div>
<div v-else-if="status.pf_type === 'video:album'" class="w-100">
<video-album-presenter
:status="status"
@togglecw="toggleContentWarning" />
</div>
<div v-else-if="status.pf_type === 'photo:video:album'" class="w-100">
<mixed-album-presenter
:status="status"
@lightbox="toggleLightbox"
@togglecw="toggleContentWarning" />
</div>
</div>
<div v-else class="card-body p-0">
<div v-if="status.pf_type === 'photo'" :class="{ fixedHeight: fixedHeight }">
<div v-if="statusRender.sensitive == true" class="content-label-wrapper">
<div class="text-light content-label">
<p class="text-center">
<i class="far fa-eye-slash fa-2x"></i>
</p>
<p class="h4 font-weight-bold text-center">
{{ isFiltered ? 'Filtered Content' : $t('common.sensitiveContent') }}
</p>
<p class="text-center py-2 content-label-text">
{{ status.spoiler_text ? status.spoiler_text : $t('common.sensitiveContentWarning') }}
</p>
<p class="mb-0">
<button class="btn btn-outline-light btn-block btn-sm font-weight-bold" @click="toggleContentWarning()">See Post</button>
</p>
</div>
<blur-hash-image
width="32"
height="32"
:punch="1"
class="blurhash-wrapper"
:hash="status.media_attachments[0].blurhash"
/>
</div>
<div
v-else
class="content-label-wrapper"
@click.prevent="toggleLightbox"
>
<img
:src="status.media_attachments[0].url"
class="content-label-wrapper-img" />
<blur-hash-image
:key="key"
width="32"
height="32"
:punch="1"
:hash="status.media_attachments[0].blurhash"
:src="status.media_attachments[0].url"
style="position: absolute;width: 105%;height: 410px;object-fit: cover;z-index: 1;top:0;left:0;filter: brightness(0.35) blur(6px);margin:-5px;">
<!-- <blur-hash-canvas
v-if="status.media_attachments[0].blurhash && status.media_attachments[0].blurhash != 'U4Rfzst8?bt7ogayj[j[~pfQ9Goe%Mj[WBay'"
:key="key"
width="32"
height="32"
:punch="1"
:hash="status.media_attachments[0].blurhash"
style="position: absolute;width: 105%;height: 410px;object-fit: cover;z-index: 1;top:0;left:0;filter: brightness(0.35);"
/> -->
<blur-hash-image
:key="key"
width="32"
height="32"
:punch="1"
:hash="status.media_attachments[0].blurhash"
:src="status.media_attachments[0].url"
class="blurhash-wrapper"
class="blurhash-wrapper"
:alt="status.media_attachments[0].description"
:title="status.media_attachments[0].description"
style="width: 100%;position: absolute;z-index:9;top:0:left:0"
/>
<p v-if="!status.sensitive && sensitive"
@click="status.sensitive = true"
style="
margin-top: 0;
padding: 10px;
color: #000;
font-size: 10px;
text-align: right;
position: absolute;
top: 0;
right: 0;
border-radius: 11px;
cursor: pointer;
background: rgba(255, 255, 255,.5);
">
<i class="fas fa-eye-slash fa-lg"></i>
</p>
</div>
</div>
style="width: 100%;position: absolute;z-index:9;top:0:left:0"
/>
<p
v-if="!status.sensitive && sensitive"
class="sensitive-curtain"
@click="status.sensitive = true">
<i class="fas fa-eye-slash fa-lg"></i>
</p>
</div>
</div>
<video-player
v-else-if="status.pf_type === 'video'"
:status="status"
:fixedHeight="fixedHeight"
:fixed-height="fixedHeight"
/>
<div v-else-if="status.pf_type === 'photo:album'" class="card-img-top shadow" style="border-radius: 15px;">
<photo-album-presenter :status="status" v-on:lightbox="toggleLightbox" v-on:togglecw="toggleContentWarning()" style="border-radius:15px !important;object-fit: contain;background-color: #000;overflow: hidden;" :class="{ fixedHeight: fixedHeight }"/>
</div>
<div v-else-if="status.pf_type === 'photo:album'" class="card-img-top shadow" style="border-radius: 15px;">
<photo-album-presenter
:status="status"
class="photo-presenter"
:class="{ fixedHeight: fixedHeight }"
@lightbox="toggleLightbox"
@togglecw="toggleContentWarning()" />
</div>
<div v-else-if="status.pf_type === 'photo:video:album'" class="card-img-top shadow" style="border-radius: 15px;">
<mixed-album-presenter
:status="status"
class="mixed-presenter"
:class="{ fixedHeight: fixedHeight }"
@lightbox="toggleLightbox"
@togglecw="status.sensitive = false" />
<div v-else-if="status.pf_type === 'photo:video:album'" class="card-img-top shadow" style="border-radius: 15px;">
<mixed-album-presenter :status="status" v-on:lightbox="toggleLightbox" v-on:togglecw="status.sensitive = false" style="border-radius:15px !important;object-fit: contain;background-color: #000;overflow: hidden;align-items:center" :class="{ fixedHeight: fixedHeight }"></mixed-album-presenter>
</div>
</div>
<div v-else-if="status.pf_type === 'text'">
<div v-else-if="status.pf_type === 'text'">
<div v-if="status.sensitive" class="border m-3 p-5 rounded-lg">
<p class="text-center">
<i class="far fa-eye-slash fa-2x"></i>
@ -135,85 +136,153 @@
</div>
</div>
<div v-else class="bg-light rounded-lg d-flex align-items-center justify-content-center" style="height: 400px;">
<div>
<p class="text-center">
<i class="fas fa-exclamation-triangle fa-4x"></i>
</p>
<p class="lead text-center mb-0">
Cannot display post
</p>
<p class="small text-center mb-0">
<!-- <a class="font-weight-bold primary" href="#">Report issue</a> -->
{{status.pf_type}}:{{status.id}}
</p>
</div>
</div>
</div>
<div
v-if="status.content && !status.sensitive"
class="card-body status-text"
:class="[ status.pf_type === 'text' ? 'py-0' : 'pb-0']">
<p>
<read-more :status="status" :cursor-limit="300"/>
</p>
<!-- <p v-html="status.content_text || status.content">
</p> -->
</div>
</div>
<div v-else class="bg-light rounded-lg d-flex align-items-center justify-content-center" style="height: 400px;">
<div>
<p class="text-center">
<i class="fas fa-exclamation-triangle fa-4x"></i>
</p>
<p class="lead text-center mb-0">
Cannot display post
</p>
<p class="small text-center mb-0">
{{ status.pf_type }}:{{ status.id }}
</p>
</div>
</div>
</div>
<div
v-if="status.content && !status.sensitive"
class="card-body status-text"
:class="[ status.pf_type === 'text' ? 'py-0' : 'pb-0']">
<p>
<read-more :status="status" :cursor-limit="300" />
</p>
</div>
</div>
</template>
<script type="text/javascript">
import BigPicture from 'bigpicture';
import ReadMore from './ReadMore.vue';
import VideoPlayer from '@/presenter/VideoPlayer.vue';
import BigPicture from "bigpicture";
import ReadMore from "./ReadMore.vue";
import VideoPlayer from "@/presenter/VideoPlayer.vue";
export default {
props: ['status'],
export default {
components: {
"read-more": ReadMore,
components: {
"read-more": ReadMore,
"video-player": VideoPlayer
},
data() {
return {
key: 1,
sensitive: false,
};
},
computed: {
fixedHeight: {
get() {
return this.$store.state.fixedHeight == true;
}
}
},
methods: {
toggleLightbox(e) {
BigPicture({
el: e.target
})
},
toggleContentWarning() {
this.key++;
this.sensitive = true;
this.status.sensitive = !this.status.sensitive;
},
},
props: {
status: {
type: Object
},
isFiltered: {
type: Boolean
},
filters: {
type: Array
}
},
data() {
return {
key: 1,
sensitive: false
};
},
computed: {
statusRender: {
get() {
if (this.isFiltered) {
this.status.spoiler_text = "Filtered because it contains the following keywords: " + this.status.filtered.map(f => f.keyword_matches).flat(1).join(", ");
this.status.sensitive = true;
}
return this.status;
}
},
fixedHeight: {
get() {
return this.$store.state.fixedHeight == true;
}
}
},
methods: {
toggleLightbox(e) {
BigPicture({
el: e.target
});
},
toggleContentWarning() {
this.key++;
this.sensitive = true;
this.status.sensitive = !this.status.sensitive;
},
getPoster(status) {
let url = status.media_attachments[0].preview_url;
if(url.endsWith('no-preview.jpg') || url.endsWith('no-preview.png')) {
if (url.endsWith("no-preview.jpg") || url.endsWith("no-preview.png")) {
return;
}
return url;
}
}
}
}
};
</script>
<style scoped>
.sensitive-curtain {
margin-top: 0;
padding: 10px;
color: #000;
font-size: 10px;
text-align: right;
position: absolute;
top: 0;
right: 0;
border-radius: 11px;
cursor: pointer;
background: rgba(255, 255, 255,.5);
}
.content-label-wrapper {
position: relative;
width:100%;
height: 400px;
overflow: hidden;
z-index:1
}
.content-label-wrapper-img {
position: absolute;
width: 105%;height: 410px;
object-fit: cover;
z-index: 1;
top:0;
left:0;
filter: brightness(0.35) blur(6px);
margin:-5px;
}
.photo-presenter {
border-radius:15px !important;
object-fit: contain;
background-color: #000;
overflow: hidden;
}
.mixed-presenter {
border-radius:15px !important;
object-fit: contain;
background-color: #000;
overflow: hidden;
align-items:center;
}
</style>

@ -1,160 +1,167 @@
<template>
<div v-if="status.sensitive == true" class="content-label-wrapper">
<div class="text-light content-label">
<p class="text-center">
<i class="far fa-eye-slash fa-2x"></i>
</p>
<p class="h4 font-weight-bold text-center">
Sensitive Content
</p>
<p class="text-center py-2 content-label-text">
{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.'}}
</p>
<p class="mb-0">
<button @click="toggleContentWarning()" class="btn btn-outline-light btn-block btn-sm font-weight-bold">See Post</button>
</p>
</div>
<blur-hash-image
width="32"
height="32"
:punch="1"
:hash="status.media_attachments[0].blurhash"
:alt="altText(status)"/>
</div>
<div v-else>
<div :title="status.media_attachments[0].description" style="position: relative;">
<img class="card-img-top"
:src="status.media_attachments[0].url"
loading="lazy"
:alt="altText(status)"
:width="width()"
:height="height()"
onerror="this.onerror=null;this.src='/storage/no-preview.png'"
@click.prevent="toggleLightbox">
<div v-if="status.sensitive == true" class="content-label-wrapper">
<div class="text-light content-label">
<p class="text-center">
<i class="far fa-eye-slash fa-2x"></i>
</p>
<p class="h4 font-weight-bold text-center">
{{ isFiltered ? 'Filtered Content' : 'Sensitive Content' }}
</p>
<p class="text-center py-2 content-label-text">
{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.' }}
</p>
<p class="mb-0">
<button class="btn btn-outline-light btn-block btn-sm font-weight-bold" @click="toggleContentWarning()">See Post</button>
</p>
</div>
<blur-hash-image
width="32"
height="32"
:punch="1"
:hash="status.media_attachments[0].blurhash"
:alt="altText(status)"
/>
</div>
<div v-else>
<div
:title="status.media_attachments[0].description"
style="position: relative;">
<!-- <blur-hash-image
class="card-img-top"
width="32"
height="32"
:punch="1"
:hash="status.media_attachments[0].blurhash"
:src="status.media_attachments[0].url"
:alt="altText(status)"
@click.prevent="toggleLightbox"/> -->
<img
class="card-img-top"
:src="status.media_attachments[0].url"
loading="lazy"
:alt="altText(status)"
:width="width()"
:height="height()"
onerror="this.onerror=null;this.src='/storage/no-preview.png'"
@click.prevent="toggleLightbox"
/>
<p v-if="!status.sensitive && sensitive"
@click="status.sensitive = true"
style="
margin-top: 0;
padding: 10px;
color: #fff;
font-size: 10px;
text-align: right;
position: absolute;
top: 0;
right: 0;
border-top-left-radius: 5px;
cursor: pointer;
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
">
<i class="fas fa-eye-slash fa-lg"></i>
</p>
<p
v-if="!status.sensitive && sensitive"
class="sensitive-curtain"
@click="status.sensitive = true">
<i class="fas fa-eye-slash fa-lg"></i>
</p>
<p
v-if="status.media_attachments[0].license"
style="
margin-bottom: 0;
padding: 0 5px;
color: #fff;
font-size: 10px;
text-align: right;
position: absolute;
bottom: 0;
right: 0;
border-top-left-radius: 5px;
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
"><a :href="status.url" class="font-weight-bold text-light">Photo</a> by <a :href="status.account.url" class="font-weight-bold text-light">&commat;{{status.account.username}}</a> licensed under <a :href="status.media_attachments[0].license.url" class="font-weight-bold text-light">{{status.media_attachments[0].license.title}}</a></p>
</div>
</div>
<p
v-if="status.media_attachments[0].license"
class="photo-license">
<a :href="status.url" class="font-weight-bold text-light">Photo</a> by <a :href="status.account.url" class="font-weight-bold text-light">&commat;{{ status.account.username }}</a> licensed under <a :href="status.media_attachments[0].license.url" class="font-weight-bold text-light">{{ status.media_attachments[0].license.title }}</a>
</p>
</div>
</div>
</template>
<style type="text/css" scoped>
.card-img-top {
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
}
.content-label-wrapper {
position: relative;
}
.content-label {
margin: 0;
position: absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
z-index: 2;
background: rgba(0, 0, 0, 0.2)
}
</style>
<script type="text/javascript">
import BigPicture from 'bigpicture';
import BigPicture from "bigpicture";
export default {
props: ['status'],
export default {
props: {
status: {
type: Object
},
isFiltered: {
type: Boolean,
default: false
}
},
data() {
return {
sensitive: this.status.sensitive
}
},
data() {
return {
sensitive: this.status.sensitive
};
},
mounted() {
},
methods: {
altText(status) {
let desc = status.media_attachments[0].description;
methods: {
altText(status) {
let desc = status.media_attachments[0].description;
if(desc) {
return desc;
}
if (desc) {
return desc;
}
return 'Photo was not tagged with any alt text.';
},
return "Photo was not tagged with any alt text.";
},
toggleContentWarning(status) {
this.$emit('togglecw');
},
toggleContentWarning(status) {
this.$emit("togglecw");
},
toggleLightbox(e) {
BigPicture({
el: e.target
})
},
toggleLightbox(e) {
BigPicture({
el: e.target
});
},
width() {
if( !this.status.media_attachments[0].meta ||
!this.status.media_attachments[0].meta.original ||
!this.status.media_attachments[0].meta.original.width ) {
return;
}
return this.status.media_attachments[0].meta.original.width;
},
width() {
if (!this.status.media_attachments[0].meta ||
!this.status.media_attachments[0].meta.original ||
!this.status.media_attachments[0].meta.original.width) {
return;
}
return this.status.media_attachments[0].meta.original.width;
},
height() {
if( !this.status.media_attachments[0].meta ||
!this.status.media_attachments[0].meta.original ||
!this.status.media_attachments[0].meta.original.height ) {
return;
}
return this.status.media_attachments[0].meta.original.height;
}
}
}
height() {
if (!this.status.media_attachments[0].meta ||
!this.status.media_attachments[0].meta.original ||
!this.status.media_attachments[0].meta.original.height) {
return;
}
return this.status.media_attachments[0].meta.original.height;
}
}
};
</script>
<style type="text/css" scoped>
.card-img-top {
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
}
.content-label-wrapper {
position: relative;
}
.content-label {
margin: 0;
position: absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
z-index: 2;
background: rgba(0, 0, 0, 0.2)
}
.sensitive-curtain {
margin-top: 0;
padding: 10px;
color: #fff;
font-size: 10px;
text-align: right;
position: absolute;
top: 0;
right: 0;
border-top-left-radius: 5px;
cursor: pointer;
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
}
.photo-license {
margin-bottom: 0;
padding: 0 5px;
color: #fff;
font-size: 10px;
text-align: right;
position: absolute;
bottom: 0;
right: 0;
border-top-left-radius: 5px;
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
}
</style>

Loading…
Cancel
Save