Update to new version of welshman, including new thunks and wrap manager

This commit is contained in:
Jon Staab
2025-10-17 10:19:21 -07:00
parent e0099141aa
commit 6ca74c21bf
21 changed files with 205 additions and 315 deletions
+2 -1
View File
@@ -6,6 +6,7 @@
import {
thunks,
pubkey,
mergeThunks,
deriveProfile,
deriveProfileDisplay,
displayProfileByPubkey,
@@ -52,12 +53,12 @@
onEdit,
}: Props = $props()
const thunk = $thunks[event.id]
const path = getChannelItemPath(url, event)
const shouldProtect = canEnforceNip70(url)
const today = formatTimestampAsDate(now())
const profile = deriveProfile(event.pubkey, [url])
const profileDisplay = deriveProfileDisplay(event.pubkey, [url])
const thunk = mergeThunks($thunks.filter(t => t.event.id === event.id))
const [_, colorValue] = colors[parseInt(hash(event.pubkey)) % colors.length]
const comments = deriveEventsForUrl(url, [{kinds: [COMMENT], "#e": [event.id]}])
+8 -9
View File
@@ -11,6 +11,7 @@
MINUTE,
sortBy,
remove,
enumerate,
formatTimestampAsDate,
} from "@welshman/lib"
import type {TrustedEvent, EventTemplate, EventContent} from "@welshman/util"
@@ -30,7 +31,6 @@
loadInboxRelaySelections,
inboxRelaySelectionsByPubkey,
} from "@welshman/app"
import type {AbstractThunk} from "@welshman/app"
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte"
@@ -126,14 +126,13 @@
// Split the message into multiple pieces so that we can use kind 15 to send images per nip 17
// Sleep 1 second between each one to make sure timestamps are distinct
const thunks: AbstractThunk[] = []
for (let i = 0; i < templates.length; i++) {
const template = templates[i]
thunks.push(
await sendWrapped({pubkeys, template, delay: $userSettingsValues.send_delay + ms(i)}),
)
}
const thunks = Array.from(enumerate(templates)).map(([i, event]) =>
sendWrapped({
event,
recipients: pubkeys,
delay: $userSettingsValues.send_delay + ms(i),
}),
)
pushToast({
timeout: 30_000,
+4 -8
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import {goto} from "$app/navigation"
import {preventDefault} from "@lib/html"
import {shouldUnwrap} from "@welshman/app"
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
@@ -9,7 +10,6 @@
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {PLATFORM_NAME} from "@app/core/state"
import {enableGiftWraps} from "@app/core/commands"
import {clearModals} from "@app/util/modal"
const {next} = $props()
@@ -18,17 +18,13 @@
let loading = $state(false)
const enableChat = async () => {
enableGiftWraps()
clearModals()
goto(nextUrl)
}
const submit = async () => {
loading = true
try {
await enableChat()
shouldUnwrap.set(true)
clearModals()
goto(nextUrl)
} finally {
loading = false
}
+11 -4
View File
@@ -2,7 +2,14 @@
import {type Instance} from "tippy.js"
import {hash, formatTimestampAsTime} from "@welshman/lib"
import type {TrustedEvent, EventContent} from "@welshman/util"
import {thunks, pubkey, deriveProfile, deriveProfileDisplay, sendWrapped} from "@welshman/app"
import {
thunks,
mergeThunks,
pubkey,
deriveProfile,
deriveProfileDisplay,
sendWrapped,
} from "@welshman/app"
import {isMobile} from "@lib/html"
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
@@ -29,19 +36,19 @@
const {event, replyTo, pubkeys, showPubkey = false}: Props = $props()
const thunk = $thunks[event.id]
const isOwn = event.pubkey === $pubkey
const profile = deriveProfile(event.pubkey)
const profileDisplay = deriveProfileDisplay(event.pubkey)
const thunk = mergeThunks($thunks.filter(t => t.event.id === event.id))
const [_, colorValue] = colors[parseInt(hash(event.pubkey)) % colors.length]
const reply = () => replyTo(event)
const deleteReaction = (event: TrustedEvent) =>
sendWrapped({template: makeDelete({event, protect: false}), pubkeys})
sendWrapped({event: makeDelete({event, protect: false}), recipients: pubkeys})
const createReaction = (template: EventContent) =>
sendWrapped({template: makeReaction({event, protect: false, ...template}), pubkeys})
sendWrapped({event: makeReaction({event, protect: false, ...template}), recipients: pubkeys})
const openProfile = () => pushModal(ProfileDetail, {pubkey: event.pubkey})
@@ -15,7 +15,10 @@
const {event, pubkeys}: Props = $props()
const onEmoji = (emoji: NativeEmoji) =>
sendWrapped({template: makeReaction({event, content: emoji.unicode, protect: false}), pubkeys})
sendWrapped({
event: makeReaction({event, content: emoji.unicode, protect: false}),
recipients: pubkeys,
})
</script>
<EmojiButton {onEmoji} class="btn join-item btn-xs">
@@ -24,7 +24,10 @@
const onEmoji = ((event: TrustedEvent, pubkeys: string[], emoji: NativeEmoji) => {
history.back()
sendWrapped({template: makeReaction({event, content: emoji.unicode, protect: false}), pubkeys})
sendWrapped({
event: makeReaction({event, content: emoji.unicode, protect: false}),
recipients: pubkeys,
})
}).bind(undefined, event, pubkeys)
const showEmojiPicker = () => pushModal(EmojiPicker, {onClick: onEmoji}, {replaceState: true})
+3 -3
View File
@@ -3,7 +3,7 @@
import {page} from "$app/stores"
import {goto} from "$app/navigation"
import {splitAt} from "@welshman/lib"
import {userProfile} from "@welshman/app"
import {userProfile, shouldUnwrap} from "@welshman/app"
import Avatar from "@lib/components/Avatar.svelte"
import Divider from "@lib/components/Divider.svelte"
import PrimaryNavItem from "@lib/components/PrimaryNavItem.svelte"
@@ -13,7 +13,7 @@
import MenuOtherSpaces from "@app/components/MenuOtherSpaces.svelte"
import MenuSettings from "@app/components/MenuSettings.svelte"
import PrimaryNavItemSpace from "@app/components/PrimaryNavItemSpace.svelte"
import {userRoomsByUrl, canDecrypt, PLATFORM_RELAYS, PLATFORM_LOGO} from "@app/core/state"
import {userRoomsByUrl, PLATFORM_RELAYS, PLATFORM_LOGO} from "@app/core/state"
import {pushModal} from "@app/util/modal"
import {makeSpacePath} from "@app/util/routes"
import {notifications} from "@app/util/notifications"
@@ -37,7 +37,7 @@
const showSettingsMenu = () => pushModal(MenuSettings)
const openChat = () => ($canDecrypt ? goto("/chat") : pushModal(ChatEnable, {next: "/chat"}))
const openChat = () => ($shouldUnwrap ? goto("/chat") : pushModal(ChatEnable, {next: "/chat"}))
const hasNotification = (url: string) => {
const path = makeSpacePath(url)
+3 -2
View File
@@ -1,5 +1,6 @@
<script lang="ts">
import {goto} from "$app/navigation"
import {shouldUnwrap} from "@welshman/app"
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import Letter from "@assets/icons/letter-opened.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
@@ -11,7 +12,7 @@
import ProfileInfo from "@app/components/ProfileInfo.svelte"
import ProfileBadges from "@app/components/ProfileBadges.svelte"
import ChatEnable from "@app/components/ChatEnable.svelte"
import {canDecrypt, pubkeyLink} from "@app/core/state"
import {pubkeyLink} from "@app/core/state"
import {pushModal} from "@app/util/modal"
import {makeChatPath} from "@app/util/routes"
@@ -26,7 +27,7 @@
const chatPath = makeChatPath([pubkey])
const openChat = () => ($canDecrypt ? goto(chatPath) : pushModal(ChatEnable, {next: chatPath}))
const openChat = () => ($shouldUnwrap ? goto(chatPath) : pushModal(ChatEnable, {next: chatPath}))
</script>
<div class="flex flex-col gap-4">
+4 -12
View File
@@ -1,14 +1,8 @@
<script lang="ts">
import {stopPropagation} from "svelte/legacy"
import {noop} from "@welshman/lib"
import {
MergedThunk,
publishThunk,
isMergedThunk,
thunkIsComplete,
getFailedThunkUrls,
} from "@welshman/app"
import type {Thunk} from "@welshman/app"
import type {AbstractThunk} from "@welshman/app"
import {retryThunk, thunkIsComplete, getFailedThunkUrls} from "@welshman/app"
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Tippy from "@lib/components/Tippy.svelte"
@@ -17,7 +11,7 @@
import {pushToast} from "@app/util/toast"
interface Props {
thunk: Thunk | MergedThunk
thunk: AbstractThunk
showToastOnRetry?: boolean
class?: string
}
@@ -25,9 +19,7 @@
let {thunk, showToastOnRetry, ...restProps}: Props = $props()
const retry = () => {
thunk = isMergedThunk(thunk)
? new MergedThunk(thunk.thunks.map(t => publishThunk(t.options)))
: publishThunk(thunk.options)
thunk = retryThunk(thunk)
if (showToastOnRetry) {
pushToast({
+3 -3
View File
@@ -1,11 +1,11 @@
<script lang="ts">
import {MergedThunk, thunkIsComplete, getFailedThunkUrls} from "@welshman/app"
import type {Thunk} from "@welshman/app"
import type {AbstractThunk} from "@welshman/app"
import {thunkIsComplete, getFailedThunkUrls} from "@welshman/app"
import ThunkFailure from "@app/components/ThunkFailure.svelte"
import ThunkPending from "@app/components/ThunkPending.svelte"
interface Props {
thunk: Thunk | MergedThunk
thunk: AbstractThunk
class?: string
}
@@ -1,13 +1,13 @@
<script lang="ts">
import type {TrustedEvent} from "@welshman/util"
import {deriveIsDeleted} from "@welshman/store"
import {thunks, repository} from "@welshman/app"
import {thunks, mergeThunks, repository} from "@welshman/app"
import ThunkStatus from "@app/components/ThunkStatus.svelte"
const {event}: {event: TrustedEvent} = $props()
const thunk = $derived($thunks[event.id])
const deleted = deriveIsDeleted(repository, event)
const thunk = $derived(mergeThunks($thunks.filter(t => t.event.id === event.id)))
</script>
{#if $deleted}
+3 -14
View File
@@ -90,6 +90,7 @@ import {
waitForThunkError,
getPubkeyRelays,
userBlossomServers,
shouldUnwrap,
} from "@welshman/app"
import {compressFile} from "@src/lib/html"
import type {SettingsValues, Alert} from "@app/core/state"
@@ -103,8 +104,6 @@ import {
DEFAULT_BLOSSOM_SERVERS,
userRoomsByUrl,
userSettingsValues,
canDecrypt,
ensureUnwrapped,
userInboxRelays,
getMembershipUrls,
} from "@app/core/state"
@@ -593,8 +592,8 @@ export const createAlert = async (params: CreateAlertParams): Promise<CreateAler
}
export const createDmAlert = async () => {
if (!get(canDecrypt)) {
enableGiftWraps()
if (!shouldUnwrap.get()) {
shouldUnwrap.set(true)
}
return createAlert({
@@ -658,16 +657,6 @@ export const payInvoice = async (invoice: string) => {
}
}
// Gift Wraps
export const enableGiftWraps = () => {
canDecrypt.set(true)
for (const event of repository.query([{kinds: [WRAP]}])) {
ensureUnwrapped(event)
}
}
// File upload
export const normalizeBlossomUrl = (url: string) => normalizeUrl(url.replace(/^ws/, "http"))
+6 -72
View File
@@ -27,14 +27,7 @@ import {
} from "@welshman/lib"
import type {Socket} from "@welshman/net"
import {Pool, load, AuthStateEvent, AuthStatus, SocketEvent, netContext} from "@welshman/net"
import {
collection,
custom,
deriveEvents,
deriveEventsMapped,
withGetter,
synced,
} from "@welshman/store"
import {collection, custom, deriveEvents, deriveEventsMapped, withGetter} from "@welshman/store"
import {isKindFeed, findFeed} from "@welshman/feeds"
import {
getIdFilters,
@@ -68,7 +61,6 @@ import {
getGroupTags,
getRelayTagValues,
getPubkeyTagValues,
isHashedEvent,
displayProfile,
readList,
getListTags,
@@ -82,8 +74,8 @@ import {
RelayMode,
getRelaysFromList,
} from "@welshman/util"
import type {TrustedEvent, SignedEvent, PublishedList, List, Filter} from "@welshman/util"
import {Nip59, decrypt} from "@welshman/signer"
import type {TrustedEvent, PublishedList, List, Filter} from "@welshman/util"
import {decrypt} from "@welshman/signer"
import {routerContext, Router} from "@welshman/router"
import {
pubkey,
@@ -92,14 +84,10 @@ import {
tracker,
makeTrackerStore,
makeRepositoryStore,
relay,
getSession,
getSigner,
createSearch,
userFollows,
ensurePlaintext,
thunks,
flattenThunks,
signer,
makeOutboxLoader,
appContext,
@@ -109,7 +97,6 @@ import {
userInboxRelaySelections,
} 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)
@@ -195,46 +182,6 @@ export const defaultPubkeys = derived(userFollows, $userFollows => {
return userPubkeys.length > 5 ? userPubkeys : [...userPubkeys, ...appPubkeys]
})
const failedUnwraps = new Set()
export const ensureUnwrapped = async (event: TrustedEvent) => {
if (event.kind !== WRAP) {
return event
}
let rumor = repository.eventsByWrap.get(event.id)
if (rumor || failedUnwraps.has(event.id)) {
return rumor
}
for (const recipient of getPubkeyTagValues(event.tags)) {
const session = getSession(recipient)
const signer = getSigner(session)
if (signer) {
try {
rumor = await Nip59.fromSigner(signer).unwrap(event as SignedEvent)
break
} catch (e) {
// pass
}
}
}
if (rumor && isHashedEvent(rumor)) {
// Copy urls over to the rumor
tracker.copy(event.id, rumor.id)
// Send the rumor via our relay so listeners get updated
relay.send("EVENT", rumor)
} else {
failedUnwraps.add(event.id)
}
return rumor
}
export const trackerStore = makeTrackerStore()
export const repositoryStore = makeRepositoryStore()
@@ -262,7 +209,7 @@ export const getUrlsForEvent = derived([trackerStore, thunks], ([$tracker, $thun
const getThunksByEventId = memoize(() => {
const thunksByEventId = new Map<string, Thunk[]>()
for (const thunk of flattenThunks(Object.values($thunks))) {
for (const thunk of $thunks) {
pushToMapKey(thunksByEventId, thunk.event.id, thunk)
}
@@ -285,7 +232,7 @@ export const getUrlsForEvent = derived([trackerStore, thunks], ([$tracker, $thun
export const getEventsForUrl = (url: string, filters: Filter[]) => {
const ids = uniq([
...tracker.getIds(url),
...Array.from(flattenThunks(Object.values(get(thunks))))
...get(thunks)
.filter(t => t.options.relays.includes(url))
.map(t => t.event.id),
])
@@ -297,9 +244,7 @@ export const deriveEventsForUrl = (url: string, filters: Filter[]) =>
derived([trackerStore, thunks], ([$tracker, $thunks]) => {
const ids = uniq([
...$tracker.getIds(url),
...Array.from(flattenThunks(Object.values($thunks)))
.filter(t => t.options.relays.includes(url))
.map(t => t.event.id),
...$thunks.filter(t => t.options.relays.includes(url)).map(t => t.event.id),
])
return repository.query(filters.map(assoc("ids", ids)))
@@ -336,12 +281,6 @@ export const COMMENT_FILTER = makeCommentFilter(MESSAGE_KINDS)
// Settings
export const canDecrypt = synced({
key: "canDecrypt",
defaultValue: false,
storage: preferencesStorageProvider,
})
export const SETTINGS = "flotilla/settings"
export type SettingsValues = {
@@ -555,11 +494,6 @@ export const chats = derived(
const messagesByChatId = new Map<string, TrustedEvent[]>()
for (const message of $messages) {
// Filter out messages we sent but aren't addressed to the user
if (!getPubkeyTagValues(message.wrap?.tags || []).includes($pubkey!)) {
continue
}
const chatId = makeChatId(getPubkeyTagValues(message.tags).concat(message.pubkey))
pushToMapKey(messagesByChatId, chatId, message)
+8 -7
View File
@@ -39,6 +39,7 @@ import {
loadMutes,
loadProfile,
repository,
shouldUnwrap,
hasNegentropy,
} from "@welshman/app"
import {
@@ -46,7 +47,6 @@ import {
COMMENT_FILTER,
INDEXER_RELAYS,
REACTION_KINDS,
canDecrypt,
loadSettings,
userMembership,
defaultPubkeys,
@@ -334,14 +334,14 @@ const syncDMs = () => {
}
// When pubkey changes, re-sync
const unsubscribePubkey = derived([pubkey, canDecrypt], identity).subscribe(
([$pubkey, $canDecrypt]) => {
const unsubscribePubkey = derived([pubkey, shouldUnwrap], identity).subscribe(
([$pubkey, $shouldUnwrap]) => {
if ($pubkey !== currentPubkey) {
unsubscribeAll()
}
// If we have a pubkey, refresh our user's relay selections then sync our subscriptions
if ($pubkey && $canDecrypt) {
if ($pubkey && $shouldUnwrap) {
loadRelaySelections($pubkey)
.then(() => loadInboxRelaySelections($pubkey))
.then($l => subscribeAll($pubkey, getRelayTagValues(getListTags($l))))
@@ -352,11 +352,12 @@ const syncDMs = () => {
)
// When user inbox relays change, update synchronization
const unsubscribeSelections = userInboxRelaySelections.subscribe($l => {
const unsubscribeSelections = userInboxRelaySelections.subscribe($userInboxRelaySelections => {
const $pubkey = pubkey.get()
const $shouldUnwrap = shouldUnwrap.get()
if ($pubkey && $l) {
subscribeAll($pubkey, getRelayTagValues(getListTags($l)))
if ($pubkey && $shouldUnwrap) {
subscribeAll($pubkey, getRelayTagValues(getListTags($userInboxRelaySelections)))
}
})
+8 -13
View File
@@ -17,7 +17,6 @@ import {
getPubkeyTagValues,
} from "@welshman/util"
import {
ensureUnwrapped,
makeChatId,
entityLink,
decodeRelay,
@@ -85,20 +84,16 @@ export const getPrimaryNavItemIndex = ($page: Page) => {
}
export const goToEvent = async (event: TrustedEvent, options: Record<string, any> = {}) => {
const unwrapped = await ensureUnwrapped(event)
const urls = Array.from(tracker.getRelays(event.id))
const path = await getEventPath(event, urls)
if (unwrapped) {
const urls = Array.from(tracker.getRelays(unwrapped.id))
const path = await getEventPath(unwrapped, urls)
if (path.includes("://")) {
window.open(path)
} else {
goto(path, options)
if (path.includes("://")) {
window.open(path)
} else {
goto(path, options)
await sleep(300)
await scrollToEvent(unwrapped.id)
}
await sleep(300)
await scrollToEvent(event.id)
}
}
+25 -1
View File
@@ -33,7 +33,7 @@ import {
verifiedSymbol,
} from "@welshman/util"
import type {Zapper, TrustedEvent} from "@welshman/util"
import type {RepositoryUpdate} from "@welshman/relay"
import type {RepositoryUpdate, WrapItem} from "@welshman/net"
import type {Handle, Relay} from "@welshman/app"
import {
plaintext,
@@ -44,6 +44,7 @@ import {
zappers,
onZapper,
onHandle,
wrapManager,
} from "@welshman/app"
import {Collection} from "@lib/storage"
@@ -258,6 +259,28 @@ const syncPlaintext = async () => {
})
}
const syncWrapManager = async () => {
const collection = new Collection<WrapItem>({
table: "wraps",
shards: Array.from("0123456789abcdef"),
getShard: (item: WrapItem) => last(hash(item.id)),
})
wrapManager.load(await collection.get())
const addOne = batch(3000, (wrapItems: WrapItem[]) => collection.add(wrapItems))
const updateAll = throttle(3000, () => collection.set(wrapManager.dump()))
wrapManager.on("add", addOne)
wrapManager.on("remove", updateAll)
return () => {
wrapManager.off("add", addOne)
wrapManager.off("remove", updateAll)
}
}
export const syncDataStores = () =>
Promise.all([
syncEvents(),
@@ -267,4 +290,5 @@ export const syncDataStores = () =>
syncZappers(),
syncFreshness(),
syncPlaintext(),
syncWrapManager(),
])
+11 -51
View File
@@ -8,10 +8,9 @@
import {App, type URLOpenListenerEvent} from "@capacitor/app"
import {dev} from "$app/environment"
import {goto} from "$app/navigation"
import {sync, localStorageProvider} from "@welshman/store"
import {assoc, call, defer, dissoc, on, sleep, spec, TaskQueue} from "@welshman/lib"
import type {TrustedEvent, StampedEvent} from "@welshman/util"
import {WRAP} from "@welshman/util"
import {sync} from "@welshman/store"
import {assoc, call, defer, dissoc, on, sleep, spec} from "@welshman/lib"
import type {StampedEvent} from "@welshman/util"
import {Nip46Broker, makeSecret} from "@welshman/signer"
import type {Socket, RelayMessage, ClientMessage} from "@welshman/net"
import {
@@ -33,6 +32,7 @@
signer,
signerLog,
dropSession,
shouldUnwrap,
loginWithNip01,
loginWithNip46,
loadRelaySelections,
@@ -55,8 +55,6 @@
import {
userSettingsValues,
relaysPendingTrust,
ensureUnwrapped,
canDecrypt,
getSetting,
relaysMostlyRestricted,
} from "@app/core/state"
@@ -106,44 +104,6 @@
...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
navigator.serviceWorker?.addEventListener("message", event => {
if (event.data && event.data.type === "NAVIGATE") {
@@ -217,16 +177,9 @@
}
})
// Unwrap gift wraps as they come in, but throttled
const unwrapper = new TaskQueue<TrustedEvent>({batchSize: 10, processItem: ensureUnwrapped})
repository.on("update", ({added}) => {
for (const event of added) {
loadRelaySelections(event.pubkey)
if ($canDecrypt && event.kind === WRAP) {
unwrapper.push(event)
}
}
})
@@ -244,6 +197,13 @@
storage: preferencesStorageProvider,
})
// Sync shouldUnwrap
await sync({
key: "shouldUnwrap",
store: shouldUnwrap,
storage: preferencesStorageProvider,
})
// Sync application data (relay, events, etc)
await storage.syncDataStores()
+1 -2
View File
@@ -4,8 +4,7 @@
import type {MakeNonOptional} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
import {Address, getIdFilters} from "@welshman/util"
import {LOCAL_RELAY_URL} from "@welshman/relay"
import {load} from "@welshman/net"
import {load, LOCAL_RELAY_URL} from "@welshman/net"
import {page} from "$app/stores"
import {goto} from "$app/navigation"
import Spinner from "@lib/components/Spinner.svelte"
+3 -2
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import {onMount} from "svelte"
import {goto} from "$app/navigation"
import {shouldUnwrap} from "@welshman/app"
import AddCircle from "@assets/icons/add-circle.svg?dataurl"
import Compass from "@assets/icons/compass.svg?dataurl"
import ChatRound from "@assets/icons/chat-round.svg?dataurl"
@@ -12,11 +13,11 @@
import ChatEnable from "@app/components/ChatEnable.svelte"
import {pushModal} from "@app/util/modal"
import {makeSpacePath} from "@app/util/routes"
import {PLATFORM_NAME, PLATFORM_RELAYS, canDecrypt} from "@app/core/state"
import {PLATFORM_NAME, PLATFORM_RELAYS} from "@app/core/state"
const addSpace = () => pushModal(SpaceAdd)
const openChat = () => ($canDecrypt ? goto("/chat") : pushModal(ChatEnable, {next: "/chat"}))
const openChat = () => ($shouldUnwrap ? goto("/chat") : pushModal(ChatEnable, {next: "/chat"}))
onMount(() => {
if (PLATFORM_RELAYS.length > 0) {