-
-
-
- {#if showActivity}
-
- {/if}
-
-
+
+ {#if room && showRoom}
+
+ Posted in #
+
+ {/if}
+
+
+ {#if showActivity}
+
+ {/if}
+
diff --git a/src/app/components/ThreadCreate.svelte b/src/app/components/ThreadCreate.svelte
index 4f0a734f..51723d4f 100644
--- a/src/app/components/ThreadCreate.svelte
+++ b/src/app/components/ThreadCreate.svelte
@@ -16,7 +16,12 @@
import {makeEditor} from "@app/editor"
import {canEnforceNip70} from "@app/core/commands"
- const {url} = $props()
+ type Props = {
+ url: string
+ room?: string
+ }
+
+ const {url, room}: Props = $props()
const shouldProtect = canEnforceNip70(url)
@@ -52,6 +57,10 @@
tags.push(PROTECTED)
}
+ if (room) {
+ tags.push(["h", room])
+ }
+
publishThunk({
relays: [url],
event: makeEvent(THREAD, {content, tags}),
diff --git a/src/app/components/ThreadItem.svelte b/src/app/components/ThreadItem.svelte
index 1a064601..8ce989c1 100644
--- a/src/app/components/ThreadItem.svelte
+++ b/src/app/components/ThreadItem.svelte
@@ -1,10 +1,12 @@
@@ -33,7 +36,11 @@
- Posted by
+ Posted by
+
+ {#if room}
+ in
+ {/if}
diff --git a/src/app/components/ZapButton.svelte b/src/app/components/ZapButton.svelte
index 55c45918..7f2ece4f 100644
--- a/src/app/components/ZapButton.svelte
+++ b/src/app/components/ZapButton.svelte
@@ -9,7 +9,7 @@
import {pushModal} from "@app/util/modal"
type Props = {
- url: string
+ url?: string
event: TrustedEvent
children: Snippet
replaceState?: boolean
diff --git a/src/app/core/requests.ts b/src/app/core/requests.ts
index e821e64a..05e9ce24 100644
--- a/src/app/core/requests.ts
+++ b/src/app/core/requests.ts
@@ -1,10 +1,6 @@
import {get, writable} from "svelte/store"
import {
partition,
- chunk,
- sample,
- sleep,
- shuffle,
uniq,
int,
YEAR,
@@ -18,12 +14,9 @@ import {
fromPairs,
} from "@welshman/lib"
import {
- MESSAGE,
DELETE,
- THREAD,
EVENT_TIME,
AUTH_INVITE,
- COMMENT,
ALERT_EMAIL,
ALERT_WEB,
ALERT_IOS,
@@ -47,24 +40,10 @@ import {
thunkQueue,
makeFeedController,
loadRelay,
- loadMutes,
- loadFollows,
- loadProfile,
- loadBlossomServers,
- loadRelaySelections,
- loadInboxRelaySelections,
} from "@welshman/app"
import {createScroller} from "@lib/html"
import {daysBetween} from "@lib/util"
-import {
- NOTIFIER_RELAY,
- INDEXER_RELAYS,
- defaultPubkeys,
- userRoomsByUrl,
- getUrlsForEvent,
- loadMembership,
- loadSettings,
-} from "@app/core/state"
+import {NOTIFIER_RELAY, getUrlsForEvent} from "@app/core/state"
// Utils
@@ -359,80 +338,6 @@ export const loadAlertStatuses = (pubkey: string) =>
filters: [{kinds: [ALERT_STATUS], "#p": [pubkey]}],
})
-// Application requests
-
-export const listenForNotifications = () => {
- const controller = new AbortController()
-
- for (const [url, allRooms] of userRoomsByUrl.get()) {
- // Limit how many rooms we load at a time, since we have to send a separate filter
- // for each one due to relay29 being picky
- const rooms = shuffle(Array.from(allRooms)).slice(0, 30)
-
- load({
- signal: controller.signal,
- relays: [url],
- filters: [
- {kinds: [THREAD], limit: 1},
- {kinds: [MESSAGE], limit: 1},
- {kinds: [COMMENT], "#K": [String(THREAD)], limit: 1},
- ...rooms.map(room => ({kinds: [MESSAGE], "#h": [room], limit: 1})),
- ],
- })
-
- request({
- signal: controller.signal,
- relays: [url],
- filters: [
- {kinds: [THREAD], since: now()},
- {kinds: [MESSAGE], since: now()},
- {kinds: [COMMENT], "#K": [String(THREAD)], since: now()},
- ...rooms.map(room => ({kinds: [MESSAGE], "#h": [room], since: now()})),
- ],
- })
- }
-
- return () => controller.abort()
-}
-
-export const loadUserData = async (pubkey: string, relays: string[] = []) => {
- await Promise.race([sleep(3000), loadRelaySelections(pubkey, relays)])
-
- const promise = Promise.race([
- sleep(3000),
- Promise.all([
- loadInboxRelaySelections(pubkey, relays),
- loadBlossomServers(pubkey, relays),
- loadMembership(pubkey, relays),
- loadSettings(pubkey, relays),
- loadProfile(pubkey, relays),
- loadFollows(pubkey, relays),
- loadMutes(pubkey, relays),
- loadAlertStatuses(pubkey),
- loadAlerts(pubkey),
- ]),
- ])
-
- // Load followed profiles slowly in the background without clogging other stuff up. Only use a single
- // indexer relay to avoid too many redundant validations, which slow things down and eat bandwidth
- promise.then(async () => {
- for (const pubkeys of chunk(50, get(defaultPubkeys))) {
- const relays = sample(1, INDEXER_RELAYS)
-
- await sleep(1000)
-
- for (const pubkey of pubkeys) {
- loadMembership(pubkey, relays)
- loadProfile(pubkey, relays)
- loadFollows(pubkey, relays)
- loadMutes(pubkey, relays)
- }
- }
- })
-
- return promise
-}
-
export const discoverRelays = (lists: List[]) =>
Promise.all(
uniq(lists.flatMap($l => getRelaysFromList($l)))
diff --git a/src/app/core/sync.ts b/src/app/core/sync.ts
new file mode 100644
index 00000000..3ea0d3b0
--- /dev/null
+++ b/src/app/core/sync.ts
@@ -0,0 +1,250 @@
+import {page} from "$app/stores"
+import type {Unsubscriber} from "svelte/store"
+import {derived, get} from "svelte/store"
+import {call, chunk, sleep, now, identity, WEEK, ago} from "@welshman/lib"
+import {
+ getListTags,
+ getRelayTagValues,
+ WRAP,
+ MESSAGE,
+ ZAP_GOAL,
+ THREAD,
+ EVENT_TIME,
+ COMMENT,
+ isSignedEvent,
+} from "@welshman/util"
+import {request, pull} from "@welshman/net"
+import {
+ pubkey,
+ loadRelay,
+ userFollows,
+ userRelaySelections,
+ userInboxRelaySelections,
+ loadRelaySelections,
+ loadInboxRelaySelections,
+ loadBlossomServers,
+ loadFollows,
+ loadMutes,
+ loadProfile,
+ repository,
+} from "@welshman/app"
+import {
+ INDEXER_RELAYS,
+ canDecrypt,
+ loadSettings,
+ userMembership,
+ defaultPubkeys,
+ decodeRelay,
+ loadMembership,
+} from "@app/core/state"
+import {loadAlerts, loadAlertStatuses} from "@app/core/requests"
+
+const syncRelays = () => {
+ for (const url of INDEXER_RELAYS) {
+ loadRelay(url)
+ }
+
+ const unsubscribePage = page.subscribe($page => {
+ if ($page.params.relay) {
+ loadRelay(decodeRelay($page.params.relay))
+ }
+ })
+
+ const unsubscribeMembership = userMembership.subscribe($l => {
+ for (const url of getRelayTagValues(getListTags($l))) {
+ loadRelay(url)
+ }
+ })
+
+ return () => {
+ unsubscribePage()
+ unsubscribeMembership()
+ }
+}
+
+const syncUserData = () => {
+ const unsubscribePubkey = pubkey.subscribe($pubkey => {
+ if ($pubkey) {
+ loadRelaySelections($pubkey)
+ }
+ })
+
+ const unsubscribeSelections = userRelaySelections.subscribe($l => {
+ const $pubkey = pubkey.get()
+
+ if ($pubkey) {
+ loadAlerts($pubkey)
+ loadAlertStatuses($pubkey)
+ loadBlossomServers($pubkey)
+ loadFollows($pubkey)
+ loadMembership($pubkey)
+ loadMutes($pubkey)
+ loadProfile($pubkey)
+ loadSettings($pubkey)
+ }
+ })
+
+ const unsubscribeFollows = userFollows.subscribe(async $l => {
+ for (const pubkeys of chunk(10, get(defaultPubkeys))) {
+ // This isn't urgent, avoid clogging other stuff up
+ await sleep(1000)
+
+ for (const pk of pubkeys) {
+ loadRelaySelections(pk).then(() => {
+ loadMembership(pk)
+ loadProfile(pk)
+ loadFollows(pk)
+ loadMutes(pk)
+ })
+ }
+ }
+ })
+
+ return () => {
+ unsubscribePubkey()
+ unsubscribeSelections()
+ unsubscribeFollows()
+ }
+}
+
+const syncSpace = (url: string) => {
+ const controller = new AbortController()
+
+ // Load historical data
+ pull({
+ relays: [url],
+ signal: controller.signal,
+ filters: [{kinds: [ZAP_GOAL, EVENT_TIME, THREAD, MESSAGE, COMMENT]}],
+ events: repository
+ .query([{kinds: [ZAP_GOAL, EVENT_TIME, THREAD, MESSAGE, COMMENT]}])
+ .filter(isSignedEvent),
+ })
+
+ // Load new events
+ request({
+ relays: [url],
+ signal: controller.signal,
+ filters: [{kinds: [ZAP_GOAL, EVENT_TIME, THREAD, MESSAGE, COMMENT], since: now()}],
+ })
+
+ return () => controller.abort()
+}
+
+const syncSpaces = () => {
+ const unsubscribersByUrl = new Map
()
+ const unsubscribeMembership = userMembership.subscribe($l => {
+ const urls = getRelayTagValues(getListTags($l))
+
+ // Start syncing newly added spaces
+ for (const url of urls) {
+ if (!unsubscribersByUrl.has(url)) {
+ unsubscribersByUrl.set(url, syncSpace(url))
+ }
+ }
+
+ // stop syncing removed spaces
+ for (const [url, unsubscribe] of unsubscribersByUrl.entries()) {
+ if (!urls.includes(url)) {
+ unsubscribersByUrl.delete(url)
+ unsubscribe()
+ }
+ }
+ })
+
+ return () => {
+ Array.from(unsubscribersByUrl.values()).forEach(call)
+ unsubscribeMembership()
+ }
+}
+
+const syncDMRelay = (url: string, pubkey: string) => {
+ const controller = new AbortController()
+
+ // Load historical data
+ pull({
+ relays: [url],
+ signal: controller.signal,
+ filters: [{kinds: [WRAP], "#p": [pubkey], until: ago(WEEK, 2)}],
+ events: repository
+ .query([{kinds: [ZAP_GOAL, EVENT_TIME, THREAD, MESSAGE, COMMENT]}])
+ .filter(isSignedEvent),
+ })
+
+ // Load new events
+ request({
+ relays: [url],
+ signal: controller.signal,
+ filters: [{kinds: [WRAP], "#p": [pubkey], since: ago(WEEK, 2)}],
+ })
+
+ return () => controller.abort()
+}
+
+const syncDMs = () => {
+ const unsubscribersByUrl = new Map()
+
+ let currentPubkey: string | undefined
+
+ const unsubscribeAll = () => {
+ for (const [url, unsubscribe] of unsubscribersByUrl.entries()) {
+ unsubscribersByUrl.delete(url)
+ unsubscribe()
+ }
+ }
+
+ const subscribeAll = (pubkey: string, urls: string[]) => {
+ // Start syncing newly added relays
+ for (const url of urls) {
+ if (!unsubscribersByUrl.has(url)) {
+ unsubscribersByUrl.set(url, syncDMRelay(url, pubkey))
+ }
+ }
+
+ // Stop syncing removed spaces
+ for (const [url, unsubscribe] of unsubscribersByUrl.entries()) {
+ if (!urls.includes(url)) {
+ unsubscribersByUrl.delete(url)
+ unsubscribe()
+ }
+ }
+ }
+
+ // When pubkey changes, re-sync
+ const unsubscribePubkey = derived([pubkey, canDecrypt], identity).subscribe(
+ ([$pubkey, $canDecrypt]) => {
+ if ($pubkey !== currentPubkey) {
+ unsubscribeAll()
+ }
+
+ // If we have a pubkey, refresh our user's relay selections then sync our subscriptions
+ if ($pubkey && $canDecrypt) {
+ loadRelaySelections($pubkey)
+ .then(() => loadInboxRelaySelections($pubkey))
+ .then($l => subscribeAll($pubkey, getRelayTagValues(getListTags($l))))
+ }
+
+ currentPubkey = $pubkey
+ },
+ )
+
+ // When user inbox relays change, update synchronization
+ const unsubscribeSelections = userInboxRelaySelections.subscribe($l => {
+ const $pubkey = pubkey.get()
+
+ if ($pubkey && $l) {
+ subscribeAll($pubkey, getRelayTagValues(getListTags($l)))
+ }
+ })
+
+ return () => {
+ unsubscribeAll()
+ unsubscribePubkey()
+ unsubscribeSelections()
+ }
+}
+
+export const syncApplicationData = () => {
+ const unsubscribers = [syncRelays(), syncUserData(), syncSpaces(), syncDMs()]
+
+ return () => unsubscribers.forEach(call)
+}
diff --git a/src/app/util/history.ts b/src/app/util/history.ts
new file mode 100644
index 00000000..b08d34a3
--- /dev/null
+++ b/src/app/util/history.ts
@@ -0,0 +1,11 @@
+import {page} from "$app/stores"
+
+export const lastPageBySpaceUrl = new Map()
+
+export const setupHistory = () => {
+ page.subscribe($page => {
+ if ($page.params.relay) {
+ lastPageBySpaceUrl.set($page.params.relay, $page.url.pathname)
+ }
+ })
+}
diff --git a/src/app/util/notifications.ts b/src/app/util/notifications.ts
index 0f3cb967..272a6b8f 100644
--- a/src/app/util/notifications.ts
+++ b/src/app/util/notifications.ts
@@ -3,10 +3,11 @@ import {synced, throttled} from "@welshman/store"
import {pubkey, relaysByUrl} from "@welshman/app"
import {prop, spec, identity, now, groupBy} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
-import {EVENT_TIME, MESSAGE, THREAD, COMMENT, getTagValue} from "@welshman/util"
+import {ZAP_GOAL, EVENT_TIME, MESSAGE, THREAD, COMMENT, getTagValue} from "@welshman/util"
import {
makeSpacePath,
makeChatPath,
+ makeGoalPath,
makeThreadPath,
makeCalendarPath,
makeSpaceChatPath,
@@ -76,45 +77,52 @@ export const notifications = derived(
}
}
- const allThreadEvents = $repository.query([
- {kinds: [THREAD]},
- {kinds: [COMMENT], "#K": [String(THREAD)]},
- ])
+ const allGoalComments = $repository.query([{kinds: [COMMENT], "#K": [String(ZAP_GOAL)]}])
- const allCalendarEvents = $repository.query([
- {kinds: [EVENT_TIME]},
- {kinds: [COMMENT], "#K": [String(EVENT_TIME)]},
- ])
+ const allThreadComments = $repository.query([{kinds: [COMMENT], "#K": [String(THREAD)]}])
- const allMessageEvents = $repository.query([{kinds: [MESSAGE]}])
+ const allCalendarComments = $repository.query([{kinds: [COMMENT], "#K": [String(EVENT_TIME)]}])
+
+ const allMessages = $repository.query([{kinds: [MESSAGE, THREAD, ZAP_GOAL, EVENT_TIME]}])
for (const [url, rooms] of $userRoomsByUrl.entries()) {
const spacePath = makeSpacePath(url)
+ const goalPath = makeGoalPath(url)
const threadPath = makeThreadPath(url)
const calendarPath = makeCalendarPath(url)
const messagesPath = makeSpaceChatPath(url)
- const threadEvents = allThreadEvents.filter(e => $getUrlsForEvent(e.id).includes(url))
- const calendarEvents = allCalendarEvents.filter(e => $getUrlsForEvent(e.id).includes(url))
- const messagesEvents = allMessageEvents.filter(e => $getUrlsForEvent(e.id).includes(url))
+ const goalComments = allGoalComments.filter(e => $getUrlsForEvent(e.id).includes(url))
+ const threadComments = allThreadComments.filter(e => $getUrlsForEvent(e.id).includes(url))
+ const calendarComments = allCalendarComments.filter(e => $getUrlsForEvent(e.id).includes(url))
+ const messages = allMessages.filter(e => $getUrlsForEvent(e.id).includes(url))
- if (hasNotification(threadPath, threadEvents[0])) {
- paths.add(spacePath)
- paths.add(threadPath)
- }
+ const commentsByGoalId = groupBy(
+ e => getTagValue("E", e.tags),
+ goalComments.filter(spec({kind: COMMENT})),
+ )
- if (hasNotification(calendarPath, calendarEvents[0])) {
- paths.add(spacePath)
- paths.add(calendarPath)
+ for (const [goalId, [comment]] of commentsByGoalId.entries()) {
+ const goalItemPath = makeGoalPath(url, goalId)
+
+ if (hasNotification(goalPath, comment)) {
+ paths.add(goalPath)
+ }
+ if (hasNotification(goalItemPath, comment)) {
+ paths.add(goalItemPath)
+ }
}
const commentsByThreadId = groupBy(
e => getTagValue("E", e.tags),
- threadEvents.filter(spec({kind: COMMENT})),
+ threadComments.filter(spec({kind: COMMENT})),
)
for (const [threadId, [comment]] of commentsByThreadId.entries()) {
const threadItemPath = makeThreadPath(url, threadId)
+ if (hasNotification(threadPath, comment)) {
+ paths.add(threadPath)
+ }
if (hasNotification(threadItemPath, comment)) {
paths.add(threadItemPath)
}
@@ -122,24 +130,26 @@ export const notifications = derived(
const commentsByEventId = groupBy(
e => getTagValue("E", e.tags),
- calendarEvents.filter(spec({kind: COMMENT})),
+ calendarComments.filter(spec({kind: COMMENT})),
)
for (const [eventId, [comment]] of commentsByEventId.entries()) {
- const calendarEventPath = makeCalendarPath(url, eventId)
+ const calendarItemPath = makeCalendarPath(url, eventId)
- if (hasNotification(calendarEventPath, comment)) {
- paths.add(calendarEventPath)
+ if (hasNotification(calendarPath, comment)) {
+ paths.add(calendarPath)
+ }
+
+ if (hasNotification(calendarItemPath, comment)) {
+ paths.add(calendarItemPath)
}
}
if (hasNip29($relaysByUrl.get(url))) {
for (const room of rooms) {
const roomPath = makeRoomPath(url, room)
- const latestEvent = allMessageEvents.find(
- e =>
- $getUrlsForEvent(e.id).includes(url) &&
- e.tags.find(t => t[0] === "h" && t[1] === room),
+ const latestEvent = allMessages.find(
+ e => $getUrlsForEvent(e.id).includes(url) && e.tags.find(spec(["h", room])),
)
if (hasNotification(roomPath, latestEvent)) {
@@ -148,7 +158,7 @@ export const notifications = derived(
}
}
} else {
- if (hasNotification(messagesPath, messagesEvents[0])) {
+ if (hasNotification(messagesPath, messages[0])) {
paths.add(spacePath)
paths.add(messagesPath)
}
diff --git a/src/app/util/routes.ts b/src/app/util/routes.ts
index acc7818e..5ad0ac8a 100644
--- a/src/app/util/routes.ts
+++ b/src/app/util/routes.ts
@@ -3,7 +3,7 @@ import * as nip19 from "nostr-tools/nip19"
import {goto} from "$app/navigation"
import {nthEq, sleep} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
-import {tracker} from "@welshman/app"
+import {tracker, relaysByUrl} from "@welshman/app"
import {scrollToEvent} from "@lib/html"
import {identity} from "@welshman/lib"
import {
@@ -23,6 +23,7 @@ import {
decodeRelay,
encodeRelay,
userRoomsByUrl,
+ hasNip29,
ROOM,
} from "@app/core/state"
@@ -36,6 +37,14 @@ export const makeSpacePath = (url: string, ...extra: (string | undefined)[]) =>
.filter(identity)
.map(s => encodeURIComponent(s as string))
.join("/")
+ } else {
+ const relay = relaysByUrl.get().get(url)
+
+ if (hasNip29(relay)) {
+ path += "/recent"
+ } else {
+ path += "/chat"
+ }
}
return path
@@ -143,3 +152,14 @@ export const getEventPath = async (event: TrustedEvent, urls: string[]) => {
return entityLink(nip19.neventEncode({id: event.id, relays: urls}))
}
+
+export const getChannelItemPath = (url: string, event: TrustedEvent) => {
+ switch (event.kind) {
+ case THREAD:
+ return makeThreadPath(url, event.id)
+ case ZAP_GOAL:
+ return makeGoalPath(url, event.id)
+ case EVENT_TIME:
+ return makeCalendarPath(url, event.id)
+ }
+}
diff --git a/src/app/util/storage.ts b/src/app/util/storage.ts
index 19376b48..49cc8c01 100644
--- a/src/app/util/storage.ts
+++ b/src/app/util/storage.ts
@@ -167,20 +167,14 @@ const syncTracker = async () => {
tracker.load(relaysById)
- let p = Promise.resolve()
-
const updateOne = batch(3000, (ids: string[]) => {
- p = p.then(() => {
- collection.add(ids.map(id => [id, Array.from(tracker.getRelays(id))]))
- })
+ collection.add(ids.map(id => [id, Array.from(tracker.getRelays(id))]))
})
const updateAll = throttle(3000, () => {
- p = p.then(() => {
- collection.set(
- Array.from(tracker.relaysById.entries()).map(([id, relays]) => [id, Array.from(relays)]),
- )
- })
+ collection.set(
+ Array.from(tracker.relaysById.entries()).map(([id, relays]) => [id, Array.from(relays)]),
+ )
})
tracker.on("add", updateOne)
diff --git a/src/assets/icons/index.html b/src/assets/icons/index.html
new file mode 100644
index 00000000..c4a2df4e
--- /dev/null
+++ b/src/assets/icons/index.html
@@ -0,0 +1,1353 @@
+
+
+
+
+
+ Icon Gallery
+
+
+
+
+
+
+
+
+
+
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 8494a5b5..38530683 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -4,31 +4,17 @@
import {throttle} from "throttle-debounce"
import {onMount} from "svelte"
import * as nip19 from "nostr-tools/nip19"
- import {get, derived} from "svelte/store"
+ import {get} from "svelte/store"
import {App, type URLOpenListenerEvent} from "@capacitor/app"
import {dev} from "$app/environment"
import {goto} from "$app/navigation"
import {sync, localStorageProvider} from "@welshman/store"
- import {
- ago,
- assoc,
- call,
- defer,
- dissoc,
- identity,
- memoize,
- on,
- sleep,
- spec,
- TaskQueue,
- WEEK,
- } from "@welshman/lib"
+ 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 {Nip46Broker, makeSecret} from "@welshman/signer"
import type {Socket, RelayMessage, ClientMessage} from "@welshman/net"
import {
- request,
defaultSocketPolicies,
makeSocketPolicyAuth,
SocketEvent,
@@ -40,7 +26,6 @@
isClientClose,
} from "@welshman/net"
import {
- loadRelay,
repository,
pubkey,
session,
@@ -64,20 +49,18 @@
import {preferencesStorageProvider} from "@lib/storage"
import AppContainer from "@app/components/AppContainer.svelte"
import ModalContainer from "@app/components/ModalContainer.svelte"
+ import {setupHistory} from "@app/util/history"
import {setupTracking} from "@app/util/tracking"
import {setupAnalytics} from "@app/util/analytics"
import {
- INDEXER_RELAYS,
- userMembership,
userSettingsValues,
relaysPendingTrust,
ensureUnwrapped,
canDecrypt,
getSetting,
relaysMostlyRestricted,
- userInboxRelays,
} from "@app/core/state"
- import {loadUserData, listenForNotifications} from "@app/core/requests"
+ import {syncApplicationData} from "@app/core/sync"
import {theme} from "@app/util/theme"
import {toast, pushToast} from "@app/util/toast"
import {initializePushNotifications} from "@app/util/push"
@@ -192,8 +175,6 @@
// TODO: remove ack result
if (pubkey && ["ack", connectSecret].includes(result)) {
- await loadUserData(pubkey)
-
loginWithNip46(pubkey, clientSecret, signerPubkey, relays)
broker.cleanup()
success = true
@@ -224,6 +205,7 @@
if (!initialized) {
initialized = true
+ setupHistory()
setupTracking()
setupAnalytics()
@@ -374,46 +356,8 @@
},
)
- // Load relay info
- for (const url of INDEXER_RELAYS) {
- loadRelay(url)
- }
-
- // Load user data
- if ($pubkey) {
- await loadUserData($pubkey)
- }
-
- // Listen for space data, populate space-based notifications
- let unsubSpaces: any
-
- userMembership.subscribe(
- memoize($membership => {
- unsubSpaces?.()
- unsubSpaces = listenForNotifications()
- }),
- )
-
- // Listen for chats, populate chat-based notifications
- let controller: AbortController
-
- derived([pubkey, canDecrypt, userInboxRelays], identity).subscribe(
- ([$pubkey, $canDecrypt, $userInboxRelays]) => {
- controller?.abort()
- controller = new AbortController()
-
- if ($pubkey && $canDecrypt) {
- request({
- signal: controller.signal,
- relays: $userInboxRelays,
- filters: [
- {kinds: [WRAP], "#p": [$pubkey], since: ago(WEEK, 2)},
- {kinds: [WRAP], "#p": [$pubkey], limit: 100},
- ],
- })
- }
- },
- )
+ // Load user data, listen for messages, etc
+ syncApplicationData()
// subscribe to badge count for changes
notifications.badgeCount.subscribe(notifications.handleBadgeCountChanges)
diff --git a/src/routes/settings/profile/+page.svelte b/src/routes/settings/profile/+page.svelte
index b1ce4837..cca0b6a3 100644
--- a/src/routes/settings/profile/+page.svelte
+++ b/src/routes/settings/profile/+page.svelte
@@ -17,7 +17,7 @@
import FieldInline from "@lib/components/FieldInline.svelte"
import Button from "@lib/components/Button.svelte"
import Avatar from "@lib/components/Avatar.svelte"
- import Content from "@app/components/Content.svelte"
+ import ContentMinimal from "@app/components/ContentMinimal.svelte"
import ProfileEdit from "@app/components/ProfileEdit.svelte"
import ProfileDelete from "@app/components/ProfileDelete.svelte"
import SignerStatus from "@app/components/SignerStatus.svelte"
@@ -66,7 +66,7 @@
{#key $profile?.about}
-