use database for account caching

This commit is contained in:
Nolan Lawson 2018-01-23 09:21:21 -08:00
parent 47c058a19f
commit 48d47160d7
5 changed files with 46 additions and 36 deletions

View file

@ -38,22 +38,6 @@
this.fire('initialized') this.fire('initialized')
})) }))
}) })
this.observe('statuses', statuses => {
let cachedAccountNames = this.store.get('cachedAccountNames') || {}
for (let status of statuses) {
cachedAccountNames[status.account.id] = {
username: status.account.username,
acct: status.account.acct
}
if (status.reblog) {
cachedAccountNames[status.reblog.account.id] = {
username: status.reblog.account.username,
acct: status.reblog.account.acct
}
}
}
this.store.set({'cachedAccountNames': cachedAccountNames})
})
}, },
data: () => ({ data: () => ({
StatusListItem: StatusListItem, StatusListItem: StatusListItem,

View file

@ -1,3 +1,4 @@
export const STATUSES_STORE = 'statuses' export const STATUSES_STORE = 'statuses'
export const TIMELINE_STORE = 'timelines' export const TIMELINE_STORE = 'timelines'
export const META_STORE = 'meta' export const META_STORE = 'meta'
export const ACCOUNTS_STORE= 'accounts'

View file

@ -10,7 +10,7 @@ import {
import { import {
META_STORE, META_STORE,
TIMELINE_STORE, TIMELINE_STORE,
STATUSES_STORE STATUSES_STORE, ACCOUNTS_STORE
} from './constants' } from './constants'
export async function getTimeline(instanceName, timeline, maxId = null, limit = 20) { export async function getTimeline(instanceName, timeline, maxId = null, limit = 20) {
@ -38,16 +38,19 @@ export async function getTimeline(instanceName, timeline, maxId = null, limit =
export async function insertStatuses(instanceName, timeline, statuses) { export async function insertStatuses(instanceName, timeline, statuses) {
const db = await getDatabase(instanceName, timeline) const db = await getDatabase(instanceName, timeline)
await dbPromise(db, [TIMELINE_STORE, STATUSES_STORE], 'readwrite', (stores) => { await dbPromise(db, [TIMELINE_STORE, STATUSES_STORE, ACCOUNTS_STORE], 'readwrite', (stores) => {
let [ timelineStore, statusesStore ] = stores let [ timelineStore, statusesStore, accountsStore ] = stores
for (let status of statuses) { for (let status of statuses) {
statusesStore.put(status) statusesStore.put(status)
// reverse chronological order, prefixed by timeline // reverse chronological order, prefixed by timeline
let id = timeline + '\u0000' + toReversePaddedBigInt(status.id)
timelineStore.put({ timelineStore.put({
id: id, id: (timeline + '\u0000' + toReversePaddedBigInt(status.id)),
statusId: status.id statusId: status.id
}) })
accountsStore.put(status.account)
if (status.reblog) {
accountsStore.put(status.reblog.account)
}
} }
}) })
} }
@ -71,6 +74,15 @@ export async function setInstanceVerifyCredentials(instanceName, verifyCredentia
}) })
} }
export async function getAccount(instanceName, accountId) {
const db = await getDatabase(instanceName)
return await dbPromise(db, ACCOUNTS_STORE, 'readonly', (store, callback) => {
store.get(accountId).onsuccess = (e) => {
callback(e.target.result && e.target.result)
}
})
}
export async function clearDatabaseForInstance(instanceName) { export async function clearDatabaseForInstance(instanceName) {
await deleteDatabase(instanceName) await deleteDatabase(instanceName)
} }

View file

@ -4,7 +4,8 @@ const databaseCache = {}
import { import {
META_STORE, META_STORE,
TIMELINE_STORE, TIMELINE_STORE,
STATUSES_STORE STATUSES_STORE,
ACCOUNTS_STORE
} from './constants' } from './constants'
export function getDatabase(instanceName) { export function getDatabase(instanceName) {
@ -23,6 +24,7 @@ export function getDatabase(instanceName) {
let db = req.result; let db = req.result;
db.createObjectStore(META_STORE, {keyPath: 'key'}) db.createObjectStore(META_STORE, {keyPath: 'key'})
db.createObjectStore(STATUSES_STORE, {keyPath: 'id'}) db.createObjectStore(STATUSES_STORE, {keyPath: 'id'})
db.createObjectStore(ACCOUNTS_STORE, {keyPath: 'id'})
let timelineStore = db.createObjectStore(TIMELINE_STORE, {keyPath: 'id'}) let timelineStore = db.createObjectStore(TIMELINE_STORE, {keyPath: 'id'})
timelineStore.createIndex('statusId', 'statusId') timelineStore.createIndex('statusId', 'statusId')
} }

View file

@ -1,14 +1,14 @@
<:Head> <:Head>
<title>{{'Pinafore ' + (cachedProfileName || profileName || '')}}</title> <title>{{'Pinafore ' + profileName}}</title>
</:Head> </:Head>
<Layout page='tags' <Layout page='tags'
dynamicPage="{{cachedProfileName || profileName || ''}}" dynamicPage="{{profileName}}"
dynamicHref="/accounts/{{params.accountId}}" dynamicHref="/accounts/{{params.accountId}}"
dynamicLabel="{{cachedShortProfileName || shortProfileName || ''}}" dynamicLabel="{{shortProfileName}}"
dynamicIcon="#fa-user" > dynamicIcon="#fa-user" >
{{#if $isUserLoggedIn}} {{#if $isUserLoggedIn}}
<DynamicPageBanner title="{{cachedProfileName || profileName || ''}}" /> <DynamicPageBanner title="{{profileName}}" />
<LazyTimeline timeline='account/{{params.accountId}}' /> <LazyTimeline timeline='account/{{params.accountId}}' />
{{else}} {{else}}
<HiddenFromSSR> <HiddenFromSSR>
@ -28,28 +28,39 @@
import HiddenFromSSR from '../_components/HiddenFromSSR' import HiddenFromSSR from '../_components/HiddenFromSSR'
import DynamicPageBanner from '../_components/DynamicPageBanner.html' import DynamicPageBanner from '../_components/DynamicPageBanner.html'
import { getAccount } from '../_utils/mastodon/user' import { getAccount } from '../_utils/mastodon/user'
import { database } from '../_utils/database/database'
export default { export default {
async oncreate() { oncreate() {
let currentInstance = this.store.get('currentInstance') let currentInstance = this.store.get('currentInstance')
let accessToken = this.store.get('accessToken') let accessToken = this.store.get('accessToken')
let accountId = this.get('params').accountId let accountId = this.get('params').accountId
let account = await getAccount(currentInstance, accessToken, accountId) database.getAccount(currentInstance, accountId).then(account => {
this.set({account: account}) this.set({cachedAccount: account})
})
getAccount(currentInstance, accessToken, accountId).then(account => {
this.set({account: account})
})
}, },
store: () => store, store: () => store,
computed: { computed: {
profileName: (account) => { remoteProfileName: (account) => {
return account && ('@' + account.acct) return account && ('@' + account.acct)
}, },
shortProfileName: (account) => { remoteShortProfileName: (account) => {
return account && ('@' + account.username) return account && ('@' + account.username)
}, },
cachedProfileName: ($cachedAccountNames, params) => { cachedProfileName: (cachedAccount) => {
return $cachedAccountNames && $cachedAccountNames[params.accountId] && ('@' + $cachedAccountNames[params.accountId].acct) return cachedAccount && ('@' + cachedAccount.acct)
}, },
cachedShortProfileName: ($cachedAccountNames, params) => { cachedShortProfileName: (cachedAccount) => {
return $cachedAccountNames && $cachedAccountNames[params.accountId] && ('@' + $cachedAccountNames[params.accountId].username) return cachedAccount && ('@' + cachedAccount.username)
},
profileName: (remoteProfileName, cachedProfileName) => {
return remoteProfileName || cachedProfileName || ''
},
shortProfileName: (remoteShortProfileName, cachedShortProfileName) => {
return remoteShortProfileName || cachedShortProfileName || ''
} }
}, },
components: { components: {