mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-26 16:23:16 +00:00
Update Timeline.vue component
This commit is contained in:
parent
5b720b239e
commit
66d6dfd189
1 changed files with 140 additions and 34 deletions
|
@ -66,15 +66,24 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card mb-sm-4 status-card card-md-rounded-0 shadow-none border">
|
<div class="card mb-sm-4 status-card card-md-rounded-0 shadow-none border">
|
||||||
<div v-if="!modes.distractionFree" class="card-header d-inline-flex align-items-center bg-white">
|
<div v-if="!modes.distractionFree" class="card-header d-inline-flex align-items-center bg-white">
|
||||||
<img v-bind:src="status.account.avatar" width="32px" height="32px" style="border-radius: 32px;">
|
<img v-bind:src="status.account.avatar" width="32px" height="32px" style="border-radius: 32px;">
|
||||||
<a class="username font-weight-bold pl-2 text-dark" v-bind:href="status.account.url">
|
<div class="pl-2">
|
||||||
{{status.account.username}}
|
<!-- <a class="d-block username font-weight-bold text-dark" v-bind:href="status.account.url" style="line-height:0.5;"> -->
|
||||||
</a>
|
<a class="username font-weight-bold text-dark text-decoration-none" v-bind:href="status.account.url">
|
||||||
|
{{status.account.username}}
|
||||||
|
</a>
|
||||||
|
<span v-if="scope != 'home' && status.account.id != profile.id && status.account.relationship">
|
||||||
|
<span class="px-1">•</span>
|
||||||
|
<span :class="'font-weight-bold cursor-pointer ' + [status.account.relationship.following == true ? 'text-muted' : 'text-primary']" @click="followAction(status)">{{status.account.relationship.following == true ? 'Following' : 'Follow'}}</span>
|
||||||
|
</span>
|
||||||
|
<a v-if="status.place" class="d-block small text-decoration-none" :href="'/discover/places/'+status.place.id+'/'+status.place.slug" style="color:#718096">{{status.place.name}}, {{status.place.country}}</a>
|
||||||
|
</div>
|
||||||
<div class="text-right" style="flex-grow:1;">
|
<div class="text-right" style="flex-grow:1;">
|
||||||
<button class="btn btn-link text-dark py-0" type="button" @click="ctxMenu(status)">
|
<button class="btn btn-link text-dark py-0" type="button" @click="ctxMenu(status)">
|
||||||
<span class="fas fa-ellipsis-h text-dark"></span>
|
<span class="fas fa-ellipsis-h text-lighter"></span>
|
||||||
</button>
|
</button>
|
||||||
<!-- <div class="dropdown-menu dropdown-menu-right">
|
<!-- <div class="dropdown-menu dropdown-menu-right">
|
||||||
<a class="dropdown-item font-weight-bold" :href="status.url">Go to post</a>
|
<a class="dropdown-item font-weight-bold" :href="status.url">Go to post</a>
|
||||||
|
@ -114,7 +123,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="postPresenterContainer" v-on:dblclick="likeStatus(status)">
|
<div class="postPresenterContainer" @click="lightbox(status)">
|
||||||
<div v-if="status.pf_type === 'photo'" class="w-100">
|
<div v-if="status.pf_type === 'photo'" class="w-100">
|
||||||
<photo-presenter :status="status" v-on:lightbox="lightbox"></photo-presenter>
|
<photo-presenter :status="status" v-on:lightbox="lightbox"></photo-presenter>
|
||||||
</div>
|
</div>
|
||||||
|
@ -141,10 +150,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div v-if="!modes.distractionFree" class="reactions my-1">
|
<div v-if="!modes.distractionFree" class="reactions my-1 pb-2">
|
||||||
<h3 v-bind:class="[status.favourited ? 'fas fa-heart text-danger pr-3 m-0 cursor-pointer' : 'far fa-heart pr-3 m-0 like-btn cursor-pointer']" title="Like" v-on:click="likeStatus(status, $event)"></h3>
|
<h3 v-bind:class="[status.favourited ? 'fas fa-heart text-danger pr-3 m-0 cursor-pointer' : 'far fa-heart pr-3 m-0 like-btn text-lighter cursor-pointer']" title="Like" v-on:click="likeStatus(status, $event)"></h3>
|
||||||
<h3 v-if="!status.comments_disabled" class="far fa-comment pr-3 m-0 cursor-pointer" title="Comment" v-on:click="commentFocus(status, $event)"></h3>
|
<h3 v-if="!status.comments_disabled" class="far fa-comment text-lighter pr-3 m-0 cursor-pointer" title="Comment" v-on:click="commentFocus(status, $event)"></h3>
|
||||||
<h3 v-if="status.visibility == 'public'" v-bind:class="[status.reblogged ? 'far fa-share-square pr-3 m-0 text-primary cursor-pointer' : 'far fa-share-square pr-3 m-0 share-btn cursor-pointer']" title="Share" v-on:click="shareStatus(status, $event)"></h3>
|
<h3 v-if="status.visibility == 'public'" v-bind:class="[status.reblogged ? 'fas fa-retweet pr-3 m-0 text-primary cursor-pointer' : 'fas fa-retweet pr-3 m-0 text-lighter share-btn cursor-pointer']" title="Share" v-on:click="shareStatus(status, $event)"></h3>
|
||||||
|
<span class="float-right">
|
||||||
|
<h3 class="fas fa-expand pr-3 m-0 cursor-pointer text-lighter" v-on:click="lightbox(status)"></h3>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="likes font-weight-bold" v-if="expLc(status) == true && !modes.distractionFree">
|
<div class="likes font-weight-bold" v-if="expLc(status) == true && !modes.distractionFree">
|
||||||
|
@ -165,8 +177,11 @@
|
||||||
<span v-html="reply.content"></span>
|
<span v-html="reply.content"></span>
|
||||||
</span>
|
</span>
|
||||||
<span class="mb-0" style="min-width:38px">
|
<span class="mb-0" style="min-width:38px">
|
||||||
<span v-on:click="likeStatus(reply, $event)"><i v-bind:class="[reply.favourited ? 'fas fa-heart fa-sm text-danger':'far fa-heart fa-sm text-lighter']"></i></span>
|
<span v-on:click="likeStatus(reply, $event)"><i v-bind:class="[reply.favourited ? 'fas fa-heart fa-sm text-danger cursor-pointer':'far fa-heart fa-sm text-lighter cursor-pointer']"></i></span>
|
||||||
<post-menu :status="reply" :profile="profile" size="sm" :modal="'true'" :feed="feed" class="d-inline-flex pl-2"></post-menu>
|
<!-- <post-menu :status="reply" :profile="profile" size="sm" :modal="'true'" :feed="feed" class="d-inline-flex pl-2"></post-menu> -->
|
||||||
|
<span class="text-lighter pl-2 cursor-pointer" @click="ctxMenu(reply)">
|
||||||
|
<span class="fas fa-ellipsis-v text-lighter"></span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -209,7 +224,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!loading && feed.length > 0">
|
<div v-if="!loading && feed.length">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<infinite-loading @infinite="infiniteTimeline" :distance="800">
|
<infinite-loading @infinite="infiniteTimeline" :distance="800">
|
||||||
|
@ -252,22 +267,36 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="card-footer bg-white py-1 d-none">
|
<div class="card-footer bg-transparent border-0 mt-2 py-1">
|
||||||
<div class="d-flex justify-content-between text-center">
|
<div class="d-flex justify-content-between text-center">
|
||||||
<span class="pl-3 cursor-pointer" v-on:click="redirect(profile.url)">
|
<span class="cursor-pointer" @click="redirect(profile.url)">
|
||||||
<p class="mb-0 font-weight-bold">{{profile.statuses_count}}</p>
|
<p class="mb-0 font-weight-bold">{{profile.statuses_count}}</p>
|
||||||
<p class="mb-0 small text-muted">Posts</p>
|
<p class="mb-0 small text-muted">Posts</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="cursor-pointer" v-on:click="followersModal()">
|
<span class="cursor-pointer" @click="redirect(profile.url+'?md=followers')">
|
||||||
<p class="mb-0 font-weight-bold">{{profile.followers_count}}</p>
|
<p class="mb-0 font-weight-bold">{{profile.followers_count}}</p>
|
||||||
<p class="mb-0 small text-muted">Followers</p>
|
<p class="mb-0 small text-muted">Followers</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="pr-3 cursor-pointer" v-on:click="followingModal()">
|
<span class="cursor-pointer" @click="redirect(profile.url+'?md=following')">
|
||||||
<p class="mb-0 font-weight-bold">{{profile.following_count}}</p>
|
<p class="mb-0 font-weight-bold">{{profile.following_count}}</p>
|
||||||
<p class="mb-0 small text-muted">Following</p>
|
<p class="mb-0 small text-muted">Following</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="showTips" class="mb-4 card-tips">
|
||||||
|
<div class="card border shadow-none mb-3" style="max-width: 18rem;">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-title">
|
||||||
|
<span class="font-weight-bold">Tip: Hide follower counts</span>
|
||||||
|
<span class="float-right cursor-pointer" @click.prevent="hideTips()"><i class="fas fa-times text-lighter"></i></span>
|
||||||
|
</div>
|
||||||
|
<p class="card-text">
|
||||||
|
<span style="font-size:13px;">You can hide followers or following count and lists on your profile.</span>
|
||||||
|
<br><a href="/settings/privacy/" class="small font-weight-bold">Privacy Settings</a></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -400,9 +429,25 @@
|
||||||
<!-- <div class="list-group-item rounded cursor-pointer" @click="ctxMenuEmbed()">Embed</div>
|
<!-- <div class="list-group-item rounded cursor-pointer" @click="ctxMenuEmbed()">Embed</div>
|
||||||
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuShare()">Share</div> -->
|
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuShare()">Share</div> -->
|
||||||
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuCopyLink()">Copy Link</div>
|
<div class="list-group-item rounded cursor-pointer" @click="ctxMenuCopyLink()">Copy Link</div>
|
||||||
|
<div v-if="profile && profile.is_admin == true" class="list-group-item rounded cursor-pointer" @click="ctxModMenuShow()">Moderation Tools</div>
|
||||||
|
<div v-if="ctxMenuStatus && (profile.is_admin || profile.id == ctxMenuStatus.account.id)" class="list-group-item rounded cursor-pointer" @click="deletePost(ctxMenuStatus)">Delete</div>
|
||||||
<div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxMenu()">Cancel</div>
|
<div class="list-group-item rounded cursor-pointer text-lighter" @click="closeCtxMenu()">Cancel</div>
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
<b-modal ref="ctxModModal"
|
||||||
|
id="ctx-mod-modal"
|
||||||
|
hide-header
|
||||||
|
hide-footer
|
||||||
|
centered
|
||||||
|
rounded
|
||||||
|
size="sm"
|
||||||
|
body-class="list-group-flush p-0 rounded">
|
||||||
|
<div class="list-group text-center">
|
||||||
|
<div class="list-group-item rounded cursor-pointer" @click="moderatePost(ctxMenuStatus, 'unlist')">Unlist from Timelines</div>
|
||||||
|
<div class="list-group-item rounded cursor-pointer" @click="">Add Content Warning</div>
|
||||||
|
<div class="list-group-item rounded cursor-pointer text-lighter" @click="ctxModMenuClose()">Cancel</div>
|
||||||
|
</div>
|
||||||
|
</b-modal>
|
||||||
<b-modal ref="ctxShareModal"
|
<b-modal ref="ctxShareModal"
|
||||||
id="ctx-share-modal"
|
id="ctx-share-modal"
|
||||||
title="Share"
|
title="Share"
|
||||||
|
@ -444,8 +489,8 @@
|
||||||
size="lg"
|
size="lg"
|
||||||
body-class="p-0"
|
body-class="p-0"
|
||||||
>
|
>
|
||||||
<div v-if="lightboxMedia" :class="lightboxMedia.filter_class">
|
<div v-if="lightboxMedia" :class="lightboxMedia.filter_class" class="w-100 h-100">
|
||||||
<img :src="lightboxMedia.url" class="img-fluid" style="min-height: 100%; min-width: 100%">
|
<img :src="lightboxMedia.url" style="max-height: 100%; max-width: 100%">
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
</div>
|
</div>
|
||||||
|
@ -524,7 +569,8 @@
|
||||||
ctxMenuStatus: false,
|
ctxMenuStatus: false,
|
||||||
ctxMenuRelationship: false,
|
ctxMenuRelationship: false,
|
||||||
ctxEmbedPayload: false,
|
ctxEmbedPayload: false,
|
||||||
copiedEmbed: false
|
copiedEmbed: false,
|
||||||
|
showTips: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -563,6 +609,10 @@
|
||||||
this.modes.distractionFree = false;
|
this.modes.distractionFree = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(localStorage.getItem('metro-tips') == 'false') {
|
||||||
|
this.showTips = false;
|
||||||
|
}
|
||||||
|
|
||||||
this.$nextTick(function () {
|
this.$nextTick(function () {
|
||||||
$('[data-toggle="tooltip"]').tooltip()
|
$('[data-toggle="tooltip"]').tooltip()
|
||||||
});
|
});
|
||||||
|
@ -623,13 +673,19 @@
|
||||||
this.max_id = Math.min(...ids);
|
this.max_id = Math.min(...ids);
|
||||||
$('.timeline .pagination').removeClass('d-none');
|
$('.timeline .pagination').removeClass('d-none');
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.fetchHashtagPosts();
|
if(this.feed.length == 6) {
|
||||||
|
this.fetchHashtagPosts();
|
||||||
|
this.fetchTimelineApi();
|
||||||
|
} else {
|
||||||
|
this.fetchHashtagPosts();
|
||||||
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
infiniteTimeline($state) {
|
infiniteTimeline($state) {
|
||||||
if(this.loading) {
|
if(this.loading) {
|
||||||
|
$state.complete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let apiUrl = false;
|
let apiUrl = false;
|
||||||
|
@ -649,7 +705,7 @@
|
||||||
axios.get(apiUrl, {
|
axios.get(apiUrl, {
|
||||||
params: {
|
params: {
|
||||||
max_id: this.max_id,
|
max_id: this.max_id,
|
||||||
limit: 6
|
limit: 9
|
||||||
},
|
},
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.data.length && this.loading == false) {
|
if (res.data.length && this.loading == false) {
|
||||||
|
@ -826,7 +882,7 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deletePost(status, index) {
|
deletePost(status) {
|
||||||
if($('body').hasClass('loggedIn') == false || this.ownerOrAdmin(status) == false) {
|
if($('body').hasClass('loggedIn') == false || this.ownerOrAdmin(status) == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -841,8 +897,8 @@
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
this.feed = this.feed.filter(s => {
|
this.feed = this.feed.filter(s => {
|
||||||
return s.id != status.id;
|
return s.id != status.id;
|
||||||
})
|
});
|
||||||
swal('Success', 'You have successfully deleted this post', 'success');
|
this.$refs.ctxModal.hide();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
swal('Error', 'Something went wrong. Please try again later.', 'error');
|
swal('Error', 'Something went wrong. Please try again later.', 'error');
|
||||||
});
|
});
|
||||||
|
@ -916,6 +972,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'unlisted':
|
case 'unlisted':
|
||||||
msg = 'Are you sure you want to unlist from timelines for ' + username + ' ?';
|
msg = 'Are you sure you want to unlist from timelines for ' + username + ' ?';
|
||||||
swal({
|
swal({
|
||||||
|
@ -1073,8 +1130,8 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
lightbox(src) {
|
lightbox(status) {
|
||||||
this.lightboxMedia = src;
|
this.lightboxMedia = status.media_attachments[0];
|
||||||
this.$refs.lightboxModal.show();
|
this.$refs.lightboxModal.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1114,13 +1171,26 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
followModalAction(id, index, type = 'following') {
|
followAction(status) {
|
||||||
|
let id = status.account.id;
|
||||||
|
|
||||||
axios.post('/i/follow', {
|
axios.post('/i/follow', {
|
||||||
item: id
|
item: id
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if(type == 'following') {
|
this.feed.forEach(s => {
|
||||||
this.following.splice(index, 1);
|
if(s.account.id == id) {
|
||||||
|
s.account.relationship.following = !s.account.relationship.following;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let username = status.account.acct;
|
||||||
|
|
||||||
|
if(status.account.relationship.following) {
|
||||||
|
swal('Follow successful!', 'You are now following ' + username, 'success');
|
||||||
|
} else {
|
||||||
|
swal('Unfollow successful!', 'You are no longer following ' + username, 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
if(err.response.data.message) {
|
if(err.response.data.message) {
|
||||||
swal('Error', err.response.data.message, 'error');
|
swal('Error', err.response.data.message, 'error');
|
||||||
|
@ -1190,7 +1260,6 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchHashtagPosts() {
|
fetchHashtagPosts() {
|
||||||
|
|
||||||
axios.get('/api/local/discover/tag/list')
|
axios.get('/api/local/discover/tag/list')
|
||||||
.then(res => {
|
.then(res => {
|
||||||
let tags = res.data;
|
let tags = res.data;
|
||||||
|
@ -1210,7 +1279,6 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ctxMenu(status) {
|
ctxMenu(status) {
|
||||||
|
@ -1255,9 +1323,16 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
ctxMenuFollow() {
|
ctxMenuFollow() {
|
||||||
|
let id = this.ctxMenuStatus.account.id;
|
||||||
axios.post('/i/follow', {
|
axios.post('/i/follow', {
|
||||||
item: this.ctxMenuStatus.account.id
|
item: id
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
|
this.feed.forEach(s => {
|
||||||
|
if(s.account.id == id) {
|
||||||
|
s.account.relationship.following = !s.account.relationship.following;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let username = this.ctxMenuStatus.account.acct;
|
let username = this.ctxMenuStatus.account.acct;
|
||||||
this.closeCtxMenu();
|
this.closeCtxMenu();
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
@ -1267,10 +1342,21 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
ctxMenuUnfollow() {
|
ctxMenuUnfollow() {
|
||||||
|
let id = this.ctxMenuStatus.account.id;
|
||||||
axios.post('/i/follow', {
|
axios.post('/i/follow', {
|
||||||
item: this.ctxMenuStatus.account.id
|
item: id
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
|
this.feed.forEach(s => {
|
||||||
|
if(s.account.id == id) {
|
||||||
|
s.account.relationship.following = !s.account.relationship.following;
|
||||||
|
}
|
||||||
|
});
|
||||||
let username = this.ctxMenuStatus.account.acct;
|
let username = this.ctxMenuStatus.account.acct;
|
||||||
|
if(this.scope == 'home') {
|
||||||
|
this.feed = this.feed.filter(s => {
|
||||||
|
return s.account.id != this.ctxMenuStatus.account.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
this.closeCtxMenu();
|
this.closeCtxMenu();
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
swal('Unfollow successful!', 'You are no longer following ' + username, 'success');
|
swal('Unfollow successful!', 'You are no longer following ' + username, 'success');
|
||||||
|
@ -1300,6 +1386,26 @@
|
||||||
ctxCopyEmbed() {
|
ctxCopyEmbed() {
|
||||||
navigator.clipboard.writeText(this.ctxEmbedPayload);
|
navigator.clipboard.writeText(this.ctxEmbedPayload);
|
||||||
this.$refs.ctxEmbedModal.hide();
|
this.$refs.ctxEmbedModal.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
ctxModMenuShow() {
|
||||||
|
this.$refs.ctxModal.hide();
|
||||||
|
this.$refs.ctxModModal.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
ctxModMenu() {
|
||||||
|
this.$refs.ctxModal.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
ctxModMenuClose() {
|
||||||
|
this.$refs.ctxModal.hide();
|
||||||
|
this.$refs.ctxModModal.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideTips() {
|
||||||
|
this.showTips = false;
|
||||||
|
let ls = window.localStorage;
|
||||||
|
ls.setItem('metro-tips', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue