From a10d851fb7d3b50bf730066f5e5703da43b8a63e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 13 Dec 2020 22:54:24 -0700 Subject: [PATCH] Update PostComponent, add reply modal --- .../assets/js/components/PostComponent.vue | 433 ++++++++++++++---- resources/assets/js/components/PostMenu.vue | 31 +- resources/assets/js/components/Timeline.vue | 15 +- 3 files changed, 350 insertions(+), 129 deletions(-) diff --git a/resources/assets/js/components/PostComponent.vue b/resources/assets/js/components/PostComponent.vue index b35292490..cdea3e58a 100644 --- a/resources/assets/js/components/PostComponent.vue +++ b/resources/assets/js/components/PostComponent.vue @@ -35,24 +35,10 @@
-
@@ -108,30 +94,16 @@
-
-
+
@@ -227,7 +199,12 @@
-
+
+
+ Loading... +
+
+

@@ -252,18 +229,13 @@
-
@@ -271,9 +243,6 @@
-

More posts from {{this.statusUsername}}

@@ -474,6 +443,7 @@
+ + body-class="list-group-flush py-3 px-0">
-
+

Learn more about Tagging People.

+ +
+
Unfollow
+
Follow
+
Embed
+
Copy Link
+
{{ showComments ? 'Disable' : 'Enable'}} Comments
+ Edit +
ModTools
+
Block
+
Unblock
+ Report +
Delete
+
Cancel
+
+
+ +
+
{{ showComments ? 'Disable' : 'Enable'}} Comments
+ +
Unlist from Timelines
+
Remove Content Warning
+
Add Content Warning
+
Cancel
+
+
+ +
+ + +
+ +
+
+
+ + {{replyText.length > config.uploader.max_caption_length ? config.uploader.max_caption_length - replyText.length : replyText.length}}/{{config.uploader.max_caption_length}} + +
+
+
+ + +
+ + +
+
+
+
@@ -742,6 +794,7 @@ export default { loaded: false, loading: null, replyingToId: this.statusId, + replyingToUsername: this.statusUsername, replyToIndex: 0, replySending: false, emoji: window.App.util.emoji, @@ -753,9 +806,10 @@ export default { ctxEmbedShowLikes: false, ctxEmbedCompactMode: false, layout: this.profileLayout, - canEdit: false, showProfileMorePosts: false, - profileMorePosts: [] + profileMorePosts: [], + replySending: false, + reactionBarLoading: true, } }, watch: { @@ -811,16 +865,6 @@ export default { }, methods: { - showMuteBlock() { - let sid = this.status.account.id; - let uid = this.user.id; - if(sid == uid) { - $('.post-actions .menu-author').removeClass('d-none'); - } else { - $('.post-actions .menu-user').removeClass('d-none'); - } - }, - reportUrl() { return '/i/report?type=post&id=' + this.status.id; }, @@ -839,33 +883,20 @@ export default { axios.get('/api/v2/profile/'+this.statusUsername+'/status/'+this.statusId) .then(response => { self.status = response.data.status; - self.user = response.data.user; - window._sharedData.curUser = self.user; - window.App.util.navatar(); self.media = self.status.media_attachments; - self.reactions = response.data.reactions; - self.likes = response.data.likes; - self.shares = response.data.shares; self.likesPage = 2; self.sharesPage = 2; - this.showMuteBlock(); self.showCaption = !response.data.status.sensitive; if(self.status.comments_disabled == false) { self.showComments = true; this.fetchComments(); } - if(this.ownerOrAdmin()) { - let od = new Date(this.status.created_at).getTime() + (1 * 24 * 60 * 60 * 1000); - let now = new Date().getTime(); - if(od > now) { - this.canEdit = true; - } - } this.loaded = true; setTimeout(function() { self.fetchProfilePosts(); }, 3000); setTimeout(function() { + self.fetchState(); document.querySelectorAll('.status-comment .comment-text a').forEach(function(i, e) { if(i.href.startsWith(window.location.origin)) { return; @@ -882,6 +913,20 @@ export default { }); }, + fetchState() { + let self = this; + axios.get('/api/v2/profile/'+this.statusUsername+'/status/'+this.statusId+'/state') + .then(res => { + self.user = res.data.user; + window._sharedData.curUser = self.user; + window.App.util.navatar(); + self.likes = res.data.likes; + self.shares = res.data.shares; + self.reactions = res.data.reactions; + self.reactionBarLoading = false; + }); + }, + likesModal() { if($('body').hasClass('loggedIn') == false) { window.location.href = '/login?next=' + encodeURIComponent('/p/' + this.status.shortcode); @@ -890,14 +935,31 @@ export default { if(this.status.favourites_count == 0) { return; } - this.$refs.likesModal.show(); + if(this.likes.length) { + this.$refs.likesModal.show(); + return; + } + axios.get('/api/v2/likes/profile/'+this.statusUsername+'/status/'+this.statusId) + .then(res => { + this.likes = res.data.data; + this.$refs.likesModal.show(); + }); }, sharesModal() { if(this.status.reblogs_count == 0 || $('body').hasClass('loggedIn') == false) { + window.location.href = '/login?next=' + encodeURIComponent('/p/' + this.status.shortcode); return; } - this.$refs.sharesModal.show(); + if(this.shares.length) { + this.$refs.sharesModal.show(); + return; + } + axios.get('/api/v2/shares/profile/'+this.statusUsername+'/status/'+this.statusId) + .then(res => { + this.shares = res.data.data; + this.$refs.sharesModal.show(); + }); }, infiniteLikesHandler($state) { @@ -1010,21 +1072,6 @@ export default { }); }, - muteProfile() { - if($('body').hasClass('loggedIn') == false) { - return; - } - - axios.post('/i/mute', { - type: 'user', - item: this.status.account.id - }).then(res => { - swal('Success', 'You have successfully muted ' + this.status.account.acct, 'success'); - }).catch(err => { - swal('Error', 'Something went wrong. Please try again later.', 'error'); - }); - }, - blockProfile() { if($('body').hasClass('loggedIn') == false) { return; @@ -1034,12 +1081,31 @@ export default { type: 'user', item: this.status.account.id }).then(res => { + this.$refs.ctxModal.hide(); + this.relationship.blocking = true; swal('Success', 'You have successfully blocked ' + this.status.account.acct, 'success'); }).catch(err => { swal('Error', 'Something went wrong. Please try again later.', 'error'); }); }, + unblockProfile() { + if($('body').hasClass('loggedIn') == false) { + return; + } + + axios.post('/i/unblock', { + type: 'user', + item: this.status.account.id + }).then(res => { + this.relationship.blocking = false; + this.$refs.ctxModal.hide(); + swal('Success', 'You have successfully unblocked ' + this.status.account.acct, 'success'); + }).catch(err => { + swal('Error', 'Something went wrong. Please try again later.', 'error'); + }); + }, + deletePost(status) { if(!this.ownerOrAdmin()) { return; @@ -1082,6 +1148,7 @@ export default { postReply() { let self = this; + this.replySending = true; if(this.replyText.length == 0 || this.replyText.trim() == '@'+this.status.account.acct) { self.replyText = null; @@ -1106,7 +1173,7 @@ export default { self.results.unshift(entity); } let elem = $('.status-comments')[0]; - elem.scrollTop = elem.clientHeight; + elem.scrollTop = elem.clientHeight * 2; } else { if(self.replyToIndex >= 0) { let el = self.results[self.replyToIndex]; @@ -1114,6 +1181,8 @@ export default { el.reply_count = el.reply_count + 1; } } + self.$refs.replyModal.hide(); + self.replySending = false; }); }, @@ -1147,15 +1216,25 @@ export default { }, replyFocus(e, index, prependUsername = false) { + if($('body').hasClass('loggedIn') == false) { + this.redirect('/login?next=' + encodeURIComponent(window.location.pathname)); + return; + } + + if(this.status.comments_disabled) { + return; + } + this.replyToIndex = index; this.replyingToId = e.id; + this.replyingToUsername = e.account.username; this.reply_to_profile_id = e.account.id; let username = e.account.local ? '@' + e.account.username + ' ' : '@' + e.account.acct + ' '; if(prependUsername == true) { this.replyText = username; } - $('textarea[name="comment"]').focus(); + this.$refs.replyModal.show(); }, fetchComments() { @@ -1289,7 +1368,9 @@ export default { item: self.status.id, disableComments: false }).then(function(res) { - window.location.href = self.status.url; + self.status.comments_disabled = false; + self.$refs.ctxModal.hide(); + window.location.reload(); }).catch(function(err) { return; }); @@ -1299,8 +1380,9 @@ export default { item: self.status.id, disableComments: true }).then(function(res) { - self.status.comments_disabled = false; + self.status.comments_disabled = true; self.showComments = false; + self.$refs.ctxModal.hide(); }).catch(function(err) { return; }); @@ -1374,6 +1456,7 @@ export default { showEmbedPostModal() { let mode = this.ctxEmbedCompactMode ? 'compact' : 'full'; this.ctxEmbedPayload = window.App.util.embed.post(this.status.url, this.ctxEmbedShowCaption, this.ctxEmbedShowLikes, mode); + this.$refs.ctxModal.hide(); this.$refs.embedModal.show(); }, @@ -1461,10 +1544,166 @@ export default { swal('An Error Occurred', 'Please try again later.', 'error'); }); }, + copyPostUrl() { navigator.clipboard.writeText(this.statusUrl); return; - } + }, + + moderatePost(action, $event) { + let status = this.status; + let username = status.account.username; + let msg = ''; + let self = this; + switch(action) { + case 'addcw': + msg = 'Are you sure you want to add a content warning to this post?'; + swal({ + title: 'Confirm', + text: msg, + icon: 'warning', + buttons: true, + dangerMode: true + }).then(res => { + if(res) { + axios.post('/api/v2/moderator/action', { + action: action, + item_id: status.id, + item_type: 'status' + }).then(res => { + swal('Success', 'Successfully added content warning', 'success'); + status.sensitive = true; + self.ctxModMenuClose(); + }).catch(err => { + swal( + 'Error', + 'Something went wrong, please try again later.', + 'error' + ); + self.ctxModMenuClose(); + }); + } + }); + break; + + case 'remcw': + msg = 'Are you sure you want to remove the content warning on this post?'; + swal({ + title: 'Confirm', + text: msg, + icon: 'warning', + buttons: true, + dangerMode: true + }).then(res => { + if(res) { + axios.post('/api/v2/moderator/action', { + action: action, + item_id: status.id, + item_type: 'status' + }).then(res => { + swal('Success', 'Successfully added content warning', 'success'); + status.sensitive = false; + self.ctxModMenuClose(); + }).catch(err => { + swal( + 'Error', + 'Something went wrong, please try again later.', + 'error' + ); + self.ctxModMenuClose(); + }); + } + }); + break; + + case 'unlist': + msg = 'Are you sure you want to unlist this post?'; + swal({ + title: 'Confirm', + text: msg, + icon: 'warning', + buttons: true, + dangerMode: true + }).then(res => { + if(res) { + axios.post('/api/v2/moderator/action', { + action: action, + item_id: status.id, + item_type: 'status' + }).then(res => { + // this.feed = this.feed.filter(f => { + // return f.id != status.id; + // }); + swal('Success', 'Successfully unlisted post', 'success'); + self.ctxModMenuClose(); + }).catch(err => { + self.ctxModMenuClose(); + swal( + 'Error', + 'Something went wrong, please try again later.', + 'error' + ); + }); + } + }); + break; + } + }, + + ctxMenu() { + this.$refs.ctxModal.show(); + return; + }, + + closeCtxMenu(truncate) { + this.$refs.ctxModal.hide(); + }, + + ctxModMenu() { + this.$refs.ctxModal.hide(); + this.$refs.ctxModModal.show(); + }, + + ctxModMenuClose() { + this.$refs.ctxModal.hide(); + this.$refs.ctxModModal.hide(); + }, + + ctxMenuCopyLink() { + let status = this.status; + navigator.clipboard.writeText(status.url); + this.closeCtxMenu(); + return; + }, + + ctxMenuFollow() { + let id = this.status.account.id; + axios.post('/i/follow', { + item: id + }).then(res => { + let username = this.status.account.acct; + this.relationship.following = true; + this.$refs.ctxModal.hide(); + setTimeout(function() { + swal('Follow successful!', 'You are now following ' + username, 'success'); + }, 500); + }); + }, + + ctxMenuUnfollow() { + let id = this.status.account.id; + axios.post('/i/follow', { + item: id + }).then(res => { + let username = this.status.account.acct; + this.relationship.following = false; + this.$refs.ctxModal.hide(); + setTimeout(function() { + swal('Unfollow successful!', 'You are no longer following ' + username, 'success'); + }, 500); + }); + }, + }, } diff --git a/resources/assets/js/components/PostMenu.vue b/resources/assets/js/components/PostMenu.vue index 771dc4733..a4d12d866 100644 --- a/resources/assets/js/components/PostMenu.vue +++ b/resources/assets/js/components/PostMenu.vue @@ -57,35 +57,8 @@ Hide - Report - Mute Profile - Block Profile - - Delete - - - -

Enforce CW

-

Adds a CW to every post
made by this account.

-
- -

No Autolinking

-

Do not transform mentions,
hashtags or urls into HTML.

-
- -

Unlisted Posts

-

Removes account from
public/network timelines.

-
- -

Disable Account

-

Temporarily disable account
until next time user log in.

-
- -

Suspend Account

-

This prevents any new interactions,
without deleting existing data.

-
- -
+ Report +
Delete
diff --git a/resources/assets/js/components/Timeline.vue b/resources/assets/js/components/Timeline.vue index 8e102feb0..62d555940 100644 --- a/resources/assets/js/components/Timeline.vue +++ b/resources/assets/js/components/Timeline.vue @@ -438,11 +438,11 @@ size="sm" body-class="list-group-flush p-0 rounded">
-
Report inappropriate
+
Report
Unfollow
Follow
Go to post
-
Embed
+
Embed
Copy Link
Moderation Tools
@@ -558,6 +558,10 @@
+
+ + +