From 1c2048749480800e2d44b3876378beee421a79ba Mon Sep 17 00:00:00 2001
From: tusooa <tusooa@kazv.moe>
Date: Wed, 12 Jul 2023 20:45:44 -0400
Subject: Implement showing quotes

---
 src/components/status/status.vue | 9 +++++++++
 1 file changed, 9 insertions(+)

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

diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 35b15362..58fc0eca 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -364,6 +364,15 @@
             @parseReady="setHeadTailLinks"
           />
 
+          <article
+            v-if="quotedStatus"
+            class="quoted-status"
+          >
+            <Status
+              :statusoid="quotedStatus"
+            />
+          </article>
+
           <div
             v-if="inConversation && !isPreview && replies && replies.length"
             class="replies"
-- 
cgit v1.2.3-70-g09d2


From d22079cf7392a1ef184d7c03ff7cb680e3e1c99c Mon Sep 17 00:00:00 2001
From: tusooa <tusooa@kazv.moe>
Date: Thu, 13 Jul 2023 00:37:57 -0400
Subject: Handle recursive quotes

---
 .../post_status_form/post_status_form.js           |  2 +-
 src/components/status/status.js                    | 25 ++++++++++++++++-
 src/components/status/status.scss                  | 12 ++++++++
 src/components/status/status.vue                   | 32 +++++++++++++++++++++-
 src/i18n/en.json                                   |  5 +++-
 .../entity_normalizer/entity_normalizer.service.js |  2 +-
 6 files changed, 73 insertions(+), 5 deletions(-)

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

diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 73176132..17350998 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -281,7 +281,7 @@ const PostStatusForm = {
           repliedStatus.visibility === 'local') {
         return true
       } else if (repliedStatus.visibility === 'private') {
-        return repliedStatus.account.id === this.$store.state.users.currentUser.id
+        return repliedStatus.user.id === this.$store.state.users.currentUser.id
       }
     },
     ...mapGetters(['mergedConfig']),
diff --git a/src/components/status/status.js b/src/components/status/status.js
index c10c6cf5..e722a635 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -133,6 +133,7 @@ const Status = {
     'showPinned',
     'inProfile',
     'profileUserId',
+    'inQuote',
 
     'simpleTree',
     'controlledThreadDisplayStatus',
@@ -159,7 +160,8 @@ const Status = {
       uncontrolledMediaPlaying: [],
       suspendable: true,
       error: null,
-      headTailLinks: null
+      headTailLinks: null,
+      displayQuote: !this.inQuote
     }
   },
   computed: {
@@ -402,8 +404,17 @@ const Status = {
     editingAvailable () {
       return this.$store.state.instance.editingAvailable
     },
+    hasVisibleQuote () {
+      return this.status.quote_url && this.status.quote_visible
+    },
+    hasInvisibleQuote () {
+      return this.status.quote_url && !this.status.quote_visible
+    },
     quotedStatus () {
       return this.status.quote_id ? this.$store.state.statuses.allStatusesObject[this.status.quote_id] : undefined
+    },
+    shouldDisplayQuote () {
+      return this.quotedStatus && this.displayQuote
     }
   },
   methods: {
@@ -472,6 +483,18 @@ const Status = {
           window.scrollBy(0, rect.bottom - window.innerHeight + 50)
         }
       }
+    },
+    toggleDisplayQuote () {
+      if (this.shouldDisplayQuote) {
+        this.displayQuote = false
+      } else if (!this.quotedStatus) {
+        this.$store.dispatch('fetchStatus', this.status.quote_id)
+          .then(() => {
+            this.displayQuote = true
+          })
+      } else {
+        this.displayQuote = true
+      }
     }
   },
   watch: {
diff --git a/src/components/status/status.scss b/src/components/status/status.scss
index 4dfd1f87..760c6ac1 100644
--- a/src/components/status/status.scss
+++ b/src/components/status/status.scss
@@ -427,5 +427,17 @@
     margin-top: 0.5em;
     border: 1px solid var(--border, $fallback--border);
     border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
+
+    &.-unavailable-prompt {
+      padding: 0.5em;
+    }
+  }
+
+  .display-quoted-status-button {
+    margin: 0.5em;
+
+    &-icon {
+      color: inherit;
+    }
   }
 }
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 58fc0eca..c49a9e7b 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -365,13 +365,43 @@
           />
 
           <article
-            v-if="quotedStatus"
+            v-if="hasVisibleQuote"
             class="quoted-status"
           >
+            <button
+              class="button-unstyled -link display-quoted-status-button"
+              :aria-expanded="shouldDisplayQuote"
+              @click="toggleDisplayQuote"
+            >
+              {{ shouldDisplayQuote ? $t('status.hide_quote') : $t('status.display_quote') }}
+              <FAIcon
+                class="display-quoted-status-button-icon"
+                :icon="shouldDisplayQuote ? 'chevron-up' : 'chevron-down'"
+              />
+            </button>
             <Status
+              v-if="shouldDisplayQuote"
               :statusoid="quotedStatus"
+              :in-quote="true"
             />
           </article>
+          <p
+            v-else-if="hasInvisibleQuote"
+            class="quoted-status -unavailable-prompt"
+          >
+            <i18n-t keypath="status.invisible_quote">
+              <template #link>
+                <bdi>
+                  <a
+                    :href="status.quote_url"
+                    target="_blank"
+                  >
+                    {{ status.quote_url }}
+                  </a>
+                </bdi>
+              </template>
+            </i18n-t>
+          </p>
 
           <div
             v-if="inConversation && !isPreview && replies && replies.length"
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 4bfad3f9..2358a4ce 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -1030,7 +1030,10 @@
     "show_all_conversation": "Show full conversation ({numStatus} other status) | Show full conversation ({numStatus} other statuses)",
     "show_only_conversation_under_this": "Only show replies to this status",
     "status_history": "Status history",
-    "reaction_count_label": "{num} person reacted | {num} people reacted"
+    "reaction_count_label": "{num} person reacted | {num} people reacted",
+    "hide_quote": "Hide the quoted status",
+    "display_quote": "Display the quoted status",
+    "invisible_quote": "Quoted status unavailable: {link}"
   },
   "user_card": {
     "approve": "Approve",
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index fb9ee80a..610ba1ab 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -326,7 +326,7 @@ export const parseStatus = (data) => {
       output.emoji_reactions = pleroma.emoji_reactions
       output.parent_visible = pleroma.parent_visible === undefined ? true : pleroma.parent_visible
       output.quote = pleroma.quote ? parseStatus(pleroma.quote) : undefined
-      output.quote_id = output.quote ? output.quote.id : undefined
+      output.quote_id = pleroma.quote_id ? pleroma.quote_id : (output.quote ? output.quote.id : undefined)
       output.quote_url = pleroma.quote_url
       output.quote_visible = pleroma.quote_visible
     } else {
-- 
cgit v1.2.3-70-g09d2

