loads decks from indexedDB
This commit is contained in:
parent
e37d0db517
commit
c6e731d473
5 changed files with 105 additions and 64 deletions
59
src/state.ts
59
src/state.ts
|
@ -1,59 +0,0 @@
|
|||
import { reactive, ref, Ref } from 'vue'
|
||||
import { State, Notification, IDeck } from './types'
|
||||
import { defaultDeck } from './lib/deck'
|
||||
import { DeckDB } from './storage'
|
||||
|
||||
interface Payload {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const state: State = {
|
||||
settings: ref({}),
|
||||
decks: ref([]),
|
||||
notifications: ref([])
|
||||
}
|
||||
|
||||
/// actions are called like action['sub/foo'](state.sub, payload)
|
||||
export const stateActions = {
|
||||
'notifications/add' (notifications: Ref<Notification[]>, payload: Payload) {
|
||||
notifications.value.push({
|
||||
level: 'info',
|
||||
title: '',
|
||||
content: '',
|
||||
dismissed: false,
|
||||
...payload
|
||||
})
|
||||
},
|
||||
'notifications/dismiss' (notifications: Ref<Notification[]>, notification: Notification) {
|
||||
notification.dismissed = true
|
||||
notifications.value = notifications.value.filter(note => !note.dismissed)
|
||||
},
|
||||
'decks/new' (): IDeck {
|
||||
return defaultDeck()
|
||||
}
|
||||
}
|
||||
|
||||
export function useState (field: string): { [key: string]: any } {
|
||||
const collection = ref(state[field])
|
||||
const actions = Object.keys(stateActions).reduce((acc, key) => {
|
||||
if (key.startsWith(`${field}/`)) {
|
||||
const newKey = key.split('/')[1]
|
||||
acc[newKey] = (payload: Payload) => stateActions[key](collection, payload)
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return { collection, actions }
|
||||
}
|
||||
|
||||
const deckDB = new DeckDB()
|
||||
console.log('deck db', deckDB)
|
||||
deckDB.putDeck(defaultDeck()).then(() => {
|
||||
return deckDB.decks.toArray()
|
||||
}).then(decks => {
|
||||
console.log('Created Decks DB', decks)
|
||||
}).catch(error => {
|
||||
console.error('Cannot use in-browser database. This happens for example in Firefox when used in private mode. Unfortunately there is no fix. Please use this app outside of private mode. You can read more about the issue here: https://bugzilla.mozilla.org/show_bug.cgi?id=781982 and here: https://bugzilla.mozilla.org/show_bug.cgi?id=1639542', error)
|
||||
})
|
||||
|
||||
export default reactive(state)
|
28
src/state/actions.ts
Normal file
28
src/state/actions.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { Ref } from 'vue'
|
||||
import { Notification, IDeck, KV } from '../types'
|
||||
import { defaultDeck } from '../lib/deck'
|
||||
|
||||
/// actions are called like action['sub/foo'](state.sub, payload)
|
||||
export default {
|
||||
|
||||
// NOTIFICATION ACTIONS
|
||||
'notifications/add' (notifications: Ref<Notification[]>, payload: KV<any>) {
|
||||
notifications.value.push({
|
||||
level: 'info',
|
||||
title: '',
|
||||
content: '',
|
||||
dismissed: false,
|
||||
...payload
|
||||
})
|
||||
},
|
||||
|
||||
'notifications/dismiss' (notifications: Ref<Notification[]>, notification: Notification) {
|
||||
notification.dismissed = true
|
||||
notifications.value = notifications.value.filter(note => !note.dismissed)
|
||||
},
|
||||
|
||||
// DECK ACTIONS
|
||||
'decks/new' (): IDeck {
|
||||
return defaultDeck()
|
||||
}
|
||||
}
|
46
src/state/index.ts
Normal file
46
src/state/index.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { reactive, ref } from 'vue'
|
||||
import { State, KV } from '../types'
|
||||
import { DeckDB } from '../storage'
|
||||
import stateActions from './actions'
|
||||
import { defaultDeck } from '../lib/deck'
|
||||
import { defaultCard } from '../lib/card'
|
||||
|
||||
const state: State = {
|
||||
settings: ref({}),
|
||||
decks: ref([]),
|
||||
notifications: ref([]),
|
||||
initialized: ref(false)
|
||||
}
|
||||
|
||||
export function useState (field: string): { [key: string]: any } {
|
||||
const collection = ref(state[field])
|
||||
const actions = Object.keys(stateActions).reduce((acc, key) => {
|
||||
if (key.startsWith(`${field}/`)) {
|
||||
const newKey = key.split('/')[1]
|
||||
acc[newKey] = (payload: KV<any>) => stateActions[key](collection, payload)
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return { collection, actions }
|
||||
}
|
||||
|
||||
export const deckDB = new DeckDB()
|
||||
deckDB.getDecks().then(decks => {
|
||||
state.decks.value = decks
|
||||
})
|
||||
|
||||
const testDeck = defaultDeck()
|
||||
testDeck.cards.push(defaultCard())
|
||||
|
||||
/*
|
||||
deckDB.putDeck(testDeck).then(() => {
|
||||
return deckDB.getDecks()
|
||||
}).then(decks => {
|
||||
console.log('Created Decks DB', decks)
|
||||
}).catch(error => {
|
||||
console.error('Cannot use in-browser database. This happens for example in Firefox when used in private mode. Unfortunately there is no fix. Please use this app outside of private mode. You can read more about the issue here: https://bugzilla.mozilla.org/show_bug.cgi?id=781982 and here: https://bugzilla.mozilla.org/show_bug.cgi?id=1639542', error)
|
||||
})
|
||||
*/
|
||||
|
||||
export default reactive(state)
|
|
@ -1,16 +1,16 @@
|
|||
import Dexie from 'dexie'
|
||||
import { IDeck, ICard } from './types'
|
||||
import { IDeck, ICard, CardSize, Arrangement, PageSize } from './types'
|
||||
|
||||
interface IDeckTable {
|
||||
id?: number;
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
color: string;
|
||||
icon: string;
|
||||
cards: number[]; // array of card IDs
|
||||
cardSize: string;
|
||||
arrangement: string;
|
||||
pageSize: string;
|
||||
cardSize: CardSize;
|
||||
arrangement: Arrangement;
|
||||
pageSize: PageSize;
|
||||
roundedCorners: boolean;
|
||||
}
|
||||
|
||||
|
@ -35,11 +35,23 @@ export class DeckDB extends Dexie {
|
|||
console.log('deck db initialized', this)
|
||||
}
|
||||
|
||||
// explicitely ignore ID and add deck to database
|
||||
public async addDeck (deck: IDeck) {
|
||||
const deckWithoutId: IDeckTable = {
|
||||
...deck,
|
||||
cards: deck.cards.map(card => card.id)
|
||||
}
|
||||
delete deckWithoutId.id
|
||||
await this.decks.add(deckWithoutId)
|
||||
}
|
||||
|
||||
// add or update deck
|
||||
public async putDeck (deck: IDeck) {
|
||||
const cards = await this.cards.bulkPut(deck.cards, { allKeys: true })
|
||||
await this.decks.put({ ...deck, cards })
|
||||
}
|
||||
|
||||
// add or update card
|
||||
public async putCard (card: ICard, deckId: number) {
|
||||
const cardId = await this.cards.put(card)
|
||||
const deck = await this.decks.get(deckId)
|
||||
|
@ -49,4 +61,17 @@ export class DeckDB extends Dexie {
|
|||
await this.decks.put(deck)
|
||||
}
|
||||
}
|
||||
|
||||
public async getDecks () {
|
||||
const decks = await this.decks.toArray()
|
||||
|
||||
return Promise.all(decks.map(async deckTable => {
|
||||
const cardIds = deckTable.cards
|
||||
const deck: IDeck = {
|
||||
...deckTable,
|
||||
cards: await this.cards.bulkGet(cardIds)
|
||||
}
|
||||
return deck
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,4 +82,5 @@ export interface State {
|
|||
settings: Ref<Settings>;
|
||||
decks: Ref<IDeck[]>;
|
||||
notifications: Ref<Notification[]>;
|
||||
initialized: Ref<boolean>;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue