Compare commits

...

5 commits

Author SHA1 Message Date
Werner Kroneman 38576a80b4 Added docs idb proxy.
Some checks are pending
Check SPDX-License-Identifier / check-spdx-license-id (push) Waiting to run
Check copyright year / check_copyright_year (push) Waiting to run
Publish Docker image (develop) / Build (linux/amd64) (push) Waiting to run
Publish Docker image (develop) / Build (linux/arm64) (push) Waiting to run
Publish Docker image (develop) / merge (push) Blocked by required conditions
Dockle / dockle (push) Waiting to run
Lint / pnpm_install (push) Waiting to run
Lint / lint (backend) (push) Blocked by required conditions
Lint / lint (frontend) (push) Blocked by required conditions
Lint / lint (frontend-embed) (push) Blocked by required conditions
Lint / lint (frontend-shared) (push) Blocked by required conditions
Lint / lint (misskey-bubble-game) (push) Blocked by required conditions
Lint / lint (misskey-js) (push) Blocked by required conditions
Lint / lint (misskey-reversi) (push) Blocked by required conditions
Lint / lint (sw) (push) Blocked by required conditions
Lint / typecheck (backend) (push) Blocked by required conditions
Lint / typecheck (misskey-js) (push) Blocked by required conditions
Lint / typecheck (sw) (push) Blocked by required conditions
Storybook / build (push) Waiting to run
Test (frontend) / vitest (20.16.0) (push) Waiting to run
Test (frontend) / e2e (chrome, 20.16.0) (push) Waiting to run
Test (production install and build) / production (20.16.0) (push) Waiting to run
2024-11-17 13:16:05 +02:00
Werner Kroneman 9fa011c6e0 Added docs to Keys for localStorage. 2024-11-17 12:59:58 +02:00
Werner Kroneman 73be97195b Added docs to miLocalStorage. 2024-11-17 12:59:32 +02:00
Werner Kroneman 8cca5f0001 Added docs (and observations) to notes count. 2024-11-17 12:54:26 +02:00
Werner Kroneman a2dc196a07 Added docs to $i, iAmModerator, iAmAdmin. 2024-11-17 12:48:39 +02:00
3 changed files with 103 additions and 1 deletions

View file

@ -22,23 +22,66 @@ type Account = Misskey.entities.MeDetailed & { token: string };
const accountData = miLocalStorage.getItem('account'); const accountData = miLocalStorage.getItem('account');
// TODO: 外部からはreadonlyに // TODO: 外部からはreadonlyに
/**
* Reactive state for the current account. "I" as in "I am logged in".
* Initialized from local storage if available, otherwise null.
*
* @type {Account | null}
*/
export const $i = accountData ? reactive(JSON.parse(accountData) as Account) : null; export const $i = accountData ? reactive(JSON.parse(accountData) as Account) : null;
/**
* Whether the current account is a moderator.
*
* @type {boolean}
*/
export const iAmModerator = $i != null && ($i.isAdmin === true || $i.isModerator === true); export const iAmModerator = $i != null && ($i.isAdmin === true || $i.isModerator === true);
/**
* Whether the current account is an administrator.
*
* @type {boolean}
*/
export const iAmAdmin = $i != null && $i.isAdmin; export const iAmAdmin = $i != null && $i.isAdmin;
/**
* Whether it is necessary to sign in; checks if the current
* account is null and throws an error if so.
*
* @throws {Error} If the current account is null
* @returns {Account} The current account
*/
export function signinRequired() { export function signinRequired() {
if ($i == null) throw new Error('signin required'); if ($i == null) throw new Error('signin required');
return $i; return $i;
} }
/**
* Extracts the current number of notes from the current account.
*
* Note: This appears to only be used for the "notes1" achievement.
*
* Also, separating it like this might cause counts to get out-of-sync.
*/
export let notesCount = $i == null ? 0 : $i.notesCount; export let notesCount = $i == null ? 0 : $i.notesCount;
/**
* Increments the number of notes by one.
*
* Documentation TODO: What about $i.notesCount? Why not increment that?
*/
export function incNotesCount() { export function incNotesCount() {
notesCount++; notesCount++;
} }
export async function signout() { export async function signout() {
if (!$i) return;
// If we're not signed in, there's nothing to do.
if (!$i) {
// Error log:
console.error('signout() called when not signed in');
return;
}
waiting(); waiting();
miLocalStorage.removeItem('account'); miLocalStorage.removeItem('account');

View file

@ -3,6 +3,9 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
/**
* A typesafe enum of keys for localStorage.
*/
export type Keys = export type Keys =
'v' | 'v' |
'lastVersion' | 'lastVersion' |
@ -44,16 +47,45 @@ export type Keys =
// セッション毎に廃棄されるLocalStorage代替セーフモードなどで使用できそう // セッション毎に廃棄されるLocalStorage代替セーフモードなどで使用できそう
//const safeSessionStorage = new Map<Keys, string>(); //const safeSessionStorage = new Map<Keys, string>();
/**
* A utility object for interacting with the browser's localStorage.
*
* It's mostly a small wrapper around window.localStorage, but it validates
* keys with a typesafe enum, and provides a few convenience methods for JSON.
*/
export const miLocalStorage = { export const miLocalStorage = {
/**
* Retrieves an item from localStorage.
* @param {Keys} key - The key of the item to retrieve.
* @returns {string | null} The value of the item, or null if the item does not exist.
*/
getItem: (key: Keys): string | null => { getItem: (key: Keys): string | null => {
return window.localStorage.getItem(key); return window.localStorage.getItem(key);
}, },
/**
* Stores an item in localStorage.
* @param {Keys} key - The key of the item to store.
* @param {string} value - The value of the item to store.
*/
setItem: (key: Keys, value: string): void => { setItem: (key: Keys, value: string): void => {
window.localStorage.setItem(key, value); window.localStorage.setItem(key, value);
}, },
/**
* Removes an item from localStorage.
* @param {Keys} key - The key of the item to remove.
*/
removeItem: (key: Keys): void => { removeItem: (key: Keys): void => {
window.localStorage.removeItem(key); window.localStorage.removeItem(key);
}, },
/**
* Retrieves an item from localStorage and parses it as JSON.
* @param {Keys} key - The key of the item to retrieve.
* @returns {any | undefined} The parsed value of the item, or undefined if the item does not exist.
*/
getItemAsJson: (key: Keys): any | undefined => { getItemAsJson: (key: Keys): any | undefined => {
const item = miLocalStorage.getItem(key); const item = miLocalStorage.getItem(key);
if (item === null) { if (item === null) {
@ -61,6 +93,12 @@ export const miLocalStorage = {
} }
return JSON.parse(item); return JSON.parse(item);
}, },
/**
* Stores an item in localStorage as a JSON string.
* @param {Keys} key - The key of the item to store.
* @param {any} value - The value of the item to store.
*/
setItemAsJson: (key: Keys, value: any): void => { setItemAsJson: (key: Keys, value: any): void => {
miLocalStorage.setItem(key, JSON.stringify(value)); miLocalStorage.setItem(key, JSON.stringify(value));
}, },

View file

@ -26,6 +26,7 @@ if (window.Cypress) {
console.log('Cypress detected. It will use localStorage.'); console.log('Cypress detected. It will use localStorage.');
} }
// Check for the availability of indexedDB.
if (idbAvailable) { if (idbAvailable) {
await iset('idb-test', 'test') await iset('idb-test', 'test')
.catch(err => { .catch(err => {
@ -37,16 +38,36 @@ if (idbAvailable) {
console.error('indexedDB is unavailable. It will use localStorage.'); console.error('indexedDB is unavailable. It will use localStorage.');
} }
/**
* Get a value from indexedDB (or localStorage as a fallback).
*
* @param key The key of the item to retrieve.
*
* @returns The value of the item.
*/
export async function get(key: string) { export async function get(key: string) {
if (idbAvailable) return iget(key); if (idbAvailable) return iget(key);
return miLocalStorage.getItemAsJson(`${PREFIX}${key}`); return miLocalStorage.getItemAsJson(`${PREFIX}${key}`);
} }
/**
* Set a value in indexedDB (or localStorage as a fallback).
*
* @param {string} key - The key of the item to set.
* @param {any} val - The value of the item to set.
* @returns {Promise<void>} - A promise that resolves when the value has been set.`
*/
export async function set(key: string, val: any) { export async function set(key: string, val: any) {
if (idbAvailable) return iset(key, val); if (idbAvailable) return iset(key, val);
return miLocalStorage.setItemAsJson(`${PREFIX}${key}`, val); return miLocalStorage.setItemAsJson(`${PREFIX}${key}`, val);
} }
/**
* Delete a value from indexedDB (or localStorage as a fallback).
*
* @param {string} key - The key of the item to delete.
* @returns {Promise<void>} - A promise that resolves when the value has been deleted.
*/
export async function del(key: string) { export async function del(key: string) {
if (idbAvailable) return idel(key); if (idbAvailable) return idel(key);
return miLocalStorage.removeItem(`${PREFIX}${key}`); return miLocalStorage.removeItem(`${PREFIX}${key}`);