mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 19:07:06 +00:00
Use capacitor preferences package instead of localStorage
This commit is contained in:
committed by
Jon Staab
parent
2672a8f922
commit
c94d314f6d
@@ -12,6 +12,7 @@ dependencies {
|
|||||||
implementation project(':capacitor-community-safe-area')
|
implementation project(':capacitor-community-safe-area')
|
||||||
implementation project(':capacitor-app')
|
implementation project(':capacitor-app')
|
||||||
implementation project(':capacitor-keyboard')
|
implementation project(':capacitor-keyboard')
|
||||||
|
implementation project(':capacitor-preferences')
|
||||||
implementation project(':capacitor-push-notifications')
|
implementation project(':capacitor-push-notifications')
|
||||||
implementation project(':capawesome-capacitor-badge')
|
implementation project(':capawesome-capacitor-badge')
|
||||||
implementation project(':nostr-signer-capacitor-plugin')
|
implementation project(':nostr-signer-capacitor-plugin')
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ project(':capacitor-app').projectDir = new File('../node_modules/.pnpm/@capacito
|
|||||||
include ':capacitor-keyboard'
|
include ':capacitor-keyboard'
|
||||||
project(':capacitor-keyboard').projectDir = new File('../node_modules/.pnpm/@capacitor+keyboard@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/keyboard/android')
|
project(':capacitor-keyboard').projectDir = new File('../node_modules/.pnpm/@capacitor+keyboard@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/keyboard/android')
|
||||||
|
|
||||||
|
include ':capacitor-preferences'
|
||||||
|
project(':capacitor-preferences').projectDir = new File('../node_modules/.pnpm/@capacitor+preferences@7.0.2_@capacitor+core@7.2.0/node_modules/@capacitor/preferences/android')
|
||||||
|
|
||||||
include ':capacitor-push-notifications'
|
include ':capacitor-push-notifications'
|
||||||
project(':capacitor-push-notifications').projectDir = new File('../node_modules/.pnpm/@capacitor+push-notifications@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/push-notifications/android')
|
project(':capacitor-push-notifications').projectDir = new File('../node_modules/.pnpm/@capacitor+push-notifications@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/push-notifications/android')
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ def capacitor_pods
|
|||||||
pod 'CapacitorCommunitySafeArea', :path => '../../node_modules/.pnpm/@capacitor-community+safe-area@7.0.0-alpha.1_@capacitor+core@7.2.0/node_modules/@capacitor-community/safe-area'
|
pod 'CapacitorCommunitySafeArea', :path => '../../node_modules/.pnpm/@capacitor-community+safe-area@7.0.0-alpha.1_@capacitor+core@7.2.0/node_modules/@capacitor-community/safe-area'
|
||||||
pod 'CapacitorApp', :path => '../../node_modules/.pnpm/@capacitor+app@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/app'
|
pod 'CapacitorApp', :path => '../../node_modules/.pnpm/@capacitor+app@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/app'
|
||||||
pod 'CapacitorKeyboard', :path => '../../node_modules/.pnpm/@capacitor+keyboard@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/keyboard'
|
pod 'CapacitorKeyboard', :path => '../../node_modules/.pnpm/@capacitor+keyboard@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/keyboard'
|
||||||
|
pod 'CapacitorPreferences', :path => '../../node_modules/.pnpm/@capacitor+preferences@7.0.2_@capacitor+core@7.2.0/node_modules/@capacitor/preferences'
|
||||||
pod 'CapacitorPushNotifications', :path => '../../node_modules/.pnpm/@capacitor+push-notifications@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/push-notifications'
|
pod 'CapacitorPushNotifications', :path => '../../node_modules/.pnpm/@capacitor+push-notifications@7.0.1_@capacitor+core@7.2.0/node_modules/@capacitor/push-notifications'
|
||||||
pod 'CapawesomeCapacitorBadge', :path => '../../node_modules/.pnpm/@capawesome+capacitor-badge@7.0.1_@capacitor+core@7.2.0/node_modules/@capawesome/capacitor-badge'
|
pod 'CapawesomeCapacitorBadge', :path => '../../node_modules/.pnpm/@capawesome+capacitor-badge@7.0.1_@capacitor+core@7.2.0/node_modules/@capawesome/capacitor-badge'
|
||||||
pod 'NostrSignerCapacitorPlugin', :path => '../../node_modules/.pnpm/nostr-signer-capacitor-plugin@0.0.4_@capacitor+core@7.2.0/node_modules/nostr-signer-capacitor-plugin'
|
pod 'NostrSignerCapacitorPlugin', :path => '../../node_modules/.pnpm/nostr-signer-capacitor-plugin@0.0.4_@capacitor+core@7.2.0/node_modules/nostr-signer-capacitor-plugin'
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
"@capacitor/core": "^7.0.1",
|
"@capacitor/core": "^7.0.1",
|
||||||
"@capacitor/ios": "^7.0.0",
|
"@capacitor/ios": "^7.0.0",
|
||||||
"@capacitor/keyboard": "^7.0.0",
|
"@capacitor/keyboard": "^7.0.0",
|
||||||
|
"@capacitor/preferences": "^7.0.2",
|
||||||
"@capacitor/push-notifications": "^7.0.1",
|
"@capacitor/push-notifications": "^7.0.1",
|
||||||
"@capawesome/capacitor-badge": "^7.0.1",
|
"@capawesome/capacitor-badge": "^7.0.1",
|
||||||
"@getalby/sdk": "^5.1.0",
|
"@getalby/sdk": "^5.1.0",
|
||||||
|
|||||||
BIN
pnpm-lock.yaml
generated
BIN
pnpm-lock.yaml
generated
Binary file not shown.
@@ -78,6 +78,7 @@ import {
|
|||||||
userRoomsByUrl,
|
userRoomsByUrl,
|
||||||
userSettingsValues,
|
userSettingsValues,
|
||||||
} from "@app/core/state"
|
} from "@app/core/state"
|
||||||
|
import {preferencesStorageProvider} from "@src/lib/storage"
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
|
|
||||||
@@ -124,6 +125,7 @@ export const logout = async () => {
|
|||||||
await clearStorage()
|
await clearStorage()
|
||||||
|
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
|
await preferencesStorageProvider.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronization
|
// Synchronization
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import {
|
|||||||
deriveEventsMapped,
|
deriveEventsMapped,
|
||||||
withGetter,
|
withGetter,
|
||||||
synced,
|
synced,
|
||||||
localStorageProvider,
|
|
||||||
} from "@welshman/store"
|
} from "@welshman/store"
|
||||||
import {
|
import {
|
||||||
getIdFilters,
|
getIdFilters,
|
||||||
@@ -97,6 +96,7 @@ import {
|
|||||||
publishThunk,
|
publishThunk,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import type {Thunk, Relay} from "@welshman/app"
|
import type {Thunk, Relay} from "@welshman/app"
|
||||||
|
import {preferencesStorageProvider} from "@src/lib/storage"
|
||||||
|
|
||||||
export const fromCsv = (s: string) => (s || "").split(",").filter(identity)
|
export const fromCsv = (s: string) => (s || "").split(",").filter(identity)
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ netContext.isEventValid = (event: TrustedEvent, url: string) =>
|
|||||||
export const canDecrypt = synced({
|
export const canDecrypt = synced({
|
||||||
key: "canDecrypt",
|
key: "canDecrypt",
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
storage: localStorageProvider,
|
storage: preferencesStorageProvider,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const SETTINGS = "flotilla/settings"
|
export const SETTINGS = "flotilla/settings"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {derived} from "svelte/store"
|
import {derived} from "svelte/store"
|
||||||
import {synced, localStorageProvider, throttled} from "@welshman/store"
|
import {synced, throttled} from "@welshman/store"
|
||||||
import {pubkey, relaysByUrl} from "@welshman/app"
|
import {pubkey, relaysByUrl} from "@welshman/app"
|
||||||
import {prop, spec, identity, now, groupBy} from "@welshman/lib"
|
import {prop, spec, identity, now, groupBy} from "@welshman/lib"
|
||||||
import type {TrustedEvent} from "@welshman/util"
|
import type {TrustedEvent} from "@welshman/util"
|
||||||
@@ -13,13 +13,14 @@ import {
|
|||||||
makeRoomPath,
|
makeRoomPath,
|
||||||
} from "@app/util/routes"
|
} from "@app/util/routes"
|
||||||
import {chats, hasNip29, getUrlsForEvent, userRoomsByUrl, repositoryStore} from "@app/core/state"
|
import {chats, hasNip29, getUrlsForEvent, userRoomsByUrl, repositoryStore} from "@app/core/state"
|
||||||
|
import {preferencesStorageProvider} from "@src/lib/storage"
|
||||||
|
|
||||||
// Checked state
|
// Checked state
|
||||||
|
|
||||||
export const checked = synced<Record<string, number>>({
|
export const checked = synced<Record<string, number>>({
|
||||||
key: "checked",
|
key: "checked",
|
||||||
defaultValue: {},
|
defaultValue: {},
|
||||||
storage: localStorageProvider,
|
storage: preferencesStorageProvider,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const deriveChecked = (key: string) => derived(checked, prop(key))
|
export const deriveChecked = (key: string) => derived(checked, prop(key))
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import {synced, localStorageProvider} from "@welshman/store"
|
import {preferencesStorageProvider} from "@src/lib/storage"
|
||||||
|
import {synced} from "@welshman/store"
|
||||||
|
|
||||||
export const theme = synced({
|
export const theme = synced({
|
||||||
key: "theme",
|
key: "theme",
|
||||||
defaultValue: "dark",
|
defaultValue: "dark",
|
||||||
storage: localStorageProvider,
|
storage: preferencesStorageProvider,
|
||||||
})
|
})
|
||||||
|
|||||||
28
src/lib/storage.ts
Normal file
28
src/lib/storage.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import {type StorageProvider} from "@welshman/store"
|
||||||
|
import {Preferences} from "@capacitor/preferences"
|
||||||
|
|
||||||
|
export class PreferencesStorageProvider implements StorageProvider {
|
||||||
|
get = async <T>(key: string): Promise<T | undefined> => {
|
||||||
|
const result = await Preferences.get({key})
|
||||||
|
if (!result.value) return undefined
|
||||||
|
try {
|
||||||
|
return JSON.parse(result.value)
|
||||||
|
} catch (e) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = Promise.resolve()
|
||||||
|
set = async <T>(key: string, value: T): Promise<void> => {
|
||||||
|
this.p = this.p.then(async () => await Preferences.set({key, value: JSON.stringify(value)}))
|
||||||
|
await this.p
|
||||||
|
}
|
||||||
|
|
||||||
|
clear = async (): Promise<void> => {
|
||||||
|
await Preferences.clear()
|
||||||
|
this.p = Promise.resolve()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// singleton instance of PreferencesStorageProvider
|
||||||
|
export const preferencesStorageProvider = new PreferencesStorageProvider()
|
||||||
@@ -10,18 +10,18 @@
|
|||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {sync, localStorageProvider} from "@welshman/store"
|
import {sync, localStorageProvider} from "@welshman/store"
|
||||||
import {
|
import {
|
||||||
identity,
|
|
||||||
call,
|
|
||||||
memoize,
|
|
||||||
spec,
|
|
||||||
sleep,
|
|
||||||
on,
|
|
||||||
defer,
|
|
||||||
ago,
|
ago,
|
||||||
WEEK,
|
|
||||||
TaskQueue,
|
|
||||||
assoc,
|
assoc,
|
||||||
|
call,
|
||||||
|
defer,
|
||||||
dissoc,
|
dissoc,
|
||||||
|
identity,
|
||||||
|
memoize,
|
||||||
|
on,
|
||||||
|
sleep,
|
||||||
|
spec,
|
||||||
|
TaskQueue,
|
||||||
|
WEEK,
|
||||||
} from "@welshman/lib"
|
} from "@welshman/lib"
|
||||||
import type {TrustedEvent, StampedEvent} from "@welshman/util"
|
import type {TrustedEvent, StampedEvent} from "@welshman/util"
|
||||||
import {
|
import {
|
||||||
@@ -82,6 +82,7 @@
|
|||||||
import * as net from "@welshman/net"
|
import * as net from "@welshman/net"
|
||||||
import * as app from "@welshman/app"
|
import * as app from "@welshman/app"
|
||||||
import {nsecDecode} from "@lib/util"
|
import {nsecDecode} from "@lib/util"
|
||||||
|
import {preferencesStorageProvider} from "@lib/storage"
|
||||||
import AppContainer from "@app/components/AppContainer.svelte"
|
import AppContainer from "@app/components/AppContainer.svelte"
|
||||||
import ModalContainer from "@app/components/ModalContainer.svelte"
|
import ModalContainer from "@app/components/ModalContainer.svelte"
|
||||||
import {setupTracking} from "@app/util/tracking"
|
import {setupTracking} from "@app/util/tracking"
|
||||||
@@ -134,6 +135,44 @@
|
|||||||
...notifications,
|
...notifications,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// migrate from localStorage to capacitor Preferences storage if needed
|
||||||
|
const runMigration = async () => {
|
||||||
|
const isSome = (item: any) => {
|
||||||
|
return item !== undefined && item !== null && item !== ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const localStoragePubKey = await localStorageProvider.get("pubkey")
|
||||||
|
if (isSome(localStoragePubKey)) {
|
||||||
|
await preferencesStorageProvider.set("pubkey", localStoragePubKey)
|
||||||
|
localStorage.removeItem("pubkey")
|
||||||
|
}
|
||||||
|
|
||||||
|
const localStorageSessions = await localStorageProvider.get("sessions")
|
||||||
|
if (isSome(localStorageSessions)) {
|
||||||
|
await preferencesStorageProvider.set("sessions", localStorageSessions)
|
||||||
|
localStorage.removeItem("sessions")
|
||||||
|
}
|
||||||
|
|
||||||
|
const localStorageCanDecrypt = await localStorageProvider.get("canDecrypt")
|
||||||
|
if (isSome(localStorageCanDecrypt)) {
|
||||||
|
await preferencesStorageProvider.set("canDecrypt", localStorageCanDecrypt)
|
||||||
|
localStorage.removeItem("canDecrypt")
|
||||||
|
}
|
||||||
|
|
||||||
|
const localStorageChecked = await localStorageProvider.get("checked")
|
||||||
|
if (isSome(localStorageChecked)) {
|
||||||
|
await preferencesStorageProvider.set("checked", localStorageChecked)
|
||||||
|
localStorage.removeItem("checked")
|
||||||
|
}
|
||||||
|
|
||||||
|
const localStorageTheme = await localStorageProvider.get("theme")
|
||||||
|
if (isSome(localStorageTheme)) {
|
||||||
|
await preferencesStorageProvider.set("theme", localStorageTheme)
|
||||||
|
localStorage.removeItem("theme")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await runMigration()
|
||||||
|
|
||||||
// Listen for navigation messages from service worker
|
// Listen for navigation messages from service worker
|
||||||
navigator.serviceWorker?.addEventListener("message", event => {
|
navigator.serviceWorker?.addEventListener("message", event => {
|
||||||
if (event.data && event.data.type === "NAVIGATE") {
|
if (event.data && event.data.type === "NAVIGATE") {
|
||||||
@@ -221,17 +260,17 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Sync current pubkey
|
// Sync current pubkey
|
||||||
sync({
|
await sync({
|
||||||
key: "pubkey",
|
key: "pubkey",
|
||||||
store: pubkey,
|
store: pubkey,
|
||||||
storage: localStorageProvider,
|
storage: preferencesStorageProvider,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Sync user sessions
|
// Sync user sessions
|
||||||
sync({
|
await sync({
|
||||||
key: "sessions",
|
key: "sessions",
|
||||||
store: sessions,
|
store: sessions,
|
||||||
storage: localStorageProvider,
|
storage: preferencesStorageProvider,
|
||||||
})
|
})
|
||||||
|
|
||||||
await initStorage("flotilla", 8, {
|
await initStorage("flotilla", 8, {
|
||||||
|
|||||||
Reference in New Issue
Block a user