From 562a58f03011be47b65ab631de146b3d74d1de19 Mon Sep 17 00:00:00 2001
From: Nolan Lawson <nolan@nolanlawson.com>
Date: Sun, 4 Mar 2018 12:55:45 -0800
Subject: [PATCH] fix node removal with no parent caused by focus changes

---
 .../computations/instanceComputations.js      | 17 ------
 .../computations/timelineComputations.js      | 54 +++++++++++++------
 routes/_store/mixins/timelineMixins.js        | 21 +++++---
 3 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/routes/_store/computations/instanceComputations.js b/routes/_store/computations/instanceComputations.js
index 7d8eaafd..b0718df5 100644
--- a/routes/_store/computations/instanceComputations.js
+++ b/routes/_store/computations/instanceComputations.js
@@ -60,21 +60,4 @@ export function instanceComputations (store) {
       return list ? list.title : ''
     }
   )
-
-  store.compute('numberOfNotifications',
-    ['timelines', 'currentInstance', 'currentTimeline'],
-    (timelines, currentInstance, currentTimeline) => {
-      return currentTimeline !== 'notifications' &&
-        timelines &&
-        timelines[currentInstance] &&
-        timelines[currentInstance].notifications &&
-        timelines[currentInstance].notifications.itemIdsToAdd &&
-        timelines[currentInstance].notifications.itemIdsToAdd.length
-    }
-  )
-
-  store.compute('hasNotifications',
-    ['numberOfNotifications'],
-    (numberOfNotifications) => !!numberOfNotifications
-  )
 }
diff --git a/routes/_store/computations/timelineComputations.js b/routes/_store/computations/timelineComputations.js
index 0eb37a6b..30dc74dc 100644
--- a/routes/_store/computations/timelineComputations.js
+++ b/routes/_store/computations/timelineComputations.js
@@ -1,23 +1,45 @@
 
-function computeForTimeline (store, key) {
-  store.compute(key, ['currentTimelineData'], (currentTimelineData) => currentTimelineData[key])
+function computeForTimeline (store, key, defaultValue) {
+  store.compute(key,
+    ['currentInstance', 'currentTimeline', `timelineData_${key}`],
+    (currentInstance, currentTimeline, root) => {
+      let instanceData = root && root[currentInstance]
+      return (currentTimeline && instanceData && currentTimeline in instanceData) ? instanceData[currentTimeline] : defaultValue
+    })
 }
 
 export function timelineComputations (store) {
-  store.compute('currentTimelineData', ['currentInstance', 'currentTimeline', 'timelines'],
-    (currentInstance, currentTimeline, timelines) => {
-      return ((timelines && timelines[currentInstance]) || {})[currentTimeline] || {}
-    })
+  computeForTimeline(store, 'timelineItemIds', null)
+  computeForTimeline(store, 'runningUpdate', false)
+  computeForTimeline(store, 'initialized', false)
+  computeForTimeline(store, 'lastFocusedElementSelector', null)
+  computeForTimeline(store, 'ignoreBlurEvents', false)
+  computeForTimeline(store, 'itemIdsToAdd', null)
+  computeForTimeline(store, 'showHeader', false)
+  computeForTimeline(store, 'shouldShowHeader', false)
 
-  computeForTimeline(store, 'timelineItemIds')
-  computeForTimeline(store, 'runningUpdate')
-  computeForTimeline(store, 'initialized')
-  computeForTimeline(store, 'lastFocusedElementSelector')
-  computeForTimeline(store, 'ignoreBlurEvents')
-  computeForTimeline(store, 'itemIdsToAdd')
-  computeForTimeline(store, 'showHeader')
-  computeForTimeline(store, 'shouldShowHeader')
+  store.compute('firstTimelineItemId', ['timelineItemIds'], (timelineItemIds) => {
+    return timelineItemIds && timelineItemIds[0]
+  })
+  store.compute('lastTimelineItemId', ['timelineItemIds'], (timelineItemIds) => {
+    return timelineItemIds && timelineItemIds[timelineItemIds.length - 1]
+  })
 
-  store.compute('firstTimelineItemId', ['timelineItemIds'], (timelineItemIds) => timelineItemIds && timelineItemIds.length && timelineItemIds[0])
-  store.compute('lastTimelineItemId', ['timelineItemIds'], (timelineItemIds) => timelineItemIds && timelineItemIds.length && timelineItemIds[timelineItemIds.length - 1])
+  store.compute('numberOfNotifications',
+    [`timelineData_itemIdsToAdd`, 'currentInstance', 'currentTimeline'],
+    (root, currentInstance, currentTimeline) => {
+      return (
+        currentTimeline !== 'notifications' &&
+        root &&
+        root[currentInstance] &&
+        root[currentInstance].notifications &&
+        root[currentInstance].notifications.length
+      ) || 0
+    }
+  )
+
+  store.compute('hasNotifications',
+    ['numberOfNotifications'],
+    (numberOfNotifications) => !!numberOfNotifications
+  )
 }
diff --git a/routes/_store/mixins/timelineMixins.js b/routes/_store/mixins/timelineMixins.js
index 9fd09e80..924dbbe4 100644
--- a/routes/_store/mixins/timelineMixins.js
+++ b/routes/_store/mixins/timelineMixins.js
@@ -1,16 +1,21 @@
 export function timelineMixins (Store) {
   Store.prototype.setForTimeline = function (instanceName, timelineName, obj) {
-    let timelines = this.get('timelines') || {}
-    let timelineData = timelines[instanceName] || {}
-    timelineData[timelineName] = Object.assign(timelineData[timelineName] || {}, obj)
-    timelines[instanceName] = timelineData
-    this.set({timelines: timelines})
+    let valuesToSet = {}
+    for (let key of Object.keys(obj)) {
+      let rootKey = `timelineData_${key}`
+      let root = this.get(rootKey) || {}
+      let instanceData = root[instanceName] = root[instanceName] || {}
+      instanceData[timelineName] = obj[key]
+      valuesToSet[rootKey] = root
+    }
+
+    this.set(valuesToSet)
   }
 
   Store.prototype.getForTimeline = function (instanceName, timelineName, key) {
-    let timelines = this.get('timelines') || {}
-    let timelineData = timelines[instanceName] || {}
-    return (timelineData[timelineName] || {})[key]
+    let rootKey = `timelineData_${key}`
+    let root = this.get(rootKey)
+    return root && root[instanceName] && root[instanceName][timelineName]
   }
 
   Store.prototype.setForCurrentTimeline = function (obj) {