Update post component

pull/5828/head
Daniel Supernault 3 months ago
parent 6004f574dd
commit e92f904be3
No known key found for this signature in database
GPG Key ID: 23740873EE6F76A1

@ -1,443 +1,444 @@
<template> <template>
<div class="post-timeline-component web-wrapper"> <div class="post-timeline-component web-wrapper">
<div v-if="isLoaded" class="container-fluid mt-3"> <div v-if="isLoaded" class="container-fluid mt-3">
<div class="row"> <div class="row">
<div class="col-md-4 col-lg-3 d-md-block"> <div class="col-md-4 col-lg-3 d-md-block">
<sidebar :user="user" /> <sidebar :user="user" />
</div> </div>
<div class="col-md-8 col-lg-6"> <div class="col-md-8 col-lg-6">
<div v-if="isReply" class="p-3 rounded-top mb-n3" style="background-color: var(--card-header-accent)"> <div v-if="isReply" class="p-3 rounded-top mb-n3" style="background-color: var(--card-header-accent)">
<p> <p>
<i class="fal fa-reply mr-1"></i> In reply to <i class="fal fa-reply mr-1"></i> In reply to
<a <a
:href="'/i/web/profile/' + reply.account.id" :href="'/i/web/profile/' + reply.account.id"
class="font-weight-bold primary" class="font-weight-bold primary"
@click.prevent="goToProfile(reply.account)"> @click.prevent="goToProfile(reply.account)">
&commat;{{ reply.account.acct }} &commat;{{ reply.account.acct }}
</a> </a>
<button <button
@click.prevent="goToPost(reply)" @click.prevent="goToPost(reply)"
class="btn btn-primary font-weight-bold btn-sm px-3 float-right rounded-pill"> class="btn btn-primary font-weight-bold btn-sm px-3 float-right rounded-pill">
View Post View Post
</button> </button>
</p> </p>
</div> </div>
<status <status
:key="post.id + ':fui:' + forceUpdateIdx" :key="post.id + ':fui:' + forceUpdateIdx"
:status="post" :status="post"
:profile="user" :profile="user"
v-on:menu="openContextMenu()" v-on:menu="openContextMenu()"
v-on:like="likeStatus()" v-on:like="likeStatus()"
v-on:unlike="unlikeStatus()" v-on:unlike="unlikeStatus()"
v-on:likes-modal="openLikesModal()" v-on:likes-modal="openLikesModal()"
v-on:shares-modal="openSharesModal()" v-on:shares-modal="openSharesModal()"
v-on:bookmark="handleBookmark()" v-on:bookmark="handleBookmark()"
v-on:share="shareStatus()" v-on:share="shareStatus()"
v-on:unshare="unshareStatus()" v-on:unshare="unshareStatus()"
v-on:follow="follow()" v-on:follow="follow()"
v-on:unfollow="unfollow()" v-on:unfollow="unfollow()"
v-on:counter-change="counterChange" v-on:counter-change="counterChange"
/> />
</div> </div>
<div class="d-none d-lg-block col-lg-3"> <div class="d-none d-lg-block col-lg-3">
<rightbar /> <rightbar />
</div> </div>
</div> </div>
</div> </div>
<div v-if="postStateError" class="container-fluid mt-3"> <div v-if="postStateError" class="container-fluid mt-3">
<div class="row"> <div class="row">
<div class="col-md-4 col-lg-3 d-md-block"> <div class="col-md-4 col-lg-3 d-md-block">
<sidebar :user="user" /> <sidebar :user="user" />
</div> </div>
<div class="col-md-8 col-lg-6"> <div class="col-md-8 col-lg-6">
<div class="card card-body shadow-none border"> <div class="card card-body shadow-none border">
<div class="d-flex align-self-center flex-column" style="max-width: 500px;"> <div class="d-flex align-self-center flex-column" style="max-width: 500px;">
<p class="text-center"> <p class="text-center">
<i class="far fa-exclamation-triangle fa-3x text-lighter"></i> <i class="far fa-exclamation-triangle fa-3x text-lighter"></i>
</p> </p>
<p class="text-center lead font-weight-bold">Error displaying post</p> <p class="text-center lead font-weight-bold">Error displaying post</p>
<p class="mb-0">This can happen for a few reasons:</p> <p class="mb-0">This can happen for a few reasons:</p>
<ul class="text-lighter"> <ul class="text-lighter">
<li>The url is invalid or has a typo</li> <li>The url is invalid or has a typo</li>
<li>The page has been flagged for review by our automated abuse detection systems</li> <li>The page has been flagged for review by our automated abuse detection systems</li>
<li>The content may have been deleted</li> <li>The content may have been deleted</li>
<li>You do not have permission to view this content</li> <li>You do not have permission to view this content</li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
<div class="d-none d-lg-block col-lg-3"> <div class="d-none d-lg-block col-lg-3">
<rightbar /> <rightbar />
</div> </div>
</div> </div>
</div> </div>
<context-menu <context-menu
v-if="isLoaded" v-if="isLoaded"
ref="contextMenu" ref="contextMenu"
:status="post" :status="post"
:profile="user" :profile="user"
@report-modal="handleReport()" @report-modal="handleReport()"
@delete="deletePost()" @delete="deletePost()"
v-on:edit="handleEdit" v-on:edit="handleEdit"
/> />
<likes-modal <likes-modal
v-if="showLikesModal" v-if="showLikesModal"
ref="likesModal" ref="likesModal"
:status="post" :status="post"
:profile="user" :profile="user"
/> />
<shares-modal <shares-modal
v-if="showSharesModal" v-if="showSharesModal"
ref="sharesModal" ref="sharesModal"
:status="post" :status="post"
:profile="profile" :profile="profile"
/> />
<report-modal <report-modal
v-if="post" v-if="post"
ref="reportModal" ref="reportModal"
:status="post" :status="post"
/> />
<post-edit-modal <post-edit-modal
ref="editModal" ref="editModal"
v-on:update="mergeUpdatedPost" v-on:update="mergeUpdatedPost"
/> />
<drawer /> <drawer />
</div> </div>
</template> </template>
<script type="text/javascript"> <script type="text/javascript">
import Drawer from './partials/drawer.vue'; import Drawer from './partials/drawer.vue';
import Rightbar from './partials/rightbar.vue'; import Rightbar from './partials/rightbar.vue';
import Sidebar from './partials/sidebar.vue'; import Sidebar from './partials/sidebar.vue';
import Status from './partials/TimelineStatus.vue'; import Status from './partials/TimelineStatus.vue';
import ContextMenu from './partials/post/ContextMenu.vue'; import ContextMenu from './partials/post/ContextMenu.vue';
import MediaContainer from './partials/post/MediaContainer.vue'; import MediaContainer from './partials/post/MediaContainer.vue';
import LikesModal from './partials/post/LikeModal.vue'; import LikesModal from './partials/post/LikeModal.vue';
import SharesModal from './partials/post/ShareModal.vue'; import SharesModal from './partials/post/ShareModal.vue';
import ReportModal from './partials/modal/ReportPost.vue'; import ReportModal from './partials/modal/ReportPost.vue';
import PostEditModal from './partials/post/PostEditModal.vue'; import PostEditModal from './partials/post/PostEditModal.vue';
export default { export default {
props: { props: {
cachedStatus: { cachedStatus: {
type: Object type: Object
}, },
cachedProfile: { cachedProfile: {
type: Object type: Object
} }
}, },
components: { components: {
"drawer": Drawer, "drawer": Drawer,
"sidebar": Sidebar, "sidebar": Sidebar,
"status": Status, "status": Status,
"context-menu": ContextMenu, "context-menu": ContextMenu,
"media-container": MediaContainer, "media-container": MediaContainer,
"likes-modal": LikesModal, "likes-modal": LikesModal,
"shares-modal": SharesModal, "shares-modal": SharesModal,
"rightbar": Rightbar, "rightbar": Rightbar,
"report-modal": ReportModal, "report-modal": ReportModal,
"post-edit-modal": PostEditModal "post-edit-modal": PostEditModal
}, },
data() { data() {
return { return {
isLoaded: false, isLoaded: false,
user: undefined, user: undefined,
profile: undefined, profile: undefined,
post: undefined, post: undefined,
relationship: {}, relationship: {},
media: undefined, media: undefined,
mediaIndex: 0, mediaIndex: 0,
showLikesModal: false, showLikesModal: false,
isReply: false, isReply: false,
reply: {}, reply: {},
showSharesModal: false, showSharesModal: false,
postStateError: false, postStateError: false,
forceUpdateIdx: 0 forceUpdateIdx: 0
} }
}, },
created() { created() {
this.init(); this.init();
}, },
watch: { watch: {
'$route': 'init' '$route': 'init'
}, },
methods: { methods: {
init() { init() {
this.fetchSelf(); this.fetchSelf();
}, },
fetchSelf() { fetchSelf() {
this.user = window._sharedData.user; this.user = window._sharedData.user;
this.fetchPost(); this.isReply = false;
}, this.fetchPost();
},
fetchPost() {
axios.get('/api/pixelfed/v1/statuses/'+this.$route.params.id) fetchPost() {
.then(res => { axios.get('/api/pixelfed/v1/statuses/'+this.$route.params.id)
if(!res.data || !res.data.hasOwnProperty('id')) { .then(res => {
this.$router.push('/i/web/404'); if(!res.data || !res.data.hasOwnProperty('id')) {
} this.$router.push('/i/web/404');
if(!res.data.hasOwnProperty('account') || !res.data.account) { }
this.postStateError = true; if(!res.data.hasOwnProperty('account') || !res.data.account) {
return; this.postStateError = true;
} return;
this.post = res.data; }
this.media = this.post.media_attachments; this.post = res.data;
this.profile = this.post.account; this.media = this.post.media_attachments;
if(this.post.in_reply_to_id) { this.profile = this.post.account;
this.fetchReply(); if(this.post.in_reply_to_id) {
} else { this.fetchReply();
this.fetchRelationship(); } else {
} this.fetchRelationship();
}).catch(err => { }
switch(err.response.status) { }).catch(err => {
case 403: switch(err.response.status) {
case 404: case 403:
this.$router.push('/i/web/404'); case 404:
break; this.$router.push('/i/web/404');
} break;
}) }
}, })
},
fetchReply() {
axios.get('/api/pixelfed/v1/statuses/' + this.post.in_reply_to_id) fetchReply() {
.then(res => { axios.get('/api/pixelfed/v1/statuses/' + this.post.in_reply_to_id)
this.reply = res.data; .then(res => {
this.isReply = true; this.reply = res.data;
this.fetchRelationship(); this.isReply = true;
}) this.fetchRelationship();
.catch(err => { })
this.fetchRelationship(); .catch(err => {
}) this.fetchRelationship();
}, })
},
fetchRelationship() {
if(this.profile.id == this.user.id) { fetchRelationship() {
this.relationship = {}; if(this.profile.id == this.user.id) {
this.fetchState(); this.relationship = {};
return; this.fetchState();
} return;
}
axios.get('/api/pixelfed/v1/accounts/relationships', {
params: { axios.get('/api/pixelfed/v1/accounts/relationships', {
'id[]': this.profile.id params: {
} 'id[]': this.profile.id
}).then(res => { }
this.relationship = res.data[0]; }).then(res => {
this.fetchState(); this.relationship = res.data[0];
}); this.fetchState();
}, });
},
fetchState() {
axios.get('/api/v2/statuses/'+this.post.id+'/state') fetchState() {
.then(res => { axios.get('/api/v2/statuses/'+this.post.id+'/state')
this.post.favourited = res.data.liked; .then(res => {
this.post.reblogged = res.data.shared; this.post.favourited = res.data.liked;
this.post.bookmarked = res.data.bookmarked; this.post.reblogged = res.data.shared;
if(!this.post.favourites_count && this.post.favourited) { this.post.bookmarked = res.data.bookmarked;
this.post.favourites_count = 1; if(!this.post.favourites_count && this.post.favourited) {
} this.post.favourites_count = 1;
this.isLoaded = true; }
}).catch(err => { this.isLoaded = true;
this.isLoaded = false; }).catch(err => {
this.postStateError = true; this.isLoaded = false;
}) this.postStateError = true;
}, })
},
goBack() {
this.$router.push('/i/web'); goBack() {
}, this.$router.push('/i/web');
},
likeStatus() {
let count = this.post.favourites_count; likeStatus() {
this.post.favourites_count = count + 1; let count = this.post.favourites_count;
this.post.favourited = !this.post.favourited; this.post.favourites_count = count + 1;
this.post.favourited = !this.post.favourited;
axios.post('/api/v1/statuses/' + this.post.id + '/favourite')
.then(res => { axios.post('/api/v1/statuses/' + this.post.id + '/favourite')
// .then(res => {
}).catch(err => { //
this.post.favourites_count = count; }).catch(err => {
this.post.favourited = false; this.post.favourites_count = count;
}) this.post.favourited = false;
}, })
},
unlikeStatus() {
let count = this.post.favourites_count; unlikeStatus() {
this.post.favourites_count = count - 1; let count = this.post.favourites_count;
this.post.favourited = !this.post.favourited; this.post.favourites_count = count - 1;
this.post.favourited = !this.post.favourited;
axios.post('/api/v1/statuses/' + this.post.id + '/unfavourite')
.then(res => { axios.post('/api/v1/statuses/' + this.post.id + '/unfavourite')
// .then(res => {
}).catch(err => { //
this.post.favourites_count = count; }).catch(err => {
this.post.favourited = false; this.post.favourites_count = count;
}) this.post.favourited = false;
}, })
},
shareStatus() {
let count = this.post.reblogs_count; shareStatus() {
this.post.reblogs_count = count + 1; let count = this.post.reblogs_count;
this.post.reblogged = !this.post.reblogged; this.post.reblogs_count = count + 1;
this.post.reblogged = !this.post.reblogged;
axios.post('/api/v1/statuses/' + this.post.id + '/reblog')
.then(res => { axios.post('/api/v1/statuses/' + this.post.id + '/reblog')
// .then(res => {
}).catch(err => { //
this.post.reblogs_count = count; }).catch(err => {
this.post.reblogged = false; this.post.reblogs_count = count;
}) this.post.reblogged = false;
}, })
},
unshareStatus() {
let count = this.post.reblogs_count; unshareStatus() {
this.post.reblogs_count = count - 1; let count = this.post.reblogs_count;
this.post.reblogged = !this.post.reblogged; this.post.reblogs_count = count - 1;
this.post.reblogged = !this.post.reblogged;
axios.post('/api/v1/statuses/' + this.post.id + '/unreblog')
.then(res => { axios.post('/api/v1/statuses/' + this.post.id + '/unreblog')
// .then(res => {
}).catch(err => { //
this.post.reblogs_count = count; }).catch(err => {
this.post.reblogged = false; this.post.reblogs_count = count;
}) this.post.reblogged = false;
}, })
},
follow() {
axios.post('/api/v1/accounts/' + this.post.account.id + '/follow') follow() {
.then(res => { axios.post('/api/v1/accounts/' + this.post.account.id + '/follow')
this.$store.commit('updateRelationship', [res.data]); .then(res => {
this.user.following_count++; this.$store.commit('updateRelationship', [res.data]);
this.post.account.followers_count++; this.user.following_count++;
}).catch(err => { this.post.account.followers_count++;
swal('Oops!', 'An error occurred when attempting to follow this account.', 'error'); }).catch(err => {
this.post.relationship.following = false; swal('Oops!', 'An error occurred when attempting to follow this account.', 'error');
}); this.post.relationship.following = false;
}, });
},
unfollow() {
axios.post('/api/v1/accounts/' + this.post.account.id + '/unfollow') unfollow() {
.then(res => { axios.post('/api/v1/accounts/' + this.post.account.id + '/unfollow')
this.$store.commit('updateRelationship', [res.data]); .then(res => {
this.user.following_count--; this.$store.commit('updateRelationship', [res.data]);
this.post.account.followers_count--; this.user.following_count--;
}).catch(err => { this.post.account.followers_count--;
swal('Oops!', 'An error occurred when attempting to unfollow this account.', 'error'); }).catch(err => {
this.post.relationship.following = true; swal('Oops!', 'An error occurred when attempting to unfollow this account.', 'error');
}); this.post.relationship.following = true;
}, });
},
openContextMenu() {
this.$nextTick(() => { openContextMenu() {
this.$refs.contextMenu.open(); this.$nextTick(() => {
}); this.$refs.contextMenu.open();
}, });
},
openLikesModal() {
this.showLikesModal = true; openLikesModal() {
this.$nextTick(() => { this.showLikesModal = true;
this.$refs.likesModal.open(); this.$nextTick(() => {
}); this.$refs.likesModal.open();
}, });
},
openSharesModal() {
this.showSharesModal = true; openSharesModal() {
this.$nextTick(() => { this.showSharesModal = true;
this.$refs.sharesModal.open(); this.$nextTick(() => {
}); this.$refs.sharesModal.open();
}, });
},
deletePost() {
this.$router.push('/i/web'); deletePost() {
}, this.$router.push('/i/web');
},
goToPost(post) {
this.$router.push({ goToPost(post) {
name: 'post', this.$router.push({
path: `/i/web/post/${post.id}`, name: 'post',
params: { path: `/i/web/post/${post.id}`,
id: post.id, params: {
cachedStatus: post, id: post.id,
cachedProfile: this.user cachedStatus: post,
} cachedProfile: this.user
}) }
}, })
},
goToProfile(account) {
this.$router.push({ goToProfile(account) {
name: 'profile', this.$router.push({
path: `/i/web/profile/${account.id}`, name: 'profile',
params: { path: `/i/web/profile/${account.id}`,
id: account.id, params: {
cachedProfile: account, id: account.id,
cachedUser: this.user cachedProfile: account,
} cachedUser: this.user
}) }
}, })
},
handleBookmark() {
axios.post('/i/bookmark', { handleBookmark() {
item: this.post.id axios.post('/i/bookmark', {
}) item: this.post.id
.then(res => { })
this.post.bookmarked = !this.post.bookmarked; .then(res => {
}) this.post.bookmarked = !this.post.bookmarked;
.catch(err => { })
this.$bvToast.toast('Cannot bookmark post at this time.', { .catch(err => {
title: 'Bookmark Error', this.$bvToast.toast('Cannot bookmark post at this time.', {
variant: 'danger', title: 'Bookmark Error',
autoHideDelay: 5000 variant: 'danger',
}); autoHideDelay: 5000
}); });
}, });
},
handleReport() {
this.$nextTick(() => { handleReport() {
this.$refs.reportModal.open(); this.$nextTick(() => {
}); this.$refs.reportModal.open();
}, });
},
counterChange(type) {
switch(type) { counterChange(type) {
case 'comment-increment': switch(type) {
this.post.reply_count = this.post.reply_count + 1; case 'comment-increment':
break; this.post.reply_count = this.post.reply_count + 1;
break;
case 'comment-decrement':
this.post.reply_count = this.post.reply_count - 1; case 'comment-decrement':
break; this.post.reply_count = this.post.reply_count - 1;
} break;
}, }
},
handleEdit(status) {
this.$refs.editModal.show(status); handleEdit(status) {
this.$refs.editModal.show(status);
}, },
mergeUpdatedPost(post) { mergeUpdatedPost(post) {
this.post = post; this.post = post;
this.$nextTick(() => { this.$nextTick(() => {
this.forceUpdateIdx++; this.forceUpdateIdx++;
}); });
} }
} }
} }
</script> </script>

Loading…
Cancel
Save