Update RemotePost.vue, improve text only post UI

This commit is contained in:
Daniel Supernault 2021-07-21 01:16:37 -06:00
parent 86219b57fc
commit b0257be20e
No known key found for this signature in database
GPG key ID: 0DEF1C662C9033F7
2 changed files with 153 additions and 16 deletions

View file

@ -9,9 +9,20 @@
<p class="text-center font-weight-bold"><a href="#" class="btn btn-primary font-weight-bold px-5" @click.prevent="warning = false; fetchData()">View Status</a></p> <p class="text-center font-weight-bold"><a href="#" class="btn btn-primary font-weight-bold px-5" @click.prevent="warning = false; fetchData()">View Status</a></p>
</div> </div>
</div> </div>
<div v-if="loaded && warning == false" class="postComponent"> <div v-if="loaded && warning == false && currentLayout === 'status'" class="postComponent">
<div class="container px-0"> <div class="container px-0">
<div class="card card-md-rounded-0 status-container orientation-unknown shadow-none border">
<div v-if="status.pf_type === 'text'" class="col-12 col-md-6 offset-md-3">
<status-card
class="border-top"
:status="status"
:recommended="false"
v-on:comment-focus="commentFocus" />
</div>
<div v-else class="card card-md-rounded-0 status-container orientation-unknown shadow-none border">
<div class="row px-0 mx-0"> <div class="row px-0 mx-0">
<div class="d-flex d-md-none align-items-center justify-content-between card-header bg-white w-100"> <div class="d-flex d-md-none align-items-center justify-content-between card-header bg-white w-100">
<div class="d-flex"> <div class="d-flex">
@ -242,6 +253,7 @@
</div> </div>
</div> </div>
<div class="container" v-if="showProfileMorePosts"> <div class="container" v-if="showProfileMorePosts">
<p class="text-lighter px-3 mt-5" style="font-weight: 600;font-size: 15px;">More posts from <a :href="profileUrl" class="text-dark">{{this.statusUsername}}</a></p> <p class="text-lighter px-3 mt-5" style="font-weight: 600;font-size: 15px;">More posts from <a :href="profileUrl" class="text-dark">{{this.statusUsername}}</a></p>
<div class="profile-timeline mt-md-4"> <div class="profile-timeline mt-md-4">
@ -275,6 +287,14 @@
</div> </div>
</div> </div>
<comment-card
v-if="currentLayout === 'comments'"
:status="status"
:profile="profile"
v-on:current-layout="setCurrentLayout"
:backToStatus="true"
/>
<b-modal ref="likesModal" <b-modal ref="likesModal"
id="l-modal" id="l-modal"
hide-footer hide-footer
@ -521,6 +541,9 @@
pixelfed.postComponent = {}; pixelfed.postComponent = {};
import StatusCard from './partials/StatusCard.vue';
import CommentCard from './partials/CommentCard.vue';
export default { export default {
props: [ props: [
'status-id', 'status-id',
@ -532,12 +555,19 @@ export default {
'status-profile-id', 'status-profile-id',
'profile-layout' 'profile-layout'
], ],
components: {
StatusCard,
CommentCard
},
data() { data() {
return { return {
config: window.App.config, config: window.App.config,
status: false, status: false,
media: {}, media: {},
user: false, user: false,
profile: false,
reactions: { reactions: {
liked: false, liked: false,
shared: false shared: false
@ -573,10 +603,14 @@ export default {
replySending: false, replySending: false,
reactionBarLoading: true, reactionBarLoading: true,
profileUrl: null, profileUrl: null,
currentLayout: 'status'
} }
}, },
mounted() { mounted() {
axios.get('/api/pixelfed/v1/accounts/verify_credentials').then(res => {
this.profile = res.data;
});
this.fetchRelationships(); this.fetchRelationships();
if(localStorage.getItem('pf_metro_ui.exp.rm') == 'false') { if(localStorage.getItem('pf_metro_ui.exp.rm') == 'false') {
this.showReadMore = false; this.showReadMore = false;
@ -625,9 +659,9 @@ export default {
} }
self.profileUrl = '/i/web/profile/_/' + response.data.status.account.id; self.profileUrl = '/i/web/profile/_/' + response.data.status.account.id;
this.loaded = true; this.loaded = true;
setTimeout(function() { // setTimeout(function() {
self.fetchProfilePosts(); // self.fetchProfilePosts();
}, 3000); // }, 3000);
setTimeout(function() { setTimeout(function() {
self.fetchState(); self.fetchState();
document.querySelectorAll('.status-comment .postCommentsContainer .comment-body a').forEach(function(i, e) { document.querySelectorAll('.status-comment .postCommentsContainer .comment-body a').forEach(function(i, e) {
@ -1198,9 +1232,9 @@ export default {
status.sensitive == false status.sensitive == false
}); });
let ids = data.map(status => status.id); let ids = data.map(status => status.id);
if(data.length >= 3) { // if(data.length >= 3) {
self.showProfileMorePosts = true; // self.showProfileMorePosts = true;
} // }
self.profileMorePosts = data.slice(0,6); self.profileMorePosts = data.slice(0,6);
}) })
}, },
@ -1405,6 +1439,75 @@ export default {
}); });
}, },
setCurrentLayout(layout) {
this.currentLayout = layout;
},
commentFocus(status, $event) {
if(status.comments_disabled) {
return;
}
this.replies = {};
this.replyStatus = {};
this.replyText = '';
this.replyId = status.id;
this.replyStatus = status;
// this.$refs.replyModal.show();
this.fetchStatusComments(status, '');
$('nav').hide();
$('footer').hide();
$('.mobile-footer-spacer').attr('style', 'display:none !important');
$('.mobile-footer').attr('style', 'display:none !important');
$('.mt-md-4').hide();
this.currentLayout = 'comments';
window.history.pushState({}, '', this.getStatusUrl(status));
return;
},
fetchStatusComments(status, card) {
let url = '/api/v2/comments/'+status.account.id+'/status/'+status.id;
axios.get(url)
.then(response => {
let self = this;
this.replies = _.reverse(response.data.data);
this.pagination = response.data.meta.pagination;
if(this.replies.length > 0) {
$('.load-more-link').removeClass('d-none');
}
$('.postCommentsLoader').addClass('d-none');
$('.postCommentsContainer').removeClass('d-none');
// setTimeout(function() {
// document.querySelectorAll('.status-comment .postCommentsContainer .comment-body a').forEach(function(i, e) {
// i.href = App.util.format.rewriteLinks(i);
// });
// }, 500);
}).catch(error => {
if(!error.response) {
$('.postCommentsLoader .lds-ring')
.attr('style','width:100%')
.addClass('pt-4 font-weight-bold text-muted')
.text('An error occurred, cannot fetch comments. Please try again later.');
} else {
switch(error.response.status) {
case 401:
$('.postCommentsLoader .lds-ring')
.attr('style','width:100%')
.addClass('pt-4 font-weight-bold text-muted')
.text('Please login to view.');
break;
default:
$('.postCommentsLoader .lds-ring')
.attr('style','width:100%')
.addClass('pt-4 font-weight-bold text-muted')
.text('An error occurred, cannot fetch comments. Please try again later.');
break;
}
}
});
},
}, },
} }
</script> </script>

View file

@ -24,7 +24,7 @@
<div class="media-body"> <div class="media-body">
<p class="d-flex justify-content-between align-items-top mb-0" style="overflow-y: hidden;"> <p class="d-flex justify-content-between align-items-top mb-0" style="overflow-y: hidden;">
<span class="mr-2" style="font-size: 13px;"> <span class="mr-2" style="font-size: 13px;">
<a class="text-dark font-weight-bold mr-1 text-break" :href="status.account.url" v-bind:title="status.account.username">{{trimCaption(status.account.username,15)}}</a> <a class="text-dark font-weight-bold mr-1 text-break" :href="profileUrl(status)" v-bind:title="status.account.username">{{trimCaption(status.account.username,15)}}</a>
<span class="text-break comment-body" style="word-break: break-all;" v-html="status.content"></span> <span class="text-break comment-body" style="word-break: break-all;" v-html="status.content"></span>
</span> </span>
</p> </p>
@ -52,7 +52,7 @@
<div class="media-body"> <div class="media-body">
<div v-if="reply.sensitive == true"> <div v-if="reply.sensitive == true">
<span class="py-3"> <span class="py-3">
<a class="text-dark font-weight-bold mr-3" style="font-size: 13px;" :href="reply.account.url" v-bind:title="reply.account.username">{{trimCaption(reply.account.username,15)}}</a> <a class="text-dark font-weight-bold mr-3" style="font-size: 13px;" :href="profileUrl(reply)" v-bind:title="reply.account.username">{{trimCaption(reply.account.username,15)}}</a>
<span class="text-break" style="font-size: 13px;"> <span class="text-break" style="font-size: 13px;">
<span class="font-italic text-muted">This comment may contain sensitive material</span> <span class="font-italic text-muted">This comment may contain sensitive material</span>
<span class="text-primary cursor-pointer pl-1" @click="reply.sensitive = false;">Show</span> <span class="text-primary cursor-pointer pl-1" @click="reply.sensitive = false;">Show</span>
@ -62,7 +62,7 @@
<div v-else> <div v-else>
<p class="d-flex justify-content-between align-items-top read-more mb-0" style="overflow-y: hidden;"> <p class="d-flex justify-content-between align-items-top read-more mb-0" style="overflow-y: hidden;">
<span class="mr-3" style="font-size: 13px;"> <span class="mr-3" style="font-size: 13px;">
<a class="text-dark font-weight-bold mr-1 text-break" :href="reply.account.url" v-bind:title="reply.account.username">{{trimCaption(reply.account.username,15)}}</a> <a class="text-dark font-weight-bold mr-1 text-break" :href="profileUrl(reply)" v-bind:title="reply.account.username">{{trimCaption(reply.account.username,15)}}</a>
<span class="text-break comment-body" style="word-break: break-all;" v-html="reply.content"></span> <span class="text-break comment-body" style="word-break: break-all;" v-html="reply.content"></span>
</span> </span>
<span class="text-right" style="min-width: 30px;"> <span class="text-right" style="min-width: 30px;">
@ -73,7 +73,7 @@
</span> </span>
</p> </p>
<p class="mb-0"> <p class="mb-0">
<a v-once class="text-muted mr-3 text-decoration-none small" style="width: 20px;" v-text="timeAgo(reply.created_at)" :href="reply.url"></a> <a v-once class="text-muted mr-3 text-decoration-none small" style="width: 20px;" v-text="timeAgo(reply.created_at)" :href="statusUrl(reply)"></a>
<span v-if="reply.favourites_count" class="text-muted comment-reaction font-weight-bold mr-3 small">{{reply.favourites_count == 1 ? '1 like' : reply.favourites_count + ' likes'}}</span> <span v-if="reply.favourites_count" class="text-muted comment-reaction font-weight-bold mr-3 small">{{reply.favourites_count == 1 ? '1 like' : reply.favourites_count + ' likes'}}</span>
<span class="small text-muted comment-reaction font-weight-bold cursor-pointer" v-on:click="replyFocus(reply, index, true)">Reply</span> <span class="small text-muted comment-reaction font-weight-bold cursor-pointer" v-on:click="replyFocus(reply, index, true)">Reply</span>
</p> </p>
@ -87,7 +87,7 @@
<div class="media-body"> <div class="media-body">
<p class="d-flex justify-content-between align-items-top read-more mb-0" style="overflow-y: hidden;"> <p class="d-flex justify-content-between align-items-top read-more mb-0" style="overflow-y: hidden;">
<span class="mr-2" style="font-size: 13px;"> <span class="mr-2" style="font-size: 13px;">
<a class="text-dark font-weight-bold mr-1" :href="s.account.url" :title="s.account.username">{{s.account.username}}</a> <a class="text-dark font-weight-bold mr-1" :href="profileUrl(s)" :title="s.account.username">{{s.account.username}}</a>
<span class="text-break comment-body" style="word-break: break-all;" v-html="s.content"></span> <span class="text-break comment-body" style="word-break: break-all;" v-html="s.content"></span>
</span> </span>
<span> <span>
@ -95,7 +95,7 @@
</span> </span>
</p> </p>
<p class="mb-0"> <p class="mb-0">
<a v-once class="text-muted mr-3 text-decoration-none small" style="width: 20px;" v-text="timeAgo(s.created_at)" :href="s.url"></a> <a v-once class="text-muted mr-3 text-decoration-none small" style="width: 20px;" v-text="timeAgo(s.created_at)" :href="statusUrl(s)"></a>
<span v-if="s.favourites_count" class="text-muted comment-reaction font-weight-bold mr-3">{{s.favourites_count == 1 ? '1 like' : s.favourites_count + ' likes'}}</span> <span v-if="s.favourites_count" class="text-muted comment-reaction font-weight-bold mr-3">{{s.favourites_count == 1 ? '1 like' : s.favourites_count + ' likes'}}</span>
</p> </p>
</div> </div>
@ -190,7 +190,20 @@
import ContextMenu from './ContextMenu.vue'; import ContextMenu from './ContextMenu.vue';
export default { export default {
props: ['status', 'profile'], props: {
'status': {
type: Object
},
'profile': {
type: Object
},
'backToStatus': {
type: Boolean,
default: false
}
},
components: { components: {
"context-menu": ContextMenu "context-menu": ContextMenu
@ -249,6 +262,11 @@
methods: { methods: {
commentNavigateBack(id) { commentNavigateBack(id) {
if(this.backToStatus) {
window.location.href = this.statusUrl(this.status);
return;
}
$('nav').show(); $('nav').show();
$('footer').show(); $('footer').show();
$('.mobile-footer-spacer').attr('style', 'display:block'); $('.mobile-footer-spacer').attr('style', 'display:block');
@ -393,7 +411,23 @@
ctxMenu(status) { ctxMenu(status) {
this.ctxMenuStatus = status; this.ctxMenuStatus = status;
this.$refs.cMenu.open(); this.$refs.cMenu.open();
} },
statusUrl(status) {
if(status.local == true) {
return status.url;
}
return '/i/web/post/_/' + status.account.id + '/' + status.id;
},
profileUrl(status) {
if(status.local == true) {
return status.account.url;
}
return '/i/web/profile/_/' + status.account.id;
},
} }
} }