commit: 2a97bdb39d7533ae55ddb0713d4fb3d670017ea5
parent 8ade11783aa4740a2cff61f27938f3408c3e0eb0
Author: Henry Jameson <me@hjkos.com>
Date: Sun, 20 Feb 2022 00:04:47 +0200
fix pinned statuses appearing at the bottom of user timeline (and
possibly fetching new ones there)
Diffstat:
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/src/components/timeline/timeline.vue b/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"
diff --git a/src/modules/statuses.js b/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 })