Commit Graph
3578 Commits
Author SHA1 Message Date
cbae70336d fix: align GIF picker tap hitboxes with visible thumbnails
Fix GIF picker grid tap hitbox selecting adjacent item by aligning GIF picker tap hitboxes with visible thumbnails.

Co-authored-by: danieldaquino <24692108+danieldaquino@users.noreply.github.com>
Changelog-Fixed: Fix GIF picker grid tap hitbox selecting adjacent item
Closes: https://github.com/damus-io/damus/issues/3744
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-05-21 15:35:52 -07:00
Daniel D’AquinoandGitHub 73eddeae46 Merge pull request #3773 from jb55/jb55-ios-2397-restore-signal-indicator
Restore signal indicator

Changelog-Changed: Restored signal indicator
Changelog-Fixed: Fixed issues that could cause the signal indicator to become outdated
2026-05-18 16:50:36 -07:00
William CasarinandClaude Opus 4.6 945ebff880 signal: hide indicator when all relays are connected
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-18 12:12:11 -07:00
William CasarinandClaude Opus 4.6 d2ef0ac3b1 relay: fix relays refusing to reconnect after initial connect fails
When isConnecting gets stuck (e.g. from silenced error 57 or lost
WebSocket events), reconnect() would bail out permanently. Instead of
unconditionally blocking on isConnecting, allow reconnect if the
connection attempt has gone stale (>5s with no socket response).

Closes: https://github.com/damus-io/damus/issues/3774

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-18 11:53:57 -07:00
William CasarinandClaude Opus 4.6 aae43cff3b Fix connectivity indicator and port signal bars from Android
The SignalView was never appearing because update_signal_from_pool was
defined but never called, leaving signal data at 0/0. Fix by having
RelayPool maintain its own SignalModel, updating it on connection
events, relay add/remove. Wire views directly to the pool signal via
NostrNetworkManager instead of the disconnected HomeModel.signal.

Replace the text-based indicator with signal strength bars matching
the Android app: 4 progressive-height bars colored red->yellow->green
based on the connected/total relay ratio.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-18 11:00:00 -07:00
Daniel D’AquinoandGitHub c2cdd1292f Merge pull request #3740 from danieldaquino/gh-3731
Sentry integration
2026-05-11 11:34:11 -07:00
Daniel D’Aquino 3c98282f95 Sentry integration
Changelog-Added: Added Sentry error and diagnostics reporting to aid
future quality improvements
Closes: #3731
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-05-11 11:30:20 -07:00
Daniel D’Aquino 111fabf0b3 Replace Tenor GIF integration with Purple proxy
Remove Tenor API client and models; add PurpleGIFAPIClient and a
robust GIFModels decoder that supports Tenor and KLIPY payloads.
Remove Tenor API key setting and Secrets entry. Update GIF picker to
accept a Purple-backed view model, adjust Labs text, and update
Xcode project file references.

Closes: #3695
Changelog-Changed: Made GIF keyboard widely available to Purple users
without need for an API key (Damus Labs)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-05-04 11:39:15 -07:00
Daniel D’Aquino 2af65320ef Improve large-DB compaction UX and add developer auto-compact testing
mode

- Skip automatic compaction when `data.mdb` is 10GB or larger, and
  surface an in-app notification instead of surprising users with a long
  startup wait
- Keep manual compaction available for large databases by tracking
  whether a next-launch compaction request was scheduled automatically
  or explicitly by the user
- Add a large-database explanation to the compaction loading screen to
  clarify that long runtimes are expected for oversized databases and
  are usually a one-time catch-up cost
- Add a developer-only `Every minute` auto-compact schedule to make
  rollout and reminder behavior easier to test locally
- Add and update unit tests covering large-database auto-compaction
  skips, request-source persistence, reminder scheduling, and the
  developer testing interval

Motivation:
TestFlight users with long-lived databases were hitting the brand-new
compaction flow for the first time, which could turn startup into a
multi-minute wait. These changes make automatic compaction less
disruptive for very large databases, preserve an explicit manual path
for users who want to optimize immediately, and add a fast
developer-only schedule to make the new behavior easier to validate
during testing.

This is an enhancement for an unreleased feature, so therefore no
changelog is needed.

Closes: https://github.com/damus-io/damus/issues/3730
Changelog-None

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-04-29 14:40:18 -07:00
Daniel D’Aquino d6654dff29 Report Compaction Progress and Improve UI
Add NdbCompactionProgress and Step with user-facing titles/details,
and a progress callback to Ndb.compact_if_needed to emit stage updates.
Refactor CompactionView to a single CompactionState and render linear
progress, step title/detail and percentage. Ensure UI updates happen on
the MainActor and surface errors/completion cleanly.

Changelog-None
Closes: https://github.com/damus-io/damus/issues/3730

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-04-27 10:09:59 -07:00
Daniel D’Aquino 0d2f55f4e3 Move DB compaction to CompactionView
Introduce CompactionView and CompactionLoadingView to schedule and run
Ndb compaction on a background task before showing the main UI. Replace
the direct compaction calls in ContentView and make CompactionView the
app's launch entry so startup compaction presents a loading UI and
avoids blocking the main thread.

Changelog-Fixed: Fixed startup crash when app performs long-running
compaction procedure
Closes: #3726

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-04-23 19:02:01 -07:00
Daniel D’AquinoandGitHub 5cb8a495b5 Merge pull request #3708 from askeew/favorites-fix-xcode
Fix favorites timeline
2026-04-13 12:07:35 -07:00
Daniel D’AquinoandGitHub f7669d1093 Merge pull request #3719 from damus-io/copilot/add-auto-compact-lmdb-setting
Auto compact LMDB on a schedule
2026-04-06 17:13:04 -07:00
Daniel D’Aquino 9285504d9a Add auto-compact LMDB schedule setting with UI and tests
Closes: https://github.com/damus-io/damus/issues/3718
Changelog-Added: Automatic lossless storage optimization
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-04-06 15:01:06 -07:00
652e802ca6 Improve BlurOverlayView to look protective, not broken
The blur overlay previously used error-state iconography (eye.slash icon,
"Tap to load" button, raw URL display) which made users think media was
broken rather than intentionally hidden. Redesign to communicate
intentional protection:

- Replace eye.slash icon with shield icon
- Change title from "Media from someone you don't follow" to
  "Content hidden" (the old text was also wrong for undistractMode)
- Rename button from "Tap to load" to "Show"
- Remove raw URL display that added noise
- Remove unused properties (artifacts, size, damus_state, parentView)
  and dead ParentViewType enum that only existed for the URL display
- Simplify all 4 call sites to pass only the blur binding

Changelog-Changed: Redesigned media blur overlay to look like intentional protection instead of a broken state

Closes: https://github.com/damus-io/damus/issues/3662
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 14:48:30 -07:00
Askeew 75bbae86b3 Fix favorites timeline: filter in-place, manage queuing, persist tab selection and sync has_event.
Changelog-None:
Signed-off-by: Askeew <askeew@hotmail.com>
2026-03-27 09:10:36 +01:00
Daniel D’AquinoandGitHub 92cca89c06 Merge pull request #3642 from ericholguin/ios-26-fixes
ui: Fixes for iOS 26 toolbars
2026-03-18 17:21:59 -07:00
ericholguinandDaniel D’Aquino d99443be6d ui: Fixes for iOS 26 toolbars
Note: This will only become user-facing once we switch to liquid glass
mode, therefore no changelog entry is needed now.

Changelog-None
Closes: https://github.com/damus-io/damus/issues/3702
Co-Authored-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: ericholguin <ericholguin@apache.org>
2026-03-18 17:07:25 -07:00
Daniel D’AquinoandGitHub f175e79a78 Merge pull request #3699 from alltheseas/fix/relay-list-bottom-cutoff
fix: add bottom padding to UserRelaysView to prevent last relay cutoff
2026-03-18 14:40:05 -07:00
alltheseasandClaude Opus 4.6 4fe94b081c fix: add bottom padding to UserRelaysView to prevent last relay from being cut off
Closes #3697

Signed-off-by: alltheseas

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 15:40:47 -05:00
Daniel D’Aquino 96eb780f11 Reduce max age for stale temporary snapshots
The previous fix that implemented cleanup of temporary snapshots
included a max age for stale temporary snapshots, which was originally
set to 24h.

This improved the situation, but it still meant that the app could
accumulate 24 old snapshots, which leads to a non-trivial storage
amount.

This commit changes that to 30 minutes for better storage efficiency.

The previous fix was not published on the App Store yet, so no changelog
entry is needed.

Closes: https://github.com/damus-io/damus/issues/3696
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-03-18 12:07:55 -07:00
Daniel D’AquinoandGitHub e07e8c2dc3 Merge pull request #3668 from tyiu/translations
Translations
2026-03-16 20:00:48 -07:00
Daniel D’AquinoGitHubcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
ae1fefcfdd Fix subject-verb agreement issue in user-facing label
"Notes... usually contains" should be "Notes... usually contain" since "Notes" is plural.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-16 20:00:02 -07:00
2e10c0b4c5 Fix stale relay list: replace UserDefaults hex lookup with ndb query
Replace the fragile `latestRelayListEventIdHex` UserDefaults lookup in
`getLatestNIP65RelayListEvent()` with a direct nostrdb query using
`ndb.query(filters:maxResults:)` on the AUTHOR_KINDS index. This
eliminates the stale-hex failure mode where relay add/remove operations
would silently fall back to bootstrap or year-old relay lists.

Add an in-memory `lastSetRelayList` cache to bridge the nostrdb async
write gap — `set()` populates it, `getUserCurrentRelayList()` checks it
first, and `load()` clears it once ndb has committed.

Remove `latestRelayListEventIdHex` from: Delegate protocol,
DamusState, SaveKeysView, UserSettingsStore, and all test mocks.

Includes 5 regression tests that fail before the fix and pass after:
- testRemoveRelayDoesNotFallBackToBootstrapList
- testCacheBridgesAsyncWriteGap
- testRapidSequentialRemovesDoNotReintroduceRelays
- testLoadClearsCacheAndReadsFromNdb
- testNdbQueryFindsRelayListWithoutStoredHex

Changelog-Fixed: Fix stale relay list causing inability to disconnect relays
Closes: #3537
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
2026-03-16 18:32:22 -07:00
Daniel D’Aquino 2c6e574b11 feat: implement LMDB compact solution for storage optimization
- Add `compact(to:)` method on `Ndb` using `mdb_env_copy2` / `ndb_snapshot`
  with `MDB_CP_COMPACT` flag to produce a smaller compacted database copy
- Add `compact_if_needed(db_path:)` static startup method that reads a
  UserDefaults flag, opens a temp Ndb, compacts to a sibling temp dir,
  atomically replaces `data.mdb`, cleans up, and clears the flag
- Add `set_compact_on_next_launch()` to schedule compaction from the UI
- Call `Ndb.compact_if_needed()` in `ContentView.connect()` before the
  main Ndb instance is opened
- Add `CompactDatabaseButton` to `StorageSettingsView` with a confirmation
  dialog that informs the user a restart is needed
- Add `NdbCompactionTests` unit tests covering flag API, no-op path,
  missing-DB path, and full round-trip compaction

Closes: https://github.com/damus-io/damus/issues/3680
Changelog-Added: Added "Compact Database" button in Settings → Storage that reclaims unused space by compacting the NostrDB on the next app launch
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-03-16 16:29:27 -07:00
Daniel D’Aquino 2ea9cdd416 Fix snapshot promotion and add temporary snapshot cleanup
Preserve the last good shared snapshot until a replacement is fully staged, and proactively remove stale snapshot_temp_* directories left behind by interrupted snapshot attempts. This prevents orphaned temp snapshots from accumulating while avoiding false cleanup errors after successful promotion.

Changelog-Fixed: Fixed issue where temporary files would not get cleaned up
Closes: https://github.com/damus-io/damus/issues/3684
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-03-16 03:03:56 -07:00
Daniel D’Aquino 0a801b01cb Add full container file breakdown to storage settings export
Users reported total app storage significantly higher than what the
storage settings view shows. To aid debugging, the export now includes
a "Full Container File Breakdown" section that enumerates every regular
file in the app sandbox and shared app group container, sorted by size
descending so orphaned/unexpectedly large files are easy to spot.

Changes:
- StorageStatsManager: add ContainerFileEntry and containerFileBreakdown()
- StorageStatsViewHelper: add formatContainerFileBreakdown() helper and
  include it at the end of formatStorageStatsAsText output

Closes: https://github.com/damus-io/damus/issues/3677
Changelog-Added: Full container file breakdown in storage settings export
2026-03-13 15:09:54 -07:00
alltheseasandClaude Opus 4.6 1768432a1e Move client tag display from feed to note detail view
Remove client tag from EventTop (feed header) and display it inline
next to the timestamp in SelectedEventView instead. Removes unused
ClientTagLabel struct. Applies lineLimit(1) with tail truncation to
guard against unbounded client tag names.

Closes: https://github.com/damus-io/damus/issues/3672
Signed-off-by: alltheseas

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:49:29 -05:00
tyiu 31e281ce73 Fix localization issues and export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2026-03-09 21:08:29 -04:00
transifex-integration[bot]andtyiu 963da2d4eb Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2026-03-07 00:23:32 -05:00
alltheseasandDaniel D’Aquino af3bb212c3 Show client tags on events
Display "via ClientName" indicator beside timestamps when an event has
a client tag, allowing users to see which nostr app published it.

Changelog-Added: Show client name on events when available
Closes: https://github.com/damus-io/damus/issues/3323
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
2026-02-27 13:19:55 -08:00
alltheseasandDaniel D’Aquino 7f2c575f20 Expose client tag toggle in settings
Add a Privacy section in Appearance settings allowing users to disable
client tag publishing if they prefer not to identify Damus when posting.

Ref: https://github.com/damus-io/damus/issues/3323
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
2026-02-27 13:19:55 -08:00
alltheseasandDaniel D’Aquino ec28822451 Add Damus client tag emission
- Add ClientTagMetadata struct with parsing helpers and documentation
- Append Damus client tags when posting across app, share, and drafts flows
- Gate the behavior behind a new publish_client_tag setting (default on)

Changelog-Added: Add client tag to published events to identify Damus
Ref: https://github.com/damus-io/damus/issues/3323
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
2026-02-27 13:19:55 -08:00
Daniel D’Aquino 795fce1b65 Add storage usage stats settings view
This commit implements a new Storage settings view that displays storage
usage statistics for NostrDB, snapshot database, and Kingfisher image cache.

Key features:
- Interactive pie chart visualization (iOS 17+) with tap-to-select functionality
- Pull-to-refresh gesture to recalculate storage
- Categorized list showing each storage type with size and percentage
- Total storage sum displayed at bottom
- Conditional compilation for iOS 16/17+ compatibility
- All calculations run on background thread to avoid blocking main thread
- NostrDB storage breakdown

Changelog-Added: Storage usage statistics view in Settings
Changelog-Changed: Moved clear cache button to storage settings
Closes: https://github.com/damus-io/damus/issues/3649
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-02-25 15:45:37 -08:00
copilot-swe-agent[bot]andDaniel D’Aquino 65e767b774 fix: refresh balance and transactions in WalletModel.connect() on wallet switch
When a new wallet is connected, clear stale balance and transaction data
from the previous wallet immediately so the view does not display outdated
information while fresh data is being fetched.

Closes: https://github.com/damus-io/damus/issues/3644
Changelog-Fixed: Wallet view now immediately clears stale data when switching wallets
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Co-authored-by: Daniel D’Aquino <daniel@daquino.me>
Tested-by: Daniel D’Aquino <daniel@daquino.me>
2026-02-25 13:24:11 -08:00
CopilotGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>danieldaquino
7be75f37c6 Fix: Gracefully ignore unsupported NWC response types (e.g. get_info)
When another NWC client (e.g. Alby) connected to the same relay calls
`get_info`, Damus receives the response and previously threw a
DecodingError.typeMismatch, causing an "Oops" error dialog to be shown.

Fix: Make `result_type` optional in `WalletConnect.Response`. Unknown
result types now decode without throwing — `result_type` and `result`
are set to `nil`, and the rest of the existing nil-guarded code paths
handle this silently.

Adds a test to verify `get_info` (and any future unknown result type)
is decoded gracefully.

Closes: #2204
Changelog-Fixed: Fixed issue where the app could display an error message when using another NWC wallet in parallel
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danieldaquino <24692108+danieldaquino@users.noreply.github.com>
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-02-23 12:50:25 -08:00
ericholguinandDaniel D’Aquino 84ef5ecf53 gifs: Tenor GIFs
This PR adds GIFs to Damus using Tenor as the service.
This is a Damus Labs feature to begin with.
In the future we should be able to also query nostr for gif media.

Changelog-Added: Added GIF keyboard support (Damus Labs only)
Signed-off-by: ericholguin <ericholguin@apache.org>
2026-02-20 17:56:04 -08:00
yseandDaniel D’Aquino b59816e180 wallet: models: unset type field for list transactions request
Removes the empty `type` field from the wallet's list_transactions
request in favor of a null field, which is parsable by serializers.

Signed-off-by: Hydra Yse <hydra_yse@proton.me>
2026-02-18 22:52:09 -08:00
yseandDaniel D’Aquino 609cdcc5f9 wallet: errors: add %@ string formatting instead of %s
This fixes a UI issue where the error message from the NWC response
would be incorrectly displayed due to utf-8 formatting.

Signed-off-by: Hydra Yse <hydra_yse@proton.me>
2026-02-18 22:33:33 -08:00
alltheseasandDaniel D’Aquino cfafcffde2 fix: wait for relay connection before loading nevent URLs
LoadableNostrEventViewModel.load() now calls awaitConnection() before
executeLoadingLogic(), preventing premature "not found" when opening
nevent URLs or search results before relays finish connecting.

Closes: https://github.com/damus-io/damus/pull/3559

Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
Tested-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: Daniel D’Aquino <daniel@daquino.me>
2026-02-16 19:51:21 -08:00
Daniel D’Aquino 2e1a98ff19 Add useful view for note-not-found state in quoted notes
Changelog-Added: Added a view for quotes notes that could not be loaded, including actionable items
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-02-16 13:16:21 -08:00
Daniel D’Aquino 7fa044d205 Fix infinite loading spinner regression
Root cause:
1. `lookup` looks up a note by its note id, and saving its note key
2. `lookup` then returns early (i.e. does not loading anything from the
   network) since it found the note
3. On the view, once it borrows the note from NostrDB (a query using its
   NoteKey), the query fails (Most likely due to transaction inheritance
   and the fact that the inherited transaction may be an older snapshot
   of the database without the note), causing the view loading logic to
   fail silently, leading to the infinite loading spinner

The issue was addressed by performing a single query during lookup and
copying the note contents directly at that point to avoid this
transaction inheritance issue.

In the future we should consider a more comprehensive fix to address
other instances where this may happen. I opened
https://github.com/damus-io/damus/issues/3607 for this future work.

Changelog-Fixed: Fixed an issue where notes would keep loading indefinitely in some cases
Closes: https://github.com/damus-io/damus/issues/3498
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-02-16 13:16:21 -08:00
William CasarinandClaude Opus 4.6 be6b0e2702 Move note language computation off the main thread
NLLanguageRecognizer.processString() is an expensive NLP operation that
was moved to @MainActor in 5058fb33, causing UI jank when scrolling.

This moves language detection back to the async preload path where it
runs off the main thread. get_preload_plan is synchronous again and
defers language computation to preload_event. Translations still happen
on the first preload pass since preload_event now checks .havent_tried
directly rather than relying on the load_translations flag from the plan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 10:16:25 -08:00
Daniel D’Aquino e271fa90d9 Fix issue that would cause RelayPool to close after ephemeral lease release
Issue was not released, so a changelog item is not needed.

Changelog-None
Closes: https://github.com/damus-io/damus/issues/3604
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-02-06 17:44:17 -08:00
William CasarinandDaniel D’Aquino 8c5027248b Show "Favorites" label below logo when viewing favorites timeline
Adds a visual indicator under the Damus logo when the favorites
timeline is active. Uses fixed height with opacity to prevent
layout bouncing when switching timelines.
2026-02-06 17:30:11 -08:00
William CasarinandDaniel D’Aquino 434c54f98e Fix favorites timeline not showing events when switching
The favorites timeline was empty because:
1. The @StateObject filter in InnerTimelineView was captured once at init
2. Favorite events were mixed with follows events and got drowned out

Fixed by:
- Adding viewId parameter to TimelineView to force view recreation on switch
- Creating separate favoriteEvents EventHolder for favorites
- Adding dedicated subscribe_to_favorites() subscription that inserts
  directly into favoriteEvents when contact cards are loaded
2026-02-06 17:30:11 -08:00
alltheseasGitHuballtheseasClaude Opus 4.5Daniel D'Aquino <daniel@daquino.me
9a1ae6f9b5 Consume NIP-19 relay hints for event fetching
Extract and use relay hints from bech32 entities (nevent, nprofile, naddr)
and event tag references (e, q tags) to fetch events from hinted relays
not in the user's relay pool.

Changes:
- Parse relay hints from bech32 TLV data in URLHandler
- Pass relay hints through SearchType and NoteReference enums
- Add ensureConnected() to RelayPool for ephemeral relay connections
- Implement ephemeral relay lease management with race condition protection
- Add repostTarget() helper to extract relay hints from repost e tags
- Add QuoteRef struct to preserve relay hints from q tags (NIP-10/NIP-18)
- Support relay hints in replies with author pubkey in e-tags (NIP-10)
- Implement fallback broadcast when hinted relays don't respond
- Add comprehensive test coverage for relay hint functionality
- Add DEBUG logging for relay hint tracing during development

Implementation details:
- Connect to hinted relays as ephemeral, returning early when first connects
- Use total deadline to prevent timeout accumulation across hint attempts
- Decrement lease count before suspension points to ensure atomicity
- Fall back to broadcast if hints don't resolve or respond

Closes: https://github.com/damus-io/damus/issues/1147
Changelog-Added: Added relay hint support for nevent, nprofile, naddr links and event tag references (reposts, quotes, replies)
Signed-off-by: alltheseas
Signed-off-by: Daniel D'Aquino <daniel@daquino.me>
Co-authored-by: alltheseas <alltheseas@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Daniel D'Aquino <daniel@daquino.me
2026-02-02 18:52:41 -08:00
1505a8f2e4 Simplify Swift invoice handling with non-optional return types
- Mentions.swift: convert_invoice_description now returns non-optional
  InvoiceDescription, returning empty description for BOLT11 compliance
  (both description and description_hash are optional per spec)

- Block.swift, NdbBlock.swift, NostrEvent.swift, NoteContent.swift:
  Updated call sites to use non-optional invoice conversion

- InvoiceTests.swift: Added test for specific failing invoice

Signed-off-by: alltheseas <alltheseas@noreply.github.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:10:09 -08:00
Daniel D’Aquino c88d881801 Fix wallet view hanging on loading placeholder indefinitely
Resolves a race condition in wallet data fetching that caused views to
hang on loading placeholders. The issue occurred due to:

1. Multiple state updates triggering view re-renders mid-fetch
2. Refreshable tasks getting cancelled before completion

Changes:
- Remove premature state reset in refreshWalletInformation()
- Atomically update balance and transactions together after fetching
- Replace onAppear + manual task cancellation with SwiftUI .task modifier
- Simplify refresh flow to use proper async/await without explicit task management

This ensures the wallet view completes data loading in a single atomic
operation, preventing intermediate loading states from persisting.

Closes: https://github.com/damus-io/damus/issues/2999
Changelog-Fixed: Wallet view no longer hangs on loading placeholder
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-01-28 19:01:05 -08:00
Daniel D’Aquino fa4b7a7518 Wait for app to load the relay list and connect before loading universe view
This commit addresses a race condition that happened when the user
initializes the app on the universe view, where the loading function
would run before the relay list was fully loaded and connected, causing
the loading function to connect to an empty relay list.

The issue was fixed by introducing a call that allows callers to wait
for the app to connect to the network

Changelog-Fixed: Fixed issue where the app would occasionally launch an empty universe view
Closes: https://github.com/damus-io/damus/issues/3528
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2026-01-28 16:58:30 -08:00