Commit Graph
44 Commits
Author SHA1 Message Date
b105dadd14 longform: fix note URLs not opening from nevent references
Previously, clicking nevent links pointing to longform notes (kind 30023)
showed "Can't display note" error because .longform was listed as an
unsupported kind in LoadableNostrEventView. This fix adds .longform to
the supported kinds alongside .text and .highlight, routing them to
ThreadModel for proper display.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Closes: https://github.com/damus-io/damus/pull/3487
Closes: https://github.com/damus-io/damus/issues/3003
Closes: https://github.com/damus-io/damus/issues/3485
Changelog-Fixed: Longform article links now open correctly when shared as nevent URLs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-07 17:12:28 -08:00
078042546b longform: fix opening midway instead of at top
The scroll_to_event function defaults to anchor: .bottom, which positions
the selected event at the bottom of the viewport. For longform notes,
this causes the article to open midway or at the bottom instead of the
top where the title is.

Changed the initial scroll anchor to .top only for longform articles
(kind 30023), preserving the existing .bottom behavior for regular notes
which keeps parent context visible in reply threads.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Closes: https://github.com/damus-io/damus/issues/2481
Closes: https://github.com/damus-io/damus/pull/3488
Changelog-Fixed: Longform articles now open at the top instead of midway through
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: alltheseas
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino 93834f8de2 longform: simplify redundant boolean conditions in LongformPreview blur logic
The conditions !blur_images || (!blur_images && X) simplify to just
!blur_images, and the else branch covers the blur_images case.

Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino 760d0a8126 longform: change focus mode to only hide chrome on scroll down, tap to restore
Previously scrolling up would restore the nav/tab bars. Now only tapping
restores chrome, giving a cleaner reading experience without accidental
restoration while scrolling.

Changelog-Changed: Changed focus mode to only hide navigation on scroll down
Signed-off-by: alltheseas
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino c934bc7653 longform: fix tab bar staying hidden when switching to non-longform event
Restore chrome (nav bar + tab bar) when user taps to select a different
event in thread view. Previously the tab bar could stay hidden because
updateChromeVisibility short-circuits when isLongformEvent is false.

Changelog-Fixed: Fixed tab bar staying hidden when switching from longform to non-longform event
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino 527b53a7c8 longform: add focus mode with auto-hide chrome
When reading longform articles, scrolling down hides the navigation bar and
tab bar for a distraction-free reading experience. Tap anywhere to restore
the chrome, or it automatically restores when leaving the view.

Closes: https://github.com/damus-io/damus/issues/3493
Changelog-Added: Added focus mode with auto-hide navigation for longform reading
Signed-off-by: alltheseas
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino ef262b3c22 longform: remove card styling from preview in full article view
When viewing the full article (not truncated), remove the card border and
background styling for a cleaner reading experience. Card styling is now
only shown in truncated preview mode (timeline, search results).

Changelog-Changed: Removed card styling from longform preview in full article view
Signed-off-by: alltheseas
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino 28a2c23a76 longform: add sepia mode and line height settings
Add settings for longform article reading experience:
- Sepia mode toggle for comfortable reading with warm tones
- Line height slider (1.2-2.0x) for adjustable text spacing
Both settings persist and apply to the full longform article view.

Closes: https://github.com/damus-io/damus/issues/3495
Changelog-Added: Added sepia mode and line height settings for longform articles
Signed-off-by: alltheseas
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino e8e2653316 longform: add estimated read time to longform preview
Display estimated reading time in minutes alongside word count for longform
articles. Uses standard 200 words per minute reading rate calculation.

Closes: https://github.com/damus-io/damus/issues/3492
Changelog-Added: Added estimated read time to longform preview
Signed-off-by: alltheseas
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino 0233f2ae48 longform: add reading progress bar
Display a thin purple progress bar at top of longform articles (kind 30023)
that tracks scroll position through the content. Uses top/bottom GeometryReader
trackers to measure content bounds and calculates progress linearly.

Closes: https://github.com/damus-io/damus/issues/3494
Changelog-Added: Added reading progress bar for longform articles
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino 767b318763 longform: fix stretched/cut-off images in longform notes
Pre-process markdown with ensureBlockLevelImages() to add paragraph breaks
around standalone images, forcing proper block-level parsing. Creates
KingfisherImageProvider for MarkdownUI to handle proper aspect ratio and
image caching.

Changelog-Fixed: Fixed stretched/cut-off images in longform notes
Closes: https://github.com/damus-io/damus/pull/3489
Closes: https://github.com/damus-io/damus/pull/3496
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-07 17:12:28 -08:00
4f401c6ce9 input: convert pasted npub/nprofile to mention with async profile fetch
When pasting an npub or nprofile into the post composer, automatically
convert it to a human-readable mention link. If the profile isn't
cached locally, fetch it from relays and update the mention display
name when it arrives.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Changelog-Added: Added automatic conversion of pasted npub/nprofile to human-readable mentions in post composer
Closes: https://github.com/damus-io/damus/issues/2289
Closes: https://github.com/damus-io/damus/pull/3473
Co-Authored-By: Claude Opus 4.5
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: alltheseas
Reviewed-by: William Casarin <jb55@jb55.com>
2026-01-07 17:12:28 -08:00
a4ad4960c4 input: preserve mention links when inserting text before them
Previously, inserting text right before a mention (@user) would remove
the link attribute, breaking the mention. This was because the
intersection check in shouldChangeTextIn would trigger and remove the
link for any edit that touched the link boundary.

Added a new condition to handle insertion at the left edge of a link
separately, similar to the existing handling for the right edge. This
allows users to type before a mention without breaking it.

Added UI test that creates a real mention via autocomplete selection,
then verifies text can be typed before it without corrupting the
mention. The test uses predicate-based waits for reliability and
properly marks the UserView as an accessibility element. Link attribute
preservation is verified in unit tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Changelog-Fixed: Fixed mentions unlinking when typing text before them
Closes: https://github.com/damus-io/damus/pull/3473
Closes: https://github.com/damus-io/damus/issues/3460
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: alltheseas <alltheseas@users.noreply.github.com>
Reviewed-by: William Casarin <jb55@jb55.com>
2026-01-07 17:12:28 -08:00
4941b502d5 input: fix cursor jumping to position 0 after typing first character
When composing a new note, the cursor would jump in front of the first
letter after typing it. This occurred because multiple SwiftUI view
updates (text change, placeholder removal, height change) could cause
the cursor position to be incorrectly restored.

The fix explicitly tracks the cursor position after each text change
by calling updateCursorPosition, ensuring the correct position is
always used regardless of view update timing.

Refactored textViewDidChange to use early return pattern for clarity.

Added UI test to guard against cursor position regressions in the
post composer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Changelog-Fixed: Fixed cursor jumping behind first letter when typing a new note
Closes: https://github.com/damus-io/damus/pull/3473
Closes: https://github.com/damus-io/damus/issues/3461
Co-Authored-By: Claude Opus 4.5
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: alltheseas
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-07 17:12:28 -08:00
alltheseasandDaniel D’Aquino f506f9cfe8 docs: update AGENTS.md - dont block main thread
updated AGENTS.md with don't cause freezes, hangs requirement

Closes: https://github.com/damus-io/damus/pull/3486
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-07 17:12:28 -08:00
alltheseasandWilliam Casarin cddee92f3a thread: trust own replies in threads
Changelog-Fixed: Fix issue where your own replies were sometimes not trusted
Closes: https://github.com/damus-io/damus/issues/3404
Closes: https://github.com/damus-io/damus/pull/3416
Signed-off-by: alltheseas
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-06 12:20:47 -08:00
alltheseasandWilliam Casarin 67e61417d9 search: sort search results by recency
Closes: https://github.com/damus-io/damus/issues/3407
Closes: https://github.com/damus-io/nostrdb/pull/102
Changelog-Fixed: Fix issue where search results were out of order
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
2026-01-06 12:20:47 -08:00
be7a23bea8 filter: option to mute posts with too many hashtags
Posts with more than the configured number of hashtags (default: 3) are
now automatically filtered from timelines. This helps reduce hashtag spam.

- Add hide_hashtag_spam and max_hashtags settings to UserSettingsStore
- Add hashtag_spam_filter that counts hashtags in content text
- Add toggle and slider UI in Appearance > Content filters settings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Changelog-Added: Added hashtag spam filter setting to hide posts with too many hashtags
Closes: https://github.com/damus-io/damus/pull/3425
Closes: https://github.com/damus-io/damus/issues/1677
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: William Casarin <jb55@jb55.com>
Signed-off-by: alltheseas
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-06 12:20:47 -08:00
alltheseasandWilliam Casarin f7fcb2cb91 test: add regression tests for repost notification bug
Adds comprehensive tests to prevent regression of issue #3165 where
repost notifications were incorrectly blocked by home feed deduplication.

Tests cover:
- Regression test: notifications not blocked by home dedup (main fix)
- Home feed deduplication still works correctly
- Dedup tracks inner event ID, not repost event ID
- Context isolation (.other context doesn't affect dedup)

Each test documents the expected behavior and provides clear failure
messages to aid debugging if the bug reoccurs.

Signed-off-by: alltheseas
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-06 12:20:38 -08:00
alltheseasandWilliam Casarin d27d4e65cb fix: move repost dedup inside home context to fix notifications
The repost deduplication logic was incorrectly placed before the context
switch in handle_text_event(), causing notification events to be filtered
out when the same note had already been reposted in the home feed.

This fix moves the dedup logic inside the .home case where it belongs.
Notifications should always show reposts of YOUR posts, even if the same
note was already reposted by someone else in your home feed.

Root cause: commit bed4e00 added home feed dedup but placed the logic
before the context switch, affecting all contexts instead of just home.

Note on nostrdb: This bug is purely in application routing logic and
does not require database-level changes. The existing nostrdb TODO
(about inner event validation) is unrelated to this notification issue.

Changelog-Fixed: Fixed repost notifications not appearing in notifications tab
Closes: #3165
Closes: https://github.com/damus-io/damus/pull/3448
Signed-off-by: alltheseas
Signed-off-by: William Casarin <jb55@jb55.com>
2026-01-06 12:20:04 -08:00
alltheseasandGitHub 0cbeaf8ea8 Update AGENTS.md
- add nesting rules
- add nostrdb consideration
- change code commentary to docstring coverage requirement
2025-12-29 12:41:56 -08:00
alltheseasandDaniel D’Aquino 6d9107f662 Persist mute list across cold start
Closes: https://github.com/damus-io/damus/issues/3389
Changelog-Fixed: Added more guards to prevent accidental overrides of the user's mutelist
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
Co-authored-by: Daniel D’Aquino <daniel@daquino.me>
2025-12-22 17:19:50 -08:00
a0cecdc8ad Fix missing profile names and pictures due to stream timing
When a view subscribes to profile updates via streamProfile() or
streamProfiles(), the stream now immediately yields any existing
profile data from NostrDB before waiting for network updates.

Previously, subscribers had to wait up to ~1 second for the
subscriptionSwitcherTask to restart the profile listener before
receiving any data. During this window, views would display
abbreviated pubkeys (e.g., "npub1abc...") or robohash placeholders
instead of the cached profile name and picture.

The fix adds a simple NDB lookup when creating the stream. This has
negligible performance impact since:
- It's a one-time operation per subscription (not per update)
- The same lookup was already happening in view bodies anyway
- NDB lookups are fast local queries

A new `yieldCached` parameter (default: true) allows callers to opt
out of the initial cached emission. NoteContentView uses this to
avoid redundant artifact re-renders — it only needs network updates
since its initial render already uses cached profile data.

Furthermore, when a profile has no metadata, the display name now shows
"npub1yrse...q9ye" instead of "1yrsedhw:8q0pq9ye" for a better UX.

Closes: https://github.com/damus-io/damus/issues/3454
Closes: https://github.com/damus-io/damus/issues/3455
Changelog-Changed: Changed abbreviated pubkey format to npub1...xyz for better readability
Changelog-Fixed: Fixed instances where a profile would not display profile name and picture for a few seconds
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
Co-authored-by: Daniel D’Aquino <daniel@daquino.me>
2025-12-19 17:21:49 -08:00
alltheseasandDaniel D’Aquino 5058fb33d7 Restore translated note rendering
Changelog-Fixed: Fixed broken automatic translations
Closes: https://github.com/damus-io/damus/issues/3406
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
2025-12-15 18:15:34 -08:00
alltheseasandWilliam Casarin d3a54458f5 search: highlight terms in note search results
Changelog-Changed: Highlight note search results
Signed-off-by: alltheseas
2025-12-10 18:29:31 -08:00
alltheseasandGitHub 674d4683c3 Fix blank notifications on app startup
The notifications stream used streamIndefinitely(), discarding EOSE signals. This caused a race condition where:

1. NotificationsView.onAppear fires and calls flush().
2. flush() finds an empty queue (events haven’t arrived yet).
3. Events arrive and queue up in incoming_events.
4. No second flush happens, so notifications stay blank.

Fix: Switch to advancedStream() and handle .ndbEose to flush queued notifications once the local database finishes loading. This mirrors how the Home timeline handles initial data loading.

The ndbEose handler also disables queuing (set_should_queue(false)), so any events arriving after the initial load display immediately.

When the Notifications tab becomes visible, disable queuing so any events arriving afterward insert immediately into the displayed list.

This defensive measure complements the ndbEose flush in HomeModel. Together, they provide belt-and-suspenders protection:

1. ndbEose flush (primary): Triggers when local DB finishes loading, flushing queued events and disabling queuing.
2. onAppear disable (safety net): If the user navigates to notifications before ndbEose fires, this ensures new events aren’t queued forever.

Whichever fires first wins - both set should_queue=false, and the second call is a harmless no-op.

Closes: https://github.com/damus-io/damus/issues/3399
Changelog-Fixed: Fixed an issue where notifications view would occasionally appear blank when the app started.
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
2025-12-10 15:26:18 -08:00
5066a39ffb Fix jumpy cursor bug
This fixes jumpy cursor bug by clamping cursor restoration and consuming tag diff only once.

Closes: https://github.com/damus-io/damus/issues/747
Changelog-Fixed: Fixed incorrect behaviour on the post editor that would cause the text cursor to occasionally jump beyond the correct location in some editing operations.
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
Co-authored-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-12-08 16:32:38 -08:00
alltheseasandGitHub 498af9bc3a Hide empty chat action bar overlays
Changelog-Fixed: Fixed an issue where an empty dot would appear on some thread chat views
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
Closes: https://github.com/damus-io/damus/issues/3368
2025-12-05 18:35:55 -08:00
alltheseasandGitHub 066b5ff379 Fix mention profile fetch for mention_index blocks
Closes: https://github.com/damus-io/damus/issues/3344
Changelog-Fixed: Ensure mention profile prefetch covers mention_index blocks
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
2025-12-03 10:56:13 -08:00
alltheseasandDaniel D’Aquino 7eafe973d9 Ensure mention profiles render with display names
Co-authored-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/3331
Changelog-Fixed: Fix mention pills falling back to @npub text when profile metadata is missing
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
2025-11-26 11:05:42 -08:00
alltheseasandGitHub d651084465 Add AGENTS.md
Changelog-None
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
2025-11-21 12:48:41 -08:00
alltheseas 6605c5e583 Removes notifications from muted npubs 2025-10-15 00:03:20 -05:00
alltheseasandGitHub 3a2ce04d6b Update EventMenu.swift
replaced deprecated noteID with neventID in EventMenu.swift. NoteID currently appears in bubble/context menu of each note (top right three dots ellipsis).
2025-02-21 08:45:55 -06:00
alltheseasandGitHub fa70c376b1 Update README.md
Added NIP-70 to NIP list
2024-07-10 01:02:46 +03:00
alltheseasandWilliam Casarin c99aaea598 Add working email hyperlink
Closes: https://github.com/damus-io/damus/issues/2260
Closes: https://github.com/damus-io/damus/prs/2272
Changelog-Changed: Added first aid contact damus support email
Signed-off-by: elsat <npub1zafcms4xya5ap9zr7xxr0jlrtrattwlesytn2s42030lzu0dwlzqpd26k5>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-17 15:38:05 -07:00
alltheseasandGitHub b733799567 Update issue templates
Added feature request template
2024-03-25 10:12:13 -05:00
alltheseasandGitHub db8dfc5edc Update issue templates
Modified issue bug report template.
2024-03-25 10:08:51 -05:00
alltheseasandGitHub 4413ec0ec5 Update README.md
added reference to nip-04 encrypted DM support, including link to nostr-protocol nip-04 page
2024-03-13 10:06:01 -05:00
alltheseasandGitHub b5f31ef714 Update README.md
added how Damus and nostr win
2024-02-06 10:06:07 -06:00
alltheseasandGitHub 907a49813f Update README.md
added funding disclosure
2024-02-06 09:57:36 -06:00
alltheseasandGitHub eb383c6bf0 Update README.md
grammar, typos
2024-02-06 09:54:36 -06:00
alltheseasandGitHub e72e7b7196 Update README.md
-added purple
-added DM privacy warning
-updated NIPs
-added comparison vs twitter
2024-02-06 09:53:08 -06:00
alltheseasandWilliam Casarin 75a9b4df7f menu: move mute thread further away from bookmark
Closes: https://github.com/damus-io/damus/pull/1886
Closes: https://github.com/damus-io/damus/pull/1878
Changelog-Changed: Move mute thread in menu so it's not clicked by accident
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-16 21:04:51 -08:00
95f1127b74 Readme.MD: add privacy section, and link to issues
Added:
1. Damus implications on user privacy (IP address)
2. Added direct link to Damus github issues for interested contributors
3. Added statement of relation between IP address and public key

Co-authored-by: Max Hillebrand <30683012+MaxHillebrand@users.noreply.github.com>
2023-04-25 08:57:45 -07:00