Browse Source

fix pinned statuses appearing at the bottom of user timeline (and
possibly fetching new ones there)

Henry Jameson 2 years ago
parent
commit
2a97bdb39d
2 changed files with 31 additions and 3 deletions
  1. 1 1
      src/components/timeline/timeline.vue
  2. 30 2
      src/modules/statuses.js

+ 1 - 1
src/components/timeline/timeline.vue

@@ -37,7 +37,7 @@
         </template>
         <template v-for="status in timeline.visibleStatuses">
           <conversation
-            v-if="!excludedStatusIdsObject[status.id]"
+            v-if="status._meta.fetchedFromPinned <= 0"
             :key="status.id"
             class="status-fadein"
             :status-id="status.id"

+ 30 - 2
src/modules/statuses.js

@@ -84,7 +84,7 @@ const mergeOrAdd = (arr, obj, item) => {
     // We already have this, so only merge the new info.
     // We ignore null values to avoid overwriting existing properties with missing data
     // we also skip 'user' because that is handled by users module
-    merge(oldItem, omitBy(item, (v, k) => v === null || k === 'user'))
+    merge(oldItem, omitBy(item, (v, k) => v === null || k === 'user' || k === '_meta'))
     // Reactivity fix.
     oldItem.attachments.splice(oldItem.attachments.length)
     return { item: oldItem, new: false }
@@ -122,6 +122,22 @@ const sortTimeline = (timeline) => {
 
 // Add status to the global storages (arrays and objects maintaining statuses) except timelines
 const addStatusToGlobalStorage = (state, data) => {
+  // POST METADATA PROCESSING.
+  // In this context "metadata" means all the sidechannel information about the post that we have
+  // i.e. where post was obtained from (which endpoint), what timestamp was etc. anything that isn't
+  // directly attached into it by server.
+  //
+  // @@_meta.fetchedFromPinned: number
+  // -1 = fetched from elsewhere
+  // +1 = fetched from pinned posts
+  // 0 = fetched from elsewhere and from pinned posts
+  //
+  // The logic is mainly for user profile page - don't show post in timeline context
+  // if post was ONLY fetched from pinned posts, show it if it was obtained from
+  // elsewhere (i.e. user posts fetching)
+  data._meta = data._meta || {}
+  data._meta.fetchedFromPinned = data._meta.fetchedFromPinned || -1
+
   const result = mergeOrAdd(state.allStatuses, state.allStatusesObject, data)
   if (result.new) {
     // Add to conversation
@@ -133,6 +149,18 @@ const addStatusToGlobalStorage = (state, data) => {
     } else {
       set(conversationsObject, conversationId, [status])
     }
+  } else {
+    // If post was fetched from elsewhere AND from pinned (=0 we don't care anymore)
+    // otherwise we sum the old data and new data and clamp it to [-1; 1]
+    if (result.item._meta.fetchedFromPinned !== 0) {
+      result.item._meta.fetchedFromPinned = Math.min(
+        1,
+        Math.max(
+          -1,
+          result.item._meta.fetchedFromPinned + data._meta.fetchedFromPinned
+        )
+      )
+    }
   }
   return result
 }
@@ -626,7 +654,7 @@ const statuses = {
     },
     fetchPinnedStatuses ({ rootState, dispatch }, userId) {
       rootState.api.backendInteractor.fetchPinnedStatuses({ id: userId })
-        .then(statuses => dispatch('addNewStatuses', { statuses, timeline: 'user', userId, showImmediately: true, noIdUpdate: true }))
+        .then(statuses => dispatch('addNewStatuses', { statuses: statuses.map(status => ({ ...status, _meta: { fetchedFromPinned: 1 } })), timeline: 'user', userId, showImmediately: true, noIdUpdate: true }))
     },
     pinStatus ({ rootState, dispatch }, statusId) {
       return rootState.api.backendInteractor.pinOwnStatus({ id: statusId })