From 09fe160e8b9fad7a8c70e44ae894d67211b993e1 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Fri, 26 Feb 2021 16:23:11 +0200
Subject: separate screen_name and screen_name_ui with decoded punycode

---
 src/components/notification/notification.vue | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'src/components/notification/notification.vue')

diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index f56aa977..0081dee4 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -11,7 +11,7 @@
     >
       <small>
         <router-link :to="userProfileLink">
-          {{ notification.from_profile.screen_name }}
+          {{ notification.from_profile.screen_name_ui }}
         </router-link>
       </small>
       <button
@@ -54,14 +54,14 @@
             <bdi
               v-if="!!notification.from_profile.name_html"
               class="username"
-              :title="'@'+notification.from_profile.screen_name"
+              :title="'@'+notification.from_profile.screen_name_ui"
               v-html="notification.from_profile.name_html"
             />
             <!-- eslint-enable vue/no-v-html -->
             <span
               v-else
               class="username"
-              :title="'@'+notification.from_profile.screen_name"
+              :title="'@'+notification.from_profile.screen_name_ui"
             >{{ notification.from_profile.name }}</span>
             <span v-if="notification.type === 'like'">
               <FAIcon
@@ -152,7 +152,7 @@
             :to="userProfileLink"
             class="follow-name"
           >
-            @{{ notification.from_profile.screen_name }}
+            @{{ notification.from_profile.screen_name_ui }}
           </router-link>
           <div
             v-if="notification.type === 'follow_request'"
@@ -177,7 +177,7 @@
           class="move-text"
         >
           <router-link :to="targetUserProfileLink">
-            @{{ notification.target.screen_name }}
+            @{{ notification.target.screen_name_ui }}
           </router-link>
         </div>
         <template v-else>
-- 
cgit v1.2.3-70-g09d2


From b87a9d6675cf7cd8d37d45e62013fab27cbc46e6 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 8 Jun 2021 16:14:01 +0300
Subject: Rearranged settings, moved more stuff to filtering where apllicable.
 Changed how filering works.

---
 src/components/notification/notification.scss      |   6 +
 src/components/notification/notification.vue       |   1 +
 src/components/notifications/notifications.scss    |   5 -
 .../settings_modal/tabs/filtering_tab.vue          | 195 ++++++++++++++-------
 src/components/settings_modal/tabs/general_tab.vue | 154 ++++++----------
 src/components/status/status.js                    |  44 +++--
 src/components/timeline/timeline_quick_settings.js |   3 +-
 src/i18n/en.json                                   |  14 +-
 src/modules/config.js                              |   2 +
 src/modules/instance.js                            |   3 +
 10 files changed, 242 insertions(+), 185 deletions(-)

(limited to 'src/components/notification/notification.vue')

diff --git a/src/components/notification/notification.scss b/src/components/notification/notification.scss
index f5905560..e075747b 100644
--- a/src/components/notification/notification.scss
+++ b/src/components/notification/notification.scss
@@ -2,6 +2,12 @@
 
 // TODO Copypaste from Status, should unify it somehow
 .Notification {
+  border-bottom: 1px solid;
+  border-color: $fallback--border;
+  border-color: var(--border, $fallback--border);
+  word-wrap: break-word;
+  word-break: break-word;
+
   &.-muted {
     padding: 0.25em 0.6em;
     height: 1.2em;
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 0081dee4..fb324cec 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -1,6 +1,7 @@
 <template>
   <Status
     v-if="notification.type === 'mention'"
+    class="Notification"
     :compact="true"
     :statusoid="notification.status"
   />
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 2bb627a8..b513d8b5 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -37,11 +37,6 @@
 
 .notification {
   box-sizing: border-box;
-  border-bottom: 1px solid;
-  border-color: $fallback--border;
-  border-color: var(--border, $fallback--border);
-  word-wrap: break-word;
-  word-break: break-word;
 
   &:hover .animated.Avatar {
     canvas {
diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue
index 6fc9ceaa..5d3c614a 100644
--- a/src/components/settings_modal/tabs/filtering_tab.vue
+++ b/src/components/settings_modal/tabs/filtering_tab.vue
@@ -1,73 +1,138 @@
 <template>
   <div :label="$t('settings.filtering')">
     <div class="setting-item">
-      <div class="select-multiple">
-        <span class="label">{{ $t('settings.notification_visibility') }}</span>
-        <ul class="option-list">
-          <li>
-            <BooleanSetting path="notificationVisibility.likes">
-              {{ $t('settings.notification_visibility_likes') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.repeats">
-              {{ $t('settings.notification_visibility_repeats') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.follows">
-              {{ $t('settings.notification_visibility_follows') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.mentions">
-              {{ $t('settings.notification_visibility_mentions') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.moves">
-              {{ $t('settings.notification_visibility_moves') }}
-            </BooleanSetting>
-          </li>
-          <li>
-            <BooleanSetting path="notificationVisibility.emojiReactions">
-              {{ $t('settings.notification_visibility_emoji_reactions') }}
-            </BooleanSetting>
-          </li>
-        </ul>
-      </div>
-      <ChoiceSetting
-        id="replyVisibility"
-        path="replyVisibility"
-        :options="replyVisibilityOptions"
-      >
-        {{ $t('settings.replies_in_timeline') }}
-      </ChoiceSetting>
-      <div>
-        <BooleanSetting path="hidePostStats">
-          {{ $t('settings.hide_post_stats') }}
-        </BooleanSetting>
-      </div>
-      <div>
-        <BooleanSetting path="hideUserStats">
-          {{ $t('settings.hide_user_stats') }}
-        </BooleanSetting>
-      </div>
+      <h2>{{ $t('settings.posts') }}</h2>
+      <ul class="setting-list">
+        <li>
+          <BooleanSetting path="hideFilteredStatuses">
+            {{ $t('settings.hide_filtered_statuses') }}
+          </BooleanSetting>
+          <ul
+            class="setting-list suboptions"
+            :class="[{disabled: !streaming}]"
+          >
+            <li>
+              <BooleanSetting
+                :disabled="hideFilteredStatuses"
+                path="hideWordFilteredPosts"
+              >
+                {{ $t('settings.hide_wordfiltered_statuses') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting
+                :disabled="hideFilteredStatuses"
+                path="hideMutedThreads"
+              >
+                {{ $t('settings.hide_muted_threads') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting
+                :disabled="hideFilteredStatuses"
+                path="hideMutedPosts"
+                >
+                {{ $t('settings.hide_muted_posts') }}
+              </BooleanSetting>
+            </li>
+          </ul>
+        </li>
+        <li>
+          <BooleanSetting path="hidePostStats">
+            {{ $t('settings.hide_post_stats') }}
+          </BooleanSetting>
+        </li>
+        <ChoiceSetting
+          id="replyVisibility"
+          path="replyVisibility"
+          :options="replyVisibilityOptions"
+        >
+          {{ $t('settings.replies_in_timeline') }}
+        </ChoiceSetting>
+        <li>
+          <h3>{{ $t('settings.wordfilter') }}</h3>
+          <textarea
+            id="muteWords"
+            v-model="muteWordsString"
+            class="resize-height"
+          />
+          <div>{{ $t('settings.filtering_explanation') }}</div>
+        </li>
+        <h3>{{ $t('settings.attachments') }}</h3>
+        <li>
+          <label for="maxThumbnails">
+            {{ $t('settings.max_thumbnails') }}
+          </label>
+          <input
+            id="maxThumbnails"
+            path.number="maxThumbnails"
+            class="number-input"
+            type="number"
+            min="0"
+            step="1"
+          >
+        </li>
+        <li>
+          <BooleanSetting path="hideAttachments">
+            {{ $t('settings.hide_attachments_in_tl') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="hideAttachmentsInConv">
+            {{ $t('settings.hide_attachments_in_convo') }}
+          </BooleanSetting>
+        </li>
+      </ul>
     </div>
     <div class="setting-item">
-      <div>
-        <p>{{ $t('settings.filtering_explanation') }}</p>
-        <textarea
-          id="muteWords"
-          v-model="muteWordsString"
-          class="resize-height"
-        />
-      </div>
-      <div>
-        <BooleanSetting path="hideFilteredStatuses">
-          {{ $t('settings.hide_filtered_statuses') }}
-        </BooleanSetting>
-      </div>
+      <h2>{{ $t('settings.user_profiles') }}</h2>
+      <ul class="setting-list">
+        <li>
+          <BooleanSetting path="hideUserStats">
+            {{ $t('settings.hide_user_stats') }}
+          </BooleanSetting>
+        </li>
+      </ul>
+    </div>
+    <div class="setting-item">
+      <h2>{{ $t('settings.notifications') }}</h2>
+      <ul class="setting-list">
+        <li class="select-multiple">
+          <span class="label">{{ $t('settings.notification_visibility') }}</span>
+          <ul class="option-list">
+            <li>
+              <BooleanSetting path="notificationVisibility.likes">
+                {{ $t('settings.notification_visibility_likes') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.repeats">
+                {{ $t('settings.notification_visibility_repeats') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.follows">
+                {{ $t('settings.notification_visibility_follows') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.mentions">
+                {{ $t('settings.notification_visibility_mentions') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.moves">
+                {{ $t('settings.notification_visibility_moves') }}
+              </BooleanSetting>
+            </li>
+            <li>
+              <BooleanSetting path="notificationVisibility.emojiReactions">
+                {{ $t('settings.notification_visibility_emoji_reactions') }}
+              </BooleanSetting>
+            </li>
+          </ul>
+        </li>
+      </ul>
     </div>
   </div>
 </template>
diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue
index bdb29edf..5243d336 100644
--- a/src/components/settings_modal/tabs/general_tab.vue
+++ b/src/components/settings_modal/tabs/general_tab.vue
@@ -21,19 +21,9 @@
             {{ $t('settings.hide_wallpaper') }}
           </BooleanSetting>
         </li>
-      </ul>
-    </div>
-    <div class="setting-item">
-      <h2>{{ $t('nav.timeline') }}</h2>
-      <ul class="setting-list">
         <li>
-          <BooleanSetting path="hideMutedPosts">
-            {{ $t('settings.hide_muted_posts') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <BooleanSetting path="collapseMessageWithSubject">
-            {{ $t('settings.collapse_subject') }}
+          <BooleanSetting path="stopGifs">
+            {{ $t('settings.stop_gifs') }}
           </BooleanSetting>
         </li>
         <li>
@@ -63,98 +53,36 @@
             </small>
           </BooleanSetting>
         </li>
-        <li>
-          <BooleanSetting path="emojiReactionsOnTimeline">
-            {{ $t('settings.emoji_reactions_on_timeline') }}
-          </BooleanSetting>
-        </li>
         <li>
           <BooleanSetting path="virtualScrolling">
             {{ $t('settings.virtual_scrolling') }}
           </BooleanSetting>
         </li>
-      </ul>
-    </div>
-
-    <div class="setting-item">
-      <h2>{{ $t('settings.composing') }}</h2>
-      <ul class="setting-list">
-        <li>
-          <BooleanSetting path="scopeCopy">
-            {{ $t('settings.scope_copy') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <BooleanSetting path="alwaysShowSubjectInput">
-            {{ $t('settings.subject_input_always_show') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <ChoiceSetting
-            id="subjectLineBehavior"
-            path="subjectLineBehavior"
-            :options="subjectLineOptions"
-          >
-            {{ $t('settings.subject_line_behavior') }}
-          </ChoiceSetting>
-        </li>
-        <li v-if="postFormats.length > 0">
-          <ChoiceSetting
-            id="postContentType"
-            path="postContentType"
-            :options="postContentOptions"
-          >
-            {{ $t('settings.post_status_content_type') }}
-          </ChoiceSetting>
-        </li>
-        <li>
-          <BooleanSetting path="minimalScopesMode">
-            {{ $t('settings.minimal_scopes_mode') }}
-          </BooleanSetting>
-        </li>
-        <li>
-          <BooleanSetting path="sensitiveByDefault">
-            {{ $t('settings.sensitive_by_default') }}
-          </BooleanSetting>
-        </li>
         <li>
           <BooleanSetting path="autohideFloatingPostButton">
             {{ $t('settings.autohide_floating_post_button') }}
           </BooleanSetting>
         </li>
-        <li>
-          <BooleanSetting path="padEmoji">
-            {{ $t('settings.pad_emoji') }}
-          </BooleanSetting>
-        </li>
       </ul>
     </div>
-
     <div class="setting-item">
-      <h2>{{ $t('settings.attachments') }}</h2>
+      <h2>{{ $t('settings.post_look_feel') }}</h2>
       <ul class="setting-list">
         <li>
-          <BooleanSetting path="hideAttachments">
-            {{ $t('settings.hide_attachments_in_tl') }}
+          <BooleanSetting path="collapseMessageWithSubject">
+            {{ $t('settings.collapse_subject') }}
           </BooleanSetting>
         </li>
         <li>
-          <BooleanSetting path="hideAttachmentsInConv">
-            {{ $t('settings.hide_attachments_in_convo') }}
+          <BooleanSetting path="emojiReactionsOnTimeline">
+            {{ $t('settings.emoji_reactions_on_timeline') }}
           </BooleanSetting>
         </li>
+        <h3>{{ $t('settings.attachments') }}</h3>
         <li>
-          <label for="maxThumbnails">
-            {{ $t('settings.max_thumbnails') }}
-          </label>
-          <input
-            id="maxThumbnails"
-            path.number="maxThumbnails"
-            class="number-input"
-            type="number"
-            min="0"
-            step="1"
-          >
+          <BooleanSetting path="useContainFit">
+            {{ $t('settings.use_contain_fit') }}
+          </BooleanSetting>
         </li>
         <li>
           <BooleanSetting path="hideNsfw">
@@ -179,11 +107,6 @@
             </BooleanSetting>
           </li>
         </ul>
-        <li>
-          <BooleanSetting path="stopGifs">
-            {{ $t('settings.stop_gifs') }}
-          </BooleanSetting>
-        </li>
         <li>
           <BooleanSetting path="loopVideo">
             {{ $t('settings.loop_video') }}
@@ -213,31 +136,70 @@
             {{ $t('settings.play_videos_in_modal') }}
           </BooleanSetting>
         </li>
+        <h3>{{ $t('settings.fun') }}</h3>
         <li>
-          <BooleanSetting path="useContainFit">
-            {{ $t('settings.use_contain_fit') }}
+          <BooleanSetting path="greentext">
+            {{ $t('settings.greentext') }}
           </BooleanSetting>
         </li>
       </ul>
     </div>
 
     <div class="setting-item">
-      <h2>{{ $t('settings.notifications') }}</h2>
+      <h2>{{ $t('settings.composing') }}</h2>
       <ul class="setting-list">
         <li>
-          <BooleanSetting path="webPushNotifications">
-            {{ $t('settings.enable_web_push_notifications') }}
+          <BooleanSetting path="scopeCopy">
+            {{ $t('settings.scope_copy') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="alwaysShowSubjectInput">
+            {{ $t('settings.subject_input_always_show') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <ChoiceSetting
+            id="subjectLineBehavior"
+            path="subjectLineBehavior"
+            :options="subjectLineOptions"
+          >
+            {{ $t('settings.subject_line_behavior') }}
+          </ChoiceSetting>
+        </li>
+        <li v-if="postFormats.length > 0">
+          <ChoiceSetting
+            id="postContentType"
+            path="postContentType"
+            :options="postContentOptions"
+          >
+            {{ $t('settings.post_status_content_type') }}
+          </ChoiceSetting>
+        </li>
+        <li>
+          <BooleanSetting path="minimalScopesMode">
+            {{ $t('settings.minimal_scopes_mode') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="sensitiveByDefault">
+            {{ $t('settings.sensitive_by_default') }}
+          </BooleanSetting>
+        </li>
+        <li>
+          <BooleanSetting path="padEmoji">
+            {{ $t('settings.pad_emoji') }}
           </BooleanSetting>
         </li>
       </ul>
     </div>
 
     <div class="setting-item">
-      <h2>{{ $t('settings.fun') }}</h2>
+      <h2>{{ $t('settings.notifications') }}</h2>
       <ul class="setting-list">
         <li>
-          <BooleanSetting path="greentext">
-            {{ $t('settings.greentext') }}
+          <BooleanSetting path="webPushNotifications">
+            {{ $t('settings.enable_web_push_notifications') }}
           </BooleanSetting>
         </li>
       </ul>
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 470c01f1..5c7caa28 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -157,26 +157,32 @@ const Status = {
       return muteWordHits(this.status, this.muteWords)
     },
     muted () {
+      if (this.statusoid.user.id === this.currentUser.id) return false
+      const reasonsToMute = this.userIsMuted ||
+        // Thread is muted
+        status.thread_muted ||
+        // Wordfiltered
+        this.muteWordHits.length > 0
+      return !this.unmuted && !this.shouldNotMute && reasonsToMute
+    },
+    userIsMuted () {
       if (this.statusoid.user.id === this.currentUser.id) return false
       const { status } = this
       const { reblog } = status
       const relationship = this.$store.getters.relationship(status.user.id)
       const relationshipReblog = reblog && this.$store.getters.relationship(reblog.user.id)
-      const reasonsToMute = (
-        // Post is muted according to BE
-        status.muted ||
+      return status.muted ||
         // Reprööt of a muted post according to BE
         (reblog && reblog.muted) ||
         // Muted user
         relationship.muting ||
         // Muted user of a reprööt
-        (relationshipReblog && relationshipReblog.muting) ||
-        // Thread is muted
-        status.thread_muted ||
-        // Wordfiltered
-        this.muteWordHits.length > 0
-      )
-      const excusesNotToMute = (
+        (relationshipReblog && relationshipReblog.muting)
+    },
+    shouldNotMute () {
+      const { status } = this
+      const { reblog } = status
+      return (
         (
           this.inProfile && (
             // Don't mute user's posts on user timeline (except reblogs)
@@ -189,14 +195,26 @@ const Status = {
         (this.inConversation && status.thread_muted)
         // No excuses if post has muted words
       ) && !this.muteWordHits.length > 0
-
-      return !this.unmuted && !excusesNotToMute && reasonsToMute
+    },
+    hideMutedUsers () {
+      return this.mergedConfig.hideMutedPosts
+    },
+    hideMutedThreads () {
+      return this.mergedConfig.hideMutedThreads
     },
     hideFilteredStatuses () {
       return this.mergedConfig.hideFilteredStatuses
     },
+    hideWordFilteredPosts () {
+      return this.mergedConfig.hideWordFilteredPosts
+    },
     hideStatus () {
-      return (this.muted && this.hideFilteredStatuses) || this.virtualHidden
+      return (this.virtualHidden || !this.shouldNotMute) && (
+        (this.muted && this.hideFilteredStatuses) ||
+        (this.userIsMuted && this.hideMutedUsers) ||
+        (this.status.thread_muted && this.hideMutedThreads) ||
+        (this.muteWordHits.length > 0 && this.hideWordFilteredPosts)
+      )
     },
     isFocused () {
       // retweet or root of an expanded conversation
diff --git a/src/components/timeline/timeline_quick_settings.js b/src/components/timeline/timeline_quick_settings.js
index eae65a55..7b4931ce 100644
--- a/src/components/timeline/timeline_quick_settings.js
+++ b/src/components/timeline/timeline_quick_settings.js
@@ -48,10 +48,9 @@ const TimelineQuickSettings = {
       }
     },
     hideMutedPosts: {
-      get () { return this.mergedConfig.hideMutedPosts || this.mergedConfig.hideFilteredStatuses },
+      get () { return this.mergedConfig.hideFilteredStatuses },
       set () {
         const value = !this.hideMutedPosts
-        this.$store.dispatch('setOption', { name: 'hideMutedPosts', value })
         this.$store.dispatch('setOption', { name: 'hideFilteredStatuses', value })
       }
     }
diff --git a/src/i18n/en.json b/src/i18n/en.json
index aa440ac1..89e808aa 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -259,6 +259,7 @@
     "security": "Security",
     "setting_changed": "Setting is different from default",
     "enter_current_password_to_confirm": "Enter your current password to confirm your identity",
+    "post_look_feel": "Posts Look & Feel",
     "mfa": {
       "otp": "OTP",
       "setup_otp": "Setup OTP",
@@ -331,6 +332,7 @@
     "emoji_reactions_on_timeline": "Show emoji reactions on timeline",
     "export_theme": "Save preset",
     "filtering": "Filtering",
+    "wordfilter": "Wordfilter",
     "filtering_explanation": "All statuses containing these words will be muted, one per line",
     "word_filter": "Word filter",
     "follow_export": "Follow export",
@@ -346,7 +348,7 @@
     "hide_media_previews": "Hide media previews",
     "hide_muted_posts": "Hide posts of muted users",
     "hide_all_muted_posts": "Hide muted posts",
-    "max_thumbnails": "Maximum amount of thumbnails per post",
+    "max_thumbnails": "Maximum amount of thumbnails per post (empty = no limit)",
     "hide_isp": "Hide instance-specific panel",
     "right_sidebar": "Show sidebar on the right side",
     "hide_wallpaper": "Hide instance wallpaper",
@@ -354,7 +356,9 @@
     "use_one_click_nsfw": "Open NSFW attachments with just one click",
     "hide_post_stats": "Hide post statistics (e.g. the number of favorites)",
     "hide_user_stats": "Hide user statistics (e.g. the number of followers)",
-    "hide_filtered_statuses": "Hide filtered statuses",
+    "hide_filtered_statuses": "Hide all filtered posts",
+    "hide_wordfiltered_statuses": "Hide word-filtered statuses",
+    "hide_muted_threads": "Hide muted threads",
     "import_blocks_from_a_csv_file": "Import blocks from a csv file",
     "import_followers_from_a_csv_file": "Import follows from a csv file",
     "import_theme": "Load preset",
@@ -395,6 +399,8 @@
     "name_bio": "Name & bio",
     "new_email": "New email",
     "new_password": "New password",
+    "posts": "Posts",
+    "user_profiles": "User Profiles",
     "notification_visibility": "Types of notifications to show",
     "notification_visibility_follows": "Follows",
     "notification_visibility_likes": "Favorites",
@@ -411,7 +417,7 @@
     "hide_followers_count_description": "Don't show follower count",
     "show_admin_badge": "Show \"Admin\" badge in my profile",
     "show_moderator_badge": "Show \"Moderator\" badge in my profile",
-    "nsfw_clickthrough": "Enable clickthrough attachment and link preview image hiding for NSFW statuses",
+    "nsfw_clickthrough": "Censor NSFW content",
     "oauth_tokens": "OAuth tokens",
     "token": "Token",
     "refresh_token": "Refresh token",
@@ -455,7 +461,7 @@
     "subject_line_noop": "Do not copy",
     "post_status_content_type": "Post status content type",
     "sensitive_by_default": "Mark posts as sensitive by default",
-    "stop_gifs": "Play-on-hover GIFs",
+    "stop_gifs": "Pause animated images until you hover on them",
     "streaming": "Enable automatic streaming of new posts when scrolled to the top",
     "user_mutes": "Users",
     "useStreamingApi": "Receive posts and notifications real-time",
diff --git a/src/modules/config.js b/src/modules/config.js
index 0f596750..df66bfe6 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -23,6 +23,8 @@ export const defaultState = {
   hideInstanceWallpaper: false,
   // bad name: actually hides posts of muted USERS
   hideMutedPosts: undefined, // instance default
+  hideMutedThreads: undefined, // instance default
+  hideWordFilteredPosts: undefined, // instance default
   collapseMessageWithSubject: undefined, // instance default
   padEmoji: true,
   hideAttachments: false,
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 539b9c66..60038f08 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -21,7 +21,10 @@ const defaultState = {
   collapseMessageWithSubject: false,
   greentext: false,
   hideFilteredStatuses: false,
+  // bad name: actually hides posts of muted USERS
   hideMutedPosts: false,
+  hideMutedThreads: true,
+  hideWordFilteredPosts: false,
   hidePostStats: false,
   hideSitename: false,
   hideUserStats: false,
-- 
cgit v1.2.3-70-g09d2


From a3c703bd37fc55c2377cb0bf099af6a21ea07e8e Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 14 Jun 2021 02:52:41 +0300
Subject: compact notifs

---
 src/components/gallery/gallery.vue               |  5 ++-
 src/components/notification/notification.vue     |  3 +-
 src/components/status_body/status_body.js        |  1 +
 src/components/status_body/status_body.scss      | 56 ++++++++++++++++++++++++
 src/components/status_body/status_body.vue       |  7 ++-
 src/components/status_content/status_content.js  |  1 +
 src/components/status_content/status_content.vue | 13 +++++-
 7 files changed, 81 insertions(+), 5 deletions(-)

(limited to 'src/components/notification/notification.vue')

diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index ca91c9c1..3e967e9c 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -36,7 +36,10 @@
   height: 0;
   width: 100%;
   flex-grow: 1;
-  margin-top: 0.5em;
+
+  &:not(:first-child) {
+    margin-top: 0.5em;
+  }
 
   .gallery-row-inner {
     position: absolute;
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 0081dee4..396ae0e1 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -181,8 +181,9 @@
           </router-link>
         </div>
         <template v-else>
-          <status-content
+          <StatusContent
             class="faint"
+            :compact="true"
             :status="notification.action"
           />
         </template>
diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js
index 26491e1b..6dc028a6 100644
--- a/src/components/status_body/status_body.js
+++ b/src/components/status_body/status_body.js
@@ -23,6 +23,7 @@ library.add(
 const StatusContent = {
   name: 'StatusContent',
   props: [
+    'compact',
     'status',
     'focused',
     'noHeading',
diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss
index 81a687f1..a93c92e0 100644
--- a/src/components/status_body/status_body.scss
+++ b/src/components/status_body/status_body.scss
@@ -1,11 +1,17 @@
 @import '../../_variables.scss';
 
 .StatusBody {
+  display: flex;
+  flex-direction: column;
 
   .emoji {
     --_still_image-label-scale: 0.5;
   }
 
+  .attachments {
+    margin-top: 0.5em;
+  }
+
   & .text,
   & .summary {
     font-family: var(--postFont, sans-serif);
@@ -115,4 +121,54 @@
   .cyantext {
     color: var(--postCyantext, $fallback--cBlue);
   }
+
+  &.-compact {
+    flex-direction: row;
+
+    --emoji-size: 16px;
+
+    & .body,
+    & .attachments {
+      max-height: 3.25em;
+    }
+
+    .body {
+      overflow: hidden;
+      white-space: normal;
+      min-width: 5em;
+      flex: 5 1 auto;
+      mask-size: auto 3.5em, auto auto;
+      mask-position: 0 0, 0 0;
+      mask-repeat: repeat-x, repeat;
+      mask-image:
+        linear-gradient(to top, white 0.5em, transparent 2.5em),
+        linear-gradient(to top, white, white);
+
+      /* Autoprefixed seem to ignore this one, and also syntax is different */
+      -webkit-mask-composite: xor;
+      mask-composite: exclude;
+    }
+
+    .attachments {
+      margin-top: 0;
+      flex: 1 1 auto;
+      min-width: 5em;
+      height: 100%;
+    }
+
+    .summary-wrapper {
+      .summary::after {
+        content: ': ';
+      }
+
+      line-height: inherit;
+      margin: 0;
+      border: none;
+      display: inline-block;
+    }
+
+    .text-wrapper {
+      display: inline-block;
+    }
+  }
 }
diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
index 3dc4916c..6609d989 100644
--- a/src/components/status_body/status_body.vue
+++ b/src/components/status_body/status_body.vue
@@ -1,5 +1,8 @@
 <template>
-  <div class="StatusBody">
+<div
+  class="StatusBody"
+  :class="{ '-compact': compact }"
+>
     <div class="body">
       <div
         v-if="status.summary_raw_html"
@@ -8,6 +11,7 @@
       >
         <RichContent
           class="media-body summary"
+          :single-line="compact"
           :html="status.summary_raw_html"
           :emoji="status.emojis"
         />
@@ -52,6 +56,7 @@
             :html="status.raw_html"
             :emoji="status.emojis"
             :handle-links="true"
+            :single-line="compact"
             :greentext="mergedConfig.greentext"
             @parseReady="setHeadTailLinks"
           />
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
index 11a4974b..4d6f0a14 100644
--- a/src/components/status_content/status_content.js
+++ b/src/components/status_content/status_content.js
@@ -28,6 +28,7 @@ const StatusContent = {
   name: 'StatusContent',
   props: [
     'status',
+    'compact',
     'focused',
     'noHeading',
     'fullContent',
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index feb34d2c..06edd780 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -1,8 +1,12 @@
 <template>
-  <div class="StatusContent">
+<div
+  class="StatusContent"
+  :class="{ '-compact': compact }"
+>
     <slot name="header" />
     <StatusBody
       :status="status"
+      :compact="compact"
       :single-line="singleLine"
       :hide-mentions="hideMentions"
       @parseReady="setHeadTailLinks"
@@ -36,7 +40,7 @@
       </div>
 
       <div
-        v-if="status.card && !noHeading"
+        v-if="status.card && !noHeading && !compact"
         class="link-preview media-body"
       >
         <link-preview
@@ -59,5 +63,10 @@ $status-margin: 0.75em;
 .StatusContent {
   flex: 1;
   min-width: 0;
+  &.-compact {
+    flex {
+      display: flex;
+    }
+  }
 }
 </style>
-- 
cgit v1.2.3-70-g09d2


From 4c974f5ca21c6a514d0dfc09a0aeab7789da95c5 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 13 Aug 2021 13:06:42 +0300
Subject: richcontent support in polls, user cards and user profiles

---
 src/components/basic_user_card/basic_user_card.js  |  4 +-
 src/components/basic_user_card/basic_user_card.vue | 12 ++---
 src/components/notification/notification.js        |  4 +-
 src/components/notification/notification.scss      |  2 +
 src/components/notification/notification.vue       | 14 ++---
 src/components/notifications/notifications.scss    |  7 ---
 src/components/poll/poll.vue                       | 12 ++++-
 src/components/rich_content/rich_content.scss      |  1 +
 src/components/status_content/status_content.vue   |  5 +-
 src/components/user_card/user_card.js              |  4 +-
 src/components/user_card/user_card.vue             | 61 +++++-----------------
 src/components/user_profile/user_profile.js        |  4 +-
 src/components/user_profile/user_profile.vue       | 20 ++++---
 .../entity_normalizer/entity_normalizer.service.js |  5 +-
 14 files changed, 69 insertions(+), 86 deletions(-)

(limited to 'src/components/notification/notification.vue')

diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js
index 87085a28..8f41e2fb 100644
--- a/src/components/basic_user_card/basic_user_card.js
+++ b/src/components/basic_user_card/basic_user_card.js
@@ -1,5 +1,6 @@
 import UserCard from '../user_card/user_card.vue'
 import UserAvatar from '../user_avatar/user_avatar.vue'
+import RichContent from 'src/components/rich_content/rich_content.jsx'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 
 const BasicUserCard = {
@@ -13,7 +14,8 @@ const BasicUserCard = {
   },
   components: {
     UserCard,
-    UserAvatar
+    UserAvatar,
+    RichContent
   },
   methods: {
     toggleUserExpanded () {
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index c53f6a9c..53deb1df 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -25,17 +25,11 @@
         :title="user.name"
         class="basic-user-card-user-name"
       >
-        <!-- eslint-disable vue/no-v-html -->
-        <span
-          v-if="user.name_html"
+        <RichContent
           class="basic-user-card-user-name-value"
-          v-html="user.name_html"
+          :html="user.name"
+          :emoji="user.emoji"
         />
-        <!-- eslint-enable vue/no-v-html -->
-        <span
-          v-else
-          class="basic-user-card-user-name-value"
-        >{{ user.name }}</span>
       </div>
       <div>
         <router-link
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index 4aa9affd..398bb7a9 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -4,6 +4,7 @@ import Status from '../status/status.vue'
 import UserAvatar from '../user_avatar/user_avatar.vue'
 import UserCard from '../user_card/user_card.vue'
 import Timeago from '../timeago/timeago.vue'
+import RichContent from 'src/components/rich_content/rich_content.jsx'
 import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
 import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@@ -44,7 +45,8 @@ const Notification = {
     UserAvatar,
     UserCard,
     Timeago,
-    Status
+    Status,
+    RichContent
   },
   methods: {
     toggleUserExpanded () {
diff --git a/src/components/notification/notification.scss b/src/components/notification/notification.scss
index f5905560..ec291547 100644
--- a/src/components/notification/notification.scss
+++ b/src/components/notification/notification.scss
@@ -2,6 +2,8 @@
 
 // TODO Copypaste from Status, should unify it somehow
 .Notification {
+  --emoji-size: 14px;
+
   &.-muted {
     padding: 0.25em 0.6em;
     height: 1.2em;
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 0081dee4..634ec8ee 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -51,12 +51,14 @@
         <span class="notification-details">
           <div class="name-and-action">
             <!-- eslint-disable vue/no-v-html -->
-            <bdi
-              v-if="!!notification.from_profile.name_html"
-              class="username"
-              :title="'@'+notification.from_profile.screen_name_ui"
-              v-html="notification.from_profile.name_html"
-            />
+            <bdi v-if="!!notification.from_profile.name_html">
+              <RichContent
+                class="username"
+                :title="'@'+notification.from_profile.screen_name_ui"
+                :html="notification.from_profile.name_html"
+                :emoji="notification.from_profile.emoji"
+              />
+            </bdi>
             <!-- eslint-enable vue/no-v-html -->
             <span
               v-else
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 2bb627a8..77b3c438 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -148,13 +148,6 @@
       max-width: 100%;
       text-overflow: ellipsis;
       white-space: nowrap;
-
-      img {
-        width: 14px;
-        height: 14px;
-        vertical-align: middle;
-        object-fit: contain
-      }
     }
 
     .timeago {
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index 6e0234b3..63b44e4f 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -17,7 +17,11 @@
           <span class="result-percentage">
             {{ percentageForOption(option.votes_count) }}%
           </span>
-          <RichContent :html="option.title_html" :handle-links="false" :emoji="emoji" />
+          <RichContent
+            :html="option.title_html"
+            :handle-links="false"
+            :emoji="emoji"
+          />
         </div>
         <div
           class="result-fill"
@@ -41,7 +45,11 @@
           :value="index"
         >
         <label class="option-vote">
-          <RichContent :html="option.title_html" :handle-links="false" :emoji="emoji" />
+          <RichContent
+            :html="option.title_html"
+            :handle-links="false"
+            :emoji="emoji"
+          />
         </label>
       </div>
     </div>
diff --git a/src/components/rich_content/rich_content.scss b/src/components/rich_content/rich_content.scss
index 12cb9776..db08ef1e 100644
--- a/src/components/rich_content/rich_content.scss
+++ b/src/components/rich_content/rich_content.scss
@@ -49,6 +49,7 @@
   }
 
   .emoji {
+    display: inline-block;
     width: var(--emoji-size, 32px);
     height: var(--emoji-size, 32px);
   }
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index 3f65e64a..5cebc697 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -7,7 +7,10 @@
       @parseReady="$emit('parseReady', $event)"
     >
       <div v-if="status.poll && status.poll.options">
-        <poll :base-poll="status.poll" :emoji="status.emojis" />
+        <Poll
+          :base-poll="status.poll"
+          :emoji="status.emojis"
+        />
       </div>
 
       <div
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index d9fb64d1..98e6c2f2 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -5,6 +5,7 @@ import FollowButton from '../follow_button/follow_button.vue'
 import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import AccountActions from '../account_actions/account_actions.vue'
 import Select from '../select/select.vue'
+import RichContent from 'src/components/rich_content/rich_content.jsx'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 import { mapGetters } from 'vuex'
 import { library } from '@fortawesome/fontawesome-svg-core'
@@ -118,7 +119,8 @@ export default {
     AccountActions,
     ProgressButton,
     FollowButton,
-    Select
+    Select,
+    RichContent
   },
   methods: {
     muteUser () {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index a16f7873..794a2350 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -38,21 +38,12 @@
           </router-link>
           <div class="user-summary">
             <div class="top-line">
-              <!-- eslint-disable vue/no-v-html -->
-              <div
-                v-if="user.name_html"
+              <RichContent
                 :title="user.name"
                 class="user-name"
-                v-html="user.name_html"
+                :html="user.name"
+                :emoji="user.emoji"
               />
-              <!-- eslint-enable vue/no-v-html -->
-              <div
-                v-else
-                :title="user.name"
-                class="user-name"
-              >
-                {{ user.name }}
-              </div>
               <button
                 v-if="isOtherUser && !user.is_local"
                 :href="user.statusnet_profile_url"
@@ -255,20 +246,12 @@
           <span>{{ hideFollowersCount ? $t('user_card.hidden') : user.followers_count }}</span>
         </div>
       </div>
-      <!-- eslint-disable vue/no-v-html -->
-      <p
-        v-if="!hideBio && user.description_html"
+      <RichContent
+        v-if="!hideBio"
         class="user-card-bio"
-        @click.prevent="linkClicked"
-        v-html="user.description_html"
+        :html="user.description_html"
+        :emoji="user.emoji"
       />
-      <!-- eslint-enable vue/no-v-html -->
-      <p
-        v-else-if="!hideBio"
-        class="user-card-bio"
-      >
-        {{ user.description }}
-      </p>
     </div>
   </div>
 </template>
@@ -281,9 +264,10 @@
 .user-card {
   position: relative;
 
-  &:hover .Avatar {
+  &:hover {
     --_still-image-img-visibility: visible;
     --_still-image-canvas-visibility: hidden;
+    --_still-image-label-visibility: hidden;
   }
 
   .panel-heading {
@@ -327,12 +311,12 @@
     }
   }
 
-  p {
-    margin-bottom: 0;
-  }
-
   &-bio {
     text-align: center;
+    display: block;
+    line-height: 18px;
+    padding: 1em;
+    margin: 0;
 
     a {
       color: $fallback--link;
@@ -344,11 +328,6 @@
       vertical-align: middle;
       max-width: 100%;
       max-height: 400px;
-
-      &.emoji {
-        width: 32px;
-        height: 32px;
-      }
     }
   }
 
@@ -450,13 +429,6 @@
     // big one
     z-index: 1;
 
-    img {
-      width: 26px;
-      height: 26px;
-      vertical-align: middle;
-      object-fit: contain
-    }
-
     .top-line {
       display: flex;
     }
@@ -469,12 +441,7 @@
     margin-right: 1em;
     font-size: 15px;
 
-    img {
-      object-fit: contain;
-      height: 16px;
-      width: 16px;
-      vertical-align: middle;
-    }
+    --emoji-size: 14px;
   }
 
   .bottom-line {
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index c0b55a6c..7a475609 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -4,6 +4,7 @@ import FollowCard from '../follow_card/follow_card.vue'
 import Timeline from '../timeline/timeline.vue'
 import Conversation from '../conversation/conversation.vue'
 import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js'
+import RichContent from 'src/components/rich_content/rich_content.jsx'
 import List from '../list/list.vue'
 import withLoadMore from '../../hocs/with_load_more/with_load_more'
 import { library } from '@fortawesome/fontawesome-svg-core'
@@ -164,7 +165,8 @@ const UserProfile = {
     FriendList,
     FollowCard,
     TabSwitcher,
-    Conversation
+    Conversation,
+    RichContent
   }
 }
 
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index aef897ae..726216ff 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -20,20 +20,24 @@
           :key="index"
           class="user-profile-field"
         >
-          <!-- eslint-disable vue/no-v-html -->
           <dt
             :title="user.fields_text[index].name"
             class="user-profile-field-name"
-            @click.prevent="linkClicked"
-            v-html="field.name"
-          />
+          >
+            <RichContent
+              :html="field.name"
+              :emoji="user.emoji"
+            />
+          </dt>
           <dd
             :title="user.fields_text[index].value"
             class="user-profile-field-value"
-            @click.prevent="linkClicked"
-            v-html="field.value"
-          />
-          <!-- eslint-enable vue/no-v-html -->
+          >
+            <RichContent
+              :html="field.value"
+              :emoji="user.emoji"
+            />
+          </dd>
         </dl>
       </div>
       <tab-switcher
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index c80ea487..d84e3422 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -56,10 +56,11 @@ export const parseUser = (data) => {
 
     output.emoji = data.emojis
     output.name = data.display_name
-    output.name_html = addEmojis(escape(data.display_name), data.emojis)
+    output.name_html = escape(data.display_name)
 
     output.description = data.note
-    output.description_html = addEmojis(data.note, data.emojis)
+    // TODO cleanup this shit, output.description is overriden with source data
+    output.description_html = data.note
 
     output.fields = data.fields
     output.fields_html = data.fields.map(field => {
-- 
cgit v1.2.3-70-g09d2

