From 61bb69c88f6d70431a72bfb649d0f796b976a83b Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Sun, 8 Aug 2021 12:40:17 -0400
Subject: [PATCH] Optimize thread display

---
 src/_variables.scss                          |   2 +
 src/components/conversation/conversation.vue | 215 +++++++++++--------
 src/components/status/status.scss            |   9 -
 src/components/thread_tree/thread_tree.vue   |  16 +-
 4 files changed, 139 insertions(+), 103 deletions(-)

diff --git a/src/_variables.scss b/src/_variables.scss
index 9004d551..099d3606 100644
--- a/src/_variables.scss
+++ b/src/_variables.scss
@@ -30,3 +30,5 @@ $fallback--attachmentRadius: 10px;
 $fallback--chatMessageRadius: 10px;
 
 $fallback--buttonShadow: 0px 0px 2px 0px rgba(0, 0, 0, 1), 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset;
+
+$status-margin: 0.75em;
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index 0ffd8c37..cd108f69 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -18,94 +18,102 @@
         {{ $t('timeline.collapse') }}
       </button>
     </div>
-    <div
-      v-if="diveMode"
-      class="conversation-undive-box"
-    >
-      <i18n
-        path="status.show_all_conversation"
-        tag="button"
-        class="button-unstyled -link"
-        @click.prevent="undive"
+    <div class="conversation-body panel-body">
+      <div
+        v-if="diveMode"
+        class="conversation-undive-box"
       >
-        <FAIcon icon="angle-double-left" />
-      </i18n>
-    </div>
-    <div
-      v-if="diveMode"
-      class="conversation-undive-box"
-    >
-      <i18n
-        path="status.return_to_last_showing"
-        tag="button"
-        class="button-unstyled -link"
-        @click.prevent="diveBack"
+        <i18n
+          path="status.show_all_conversation"
+          tag="button"
+          class="button-unstyled -link"
+          @click.prevent="undive"
+        >
+          <FAIcon icon="angle-double-left" />
+        </i18n>
+      </div>
+      <div
+        v-if="diveMode"
+        class="conversation-undive-box"
       >
-        <FAIcon icon="chevron-left" />
-      </i18n>
-    </div>
-    <div v-if="isTreeView">
-      <thread-tree
-        v-for="status in showingTopLevel"
-        :key="status.id"
-        ref="statusComponent"
-        :depth="0"
+        <i18n
+          path="status.return_to_last_showing"
+          tag="button"
+          class="button-unstyled -link"
+          @click.prevent="diveBack"
+        >
+          <FAIcon icon="chevron-left" />
+        </i18n>
+      </div>
+      <div
+        v-if="isTreeView"
+        class="thread-body"
+      >
+        <thread-tree
+          v-for="status in showingTopLevel"
+          :key="status.id"
+          ref="statusComponent"
+          :depth="0"
 
-        :status="status"
-        :in-profile="inProfile"
-        :conversation="conversation"
-        :collapsable="collapsable"
-        :is-expanded="isExpanded"
-        :pinned-status-ids-object="pinnedStatusIdsObject"
-        :profile-user-id="profileUserId"
+          :status="status"
+          :in-profile="inProfile"
+          :conversation="conversation"
+          :collapsable="collapsable"
+          :is-expanded="isExpanded"
+          :pinned-status-ids-object="pinnedStatusIdsObject"
+          :profile-user-id="profileUserId"
 
-        :focused="focused"
-        :get-replies="getReplies"
-        :highlight="maybeHighlight"
-        :set-highlight="setHighlight"
-        :toggle-expanded="toggleExpanded"
+          :focused="focused"
+          :get-replies="getReplies"
+          :highlight="maybeHighlight"
+          :set-highlight="setHighlight"
+          :toggle-expanded="toggleExpanded"
 
-        :simple="treeViewIsSimple"
-        :toggle-thread-display="toggleThreadDisplay"
-        :thread-display-status="threadDisplayStatus"
-        :show-thread-recursively="showThreadRecursively"
-        :total-reply-count="totalReplyCount"
-        :total-reply-depth="totalReplyDepth"
-        :status-content-properties="statusContentProperties"
-        :set-status-content-property="setStatusContentProperty"
-        :toggle-status-content-property="toggleStatusContentProperty"
-        :dive="canDive ? diveIntoStatus : undefined"
-      />
-    </div>
-    <div v-if="isLinearView">
-      <status
-        v-for="status in conversation"
-        :key="status.id"
-        ref="statusComponent"
-        :inline-expanded="collapsable && isExpanded"
-        :statusoid="status"
-        :expandable="!isExpanded"
-        :show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]"
-        :focused="focused(status.id)"
-        :in-conversation="isExpanded"
-        :highlight="getHighlight()"
-        :replies="getReplies(status.id)"
-        :in-profile="inProfile"
-        :profile-user-id="profileUserId"
-        class="conversation-status status-fadein panel-body"
+          :simple="treeViewIsSimple"
+          :toggle-thread-display="toggleThreadDisplay"
+          :thread-display-status="threadDisplayStatus"
+          :show-thread-recursively="showThreadRecursively"
+          :total-reply-count="totalReplyCount"
+          :total-reply-depth="totalReplyDepth"
+          :status-content-properties="statusContentProperties"
+          :set-status-content-property="setStatusContentProperty"
+          :toggle-status-content-property="toggleStatusContentProperty"
+          :dive="canDive ? diveIntoStatus : undefined"
+        />
+      </div>
+      <div
+        v-if="isLinearView"
+        class="thread-body"
+      >
+        <status
+          v-for="status in conversation"
+          :key="status.id"
+          ref="statusComponent"
+          :inline-expanded="collapsable && isExpanded"
+          :statusoid="status"
+          :expandable="!isExpanded"
+          :show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]"
+          :focused="focused(status.id)"
+          :in-conversation="isExpanded"
+          :highlight="getHighlight()"
+          :replies="getReplies(status.id)"
+          :in-profile="inProfile"
+          :profile-user-id="profileUserId"
+          class="conversation-status status-fadein panel-body"
 
-        :toggle-thread-display="toggleThreadDisplay"
-        :thread-display-status="threadDisplayStatus"
-        :show-thread-recursively="showThreadRecursively"
-        :total-reply-count="totalReplyCount"
-        :total-reply-depth="totalReplyDepth"
-        :status-content-properties="statusContentProperties"
-        :set-status-content-property="setStatusContentProperty"
-        :toggle-status-content-property="toggleStatusContentProperty"
+          :toggle-thread-display="toggleThreadDisplay"
+          :thread-display-status="threadDisplayStatus"
+          :show-thread-recursively="showThreadRecursively"
+          :total-reply-count="totalReplyCount"
+          :total-reply-depth="totalReplyDepth"
+          :status-content-properties="statusContentProperties"
+          :set-status-content-property="setStatusContentProperty"
+          :toggle-status-content-property="toggleStatusContentProperty"
 
-        @goto="setHighlight"
-        @toggleExpanded="toggleExpanded"
-      />
+          @goto="setHighlight"
+          @toggleExpanded="toggleExpanded"
+        />
+      </div>
     </div>
   </div>
   <div
@@ -121,21 +129,54 @@
 
 .Conversation {
   .conversation-undive-box {
-    padding: 1em;
+    padding: $status-margin;
   }
+
+  /* HACK: we want the border width to scale with the status *below it* */
   .conversation-undive-box,
   .conversation-status {
-    border-bottom-width: 1px;
-    border-bottom-style: solid;
-    border-bottom-color: var(--border, $fallback--border);
+    border-top-width: 1px;
+    border-top-style: solid;
+    border-top-color: var(--border, $fallback--border);
     border-radius: 0;
   }
 
+  &.-expanded .conversation-body .thread-tree:nth-child(1) > .conversation-status {
+    border-top-left-radius: $fallback--panelRadius;
+    border-top-left-radius: var(--panelRadius, $fallback--panelRadius);
+  }
+
+  /* first element in conversation body */
+  &.-expanded .conversation-body {
+    .conversation-undive-box:nth-child(1),
+    & > .conversation-status:nth-child(1),
+    & > .thread-body:nth-child(1) > .thread-tree:nth-child(1) > .conversation-status:nth-child(1), {
+      border-top: none;
+    }
+  }
+
+  /* first unexpanded statuses in timeline */
+  &:first-child:not(.-expanded) {
+    .conversation-body {
+      .conversation-status {
+        border-top: none;
+      }
+    }
+  }
+
+  /* expanded conversation in timeline */
+  &.status-fadein.-expanded .thread-body {
+    border-left-width: 4px;
+    border-left-style: solid;
+    border-left-color: $fallback--cRed;
+    border-left-color: var(--cRed, $fallback--cRed);
+    border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
+    border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
+    border-bottom: 1px solid var(--border, $fallback--border);
+  }
   &.-expanded {
     .conversation-status:last-child {
       border-bottom: none;
-      border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
-      border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
     }
   }
 }
diff --git a/src/components/status/status.scss b/src/components/status/status.scss
index 2028ade9..80bc392d 100644
--- a/src/components/status/status.scss
+++ b/src/components/status/status.scss
@@ -1,7 +1,5 @@
 @import '../../_variables.scss';
 
-$status-margin: 0.75em;
-
 .Status {
   min-width: 0;
   white-space: normal;
@@ -28,13 +26,6 @@ $status-margin: 0.75em;
     --icon: var(--selectedPostIcon, $fallback--icon);
   }
 
-  &.-conversation {
-    border-left-width: 4px;
-    border-left-style: solid;
-    border-left-color: $fallback--cRed;
-    border-left-color: var(--cRed, $fallback--cRed);
-  }
-
   .gravestone {
     padding: $status-margin;
     color: $fallback--faint;
diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
index fa1e5f86..aafad66e 100644
--- a/src/components/thread_tree/thread_tree.vue
+++ b/src/components/thread_tree/thread_tree.vue
@@ -109,14 +109,16 @@
 <style lang="scss">
 @import '../../_variables.scss';
 .thread-tree-replies {
-  margin-left: 1em;
+  margin-left: $status-margin;
+  border-left: 1px solid var(--border, $fallback--border);
+  border-top-left-radius: $fallback--panelRadius;
+  border-top-left-radius: var(--panelRadius, $fallback--panelRadius);
+  border-bottom-left-radius: $fallback--panelRadius;
+  border-bottom-left-radius: var(--panelRadius, $fallback--panelRadius);
 }
+
 .thread-tree-replies-hidden {
-  padding: 1em;
-  border-bottom: 1px solid var(--border, #222);
-}
-.conversation-status.conversation-status-treeview:last-child,
-.Conversation.-expanded .conversation-status.conversation-status-treeview:last-child {
-  border-bottom: 1px solid var(--border, #222);
+  padding: $status-margin;
+  border-top: 1px solid var(--border, $fallback--border);
 }
 </style>