-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
User IndexedDB #1230
Merged
Merged
User IndexedDB #1230
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
5e9e2af
init
dbauszus-glx 0af0291
userIDB put locale
dbauszus-glx 118eede
remove console.log(locale) from userIDB plugin
dbauszus-glx f00aa06
Merge branch 'main' into user-IndexedDB
dbauszus-glx 0dfb14a
Merge branch 'main' into user-IndexedDB
dbauszus-glx df2b672
updateLayer
dbauszus-glx 47ac671
Update docs
RobAndrewHurst 928d9ea
store to string
dbauszus-glx 92576ae
Updated docs
RobAndrewHurst 9e3932f
Merge remote-tracking branch 'refs/remotes/dbauszus-glx/user-IndexedD…
RobAndrewHurst 35b4848
Update documentation
RobAndrewHurst b37ccb1
Update docs
RobAndrewHurst 91d2ecb
Merge branch 'main' into pr/dbauszus-glx/1230
RobAndrewHurst 2c6aec1
mapp.user; alert; plugin.title
dbauszus-glx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
export function userIDB(plugin, mapview) { | ||
|
||
if (!mapp.user?.email) { | ||
|
||
console.warn(`The userIDB plugin requires a mapp.user`) | ||
return; | ||
} | ||
|
||
// Find the btnColumn element. | ||
const btnColumn = document.getElementById('mapButton'); | ||
|
||
if (!btnColumn) return; | ||
|
||
plugin.title ??= "Update userIDB locale" | ||
|
||
// Append the plugin btn to the btnColumn. | ||
btnColumn.append(mapp.utils.html.node` | ||
<button | ||
title=${plugin.title} | ||
onclick=${()=>{ | ||
|
||
mapview.locale.layers.forEach(layer => { | ||
|
||
if (typeof layer !== 'object') return; | ||
|
||
updateLayer(layer, mapview.layers[layer.key]) | ||
}) | ||
|
||
mapp.utils.userIndexedDB.put('locales', mapview.locale) | ||
|
||
alert(`User ${mapp.user.email} IndexedDB updated.`) | ||
|
||
}}> | ||
<div class="mask-icon" style="mask-image:url(https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/rule_settings/default/24px.svg)">`); | ||
} | ||
|
||
function updateLayer(layer, _layer) { | ||
|
||
if (!_layer) return; | ||
|
||
Object.keys(_layer).forEach(key => { | ||
|
||
if (_layer[key] === undefined) return; | ||
|
||
if (_layer[key] === null) { | ||
layer[key] = null; | ||
} | ||
|
||
if (typeof _layer[key] === 'function') return; | ||
|
||
if (typeof _layer[key] === 'object') return; | ||
|
||
layer[key] = _layer[key] | ||
}) | ||
|
||
return layer; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
/** | ||
* ### mapp.utils.userIndexedDB | ||
* This [indexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Terminology) implementation allows to store, get, and update a locale object from the 'locales' object store in a user indexedDB. | ||
* | ||
* There are many different operations that the indexedDB can handle. Typically the operations are CRUD. | ||
* | ||
* The `userIndexDB` methods have all been moved to the `mapp.utils` object. | ||
* | ||
* The logic for initialisation for the userIndexedDB object is the following: | ||
* - `userIndexedDB.open(store)` will open a DB with the following name `${mapp.user.email} - {mapp.user.title}. | ||
* - The database will not be created if there is a pre-existing DB. | ||
* - The creation will trigger the `onupgradeneeded` event which checks whether the request `store` exists in the userIndexedDB. | ||
* | ||
* The `process.env.TITLE` will be added to the user object in the cookie module. | ||
* The `user.title` is required to generate a unique indexedDB for each user[email/instance[title]] | ||
* | ||
* All object stores use the key value as a keypath for object indicies. | ||
* | ||
* Adding the url parameter `useridb=true` will ask the default script to get the keyed locale from the user indexedDB. | ||
* The userLocale will be assigned as locale if available. | ||
* | ||
* ```js | ||
* if (mapp.hooks.current.useridb) { | ||
|
||
let userLocale = await mapp.utils.userIndexedDB.get('locales', locale.key) | ||
|
||
if (!userLocale) { | ||
await mapp.utils.userIndexedDB.add('locales', locale) | ||
} else { | ||
locale = userLocale | ||
} | ||
} | ||
* ``` | ||
* | ||
* The userIDB plugin adds a button to put [update] the locale in the user indexedDB. | ||
* | ||
* ```js | ||
* export function userIDB(plugin, mapview) { | ||
|
||
// Find the btnColumn element. | ||
const btnColumn = document.getElementById('mapButton'); | ||
|
||
if (!btnColumn) return; | ||
|
||
// Append the plugin btn to the btnColumn. | ||
btnColumn.append(mapp.utils.html.node` | ||
<button | ||
title="Update userIDB locale" | ||
onclick=${()=>{ | ||
|
||
mapp.utils.userIndexedDB.put('locales', mapview.locale) | ||
|
||
}}> | ||
<div class="mask-icon" style="mask-image:url(https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/rule_settings/default/24px.svg)">`); | ||
} | ||
* ``` | ||
* This can be tested but updating the mapview.locale in another plugin, e.g. dark_mode | ||
* | ||
* The enabled status will be stored with the local applying the setting when the locale is loaded with the useridb=true url param. | ||
* | ||
* ```js | ||
* mapp.plugins.dark_mode = (plugin, mapview) => { | ||
|
||
// Get the map button | ||
const mapButton = document.getElementById("mapButton"); | ||
|
||
// If mapbutton doesn't exist, return (for custom views). | ||
if (!mapButton) return; | ||
|
||
// toggle dark_mode if enabled in config. | ||
mapview.locale.dark_mode.enabled && toggleDarkMode() | ||
|
||
// If the button container exists, append the dark mode button. | ||
mapButton.append(mapp.utils.html.node` | ||
<button | ||
title="Color Mode" | ||
class="btn-color-mode" | ||
onclick=${()=>{ | ||
mapview.locale.dark_mode.enabled = toggleDarkMode() | ||
}}> | ||
<div class="mask-icon">`); | ||
} | ||
* ``` | ||
* | ||
* @module /utils/userIndexedDB | ||
*/ | ||
|
||
let IDB | ||
|
||
/** | ||
* @param {Object} store | ||
* @returns {Promise} OpenDBPromise | ||
*/ | ||
export async function openDB(_store) { | ||
|
||
const store = _store.toString() | ||
|
||
const OpenDBPromise = new Promise((resolve, reject) => { | ||
|
||
// will create a new database if db/version doesn't exist. | ||
const IDBRequest = indexedDB.open(`${mapp.user.email} - ${mapp.user.title}`, 3); | ||
|
||
IDBRequest.onerror = (event) => { | ||
console.error(IDBRequest.error) | ||
resolve(IDBRequest) | ||
}; | ||
|
||
IDBRequest.onsuccess = (event) => { | ||
|
||
if (!event.target.result.objectStoreNames.contains(store)) { | ||
|
||
console.warn(`UserIDB doesn't contain "${store}" objectStore.`) | ||
|
||
IDB = null | ||
resolve() | ||
} | ||
|
||
IDB = event.target.result | ||
resolve() | ||
} | ||
|
||
// will be called on database versioning. | ||
IDBRequest.onupgradeneeded = (event) => { | ||
|
||
// onsuccess method will be called after the object store is created. | ||
event.target.result.createObjectStore(store, { keyPath: 'key' }); | ||
}; | ||
}) | ||
|
||
await OpenDBPromise | ||
|
||
return OpenDBPromise | ||
} | ||
|
||
/** | ||
* - deletes the user indexedDB. | ||
* @function deleteDB | ||
*/ | ||
export function deleteDB() { | ||
|
||
if (!mapp.user) return; | ||
|
||
indexedDB.deleteDatabase(`${mapp.user.email} - ${mapp.user.title}`) | ||
|
||
console.log('Database deleted') | ||
} | ||
|
||
/** | ||
* - Adds the keyed object to the named store. | ||
* - The key will be returned on success. | ||
* - Adding the same keyed object twice will result in an error. | ||
* @function add | ||
* @param {Object} store | ||
* @param {Object} obj | ||
* @returns {Promise} addPromise | ||
*/ | ||
export async function add(store, obj) { | ||
|
||
if (!IDB) await openDB(store) | ||
|
||
const addPromise = new Promise((resolve, reject) => { | ||
|
||
const IDBTransaction = IDB.transaction([store], 'readwrite'); | ||
|
||
const objectStore = IDBTransaction.objectStore(store) | ||
|
||
const IDBRequest = objectStore.add(obj); | ||
|
||
IDBRequest.onerror = (event) => { | ||
console.error(IDBRequest.error) | ||
resolve(IDBRequest) | ||
}; | ||
|
||
IDBRequest.onsuccess = (event) => { | ||
resolve(event.target.result) | ||
}; | ||
}) | ||
|
||
await addPromise | ||
|
||
return addPromise | ||
} | ||
|
||
/** | ||
* - Gets the keyed object from the named store. | ||
* @param {Object} store | ||
* @param {string} key | ||
* @returns {Promise} getPromise | ||
*/ | ||
export async function get(store, key) { | ||
|
||
if (!IDB) await openDB(store) | ||
|
||
const getPromise = new Promise((resolve, reject) => { | ||
|
||
const IDBTransaction = IDB.transaction([store], 'readwrite'); | ||
|
||
const objectStore = IDBTransaction.objectStore(store) | ||
|
||
const IDBRequest = objectStore.get(key); | ||
|
||
IDBRequest.onerror = (event) => { | ||
console.error(IDBRequest.error) | ||
reject(IDBRequest) | ||
}; | ||
|
||
IDBRequest.onsuccess = (event) => { | ||
resolve(IDBRequest.result) | ||
}; | ||
}) | ||
|
||
await getPromise | ||
|
||
return getPromise | ||
} | ||
|
||
/** | ||
* - puts the keyed object to the named store. | ||
* - This will override the existing keyed object. | ||
* - Updates work by replacing (put) the same keyed object into an user indexedDB. | ||
* @param {Object} store | ||
* @param {Object} obj | ||
* @returns {Promise} updatePromise | ||
*/ | ||
export async function put(store, obj) { | ||
|
||
if (!IDB) await openDB(store) | ||
|
||
const updatePromise = new Promise((resolve, reject) => { | ||
|
||
const IDBTransaction = IDB.transaction([store], 'readwrite'); | ||
|
||
const objectStore = IDBTransaction.objectStore(store) | ||
|
||
const IDBRequest = objectStore.put(obj); | ||
|
||
IDBRequest.onerror = (event) => { | ||
console.error(IDBRequest.error) | ||
reject(IDBRequest) | ||
}; | ||
|
||
IDBRequest.onsuccess = (event) => { | ||
resolve(IDBRequest.result) | ||
}; | ||
}) | ||
|
||
await updatePromise | ||
|
||
return updatePromise | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lekker!