more offline work

This commit is contained in:
Nolan Lawson 2018-01-18 21:25:12 -08:00
parent cbcb270ed3
commit a2f0f9bc39
5 changed files with 55 additions and 24 deletions

View file

@ -1,4 +1,4 @@
<:Window bind:innerHeight bind:online /> <:Window bind:innerHeight />
<Nav page={{page}} /> <Nav page={{page}} />
<div class="container" on:scroll="onScroll(event)" ref:node> <div class="container" on:scroll="onScroll(event)" ref:node>
@ -12,27 +12,15 @@
import debounce from 'lodash/debounce' import debounce from 'lodash/debounce'
import throttle from 'lodash/throttle' import throttle from 'lodash/throttle'
import { toast } from '../_utils/toast'
import { mark, stop } from '../_utils/marks' import { mark, stop } from '../_utils/marks'
const SCROLL_EVENT_DELAY = 300 const SCROLL_EVENT_DELAY = 300
const RESIZE_EVENT_DELAY = 700 const RESIZE_EVENT_DELAY = 700
const OFFLINE_DELAY = 1000
const notifyOffline = debounce(() => {
toast.say('You appear to be offline. You can still read toots while offline.')
}, OFFLINE_DELAY)
export default { export default {
oncreate() { oncreate() {
mark('onCreate Layout') mark('onCreate Layout')
let node = this.refs.node let node = this.refs.node
this.observe('online', online => {
document.body.classList.toggle('offline', !online)
if (!online) {
notifyOffline()
}
})
this.observe('innerHeight', debounce(() => { this.observe('innerHeight', debounce(() => {
// respond to window resize events // respond to window resize events
this.store.set({ this.store.set({

View file

@ -25,10 +25,15 @@ const importIndexedDBGetAllShim = () => import(
/* webpackChunkName: 'indexeddb-getall-shim' */ 'indexeddb-getall-shim' /* webpackChunkName: 'indexeddb-getall-shim' */ 'indexeddb-getall-shim'
) )
const importOfflineNotification = () => import(
/* webpackHunkName: 'offlineNotification' */ '../_utils/offlineNotification'
)
export { export {
importURLSearchParams, importURLSearchParams,
importTimeline, importTimeline,
importIntersectionObserver, importIntersectionObserver,
importRequestIdleCallback, importRequestIdleCallback,
importIndexedDBGetAllShim importIndexedDBGetAllShim,
importOfflineNotification
} }

View file

@ -1,7 +1,29 @@
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
import padStart from 'lodash/padStart'
const STORE = 'statuses' const STORE = 'statuses'
function toPaddedBigInt(id) {
return padStart(id, 30, '0')
}
function toReversePaddedBigInt(id) {
let bigInt = toPaddedBigInt(id)
let res = ''
for (let i = 0; i < bigInt.length; i++) {
res += (9 - parseInt(bigInt.charAt(i), 10)).toString(10)
}
return res
}
function transformStatusForStorage(status) {
status = cloneDeep(status)
status.pinafore_id_as_big_int = toPaddedBigInt(status.id)
status.pinafore_id_as_negative_big_int = toReversePaddedBigInt(status.id)
status.pinafore_stale = true
return status
}
const dbPromise = new Promise((resolve, reject) => { const dbPromise = new Promise((resolve, reject) => {
let req = indexedDB.open(STORE, 1) let req = indexedDB.open(STORE, 1)
req.onerror = reject req.onerror = reject
@ -20,21 +42,13 @@ const dbPromise = new Promise((resolve, reject) => {
req.onsuccess = () => resolve(req.result) req.onsuccess = () => resolve(req.result)
}) })
function transformStatusForStorage(status) {
status = cloneDeep(status)
status.pinafore_id_as_big_int = parseInt(status.id, 10)
status.pinafore_id_as_negative_big_int = -parseInt(status.id, 10)
status.pinafore_stale = true
return status
}
export async function getTimelineAfter(max_id = null, limit = 20) { export async function getTimelineAfter(max_id = null, limit = 20) {
const db = await dbPromise const db = await dbPromise
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
const tx = db.transaction(STORE, 'readonly') const tx = db.transaction(STORE, 'readonly')
const store = tx.objectStore(STORE) const store = tx.objectStore(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 : -parseInt(max_id, 10) let sinceAsNegativeBigInt = max_id === null ? null : toReversePaddedBigInt(max_id)
let query = sinceAsNegativeBigInt === null ? null : IDBKeyRange.lowerBound(sinceAsNegativeBigInt, false) let query = sinceAsNegativeBigInt === null ? null : IDBKeyRange.lowerBound(sinceAsNegativeBigInt, false)
let res let res

View file

@ -0,0 +1,21 @@
import debounce from 'lodash/debounce'
import { toast } from './toast'
const OFFLINE_DELAY = 1000
const notifyOffline = debounce(() => {
toast.say('You appear to be offline. You can still read toots while offline.')
}, OFFLINE_DELAY)
const observe = online => {
if (!localStorage.store_currentInstance) {
return // only show notification for logged-in users
}
document.body.classList.toggle('offline', !online)
if (!online) {
notifyOffline()
}
}
window.addEventListener('offline', () => observe(false));
window.addEventListener('online', () => observe(true));

View file

@ -1,10 +1,12 @@
import { init } from 'sapper/runtime.js' import { init } from 'sapper/runtime.js'
import { toast } from '../routes/_utils/toast' import { toast } from '../routes/_utils/toast'
import { import {
importURLSearchParams, importURLSearchParams,
importIntersectionObserver, importIntersectionObserver,
importRequestIdleCallback, importRequestIdleCallback,
importIndexedDBGetAllShim, importIndexedDBGetAllShim,
importOfflineNotification
} from '../routes/_utils/asyncModules' } from '../routes/_utils/asyncModules'
// polyfills // polyfills
@ -24,5 +26,6 @@ Promise.all([
} }
} }
} }
}) })
importOfflineNotification()