From 296ab5430147f01107131046dcd428085bef9020 Mon Sep 17 00:00:00 2001 From: scarlett <nia@netbsd.org> Date: Fri, 24 Aug 2018 20:04:26 +0100 Subject: [PATCH] Add settings for changing the visibility of replies in the timeline. --- src/components/settings/settings.js | 4 +++ src/components/settings/settings.vue | 10 +++++++ src/components/status/status.js | 42 ++++++++++++++++++++++++++++ src/components/status/status.vue | 2 +- src/i18n/messages.js | 3 ++ src/main.js | 1 + src/modules/config.js | 1 + 7 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index c85ef59f..d5ca33cc 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -8,6 +8,7 @@ const settings = { hideAttachmentsLocal: this.$store.state.config.hideAttachments, hideAttachmentsInConvLocal: this.$store.state.config.hideAttachmentsInConv, hideNsfwLocal: this.$store.state.config.hideNsfw, + replyVisibilityLocal: this.$store.state.config.replyVisibility, loopVideoLocal: this.$store.state.config.loopVideo, loopVideoSilentOnlyLocal: this.$store.state.config.loopVideoSilentOnly, muteWordsString: this.$store.state.config.muteWords.join('\n'), @@ -44,6 +45,9 @@ const settings = { hideNsfwLocal (value) { this.$store.dispatch('setOption', { name: 'hideNsfw', value }) }, + replyVisibilityLocal (value) { + this.$store.dispatch('setOption', { name: 'replyVisibility', value }) + }, loopVideoLocal (value) { this.$store.dispatch('setOption', { name: 'loopVideo', value }) }, diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 415317f0..9612876e 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -38,6 +38,16 @@ <input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal"> <label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label> </li> + <li> + <label for="replyVisibility" class="select"> + <select id="replyVisibility" v-model="replyVisibilityLocal"> + <option value="all" selected>{{$t('settings.reply_visibility_all')}}</option> + <option value="following">{{$t('settings.reply_visibility_following')}}</option> + <option value="self">{{$t('settings.reply_visibility_self')}}</option> + </select> + <i class="icon-down-open"/> + </label> + </li> </ul> </div> <div class="setting-item"> diff --git a/src/components/status/status.js b/src/components/status/status.js index 9670f69d..a6cb6b6f 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -105,6 +105,48 @@ const Status = { const lengthScore = this.status.statusnet_html.split(/<p|<br/).length + this.status.text.length / 80 return lengthScore > 20 }, + isReply () { + if (this.status.in_reply_to_status_id) { + return true + } + // For private replies where we can't see the OP, in_reply_to_status_id will be null. + // So instead, check that the post starts with a @mention. + if (this.status.visibility === 'private') { + var textBody = this.status.text + if (this.status.summary !== null) { + textBody = textBody.substring(this.status.summary.length, textBody.length) + } + return textBody.startsWith('@') + } + return false + }, + hideReply () { + if (this.$store.state.config.replyVisibility === 'all') { + return false + } + if (this.inlineExpanded || this.expanded || !this.isReply) { + return false + } + if (this.status.user.id === this.$store.state.users.currentUser.id) { + return false + } + if (this.status.activity_type === 'repeat') { + return false + } + var checkFollowing = this.$store.state.config.replyVisibility === 'following' + for (var i = 0; i < this.status.attentions.length; ++i) { + if (this.status.user.id === this.status.attentions[i].id) { + continue + } + if (checkFollowing && this.status.attentions[i].following) { + return false + } + if (this.status.attentions[i].id === this.$store.state.users.currentUser.id) { + return false + } + } + return this.status.attentions.length > 0 + }, hideSubjectStatus () { if (this.tallStatus && !this.$store.state.config.collapseMessageWithSubject) { return false diff --git a/src/components/status/status.vue b/src/components/status/status.vue index e7d5ed7a..2bc44ee7 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -1,5 +1,5 @@ <template> - <div class="status-el" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]"> + <div class="status-el" v-if="!hideReply" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]"> <template v-if="muted && !noReplyLinks"> <div class="media status container muted"> <small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small> diff --git a/src/i18n/messages.js b/src/i18n/messages.js index 04460ecc..a86ac3ea 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -325,6 +325,9 @@ const en = { loop_video: 'Loop videos', loop_video_silent_only: 'Loop only videos without sound (i.e. Mastodon\'s "gifs")', reply_link_preview: 'Enable reply-link preview on mouse hover', + reply_visibility_all: 'Show all replies', + reply_visibility_following: 'Only show replies directed at me or users I\'m following', + reply_visibility_self: 'Only show replies directed at me', follow_import: 'Follow import', import_followers_from_a_csv_file: 'Import follows from a csv file', follows_imported: 'Follows imported! Processing them will take a while.', diff --git a/src/main.js b/src/main.js index 4124214d..1648d847 100644 --- a/src/main.js +++ b/src/main.js @@ -49,6 +49,7 @@ const persistedStateOptions = { 'config.hideAttachments', 'config.hideAttachmentsInConv', 'config.hideNsfw', + 'config.replyVisibility', 'config.autoLoad', 'config.hoverPreview', 'config.streaming', diff --git a/src/modules/config.js b/src/modules/config.js index 60210a95..45bb1465 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -15,6 +15,7 @@ const defaultState = { hoverPreview: true, pauseOnUnfocused: true, stopGifs: false, + replyVisibility: 'all', muteWords: [], highlight: {} }