From 56ba259ccf2bdb39451e8d4f0794598624e8613a Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Thu, 26 Sep 2019 09:07:49 -0700 Subject: [PATCH] fix: fix basic login - clear store on log out (#1545) fixes #1544 --- src/routes/_actions/instances.js | 52 +++++++++++++------ src/routes/_actions/timeline.js | 1 + .../virtualList/VirtualListContainer.html | 4 +- .../virtualList/virtualListStore.js | 37 +++++++++---- src/routes/_database/timelines/insertion.js | 1 + src/routes/_store/mixins/autosuggestMixins.js | 11 ++++ src/routes/_store/mixins/timelineMixins.js | 11 ++++ src/routes/_thirdparty/quick-lru/quick-lru.js | 11 ++++ src/routes/_utils/asyncModules.js | 4 ++ 9 files changed, 105 insertions(+), 27 deletions(-) diff --git a/src/routes/_actions/instances.js b/src/routes/_actions/instances.js index 2dbd8e51..384dbae8 100644 --- a/src/routes/_actions/instances.js +++ b/src/routes/_actions/instances.js @@ -6,6 +6,7 @@ import { goto } from '../../../__sapper__/client' import { cacheFirstUpdateAfter } from '../_utils/sync' import { getInstanceInfo } from '../_api/instance' import { database } from '../_database/database' +import { importVirtualListStore } from '../_utils/asyncModules' export function changeTheme (instanceName, newTheme) { const { instanceThemes } = store.get() @@ -33,29 +34,50 @@ export function switchToInstance (instanceName) { export async function logOutOfInstance (instanceName, message = `Logged out of ${instanceName}`) { const { - loggedInInstances, - instanceThemes, - loggedInInstancesInOrder, composeData, - currentInstance + currentInstance, + customEmoji, + instanceInfos, + instanceLists, + instanceThemes, + loggedInInstances, + loggedInInstancesInOrder, + verifyCredentials } = store.get() loggedInInstancesInOrder.splice(loggedInInstancesInOrder.indexOf(instanceName), 1) - const newInstance = instanceName === currentInstance - ? loggedInInstancesInOrder[0] - : currentInstance - delete loggedInInstances[instanceName] - delete instanceThemes[instanceName] - delete composeData[instanceName] + const newInstance = instanceName === currentInstance ? loggedInInstancesInOrder[0] : currentInstance + const objectsToClear = [ + composeData, + customEmoji, + instanceInfos, + instanceLists, + instanceThemes, + loggedInInstances, + verifyCredentials + ] + for (const obj of objectsToClear) { + delete obj[instanceName] + } store.set({ - loggedInInstances: loggedInInstances, - instanceThemes: instanceThemes, - loggedInInstancesInOrder: loggedInInstancesInOrder, + composeData, currentInstance: newInstance, - searchResults: null, + customEmoji, + instanceInfos, + instanceLists, + instanceThemes, + loggedInInstances, + loggedInInstancesInOrder, queryInSearch: '', - composeData: composeData + searchResults: null, + timelineInitialized: false, + timelinePreinitialized: false, + verifyCredentials }) + store.clearTimelineDataForInstance(instanceName) + store.clearAutosuggestDataForInstance(instanceName) store.save() + const { virtualListStore } = await importVirtualListStore() + virtualListStore.clearRealmByPrefix(currentInstance + '/') // TODO: this is a hacky way to clear the vlist cache toast.say(message) const { enableGrayscale } = store.get() switchToTheme(instanceThemes[newInstance], enableGrayscale) diff --git a/src/routes/_actions/timeline.js b/src/routes/_actions/timeline.js index b849ce8e..5d4237ef 100644 --- a/src/routes/_actions/timeline.js +++ b/src/routes/_actions/timeline.js @@ -108,6 +108,7 @@ export async function setupTimeline () { timelineItemSummariesAreStale, currentTimeline } = store.get() + console.log({ timelineItemSummaries, timelineItemSummariesAreStale, currentTimeline }) if (!timelineItemSummaries || timelineItemSummariesAreStale || currentTimeline.startsWith('status/')) { diff --git a/src/routes/_components/virtualList/VirtualListContainer.html b/src/routes/_components/virtualList/VirtualListContainer.html index faefac60..e4521702 100644 --- a/src/routes/_components/virtualList/VirtualListContainer.html +++ b/src/routes/_components/virtualList/VirtualListContainer.html @@ -40,7 +40,7 @@ scrollContainer.scrollTop = scrollTop stop('set scrollTop') doubleRAF(() => { - console.log('initialized VirtualList') + console.log('initialized VirtualList (1)') this.fire('initialized') }) }) @@ -50,7 +50,7 @@ this.fire('noNeedToScroll') this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => { if (allVisibleItemsHaveHeight) { - console.log('initialized VirtualList') + console.log('initialized VirtualList (2)') this.fire('initialized') } }) diff --git a/src/routes/_components/virtualList/virtualListStore.js b/src/routes/_components/virtualList/virtualListStore.js index 3b4dbdda..98e647c9 100644 --- a/src/routes/_components/virtualList/virtualListStore.js +++ b/src/routes/_components/virtualList/virtualListStore.js @@ -8,6 +8,21 @@ class VirtualListStore extends RealmStore { constructor (state) { super(state, /* maxSize */ 10) } + + // TODO: this is hacky + clearRealmByPrefix (prefix) { + const { realms } = this.get() + if (!realms) { + return + } + for (const key of realms.getAllKeys()) { + if (key.startsWith(prefix)) { + console.log('deleted realm', key) + realms.delete(key) + } + } + this.set({ realms }) + } } const virtualListStore = new VirtualListStore() @@ -103,17 +118,19 @@ virtualListStore.compute('allVisibleItemsHaveHeight', return true }) -if (process.browser && process.env.NODE_ENV !== 'production') { - window.virtualListStore = virtualListStore +if (process.browser) { + window.__virtualListStore = virtualListStore // for debugging - virtualListStore.on('state', ({ changed }) => { - if (changed.visibleItems) { - window.visibleItemsChangedCount = (window.visibleItemsChangedCount || 0) + 1 - } - if (changed.rawVisibleItems) { - window.rawVisibleItemsChangedCount = (window.rawVisibleItemsChangedCount || 0) + 1 - } - }) + if (process.env.NODE_ENV !== 'production') { // for extra debugging + virtualListStore.on('state', ({ changed }) => { + if (changed.visibleItems) { + window.visibleItemsChangedCount = (window.visibleItemsChangedCount || 0) + 1 + } + if (changed.rawVisibleItems) { + window.rawVisibleItemsChangedCount = (window.rawVisibleItemsChangedCount || 0) + 1 + } + }) + } } export { diff --git a/src/routes/_database/timelines/insertion.js b/src/routes/_database/timelines/insertion.js index 2e1492ff..0dae319b 100644 --- a/src/routes/_database/timelines/insertion.js +++ b/src/routes/_database/timelines/insertion.js @@ -110,6 +110,7 @@ async function insertStatusThread (instanceName, statusId, statuses) { } export async function insertTimelineItems (instanceName, timeline, timelineItems) { + console.log('insertTimelineItems', instanceName, timeline, timelineItems) /* no await */ scheduleCleanup() if (timeline === 'notifications' || timeline === 'notifications/mentions') { return insertTimelineNotifications(instanceName, timeline, timelineItems) diff --git a/src/routes/_store/mixins/autosuggestMixins.js b/src/routes/_store/mixins/autosuggestMixins.js index f21efd9c..6d05177a 100644 --- a/src/routes/_store/mixins/autosuggestMixins.js +++ b/src/routes/_store/mixins/autosuggestMixins.js @@ -23,4 +23,15 @@ export function autosuggestMixins (Store) { const { currentInstance, currentComposeRealm } = this.get() return get(this.get()[`autosuggestData_${key}`], [currentInstance, currentComposeRealm]) } + + Store.prototype.clearAutosuggestDataForInstance = function (instanceName) { + const changes = {} + Object.entries(this.get()).forEach(([key, value]) => { + if (key.startsWith('autosuggestData_') && value) { + delete value[instanceName] + changes[key] = value + } + }) + this.set(changes) + } } diff --git a/src/routes/_store/mixins/timelineMixins.js b/src/routes/_store/mixins/timelineMixins.js index e4fe3ad1..898fa8f5 100644 --- a/src/routes/_store/mixins/timelineMixins.js +++ b/src/routes/_store/mixins/timelineMixins.js @@ -43,4 +43,15 @@ export function timelineMixins (Store) { return key.startsWith('status/') }) } + + Store.prototype.clearTimelineDataForInstance = function (instanceName) { + const changes = {} + Object.entries(this.get()).forEach(([key, value]) => { + if (key.startsWith('timelineData_') && value) { + delete value[instanceName] + changes[key] = value + } + }) + this.set(changes) + } } diff --git a/src/routes/_thirdparty/quick-lru/quick-lru.js b/src/routes/_thirdparty/quick-lru/quick-lru.js index 1dc132d6..def21406 100644 --- a/src/routes/_thirdparty/quick-lru/quick-lru.js +++ b/src/routes/_thirdparty/quick-lru/quick-lru.js @@ -87,6 +87,17 @@ export class QuickLRU extends EventEmitter { this._size = 0 } + getAllKeys () { + const set = new Set() + for (const key of this.cache.keys()) { + set.add(key) + } + for (const key of this.oldCache.keys()) { + set.add(key) + } + return set + } + // unused // * keys() { // for (const [key] of this) { diff --git a/src/routes/_utils/asyncModules.js b/src/routes/_utils/asyncModules.js index 4ed1c184..9436ade2 100644 --- a/src/routes/_utils/asyncModules.js +++ b/src/routes/_utils/asyncModules.js @@ -51,3 +51,7 @@ export const importComposeBox = () => import( export const importTesseractWorker = () => import( /* webpackChunkName: 'tesseractWorker' */ '../_utils/tesseractWorker.js' ).then(getDefault) + +export const importVirtualListStore = () => import( + /* webpackChunkName: 'virtualListStore.js' */ '../_components/virtualList/virtualListStore.js' +)