refine offline mode

This commit is contained in:
Nolan Lawson 2018-01-19 18:04:31 -08:00
parent 6564880aa8
commit 0dbfbcf0f2
2 changed files with 31 additions and 25 deletions

View File

@ -19,6 +19,7 @@
import { mergeStatuses } from '../_utils/statuses' import { mergeStatuses } from '../_utils/statuses'
import { mark, stop } from '../_utils/marks' import { mark, stop } from '../_utils/marks'
import { timelines } from '../_static/timelines' import { timelines } from '../_static/timelines'
import { toast } from '../_utils/toast'
const database = worker() const database = worker()
@ -30,12 +31,7 @@
let instanceData = this.store.get('currentInstanceData') let instanceData = this.store.get('currentInstanceData')
let online = this.get('online') let online = this.get('online')
let timeline = this.get('timeline') let timeline = this.get('timeline')
let statuses = online ? let statuses = await this.fetchStatusesAndPossiblyFallBack()
await getTimeline(instanceName, instanceData.access_token, timeline, null, FETCH_LIMIT) :
await database.getTimeline(instanceName, timeline, null, FETCH_LIMIT)
if (online) {
database.insertStatuses(instanceName, timeline, statuses)
}
this.addStatuses(statuses) this.addStatuses(statuses)
this.set({initialized: true}) this.set({initialized: true})
this.fire('initialized') this.fire('initialized')
@ -52,7 +48,8 @@
key: status.id key: status.id
})), })),
lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id, lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id,
label: (timeline, $currentInstance) => `${timelines[timeline].label} timeline for ${$currentInstance}` label: (timeline, $currentInstance) => `${timelines[timeline].label} timeline for ${$currentInstance}`,
anyStatusesAreStale: (statuses) => statuses.some(status => status.pinafore_stale)
}, },
store: () => store, store: () => store,
components: { components: {
@ -70,21 +67,8 @@
} }
mark('onScrollToBottom') mark('onScrollToBottom')
this.set({ runningUpdate: true }) this.set({ runningUpdate: true })
let lastStatusId = this.get('lastStatusId') let newStatuses = await this.fetchStatusesAndPossiblyFallBack()
let instanceName = this.store.get('currentInstance') this.addStatuses(newStatuses)
let instanceData = this.store.get('currentInstanceData')
let online = this.get('online')
let timeline = this.get('timeline')
let newStatuses = online ?
await getTimeline(instanceName, instanceData.access_token, timeline, lastStatusId, FETCH_LIMIT) :
await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
if (online) {
database.insertStatuses(instanceName, timeline, newStatuses)
}
let statuses = this.get('statuses')
if (statuses) {
this.addStatuses(newStatuses)
}
this.set({ runningUpdate: false }) this.set({ runningUpdate: false })
stop('onScrollToBottom') stop('onScrollToBottom')
}, },
@ -98,6 +82,28 @@
} }
let merged = mergeStatuses(statuses, newStatuses) let merged = mergeStatuses(statuses, newStatuses)
this.set({ statuses: merged }) this.set({ statuses: merged })
},
async fetchStatusesAndPossiblyFallBack() {
let online = this.get('online')
let instanceName = this.store.get('currentInstance')
let instanceData = this.store.get('currentInstanceData')
let timeline = this.get('timeline')
let lastStatusId = this.get('lastStatusId')
let anyStatusesAreStale = this.get('anyStatusesAreStale')
let statuses
if (!online || anyStatusesAreStale) { // if we're in offline mode, stay in offline mode to avoid weirdness
statuses = await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
} else {
try {
statuses = await getTimeline(instanceName, instanceData.access_token, timeline, lastStatusId, FETCH_LIMIT)
/* no await */ database.insertStatuses(instanceName, timeline, statuses)
} catch (e) {
console.error(e)
toast.say('Internet request failed. Showing offline content.')
statuses = await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
}
}
return statuses
} }
} }
} }

View File

@ -2,14 +2,14 @@ import { cleanupOldStatuses } from './cleanup'
import { OBJECT_STORE, getDatabase, doTransaction } from './shared' import { OBJECT_STORE, getDatabase, doTransaction } from './shared'
import { toReversePaddedBigInt, transformStatusForStorage } from './utils' import { toReversePaddedBigInt, transformStatusForStorage } from './utils'
export async function getTimeline(instanceName, timeline, max_id = null, limit = 20) { export async function getTimeline(instanceName, timeline, maxId = null, limit = 20) {
const db = await getDatabase(instanceName, timeline) const db = await getDatabase(instanceName, timeline)
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
const tx = db.transaction(OBJECT_STORE, 'readonly') const tx = db.transaction(OBJECT_STORE, 'readonly')
const store = tx.objectStore(OBJECT_STORE) const store = tx.objectStore(OBJECT_STORE)
const index = store.index('pinafore_id_as_negative_big_int') const index = store.index('pinafore_id_as_negative_big_int')
let sinceAsNegativeBigInt = max_id === null ? null : toReversePaddedBigInt(max_id) let sinceAsNegativeBigInt = maxId ? toReversePaddedBigInt(maxId) : null
let query = sinceAsNegativeBigInt === null ? null : IDBKeyRange.lowerBound(sinceAsNegativeBigInt, false) let query = sinceAsNegativeBigInt ? IDBKeyRange.lowerBound(sinceAsNegativeBigInt, false) : null
let res let res
index.getAll(query, limit).onsuccess = (e) => { index.getAll(query, limit).onsuccess = (e) => {