From a0e7803e42afa64b03a441ed576ac4ed816cc735 Mon Sep 17 00:00:00 2001
From: shpuld <shp@cock.li>
Date: Fri, 13 Apr 2018 22:35:55 +0300
Subject: [PATCH] change timeline min/max id updating behavior to not get stuck
 with 20 wrong type of activities on fetch older.

---
 src/modules/statuses.js                       | 145 ++++--------------
 .../timeline_fetcher.service.js               |   2 +-
 2 files changed, 28 insertions(+), 119 deletions(-)

diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 8bc0631e..bbdd87b5 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,7 +1,23 @@
-import { includes, remove, slice, sortBy, toInteger, each, find, flatten, maxBy, last, merge, max, isArray } from 'lodash'
+import { includes, remove, slice, sortBy, toInteger, each, find, flatten, maxBy, minBy, merge, max, min, isArray } from 'lodash'
 import apiService from '../services/api/api.service.js'
 // import parse from '../services/status_parser/status_parser.js'
 
+const emptyTl = () => ({
+  statuses: [],
+  statusesObject: {},
+  faves: [],
+  visibleStatuses: [],
+  visibleStatusesObject: {},
+  newStatusCount: 0,
+  maxId: 0,
+  minVisibleId: 0,
+  loading: false,
+  followers: [],
+  friends: [],
+  viewing: 'statuses',
+  flushMarker: 0
+})
+
 export const defaultState = {
   allStatuses: [],
   allStatusesObject: {},
@@ -10,96 +26,12 @@ export const defaultState = {
   favorites: new Set(),
   error: false,
   timelines: {
-    mentions: {
-      statuses: [],
-      statusesObject: {},
-      faves: [],
-      visibleStatuses: [],
-      visibleStatusesObject: {},
-      newStatusCount: 0,
-      maxId: 0,
-      minVisibleId: 0,
-      loading: false,
-      followers: [],
-      friends: [],
-      viewing: 'statuses',
-      flushMarker: 0
-    },
-    public: {
-      statuses: [],
-      statusesObject: {},
-      faves: [],
-      visibleStatuses: [],
-      visibleStatusesObject: {},
-      newStatusCount: 0,
-      maxId: 0,
-      minVisibleId: 0,
-      loading: false,
-      followers: [],
-      friends: [],
-      viewing: 'statuses',
-      flushMarker: 0
-    },
-    user: {
-      statuses: [],
-      statusesObject: {},
-      faves: [],
-      visibleStatuses: [],
-      visibleStatusesObject: {},
-      newStatusCount: 0,
-      maxId: 0,
-      minVisibleId: 0,
-      loading: false,
-      followers: [],
-      friends: [],
-      viewing: 'statuses',
-      flushMarker: 0
-    },
-    publicAndExternal: {
-      statuses: [],
-      statusesObject: {},
-      faves: [],
-      visibleStatuses: [],
-      visibleStatusesObject: {},
-      newStatusCount: 0,
-      maxId: 0,
-      minVisibleId: 0,
-      loading: false,
-      followers: [],
-      friends: [],
-      viewing: 'statuses',
-      flushMarker: 0
-    },
-    friends: {
-      statuses: [],
-      statusesObject: {},
-      faves: [],
-      visibleStatuses: [],
-      visibleStatusesObject: {},
-      newStatusCount: 0,
-      maxId: 0,
-      minVisibleId: 0,
-      loading: false,
-      followers: [],
-      friends: [],
-      viewing: 'statuses',
-      flushMarker: 0
-    },
-    tag: {
-      statuses: [],
-      statusesObject: {},
-      faves: [],
-      visibleStatuses: [],
-      visibleStatusesObject: {},
-      newStatusCount: 0,
-      maxId: 0,
-      minVisibleId: 0,
-      loading: false,
-      followers: [],
-      friends: [],
-      viewing: 'statuses',
-      flushMarker: 0
-    }
+    mentions: emptyTl(),
+    public: emptyTl(),
+    user: emptyTl(),
+    publicAndExternal: emptyTl(),
+    friends: emptyTl(),
+    tag: emptyTl()
   }
 }
 
@@ -174,8 +106,6 @@ const mergeOrAdd = (arr, obj, item) => {
 const sortTimeline = (timeline) => {
   timeline.visibleStatuses = sortBy(timeline.visibleStatuses, ({id}) => -id)
   timeline.statuses = sortBy(timeline.statuses, ({id}) => -id)
-  timeline.minVisibleId = (last(timeline.visibleStatuses) || {}).id
-
   return timeline
 }
 
@@ -189,10 +119,9 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
   const allStatusesObject = state.allStatusesObject
   const timelineObject = state.timelines[timeline]
 
-  // Set the maxId to the new id if it's larger.
-  const updateMaxId = ({id}) => {
-    if (!timeline || noIdUpdate) { return false }
-    timelineObject.maxId = max([id, timelineObject.maxId])
+  if (timeline && !noIdUpdate) {
+    timelineObject.maxId = max([maxBy(statuses, 'id').id + 1, timelineObject.maxId])
+    timelineObject.minVisibleId = min([minBy(statuses, 'id').id - 1, timelineObject.minVisibleId])
   }
 
   const addStatus = (status, showImmediately, addToTimeline = true) => {
@@ -200,8 +129,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
     status = result.item
 
     if (result.new) {
-      updateMaxId(status)
-
       if (statusType(status) === 'retweet' && status.retweeted_status.user.id === user.id) {
         addNotification({ type: 'repeat', status: status.retweeted_status, action: status })
       }
@@ -317,7 +244,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
       // Only update if this is a new favorite.
       if (!state.favorites.has(favorite.id)) {
         state.favorites.add(favorite.id)
-        updateMaxId(favorite)
         favoriteStatus(favorite)
       }
     },
@@ -330,7 +256,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
     },
     'deletion': (deletion) => {
       const uri = deletion.uri
-      updateMaxId(deletion)
 
       // Remove possible notification
       const status = find(allStatuses, {uri})
@@ -375,23 +300,7 @@ export const mutations = {
     each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status })
   },
   clearTimeline (state, { timeline }) {
-    const emptyTimeline = {
-      statuses: [],
-      statusesObject: {},
-      faves: [],
-      visibleStatuses: [],
-      visibleStatusesObject: {},
-      newStatusCount: 0,
-      maxId: 0,
-      minVisibleId: 0,
-      loading: false,
-      followers: [],
-      friends: [],
-      viewing: 'statuses',
-      flushMarker: 0
-    }
-
-    state.timelines[timeline] = emptyTimeline
+    state.timelines[timeline] = emptyTl()
   },
   setFavorited (state, { status, value }) {
     const newStatus = state.allStatusesObject[status.id]
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index a4a80df0..bb5fdc2e 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -30,7 +30,7 @@ const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false
 
   return apiService.fetchTimeline(args)
     .then((statuses) => {
-      if (!older && statuses.length >= 20) {
+      if (!older && statuses.length >= 20 && !timelineData.loading) {
         store.dispatch('queueFlush', { timeline: timeline, id: timelineData.maxId })
       }
       update({store, statuses, timeline, showImmediately})