feat: save preferred skin tone
This commit is contained in:
parent
bdb62c07e2
commit
d5be361a49
|
@ -1,9 +1,9 @@
|
|||
import { assertNonEmptyString } from './utils/assertNonEmptyString'
|
||||
import { assertNumber } from './utils/assertNumber'
|
||||
import { DEFAULT_DATA_SOURCE, DEFAULT_LOCALE } from './constants'
|
||||
import { DEFAULT_DATA_SOURCE, DEFAULT_LOCALE, KEY_PREFERRED_SKINTONE, STORE_KEYVALUE } from './constants'
|
||||
import { uniqEmoji } from './utils/uniqEmoji'
|
||||
import { jsonChecksum } from './utils/jsonChecksum'
|
||||
import { closeDatabase, deleteDatabase, openDatabase } from './databaseLifecycle'
|
||||
import { closeDatabase, deleteDatabase, openDatabase, get, set } from './databaseLifecycle'
|
||||
import {
|
||||
isEmpty, hasData, loadData, getEmojiByGroup,
|
||||
getEmojiBySearchQuery, getEmojiByShortcode, getEmojiByUnicode
|
||||
|
@ -101,6 +101,17 @@ export default class Database {
|
|||
return getEmojiByUnicode(this._db, unicode)
|
||||
}
|
||||
|
||||
async getPreferredSkinTone () {
|
||||
await this.ready()
|
||||
return (await get(this._db, STORE_KEYVALUE, KEY_PREFERRED_SKINTONE)) || 0
|
||||
}
|
||||
|
||||
async setPreferredSkinTone (skinTone) {
|
||||
assertNumber(skinTone)
|
||||
await this.ready()
|
||||
return set(this._db, STORE_KEYVALUE, KEY_PREFERRED_SKINTONE, skinTone)
|
||||
}
|
||||
|
||||
async _shutdown () {
|
||||
await this.ready() // reopen if we've already been closed/deleted
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
export const DB_VERSION_CURRENT = 1
|
||||
export const DB_VERSION_INITIAL = 1
|
||||
export const STORE_EMOJI = 'emoji'
|
||||
export const STORE_META = 'meta'
|
||||
export const STORE_KEYVALUE = 'keyvalue'
|
||||
export const STORE_FAVORITES = 'favorites'
|
||||
export const FIELD_TOKENS = 'tokens'
|
||||
export const INDEX_TOKENS = 'tokens'
|
||||
export const FIELD_UNICODE = 'unicode'
|
||||
|
@ -10,6 +11,7 @@ export const FIELD_ORDER = 'order'
|
|||
export const INDEX_GROUP_AND_ORDER = 'group-order'
|
||||
export const KEY_ETAG = 'eTag'
|
||||
export const KEY_URL = 'url'
|
||||
export const KEY_PREFERRED_SKINTONE = 'skinTone'
|
||||
export const MODE_READONLY = 'readonly'
|
||||
export const MODE_READWRITE = 'readwrite'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { migrations } from './migrations'
|
||||
import { DB_VERSION_CURRENT, MODE_READONLY } from './constants'
|
||||
import { DB_VERSION_CURRENT, MODE_READONLY, MODE_READWRITE } from './constants'
|
||||
import { mark, stop } from '../shared/marks'
|
||||
|
||||
const openReqs = {}
|
||||
|
@ -76,6 +76,13 @@ export function get (db, storeName, key) {
|
|||
})
|
||||
}
|
||||
|
||||
export function set (db, storeName, key, value) {
|
||||
return dbPromise(db, storeName, MODE_READWRITE, (store, cb) => {
|
||||
store.put(value, key)
|
||||
cb()
|
||||
})
|
||||
}
|
||||
|
||||
export function closeDatabase (dbName) {
|
||||
// close any open requests
|
||||
const req = openReqs[dbName]
|
||||
|
|
|
@ -3,18 +3,18 @@ import {
|
|||
INDEX_GROUP_AND_ORDER, INDEX_TOKENS, KEY_ETAG, KEY_URL,
|
||||
MODE_READONLY, MODE_READWRITE,
|
||||
STORE_EMOJI,
|
||||
STORE_META
|
||||
STORE_KEYVALUE
|
||||
} from './constants'
|
||||
import { transformEmojiBaseData } from './utils/transformEmojiBaseData'
|
||||
import { mark, stop } from '../shared/marks'
|
||||
import { extractTokens } from './utils/extractTokens'
|
||||
|
||||
export async function isEmpty (db) {
|
||||
return !(await get(db, STORE_META, KEY_URL))
|
||||
return !(await get(db, STORE_KEYVALUE, KEY_URL))
|
||||
}
|
||||
|
||||
export async function hasData (db, url, eTag) {
|
||||
const [oldETag, oldUrl] = await get(db, STORE_META, [KEY_ETAG, KEY_URL])
|
||||
const [oldETag, oldUrl] = await get(db, STORE_KEYVALUE, [KEY_ETAG, KEY_URL])
|
||||
return (oldETag === eTag && oldUrl === url)
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ export async function loadData (db, emojiBaseData, url, eTag) {
|
|||
mark('loadData')
|
||||
try {
|
||||
const transformedData = transformEmojiBaseData(emojiBaseData)
|
||||
await dbPromise(db, [STORE_EMOJI, STORE_META], MODE_READWRITE, ([emojiStore, metaStore]) => {
|
||||
await dbPromise(db, [STORE_EMOJI, STORE_KEYVALUE], MODE_READWRITE, ([emojiStore, metaStore]) => {
|
||||
let oldETag
|
||||
let oldUrl
|
||||
let oldKeys
|
||||
|
|
|
@ -4,7 +4,9 @@ import {
|
|||
FIELD_TOKENS,
|
||||
INDEX_GROUP_AND_ORDER,
|
||||
STORE_EMOJI,
|
||||
STORE_META, INDEX_TOKENS
|
||||
STORE_KEYVALUE,
|
||||
STORE_FAVORITES,
|
||||
INDEX_TOKENS
|
||||
} from './constants'
|
||||
|
||||
function initialMigration (db, tx, done) {
|
||||
|
@ -20,11 +22,12 @@ function initialMigration (db, tx, done) {
|
|||
return store
|
||||
}
|
||||
|
||||
createObjectStore(STORE_META)
|
||||
createObjectStore(STORE_KEYVALUE)
|
||||
createObjectStore(STORE_EMOJI, { keyPath: FIELD_UNICODE }, [
|
||||
{ indexName: INDEX_TOKENS, keyPath: FIELD_TOKENS, multiEntry: true },
|
||||
{ indexName: INDEX_GROUP_AND_ORDER, keyPath: [FIELD_GROUP, FIELD_ORDER] }
|
||||
])
|
||||
createObjectStore(STORE_FAVORITES, { keyPath: FIELD_UNICODE })
|
||||
done()
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ $: {
|
|||
}, TIMEOUT_BEFORE_LOADING_MESSAGE)
|
||||
try {
|
||||
await database.ready()
|
||||
currentSkinTone = await database.getPreferredSkinTone()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
message = i18n.networkError
|
||||
|
@ -336,6 +337,7 @@ function onClickSkinToneOption (event) {
|
|||
skinTonePickerExpanded = false
|
||||
focus('skintone-button')
|
||||
fireEvent('skin-tone-change', { skinTone })
|
||||
/* no await */ database.setPreferredSkinTone(skinTone)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Emoji, DatabaseConstructorOptions } from "./shared";
|
||||
import {Emoji, DatabaseConstructorOptions, SkinTone} from "./shared";
|
||||
|
||||
export default class Database {
|
||||
|
||||
|
@ -71,6 +71,22 @@ export default class Database {
|
|||
return Promise.resolve(null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's preferred skin tone. Returns 0 if not found.
|
||||
*/
|
||||
getPreferredSkinTone(): Promise<SkinTone> {
|
||||
return Promise.resolve(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user's preferred skin tone. Non-numbers throw an error.
|
||||
*
|
||||
* @param skinTone - preferred skin tone
|
||||
*/
|
||||
setPreferredSkinTone(skinTone: SkinTone): Promise<void> {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying IndexedDB connection. The Database is not usable after that (or any other Databases
|
||||
* with the same locale).
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { ALL_EMOJI, basicAfterEach, basicBeforeEach } from '../shared'
|
||||
import Database from '../../../src/database/Database'
|
||||
|
||||
describe('database tests', () => {
|
||||
beforeEach(basicBeforeEach)
|
||||
afterEach(basicAfterEach)
|
||||
|
||||
test('get and set preferred skin tone', async () => {
|
||||
const db = new Database({ dataSource: ALL_EMOJI })
|
||||
expect(await db.getPreferredSkinTone()).toBe(0)
|
||||
await db.setPreferredSkinTone(5)
|
||||
expect(await db.getPreferredSkinTone()).toBe(5)
|
||||
await expect(() => db.setPreferredSkinTone()).rejects.toThrow()
|
||||
await db.delete()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue