Compare commits

...

930 Commits

Author SHA1 Message Date
0b288c921e Reduce default zap amount and deduplicate from preset zap amount items
Changelog-Changed: Reduced default zap amount and deduplicated from preset zap amount items
Closes: https://github.com/damus-io/damus/issues/3198
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-08-23 20:59:23 -04:00
f73c0ec1c4 Add support for scanning nprofile QR codes
Changelog-Added: Added support for scanning nprofile QR codes

Closes: https://github.com/damus-io/damus/issues/2671
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-08-18 19:10:51 -07:00
Daniel D’Aquino
05b62c5860 Fix edge case around bolt11 invoice parsing
Changelog-None
Closes: https://github.com/damus-io/damus/issues/3190
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-13 12:54:46 -07:00
Daniel D’Aquino
fae061cec0 Fix MAX_PREFIX parameter on bolt11 parsing logic
Closes: https://github.com/damus-io/damus/issues/3187
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
4570ba797c Verify events at RelayConnection
This commit introduces a verification step at the relay connection
level, to help ensure notes get validated at the source and prevent
security issues associated with untrusted relays.

`RelayConnection.swift` — the source that initially handles WebSocket
messages — was analyzed, and measures were put in place to prevent
(or at least minimize) unverified nostr event data being spread
throughout the app.

The following measures were taken:
1. A note verification step was added prior to the `self.handleEvent(.nostr_event(ev))` call (which sends a Nostr response to the rest of the app for logical handling).
    a. From code analysis, there is only one such call in `RelayConnection.swift`.
2. `NostrConnectionEvent`, the object that gets passed to event handlers, had its interface modified to remove the "message" case, since:
    a. that could be a source of unverified nostr events.
    b. it is redundant an unneeded due to the `.nostr_event` case.
    c. there were no usages of it around the codebase
3. The raw websocket event handler had its label renamed to "handleUnverifiedWSEvent", to make it clear to the caller about the verification status of the data.
    a. Usages of this were inspected and no significant risk was detected.
4. A new `verify` method in NdbNote was created to verify Nostr notes, and unit tests were added to confirm tampering detections around all the major fields in a Nostr note.
5. Care was taken to ensure the performance regression is as little as
   possible.

It is worth noting that we will not need this once the local relay model
architecture is introduced, since that architecture ensures note
validation before it reaches the rest of the application and the user.

In other words, this is a temporary fix.

However, since the migration to that new architecture is a major
undertaking that will take some time to be completed, this fix was written
in order to address security concerns while the migration is unfinished.

This fix was written in a way that attempts to be as effective as
possible in reducing security risks without a risky and lenghty
refactor of the code that would delay the fix from being published.

Changelog-Fixed: Improved security around note validation
Closes: https://github.com/damus-io/damus/issues/1341
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
d1ea081018 Fix regressions in note content rendering logic
Changelog-None
Closes: https://github.com/damus-io/damus/issues/3150
Closes: https://github.com/damus-io/damus/issues/3158
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
682704b2cb Fix quoted note regression
This fixes a regression that caused quoted notes not to appear.

Changelog-None
Closes: https://github.com/damus-io/damus/issues/3163
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
176f1a338a Fix app swap crash
This commit fixes a crash that occurred when swapping between Damus and
other apps.

When Damus enters background mode, NostrDB is closed and its resources
released. When Damus re-enters foreground mode, NostrDB is reopened.

However, an issue with the transaction inheritance logic
caused a race condition where a side menu profile lookup would get an
obsolete transaction containing pointers that have been freedwhen
NostrDB was closed, causing a "use-after-free" memory error.

The issue was fixed by improving the transaction inheritance logic to
double-check if the "generation" counter (which auto increments when
Damus closes and re-opens) matches the generation marked on the
thread-specific transaction. This effectively prevents lookups from
inheriting an obsolete transaction from a previous NostrDB generation.

Closes: https://github.com/damus-io/damus/issues/3167
Changelog-Fixed: Fixed an issue where the app would crash when swapping between apps
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
fc1eb326e8 Render profile bios
Note: This brings us closer to feature parity with the master branch, so there
is no changelog item to be added

Closes: https://github.com/damus-io/damus/issues/3156
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
5e420187e0 Fix highlight comment rendering
Closes: https://github.com/damus-io/damus/issues/3129
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
4815c8a6f7 Fix nprofile parsing failure
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
f42ae0673d Reword subscript out-of-bounds assertion
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
474e2d8d57 Disable bai kanji test
To be fixed on https://github.com/damus-io/damus/issues/3154

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
95a91bed7e Disable invoice block parsing tests
It was decided on a standup meeting that this feature is not important
and failing tests can be disabled.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
ff12d8bd7e Prevent crash from ndb search test
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
f8245a7b0e Update Invoice tests to use the new blocks interface, and fix reverse blocks iteration indexing
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
4036995348 Remove deprecated nrelay uses from tests
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
5b6534fd56 Fix stack corruption in bech32 parsing
This commit fixes a stack corruption issue caused by
an off-by-one error in one of the functions responsible
for parsing bech32 entities.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
bdd10cccaa Do not show images twice
This commit fixes a logical error in the blocks rendering function.

Changelog-None
Closes: https://github.com/damus-io/damus/issues/3133
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
e9f4cbe881 Make NdbBlock ~Copyable for better lifetime safety
Changelog-None
Closes: https://github.com/damus-io/damus/issues/3127
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
91abd187d3 Improve lifetime handling in collectBlocks
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
b9d8b1dbf3 Fix blocks_size calculation
Previously two addresses from different memory regions were being
subtracted, which will lead to the incorrect number. This commit
improves the calculation.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
12a7b483a0 Fix incorrect buffer size argument in block parsing
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
caa7802bce Fix broken DM rendering
Currently NostrDB does not seem to handle encryption/decryption of DMs.
Since NostrDB now controls the block parsing process and fetches note
contents directly from the database, we have to add a specific condition
that injects decrypted content directly to the ndb content parser.

This is done in conjunction with some minor refactoring to `NdbBlocks`
and associated structs, as in C those are separated between the content
string and the offsets for each block, but in Swift this is more
ergonomically represented as a standalone/self-containing object.

No changelog entry is added because the previously broken version was
never released to the public, and therefore this fix produces no
user-facing changes compared to the last released version.

Changelog-None
Closes: https://github.com/damus-io/damus/issues/3106
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
9c47d2e0bd Temporarily disable broken tests
Some tests have been broken at some point during the nostrdb migration.
Disable them for now and address them later
(https://github.com/damus-io/damus/issues/3112)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
5cd5a249ce Add justfile
This makes it easier to work from the command line when needed

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
c86b3a999d Enable address sanitizer for debug configuration
NostrDB relies on manual memory management, so it is a good idea to
enable the address sanitizer on debug configurations, as it helps find
memory-related issues on the app, which will allow us to identify memory
issues and potential crashes earlier in the development process.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
b5afa3c0b4 Wait for note in NostrDB before rendering it
Closes: https://github.com/damus-io/damus/issues/2885
Changelog-Changed: Use NostrDB for rendering note contents
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
8f32c81b6c Create NostrDB streaming and async lookup interfaces
This commit introduces new interfaces for working with NostrDB from
Swift, including `NostrFilter` conversion, subscription streaming via
AsyncStreams and lookup/wait functions.

No user-facing changes.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
William Casarin
f8185d0ca5 fixes
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
eb99584501 project: remove some references
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
919f644cba add assert to catch potential bug
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
690e1347e0 test: fix broken tests
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
744bf4bb07 ndb: add subscription callback initializers
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
475940aa01 Fix relay compile issue
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
28a06af534 Switch over to use use blocks from nostrdb
This is still kind of broken until queries are switched over to nostrdb.
Will do this next

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
208b3331ca optimized id matching function
doesn't need to create a copy of the id

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
5b1f0c4714 c: remove some unused files from project
some binding dir stoppers, and configurator
2025-08-11 16:40:01 -07:00
William Casarin
249e765642 c: re-add damus-only C stuff 2025-08-11 16:40:01 -07:00
William Casarin
712624f515 nostrdb: fix iOS crash on latest version
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
6e7b3b94d7 nostrdb: cleanup previous patch
I wanted to not amend this since we've already applied
it in the nostrdb-update branch on damus and I don't want
to conflict

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
Daniel D’Aquino
969a2b656e nostrdb: Fix heap buffer overflow
The Address Sanitizer detected a heap buffer overflow during a memcpy operation
in nostrdb.c associated with note parsing.

It was found that not enough memory was being allocated to the buffer to
support all the content parsing.

Allocation size was increased to support the memory needed for the
parsing operations. However, the new number was not carefully calculated
as we will not run into this code path once we switch to the local relay
model.

Changelog-Fixed: Fixed memory error in nostrdb
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-08-11 16:40:01 -07:00
William Casarin
d8e7b4707e nostrdb: nip19: add kind to naddr & nevent
Add support for type KIND for bech32-encoded entities naddr and nevent
as specified in NIP-19.

Co-authored-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
a51618cfd3 nostrdb: print-search-keys: add size of key information
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
82da5da4d3 nostrdb: fix compile issues on macOS
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
37f9c93705 nostrdb: Implement nip50 fulltext searching
This adds support for nip50 fulltext searches. This allows you to use
the nostrdb query interface for executing fulltext searches instead of
the typical `ndb_text_search` api. The benefits of this include a
standardized query interface that also further filters on other fields
in the filter.

Changelog-Added: Add nip50 search filters and queries
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
094cf5e8cc nostrdb: nip50: add filter argument to fulltext search
Update fulltext search queries to include an optional filter. This can
be used to narrow down the fulltext search. This is another step towards
nip50 support in nostrdb.

I noticed the code was exiting dubiously in certain situations... so we
fix that as well. It's possible we were missing search results because
of this.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
46541694a0 nostrdb: search: sort search terms from largest to smallest
Add a helper for sorting search words from largest to smallest. This
should help search performance. For example, let's say our search index
is like so:

"the pokemon is cool"

the
the
the
...
* 1000

Our root word search would have to start 1000 new recursive queries. By
sorting by the largest word:

pokemon
pokemon
pokemon
...
* 10

We only have to do 10 recursive searches, assuming larger words are less
common, which will likely be the case most of the time

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
04d4ff4e99 nostrdb: refactor: a few small formatting changes
No functional changes, just formatting cleanups

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
2d02766461 nostrdb: filter: add ndb_filter_find_search helper
This can be used to quicky pull the search string
from a filter

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
1e6873c879 nostrdb: nip50: add support for search field in filters
We will be using this for our nip50 search support

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
d3496af5cc nostrdb: filter: fix ndb_filter_init_with and make public
This fixes an allocation issue with ndb_filter_init_with for small
page sizes. instead of allocating the buffer around pages, we allocate
based on total buffer size.

Fixes: f7aac3215575 ("filter: introduce ndb_filter_init_with")
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
ec798bdeb2 nostrdb: debug: fix debug logs
We forgot to move one DEBUG instance to NDB_LOG

Fixes: b4c2ff3d270a ("Only log to stdout if NDB_LOG is defined")
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
fa9b952295 nostrdb: add is_replaceable_kind helper
we will be using this to detect replaceable kinds

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
27f55bc09f nostrdb: refactor: use kind variable for clarity
almost no reason to do this, but whatever

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
52845a52bb nostrdb: remove ndb_writer_queue_note (dead code)
This doesn't seem to be used at all

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
4e27cca12b nostrdb: filter: introduce ndb_filter_init_with
Just a static function for now for creating smaller filter sizes. We
will use this for filters that we know are small so that we don't have
to allocate so many pages at once. It's likely the OS will only allocate
a single page anyways, but its nice to be explicit.

Changelog-Added: Add ndb_filter_init_with
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
franzap
98e9ba25da nostrdb: bug: use indices[i] as index is not defined
Closes: https://github.com/damus-io/nostrdb/pull/66
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
Ken Sedgwick
e6cb6c938b nostrdb: Only log to stdout if NDB_LOG is defined
Closes: https://github.com/damus-io/nostrdb/pull/64
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:01 -07:00
William Casarin
af5961ce26 nostrdb: query: add missing since check to kind query
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
58de0025aa nostrdb: monitor: lock monitor when we're freeing subscriptions
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
c931108741 nostrdb: subs: fix memory leak in ndb_subscribe
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
20255198fd nostrdb: bug: add missing break statement
probably harmless but it writes the note twice...

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
289a8e262a nostrdb: migrations: make migrations asyncronous
This also seems to fix some issues with older migrations.

Fixes: https://github.com/damus-io/nostrdb/issues/58
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
05baba9c03 nostrdb: flags: make some indexes optional
Make fulltext indices and note blocks optional. This will be useful for
quickly building databases when testing, since more stuff in the write
queue when writing can slow things down.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
e0461d3458 nostrdb: writer: rename any_note to needs_commit
This is a bit more clear as to what this variable actually means

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
62aa72c215 nostrdb: leak: fix memory leak when failing to write like stats
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
287b35a8fb nostrdb: migration: dont fail v3 -> v4 on 0 migrations
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
478d7b4060 nostrdb: add authors query plan
This fixes author queries

Fixes: https://github.com/damus-io/nostrdb/issues/52
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
2c4728508b nostrdb: earlier since check in ndb_query_plan_execute_created_at
this avoids a lookup if we dont need it

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
d24a3f0ce5 nostrdb: simplify ndb_query_plan_execute_ids
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
efba599779 nostrdb: ids: fix typo in ndb_query_plan_execute_ids
We should be specifying that we've matched the id here, not authors. Not
that this would have any effect.. but still.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
19243d49e1 nostrdb: always show migration text
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
6845d0df47 nostrdb: migrate notes to have pubkey indices
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
8e79ad582a nostrdb: add note pubkey and pubkey_kind indices
We need these for profile queries

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
282c02eed4 nostrdb: add ndb_db_is_index
This function can be used to check if a db is an index or not. We
will use this in future functions that rebuild indices.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
155ac27bb5 nostrdb: introduce ndb_id_u64_ts
This will be the key used by our note_profile_kind indee

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
be1d149f4b nostrdb: misc: move some functions around
because this will make the changes nicer

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
9e0dc47e98 nostrdb: rename: ndb_u64_tsid to ndb_u64_ts
technically more accurate. we are about to introduce a new type called:

	ndb_ts_u64_id

which would be confusing if we didn't do this

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
0916b14b32 nostrdb: make the subscription monitor threadsafe
This was the only thing that wasn't threadsafe. Add a simple mutex
instead of a queue so that polling is quick.

This also means we can't really return the internal subscriptions
anymore, so we remove that for now until we have a safer
interface.

Fixes: https://github.com/damus-io/nostrdb/issues/55
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
6818d001f2 nostrdb: mem: reduce default queue size
This was overkill and was using lots of memory

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
4bf9160502 nostrdb: fix heap corruption on windows
windows thinks this is heap corruption... so I
guess we have to trust it.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
02df1e209b nostrdb: windows: fix threading bugs
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
3186b0e1d3 nostrdb: fix windows build
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
de0935582c nostrdb: ndb_filter_{eq,is_subset_of}: make interfaces const
this makes rust happier

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
573de6b881 nostrdb: ndb_filter_is_subset_of
subset testing for filters. Can be used to see if one subset is
redundant in the presence of a another in the local relay model

Changelog-Added: Add ndb_filter_is_subset_of
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
44ab702792 nostrdb: add ndb_filter_eq
filter equality testing. this works because field elements are sorted

Changelog-Added: Add ndb_filter_eq for filter equality testing
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
1fdf234c46 nostrdb: rename get_elems to find_elements
This is more accurate

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
3018200e95 nostrdb: add ndb_subscription_filters
Expose a way to get the set of filters for a subscription. On the rust
side, we should likely ndb_filter_clone each filter asap, because the
result of this function will only be valid up until the subscription
ends.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
47b79fc02e nostrdb: ingest: support kind 6 reposts
This also enables processing raw json via ndb import

Fixes: https://github.com/damus-io/nostrdb/issues/46
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
0c483bb55a nostrdb: print search keys to stdout
otherwise it's way too annoying to grep

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
ddd30054e8 nostrdb: nostrdb: fix ndb_builder_find_str.
This will find strings which match the beginning of other strings,
which seems wrong.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
30c5225ed0 nostrdb: content_parser: fix incorrect comment.
Sure, this format would be nice, but it's not what the code does.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
8c446f804c nostrdb: filter: retain const variant of get_int_elemnet
otherwise rust gets bitchy at as

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
e92018aee5 nostrdb: filter: allow mutable int elements
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
cfb140472d nostrdb: bolt11: remove unneeded fields.
If we make unknown_field simply discard, we can remove decoders and
have them discard those fields.

Now we can cut down struct bolt11 to only the fields needed by
invoice.c, and also speed up parsing a little.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
2f5fd54297 nostrdb: bolt11: update to latest version from CLN
Copy the latest, which has parsing fixes.  We make a new explicit
"bolt11_decode_minimal" which doesn't check sigs, rather than neutering
the bolt11_decode logic.

As a bonus, this now correctly parses "LIGHTNING:BECH32..." format
(upper case, with prefix).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
02e970eb9b nostrdb: Makefile: fix missing dependencies on bolt11 headers.
I wondered by `make check` was giving strange errors, until I realized it wasn't fully rebuilding.

Also, remove leftover CCAN files I missed previously.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
b4b84e6895 nostrdb: resync with repo
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
7831ede057 nostrdb: ccan: update to latest.
Only change for us: CCAN_TAL_NEVER_RETURN_NULL can be defined if
we don't override tal error handling.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
a8d7d971b1 nostrdb: ccan: sync with normal versions.
This is the version of CCAN which CLN was using at the time these
were taken.  Unfortunately lots of whitespace has been changed,
but AFAICT no source changes.

Here's the command I ran (with ../ccan checked out to 1ae4c432):

```
make update-ccan CCAN_NEW="alignof array_size build_assert check_type container_of cppmagic likely list mem short_types str structeq take tal tal/str typesafe_cb utf8 endian crypto/sha256"
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
201cdd7edc nostrdb: Makefile: build using ccan/ versions of files.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
e3ca6ca5b4 nostrdb: bolt11: move utf8_check into local function.
It isn't actually in the CCAN module (though it probably should be!).
So it breaks when we update.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
494386d211 nostrdb: ccan: copy ccan files into their own subdirectory.
This lets them be updated/bugfixed together.  I just copied them for now,
didn't change anything else.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
6c53bc75f2 nostrdb: content_parser: fix blocks_size
we are crossing cursors

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
6001063754 nostrdb: nostrdb: fix ndb_builder_find_str.
This will find strings which match the beginning of other strings,
which seems wrong.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
eb0a1ee807 nostrdb: content_parser: fix incorrect comment.
Sure, this format would be nice, but it's not what the code does.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
827731b9cb nostrdb: filter: retain const variant of get_int_elemnet
otherwise rust gets bitchy at as

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
56d44d0004 nostrdb: filter: allow mutable int elements
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
7742c8fb3c nostrdb: bolt11: remove unneeded fields.
If we make unknown_field simply discard, we can remove decoders and
have them discard those fields.

Now we can cut down struct bolt11 to only the fields needed by
invoice.c, and also speed up parsing a little.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
7f2ee78512 nostrdb: bolt11: update to latest version from CLN
Copy the latest, which has parsing fixes.  We make a new explicit
"bolt11_decode_minimal" which doesn't check sigs, rather than neutering
the bolt11_decode logic.

As a bonus, this now correctly parses "LIGHTNING:BECH32..." format
(upper case, with prefix).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
4d75894bc4 nostrdb: Makefile: fix missing dependencies on bolt11 headers.
I wondered by `make check` was giving strange errors, until I realized it wasn't fully rebuilding.

Also, remove leftover CCAN files I missed previously.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
bbed448ccb nostrdb: ndb_filter_from_json
Changelog-Added: Add method for parsing filter json
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
3fb4d81d48 nostrdb: src: delete copies outside ccan/ dirs.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
fc30b68c40 nostrdb: Makefile: build using ccan/ versions of files.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Rusty Russell
0ac25b7aa3 nostrdb: bolt11: move utf8_check into local function.
It isn't actually in the CCAN module (though it probably should be!).
So it breaks when we update.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
b326f007f2 nostrdb: expose filter introspection methods
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
a86d8416fc nostrdb: expose ndb_filter_get_elements
This can be used to iterate though filter elements

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
b5c57dc935 nostrdb: make more things const
rust is happier this way

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
7d6814a481 nostrdb: add ndb_filter_json method
Changelog-Added: Add ndb_filter_json method for creating json filters
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
8dd048681b nostrdb: Fix issue where id tag filters are pushed as strings
When creating filters, sometimes IDs are pushed as strings, so if there
is ever a 0 byte, the id prematurely ends, causing the filter to not
match

Fixes: https://github.com/rust-nostr/nostr/issues/454
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
2d02a17af6 nostrdb: fix bech32 parsing and add test
was off by one

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
3171959d85 nostrdb: debug: improve tag index display
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
bca3716e33 nostrdb: fix note content parsing bug with damus.io urls
Changelog-Fixed: Fixed bug where non-bech32 damus io urls would cause corruption
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
57db252783 nostrdb: ndb_note_json: return length
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
319579f912 nostrdb: ndb: dump json in filters and fulltext queries
This is much more useful

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
92e1e4b08f nostrdb: api: add ndb_note_json
add a way to write an ndb note as json to a buffer

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
ffc50bb2c1 nostrdb: fix realloc corruption
can't figure out why this is happening, but let's disable it for now
while we test. we shouldn't hit this code path anyways once we switch
over to local notes in damus ios

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
a562be009d nostrdb: add ability to register a subscription callback
Since Damus iOS is not an immediate-mode UI like android, we would
rather not poll for results. Instead we need a way to register a
callback function that is called when we get new subscription results.

This is also useful on the android side, allowing us to request a new
frame to draw when we have new results, instead of drawing every second.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
30c9bc7db7 nostrdb: add ndb_unsubscribe
We didn't have a way to unsubscribe from subscriptions. Now we do!

Apps like notecrumbs may open up many local subscriptions based on
incoming requests. We may need to make the MAX_SUBSCRIPTIONS size much
larger, but this should be okish for now.

Changelog-Added: Add ndb_unsubscribe to unsubscribe from subscriptions
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
0ac03df841 nostrdb: build: fix compile warning
A small size_t/uint64 conversion issue

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
db99b4f4d4 nostrdb: fix dubious looking parens logic
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
cc9585b6e3 nostrdb: plan: use a less efficient plan for author query plans
This is less efficient for now but we don't have a small-author-list
query plan yet.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
bd17dcfac6 nostrdb: plan: add created_at query plan
This introduces the basic created_at query plan. We scan the created_at
+ id index in descending order looking for items that match a filter.
This is a very general query plan, but might not be very efficient for
anything other than local timelines.

Changelog-Added: Add general created_at query plan for timelines
Closes: https://github.com/damus-io/nostrdb/issues/26
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
25e91b386c nostrdb: cores: just set to 2 on unknown platforms
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
560e9e53cd nostrdb: fix a few note size compile issues
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
1c1e5fa2a0 nostrdb: random: add getrandom fallback for android
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
2d5f86b142 nostrdb: filter: make sure clone copies metadata
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
89686d758a nostrdb: filter: make sure to return clone errors
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
6c26add1da nostrdb: filter: add ndb_filter_clone
Clone filters when moving them into subscriptions. This will allow us to
fix the double free issue on the rust side.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
3c5a83392e nostrdb: filter: use relative data offsets for easy cloning
Instead of storing exact pointers inside of our filter elements, just
store offsets. This will allow us to clone filters very easily without
having to mess around with fixing up the pointers afterwards.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
1c63c3b9bb nostrdb: filter: add ndb_filter_end
This is a pretty scary looking function that realloc our large variable
filter buffer into a compact one. This saves up a bunch of memory when
we are done building the filter.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
0bd4717e01 nostrdb: query: include note size in query results
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
bebd531b58 nostrdb: return number of items popped when polling
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
5788c077c4 nostrdb: silence annoying debug
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
1b77b4f0e0 nostrdb: filters: copy filter metadata into subscription
This fixes a few ownership issues

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
62625c6ff3 nostrdb: ndb: add ndb_poll_for_notes
The polling variant of ndb_wait_for_notes. This makes more sense for
realtime apps like notedeck

Changelog-Added: Add ndb_poll_for_notes
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
c8d88058d4 nostrdb: queue: switch to prot_queue_try_pop_all
This allows you to `try pop` multiple items instead of 1

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
b8bef86ea1 nostrdb: port kernelkind's to the new bech32 parser
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
b128330b2a nostrdb: tce: fix build for previous TCE change
Fixes: 34093cd1 ("tce: add AUTH to-client-event")
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
934ea80f85 nostrdb: blocks: add word count interface
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
588cebd18d nostrdb: header: add ptr helpers for swift
swift is kind of dumb when it comes to opaque pointers

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
William Casarin
ccca6e58ec nostrdb: strblock: add typedef
I don't technically need this but it helps a lot on the swift side
of things since I already have code that uses this identifier of a
similar structure

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00
Charlie Fish
c1befa5221 nostrdb/tce: add AUTH to-client-event
This was committed to damus, but this should be in nostrdb or else we
will lose it when we update.

Damus: 84cfeb1604 ("nip42: add initial relay auth support")
Link: https://groups.google.com/a/damus.io/g/patches/c/Zx3dk01e0yg/m/t59TsVkXAQAJ
Signed-off-by: Charlie Fish <contact@charlie.fish>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
8b3c86c5de nostrdb/query: add tag index and tag queries
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
05c5a6dacb nostrdb/filter: don't end field if we don't have one active
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
1a6568deca nostrdb/perf: add some flamegraph helpers to makefile
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
1b2f4c41df nostrdb/fix macos build
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
25bcf9c243 nostrdb/ndb: measure query performance
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
3993679cc0 nostrdb/query: support until for kind query plans
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
e302bf37fa nostrdb/ndb: add inital query command
still very early, but works for kinds!

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
a45f4d3087 nostrdb/Query Plans
Instead of running queries off filters directly, we do some simple
heuristics and determine a reasonable query plan for the given filter.

To test this, also add a kind index query plan and add a test for it.

We still need tag, author, and created_at index scans. This is up next!

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
d598e178c1 nostrdb/index: make sure kind index is DUPSORT + INTEGERDUP
We will probably need a migration for this?

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
77601e77ee nostrdb/filter: rename FILTER_GENERIC to FILTER_TAG
it's a bit more intuitive

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
206efba58a nostrdb/cleanup: remove old dbscan stuff
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
a84749cd07 nostrdb/debug: add print_kind_keys helper
I needed this for debugging kind queries

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
shuoer86
099b588be2 nostrdb/Fix typos
Closes: https://github.com/damus-io/nostrdb/pull/25
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
75c7adddb8 nostrdb/query: implement kind queries
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
9f1b9ab945 nostrdb/Initial nostrdb queries
Still a lot more work to do, but this is at least a proof of concept for
querying nostrdb using filters.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
b2080a946e nostrdb/cursor: fix bug when pushing last element
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
942e47a720 nostrdb/query: extract ndb_cursor_start
This is useful for positioning LMDB cursors at the start of a query. We
will be re-using this in the upcoming query code

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
6dbf3416b9 nostrdb/cursor: remove old array code
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
2b14acd62f nostrdb/filter: don't allow adding id elements on kinds
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
267a9ac54b nostrdb/ocd: small cleanup
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
8b03ed6175 nostrdb/filters: remove ndb_filter_group from public API
We can just use a list of filters instead when subscribing

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
6cd7b945ca nostrdb/filter: use binary search for large contact list filters
This is much more efficient than linear scans

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:59 -07:00
William Casarin
e5e6735129 nostrdb/filter: sort filter elements
If they are sorted we can do binary search when matching filters like
how strfry does it.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
9c2f7a931c nostrdb/subs: always fail when calling wait_for_notes on a subid of 0
this is an invalid subscription id

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
b1bbf355de nostrdb/subs: notify on profile notes as well
We missed this in the original subscription code

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
d7a2064786 nostrdb/debug: add a few more debug statement
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
4d14ca8d0a nostrdb/filters: add ndb_filter_group_init function
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
81d65cd5bf nostrdb/subs: subs and monitor cleanup
We need to free these resources when we're done with them.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
f03d8a5ac9 nostrdb/search: don't enforce sequential tokens
This makes it a bit more flexible, but maybe we can add quoting in the
future that re-enables this. Or maybe a search option

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
0df18ae1a4 nostrdb/test: switch reaction test to use subscriptions
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
8c5ec32eaa nostrdb/Initial nostrdb relay subscriptions
This adds some initial code for the nostrdb relay subscription monitor.

When new notes are written to the database, they are checked against
active subscriptions. If any of the subscriptions are matched, the note
primary key is written to the inbox queue for that subscription.

We also add an ndb_wait_for_notes() method that simply waits for notes
to be written by the subscription monitor.

Changelog-Added: Added filter subscriptions
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
bdedf8bd8c nostrdb/disable lmdb download
since we have this committed now

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
c2383060aa nostrdb/blocks: add ndb_blocks_flags function
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
432cdb96d9 nostrdb/fix: don't write the owned flag to the DB
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
f580c7dd93 nostrdb/fix clang compile issue
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
c677233dcb nostrdb/blocks: expose block iterator internals
so we don't need heap allocation. we will be calling this a lot in tight
render loops, we don't want to be allocating on each frame.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
d063362bd7 nostrdb/blocks: write note blocks on ingest
When ingesting notes, parse text/longform contents and store them in nostrdb.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
088683696a nostrdb/blocks: actually set the note block version
Version 1 to start

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
f2795aa71c nostrdb/blocks: add ndb_blocks_free
In some situations we will need to have owned note blocks. For
example, when we try to fetch note blocks from the database and it's not
there yet. We will need to parse the content on the spot and return an
owned copy, since it will not be immediately available in the database.

Add a new flag field to note blocks that lets us know if it's owned by
malloc or nostrdb.

We the add a free function that checks this flag and frees the object if
its set. If it is not set then it doesn nothing because it likely came
from the database.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
c831976078 nostrdb/blocks: add total_size
Fix this mistake that we have with ndb_notes where we don't know the
total size of the object

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
c2c73c3af6 nostrdb/header: move bech32 around
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
971fa3e4ef nostrdb/invoice: fix crash in any-amount invoice parsing
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
dfa145dd4a nostrdb/parser: fix bech32 block decoding
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
4cfe28d802 nostrdb/bech32: fix big in bech32 size parsing
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
034f2cc02f nostrdb/blocks: add note block iterator
This adds an api that walks along and pulls compact note block data out of
nostrdb.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
kernelkind
6f9bd6c4f4 nostrdb/parser: handle period at end of url
Fix parsing URL when encountering a period at the end of the url by
setting it as disallowed from being present at the end of a
URL.

Some characters are disallowed to be present at the end of URLs.
Presently, the period character is the only disallowed character.
A character is the last character in the URL if it is followed by
is_whitespace() or if it's the last character in the string.

Signed-off-by: kernelkind <kernelkind@gmail.com>
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb5.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
d73422db38 nostrdb/content_parser: add initial db decoders
We need to pull the data out as well! Let's add some initial decoders.
We still need tests to make sure it's working.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
c3b06d281e nostrdb/bech32: add some initial tests
since we modified this recently, let's add some tests to make sure
we didn't break anything

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
1b09e9458c nostrdb/nostr_bech32: parse in one pass
since we will be decoding these in realtime, let's make sure we can
decode them in O(1)

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
e0a2dcf3db nostrdb/Inital embedded content parser
This adds some initial code for nostrdb content parsing.

We still need to write tests for encoding and decoding, so this is
likely not working yet.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
9ff1f69a82 nostrdb/search: switch to cursor_align function
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
623b8603c2 nostrdb/cursor: add align function
handy function for padding buffers to some byte alignment

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
d8b083010d nostrdb/cursor: fix some warnings
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
887eb4e1e2 nostrdb/cursor: fix empty string pushing in push_c_str
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
b5ad3ed1a5 nostrdb/cursor: add pull_varint_u32
This is a varint helper that doesn't pull larger than uint32

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
371e9fb406 nostrdb/cursor: add malloc_slice
This is the same as cursor_slice except we don't memset afterwards

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
aa5809d792 nostrdb/nostr_bech32: only parse up to raw bech32 buffers
We will be storing raw nostr bech32 buffers directly into nostrdb, so
adapt our bech32 code to reflect this.

When doing our content parsing pass, we will only look for strings and we
won't allocate any intermediate buffers. Only when we write this string
block to nostrdb will we actually allocate in our nostrdb output buffer
(no mallocs!)

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
30ba0d72cc nostrdb/bech32: retab
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
373cd71f69 nostrdb/block: add bolt11 invoice encoding/decoding
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
acaf327a07 nostrdb/make: cleanup a bit, separate bench running
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
9f0bf7dff5 nostrdb/fix github action
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
88d7eb8a86 nostrdb/fix build
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
76862776b8 nostrdb/varint: switch to 64 bit varints
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
4c55459c1f nostrdb/test: disable migrate for now
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
f7cdc7bc31 nostrdb/cursor: re-apply infinite loop bug fix
since I keep overwriting it by accident

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
1bc4971111 nostrdb/add libnostrdb.a
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
6ce6c79160 nostrdb/add initial content parser
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
1ffbd80c67 nostrdb: move everything to src
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
1fb88a912a nostrdb: port everything over to be in as sync as possible
for now
2025-08-11 16:39:43 -07:00
William Casarin
954f48b23d c: move c files into nostrdb in prep for switchover 2025-08-11 16:39:43 -07:00
William Casarin
cc75a8450a nostrdb: add supporting files for the bolt11 parser
A lot of this was pulled from core-lightning. Not sure what is actually
needed or not.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:43 -07:00
William Casarin
389c2c9695 nostrdb: add supporting files before the move commit 2025-08-11 16:39:42 -07:00
William Casarin
4a6121ba13 c: move compiler to nostrdb dir
we will be applying a patch here as well
2025-08-11 16:39:42 -07:00
William Casarin
a469f2e127 nostrdb/re-apply ispunct crash fix
since it was overwritten when we synced with damus

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
William Casarin
2f8f18b846 nostrdb/build: fix constness on config pointer in ingester thread
otherwise build fails

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
William Casarin
3a7cf4d08d nostrdb/rust: initial api for Ndb and NdbConfig
This is the start of our rust library for nostrdb. Implement idiomatic
interfaces for Ndb and NdbConfig.

Changelog-Added: Add initial rust library
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
William Casarin
e3001cc240 nostrdb/cursor: fix warning that build.rs is complaining about
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
William Casarin
d1ef113a8b nostrdb/api: don't expose many internals, like note
rust doesn't like packed structures, so hide this from bindgen

This also buttons up the API so less things are exposed which is good.

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
William Casarin
f187f4f8f2 c: move cursor.h to nostrdb subdir
everything will be in here soon
2025-08-11 16:39:42 -07:00
William Casarin
4e9583ef54 nostrdb/stream: actually use file pointer in stream api
Right now it's accidently hardcoded.

Fixes: 8376e5bca05c ("add "import -"")
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
Yasuhiro Matsumoto
cc95d5df6e nostrdb/add "import -"
Closes: https://github.com/damus-io/nostrdb/pull/21
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
William Casarin
4ca156fd83 nostrdb/build: fix additional compiler errors
When trying to build from rust

Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:39:42 -07:00
askeew
9f6da8eb79 Fix display issues with pasted or uploaded images
- Fix aspect ratio, use fit
- Remove fixed height on image frame to align close button on image
- Use overlay instead of ZStack to reduce complexity
- Add background to close button to get better contrast in light mode
- Change close-image to be a button for better accessibility

Changelog-Fixed: Fix aspect ratio on pasted or uploaded images
Signed-off-by: Askeew <askeew@hotmail.com>
Closes: https://github.com/damus-io/damus/issues/2913
2025-08-08 16:31:30 -07:00
ericholguin
65a22813a3 refactor: Adding structure
Huge refactor to add better structure to the project.
Separating features with their associated view and model structure.
This should be better organization and will allow us to improve the
overall architecture in the future.

I forsee many more improvements that can follow this change. e.g. MVVM Arch
As well as cleaning up duplicate, unused, functionality.
Many files have global functions that can also be moved or be renamed.

damus/
├── Features/
│   ├── <Feature>/
│   │   ├── Views/
│   │   └── Models/
├── Shared/
│   ├── Components/
│   ├── Media/
│   ├── Buttons/
│   ├── Extensions/
│   ├── Empty Views/
│   ├── ErrorHandling/
│   ├── Modifiers/
│   └── Utilities/
├── Core/
│   ├── Nostr/
│   ├── NIPs/
│   ├── DIPs/
│   ├── Types/
│   ├── Networking/
│   └── Storage/

Signed-off-by: ericholguin <ericholguin@apache.org>
2025-08-06 10:24:00 -07:00
fdbf271432 Add relay count and relay view to events
Changelog-Added: Added relay count and relay view to events

Closes: https://github.com/damus-io/damus/issues/1029
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-07-21 16:45:49 -07:00
b26eedc633 Fix note content rendering to not remove whitespace before hashtag
Changelog-Fixed: Fixed note content rendering to not remove whitespace before hashtag

Closes: https://github.com/damus-io/damus/issues/3122
Fixes: f436291209 ("Fix note content rendering to not remove whitespace before hashtag")
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-07-21 16:37:36 -07:00
793970beaf Add relay hints to tags and identifiers
Changelog-Added: Add relay hints to tags and identifiers
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-07-18 15:51:25 -07:00
transifex-integration[bot]
049d9170be Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-07-18 14:52:31 -07:00
transifex-integration[bot]
fd10c5672a Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-07-18 14:52:31 -07:00
transifex-integration[bot]
37bd9447f0 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-07-18 14:52:31 -07:00
transifex-integration[bot]
e8457d7486 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-07-18 14:52:31 -07:00
transifex-integration[bot]
280297ad35 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-07-18 14:52:31 -07:00
transifex-integration[bot]
7da3ead01e Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-07-18 14:52:31 -07:00
3ddb2625e9 Fix #nsfw tag filtering to be case insensitive
Closes: https://github.com/damus-io/damus/issues/3131

Changelog-Fixed: Fixed #nsfw tag filtering to be case insensitive
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-07-11 10:48:10 -07:00
Swift
f53ffae767 Fix stretchy banner header in Edit profile
Put the views into ScrollView
Fixed banner offset in Geometry reader

Changelog-Fixed: Fixed stretchy banner header in Edit profile
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2025-07-09 15:06:23 -07:00
Daniel D’Aquino
b9168f9914 Merge pull request #3121 from damus-io/translations
Translations
2025-07-09 10:43:04 -07:00
Daniel D’Aquino
63ff2b6f9e ui: Stabilize ImageCarousel height when swiping between images
This commit enhances the ImageCarousel component to maintain a consistent
height when navigating between images of different aspect ratios. The
changes prevent the UI from "jumping" during carousel navigation, which
improves the overall user experience.

Key improvements:
- Added `first_image_fill` property to store dimensions of the first image
- Modified height calculation to prioritize the first image's dimensions
- Refactored image fill calculation into a reusable `compute_item_fill` method
- Added proper view clipping to prevent content overflow
- Simplified filling behavior for more predictable layout

These changes provide a smoother, more stable carousel experience by
maintaining consistent dimensions throughout image navigation.

Changelog-Changed: Improved the image sizing behavior on the image carousel for a smoother experience
Closes: https://github.com/damus-io/damus/issues/2724
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-07-09 10:26:32 -07:00
transifex-integration[bot]
7d9468388b Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-07-08 05:48:12 +00:00
transifex-integration[bot]
66b555e0ff Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-07-07 22:04:41 -04:00
transifex-integration[bot]
8df332472c Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-07-07 22:04:41 -04:00
transifex-integration[bot]
6072668438 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2025-07-07 22:04:41 -04:00
transifex-integration[bot]
6f26ddf7ac Translate Localizable.stringsdict in ja
100% translated source file: 'Localizable.stringsdict'
on 'ja'.
2025-07-07 22:04:41 -04:00
df156df6d9 Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-07-07 22:04:40 -04:00
transifex-integration[bot]
11c367b541 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2025-07-07 22:04:40 -04:00
transifex-integration[bot]
4e1b23d1cb Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-07-07 22:04:40 -04:00
transifex-integration[bot]
2de3083dad Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-07-07 22:04:40 -04:00
93149642db Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-07-07 22:04:40 -04:00
transifex-integration[bot]
0b0d422b7a Translate Localizable.stringsdict in th
100% translated source file: 'Localizable.stringsdict'
on 'th'.
2025-07-07 22:04:40 -04:00
transifex-integration[bot]
036ea50a3a Translate Localizable.stringsdict in th
100% translated source file: 'Localizable.stringsdict'
on 'th'.
2025-07-07 22:04:39 -04:00
Daniel D’Aquino
073feccbbf CI: Fix UI tests to include new onboarding steps
Changelog-None
Closes: https://github.com/damus-io/damus/issues/3124
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-07-07 17:56:30 -07:00
Daniel D’Aquino
eeea9d3266 Integrate follow packs into onboarding suggestions
Closes: https://github.com/damus-io/damus/issues/3007
Changelog-Added: Added new onboarding suggestions based on user-selected interests
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-07-04 09:58:10 -07:00
Daniel D’Aquino
b8bf5df7bc Add .build to .gitignore
Some code editors will automatically run the SourceKit LSP on the
project, and create the `.build` folder. This folder should be ignored
by git
2025-07-04 09:58:10 -07:00
Daniel D’Aquino
e9e68422d4 Implement max budget setting for Coinos one-click wallets
Closes: https://github.com/damus-io/damus/issues/3059
Changelog-Added: Added adjustable max budget setting for Coinos one-click wallets
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-07-03 16:14:23 -07:00
Askia Linder
6f9a00d728 Handle npub correctly in draft notes
Damus stores npub as both Strings and URLs in NSAttributedString.Key.link when a note is saved as a draft. Make Damus correctly handle both when we retrieve and store drafts.

Changelog-Changed: Handle npub correctly in draft notes
Signed-off-by: Askeew <askeew@hotmail.com>
Closes: https://github.com/damus-io/damus/issues/2923
2025-07-02 09:45:13 -07:00
Askia Linder
51e07df1b5 User section will be the last section in MutedView.
Changelog-Changed: Move users-section to be last in muted view
Signed-off-by: Askeew <askeew@hotmail.com>
Closes: https://github.com/damus-io/damus/issues/2939
2025-07-02 09:24:37 -07:00
ericholguin
2a42723b81 Update README
Small improvement to the Readme

Signed-off-by: ericholguin <ericholguin@apache.org>
2025-06-23 14:53:48 -07:00
839ef6a80d Remove image, video, and icon from non-media link previews if media links are present to reduce screen clutter
Changelog-Changed: Removed media from regular link previews if media is already being shown
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-23 11:36:24 -07:00
c073dd8fea Fix note rendering to include non-media link previews with image, video, and icon removed when media previews are disabled
Closes: https://github.com/damus-io/damus/issues/3099

Changelog-Fixed: Fixed note rendering to include regular link previews with media removed when media previews are disabled
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-23 11:36:24 -07:00
Daniel D’Aquino
8d9f728cf0 Display wallet response error if available
This commit improves error handling in the wallet's "send" feature, by
displaying more specific wallet response error messages when available.

Closes: https://github.com/damus-io/damus/issues/3095
Changelog-Fixed: Improve error handling on wallet send feature
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-06-20 19:02:16 -07:00
2c62741e25 Remove incorrect Thai translation for notes_from_three_and_others
Closes: https://github.com/damus-io/damus/issues/3093
Fixes: cfb6f07c67a8 ("Remove Thai translation with incorrect arguments")

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-20 18:53:01 -07:00
transifex-integration[bot]
1f612f7fde Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-06-20 15:04:06 -07:00
transifex-integration[bot]
0e9e102d0f Translate Localizable.stringsdict in th
100% translated source file: 'Localizable.stringsdict'
on 'th'.
2025-06-20 15:04:06 -07:00
transifex-integration[bot]
b94e8765a1 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-06-20 15:04:06 -07:00
transifex-integration[bot]
53964f5c1a Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2025-06-20 15:04:06 -07:00
bd574d93c3 Fix localizable strings in FollowPackView
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-20 15:04:06 -07:00
47514ace79 Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-20 15:04:06 -07:00
transifex-integration[bot]
298b43733f Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2025-06-20 15:04:06 -07:00
transifex-integration[bot]
02116c0af5 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-06-20 15:04:06 -07:00
92121e3b2d Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-20 15:04:06 -07:00
Daniel D’Aquino
c92094823e Add send feature
Closes: https://github.com/damus-io/damus/issues/2988
Changelog-Added: Added send feature to the wallet view
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-06-20 14:12:50 -07:00
Daniel D’Aquino
f4b1a504a5 Fix issue with balance loading appearance
During the implementation of the "hide balance" feature, the balance
view was refactored in a way that caused it to not be redacted anymore,
making it show the "??" instead of the intended skeleton loader.

This commit fixes that issue without reverting the hide balance feature.

Changelog-Fixed: Fixed issue where the text "??" would appear on the balance while loading
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-06-20 14:12:50 -07:00
99ae7de5eb Rename Friends of Friends to Trusted Network and add popover tips to DMs and Notifications toolbars on Trusted Network button
Changelog-Changed: Renamed Friends of Friends to Trusted Network

Changelog-Added: Added popover tips to DMs and Notifications toolbars on Trusted Network button
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-16 13:32:02 -07:00
b3d9ee3fc0 Add tip in threads to inform users what trusted network means
Changelog-Added: Added tip in threads to inform users what trusted network means
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-16 13:32:02 -07:00
e65219ee3e Add web of trust reply sorting in threads to mitigate spam
Changelog-Added: Added web of trust reply sorting in threads to mitigate spam
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-16 13:32:02 -07:00
ericholguin
414c67a919 Follow Packs
This PR adds and enables follow packs in the universe view.

Closes: #3012

Changelog-Added: Added follow list kind 39089
Changelog-Added: Added follow pack preview
Changelog-Added: Added follow pack timeline to Universe View
Changelog-Removed: Removed hashtags in Universe View

Signed-off-by: ericholguin <ericholguin@apache.org>
2025-06-16 10:34:18 -07:00
f436291209 Hide end previewables when hashtags are present
Changelog-Fixed: Hide end previewables when hashtags are present
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-02 11:44:59 -07:00
a9196a39df Fix wallet transactions to always show profile display name unless there is no pubkey
Changelog-Fixed: Fixed wallet transactions to always show profile display name unless there is no pubkey
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-02 11:41:51 -07:00
William Casarin
6a8ee9c360 Merge remote-tracking branches 'github/pr/3066' and 'github/pr/3065' 2025-06-02 07:01:35 -07:00
947e24864e Add privacy-based redaction to nsec in key settings view
Changelog-Changed: Added privacy-based redaction to nsec in key settings view
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-01 19:54:46 -04:00
b9198d6bd7 Add privacy-based redaction to wallet view
Changelog-Changed: Added privacy-based redaction to wallet view
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-06-01 18:36:33 -04:00
William Casarin
14bf187a6e Merge remote-tracking branches 'github/pr/30{62,57,55,51,50}'
Merge a bunch of changes from terry, translations, and me

Terry Yiu (4):
      Add NIP-05 favicon to profile names and NIP-05 web of trust feed
      Fix quotes view header alignment
      Export strings for translation
      Rename Bitcoin Beach wallet to Blink

Transifex (11):
      Translate Localizable.strings in th
      Translate Localizable.strings in th
      Translate Localizable.strings in nl
      Translate Localizable.strings in de
      Translate Localizable.stringsdict in de
      Translate Localizable.stringsdict in de
      Translate Localizable.strings in th
      Translate Localizable.strings in th
      Translate Localizable.strings in th
      Translate Localizable.strings in th
      Translate Localizable.strings in th

William Casarin (2):
      perf: don't use regex in trim_{prefix,suffix}
2025-06-01 00:36:19 +02:00
William Casarin
c996e5f8b3 perf: don't use regex in trim_{prefix,suffix}
regex is overkill for this, and performance is quite bad

Fixes: b131c74ee3 ("Add prefix and suffix string trimming functions")
Signed-off-by: William Casarin <jb55@jb55.com>
2025-05-31 20:17:14 +02:00
b6dad349c9 Rename Bitcoin Beach wallet to Blink
Changelog-Changed: Renamed Bitcoin Beach wallet to Blink

Closes: https://github.com/damus-io/damus/issues/3056
2025-05-30 12:37:13 -04:00
transifex-integration[bot]
56dde30cf6 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
95bfbae131 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
3da0ff7ecc Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
b8f846ded8 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
e74c45ad39 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
e6a03522c6 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
dbc7d79ecd Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
d2b5a65eca Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-05-29 09:24:57 -07:00
transifex-integration[bot]
16b19d3a96 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-05-29 09:24:56 -07:00
transifex-integration[bot]
70edb8d7c5 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-29 09:24:56 -07:00
ea04ebe95c Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-29 09:24:56 -07:00
transifex-integration[bot]
44cf47faa4 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-29 09:24:55 -07:00
612abfd862 Fix quotes view header alignment
Changelog-Fixed: Fixed quotes view header alignment
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-27 17:40:07 -04:00
20af086273 Add NIP-05 favicon to profile names and NIP-05 web of trust feed
Changelog-Added: Added NIP-05 favicon to profile names and NIP-05 web of trust feed
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-27 00:54:03 -04:00
Swift Coder
e9c1671d06 Display Circular Indicator on top of media undergoing upload process
Removed existing progress view bar at the top of post view
Added separate stack in PVImageCarouselView for media undergoing the upload process
Changelog-Added: Display uploading indicator in post view
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2025-05-26 17:21:06 -07:00
Daniel D’Aquino
d02847d466 Version bump to 1.15
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-26 11:56:42 -07:00
Daniel D’Aquino
580fa954b2 Add changelog for v1.14
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-26 11:45:09 -07:00
Daniel D’Aquino
aef516ae9f Add relay connectivity information to NWC settings
Changelog-Changed: Added relay connectivity information to NWC settings
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:52 -07:00
Daniel D’Aquino
eb4e3b692b Do not process NWC responses not meant for the user
Soon after tightening error handling around NWC, it was noticed that
Damus was trying to process NWC responses meant for other people,
which caused a failure around the decryption process and a spam of
errors.

This commit modifies the relay filter to include only responses destined
to the user, and also guards the NWC response processing logic to ignore
responses meant for other users.

Changelog-Changed: Improved handling around NWC responses
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:52 -07:00
Daniel D’Aquino
fe52381d63 Improve error handling on NWC wallet
Changelog-Changed: Added more human visible errors on NWC wallets to aid with troubleshooting
Changelog-Added: Added copy technical info button to user visible errors, so that users can more easily share errors with developers
Closes: https://github.com/damus-io/damus/issues/3010
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:52 -07:00
Daniel D’Aquino
ab8d52e685 Add option to dismiss wallet high balance warning
Changelog-Added: Add dismiss button to wallet high balance reminders
Closes: https://github.com/damus-io/damus/issues/2994
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:52 -07:00
Daniel D’Aquino
1d32200ae3 Improve Coinos button disclaimer
Closes: https://github.com/damus-io/damus/issues/3000
Fixes: 67f0e3d296
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:52 -07:00
Daniel D’Aquino
309b00380d Add description and metadata to pay_invoice command
Changelog-Added: Zap receiver information now included for outgoing zaps
Closes: https://github.com/damus-io/damus/issues/2927
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:52 -07:00
Daniel D’Aquino
7fa2118480 Implement Codable for NdbNote
Makes it easier to work with other Swift types

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:52 -07:00
Daniel D’Aquino
1a6c17e308 Move Kingfisher data to the Caches directory
This commit moves Kingfisher data to Apple's designated caches folder
to avoid it from being backed up to iCloud.

Closes: https://github.com/damus-io/damus/issues/2993
Changelog-Fixed: Fixed issue where cached images would be backed up to iCloud
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:12:12 -07:00
Daniel D’Aquino
82a6046620 Re-enable note zaps
Let's go!

Changelog-Changed: Re-enabled note zaps as permitted by the new App Store guidelines
Closes: https://github.com/damus-io/damus/issues/3016
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-15 15:11:35 -07:00
Daniel D’Aquino
241755c8c4 Refactor wallet invoice URL handling
This is a minor refactor on the way wallet invoice URLs are handled, in
order to better fit the interface, enforce the design pattern, and avoid
side-effects in a particular function that handles opening URLs.

This design pattern was introduced to prevent issues on the previous
pattern, where URL handling was done with side-effects inside multiple
levels of nested logic and separate function calls, which would make
debugging very difficult, and cause the app to fail silently.

Closes: https://github.com/damus-io/damus/issues/3023
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-09 15:35:49 -07:00
transifex-integration[bot]
b26f66f15c Translate Localizable.stringsdict in ja
100% translated source file: 'Localizable.stringsdict'
on 'ja'.
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
28bd0c81e8 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-05-07 16:00:37 -07:00
0bd1814877 Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-07 16:00:37 -07:00
ee94f67b94 Remove arbitrary newline from localizable string
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
3a25075473 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
d16ff8f78f Translate Localizable.stringsdict in th
100% translated source file: 'Localizable.stringsdict'
on 'th'.
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
38dc90cb33 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
52bbc698b2 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
496a11f597 Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2025-05-07 16:00:37 -07:00
4a8a0ea1bd Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
c424d4da99 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2025-05-07 16:00:37 -07:00
transifex-integration[bot]
69d5fc1553 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-05-07 16:00:37 -07:00
bcb59896db Optimize classify_url function
Changelog-Fixed: Optimized classify_url function
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-07 15:13:31 -07:00
e1e6d9eb3d Add inline note rendering of invoices to pull up wallet selector sheet
Changelog-Added: Added inline note rendering of invoices to pull up wallet selector sheet
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-07 15:13:31 -07:00
f1fdae5957 Fix note rendering for those that contain previewable items or leading and trailing whitespaces
Changelog-Fixed: Fixed note rendering for those that contain previewable items or leading and trailing whitespaces
Closes: https://github.com/damus-io/damus/issues/2187
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-07 15:13:31 -07:00
ericholguin
f96647fa40 wallet: route to profile from wallet tx list
This PR allows users to tap on a profile picture from the wallet
transaction list to go to that user's profile page.

Closes: #2997

Changelog-Added: Added route to profile page from wallet tx list

Signed-off-by: ericholguin <ericholguin@apache.org>
2025-05-07 14:49:36 -07:00
Daniel D’Aquino
5ea522d306 Reinitialize videos if they enter an error state
This is a palliative fix for an issue where videos become unplayable
after a long user session.

The fix works by detecting the error state anytime the video gets
played, and reinitializes the video and corresponding player views in
order to clear the error.

Changelog-Fixed: Fixed issue where some videos would become unplayable after some time using the app
Closes: https://github.com/damus-io/damus/issues/2878
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-05-07 14:37:35 -07:00
SanjaySiddharth
54d6161acd Show additional information on top of blurred images
Changelog-Changed: Added additional information on top of blurred images
Closes: https://github.com/damus-io/damus/issues/2854
Signed-off-by: SanjaySiddharth <mjsanjaysiddharth1999@gmail.com>
2025-04-21 16:28:56 -07:00
Daniel D’Aquino
b1fd84fd75 Add safety reminder for higher balances
This commit adds a reminder to users who hold more than 100K sats in
their NWC wallet, reminding them to learn about self-custody.

Changelog-Added: Added safety reminder to wallets with higher balance
Closes: https://github.com/damus-io/damus/issues/2984
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-21 15:46:33 -07:00
Daniel D’Aquino
9dbdf7928a Add network connect call to extensions
This commit fixes a regression on the highlighter and share extensions,
which was caused by a change in the code's architecture, which required
the network manager to be initialized.

Fixes: 8d48f77d95138c93ed93989989fa930b61c2d6fb
Closes: https://github.com/damus-io/damus/issues/2955
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-21 15:29:46 -07:00
Daniel D’Aquino
67f0e3d296 Add disclaimer to Coinos button
Changelog-Changed: Added disclaimer to clarify that Coinos is a third-party service
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-21 12:23:31 -07:00
Daniel D’Aquino
e498418c2d Add one-click Coinos wallet setup
This commit implements a one-click Coinos wallet setup.

This was implemented using the Coinos API, and using account details
that are deterministically generated from the user's private key.

Closes: https://github.com/damus-io/damus/issues/2961
Changelog-Added: Added one-click Coinos wallet setup
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-21 12:23:31 -07:00
33150a42c5 Hide future notes from timeline
Changelog-Fixed: Hide future notes from timeline

Closes: https://github.com/damus-io/damus/issues/2949
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-18 16:29:12 -07:00
e7fe4ab9b4 Inverse hellthread_notifications_enabled to be hellthread_notifications_disabled and add hellthread_notifications_max_pubkeys setting
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-18 16:14:13 -07:00
c146bab08a Add notification setting to hide hellthreads
Changelog-Added: Add notification setting to hide hellthreads
Closes: https://github.com/damus-io/damus/issues/2943
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-18 16:14:13 -07:00
Daniel D’Aquino
d1cced8d54 Fetch NIP-65 relay lists from profile view
Changelog-Fixed: Fixed issue where profiles with a NIP-65 relay list would not display on Damus
Closes: https://github.com/damus-io/damus/issues/2120
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
8849b6105c Add First Aid tool to repair relay list
This adds a First aid tool to repair the NIP-65 relay list

Changelog-Added: Added separated first aid option for relay lists that does not need a contact list reset
Closes: https://github.com/damus-io/damus/issues/2120
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
3a0acfaba1 Implement NostrNetworkManager and UserRelayListManager
This commit implements a new layer called NostrNetworkManager,
responsible for managing interactions with the Nostr network, and
providing a higher level API that is easier and more secure to use for
the layer above it.

It also integrates it with the rest of the app, by moving RelayPool and PostBox
into NostrNetworkManager, along with all their usages.

Changelog-Added: Added NIP-65 relay list support
Changelog-Changed: Improved robustness of relay list handling
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
0ec2b05070 Implement safe interface for unowned NdbNotes
This commit introduces a new interface that makes it easier and safer to
handle unowned NostrDB notes, by leveraging new non-copyable and borrow
features from modern Swift.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
130bbfafb4 New async streaming interface from RelayPool
This defines a higher level and easier to use streaming interface from
RelayPool.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
ffc75772f9 NIP-65 relay list models and definitions
This commit adds the base models needed for the NIP-65 relay list support.

This introduces no user-facing changes.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
5b3fac70ed Organize RelayPool namespace
This is a non-functional refactor that organizes some classes and
structs used by RelayPool under the same namespace.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
53e3f6d86b Define protocol NostrEventConvertible
This adds a new protocol for classes that can be converted to and from a
NostrEvent.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
c28ab7a57c Renamed RelayInfo to LegacyKind3RelayRWConfiguration
This is a non-functional refactor that makes a struct name more
detailed.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
Daniel D’Aquino
09ce3af11e Add some miscellaneous documentation
This commit adds some documentation to miscellaneous functions and
classes.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-16 11:48:52 -07:00
e42c09883a Replace deprecated usage of UIMenuController with UITextViewDelegate
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-14 19:11:30 -07:00
77e3924809 Fix some compiler warnings
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-14 19:11:30 -07:00
3511b1ee91 Fix quote notes to include missing q tag
Changelog-Fixed: Fix quote notes to include missing q tag

Closes: https://github.com/damus-io/damus/issues/2615
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-14 19:10:46 -07:00
78a62c8ef0 Clean up code in ProfileName.name_choice
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-14 18:38:51 -07:00
Daniel D’Aquino
8b96b9f4e6 Merge pull request #2973 from damus-io/translations
Translations
2025-04-14 18:35:34 -07:00
Daniel D’Aquino
649a857c3a Update Kingfisher to 8.3.1
Changelog-Changed: Updated image cache for better stability
Closes: https://github.com/damus-io/damus/issues/2899
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-04-14 17:56:23 -07:00
transifex-integration[bot]
cdae2c7558 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-08 11:52:23 +00:00
transifex-integration[bot]
3639110c51 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-04-08 08:39:51 +00:00
186668512e Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-07 20:39:27 -04:00
f63666fae2 Add missing localized string comment
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-04-07 20:39:08 -04:00
transifex-integration[bot]
68d25059b1 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:30 -04:00
transifex-integration[bot]
9aef6b7f5b Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:30 -04:00
transifex-integration[bot]
d2e712575f Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:30 -04:00
transifex-integration[bot]
bf9674e6e4 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:30 -04:00
transifex-integration[bot]
4815390cbe Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:30 -04:00
transifex-integration[bot]
6ce903f1f6 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:30 -04:00
transifex-integration[bot]
b2c91ffce4 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:30 -04:00
transifex-integration[bot]
ae335b18bf Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:29 -04:00
transifex-integration[bot]
6391819fb2 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:29 -04:00
transifex-integration[bot]
5d0e56b7c7 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:29 -04:00
transifex-integration[bot]
50ccc7bd7f Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:29 -04:00
transifex-integration[bot]
b3a6bcf3b2 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:29 -04:00
transifex-integration[bot]
38b2988bbe Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-04-07 20:25:29 -04:00
transifex-integration[bot]
446c541dcb Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-04-07 20:25:29 -04:00
transifex-integration[bot]
31fd48ee52 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-04-07 20:25:28 -04:00
b35cc33c32 Add Unicode 16 emoji reactions for iOS 18.4+ by upgrading EmojiPicker
Changelog-Added: Added Unicode 16 emoji reactions for iOS 18.4+ by upgrading EmojiPicker
Closes: https://github.com/damus-io/damus/issues/2915
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-03-29 11:40:47 -03:00
SanjaySiddharth
9510290c29 Fix bug that closes the side menu when copying npub
Changelog-Fixed: Fixed issue where the side menu would close when copying the npub
Closes: https://github.com/damus-io/damus/issues/2748
Signed-off-by: SanjaySiddharth <mjsanjaysiddharth1999@gmail.com>
2025-03-28 22:00:00 -03:00
Daniel D’Aquino
3b1238b9c7 Merge pull request #2936 from damus-io/translations
Translations
2025-03-28 21:53:33 -03:00
SanjaySiddharth
3bec23ecac Add search feature to the settings screen
Closes: https://github.com/damus-io/damus/issues/2838
Changelog-Added: Added a search interface to the settings screen
Signed-off-by: SanjaySiddharth <mjsanjaysiddharth1999@gmail.com>
2025-03-28 18:48:08 -03:00
transifex-integration[bot]
7b678228b6 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:29:51 +00:00
transifex-integration[bot]
b1292d4562 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:29:41 +00:00
transifex-integration[bot]
a62d782fe5 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:29:30 +00:00
transifex-integration[bot]
81b07eb339 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:29:17 +00:00
transifex-integration[bot]
02f88398b9 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:28:56 +00:00
transifex-integration[bot]
e80961cc09 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:28:48 +00:00
transifex-integration[bot]
bd7721dc26 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:28:36 +00:00
transifex-integration[bot]
6d974bf71c Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:28:25 +00:00
transifex-integration[bot]
aeeb817735 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:27:59 +00:00
transifex-integration[bot]
b5e7033958 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:27:39 +00:00
transifex-integration[bot]
bdc843f30f Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:27:31 +00:00
transifex-integration[bot]
a823fa8e14 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:27:16 +00:00
transifex-integration[bot]
9232386c15 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:27:09 +00:00
transifex-integration[bot]
3c1547718c Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:26:58 +00:00
transifex-integration[bot]
b67a7f3e9e Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:23:06 +00:00
transifex-integration[bot]
92850d4f64 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-25 06:22:59 +00:00
Daniel D’Aquino
6323eafd7e v1.13.1 changelog
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-03-24 14:02:08 -03:00
Daniel D’Aquino
b8fe826b58 Improve syncing and performance of ThreadModel
This commit introduces two minor improvements:
1. It ensures better consistency between ThreadModel and EventCache
2. It avoids unnecessary recursion calls on `add_event`

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-03-24 13:52:35 -03:00
Daniel D’Aquino
841c49238f Fix thread parent event loading regression
This fixes a regression where ThreadModel would no longer look at
NostrDB saved notes for parent events, causing some instability on
thread loading — especially in poor networking conditions.

This was fixed by adding a call that searches for parent events in
EventCache/NostrDB each time an event is added to the ThreadModel.

That `add_event` function is the ideal spot to place the call because it
is the only interface used for all information updates incoming to the
ThreadModel, including:
- anytime an event is loaded from the network into the thread model.
- when the ThreadModel is first initialized, with an initial event.

Fixes: 74d5bee1f6
Changelog-Fixed: Fixed an issue where threads would not load properly
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-03-24 13:52:35 -03:00
transifex-integration[bot]
7ab612e3d9 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2025-03-23 18:13:22 +00:00
transifex-integration[bot]
6d8a27688f Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-03-23 16:34:49 +00:00
transifex-integration[bot]
765385319a Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-03-23 16:34:31 +00:00
transifex-integration[bot]
342c49a3e5 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-03-23 10:48:13 +00:00
transifex-integration[bot]
25860e7bb2 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-23 05:06:23 +00:00
transifex-integration[bot]
6962f2b462 Translate InfoPlist.strings in fr
100% translated source file: 'InfoPlist.strings'
on 'fr'.
2025-03-22 21:44:17 +00:00
e48ce4c6c5 Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-03-22 15:53:21 -04:00
1cb311cc2c Fix localization issues in TransactionsView
Fixes: 22f2aba969 ("Fix localization issues in TransactionsView")
Changelog-Fixed: Fix localization issues in TransactionsView
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-03-22 15:51:31 -04:00
transifex-integration[bot]
401846abe4 Translate Localizable.stringsdict in hu_HU
100% translated source file: 'Localizable.stringsdict'
on 'hu_HU'.
2025-03-22 14:50:14 -04:00
transifex-integration[bot]
16ef393350 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2025-03-22 14:50:14 -04:00
transifex-integration[bot]
d5742f8e4c Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-03-22 14:50:14 -04:00
transifex-integration[bot]
319063f823 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-03-22 14:50:14 -04:00
transifex-integration[bot]
5b13cf5634 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-03-22 14:50:14 -04:00
transifex-integration[bot]
da10b908b3 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:14 -04:00
transifex-integration[bot]
4568935bc5 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:14 -04:00
transifex-integration[bot]
467404a55e Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
fcfe1e4558 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
c9d87a1b9a Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
35ebf4dfc2 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
bc3c256d22 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
0e10e74496 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
ebe9097f73 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
d61a11b647 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:13 -04:00
transifex-integration[bot]
d980cc1f8e Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
bd6056ce2e Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
cf48fda8d0 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
dc344cd28c Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
358610575f Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
a7869fccbb Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
a50903f90a Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
9243705995 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-03-22 14:50:12 -04:00
transifex-integration[bot]
db4dd9eee9 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-03-22 14:50:10 -04:00
ericholguin
22f2aba969 nwc: Wallet Redesign
This PR redesigns the NWC wallet view. A new view is added to introduce zaps to users. The set up wallet view is simplified, with new and existing wallet setup separated.
This also adds new NWC features such as getBalance and listTransactions allowing users to see their balance and previous transactions made.

Changelog-Added: Added view introducing users to Zaps
Changelog-Added: Added new wallet view with balance and transactions list
Changelog-Changed: Improved integration with Nostr Wallet Connect wallets
Closes: https://github.com/damus-io/damus/issues/2900

Signed-off-by: ericholguin <ericholguin@apache.org>
Co-Authored-By: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-03-19 18:00:00 -03:00
Daniel D’Aquino
98f2777fda Version bump to 1.14
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-03-17 11:05:43 -03:00
Daniel D’Aquino
102ce43216 v1.13 changelog
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-03-17 10:58:12 -03:00
William Casarin
0c148c8a1f Merge Communication Notifications 2025-03-03 14:22:11 -08:00
William Casarin
3cccb2eb6b project: fix version yet again
we should always be using the inherited project version so that
everything is consistent

Signed-off-by: William Casarin <jb55@jb55.com>
2025-03-03 14:21:53 -08:00
William Casarin
af4949e26a Communication notifications
Signed-off-by: William Casarin <jb55@jb55.com>
2025-03-03 14:21:53 -08:00
Claude
5bb7e95624 chore: update Package.swift to Swift tools version 6.0 2025-03-03 12:52:56 -08:00
814bcf694f Change spaces to newlines in new posts to provide cleaner separation between text, uploaded media, and quoted notes
Changelog-Changed: Changed spaces to newlines in new posts to provide cleaner separation between text, uploaded media, and quoted notes
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-03-03 11:51:08 -08:00
Daniel D’Aquino
b0382c61b1 Merge pull request #2889 from damus-io/translations
Translations
2025-03-03 11:33:28 -08:00
e2650a8bfc Fix bug where profile view was showing more than just the notes and replies on the notes / notes & replies tabs
Changelog-Fixed: Fix bug where profile view was showing more than just the notes and replies on the notes / notes & replies tabs
Fixes: caa4bfe864 ("Fix bug where profile view was showing more than just the notes and replies on the notes / notes & replies tabs")
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-03-03 11:20:34 -08:00
transifex-integration[bot]
ac39a53b33 Translate Localizable.stringsdict in pt_PT
100% translated source file: 'Localizable.stringsdict'
on 'pt_PT'.
2025-03-02 15:18:22 +00:00
transifex-integration[bot]
fb356cdf0b Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2025-03-02 15:16:26 +00:00
transifex-integration[bot]
238e89ce16 Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2025-03-02 15:16:15 +00:00
transifex-integration[bot]
6e041c79f7 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-03-02 15:14:24 +00:00
William Casarin
6ef4b60d14 test: disable broken tests
Signed-off-by: William Casarin <jb55@jb55.com>
2025-03-01 17:07:19 -08:00
transifex-integration[bot]
054bec2d9a Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2025-03-01 14:15:26 -05:00
transifex-integration[bot]
943a46a343 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-03-01 14:15:26 -05:00
transifex-integration[bot]
17381f6b94 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-03-01 14:15:26 -05:00
transifex-integration[bot]
18c88de407 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
99d21fc89b Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
db5c86a0d1 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
736ec6fb9e Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
fa2327325a Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
4fdf048040 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
273538bd36 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
0980c8c040 Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
f0bfdeaa5a Translate Localizable.stringsdict in th
100% translated source file: 'Localizable.stringsdict'
on 'th'.
2025-03-01 14:15:25 -05:00
transifex-integration[bot]
ab7c5c18e3 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-03-01 14:15:24 -05:00
transifex-integration[bot]
6ae95ab5ec Translate Localizable.stringsdict in ja
100% translated source file: 'Localizable.stringsdict'
on 'ja'.
2025-03-01 14:15:24 -05:00
eec630b2b0 Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-03-01 14:15:23 -05:00
William Casarin
2b3d86968d add todo for fixing q tags
Signed-off-by: William Casarin <jb55@jb55.com>
2025-02-28 09:44:29 -08:00
William Casarin
935a6cae7a Merge conversation tab and other updates from Terry
I've tested these and they seem to be working!

Terry Yiu (3):
      Fix reposts banner to be localizable
      Add Conversations tab to profiles
      Remove mystery tabs meant to fix tab switching bug that no longer exists
2025-02-25 12:48:34 -08:00
William Casarin
d4940d8386 prs: ensure PR always have a linked issue
This makes project management a bit nicer in linear

Signed-off-by: William Casarin <jb55@jb55.com>
2025-02-25 10:28:37 -08:00
71ec18f6c6 Remove mystery tabs meant to fix tab switching bug that no longer exists
Changelog-Removed: Removed mystery tabs meant to fix tab switching bug that no longer exists
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-02-25 09:21:36 -05:00
caa4bfe864 Add Conversations tab to profiles
Changelog-Added: Added Conversations tab to profiles
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-02-24 21:34:16 -05:00
a87ba73160 Fix reposts banner to be localizable
Changelog-Fixed: Fixed reposts banner to be localizable
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-02-24 14:52:53 -05:00
Daniel D’Aquino
4324b185fe Improve open action handling for notifications
Push notifications were not opened reliably. To improve robustness, the
following changes were introduced:
1. The notification opening logic was updated to become more similar to
   URL handling, in a way that uses better defined interfaces and
   functions that provide better result guarantees, by separating
   complex handling logic, and the side-effects/mutations that
   are made after computing the open action — instead of relying on a
   complex logic function that produces side-effects as a result, which
   obfuscates the actual behavior of the function.
2. The LoadableThreadView was expanded and renamed to
   LoadableNostrEventView, to reflect that it can also handle non-thread
   nostr events, such as DMs, which is a necessity for handling push
   notifications.
3. A new type of Notify object, the `QueueableNotify` was introduced, to
   address issues where the listener/handler is not instantiated at the
   time the app notifies that there is a push notification to be opened.
   This was implemented using async streams, which simplifies the usage
   of this down to a simple "for-in" loop.

Closes: https://github.com/damus-io/damus/issues/2825
Changelog-Fixed: Fixed issue where some push notifications would not open in the app and leave users confused
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-21 11:28:26 -08:00
Daniel D’Aquino
1ab9b30b85 Add development and testing tips
These were included to help other developers with testing or
development.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-21 11:28:26 -08:00
William Casarin
81cf6ad297 Merge remote-tracking branches 'pr/2863', 'pr/2864', 'pr/2865' and 'pr/2866'
Daniel D’Aquino (4):
      Reduce swipe sensitivity on thread chat view
      Fix issue where a NWC connection would not work unless restarting the app
      Implement developer feature to avoid distractions
      Fix issue where note persisted after note publication
2025-02-21 11:10:55 -08:00
William Casarin
1b3be3a13b Revert "Update EventMenu.swift"
should have tested this first lol

This reverts commit 3a2ce04d6b.
2025-02-21 11:07:47 -08:00
alltheseas
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
Daniel D’Aquino
981821a6bc Fix issue where note persisted after note publication
There is no changelog entry needed because drafts are still an
unreleased feature.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/2836
2025-02-19 20:21:49 -08:00
Daniel D’Aquino
98f83769bd Fix issue where a NWC connection would not work unless restarting the app
Changelog-Fixed: Fixed issue where app would need a restart for new NWC wallets to work
Closes: https://github.com/damus-io/damus/issues/2859
Closes: https://github.com/damus-io/damus/issues/1135
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-19 17:58:14 -08:00
Daniel D’Aquino
7684f53281 Implement developer feature to avoid distractions
This commit implements an optional developer feature to scramble text
and blur images to prevent distractions during development and testing.

It is not perfect (It breaks some mentions and rich text objects, and
does not scramble non-alphanumeric languages such as Japanese), but
good enough to avoid distractions while working on most features.

No changelog entry is needed because this is not meant for the final
user.

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-19 17:39:21 -08:00
Daniel D’Aquino
15af686a58 Fix issue where a NWC connection would not work unless restarting the app
Changelog-Fixed: Fixed issue where app would need a restart for new NWC wallets to work
Closes: https://github.com/damus-io/damus/issues/2859
Closes: https://github.com/damus-io/damus/issues/1135
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-19 17:22:32 -08:00
Daniel D’Aquino
aad8f9e8d4 Reduce swipe sensitivity on thread chat view
Value determined experimentally.

Closes: https://github.com/damus-io/damus/issues/2743
Changelog-Fixed: Fixed overly sensitive horizontal swipe on thread chat view
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-17 17:22:02 -08:00
b2ee44c0ab Trim whitespaces from Lightning addresses
Changelog-Fixed: Trim whitespaces from Lightning addresses
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-02-17 16:43:32 -08:00
William Casarin
a696ac5084 Merge translations 2025-02-13 10:20:53 -08:00
William Casarin
28237c3a63 Merge release process 2025-02-13 10:19:01 -08:00
transifex-integration[bot]
1cae4640c0 Translate InfoPlist.strings in pl_PL
100% translated source file: 'InfoPlist.strings'
on 'pl_PL'.
2025-02-13 15:00:03 +00:00
transifex-integration[bot]
21a07d54cb Translate InfoPlist.strings in pl_PL
100% translated source file: 'InfoPlist.strings'
on 'pl_PL'.
2025-02-13 14:59:49 +00:00
transifex-integration[bot]
1efd07b852 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-02-13 14:58:45 +00:00
transifex-integration[bot]
e5eb7d44a2 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-02-13 04:25:45 +00:00
William Casarin
ec9a89ee4d Merge Fix unwanted draft auto-scrolls
Daniel D’Aquino (1):
      Fix unwanted auto-scrolls related to draft saving mechanism
2025-02-12 15:47:44 -08:00
William Casarin
4741c2a3e8 reposts: add links to repost listing in timeline
Signed-off-by: William Casarin <jb55@jb55.com>
2025-02-12 15:43:19 -08:00
Daniel D’Aquino
0111c5e2dc Fix unwanted auto-scrolls related to draft saving mechanism
This commit fixes an issue where the post view would scroll to the text
cursor at seemingly random times.

This was done by detaching the save view and its logic, so that we have
3 components:
1. The `PostView`
2. An auto-save view model (which is an Observable object)
3. A separate SwiftUI view for the auto-save indicator

The auto-save view model is shared between the `PostView` and the new
indicator view to ensure proper signaling and communication across
views.

However, this view model is only observed by the indicator view,
ensuring it updates its own view, while not causing any re-renders on
the rest of the `PostView`.

This refactor had the side-effect of making the auto-save logic and view
more reusable. It is now a separate collection of elements that can be
used anywhere else.

Beyond the scroll issue, this commit also prevents empty drafts from
being saved, by introducing the new save state called `.nothingToSave`

Note: No changelog item is needed because the new drafts feature was never
publicly released.

Changelog-None
Closes: https://github.com/damus-io/damus/issues/2826
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-12 13:28:40 -08:00
William Casarin
bed4e00b53 home: dont show reposts for the same note more than once
Fixes: https://github.com/damus-io/damus/issues/859
Changelog-Changed: Don't show reposts for the same note more than once in your home feed
Signed-off-by: William Casarin <jb55@jb55.com>
2025-02-12 12:19:10 -08:00
William Casarin
bf14d7138a driveby compile warning fixes
Signed-off-by: William Casarin <jb55@jb55.com>
2025-02-12 12:19:10 -08:00
emir yorulmaz
0c5da08a42 Change 'twitter' to 'X/Twitter' on README.md 2025-02-12 11:07:47 -08:00
Daniel D’Aquino
a6e123e928 Remove rust-nostr dependency
This commit removes rust-nostr dependency, and replaces the NIP-44 logic
with a new NIP-44 module based on the Swift NostrSDK implementation.

The decision to move away from rust-nostr and the Swift NostrSDK was
made for the following reasons:
1. `rust-nostr` caused the app size to double
2. We only need NIP44 functionality, and we don't need to bring
   everything else
3. The Swift NostrSDK caused conflicts around the secp256k1 dependency
   that is hard to address
4. The way we do things in the codebase is far different from the Swift
   NostrSDK, and we optimize it for use with NostrDB. Bringing it an
   outside library causes significant complexity in integration with
   NostrDB, and would effectively cause the codebase to be split into
   two different ways of achieving the same results. Therefore it is
   cleaner if we stick to our own Nostr structures and functions and
   focus on maintaining them.

However, the library CryptoSwift was added as a dependency, to bring in
ChaCha20 which is not supported by CryptoKit (CryptoKit supports the
ChaCha20-Poly1305 cipher, but NIP-44 uses ChaCha20 with HMAC-SHA256
instead)

Closes: https://github.com/damus-io/damus/issues/2849
Changelog-Changed: Made internal changes to reduce the app binary size
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-12 11:05:58 -08:00
transifex-integration[bot]
69b1173e08 Translate InfoPlist.strings in th
100% translated source file: 'InfoPlist.strings'
on 'th'.
2025-02-12 13:03:12 +00:00
transifex-integration[bot]
c3326213e9 Translate InfoPlist.strings in ja
100% translated source file: 'InfoPlist.strings'
on 'ja'.
2025-02-12 01:49:52 +00:00
325109d7b8 Remove preview strings from translation and add missing period to duplicate string to avoid double translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-02-11 09:52:03 -05:00
transifex-integration[bot]
f16d76605b Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-02-11 09:52:03 -05:00
transifex-integration[bot]
3eee1b205a Translate InfoPlist.strings in de
100% translated source file: 'InfoPlist.strings'
on 'de'.
2025-02-11 09:52:03 -05:00
transifex-integration[bot]
9545c6446d Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-02-11 09:52:03 -05:00
transifex-integration[bot]
40a75f65ab Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-02-11 09:52:03 -05:00
transifex-integration[bot]
98f42c9896 Translate InfoPlist.strings in nl
100% translated source file: 'InfoPlist.strings'
on 'nl'.
2025-02-11 09:52:03 -05:00
transifex-integration[bot]
5c22989675 Translate InfoPlist.strings in nl
100% translated source file: 'InfoPlist.strings'
on 'nl'.
2025-02-11 09:52:03 -05:00
999f16f6a4 Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-02-11 09:51:56 -05:00
transifex-integration[bot]
3f5fd6eee8 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-02-10 18:35:32 -05:00
transifex-integration[bot]
7c195aa75c Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-02-10 18:35:32 -05:00
transifex-integration[bot]
2071efc129 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-02-10 18:35:32 -05:00
transifex-integration[bot]
9db2e9b464 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-02-10 18:35:31 -05:00
transifex-integration[bot]
5f6cb568ff Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-02-10 18:35:31 -05:00
transifex-integration[bot]
045399a065 Translate Localizable.stringsdict in th
100% translated source file: 'Localizable.stringsdict'
on 'th'.
2025-02-10 18:35:31 -05:00
transifex-integration[bot]
1b526143d0 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-02-10 18:35:31 -05:00
transifex-integration[bot]
8a046c0d1b Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-02-10 18:35:31 -05:00
transifex-integration[bot]
2893e4234d Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-02-10 18:35:31 -05:00
transifex-integration[bot]
973a5ce2cb Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-02-10 18:35:31 -05:00
transifex-integration[bot]
1e81e90341 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-02-10 18:35:30 -05:00
9e7943e0e9 Fix translation export script by upgrading nostr-sdk-swift dependency to support Mac Catalyst
Changelog-Fixed: Fixed translation export script by upgrading nostr-sdk-swift dependency to support Mac Catalyst
Closes: https://github.com/damus-io/damus/issues/2841
Fixes: 24c3e61a4b ("Fix translation export script")
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-02-10 15:09:35 -08:00
Daniel D’Aquino
bb7ac4fea5 Release notes for v1.12.3
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-07 11:15:11 -08:00
Daniel D’Aquino
05d0e15359 Add release process issue template
A Github issue template to help formalizing the release process, in
order to avoid human errors in the process.

Closes: https://github.com/damus-io/damus/issues/2752
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-07 10:45:54 -08:00
Daniel D’Aquino
d4d17fcbad Add release process issue template
A Github issue template to help formalizing the release process, in
order to avoid human errors in the process.

Closes: https://github.com/damus-io/damus/issues/2752
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-05 19:35:59 +00:00
Daniel D’Aquino
c21d29a897 Improve clarity of mute button to indicate it serves as a block feature
Changelog-Changed: Improved clarity of the mute button to indicate it can be used for blocking a user
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-03 18:33:01 -08:00
Daniel D’Aquino
6e117ac39c Improve Microphone usage description
This makes the microphone access request contain a message that is more
clear to the user

Changelog-Changed: Made the microphone access request message more clear to users
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-02-03 18:33:01 -08:00
Daniel D’Aquino
79407f17e8 Add double star for Purple members that have been active for over a year
This commit adds a special badge for purple members who have been active
for more than one entire year.

Closes: https://github.com/damus-io/damus/issues/2831
Changelog-Added: Purple members who have been active for more than a year now get a special badge
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-29 21:36:36 -08:00
Daniel D’Aquino
72c19fc411 Unsubscribe from push notifications on logout
Closes: https://github.com/damus-io/damus/issues/1707
Changelog-Fixed: Fixed issue where users continue to receive push notifications after logout
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-24 10:42:29 -08:00
Daniel D’Aquino
24c3e61a4b Make drafts persistent
This commit makes drafts persistent.

It does so by:
1. Converting `DraftsArtifacts` into Nostr events
2. Wrapping those Nostr events into NIP-37 notes
3. Saving those NIP-37 notes into NostrDB
4. Loading those same notes at startup
5. Unwrapping NIP-37 notes into Nostr events
6. Parsing that into `DraftsArtifacts`, loaded into DamusState
7. PostView can then load these drafts

Furthermore, a UX indicator was added to show when a draft has been
saved.

Limitations:
1. No encoding/decoding roundtrip guarantees. That would require
   extensive and heavy refactoring which is out of the scope of this
   commit.
2. We rely on `UserSettings` to keep track of note ids, while we do not
   have Ndb query capabilities
3. No NIP-37 relay sync support has been added yet, as that adds
   important privacy and sync conflict considerations which are out of
   the scope of this ticket, which is ensuring people don't lose their
   progress while writing notes.
4. The main use cases and scenarios have been tested. Because of (1),
   there may be some small inconsistencies on the stored version of the
   draft, but care was taken to keep the substantial portions of the
   content intact.

Closes: https://github.com/damus-io/damus/issues/1862
Changelog-Added: Added local persistence of note drafts
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-24 10:36:46 -08:00
Daniel D’Aquino
74d5bee1f6 Fix disappearing events on thread view
This commit fixes an issue where events in threads would occasionally
disappear.

Previously, the computation of parent events and reply events depended
on EventCache and had to be manually computed upon event selection
change. This may lead to inconsistencies if the computation is not
re-done after a new event that leads to a change in the model, or if certain
events are not yet on the cache. Instead, these are now computed
properties inside ThreadModel, and relies exclusively on the events
already in the ThreadModel.

Several other smaller improvements were made around the affected class,
including:
- Removing unused code for simplicity
- Configuring the class external interface with more intent, avoiding
  misusage
- Adding more documentation on the usage of things, as well as
  implementation notes on why certain design decisions were taken.
- Moving things to explicit actors, to integrate more structured concurrency
- Improving code efficiency to lower computational overhead on the main
  actor
- Splitting concerns between objects with more intent and thoughful
  design.

Changelog-Fixed: Fixed an issue where events on a thread view would occasionally disappear
Closes: https://github.com/damus-io/damus/issues/2791
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-24 10:36:46 -08:00
Daniel D’Aquino
8066fa1bf8 Improve robustness of the URL handler
This commit improves reliability on the handling of
external URLs.

This was achieved through the following improvements:
1. The URL handler interface is now well-defined, with more clear inputs
   and outputs, to avoid silent failures and error paths that are hard to see
   within convoluted logic paths
2. Side effects during URL parsing were almost completely removed for
   more predictable behavior
3. Error handling logic was added to present errors to the user in a user-friendly manner,
   instead of silently failing
4. Event loading logic was moved into a special new thread view, which
   makes its own internal state evident to the user (i.e. whether
   the note is loading, loaded, or if the note could not be found)

These changes make the URL opening logic more predictable, easy to
refactor, and helps ensure the user always gets some outcome from
opening a URL, even if it means showing a "not found" or "error" screen,
to eliminate cases where nothing seems to happen.

Closes: https://github.com/damus-io/damus/issues/2429
Changelog-Fixed: Improved robustness of the URL handler
Changelog-Added: Added user-friendly error view for errors around the app that would not fit in other places
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-24 10:05:55 -08:00
26df547605 Remove language filtering from Universe feed because language detection can be inaccurate
Changelog-Removed: Removed language filtering from Universe feed because language detection can be inaccurate

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-01-22 17:23:00 +09:00
a97532b90d Translate notes even if they are in a preferred language but not the current language as that is what users expect
Changelog-Fixed: Translate notes even if they are in a preferred language but not the current language as that is what users expect

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-01-22 17:23:00 +09:00
Daniel D’Aquino
e8ba1ec806 Merge pull request #2812 from damus-io/translations
Translations
2025-01-22 16:56:56 +09:00
Daniel D’Aquino
e8c265a4d8 Version bump to 1.13
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-22 14:03:22 +09:00
Daniel D’Aquino
b33dc63fe4 v1.12 changelog
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-22 13:56:42 +09:00
transifex-integration[bot]
c4852f1309 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2025-01-21 13:36:41 +00:00
transifex-integration[bot]
39a4be7076 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2025-01-20 20:01:03 +00:00
transifex-integration[bot]
50c7edc420 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-01-20 19:40:49 +00:00
transifex-integration[bot]
67fa3c1ce5 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-01-20 19:40:37 +00:00
transifex-integration[bot]
cd671da3e7 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2025-01-20 19:40:30 +00:00
transifex-integration[bot]
3b60ca04f1 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2025-01-20 11:46:31 +00:00
transifex-integration[bot]
e2e58499f5 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2025-01-20 00:40:20 +00:00
5cadf09665 Export strings for translation 2025-01-19 12:29:10 -05:00
transifex-integration[bot]
1ca7b3462f Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:10 -05:00
transifex-integration[bot]
8a552d2b0f Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:10 -05:00
transifex-integration[bot]
9fa0f18f78 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:10 -05:00
transifex-integration[bot]
db672ca048 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:09 -05:00
transifex-integration[bot]
18ad73cd35 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:09 -05:00
transifex-integration[bot]
5719e9b37e Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:09 -05:00
transifex-integration[bot]
9fb2b3c0e5 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:09 -05:00
transifex-integration[bot]
5ec66feb06 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:09 -05:00
transifex-integration[bot]
ccc301cfcc Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:09 -05:00
transifex-integration[bot]
c1b9d0b55e Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:09 -05:00
transifex-integration[bot]
d9daa27016 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
fa3b5d57ed Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
7c3e598ca6 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
563d5c7881 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
b8cba0ee17 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
8556586af4 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
5fc52bb31b Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
a92c9f2c38 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:08 -05:00
transifex-integration[bot]
61e137696e Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:07 -05:00
transifex-integration[bot]
8fc3b124da Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:07 -05:00
transifex-integration[bot]
7852822295 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:07 -05:00
transifex-integration[bot]
85e55953b3 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:07 -05:00
transifex-integration[bot]
077f633f33 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:07 -05:00
transifex-integration[bot]
1c3d1598a3 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:07 -05:00
transifex-integration[bot]
314608627e Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:07 -05:00
transifex-integration[bot]
aeecc04b29 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:06 -05:00
transifex-integration[bot]
341389d438 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2025-01-19 12:21:06 -05:00
transifex-integration[bot]
fbeae64123 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2025-01-19 12:21:05 -05:00
ericholguin
7a4af31859 nwc: Coinos
This PR adds a button to allow users to easily connect to Coinos
Also cleans up and organizes assets.

Changelog-Added: Coinos connection button in Wallet view

Signed-off-by: ericholguin <ericholguin@apache.org>
2025-01-12 15:20:06 +09:00
Tomek ⚡ K
e106be1412 Add Alby Go to mobile wallets selection
Changelog-Added: Added Alby Go to mobile wallets selection menu
Signed-off-by: Tomek K <itstomekk@getalby.com>
2025-01-12 11:33:20 +09:00
Swift Coder
282bf80daa Cancel ongoing uploading operations after cancelling post
1] Cancel ongoing uploading operations after the user has pressed "cancel post"
2] Don't generate haptic feedback in this error case because user has already dismissed the Post View

Changelog-Fixed: Cancel ongoing uploading operations after the user cancels the post
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2025-01-06 15:55:53 +09:00
Daniel D’Aquino
bcb861a61b Improve accessibility of EditPictureControl
This commit improves accessibility of EditPictureControl, by adding
better accessibility labels and hints.

Changelog-Added: Minor accessibility improvements around picture editing and onboarding
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-06 15:45:58 +09:00
Daniel D’Aquino
bb0ad18913 Implement profile image cropping and optimization
This commit implements profile image cropping and optimization, as well
as a major refactor on EditPictureControl.

It now employs the following techniques:
- Users can now crop their profile pictures to fit a square aspect
  ratio nicely and avoid issues with automatic resizing/cropping
- Profile images are resized to a 400px by 400px image before sending it
  over the wire for better bandwidth usage
- Profile pictures are now tagged as such to the media uploaders, to
  enable media optimization or special care on their end.

Integrating the cropping step was very difficult with the previous
structures, so `EditPictureControl` was heavily refactored to have
improved state handling and better testability:

1. Enums with associated values are being used to capture all of the
   state in the picture selection process, as that helps ensure the
   needed info in each step is there and more clearly delianeate
   different steps — all at compile-time
2. The view was split into a view-model architecture, with almost all of
   the view logic ported to the new view-model class, making the view
   and the logic more clear to read as concerns are separated. This also
   enables better testabilty

Several automated tests were added to cover EditPictureControl logic and
looks.

Closes: https://github.com/damus-io/damus/issues/2643
Changelog-Added: Profile image cropping tools
Changelog-Changed: Improved profile image bandwidth optimization
Changelog-Changed: Improved reliability of picture selector
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-06 15:45:57 +09:00
Daniel D’Aquino
81830c7540 Add SwiftyCrop dependency
This commit adds the SwiftyCrop dependency, to provide users with a way
to crop their profile images prior to upload

- Dependency version is commit-hash-locked for extra security and
  reproducibility
- Reviewed code contents of the library to check for any user tracking
  code. None was found

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-01-06 15:45:57 +09:00
transifex-integration[bot]
68128b5ff1 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
aebeb26bc6 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
79cf3db279 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
dcae0d2cc7 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
2b12dc5920 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
51930e7a12 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
b04e09d2e0 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-27 20:36:57 +09:00
b6c4213515 Export strings for translation 2024-12-27 20:36:57 +09:00
transifex-integration[bot]
8230c6eded Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
e79590f795 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
79bced1246 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
896f4b55e3 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
52e65f9429 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
a22cc532e2 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
823227920c Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
3e2bbce25e Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
e05b2d9ecf Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
d7b31a1cd8 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
70f01c0880 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
2cf5f21f78 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
96e8f8b6b2 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
370cfd1b08 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
046af15734 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
9e4ab2d54c Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
7cf12e2e0d Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
a63a81b387 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
d994cd13dc Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
95e985cfce Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
3a69de9274 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
64f5acf98c Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
5167ab264d Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
e02895b29f Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
0009d11025 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
afc317bb52 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
629212ea23 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
transifex-integration[bot]
ec1252200f Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2024-12-27 20:36:57 +09:00
Swift Coder
54ea1ab803 MacOS Damus Support allowing link and photo sharing option
Changelog-Fixed: Fixed link and photo sharing support on macOS
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-27 19:13:45 +09:00
Swift Coder
4cf8097de4 Displaying suitable text instead of Empty Notification View
Changelog-Fixed:Handle empty notification pages by displaying suitable text
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-20 11:01:02 +09:00
Daniel D’Aquino
2c7384b0a9 Fix button hidden behind software keyboard in create account view
This commit fixes an issue where the "next" button is hidden behind the
software keyboard in the account creation view, where it is very hard to
press.

The fix was done by dynamically shrinking the profile picture size when
keyboard appears in smartphone screens, so that there is enough space
for all content to appear.

Changelog-Fixed: Fixed issue where the "next" button would appear hidden and hard to click on the create account view
Closes: https://github.com/damus-io/damus/issues/2771
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-12-20 10:38:20 +09:00
Swift Coder
19e312a8fb Fix non scrollable wallet screen
Changelog-Fixed: Fix non scrollable wallet screen
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-18 11:27:51 +09:00
Swift Coder
3986308638 Render Gif and video files while composing posts
Changelog-Added: Render Gif and video files while composing posts
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-16 17:22:12 +09:00
fa7740948b Export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2024-12-16 17:04:20 +09:00
892a1420f3 Fix suggested users category titles to be localizable
Changelog-Fixed: Fixed suggested users category titles to be localizable

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2024-12-16 17:04:20 +09:00
ee4cbf7363 Fix GradientFollowButton to have consistent width and autoscale text limited to 1 line
Changelog-Fixed: Fixed GradientFollowButton to have consistent width and autoscale text limited to 1 line

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2024-12-16 17:04:20 +09:00
a1b1ce949b Fix right-to-left localization issues
Changelog-Fixed: Fixed right-to-left localization issues

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2024-12-16 17:04:20 +09:00
902e8c3950 Fix AddMuteItemView to trim leading and trailing whitespaces from mute text and disallow adding text with only whitespaces
Changelog-Fixed: Fixed AddMuteItemView to trim leading and trailing whitespaces from mute text and disallow adding text with only whitespaces

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2024-12-16 17:04:20 +09:00
b776788b38 Fix SideMenuView text to autoscale and limit to 1 line
Changelog-Fixed: Fixed SideMenuView text to autoscale and limit to 1 line

Signed-off-by: Terry Yiu <git@tyiu.xyz>
2024-12-16 17:04:20 +09:00
Daniel D’Aquino
78066773f4 Improve clarity of word search label
Changelog-Changed: Improved UX around the label for searching words
Closes: https://github.com/damus-io/damus/issues/2733
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-12-13 14:00:00 +09:00
Daniel D’Aquino
0bac284eee Fix issues with inputting a profile twice to the search bar
This fixes an issue where a user would have to input a profile npub
twice in order to get a result.

The fix is composed of the following constituents:
1. The removal of the dependency on NostrDB having profile information.
   Previously the function relied on NostrDB having profile information
   about a freshly downloaded profile, which it sometimes does not. The
   function does not require the profile to be on NostrDB at the time
   the profile is found on the relay.
2. The increase in allowed relay attempts to all relays. Previously it
   would only look for about half of the relays, which could cause
   certain events to not be found
3. The closing of relay subscription on EOSE. Previously, the
   subscription would only be closed if an event was found, which could
   lead to a "leak" of open subscriptions if an event is not found.

Closes: https://github.com/damus-io/damus/issues/2635
Changelog-Fixed: Fixed an issue where a profile would need to be input twice in the search to be found
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-12-13 14:00:00 +09:00
Daniel D’Aquino
07c95d1003 Turn on strict concurrency checks
Turn on strict concurrency checks on the compiler to make potential
concurrency issues more visible and aid during debugging, as well as to
start preparing us for Swift 6.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-12-13 14:00:00 +09:00
Daniel D’Aquino
1072c5a384 Version bump to 1.12
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-12-09 18:05:12 +09:00
transifex-integration[bot]
5ed6e85ad8 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
f948dd81ca Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
391818f230 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
dc74ad37a1 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
e1c94b7ff9 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
ec933452d3 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
977b268023 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
0c778af833 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
e75e7950b5 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
8d68297cce Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
e0fd24aff5 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
b5c3ff45e4 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
786dbb21c4 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
5a17c330da Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
975be63ce1 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
d9796bd63c Translate Localizable.stringsdict in ar
100% translated source file: 'Localizable.stringsdict'
on 'ar'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
25a835624a Translate Localizable.strings in ar
100% translated source file: 'Localizable.strings'
on 'ar'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
1d06683bb3 Translate Localizable.stringsdict in pt_PT
100% translated source file: 'Localizable.stringsdict'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
8e15a86c0a Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
51a3008e5a Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
f71c1b9848 Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
151e23d524 Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
7619891c86 Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
cc98525f59 Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
8cf9549981 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
9ebf27cd37 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
16a1a9f37f Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
08d28b0f00 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-12-09 18:00:42 +09:00
d0ae3ca08a Fix non-breaking spaces in localized strings
Changelog-Fixed: Fixed non-breaking spaces in localized strings

Signed-off-by: Terry Yiu <963907+tyiu@users.noreply.github.com>
2024-12-09 18:00:42 +09:00
6e2f770876 Revert "Replace non-breaking spaces with regular spaces as Apple's NSLocalizedString macro does not seem to work with it"
This reverts commit 4adcb738a2.
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
4079bea912 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-12-09 18:00:42 +09:00
4d01340b90 Fix localization issue on Add mute item button
Changelog-Fixed: Fixed localization issue on Add mute item button

Signed-off-by: Terry Yiu <963907+tyiu@users.noreply.github.com>
2024-12-09 18:00:42 +09:00
transifex-integration[bot]
61b89c2f54 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-12-09 18:00:42 +09:00
Swift Coder
cbdff4a5f8 Add profile info text in stretchable banner with follow button
Changelog-Added: Add profile info text in stretchable banner with follow button
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-09 17:58:16 +09:00
Swift Coder
866afe970b Paste Gif image similar to jpeg and png files
This commit change will allow users to paste GIF file in the Post by copying from other apps (previously similar to pasting Jpeg and PNG image functionality)

Changelog-Added: Paste Gif image similar to jpeg and png files
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-09 16:46:40 +09:00
transifex-integration[bot]
87efc91527 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-03 18:18:41 +09:00
4121526588 Export strings for translation
Signed-off-by: Terry Yiu <963907+tyiu@users.noreply.github.com>
2024-12-03 18:18:41 +09:00
4adcb738a2 Replace non-breaking spaces with regular spaces as Apple's NSLocalizedString macro does not seem to work with it
Changelog-Fixed: Replace non-breaking spaces with regular spaces as Apple's NSLocalizedString macro does not seem to work with it

Signed-off-by: Terry Yiu <963907+tyiu@users.noreply.github.com>
2024-12-03 18:18:41 +09:00
1f17f19a6e Fix localization issues in RelayConfigView
Changelog-Fixed: Fixed localization issues in RelayConfigView

Signed-off-by: Terry Yiu <963907+tyiu@users.noreply.github.com>
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
fb54115286 Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
50dd35d089 Translate Localizable.strings in vi
100% translated source file: 'Localizable.strings'
on 'vi'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
1205b2a0e2 Translate Localizable.strings in ar
100% translated source file: 'Localizable.strings'
on 'ar'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
0a93e909ed Translate InfoPlist.strings in ar
100% translated source file: 'InfoPlist.strings'
on 'ar'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
6f3f928ac3 Translate InfoPlist.strings in bg
100% translated source file: 'InfoPlist.strings'
on 'bg'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
637ceabede Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
c25f54f7e7 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
d4ae0b1346 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
7773618547 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
a4199fa299 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
5b9ccc4ee5 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
f538e03093 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
e625297a2e Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
e603678872 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-12-03 18:18:41 +09:00
transifex-integration[bot]
9d77f1b2f7 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-12-03 18:18:41 +09:00
c4f7d25793 Fix localization issues and export strings for translation 2024-12-03 18:18:41 +09:00
transifex-integration[bot]
100f195a03 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-12-03 18:18:41 +09:00
Swift Coder
e599ef1ac9 Fix duplicate uploads
Reset orderIds and orderMap

Changelog-Fixed: Fix duplicate uploads
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-03 17:31:55 +09:00
Swift Coder
033c69b92e Remove duplicate pubkey from Follow Suggestion list
Changelog-Fixed: Remove duplicate pubkey from Follow Suggestion list
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-02 15:43:02 +09:00
Swift Coder
184e566b1b Fix Page control indicator for not reflecting current index of Image being previewed
Changelog-Fixed: Fix Page control indicator
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-12-02 15:27:14 +09:00
Swift Coder
8c321e479b Fix Damus sharing issues
1. While sharing images/videos from Apple's Message app, the file will be treated as a Link with file-url. The if-else ordering will help to fix the issue.
2. While sharing image from Signal and Facebook app, the file being received is an UIImage and error is being sent. This PR fixes the issue.

Changelog-Fixed: Fix damus sharing issues
Signed-off-by: Swift Coder  <scoder1747@gmail.com>
2024-12-02 15:22:13 +09:00
Daniel D’Aquino
960c84d02e Fix CHANGELOG markdown syntax issue
Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-22 11:49:19 -08:00
Daniel D’Aquino
02f1c2d342 Add script to help identify duplicate changelog entries
This commit adds a new script to devtools that can be used to help
identify duplicate changelog entries.

It works by identifying duplicate lines in CHANGELOG.md, and then
searching whether each one of those duplicate lines are present in a
separate text file (which can be a subset of the changelog that the user
is interested in analyzing)

No user-facing changes

Changelog-None
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-22 11:42:35 -08:00
Daniel D’Aquino
c8ca3c93f6 Changelog entry for 1.11(10)
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-22 11:42:35 -08:00
Daniel D’Aquino
5c6e5ca2de Add edit banner button UI automated test + accessibility improvements
This commit adds an automated UI test to check if the edit banner button
UI is clickable and not hidden behind a top bar or another invisible
element.

It also improves accessibility support for some elements on login and
top bar.

Changelog-Changed: Improved accessibility support on some elements
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-20 14:44:06 -08:00
Daniel D’Aquino
e3105a90c5 Move edit banner button into safe area
In some conditions, it was found that the banner edit button was
obscured behind a top nav bar.

This commit fixes that by introspecting on the safe area margins and
applying them to the button

Closes: https://github.com/damus-io/damus/issues/2636
Changelog-Fixed: Fixed issue where banner edit button is unclickable
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-20 14:44:06 -08:00
Daniel D’Aquino
38dc7b046a Fix issues with new Share extension
This commit fixes the following issues with the new Share extension:
- Typo on user-facing label
- Misconfigured Info.plist that caused the build to be rejected by AppStore Connect

This extension was never shipped to users, so no changelog entry is needed.

Changelog-None
Fixes: eeb6547d3e
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-18 11:43:24 -08:00
Daniel D’Aquino
da76ad9b66 Fix logical merge error
This commit fixes build errors caused by logical merge issues from
changes that worked in isolation but not when combined.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-18 10:32:09 -08:00
Swift Coder
177c55cf3d Fix missing tab bar while navigating
Set isSidebarVisible to false

Changelog-Fixed: missing tab bar on navigation
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-11-15 17:17:10 -08:00
Swift
eeb6547d3e Add Damus Share Feature
This PR change adds Damus Share feature to the app that allows the users to share Photos and URLs from foreign apps.

Changelog-Added: Add Damus Share Feature

Signed-off-by: Swift Coder  <scoder1747@gmail.com>
2024-11-15 17:08:44 -08:00
Daniel D’Aquino
50ef6600a8 Make QR code scanning more robust
1. Removed the dependency on finding the profile event for displaying actions to the user, even if the full profile couldn't be loaded. This allowed showing useful options such as the option to follow that pubkey.
2. Opened a profile preview sheet instead of navigating to the full profile page, enabling quick actions and saving bandwidth by not loading their timeline immediately.
3. Refactored most of that view to simplify state management and make it less prone to errors.
4. Improved error handling and management.
5. Ensured the view truly reflected the internal state of the scanner to the user.

Changelog-Fixed: Fixed some issues where QR code would not work, and improved UX
Closes: https://github.com/damus-io/damus/issues/2032
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-15 15:41:04 -08:00
Daniel D’Aquino
be43819de2 Update and refactor ImageCarousel fill handling
Previously, the ImageCarousel needed to directly set a video size
binding to the video player view, in order to communicate and listen to
video size changes, and it used that to calculate the carousel image fill.

However, in the new video coordination architecture, the video size is
not owned by the ImageCarousel, but instead it is owned by the video
player itself, which in turn is owned by the video coordinator.
Therefore, this is incompatible with several logic elements of
ImageCarousel.

This commit updates the image carousel to integrate with the new video
coordinator architecture, and it also refactors the image fill logic
almost completely — with a focus on reducing stateful behavior by
carefully employing some state management patterns.

Furthermore, the new CarouselModel was heavily documented to explain its
design decisions and inner workings.

Note: There used to be some caching on the ImageFill calculations, but
after using this new refactored version without caching, I have not
noticed any noticeable performance regressions, so I have decided not to
add them back — applying Occam's razor

Changelog-Changed: Improved image carousel image fill behavior
Closes: https://github.com/damus-io/damus/issues/2458
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Daniel D’Aquino
58017952bc Video coordination improvements and new video controls view
This commit makes several improvements to video coordination,
and implements a new video control view.

The video support stack in Damus has been re-architected to achieve
this.

The new architecture can be summarized as follows:
1. `DamusVideoCoordinator` is a singleton object in `DamusState`, and it
   is responsible for deciding which video should have the "main stage"
   focus, based on main stage requests that video player views make when
   they become visible.

   Having "main stage" focus means that the coordinator will auto-play
   that video and pause others, and is used throughout the app to
   determine which video to talk to or control, in the case of app-wide
   controls (analogous to how Apple Music needs to know which song is
   playing for displaying playback controls on the iOS home screen)

   Having a singleton take care of this establishes
   clear ownership and prevents conflicts such as double-playing video.

   This coordinator also holds a pool of video media items (`DamusVideoPlayer`),
   with exactly ONE `DamusVideoPlayer` per URL, to reduce
   bandwidth and ensure perfect syncing of the same video in different
   contexts.

2. `DamusVideoPlayer` objects hold the actual media item (video data, playback state),
   much like `AVPlayer`.
   In fact, `DamusVideoPlayer` can be described as a wrapper for `AVPlayer`,
   except it has an interface that is much more SwiftUI friendly,
   enabling playback state syncing with minimal effort.

   `DamusVideoPlayer` is NOT a view. And there is only ONE `DamusVideoPlayer`
   per URL — held by the coordinator.
   However, when the app needs to display that same video in multiple
   places, the app can instantiate multiple video player VIEWS of the
   same `DamusVideoPlayer`

3. `DamusVideoPlayer.BaseView` is the most basic video player view for a
   `DamusVideoPlayer` item. It has basically no features other than
   showing the video itself.

4. `DamusVideoPlayerView` is the standard, batteries-included, video
   player view for `DamusVideoPlayer` items, that is used throughout the
   app.

   It also tries to detect its own visibility, and makes requests to
   `DamusVideoCoordinator` to take over the main stage when it becomes
   visible.

5. `DamusVideoControlsView` is a view that presents video playback
   controls (play/pause, mute, scrubbing) for a `DamusVideoPlayer`
   object.

How a `DamusVideoPlayerView` gains and loses main stage focus:
1. `DamusVideoPlayerView` uses `VisibilityTracker` to find out when it
   becomes visible or not
2. When it becomes visible, it makes a request to the video coordinator
   to take main stage focus. The request also specifies which layer the
   video view is in (Full screen layer? Normal app layer?), which the
   video player view gets from the `\.view_layer_context` environment
   variable set by `damus_full_screen_cover`
3. The coordinator (`DamusVideoCoordinator`) keeps all of these
   requests, and uses its own internal logic and info to determine which
   video should get the main stage.
   The logic also depends on whether or not the app finds itself in full
   screen mode.
   Once the main stage is given to a different video, the previous video
   is paused, the main-staged-video is played, and the requestor
   receives a callback.
4. Once the video disappears from view, it tells the coordinator that it
   is giving up the main stage, and the coordinator then picks another
   main stage request again.

On top of this, several of other small changes and improvements were made,
such as video gesture improvements

Note: This commit causes some breakage over the image carousel sizing
logic, which will be addressed separately in the next commit.

Changelog-Fixed: Fixed iOS 18 gesture issues that would take user to the thread view when clicking on a video or unmuting it
Changelog-Fixed: Fixed several issues that would cause video to automatically play or pause incorrectly
Changelog-Fixed: Fixed issue where full screen video would disappear when going to landscape mode
Changelog-Added: Added new easy to use video controls for full screen video
Changelog-Changed: Improved video syncing and bandwidth usage when switching between timeline video and full screen mode
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Daniel D’Aquino
409be7fc58 Refactor visibility tracker
This commit moves all logic related to visibility tracking into a single
view modifier for better code reusability.

Furthermore, the modified VisibilityTracker component was more
extensively documented, for better awareness of its limitations and
usage.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Daniel D’Aquino
1bc660c9cd Improve full screen support
This commit introduces new mechanisms to solve some issues with full screen support:
1. Full screen covers disappear when its caller disappears (e.g. when it
   is an event in a lazy stack, and an orientation change causes the
   view to disappear along with the full screen cover)
2. There are no mechanisms for views to determine whether they are being
   presented under a full screen cover or not, and whether the device is
   in full screen mode or not.

The commit overcomes the above limitations through the following:
1. A full screen cover on `ContentView` that can be accessed by any view
   when calling `present(fullScreenItem)`
2. A new `damus_full_screen_cover` view modifier that automatically
   tracks whether a device is in full screen mode or not, and allows
   any descendant view in its hierarchy to introspect on which view
   layer it is being presented in.

This commit lays a foundation that will later become important for
improving video coordination.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Daniel D’Aquino
a56a59f81d Improve SwipeToDismiss modifier UX
This commit adds an opacity transition when swiping to dismiss an item,
to make it clear that the user is about to dismiss it.

Changelog-Changed: Swipe to dismiss on full screen carousel now shows an opacity effect for improved UX
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Daniel D’Aquino
1d5af6ca5c Remove event details from full screen carousel
Changelog-Changed: Removed event contents from full screen media carousel for cleaner view
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Daniel D’Aquino
f81b2b677f Fix portrait video sizing on full screen carousel
Changelog-Fixed: Fixed portrait video size on full screen carousel
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Daniel D’Aquino
290152c859 Rename VideoController to DamusVideoCoordinator
This commit renames this class to better represent what it does.

This reduces some of the term overloading between this class and other video
controller classes/structs. (Such as AVPlayerController)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-11-11 15:30:17 -08:00
Swift
c4ee52fdac Add sharing option in image carousel view (#2629)
Add share button in Full screen image carousel view images

The ellipsis (share button) allows you to share the current image being displayed in the full screen carousel viewer.

Changelog-Changed: Add share button for images on full screen image carousel view
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-11-11 14:36:27 -08:00
Swift Coder
6f04455350 Add Edit, Share, and Tap-gesture in Profile pic image viewer
Add Edit button that navigates onto Profile Page
Add ShareLink button that allows us to Share actual image
Add Tap gesture in profile pic image viewer

Changelog-Added: Add Edit, Share, and Tap-gesture in Profile pic image viewer
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-11-04 13:22:57 -08:00
Daniel D’Aquino
3b62945e5b Revert "fix: regression that dropped q tags from quote reposts"
This reverts commit 5865b000c0.
2024-11-01 11:25:24 -07:00
Swift Coder
b1b032d905 postview: add hashtag suggestions
Closes: #2604
Changelog-Changes: Add hashtag suggestions to post view
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-10-28 11:49:47 -07:00
Swift Coder
7c805f7f23 fix: avatar image on qrcode view
Closes: #2612
Changelog-Fixed: Fix avator image on qrcode view
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-10-28 11:45:45 -07:00
Swift Coder
a2b0620175 fix: banner image upload
There was a nostr.build auth issue when uploading banner images. This
fixes that.

Closes: #2614
Changelog-Fixed: Fix banner image uploa
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-10-28 11:45:45 -07:00
William Casarin
8c6bee3d90 Merge remote-tracking branch 'github/pr/2622' 2024-10-28 11:40:16 -07:00
ericholguin
bba651b37c ui: reduce bold font in side menu
This PR simply reduces the bold font in the side menu labels.

Changelog-Changed: Changed boldness of font in side menu labels.

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-26 21:55:28 -06:00
ericholguin
f657af275a ui: replace search notes button with searched word
This PR replaces the search notes button with the searched word.
This also removes the magnifying glass image from the search buttons.

Closes: #2601

Changelog-Changed: Changed search notes button with searched keyword

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-26 21:36:59 -06:00
William Casarin
03ded7d39f Merge Translations #2603
Terry Yiu (1):
      Fix localization issues and export strings

Transifex (5):
      Translate Localizable.strings in th
      Translate Localizable.strings in ja
      Translate Localizable.strings in ja
      Translate Localizable.strings in nl
      Translate Localizable.strings in hu_HU
2024-10-26 11:35:49 -07:00
William Casarin
53edc7eb0b Merge 'fix: Fix overlap in Universe view' #2607
ericholguin (1):
      fix: Fix overlap in Universe view
2024-10-26 11:34:43 -07:00
William Casarin
8b969021d5 Merge 'ux: increase opacity of tabbar and post button' #2608
ericholguin (1):
      ux: increase opacity of tabbar and post button
2024-10-26 11:33:46 -07:00
William Casarin
1e52982a5d Merge 'fix: regression that dropped q tags from quote reposts' #2617
William Casarin (2):
      fix: regression that dropped q tags from quote reposts
2024-10-26 11:30:50 -07:00
William Casarin
0038d42f71 Merge 'dismiss button in full screen carousel' #2611
Swift Coder (2):
      Fix: dismiss button in full screen carousel
      Address PR Feedback
2024-10-26 11:25:27 -07:00
Swift Coder
d94b387fb9 Address PR Feedback
Use Switch statement to address all cases instead of if-else

Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-10-25 16:17:17 -04:00
Swift Coder
8a2dbc95ca Fix: dismiss button in full screen carousel
This updates the dismiss button on the fullscreen carousel
so that it is more visible in some scenarios.

Changelog-Fixed: Fix dismiss button visibility
Signed-off-by: Swift Coder <scoder1747@gmail.com>
2024-10-25 00:37:44 -04:00
William Casarin
5865b000c0 fix: regression that dropped q tags from quote reposts
It looks like some refactor broke q tags on quote reposts. This drops
the gather_quote_tags entirely and just relies on the logic in
build_post.

The references field wasn't being used for anything other than pubkeys,
so we switch to pubkeys directly.

Changelog-Fixed: Fix quote repost counting
Signed-off-by: William Casarin <jb55@jb55.com>
2024-10-24 15:31:02 -07:00
transifex-integration[bot]
6efb512a64 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-10-22 11:14:57 +00:00
ericholguin
b7b8c7f175 ux: increase opacity of tabbar and post button
This PR simply increases the opacity of the tabbar and post button.
The increase in opacity makes the post button active.

Closes: #2598
Closes: #2599

Changelog-Changed: Changed opacity of tabbar and post button

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-21 19:25:40 -06:00
ericholguin
a76e2aa677 fix: Fix overlap in Universe view
This PR fixes the overlapping text in the Universe View.

Changelog-Fixed: Fixed overlapping text in Universe View

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-21 18:18:05 -06:00
William Casarin
d9f2317728 Merge 'Maintain images preview as per the selection order' from 'github/pr/2595'
Swift Coder (2):
      Maintain images preview as per the selection order
      document
2024-10-21 09:44:19 -07:00
transifex-integration[bot]
f1339e835b Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-10-21 08:32:58 +00:00
transifex-integration[bot]
64f2362be3 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-10-21 01:49:49 +00:00
5b184a40fd Fix localization issues and export strings
Changelog-Fixed: Fixed localization issues and exported strings

Signed-off-by: Terry Yiu <963907+tyiu@users.noreply.github.com>
2024-10-20 23:00:33 +02:00
transifex-integration[bot]
17e6191a92 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-10-17 17:32:04 +02:00
transifex-integration[bot]
1ff065d4c7 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-10-17 17:32:03 +02:00
Swift Coder
94e2c76284 document 2024-10-17 11:27:03 -04:00
Swift Coder
1925af6897 Maintain images preview as per the selection order 2024-10-17 11:23:02 -04:00
William Casarin
4effaa4324 Merge 'Side menu redesign' from 'github/pr/2569' into master
ericholguin (1):
      ui: Side menu redesign
2024-10-16 09:14:42 -07:00
William Casarin
e2a4443a9c Merge 'Fix padding for views for tabbar' from github/pr/2589 2024-10-16 09:09:24 -07:00
William Casarin
7c0e1c5ded Merge multiple image uploads
Changelog-Changed: Allow multiple images to be uploaded at the same time (swiftcoder)
2024-10-16 08:55:31 -07:00
William Casarin
f6e34ad999 Merge 'Fix sensitive chat bubble on iOS 18' 2024-10-16 08:47:39 -07:00
Swift Coder
ca5da7b5cd Ensures the order in which they were picked (with numbered badge selection) 2024-10-15 22:47:21 -04:00
Swift Coder
c08e4a2fdd Documenting 2024-10-15 10:48:48 -04:00
Swift Coder
37a50f6087 addressed upload issue in pr feedback 2024-10-15 10:43:32 -04:00
ericholguin
2040e79165 ui: Side menu redesign
This PR redesigns the side menu to more closely match Roberto's design

Changelog-Changed: Changed side menu design

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-14 19:21:57 -06:00
Daniel D’Aquino
a6449020b6 Fix sensitive chat bubble on iOS 18
This commit fixes an issue with the chat bubble view where it would
unexpectedly trigger the reaction emoji keyboard when scrolling or
swiping, which became specially sensitive on iOS 18.

The fix consists of 2 parts:
- Changing the long press gesture logic to better adhere to Apple's API specs
- Modify the SwipeActions library to allow the gesture priority to be
  configurable, and demote the swiping gesture to have normal priority
  (it was found that having a high-priority drag gesture prevents
  long-presses from being activated)

Closes: https://github.com/damus-io/damus/issues/2577
Changelog-Fixed: Fix sensitive long-press gesture on event chat bubble in iOS 18
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-10-14 18:20:44 -07:00
ericholguin
75a46f4ab4 fixes: Fix padding for views for tabbar
This PR fixes the bottom padding on views to account for the bottom tabbar,
now that the tabbar is an overlay we must account for it.

Changelog-Fixed: Fixed bottom padding for tabbar

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-14 19:07:01 -06:00
William Casarin
c948c7e230 search: truncate content
sometimes its too big for search results

Changelog-Changed: Truncate fulltext search results
Signed-off-by: William Casarin <jb55@jb55.com>
2024-10-14 12:08:25 -07:00
William Casarin
c83b0fba21 Merge 'paste images' support
Swift Coder (3):
      Allow-pasting-image-option
      Documenting
      Code optimization
2024-10-13 15:40:52 -07:00
William Casarin
b7053e8680 Merge 'ux: Seamless Timeline'
ericholguin (1):
      ux: Seamless Timeline
2024-10-13 15:14:40 -07:00
Swift Coder
17183632c8 Multiple images upload 2024-10-11 12:50:26 -04:00
Swift Coder
686d6d6e92 Code optimization 2024-10-08 17:05:04 -04:00
Swift Coder
847ae7b396 Documenting 2024-10-08 14:45:34 -04:00
Swift Coder
ba9780fb17 Allow-pasting-image-option 2024-10-08 13:52:30 -04:00
transifex-integration[bot]
42f5af0ffd Translate Localizable.strings in es_ES
100% translated source file: 'Localizable.strings'
on 'es_ES'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
55f1330fc1 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
4b326340a3 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
83f7766833 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
1e3b20f5b3 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
e508f28f7d Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
2c139863b8 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
c699409129 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
74e6d8781a Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
876f9c742f Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
1e7b57eaf3 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-10-04 12:20:28 -07:00
5615b1e1ec Fix localization build failures
Changelog-Fixed: Fixed localization build failures
Signed-off-by: Terry Yiu <963907+tyiu@users.noreply.github.com>
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
9d66a5ed4f Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-10-04 12:20:28 -07:00
transifex-integration[bot]
5555f1afec Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-10-04 12:20:28 -07:00
ericholguin
77b1b895a5 ux: fix navigation placement in profile edit view
This PR fixes the issue with the placement of the back navigation button in the profile edit view for iOS 18 devices:

Changelog-Fixed: Fixed back nav button placement in profile edit view

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-04 10:29:31 -07:00
ericholguin
6751bc15cc ux: Seamless Timeline
This PR is a ux change to make the header, tabbar, and post button disappear when the user scrolls.
The main tabbar is now an overlay which means it will display over views, this was needed in
order to get the timeline to extend behind it. However, this mean we must add bottom padding to any
view where the main tabbar is present to account for the overlap.

Changelog-Added: Disappearing header, tabbar, and post button on scroll

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-10-01 17:32:56 -06:00
William Casarin
735fa97089 Merge remote-tracking branch 'github/translations'
Transifex (11):
      Translate Localizable.strings in th
      Translate Localizable.strings in th
      Translate Localizable.strings in th
      Translate Localizable.strings in de
      Translate Localizable.strings in zh_CN
      Translate Localizable.strings in zh_HK
      Translate Localizable.strings in zh_HK
      Translate Localizable.strings in zh_TW
      Translate Localizable.strings in de
      Translate Localizable.strings in de
      Translate Localizable.strings in de
2024-09-27 13:55:17 -07:00
William Casarin
314774f032 fixup: 128 instead of 500
500 is excessive

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-27 13:52:58 -07:00
William Casarin
262bbf26ea profiles: expand search results to 128
This should be plenty

Fixes: https://github.com/damus-io/damus/issues/2547
Changelog-Changed: Expanded profile search results to 128
Changelog-Fixed: Friend profiles will now more likely show up in profile search
Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-27 13:51:08 -07:00
transifex-integration[bot]
cdf8d043c9 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-09-27 20:30:09 +00:00
transifex-integration[bot]
1eb7c94a5a Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-09-27 20:26:31 +00:00
William Casarin
5228d8cf4d Merge 'Add PR template with checklist #2548'
Daniel D’Aquino (1):
      Add PR template with checklist
2024-09-27 12:45:40 -07:00
William Casarin
782779f0d7 Merge 'v1.10.1 changelog #2494'
Daniel D’Aquino (1):
      v1.10.1 changelog
2024-09-27 12:44:21 -07:00
William Casarin
18ec8e6b6c Merge 'ui: add ndb search to universe view #2464'
William Casarin (3):
      search: use lazyvstack
      search: expand search results to 128

ericholguin (1):
      ui: add ndb search to universe view
2024-09-27 12:41:53 -07:00
William Casarin
7d82d8b76f search: expand search results to 128
This continues our hack due to the way the compiler bridges to static
sized arrays. yes its horrible. no i don't care.

Changelog-Changed: Expand nostrdb text search results to 128 items
Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-27 12:37:53 -07:00
William Casarin
f957756df7 search: use lazyvstack
we're gonna need this when expanding search results

Changelog-Changed: Use LazyVStack in text search results
Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-27 12:37:21 -07:00
Daniel D’Aquino
2cb0553723 Add PR template with checklist
This adds a PR template that will be applied to every new pull request,
to help both contributors and reviewers make sure that the contribution
guidelines are being met.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-25 12:29:16 -07:00
Daniel D’Aquino
8464e151cc v1.10.1 changelog
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-25 11:48:33 -07:00
Daniel D’Aquino
2da444e7c2 Merge branch 'release_1.10' 2024-09-25 11:19:38 -07:00
2a19d5d831 Add Apple translation popovers for notes for iOS 17.4+ and macOS 14.4+
Changelog-Added: Add Apple translation popovers for notes for iOS 17.4+ and macOS 14.4+
2024-09-23 20:14:31 -07:00
Daniel D’Aquino
f92509fddf Version bump to 1.10.1
This is needed because we already have a 1.10 build approved by Apple,
and they require a version number bump

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-22 13:32:33 -07:00
William Casarin
51ee4046a0 Merge ios18-release_1.10 fixes
Pull some things from the 1.10 release branch into master:

Daniel D’Aquino (1):
      Fix unclickable elements

William Casarin (4):
      relays: add some ping/pong and connection logs
      relay: don't reconnect when we don't have to
2024-09-22 10:29:36 +09:00
William Casarin
1e85bb946d Merge 'ios18-fixes-round1' into 'release_1.10'
Merge some additional ios18 fixes

Daniel D’Aquino (1):
      Fix unclickable elements

William Casarin (3):
      relays: add some ping/pong and connection logs
      relay: don't reconnect when we don't have to
2024-09-22 10:22:45 +09:00
William Casarin
6639c002ed relay: don't reconnect when we don't have to
We are reconnecting multiple times for two separate reasons:

1. On a cancellation "error" which does not warrant a reconnect

2. In our reconnection backoff it doesn't check If we are already
   connecting or connected. We check this so we don't reconnect multiple
   times.

This fixes many reconnection issues and makes Damus feel wayyy snappier.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-22 09:06:02 +09:00
William Casarin
2a61440aed relays: add some ping/pong and connection logs
need this for debugging connection issues

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-22 09:06:02 +09:00
Daniel D’Aquino
823c2565da Fix unclickable elements
The introduction of iOS 18 brought a new bug that made `KFAnimatedImage`
not recognize tap gestures and become unclickable. (https://github.com/onevcat/Kingfisher/issues/2295)

This commit addresses the issue with a workaround found here:
https://github.com/onevcat/Kingfisher/issues/2046#issuecomment-1554068070

The workaround was suggested by the author of the library to fix a
slightly different issue, but that property seems to work for our
purposes.

The issue is addressed by adding a `contentShape` property to usages
of `KFAnimatedImage`, in order to make them clickable. A custom modifier
was created to make the solution less obscure and more obvious.

Furthermore, one empty tap gesture handler was removed as it was
preventing other tap gesture handlers on the image carousel from being
triggered on iOS 18

Testing
-------

PASS

Configurations:
- iPhone 13 mini on iOS 18.0
- iPhone SE simulator on iOS 17.5
Damus: This commit
Coverage:
- Check that the following views are clickable:
    - Images in the carousel
    - Profile picture on notes
    - Profile picture on thread comments
    - Profile picture on profile page

Changelog-Fixed: Fix items that became unclickable on iOS 18
Closes: https://github.com/damus-io/damus/issues/2342
Closes: https://github.com/damus-io/damus/issues/2370
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-20 20:02:24 -07:00
Daniel D’Aquino
b5a81e2586 Merge branch 'release_1.10' 2024-09-18 19:14:07 -07:00
Daniel D’Aquino
6254cea600 Improve notification view filtering UX
- Add subtitle below the toolbar title to indicate the state of the filter
- Add settings icon to take user to the notification settings page, and
  thus make that more discoverable

Testing
-------

PASS

Device: iPhone 13 mini
iOS: 17.6.1
Coverage:
1. Switching back and forth between the notifications tab and other tabs
   causes subtitle to show/hide as expected in both filter options
   (all, friends)
2. Subtitle follows the friends filter
3. Subtitle shows after restarting the app
4. Settings icon appears and takes user to the notification setting view
5. Notification settings can be updated from that view.

Changelog-Changed: Improve notification view filtering UX
Closes: https://github.com/damus-io/damus/issues/2480
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-18 18:31:11 -07:00
Daniel D’Aquino
ce63f6a96b Make friends filter button more visible
This commit changes the appearance of the friends filter button to make it more visible

Testing:
- Checked appearance in both light mode and dark mode
- Checked appearance in all usages (notifications view and DM view)
- Checked consistency against the filter button in Universe view

Changelog-Changed: Improve visibility of friends filter button
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-18 18:31:11 -07:00
cr0bar
6fa2e8b5c6 Fix issue where theme would be changed to black and can't be switched back on iOS 18
Removed line which forces preferred colour scheme to dark on iOS 18, and
made adjustments to the styling to maintain text legibility

Changelog-Fixed: Fixed issue where theme would be changed to black and can't be switched back on iOS 18
Closes: https://github.com/damus-io/damus/issues/2373
Co-authored-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-18 17:50:44 -07:00
Daniel D’Aquino
2278ab09a4 Improve local contact list handling
Unless the user signed up after changes from Github issue #2057, the contact list delegate would never be set due to a logic error, which means latest_contact_event_changed would never get called and the app would never save a local contact list reference to pull from — which caused issues when switching to different relays.

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.5
Setup: Manually removed UserSettingsStore::latest_contact_event_id_hex value to replicate the entry condition for the bug
Steps:
1. Add new relay (relay.zap.store)
2. Remove all other relays
3. Attempt to add relay. Ensure new relay can be added
4. Remove all relays
5. Add the `wss://notify-staging.damus.io` relay (which will not save any events)
6. Restart app
7. Try to add a new relay. Ensure a new relay can be added
8. Make a test post. Ensure the new test post is posted successfully.

Changelog-Fixed: Fixed some scenarios where the contact list would never be saved locally and cause issues when switching relays.
Closes: https://github.com/damus-io/damus/issues/2293
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-18 16:58:43 -07:00
Daniel D’Aquino
dfa72fceb1 Fix unit test build
A change around the NostrPost interfaces caused unit tests to fail
compilation. This commit fixes that.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-13 15:57:55 -07:00
ericholguin
62772615b6 ui: add ndb search to universe view
This PR adds the NDB search functionality from the pull down search in the
posting timeline to the universe view.

Changelog-Added: Added NDB search functionality to the universe view

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-09-11 20:34:24 -06:00
Daniel D’Aquino
9e0b9debb4 Improve local contact list handling
Unless the user signed up after changes from Github issue #2057, the contact list delegate would never be set due to a logic error, which means latest_contact_event_changed would never get called and the app would never save a local contact list reference to pull from — which caused issues when switching to different relays.

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.5
Setup: Manually removed UserSettingsStore::latest_contact_event_id_hex value to replicate the entry condition for the bug
Steps:
1. Add new relay (relay.zap.store)
2. Remove all other relays
3. Attempt to add relay. Ensure new relay can be added
4. Remove all relays
5. Add the `wss://notify-staging.damus.io` relay (which will not save any events)
6. Restart app
7. Try to add a new relay. Ensure a new relay can be added
8. Make a test post. Ensure the new test post is posted successfully.

Changelog-Fixed: Fixed some scenarios where the contact list would never be saved locally and cause issues when switching relays.
Closes: https://github.com/damus-io/damus/issues/2293
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-11 16:24:54 -07:00
Daniel D’Aquino
3902fe7b30 Enable push notifications feature for everyone and set notification mode to push
This commit hardcodes the push notification feature flag to true, in
preparation for purple testflight release.

It also changes the notification mode setting string, to ensure that we
won't have issues with people being stuck with local notification mode.

Testing
-------

Steps:
1. Run app
2. Ensure push notification flag is gone from developer Settings
3. Ensure notification mode is set to push, and that the push option is available
4. Ensure push notification settings appear as "synced successfully"

Conditions:
- iPhone 13 mini, iOS 17.6.1, on a device that was already under testing
- iPad simulator, iOS 17.5, brand new account

Changelog-Added: Push notification support
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-06 14:29:19 -07:00
William Casarin
471bb4638a Merge 'Add localization data to extensions' into release_1.10
Daniel D’Aquino (1):
      Add localization data to extensions
2024-09-06 09:15:57 -07:00
transifex-integration[bot]
8c5b0ed5c4 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-09-06 07:19:26 +00:00
Daniel D’Aquino
379de6ff8e Merge branch 'release_1.10' 2024-09-05 20:08:51 -07:00
William Casarin
cb241741e3 notifications: add more logging
needed this to debug stuff

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-05 20:02:07 -07:00
William Casarin
1dbf7101b9 notifications: add support for tagged mentions
These are text notes that have you tagged but do not have inline
mentions or are replies.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-05 20:02:07 -07:00
William Casarin
d9bbca1005 notifications: don't fail if we don't have display_name
This isn't even a standard field anyways

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-05 20:02:07 -07:00
William Casarin
d2acf61e5a Merge 'Add localization data to extensions'
Daniel D’Aquino (1):
      Add localization data to extensions
2024-09-05 16:41:51 -07:00
Daniel D’Aquino
d6898c77d8 Add localization data to extensions
This commit links localization data to the extension targets so that
those targets can successfully localize data

Testing
-------

PASS

Device: iPhone 13 Mini
Damus: This commit
iOS: 17.6.1
Setup:
- Staging environment
- Push notifications enabled and configured
Steps:
1. Send a zap without message to the device with push notifications setup
2. Ensure message appears localized, not a localization key (`zap_notification_no_message`)
3. Change language to Portuguese
4. Make a highlight via the extension. Ensure some or all of the UI elements are localized into Portuguese

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/2419
2024-09-04 17:48:20 -07:00
ericholguin
dd1fdf159b Reapply and rework "ux: Mute selected text"
This commit reapplies the "ux: Mute selected text" commit, with some
manual rework to solve logical conflicts during merge.

Rework testing
--------------

PASS

Device: iPhone 13 Mini
iOS: 17.6.1
Steps:
1. Go to a note
2. Select text and click on the "highlight" button. Ensure that highlight sheet appears with the correct text
3. Select text and click on the "mute" button. Ensure that mute sheet appears with the correct text

Original commit: d663155941
Original author: ericholguin <ericholguin@apache.org>
Reworked-by: Daniel D’Aquino <daniel@daquino.me>
Retested-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-04 12:10:12 -07:00
Daniel D’Aquino
51b1b81c0e Merge branch 'release_1.10' into master 2024-09-04 10:53:59 -07:00
Daniel D’Aquino
da7af491d0 Implement support for reply notification formatting
This commit implements support for nicely formatting reply push
notifications.

Testing
-------

PASS

Device: iPhone 15 simulator
notepush: 11568aa6285142e4c19bb0da30977957a92b7d9b
Damus: This commit
Settings: Local push notification setup
Steps:
1. Create a post from account 1
2. On account 2, make a reply to that post
3. Ensure we get a push notification with:
  - A title formatted as "<ACCOUNT_2_NAME> replied to your note"
  - A body with the contents of that reply
4. Click on that push notification. Ensure you are taken to the reply
5. Now make a post from account 2 and mention account 1 in it
6. Ensure push notification says that account 2 mentioned account 1 (i.e. does not talk about a reply)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/2403
2024-09-04 10:16:55 -07:00
Daniel D’Aquino
90b284fb6e Add option to specify custom push notification server for testing
This commit adds an option that allows a user to choose a custom push
notification server, as well as the staging notify server, to help with testing

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-04 10:16:09 -07:00
William Casarin
c1a89bd617 build: fix versions again 2024-09-01 09:03:26 -07:00
William Casarin
a20f3ab2ab highlighter: fix deploy 2024-09-01 08:57:56 -07:00
William Casarin
7b9d0edef4 highlighter: add missing PostingTimelineView
This was refactored by eric on master, let's make sure we
add it to the highlighter extension build

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-01 07:33:19 -07:00
William Casarin
c22fc8613d Merge Highlighter
This brings Daniel's highlighter safari extension to master/testflight.
Previously we only had it on the 1.10 release branch. This also includes
some extended virtual addressing fixes to fix push notifications, we
also update the push notification server address since that seems to
have been missed.

Daniel D’Aquino (8):
      Update push notification server address
      Add convenience functions
      Simplify SelectableText state management
      Add support for rendering highlights with comments
      Add support for adding comments when creating a highlight
      Add highlighter extension
      Fix highlight tag ambiguity with specifiers
      Improve handling of NostrDB when switching apps

William Casarin (5):
      lmdb: patch semaphore names to use shared group container prefix
      Revert "ux: Mute selected text"
      notifications: add extended virtual addressing entitlement
      highlighter: add extended virtual addressing entitlement
2024-09-01 07:27:32 -07:00
William Casarin
f61308e573 highlighter: add extended virtual addressing entitlement
This is needed for opening nostrdb

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-01 07:23:16 -07:00
William Casarin
d93b04a54c notifications: add extended virtual addressing entitlement
It looks like our push notification service was missing the extended
virtual memory entitlement. This is required to open nostrdb databases.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-01 07:23:16 -07:00
Daniel D’Aquino
4b881e6839 Improve handling of NostrDB when switching apps
There was an issue where profiles on Damus would not load when switching
back and forth between the extension and Damus.

This commit fixes that by closing NostrDB when the extension is backgrounded

Testing
-------

PASS

Device: iPhone 13 Mini
iOS: 17.6.1
Damus: This commit
Steps:
1. Go to a webpage in safari, and open the highlight extension
2. With the highlight extension open, switch apps to Damus (without closing the extension)
3. Make sure profiles can be loaded on Damus

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-01 07:23:16 -07:00
Daniel D’Aquino
63b0661728 Fix highlight tag ambiguity with specifiers
This commit fixes the ambiguity in tags used in highlights with comments, by adding specifiers to help clients understand:
- If a URL reference is the source of the highlight or just a URL mentioned in the comment
- If a pubkey reference is the author of the highlighted content, or just a generic mention in the comment

This tries to be backwards compatible with previous versions of NIP-84.

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.5
Damus: This commit
Steps:
1. Create a new highlight from a webpage using the extension. Tag a user and attach an image
2. Check the newly-created highlight:
  1. Highlight description line should just say "Highlighted", not "Highlighted <username>"
  2. Highlight source link preview should present the URL of the highlighted page, NOT the image URL
3. Inspect the JSON for the newly-created highlight:
  1. "r" tags should include specifiers in the 3rd slot, such as "source" or "mention"
  2. "p" tags should include specifiers in the 3rd slot, such as "mention"
4. Go to an older, generic highlight (without comment) to another nostr event and check the view.
  1. Highlight description line should say "Highlighted <author_name_of_other_event>"
  2. Clicking on the highlight should lead to the highlighted event itself.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-01 07:23:16 -07:00
Daniel D’Aquino
46a66bc69d Add highlighter extension
This commit adds a highlighting extension for web pages. This works on
Safari, and can be used by selecting a text on a page and hitting the
share button at the bottom of the Safari UI

To make this possible, some refactoring was necessary:
1. Several sources were included in the extension bundle to provide access to DamusState, PostView, and the postbox
2. UIApplication.shared was replaced with `this_app`, which routes to UIApplication.shared on the main app bundle,
   and routes to a bogus UIApplication() in the extension. This is needed because UIApplication.shared cannot be used on an extension.
3. Some items were moved to different files to facilitate the transition.

The extension itself uses PostView, and implements views for several edge cases, and tries to handle the note publishing process gracefully.

Changelog-Added: Add highlighter for web pages
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-01 07:23:16 -07:00
Daniel D’Aquino
c09018be48 Add support for adding comments when creating a highlight
Changelog-Added: Add support for adding comments when creating a highlight
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-01 07:23:16 -07:00
Daniel D’Aquino
d71d448ac8 Add support for rendering highlights with comments
This commit implements rendering comments from the `["comment",
<COMMENT_TEXT>]` tag in a highlight note.

Comment contents get rendered like a kind 1 note's "content" field

This commit also adds the `r` "reference" tag as a standard tag reference type

Changelog-Added: Add support for rendering highlights with comments
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-01 07:23:16 -07:00
Daniel D’Aquino
5834e1ee9b Simplify SelectableText state management
This commit simplifies the state management and information flow for SelectableText.

This also fixes issues and inconsistencies with the selected text for a highlight action,
which often appeared in some scenarios with the symptom of a highlight
action showing the incorrect or outdated selected text.

Previously, the state of the selected text and highlight action was
tracked in two independent state/binding variables which caused
re-renders when they were modified, often leading to inconsistencies as
those two independent variables would not be changed atomically across
renders leading to inconsistent, undefined behavior

The commit addresses this by using a single state object instead of two,
and a direct callback interface when the highlight button is pressed,
which eliminates the need of relying on view re-renders to apply.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-01 07:23:16 -07:00
Daniel D’Aquino
d51179189c Add convenience functions
This commit adds a convenience initializer for DamusState that is
simpler than the normal initializer, to allow extensions to more easily
use it.

It also includes a new convenience function for `should_blur_images`

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-09-01 07:23:16 -07:00
William Casarin
b01243b101 Revert "ux: Mute selected text"
I had to revert this for now because it conflicts too heavily
with the highlighter feature which we definitely want in master.

Let's rework this using Daniel's refactor

This reverts commit d663155941.
2024-09-01 07:22:28 -07:00
William Casarin
d2a80cce4e Merge Highlighter into release_1.10
Daniel D’Aquino (7):
      Add convenience functions
      Simplify SelectableText state management
      Add support for rendering highlights with comments
      Add support for adding comments when creating a highlight
      Add highlighter extension
      Fix highlight tag ambiguity with specifiers
      Improve handling of NostrDB when switching apps

William Casarin (4):
      lmdb: patch semaphore names to use group container prefix
      notifications: add extended virtual addressing entitlement
      highlighter: add extended virtual addressing entitlement
2024-09-01 07:00:50 -07:00
William Casarin
0cc9fc1670 highlighter: add extended virtual addressing entitlement
This is needed for opening nostrdb

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-01 06:44:34 -07:00
William Casarin
1279791d65 notifications: add extended virtual addressing entitlement
It looks like our push notification service was missing the extended
virtual memory entitlement. This is required to open nostrdb databases.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-01 06:42:35 -07:00
William Casarin
5d2fc0ed54 lmdb: patch semaphore names to use group container prefix
This is an attempt to fix various issues when acquiring a IPC
semaphore on iOS

See: https://github.com/damus-io/damus/issues/2323#issuecomment-2323181204

Running this patch gives us these names:

mdb_env_setup_locks: using semnames
  'group.com.damus/MDBrwDDi_FHxD' (29),
  'group.com.damus/MDBwwDDi_FHxD' (29)

From old Apple docs:

> IPC and POSIX Semaphores and Shared Memory
>
> Normally, sandboxed apps cannot use Mach IPC, POSIX semaphores and
> shared memory, or UNIX domain sockets (usefully). However, by specifying
> an entitlement that requests membership in an application group, an app
> can use these technologies to communicate with other members of that
> application group.
>
> Note: System V semaphores are not supported in sandboxed apps.
>
> UNIX domain sockets are straightforward; they work just like any other
> file.
>
> Any semaphore or Mach port that you wish to access within a sandboxed
> app must be named according to a special convention:
>
> POSIX semaphores and shared memory names must begin with the application
> group identifier, followed by a slash (/), followed by a name of your
> choosing.
>
> Mach port names must begin with the application group identifier,
> followed by a period (.), followed by a name of your choosing.
>
> For example, if your application group’s name is
> Z123456789.com.example.app-group, you might create two semaphores named
> Z123456789.myappgroup/rdyllwflg and Z123456789.myappgroup/bluwhtflg. You
> might create a Mach port named
> Z123456789.com.example.app-group.Port_of_Kobe.
>
> Note: The maximum length of a POSIX semaphore name is only 31 bytes, so
> if you need to use POSIX semaphores, you should keep your app group
> names short.

Link: https://github.com/damus-io/damus/issues/2323#issuecomment-2323305949
Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-01 06:42:35 -07:00
William Casarin
dcafcd9184 lmdb: patch semaphore names to use shared group container prefix
mdb_env_setup_locks: using semnames
  'group.com.damus/MDBrwDDi_FHxD' (29),
  'group.com.damus/MDBwwDDi_FHxD' (29)

From old Apple docs:

> IPC and POSIX Semaphores and Shared Memory
>
> Normally, sandboxed apps cannot use Mach IPC, POSIX semaphores and
> shared memory, or UNIX domain sockets (usefully). However, by specifying
> an entitlement that requests membership in an application group, an app
> can use these technologies to communicate with other members of that
> application group.
>
> Note: System V semaphores are not supported in sandboxed apps.
>
> UNIX domain sockets are straightforward; they work just like any other
> file.
>
> Any semaphore or Mach port that you wish to access within a sandboxed
> app must be named according to a special convention:
>
> POSIX semaphores and shared memory names must begin with the application
> group identifier, followed by a slash (/), followed by a name of your
> choosing.
>
> Mach port names must begin with the application group identifier,
> followed by a period (.), followed by a name of your choosing.
>
> For example, if your application group’s name is
> Z123456789.com.example.app-group, you might create two semaphores named
> Z123456789.myappgroup/rdyllwflg and Z123456789.myappgroup/bluwhtflg. You
> might create a Mach port named
> Z123456789.com.example.app-group.Port_of_Kobe.
>
> Note: The maximum length of a POSIX semaphore name is only 31 bytes, so
> if you need to use POSIX semaphores, you should keep your app group
> names short.

Link: https://github.com/damus-io/damus/issues/2323#issuecomment-2323305949
Signed-off-by: William Casarin <jb55@jb55.com>
2024-09-01 06:20:11 -07:00
transifex-integration[bot]
8481ab85de Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2024-09-01 08:22:33 +00:00
transifex-integration[bot]
881d3a3aa1 Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2024-09-01 08:17:37 +00:00
transifex-integration[bot]
878509090f Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2024-09-01 08:15:50 +00:00
transifex-integration[bot]
24657ecc75 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2024-09-01 08:08:30 +00:00
Daniel D’Aquino
cf16a9cd10 Improve handling of NostrDB when switching apps
There was an issue where profiles on Damus would not load when switching
back and forth between the extension and Damus.

This commit fixes that by closing NostrDB when the extension is backgrounded

Testing
-------

PASS

Device: iPhone 13 Mini
iOS: 17.6.1
Damus: This commit
Steps:
1. Go to a webpage in safari, and open the highlight extension
2. With the highlight extension open, switch apps to Damus (without closing the extension)
3. Make sure profiles can be loaded on Damus

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-30 10:17:43 -07:00
Daniel D’Aquino
3a9dda5eb3 Update push notification server address
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-28 12:21:16 +03:00
William Casarin
c69ddd7241 Merge 'allow spaces when tagging' into release_1.10
Daniel D’Aquino (1):
      Improve handling of escape characters of mention suggestion menu
2024-08-28 12:16:24 +03:00
William Casarin
bfcb3e4c88 Fix AlbyHub zaps
AlbyHub does not use description hash invoices. We had some code that
looked for zap request invoices inside the description which albyhub
does not do.

Change our code to always get the zap_request from the description.

Changelog-Fixed: Fix albyhub zaps not appearing
Signed-off-by: William Casarin <jb55@jb55.com>
2024-08-28 11:10:03 +03:00
Daniel D’Aquino
27083669fa Improve handling of escape characters of mention suggestion menu
It was noticed that adding a space inadvertently escapes the user
mention suggestion menu (even though several users have an escape
character in their name)

This commit fixes that issue, and improves overall handling of user
mention escape sequences, by allowing those sequences to be made up of
multiple characters instead of a single one.

Testing
-------

Device: iPhone 13 Mini
iOS: 17.6.1
Damus: This commit
Steps:
1. Type normally. Make sure Text editing works normally
2. Try to type a mention with a long name with spaces. Make sure typing
   spaces does not cause the mention suggestions menu to be dismissed.
3. Select a user, make sure mention suggestions menu gets dismissed
4. Try to type a mention with a long name with spaces, but this time
   instead of selecting a user, just add a punctuation mark. Make sure
   the mention suggestions menu gets dismissed
5. Repeat the step above with the following escape sequences:
    1. Newline
    2. Another "@"
    3. ", "
    4. "  " (double-space)
    5. ". "
6. Delete characters all the way back to an existing mention. Make sure
   mention gets broken with a backspace, showing the mention suggestions
   menu once again.
7. Type a mention and select a user
8. Right after the new user mention, with a single space, start typing something
   else ("e.g. @daniel blah"). Make sure that the mention menu does NOT show up when cursor is at the end of "blah"
9. Right after the new user mention, with a single space, start typing a
   mention ("e.g. @daniel @jb"). Make sure the mention menu DOES show
   up, and suggests "@jb55"

Changelog-Fixed: Fix inadvertent escape from mention suggestion menu when typing a space character
Closes: https://github.com/damus-io/damus/issues/2008
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-28 10:56:25 +03:00
William Casarin
aaddbd847a Merge 'Fix AlbyHub zaps'
William Casarin (2):
      Fix AlbyHub zaps
2024-08-28 10:49:54 +03:00
William Casarin
1537501127 Fix AlbyHub zaps
AlbyHub does not use description hash invoices. We had some code that
looked for zap request invoices inside the description which albyhub
does not do.

Change our code to always get the zap_request from the description.

Fixes: https://github.com/damus-io/damus/issues/2363
Changelog-Fixed: Fix albyhub zaps not appearing
Signed-off-by: William Casarin <jb55@jb55.com>
2024-08-28 10:44:44 +03:00
William Casarin
8b020e2bd6 Merge 'Fix broken QR code scanner'
Terry Yiu (1):
      Fix broken QR code scanner and fix landscape mode
2024-08-27 14:24:40 +03:00
William Casarin
ad614f3e42 Merge 'Add nostrcheck'
Quentin (1):
      Remove non-functioning servers,add nostrcheck,NIP96 for all servers
2024-08-27 14:23:55 +03:00
William Casarin
01497d0288 Merge 'Fix push notification DM decryption' 2024-08-27 14:23:24 +03:00
Quentin
eaad552273 Remove non-functioning servers,add nostrcheck,NIP96 for all servers 2024-08-27 11:26:27 +02:00
83ecc3142e Fix broken QR code scanner and fix landscape mode
Changelog-Fixed: Fix broken QR code scanner and fix landscape mode
2024-08-26 22:04:14 +03:00
Daniel D’Aquino
ef4afbc720 Update push notification server address
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-26 11:30:01 -07:00
Daniel D’Aquino
a5cc3aec92 Fix push notification DM decryption
This commit fixes an issue where DM contents would not be displayed on a
push notification, by giving the notification extension access to the
keychain group which contains the user's private key

Testing
--------

PASS

Device: iPhone 13 mini
iOS: 17.6.1
Damus: This commit
Setup:
- Make sure that device is setup with push notifications
- DM notifications enabled
- Device registered with push notification server
Steps:
1. Send a DM push notification to yourself
2. Ensure DM contents can be decrypted on the push notification body

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/2388
2024-08-26 10:02:40 -07:00
transifex-integration[bot]
881ece214d Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-08-24 18:28:10 +00:00
Daniel D’Aquino
2b140d4279 Fix push notification DM decryption
This commit fixes an issue where DM contents would not be displayed on a
push notification, by giving the notification extension access to the
keychain group which contains the user's private key

Testing
--------

PASS

Device: iPhone 13 mini
iOS: 17.6.1
Damus: This commit
Setup:
- Make sure that device is setup with push notifications
- DM notifications enabled
- Device registered with push notification server
Steps:
1. Send a DM push notification to yourself
2. Ensure DM contents can be decrypted on the push notification body

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/2388
2024-08-23 16:43:54 -07:00
Daniel D’Aquino
b43dcd2bc7 Fix highlight tag ambiguity with specifiers
This commit fixes the ambiguity in tags used in highlights with comments, by adding specifiers to help clients understand:
- If a URL reference is the source of the highlight or just a URL mentioned in the comment
- If a pubkey reference is the author of the highlighted content, or just a generic mention in the comment

This tries to be backwards compatible with previous versions of NIP-84.

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.5
Damus: This commit
Steps:
1. Create a new highlight from a webpage using the extension. Tag a user and attach an image
2. Check the newly-created highlight:
  1. Highlight description line should just say "Highlighted", not "Highlighted <username>"
  2. Highlight source link preview should present the URL of the highlighted page, NOT the image URL
3. Inspect the JSON for the newly-created highlight:
  1. "r" tags should include specifiers in the 3rd slot, such as "source" or "mention"
  2. "p" tags should include specifiers in the 3rd slot, such as "mention"
4. Go to an older, generic highlight (without comment) to another nostr event and check the view.
  1. Highlight description line should say "Highlighted <author_name_of_other_event>"
  2. Clicking on the highlight should lead to the highlighted event itself.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-22 14:43:52 -07:00
Daniel D’Aquino
c67a75d740 Improve handling of escape characters of mention suggestion menu
It was noticed that adding a space inadvertently escapes the user
mention suggestion menu (even though several users have an escape
character in their name)

This commit fixes that issue, and improves overall handling of user
mention escape sequences, by allowing those sequences to be made up of
multiple characters instead of a single one.

Testing
-------

Device: iPhone 13 Mini
iOS: 17.6.1
Damus: This commit
Steps:
1. Type normally. Make sure Text editing works normally
2. Try to type a mention with a long name with spaces. Make sure typing
   spaces does not cause the mention suggestions menu to be dismissed.
3. Select a user, make sure mention suggestions menu gets dismissed
4. Try to type a mention with a long name with spaces, but this time
   instead of selecting a user, just add a punctuation mark. Make sure
   the mention suggestions menu gets dismissed
5. Repeat the step above with the following escape sequences:
    1. Newline
    2. Another "@"
    3. ", "
    4. "  " (double-space)
    5. ". "
6. Delete characters all the way back to an existing mention. Make sure
   mention gets broken with a backspace, showing the mention suggestions
   menu once again.
7. Type a mention and select a user
8. Right after the new user mention, with a single space, start typing something
   else ("e.g. @daniel blah"). Make sure that the mention menu does NOT show up when cursor is at the end of "blah"
9. Right after the new user mention, with a single space, start typing a
   mention ("e.g. @daniel @jb"). Make sure the mention menu DOES show
   up, and suggests "@jb55"

Changelog-Fixed: Fix inadvertent escape from mention suggestion menu when typing a space character
Closes: https://github.com/damus-io/damus/issues/2008
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-21 18:02:43 -07:00
chungwwei
7f00ef5d9d Add mute button to ProfileActionSheet
This PR adds mute button to ProfileActionSheet, allowing user to quick mute npubs/bots

Changelog-Added: Added mute button to ProfileActionSheet
Signed-off-by: chungwwei <chungwwei223@gmail.com>
2024-08-21 16:25:29 -07:00
ericholguin
d663155941 ux: Mute selected text
This PR adds the Mute action to the selected text menu. Pressing the mute
action will pop up a sheet which allows users to confirm their selection and
choose for how long they would like to mute the selected text for.

Changelog-Added: Added mute action to selected text menu

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-08-19 17:46:24 -07:00
Eric Holguin
abfe0f642f ux: Profile Edit Improvements (#2376)
This PR adds improvements to the profile edit view.  The banner image is
changed from the old ostrich image to the fresh new damoose. The image and
banner url text entries have been removed from the edit form and now live under
the image selector menu. Selecting the Image URL menu option presents a sheet
where a user can update the image URL. There are now safe guards in place for
users who update their profile, if they make any changes and try to navigate
back to home they will get an alert asking if they want to discard changes. The
Save button is also more prominent.

Changelog-Changed: Changed the default banner from ostriches to damoose
Changelog-Added: Added profile edit safe guards
Changelog-Changed: Changed image and banner url text fields to new sheet view

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-08-19 13:23:00 -07:00
f0b5162205 Fix profile view toolbar alignment bug in iOS 18
Changelog-Fixed: Fix profile view toolbar alignment bug in iOS 18
2024-08-19 13:20:53 -07:00
ericholguin
a9bb2ef98b relay: Add Tor Relay Image
This PR just adds the tor icon to relays ending with .onion

Changelog-Added: Tor relay icon

Closes: #2318
Signed-off-by: ericholguin <ericholguin@apache.org>
2024-08-19 13:20:22 -07:00
Daniel D’Aquino
eff4525720 Implement push notification preferences and update API
This commit implements push notification preferences with the push
notifications server, as well as updates itself to the new push
notifications API.

Testing
-------

Device: iPhone 15 simulator
iOS: 17.5
Damus: this commit
notepush: 3ca3a8325707535fdbc98d681d5e4a47dc313c67
Steps:
1. Enable push notifications. Settings should get synced and success message should appear
2. Disable push notifications. Sync message should disappear as it no longer applies
3. Enable push notifications again, and tweak notifications. Settings should sync with no errors
4. Leave settings screen and come back. Settings should be declared as synced

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/2360
2024-08-19 13:19:46 -07:00
William Casarin
858d9dc6f0 restore localization for custom tabs
Signed-off-by: William Casarin <jb55@jb55.com>
2024-08-19 13:18:53 -07:00
Daniel D’Aquino
55090bc102 Add highlighter extension
This commit adds a highlighting extension for web pages. This works on
Safari, and can be used by selecting a text on a page and hitting the
share button at the bottom of the Safari UI

To make this possible, some refactoring was necessary:
1. Several sources were included in the extension bundle to provide access to DamusState, PostView, and the postbox
2. UIApplication.shared was replaced with `this_app`, which routes to UIApplication.shared on the main app bundle,
   and routes to a bogus UIApplication() in the extension. This is needed because UIApplication.shared cannot be used on an extension.
3. Some items were moved to different files to facilitate the transition.

The extension itself uses PostView, and implements views for several edge cases, and tries to handle the note publishing process gracefully.

Changelog-Added: Add highlighter for web pages
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-17 16:22:26 -07:00
Daniel D’Aquino
40d3d273f0 Add support for adding comments when creating a highlight
Changelog-Added: Add support for adding comments when creating a highlight
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-17 16:22:26 -07:00
Daniel D’Aquino
f9271da11c Add support for rendering highlights with comments
This commit implements rendering comments from the `["comment",
<COMMENT_TEXT>]` tag in a highlight note.

Comment contents get rendered like a kind 1 note's "content" field

This commit also adds the `r` "reference" tag as a standard tag reference type

Changelog-Added: Add support for rendering highlights with comments
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-17 15:58:43 -07:00
Daniel D’Aquino
4f881a5667 Simplify SelectableText state management
This commit simplifies the state management and information flow for SelectableText.

This also fixes issues and inconsistencies with the selected text for a highlight action,
which often appeared in some scenarios with the symptom of a highlight
action showing the incorrect or outdated selected text.

Previously, the state of the selected text and highlight action was
tracked in two independent state/binding variables which caused
re-renders when they were modified, often leading to inconsistencies as
those two independent variables would not be changed atomically across
renders leading to inconsistent, undefined behavior

The commit addresses this by using a single state object instead of two,
and a direct callback interface when the highlight button is pressed,
which eliminates the need of relying on view re-renders to apply.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-17 15:45:18 -07:00
Daniel D’Aquino
9d97886e3f Add convenience functions
This commit adds a convenience initializer for DamusState that is
simpler than the normal initializer, to allow extensions to more easily
use it.

It also includes a new convenience function for `should_blur_images`

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-17 14:24:48 -07:00
Daniel D’Aquino
e70cfbbe63 Fix crash with blurhashes with reported dimension of 0x0
This commit fixes a consistent crash noticed when visiting a particular
profile.

The crash was occuring when trying to display the blurhash of a specific Event, where the metadata claimed the image dimensions were 0px x 0px.

The null dimensions caused a division by zero to occur when scaling the image down, yielding a NaN (Not a Number) size value, which crashed the app when trying to cast that CGFloat value down to an integer.

The crash was fixed by modifying the down-scaling computations to check for invalid dimensions, and return nil. The callers were then updated to fallback to a default display dimension.

Issue repro
-------

Device: iPhone 15 simulator
iOS: 17.5
Damus: dba1799df0
Steps:
1. Visit the profile npub1gujeqakgt7fyp6zjggxhyy7ft623qtcaay5lkc8n8gkry4cvnrzqd3f67z
2. Check accessing the profile does not crash Damus.
3. Visit the event that had invalid 0x0 dimensions on the metadata (note1qmqdualjezamcjun23l4d9xw7529m7fee6hklgtnhack2fwznxysuzuuyz)
4. Check that Damus does not crash.

Results: Steps 2 and 4 crash 100% of the time (3/3)

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.5
Damus: This commit
Steps: Same as repro
Results:
1. Crash no longer occurs
2. Blurhash looks ok

Closes: https://github.com/damus-io/damus/issues/2341
Changelog-Fixed: Fix crash when viewing notes with invalid image dimension metadata
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-13 10:43:24 -07:00
Eric Holguin
8a75537ea3 ux: Profile Edit Improvements (#2376)
This PR adds improvements to the profile edit view.  The banner image is
changed from the old ostrich image to the fresh new damoose. The image and
banner url text entries have been removed from the edit form and now live under
the image selector menu. Selecting the Image URL menu option presents a sheet
where a user can update the image URL. There are now safe guards in place for
users who update their profile, if they make any changes and try to navigate
back to home they will get an alert asking if they want to discard changes. The
Save button is also more prominent.

Changelog-Changed: Changed the default banner from ostriches to damoose
Changelog-Added: Added profile edit safe guards
Changelog-Changed: Changed image and banner url text fields to new sheet view

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-08-12 11:54:32 -07:00
Daniel D’Aquino
49c8d63d0b Merge pull request #2365 from danieldaquino/#2341
Fix crash with blurhashes with reported dimension of 0x0
2024-08-08 10:18:52 -07:00
transifex-integration[bot]
2519b0ee9f Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-08-08 02:50:07 +00:00
transifex-integration[bot]
ba1589e2e2 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-08-08 02:49:58 +00:00
transifex-integration[bot]
e9a2473bad Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-08-08 02:47:04 +00:00
Daniel D’Aquino
6480023c96 Fix crash with blurhashes with reported dimension of 0x0
This commit fixes a consistent crash noticed when visiting a particular
profile.

The crash was occuring when trying to display the blurhash of a specific Event, where the metadata claimed the image dimensions were 0px x 0px.

The null dimensions caused a division by zero to occur when scaling the image down, yielding a NaN (Not a Number) size value, which crashed the app when trying to cast that CGFloat value down to an integer.

The crash was fixed by modifying the down-scaling computations to check for invalid dimensions, and return nil. The callers were then updated to fallback to a default display dimension.

Issue repro
-------

Device: iPhone 15 simulator
iOS: 17.5
Damus: dba1799df0
Steps:
1. Visit the profile npub1gujeqakgt7fyp6zjggxhyy7ft623qtcaay5lkc8n8gkry4cvnrzqd3f67z
2. Check accessing the profile does not crash Damus.
3. Visit the event that had invalid 0x0 dimensions on the metadata (note1qmqdualjezamcjun23l4d9xw7529m7fee6hklgtnhack2fwznxysuzuuyz)
4. Check that Damus does not crash.

Results: Steps 2 and 4 crash 100% of the time (3/3)

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.5
Damus: This commit
Steps: Same as repro
Results:
1. Crash no longer occurs
2. Blurhash looks ok

Closes: https://github.com/damus-io/damus/issues/2341
Changelog-Fixed: Fix crash when viewing notes with invalid image dimension metadata
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-08-05 12:52:43 -07:00
William Casarin
774da239b9 Merge remote-tracking branches 'pr/2362', 'pr/2361', 'pr/2319' and 'pr/2355' 2024-08-05 10:57:02 -07:00
transifex-integration[bot]
90c80645ec Translate Localizable.stringsdict in ja
100% translated source file: 'Localizable.stringsdict'
on 'ja'.
2024-08-05 10:10:20 +00:00
transifex-integration[bot]
613ec23f7f Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-08-05 09:42:45 +00:00
transifex-integration[bot]
1d73ae1d32 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-08-05 08:22:18 +00:00
63e364ce5b Export strings for translation 2024-08-04 23:59:48 -04:00
transifex-integration[bot]
ee5f53e4eb Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-08-04 23:56:25 -04:00
transifex-integration[bot]
9de21a730a Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2024-08-04 23:56:25 -04:00
transifex-integration[bot]
36c09c8657 Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2024-08-04 23:56:25 -04:00
transifex-integration[bot]
e8ac143192 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2024-08-04 23:56:24 -04:00
transifex-integration[bot]
93f44939e3 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-08-04 23:56:24 -04:00
transifex-integration[bot]
48078b9b6a Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-08-04 23:56:24 -04:00
d6d6858e0b Export strings for translations 2024-08-04 23:56:24 -04:00
transifex-integration[bot]
0187ff1dc0 Translate Localizable.stringsdict in sv_SE
100% translated source file: 'Localizable.stringsdict'
on 'sv_SE'.
2024-08-04 23:56:24 -04:00
transifex-integration[bot]
4f9fef8515 Translate Localizable.strings in sv_SE
100% translated source file: 'Localizable.strings'
on 'sv_SE'.
2024-08-04 23:56:24 -04:00
transifex-integration[bot]
1ebadd42f0 Translate Localizable.stringsdict in hu_HU
100% translated source file: 'Localizable.stringsdict'
on 'hu_HU'.
2024-08-04 23:56:24 -04:00
transifex-integration[bot]
4fb4f3a2de Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-08-04 23:56:24 -04:00
transifex-integration[bot]
f49169c03c Translate InfoPlist.strings in sw
100% translated source file: 'InfoPlist.strings'
on 'sw'.
2024-08-04 23:56:23 -04:00
Daniel D’Aquino
740c10c9b2 Implement push notification preferences and update API
This commit implements push notification preferences with the push
notifications server, as well as updates itself to the new push
notifications API.

Testing
-------

Device: iPhone 15 simulator
iOS: 17.5
Damus: this commit
notepush: 3ca3a8325707535fdbc98d681d5e4a47dc313c67
Steps:
1. Enable push notifications. Settings should get synced and success message should appear
2. Disable push notifications. Sync message should disappear as it no longer applies
3. Enable push notifications again, and tweak notifications. Settings should sync with no errors
4. Leave settings screen and come back. Settings should be declared as synced

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/2360
2024-08-04 12:03:05 -07:00
ericholguin
653f9fbcbe relay: Add Tor Relay Image
This PR just adds the tor icon to relays ending with .onion

Changelog-Added: Tor relay icon

Closes: #2318
Signed-off-by: ericholguin <ericholguin@apache.org>
2024-07-30 21:22:55 -06:00
1767a677bb Fix profile view toolbar alignment bug in iOS 18
Changelog-Fixed: Fix profile view toolbar alignment bug in iOS 18
2024-07-29 10:21:06 -04:00
Daniel D’Aquino
dba1799df0 Merge pull request #2338 from ericholguin/move-posting-timeline
refactor: move posting timeline
2024-07-24 10:53:00 -07:00
Daniel D’Aquino
2db3d7310f Add changelog for v1.8 and 1.9 (14) App Store releases
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-07-19 13:12:52 -07:00
ericholguin
b2ba1e0e3b highlight: fixes and improvements
This patch allows highlights to be included in posts as well as removes context
when creating a highlight. Highlights now route as the root and selecting the
highlight in root routes to the highlighted event.

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-07-19 10:53:26 -07:00
Daniel D’Aquino
10b1cf64ae Merge pull request #2330 from ericholguin/highlight-fixes
highlight: fixes and improvements
2024-07-19 10:50:30 -07:00
ericholguin
afdd3f1d43 refactor: move posting timeline
This patch simply moves the PostingTimelineView into its own file outside of
ContentView.

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-07-15 20:10:13 -06:00
ericholguin
1b8e3fe184 highlight: fixes and improvements
This patch allows highlights to be included in posts as well as removes context
when creating a highlight. Highlights now route as the root and selecting the
highlight in root routes to the highlighted event.

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-07-15 19:58:59 -06:00
William Casarin
8ab1c6a899 restore localization for custom tabs
Signed-off-by: William Casarin <jb55@jb55.com>
2024-07-15 12:27:04 -07:00
Daniel D’Aquino
e8fae19b97 Version bump to 1.11 2024-07-15 12:19:56 -07:00
William Casarin
63e70605fc Revert "Update README.md"
This reverts commit fa70c376b1.
2024-07-14 21:30:05 -07:00
Daniel D’Aquino
35df9f7ab7 Add support for OnlyZaps mode on the new chat thread
With this commit, long-presses on chat bubbles will now reveal a zap
sheet if they are on OnlyZaps mode and have zaps unlocked.

Users without OnlyZaps or with Zaps blocked will continue to see the
emoji reaction sheet

Closes: https://github.com/damus-io/damus/issues/2327
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-07-14 21:26:03 -07:00
Daniel D’Aquino
605d88add1 Fix issue where very long names would appear in two lines on the chat event view
Closes: https://github.com/damus-io/damus/issues/2329
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-07-14 21:26:03 -07:00
Daniel D’Aquino
2b0a7d126d Add missing mention view from chat event bubble view
This commit adds event mentions to the chat bubbles.

Testing
-------

PASS

Damus: This commit
Device: iPhone 15 simulator
iOS: 17.5
Coverage:
- Tested referencing an event on a thread reply. Thread reply shows up as expected
- Checked appearance on light and dark mode
- Tapping on the mentioned event takes the user to that event

Closes: https://github.com/damus-io/damus/issues/2309
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-07-14 21:26:03 -07:00
Daniel D’Aquino
6e2c133faa Truncate long text messages on chat event view
Very large messages on the chat event view cause issues with swipe and
long-press interactions, and they might be a nuisance during scrolling.

This commit adds text truncation to the chat event view. The "show
more" button causes the user to navigate to the message, which is
reasonable to avoid overloading too many interactions on the same view
and having a huge text bubble that is difficult to interact with.

Closes: https://github.com/damus-io/damus/issues/2326
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-07-14 21:26:03 -07:00
Daniel D’Aquino
9885ff1912 Reduce minimum width for chat event view
Some users have reported that there is unwanted horizontal padding on
small messages. This was due to the minimum chat event view width. To
address this feedback, the minimum width has been reduced to a very
small amount, so that small messages with no other content can more
tightly hug the inner content.

Closes: https://github.com/damus-io/damus/issues/2312
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-07-14 21:26:03 -07:00
William Casarin
abb818bbd4 Fix crash in profile related to profile updates
Changelog-Fixed: Fix crash on profile page when there are profile updates
Signed-off-by: William Casarin <jb55@jb55.com>
2024-07-14 21:26:03 -07:00
William Casarin
f1dc023e18 fix crash when adding duplicate mute items
Changelog-Fixed: Fix crash when adding duplicate mute items
Signed-off-by: William Casarin <jb55@jb55.com>
2024-07-14 21:26:03 -07:00
William Casarin
4a332c7ffa simplify CustomPicker and fix ios18 runtime error
This fixes a reflection runtime error for our custom picker

Fixes: https://github.com/damus-io/damus/issues/2332
Signed-off-by: William Casarin <jb55@jb55.com>
2024-07-14 21:26:03 -07:00
William Casarin
616f730ae5 flatbuffers: don't crash if there are flatbuffer errors
Some japanese user profiles are breaking the flatbuffer profile
builder for some reason

Changelog-Fixed: Fix pretty bad crash when building flatbuffer profiles
Signed-off-by: William Casarin <jb55@jb55.com>
2024-07-14 21:26:03 -07:00
Daniel D’Aquino
164cea96f3 Merge pull request #2325 from tyiu/reactions-view-fix
Fix reactions view to not show reactions from replies on parent note
2024-07-13 11:23:05 -07:00
alltheseas
fa70c376b1 Update README.md
Added NIP-70 to NIP list
2024-07-10 01:02:46 +03:00
847f31f5a6 Fix reactions view to not show reactions from replies on parent note
Changelog-Fixed: Fix reactions view to not show reactions from replies on parent note
2024-07-06 19:07:33 -04:00
Daniel D’Aquino
fd130b78e7 Merge pull request #2308 from ericholguin/simplify-onboarding
ux: Simplify Onboarding
2024-07-05 12:04:59 -07:00
Daniel D’Aquino
0be0273121 Update push notification device token address
This commit sets up the correct server address to send device token
notifications to.

Testing
-------

PASS

Device: iPhone 13 Mini
iOS: 17.5
Damus: This commit
strfry-push-notify: 6c52129ab52f37f6686b1a3d1d0d8b478de9e60f
Setup:
- strfry-push-notify and notification device token server setup on the real damus server
- APNS environment setup to development on the server (temporarily)
- Developer settings turned on
- Experimental push notifications support turned ON
- "Send device tokens to localhost" setting turned OFF
- Notification mode in notification settings set to PUSH notifications
Steps:
1. Get a simulator up and running and connected to the Damus relay
2. Send a DM to the main device under test.
3. Check if push notification arrives even with Damus closed. PASS

Closes: https://github.com/damus-io/damus/issues/1733
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-07-03 11:08:13 -07:00
Daniel D’Aquino
b349de22b7 Merge changes from 'release_1.9' 2024-07-01 11:20:30 -07:00
Daniel D’Aquino
cc2d196705 Merge pull request #2310 from tyiu/mute-user-bug
Fix missing Mute button in profile view menu
2024-07-01 11:16:33 -07:00
Daniel D’Aquino
53be29efc2 Fix build error on the test target
This commit is a trivial fix for a build error on the test target

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-06-24 15:25:35 -07:00
Daniel D’Aquino
529ee63f29 Merge pull request #2295 from tyiu/change-emoji-component
Revamp emoji picker to be less error-prone and add search, frequently used, and multiple skin tone support capabilities
2024-06-24 15:23:27 -07:00
Daniel D’Aquino
490e8ec1fb Fix build error on the test target
This commit is a trivial fix for a build error on the test target

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-06-24 14:38:56 -07:00
Daniel D’Aquino
df267ffd04 Version bump to 1.10 (1) 2024-06-24 11:51:17 -07:00
Daniel D’Aquino
b771e8f49a Merge pull request #2295 from tyiu/change-emoji-component
Revamp emoji picker to be less error-prone and add search, frequently used, and multiple skin tone support capabilities
2024-06-24 11:38:31 -07:00
Daniel D’Aquino
a88e80a346 Merge pull request #2307 from damus-io/review_highlights_2024-06-19_rebased
Highlights (rebased to solve merge conflicts + minor tweaks)
2024-06-24 11:30:59 -07:00
8ac9863765 Fix missing Mute button in profile view menu
Changelog-Fixed: Fix missing Mute button in profile view menu
2024-06-23 22:40:33 -04:00
ericholguin
4a851501a1 ux: Simplify Onboarding
This patch simplifies the onboarding flow based on Jeroen's suggestions.

Setup view:
  - Removes extra nostr information
  - Only shows two buttons, create account and sign in.

Create Account view:
  - When a user uploads a photo it is now displayed
  - Name is now required
  - Public key is now hidden
  - Create account model has been updated to match metadata

Save Keys view:
  - Removes the requirement to copy the nsec
  - Simplified explanation
  - Only shows two buttons, save and not now

Testing
——
iPhone 15 Pro Max (17.0) Light Mode:
https://v.nostr.build/3P75x.mp4

iPhone SE (3rd generation) (16.4) Dark Mode:
https://v.nostr.build/wGBQL.mp4

——

Changelog-Fixed: Create Account model now uses correct metadata
Changelog-Changed: Onboarding design
2024-06-22 11:46:53 -06:00
Daniel D’Aquino
4ccfe81558 Allow highlighting to be disabled on SelectableText
Changed the interface of SelectableText to allow highlighting to be
disabled in places where it is not applicable (For example, on the
AboutView).

This prevents the need for adding dummy events in places where
highlighting is not applicable, preventing the user from making bad
highlights.

Testing
-------

PASS

Device: iPhone 13 mini
iOS: 17.5
Damus: This version
Steps:
1. Go to a user profile and select some text in their bio. The "highlight" option should not be present.
2. Go to a note and select some text. The "highlight" option should be available
2024-06-21 14:18:36 -07:00
Daniel D’Aquino
e7ed9dfe86 Small tweaks for better code safety 2024-06-21 14:11:45 -07:00
ericholguin
0dce7aea45 ux: Create Highlights
This patch allows users to create a highlight in Damus.
This is done by modifying the menu options when text is selected, including a custom highlight option.
This option presents a sheet to the user of what they are highlighting with a cancel or post button.
If they press Post the sheet will dismiss and their highlight will be posted.

Testing
——
iPhone 15 Pro Max (17.3.1) Dark Mode:
https://v.nostr.build/wGDnx.mp4

iPhone SE (3rd generation) (16.4) Light Mode:
https://v.nostr.build/xEK0e.mp4

——

Changelog-Added: Ability to create highlights

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-06-21 12:00:44 -07:00
ericholguin
6376c61bad Highlights
This patch adds highlights (NIP-84) to Damus.

Kind 9802 are handled by all the necessary models.
We show highlighted events, longform events, and url references.
Url references also leverage text fragments to take the user to the highlighted text.

Testing
——
iPhone 15 Pro Max (17.0) Dark Mode:
https://v.nostr.build/oM6DW.mp4

iPhone 15 Pro Max (17.0) Light Mode:
https://v.nostr.build/BRrmP.mp4

iPhone SE (3rd generation) (16.4) Light Mode:
https://v.nostr.build/6GzKa.mp4
——

Closes: https://github.com/damus-io/damus/issues/2172
Closes: https://github.com/damus-io/damus/issues/1772
Closes: https://github.com/damus-io/damus/issues/1773
Closes: https://github.com/damus-io/damus/issues/2173
Closes: https://github.com/damus-io/damus/issues/2175
Changelog-Added: Highlights (NIP-84)

PATCH CHANGELOG:
V1 -> V2: addressed review comments highlights are now truncated and highlight label shown in Thread view
V2 -> V3: handle case where highlight context is smaller than the highlight content

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-06-21 12:00:44 -07:00
bdd1403a7d Merge remote-tracking branch 'upstream/master' into change-emoji-component 2024-06-19 18:33:58 -04:00
Daniel D’Aquino
23c3130a82 New chat thread view
This commit changes the thread view to a new UX concept where children views of the selected view are now presented as chat bubbles, and the entire tree of conversation is shown flattened. New interactions, layout, and design changes have been introduced to revamp the user experience.

Testing
-------

Device: A mix of iPhone physical devices and simulator
iOS: A mix of iOS 17 versions
Damus: A mix of versions leading up to this one.
Coverage:
1. Unit tests are passing
2. A select few users have been using prototypes versions of this as their daily driver
3. Layout tested with an eclectic mix of threads
4. Posting new notes to the thread works
5. Clicking on reply quote view takes user to the mentioned message with a momentary visible highlight
6. Swipe actions work
7. Long press on chat bubbles works and shows emoji selector. Adding emoji sends the reaction
8. Clicking on notes selects them with an easy to follow transition

Known issues:
1. The text on the reply quote view occasionally appears to be off-center (in about 10% of occurrences). The cause is still unknown
2. Long press will still show the emoji keyboard even if user is on "onlyzaps" mode
3. Quoted events are not rendered on chat bubbles. When user posts a quoted event with no text, that could lead to confusion

Closes: https://github.com/damus-io/damus/issues/1126
Changelog-Added: Completely new threads experience that is easier and more pleasant to use
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-06-19 12:33:15 -07:00
9172102f4d Revamp emoji picker to be less error-prone and add search, frequently used, and multiple skin tone support capabilities
Changelog-Added: Revamp emoji picker to be less error-prone and add search, frequently used, and multiple skin tone support capabilities
2024-06-17 23:53:19 -04:00
ericholguin
8bcd8317f1 Fix persistent wallet on log out
This patch simply disconects the wallet connection when a user logs out.

Changelog-Fixed: Fixed wallet not disconnecting when a user logs out

Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-06-10 05:34:30 -07:00
919 changed files with 93517 additions and 13797 deletions

52
.github/ISSUE_TEMPLATE/app_release.md vendored Normal file
View File

@@ -0,0 +1,52 @@
---
name: App release process
about: Begin preparing for a new app release
title: 'Release: '
labels: release-tasks
assignees: ''
---
A new version release. Please attempt to follow the release process steps below in the order they are shown.
## TestFlight release candidates
### Release candidate 1
**Version:** _[Enter full build information for the release candidate, including major and minor version number, build number, and commit hash]_
1. [ ] Merge in all needed changes to `master`
2. [ ] Check CI, make sure it is passing
3. [ ] Prepare preliminary changelog as a draft PR: _[Enter PR link to changelog here]_
4. [ ] Make a _release_ build and submit to the internal TestFlight group via our new Release candidate workflow in Xcode Cloud.
5. [ ] Prepare short screencast style video with main changes for the announcement
6. [ ] Publish release build to these TestFlight groups:
- [ ] Alpha testers group
- [ ] Translators group
- [ ] Purple group
7. [ ] Publish announcement on Nostr
_[Duplicate this release candidate section if there is more than one release candidate]_
## App Store release
1. [ ] Release candidate checks:
- [ ] Release candidate has been on Purple TestFlight for at least one week
- [ ] No blocker issues came from feedback from Purple users (double-check)
- [ ] Check with stakeholders
- [ ] Check with developers & product for any release showstoppers (e.g., critical newfound bugs)
2. [ ] Thorough check on release notes
3. [ ] Submit to App Store review (with manual publishing setting enabled)
4. [ ] Get App Store approval from Apple
5. [ ] Prepare announcement
7. [ ] Publish on the App Store and make announcement
8. [ ] Publish changelog and tag commit hash corresponding to the release
9. [ ] Perform a version bump on the repository, in preparation for the next release
## Notes/others
_Enter any relevant notes here_

37
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,37 @@
## Summary
_[Please provide a summary of the changes in this PR.]_
## Checklist
- [ ] I have read (or I am familiar with) the [Contribution Guidelines](../docs/CONTRIBUTING.md)
- [ ] I have tested the changes in this PR
- [ ] I have opened or referred to an existing github issue related to this change.
- [ ] My PR is either small, or I have split it into smaller logical commits that are easier to review
- [ ] I have added the signoff line to all my commits. See [Signing off your work](../docs/CONTRIBUTING.md#sign-your-work---the-developers-certificate-of-origin)
- [ ] I have added appropriate changelog entries for the changes in this PR. See [Adding changelog entries](../docs/CONTRIBUTING.md#add-changelog-changed-changelog-fixed-etc)
- [ ] I do not need to add a changelog entry. Reason: _[Please provide a reason]_
- [ ] I have added appropriate `Closes:` or `Fixes:` tags in the commit messages wherever applicable, or made sure those are not needed. See [Submitting patches](https://github.com/damus-io/damus/blob/master/docs/CONTRIBUTING.md#submitting-patches)
## Test report
_Please provide a test report for the changes in this PR. You can use the template below, but feel free to modify it as needed._
**Device:** _[Please specify the device you used for testing]_
**iOS:** _[Please specify the iOS version you used for testing]_
**Damus:** _[Please specify the Damus version or commit hash you used for testing]_
**Setup:** _[Please provide a brief description of the setup you used for testing, if applicable]_
**Steps:** _[Please provide a list of steps you took to test the changes in this PR]_
**Results:**
- [ ] PASS
- [ ] Partial PASS
- Details: _[Please provide details of the partial pass]_
## Other notes
_[Please provide any other information that you think is relevant to this PR.]_

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ damus.xcodeproj/xcshareddata/xcbaselines
TODO.bak
tags
build-git-hash.txt
.build

5
ACKNOWLEDGEMENTS.md Normal file
View File

@@ -0,0 +1,5 @@
### Acknowledgements and licenses
1. This product contains code derived from [Nostr SDK iOS](https://github.com/nostr-sdk/nostr-sdk-ios). [License](https://github.com/nostr-sdk/nostr-sdk-ios/blob/40df800c6749d7ce0b6fd7328e76cbc0dc71c87b/LICENSE)
2. This product includes software developed by the "Marcin Krzyzanowski" (http://krzyzanowskim.com/). [License](https://github.com/krzyzanowskim/CryptoSwift/blob/e74bbbfbef939224b242ae7c342a90e60b88b5ce/LICENSE)

View File

@@ -1,3 +1,343 @@
## [1.14] - 2025-05-25
### Added
- Added safety reminder to wallets with higher balance (Daniel DAquino)
- Added one-click Coinos wallet setup (Daniel DAquino)
- Add notification setting to hide hellthreads (Terry Yiu)
- Added separated first aid option for relay lists that does not need a contact list reset (Daniel DAquino)
- Added NIP-65 relay list support (Daniel DAquino)
- Added Unicode 16 emoji reactions for iOS 18.4+ by upgrading EmojiPicker (Terry Yiu)
- Added a search interface to the settings screen (SanjaySiddharth)
- Added view introducing users to Zaps (ericholguin)
- Added new wallet view with balance and transactions list (ericholguin)
- Added copy technical info button to user visible errors, so that users can more easily share errors with developers (Daniel DAquino)
- Add dismiss button to wallet high balance reminders (Daniel DAquino)
- Zap receiver information now included for outgoing zaps (Daniel DAquino)
- Added inline note rendering of invoices to pull up wallet selector sheet (Terry Yiu)
- Added route to profile page from wallet tx list (ericholguin)
### Changed
- Added additional information on top of blurred images (SanjaySiddharth)
- Improved robustness of relay list handling (Daniel DAquino)
- Updated image cache for better stability (Daniel DAquino)
- Improved integration with Nostr Wallet Connect wallets (ericholguin)
- Added relay connectivity information to NWC settings (Daniel DAquino)
- Improved handling around NWC responses (Daniel DAquino)
- Added more human visible errors on NWC wallets to aid with troubleshooting (Daniel DAquino)
- Re-enabled note zaps as permitted by the new App Store guidelines (Daniel DAquino)
### Fixed
- Hide future notes from timeline (Terry Yiu)
- Fixed issue where profiles with a NIP-65 relay list would not display on Damus (Daniel DAquino)
- Fix quote notes to include missing q tag (Terry Yiu)
- Fixed issue where the side menu would close when copying the npub (SanjaySiddharth)
- Fixed issue where cached images would be backed up to iCloud (Daniel DAquino)
- Optimized classify_url function (Terry Yiu)
- Fixed note rendering for those that contain previewable items or leading and trailing whitespaces (Terry Yiu)
- Fixed issue where some videos would become unplayable after some time using the app (Daniel DAquino)
[1.14]: https://github.com/damus-io/damus/releases/tag/v1.14
## [1.13.1] - 2025-03-21
### Fixed
- Fixed an issue where threads would not load properly (Daniel DAquino)
[1.13.1]: https://github.com/damus-io/damus/releases/tag/v1.13.1
## [1.13] - 2025-03-14
### Added
- Added local persistence of note drafts (Daniel DAquino)
- Added user-friendly error view for errors around the app that would not fit in other places (Daniel DAquino)
- Coinos connection button in Wallet view (ericholguin)
- Added Alby Go to mobile wallets selection menu (Tomek ⚡ K)
- Minor accessibility improvements around picture editing and onboarding (Daniel DAquino)
- Profile image cropping tools (Daniel DAquino)
- Added Conversations tab to profiles (Terry Yiu)
- Added profile pictures to push notifications (William Casarin)
### Changed
- Don't show reposts for the same note more than once in your home feed (William Casarin)
- Improved profile image bandwidth optimization (Daniel DAquino)
- Improved reliability of picture selector (Daniel DAquino)
- Changed spaces to newlines in new posts to provide cleaner separation between text, uploaded media, and quoted notes (Terry Yiu)
### Fixed
- Fixed issue where some push notifications would not open in the app and leave users confused (Daniel DAquino)
- Fixed issue where app would need a restart for new NWC wallets to work (Daniel DAquino)
- Fixed overly sensitive horizontal swipe on thread chat view (Daniel DAquino)
- Trim whitespaces from Lightning addresses (Terry Yiu)
- Fixed translation export script by upgrading nostr-sdk-swift dependency to support Mac Catalyst (Terry Yiu)
- Fixed issue where users continue to receive push notifications after logout (Daniel DAquino)
- Fixed an issue where events on a thread view would occasionally disappear (Daniel DAquino)
- Improved robustness of the URL handler (Daniel DAquino)
- Translate notes even if they are in a preferred language but not the current language as that is what users expect (Terry Yiu)
- Cancel ongoing uploading operations after the user cancels the post (Swift Coder)
- Fixed link and photo sharing support on macOS (Swift Coder)
- Fix bug where profile view was showing more than just the notes and replies on the notes / notes & replies tabs (Terry Yiu)
- Fixed reposts banner to be localizable (Terry Yiu)
### Removed
- Removed language filtering from Universe feed because language detection can be inaccurate (Terry Yiu)
- Removed mystery tabs meant to fix tab switching bug that no longer exists (Terry Yiu)
[1.13](https://github.com/damus-io/damus/releases/tag/v1.13): https://github.com/damus-io/damus/releases/tag/v1.13
## [1.12.3] - 2025-02-06
### Added
- Purple members who have been active for more than a year now get a special badge (Daniel DAquino)
### Changed
- Improved clarity of the mute button to indicate it can be used for blocking a user (Daniel DAquino)
- Made the microphone access request message more clear to users (Daniel DAquino)
[v1.12.3]: https://github.com/damus-io/damus/releases/tag/v1.12.3
## [1.12](https://github.com/damus-io/damus/releases/tag/v1.12) - 2024-12-20
### Added
- Render Gif and video files while composing posts (Swift Coder)
- Add profile info text in stretchable banner with follow button (Swift Coder)
- Paste Gif image similar to jpeg and png files (Swift Coder)
### Changed
- Improved UX around the label for searching words (Daniel DAquino)
- Improved accessibility support on some elements (Daniel DAquino)
### Fixed
- Fixed issue where the "next" button would appear hidden and hard to click on the create account view (Daniel DAquino)
- Fix non scrollable wallet screen (Swift Coder)
- Fixed suggested users category titles to be localizable (Terry Yiu)
- Fixed GradientFollowButton to have consistent width and autoscale text limited to 1 line (Terry Yiu)
- Fixed right-to-left localization issues (Terry Yiu)
- Fixed AddMuteItemView to trim leading and trailing whitespaces from mute text and disallow adding text with only whitespaces (Terry Yiu)
- Fixed SideMenuView text to autoscale and limit to 1 line (Terry Yiu)
- Fixed an issue where a profile would need to be input twice in the search to be found (Daniel DAquino)
- Fixed non-breaking spaces in localized strings (Terry Yiu)
- Fixed localization issue on Add mute item button (Terry Yiu)
- Replace non-breaking spaces with regular spaces as Apple's NSLocalizedString macro does not seem to work with it (Terry Yiu)
- Fixed localization issues in RelayConfigView (Terry Yiu)
- Fix duplicate uploads (Swift Coder)
- Remove duplicate pubkey from Follow Suggestion list (Swift Coder)
- Fix Page control indicator (Swift Coder)
- Fix damus sharing issues (Swift Coder)
- Fixed issue where banner edit button is unclickable (Daniel DAquino)
- Handle empty notification pages by displaying suitable text (Swift Coder)
[v1.12](https://github.com/damus-io/damus/releases/tag/v1.12): [https://github.com/damus-io/damus/releases/tag/v1.12]
## [v1.11(10)](https://github.com/damus-io/damus/releases/tag/v1.11-10) - 2024-11-18
### Added
- Add Damus Share Feature (Swift)
- Added new easy to use video controls for full screen video (Daniel DAquino)
- Add Edit, Share, and Tap-gesture in Profile pic image viewer (Swift Coder)
- Disappearing header, tabbar, and post button on scroll (ericholguin)
- Add Apple translation popovers for notes for iOS 17.4+ and macOS 14.4+ (Terry Yiu)
- Added NDB search functionality to the universe view (ericholguin)
- Added mute button to ProfileActionSheet (chungwwei)
- Added mute action to selected text menu (ericholguin)
- Added support for pasting images from the clipboard to the post composer (Swift Coder)
### Changed
- Improved image carousel image fill behavior (Daniel DAquino)
- Improved video syncing and bandwidth usage when switching between timeline video and full screen mode (Daniel DAquino)
- Swipe to dismiss on full screen carousel now shows an opacity effect for improved UX (Daniel DAquino)
- Removed event contents from full screen media carousel for cleaner view (Daniel DAquino)
- Add share button for images on full screen image carousel view (Swift)
- Changed boldness of font in side menu labels. (ericholguin)
- Changed search notes button with searched keyword (ericholguin)
- Changed opacity of tabbar and post button (ericholguin)
- Allow multiple images to be uploaded at the same time (swiftcoder) (William Casarin)
- Changed side menu design (ericholguin)
- Truncate fulltext search results (William Casarin)
- Expanded profile search results to 128 (William Casarin)
- Expand nostrdb text search results to 128 items (William Casarin)
- Use LazyVStack in text search results (William Casarin)
### Fixed
- Fixed missing tab bar on navigation (Swift Coder)
- Fixed some issues where QR code would not work, and improved UX (Daniel DAquino)
- Fixed iOS 18 gesture issues that would take user to the thread view when clicking on a video or unmuting it (Daniel DAquino)
- Fixed several issues that would cause video to automatically play or pause incorrectly (Daniel DAquino)
- Fixed issue where full screen video would disappear when going to landscape mode (Daniel DAquino)
- Fixed portrait video size on full screen carousel (Daniel DAquino)
- Fix avatar image on qrcode view (Swift Coder)
- Fix banner image upload (Swift Coder)
- Fix dismiss button visibility (Swift Coder)
- Fix quote repost counting (William Casarin)
- Fixed overlapping text in Universe View (ericholguin)
- Fixed localization issues and exported strings (Terry Yiu)
- Fix sensitive long-press gesture on event chat bubble in iOS 18 (Daniel DAquino)
- Fixed bottom padding for tabbar (ericholguin)
- Fixed localization build failures (Terry Yiu)
- Fixed back nav button placement in profile edit view (ericholguin)
- Friend profiles will now more likely show up in profile search (William Casarin)
- Fix broken QR code scanner and fix landscape mode (Terry Yiu)
[1.11(10)](https://github.com/damus-io/damus/releases/tag/v1.11-10): https://github.com/damus-io/damus/releases/tag/v1.11-10
## [1.10.1] - 2024-09-22
### Added
- Push notification support (Daniel DAquino)
- Added profile edit safe guards (Eric Holguin)
- Tor relay icon (ericholguin)
- Add highlighter for web pages (Daniel DAquino)
- Add support for adding comments when creating a highlight (Daniel DAquino)
- Add support for rendering highlights with comments (Daniel DAquino)
- Ability to create highlights (ericholguin)
- Highlights (NIP-84) (ericholguin)
- Revamp emoji picker to be less error-prone and add search, frequently used, and multiple skin tone support capabilities (Terry Yiu)
### Changed
- Improve notification view filtering UX (Daniel DAquino)
- Improve visibility of friends filter button (Daniel DAquino)
- Changed the default banner from ostriches to damoose (Eric Holguin)
- Changed image and banner url text fields to new sheet view (Eric Holguin)
- Onboarding design (ericholguin)
### Fixed
- Fix items that became unclickable on iOS 18 (Daniel DAquino)
- Fix many reconnection issues (William Casarin)
- Fixed issue where theme would be changed to black and can't be switched back on iOS 18 (cr0bar)
- Fixed some scenarios where the contact list would never be saved locally and cause issues when switching relays. (Daniel DAquino)
- Fix albyhub zaps not appearing (William Casarin)
- Fix inadvertent escape from mention suggestion menu when typing a space character (Daniel DAquino)
- Fix profile view toolbar alignment bug in iOS 18 (Terry Yiu)
- Create Account model now uses correct metadata (ericholguin)
- Restore localization for custom tabs (William Casarin)
- Fix iOS 18 reflection runtime error for custom picker (William Casarin)
[1.10.1]: https://github.com/damus-io/damus/releases/tag/v1.10.1
## [1.9.1 (4)] - 2024-08-13
### Fixed
- Fix crash when viewing notes with invalid image dimension metadata (Daniel DAquino)
[1.9.1 (4)]: https://github.com/damus-io/damus/releases/tag/v1.9.1-4
## [1.9 (14)] - 2024-07-14
### Added
- Completely new threads experience that is easier and more pleasant to use (Daniel DAquino)
- Add emoji search to emoji picker (Terry Yiu)
### Changed
- Added first aid contact damus support email (alltheseas)
- Disable mutiny wallet button (William Casarin)
- Make friends show up first when searching for profiles (Terry Yiu)
### Fixed
- Fix crash on profile page when there are profile updates (William Casarin)
- Fix crash when adding duplicate mute items (William Casarin)
- Fix pretty bad crash when building flatbuffer profiles (William Casarin)
- Fix reactions view to not show reactions from replies on parent note (Terry Yiu)
- Fix missing Mute button in profile view menu (Terry Yiu)
- Fixed wallet not disconnecting when a user logs out (ericholguin)
- Fix stale feed issue when follow list is too big (Daniel DAquino)
[1.9 (14)]: https://github.com/damus-io/damus/releases/tag/v1.9-14
## [1.8] - 2024-05-11
### Added
- Added nip10 marker replies (William Casarin)
- Add marker nip10 support when reading notes (William Casarin)
- Added title image and tags to longform events (ericholguin)
- Add First Aid solution for users who do not have a contact list created for their account (Daniel DAquino)
- Relay fees metadata (ericholguin)
- Added callbackuri for a better ux when connecting mutiny wallet nwc (ericholguin)
- Add event content preview to the full screen carousel (Daniel DAquino)
- Show list of quoted reposts in threads (William Casarin)
- Proxy Tags are now viewable on Selected Events (ericholguin)
- Connect to Mutiny Wallet Button (ericholguin)
- Add ability to mute words, add new mutelist interface (Charlie) (William Casarin)
- Add ability to mute hashtag from SearchView (Charlie Fish)
### Changed
- Change reactions to use a native looking emoji picker (Terry Yiu)
- Relay detail design (ericholguin)
- Updated Zeus logo (ericholguin)
- Improve UX around video playback (Daniel DAquino)
- Moved paste nwc button to main wallet view (ericholguin)
- Errors with an NWC will show as an alert (ericholguin)
- Relay config view user interface (ericholguin)
- Always strip GPS data from images (kernelkind)
### Fixed
- Fix thread bug where a quote isn't picked up as a reply (William Casarin)
- Fixed threads not loading sometimes (William Casarin)
- Fixed issue where some replies were including the q tag (William Casarin)
- Fixed issue where timeline was scrolling when it isn't supposed to (William Casarin)
- Fix issue where bootstrap relays would inadvertently be added to the user's list on connectivity issues (Daniel DAquino)
- Fix broken GIF uploads (Daniel DAquino)
- Fix ghost notifications caused by Purple impending expiration notifications (Daniel DAquino)
- Improve reliability of contact list creation during onboarding (Daniel DAquino)
- Fix emoji reactions being cut off (ericholguin)
- Fix image indicators to limit number of dots to not spill screen beyond visible margins (ericholguin)
- Fix bug that would cause connection issues with relays defined with a trailing slash URL, and an inability to delete them. (Daniel DAquino)
- Issue where NWC Scanner view would not dismiss after a failed scan/paste (ericholguin)
[1.8]: https://github.com/damus-io/damus/releases/tag/v1.8
## [1.7-rc2] - 2024-02-28
### Added

View File

@@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.usernotifications.communication</key>
<true/>
<key>com.apple.developer.kernel.extended-virtual-addressing</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
@@ -10,5 +14,9 @@
</array>
<key>com.apple.security.network.client</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.jb55.damus2</string>
</array>
</dict>
</plist>

View File

@@ -18,7 +18,7 @@ struct NotificationExtensionState: HeadlessDamusState {
let lnurls: LNUrls
init?() {
guard let ndb = try? Ndb(owns_db_file: false) else { return nil }
guard let ndb = Ndb(owns_db_file: false) else { return nil }
self.ndb = ndb
guard let keypair = get_saved_keypair() else { return nil }

View File

@@ -55,6 +55,9 @@ struct NotificationFormatter {
var identifier = ""
switch notify.type {
case .tagged:
title = String(format: NSLocalizedString("Tagged by %@", comment: "Tagged by heading in local notification"), displayName)
identifier = "myMentionNotification"
case .mention:
title = String(format: NSLocalizedString("Mentioned by %@", comment: "Mentioned by heading in local notification"), displayName)
identifier = "myMentionNotification"
@@ -70,6 +73,9 @@ struct NotificationFormatter {
case .zap, .profile_zap:
// not handled here. Try `format_message(displayName: String, notify: LocalNotification, state: HeadlessDamusState) async -> (content: UNMutableNotificationContent, identifier: String)?`
return nil
case .reply:
title = String(format: NSLocalizedString("%@ replied to your note", comment: "Heading for local notification indicating a new reply"), displayName)
identifier = "myReplyNotification"
}
content.title = title
content.body = notify.content
@@ -87,16 +93,17 @@ struct NotificationFormatter {
// If it does not work, try async formatting methods
let content = UNMutableNotificationContent()
switch notify.type {
case .zap, .profile_zap:
guard let zap = await get_zap(from: notify.event, state: state) else {
Log.debug("format_message: async get_zap failed", for: .push_notifications)
return nil
}
content.title = Self.zap_notification_title(zap)
content.body = Self.zap_notification_body(profiles: state.profiles, zap: zap)
content.sound = UNNotificationSound.default
content.userInfo = LossyLocalNotification(type: .zap, mention: .note(notify.event.id)).to_user_info()
content.userInfo = LossyLocalNotification(type: .zap, mention: .init(nip19: .note(notify.event.id))).to_user_info()
return (content, "myZapNotification")
default:
// The sync method should have taken care of this.

View File

@@ -5,15 +5,32 @@
// Created by Daniel DAquino on 2023-11-10.
//
import Kingfisher
import ImageIO
import UserNotifications
import Foundation
import UniformTypeIdentifiers
import Intents
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
private func configureKingfisherCache() {
guard let groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.DAMUS_APP_GROUP_IDENTIFIER) else {
return
}
let cachePath = groupURL.appendingPathComponent(Constants.IMAGE_CACHE_DIRNAME)
if let cache = try? ImageCache(name: "sharedCache", cacheDirectoryURL: cachePath) {
KingfisherManager.shared.cache = cache
}
}
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
configureKingfisherCache()
self.contentHandler = contentHandler
guard let nostr_event_json = request.content.userInfo["nostr_event"] as? String,
@@ -27,9 +44,9 @@ class NotificationService: UNNotificationServiceExtension {
// Log that we got a push notification
Log.debug("Got nostr event push notification from pubkey %s", for: .push_notifications, nostr_event.pubkey.hex())
guard let state = NotificationExtensionState(),
let display_name = state.ndb.lookup_profile(nostr_event.pubkey)?.unsafeUnownedValue?.profile?.display_name // We are not holding the txn here.
else {
guard let state = NotificationExtensionState() else {
Log.debug("Failed to open nostrdb", for: .push_notifications)
// Something failed to initialize so let's go for the next best thing
guard let improved_content = NotificationFormatter.shared.format_message(event: nostr_event) else {
// We cannot format this nostr event. Suppress notification.
@@ -39,7 +56,18 @@ class NotificationService: UNNotificationServiceExtension {
contentHandler(improved_content)
return
}
let sender_profile = {
let txn = state.ndb.lookup_profile(nostr_event.pubkey)
let profile = txn?.unsafeUnownedValue?.profile
let picture = ((profile?.picture.map { URL(string: $0) }) ?? URL(string: robohash(nostr_event.pubkey)))!
return ProfileBuf(picture: picture,
name: profile?.name,
display_name: profile?.display_name,
nip05: profile?.nip05)
}()
let sender_pubkey = nostr_event.pubkey
// Don't show notification details that match mute list.
// TODO: Remove this code block once we get notification suppression entitlement from Apple. It will be covered by the `guard should_display_notification` block
if state.mutelist_manager.is_event_muted(nostr_event) {
@@ -52,25 +80,74 @@ class NotificationService: UNNotificationServiceExtension {
contentHandler(content)
return
}
guard should_display_notification(state: state, event: nostr_event, mode: .push) else {
Log.debug("should_display_notification failed", for: .push_notifications)
// We should not display notification for this event. Suppress notification.
// contentHandler(UNNotificationContent())
// TODO: We cannot really suppress until we have the notification supression entitlement. Show the raw notification
contentHandler(request.content)
return
}
guard let notification_object = generate_local_notification_object(from: nostr_event, state: state) else {
guard let notification_object = generate_local_notification_object(ndb: state.ndb, from: nostr_event, state: state) else {
Log.debug("generate_local_notification_object failed", for: .push_notifications)
// We could not process this notification. Probably an unsupported nostr event kind. Suppress.
// contentHandler(UNNotificationContent())
// TODO: We cannot really suppress until we have the notification supression entitlement. Show the raw notification
contentHandler(request.content)
return
}
Task {
if let (improvedContent, _) = await NotificationFormatter.shared.format_message(displayName: display_name, notify: notification_object, state: state) {
let sender_dn = DisplayName(name: sender_profile.name, display_name: sender_profile.display_name, pubkey: sender_pubkey)
guard let (improvedContent, _) = await NotificationFormatter.shared.format_message(displayName: sender_dn.displayName, notify: notification_object, state: state) else {
Log.debug("NotificationFormatter.format_message failed", for: .push_notifications)
return
}
do {
var options: [AnyHashable: Any] = [:]
if let imageSource = CGImageSourceCreateWithURL(sender_profile.picture as CFURL, nil),
let uti = CGImageSourceGetType(imageSource) {
options[UNNotificationAttachmentOptionsTypeHintKey] = uti
}
let attachment = try UNNotificationAttachment(identifier: sender_profile.picture.absoluteString, url: sender_profile.picture, options: options)
improvedContent.attachments = [attachment]
} catch {
Log.error("failed to get notification attachment: %s", for: .push_notifications, error.localizedDescription)
}
let kind = nostr_event.known_kind
// these aren't supported yet
if !(kind == .text || kind == .dm) {
contentHandler(improvedContent)
return
}
// rich communication notifications for kind1, dms, etc
let message_intent = await message_intent_from_note(ndb: state.ndb,
sender_profile: sender_profile,
content: improvedContent.body,
note: nostr_event,
our_pubkey: state.keypair.pubkey)
improvedContent.threadIdentifier = nostr_event.thread_id().hex()
improvedContent.categoryIdentifier = "COMMUNICATION"
let interaction = INInteraction(intent: message_intent, response: nil)
interaction.direction = .incoming
do {
try await interaction.donate()
let updated = try improvedContent.updating(from: message_intent)
contentHandler(updated)
} catch {
Log.error("failed to donate interaction: %s", for: .push_notifications, error.localizedDescription)
contentHandler(improvedContent)
}
}
@@ -85,3 +162,162 @@ class NotificationService: UNNotificationServiceExtension {
}
}
struct ProfileBuf {
let picture: URL
let name: String?
let display_name: String?
let nip05: String?
}
func message_intent_from_note(ndb: Ndb, sender_profile: ProfileBuf, content: String, note: NdbNote, our_pubkey: Pubkey) async -> INSendMessageIntent {
let sender_pk = note.pubkey
let sender = await profile_to_inperson(name: sender_profile.name,
display_name: sender_profile.display_name,
picture: sender_profile.picture.absoluteString,
nip05: sender_profile.nip05,
pubkey: sender_pk,
our_pubkey: our_pubkey)
let conversationIdentifier = note.thread_id().hex()
var recipients: [INPerson] = []
var pks: [Pubkey] = []
let meta = INSendMessageIntentDonationMetadata()
// gather recipients
if let recipient_note_id = note.direct_replies() {
let replying_to = ndb.lookup_note(recipient_note_id)
if let replying_to_pk = replying_to?.unsafeUnownedValue?.pubkey {
meta.isReplyToCurrentUser = replying_to_pk == our_pubkey
if replying_to_pk != sender_pk {
// we push the actual person being replied to first
pks.append(replying_to_pk)
}
}
}
let pubkeys = Array(note.referenced_pubkeys)
meta.recipientCount = pubkeys.count
if pubkeys.contains(sender_pk) {
meta.recipientCount -= 1
}
for pk in pubkeys.prefix(3) {
if pk == sender_pk || pks.contains(pk) {
continue
}
if !meta.isReplyToCurrentUser && pk == our_pubkey {
meta.mentionsCurrentUser = true
}
pks.append(pk)
}
for pk in pks {
let recipient = await pubkey_to_inperson(ndb: ndb, pubkey: pk, our_pubkey: our_pubkey)
recipients.append(recipient)
}
// we enable default formatting this way
var groupName = INSpeakableString(spokenPhrase: "")
// otherwise we just say its a DM
if note.known_kind == .dm {
groupName = INSpeakableString(spokenPhrase: "DM")
}
let intent = INSendMessageIntent(recipients: recipients,
outgoingMessageType: .outgoingMessageText,
content: content,
speakableGroupName: groupName,
conversationIdentifier: conversationIdentifier,
serviceName: "kind\(note.kind)",
sender: sender,
attachments: nil)
intent.donationMetadata = meta
// this is needed for recipients > 0
if let img = sender.image {
intent.setImage(img, forParameterNamed: \.speakableGroupName)
}
return intent
}
func pubkey_to_inperson(ndb: Ndb, pubkey: Pubkey, our_pubkey: Pubkey) async -> INPerson {
let profile_txn = ndb.lookup_profile(pubkey)
let profile = profile_txn?.unsafeUnownedValue?.profile
let name = profile?.name
let display_name = profile?.display_name
let nip05 = profile?.nip05
let picture = profile?.picture
return await profile_to_inperson(name: name,
display_name: display_name,
picture: picture,
nip05: nip05,
pubkey: pubkey,
our_pubkey: our_pubkey)
}
func fetch_pfp(picture: URL) async throws -> RetrieveImageResult {
try await withCheckedThrowingContinuation { continuation in
KingfisherManager.shared.retrieveImage(with: Kingfisher.ImageResource(downloadURL: picture)) { result in
switch result {
case .success(let img):
continuation.resume(returning: img)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
func profile_to_inperson(name: String?, display_name: String?, picture: String?, nip05: String?, pubkey: Pubkey, our_pubkey: Pubkey) async -> INPerson {
let npub = pubkey.npub
let handle = INPersonHandle(value: npub, type: .unknown)
var aliases: [INPersonHandle] = []
if let nip05 {
aliases.append(INPersonHandle(value: nip05, type: .emailAddress))
}
let nostrName = DisplayName(name: name, display_name: display_name, pubkey: pubkey)
let nameComponents = nostrName.nameComponents()
let displayName = nostrName.displayName
let contactIdentifier = npub
let customIdentifier = npub
let suggestionType = INPersonSuggestionType.socialProfile
var image: INImage? = nil
if let picture,
let url = URL(string: picture),
let img = try? await fetch_pfp(picture: url),
let imgdata = img.data()
{
image = INImage(imageData: imgdata)
} else {
Log.error("Failed to fetch pfp (%s) for %s", for: .push_notifications, picture ?? "nil", displayName)
}
let person = INPerson(personHandle: handle,
nameComponents: nameComponents,
displayName: displayName,
image: image,
contactIdentifier: contactIdentifier,
customIdentifier: customIdentifier,
isMe: pubkey == our_pubkey,
suggestionType: suggestionType
)
return person
}
func robohash(_ pk: Pubkey) -> String {
return "https://robohash.org/" + pk.hex()
}

View File

@@ -1,3 +1,32 @@
dependencies: [
.Package(url: "https://github.com/jb55/secp256k1.swift.git", branch: "main")
]
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "damus",
platforms: [
.iOS(.v16),
.macOS(.v12)
],
products: [
.library(
name: "damus",
targets: ["damus"]),
],
dependencies: [
.package(url: "https://github.com/jb55/secp256k1.swift.git", branch: "main")
],
targets: [
.target(
name: "damus",
dependencies: [
.product(name: "secp256k1", package: "secp256k1.swift")
],
path: "damus"),
.testTarget(
name: "damusTests",
dependencies: ["damus"],
path: "damusTests"),
]
)

View File

@@ -1,14 +1,30 @@
[![Run Test Suite](https://github.com/damus-io/damus/actions/workflows/run-tests.yaml/badge.svg?branch=master)](https://github.com/damus-io/damus/actions/workflows/run-tests.yaml)
<div align="center">
# damus
<img src="./damus/Assets.xcassets/damus-home.imageset/damus-home@2x.png" alt="Damus Logo" title="Damus logo" width=""/>
# Damus
The social network you control
A twitter-like [nostr][nostr] client for iPhone, iPad and MacOS.
<img src="./ss.png" width="50%" height="50%" />
[![License: GPL-3.0](https://img.shields.io/github/license/damus-io/damus?labelColor=27303D&color=0877d2)](/LICENSE)
## Download and Install
[![Apple](https://img.shields.io/badge/Apple-%23000000.svg?style=for-the-badge&logo=apple&logoColor=white)](https://apps.apple.com/us/app/damus/id1628663131)
## Supported Platforms
iOS 16.0+ • macOS 13.0+
<img src="./demo1.png" width="70%" height="50%" />
</div>
[nostr]: https://github.com/fiatjaf/nostr
## How is Damus better than twitter?
## How is Damus better than X/Twitter?
There are no toxic algorithms.\
You can send or receive zaps (satoshis) without asking for permission.\
[There is no central database](https://fiatjaf.com/nostr.html). Therefore, Damus is censorship resistant.\

2
TODO
View File

@@ -0,0 +1,2 @@
Fix q tags
1.5-24 profile loading was much better

View File

@@ -1,57 +0,0 @@
//
// block.h
// damus
//
// Created by William Casarin on 2023-04-09.
//
#ifndef block_h
#define block_h
#include "nostr_bech32.h"
#include "str_block.h"
#define MAX_BLOCKS 1024
enum block_type {
BLOCK_HASHTAG = 1,
BLOCK_TEXT = 2,
BLOCK_MENTION_INDEX = 3,
BLOCK_MENTION_BECH32 = 4,
BLOCK_URL = 5,
BLOCK_INVOICE = 6,
};
typedef struct invoice_block {
struct str_block invstr;
union {
struct bolt11 *bolt11;
};
} invoice_block_t;
typedef struct mention_bech32_block {
struct str_block str;
struct nostr_bech32 bech32;
} mention_bech32_block_t;
typedef struct note_block {
enum block_type type;
union {
struct str_block str;
struct invoice_block invoice;
struct mention_bech32_block mention_bech32;
int mention_index;
} block;
} block_t;
typedef struct note_blocks {
int words;
int num_blocks;
struct note_block *blocks;
} blocks_t;
void blocks_init(struct note_blocks *blocks);
void blocks_free(struct note_blocks *blocks);
#endif /* block_h */

View File

@@ -2,7 +2,6 @@
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#include "damus.h"
#include "bolt11.h"
#include "amount.h"
#include "nostr_bech32.h"

View File

@@ -1,393 +0,0 @@
//
// damus.c
// damus
//
// Created by William Casarin on 2022-10-17.
//
#include "damus.h"
#include "cursor.h"
#include "bolt11.h"
#include "bech32.h"
#include <stdlib.h>
#include <string.h>
static int parse_digit(struct cursor *cur, int *digit) {
int c;
if ((c = peek_char(cur, 0)) == -1)
return 0;
c -= '0';
if (c >= 0 && c <= 9) {
*digit = c;
cur->p++;
return 1;
}
return 0;
}
static int parse_mention_index(struct cursor *cur, struct note_block *block) {
int d1, d2, d3, ind;
u8 *start = cur->p;
if (!parse_str(cur, "#["))
return 0;
if (!parse_digit(cur, &d1)) {
cur->p = start;
return 0;
}
ind = d1;
if (parse_digit(cur, &d2))
ind = (d1 * 10) + d2;
if (parse_digit(cur, &d3))
ind = (d1 * 100) + (d2 * 10) + d3;
if (!parse_char(cur, ']')) {
cur->p = start;
return 0;
}
block->type = BLOCK_MENTION_INDEX;
block->block.mention_index = ind;
return 1;
}
static int parse_hashtag(struct cursor *cur, struct note_block *block) {
int c;
u8 *start = cur->p;
if (!parse_char(cur, '#'))
return 0;
c = peek_char(cur, 0);
if (c == -1 || is_whitespace(c) || c == '#') {
cur->p = start;
return 0;
}
consume_until_boundary(cur);
block->type = BLOCK_HASHTAG;
block->block.str.start = (const char*)(start + 1);
block->block.str.end = (const char*)cur->p;
return 1;
}
static int add_block(struct note_blocks *blocks, struct note_block block)
{
if (blocks->num_blocks + 1 >= MAX_BLOCKS)
return 0;
blocks->blocks[blocks->num_blocks++] = block;
return 1;
}
static int add_text_block(struct note_blocks *blocks, const u8 *start, const u8 *end)
{
struct note_block b;
if (start == end)
return 1;
b.type = BLOCK_TEXT;
b.block.str.start = (const char*)start;
b.block.str.end = (const char*)end;
return add_block(blocks, b);
}
static int consume_url_fragment(struct cursor *cur)
{
int c;
if ((c = peek_char(cur, 0)) < 0)
return 1;
if (c != '#' && c != '?') {
return 1;
}
cur->p++;
return consume_until_end_url(cur, 1);
}
static int consume_url_path(struct cursor *cur)
{
int c;
if ((c = peek_char(cur, 0)) < 0)
return 1;
if (c != '/') {
return 1;
}
while (cur->p < cur->end) {
c = *cur->p;
if (c == '?' || c == '#' || is_final_url_char(cur->p, cur->end)) {
return 1;
}
cur->p++;
}
return 1;
}
static int consume_url_host(struct cursor *cur)
{
char c;
int count = 0;
while (cur->p < cur->end) {
c = *cur->p;
// TODO: handle IDNs
if ((is_alphanumeric(c) || c == '.' || c == '-') && !is_final_url_char(cur->p, cur->end))
{
count++;
cur->p++;
continue;
}
return count != 0;
}
// this means the end of the URL hostname is the end of the buffer and we finished
return count != 0;
}
static int parse_url(struct cursor *cur, struct note_block *block) {
u8 *start = cur->p;
u8 *host;
int host_len;
struct cursor path_cur;
if (!parse_str(cur, "http"))
return 0;
if (parse_char(cur, 's') || parse_char(cur, 'S')) {
if (!parse_str(cur, "://")) {
cur->p = start;
return 0;
}
} else {
if (!parse_str(cur, "://")) {
cur->p = start;
return 0;
}
}
// make sure to save the hostname. We will use this to detect damus.io links
host = cur->p;
if (!consume_url_host(cur)) {
cur->p = start;
return 0;
}
// get the length of the host string
host_len = (int)(cur->p - host);
// save the current parse state so that we can continue from here when
// parsing the bech32 in the damus.io link if we have it
copy_cursor(cur, &path_cur);
// skip leading /
cursor_skip(&path_cur, 1);
if (!consume_url_path(cur)) {
cur->p = start;
return 0;
}
if (!consume_url_fragment(cur)) {
cur->p = start;
return 0;
}
// smart parens
if (start - 1 >= 0 &&
start < cur->end &&
*(start - 1) == '(' &&
(cur->p - 1) < cur->end &&
*(cur->p - 1) == ')')
{
cur->p--;
}
// save the bech32 string pos in case we hit a damus.io link
block->block.str.start = (const char *)path_cur.p;
// if we have a damus link, make it a mention
if (host_len == 8
&& !strncmp((const char *)host, "damus.io", 8)
&& parse_nostr_bech32(&path_cur, &block->block.mention_bech32.bech32))
{
block->block.str.end = (const char *)path_cur.p;
block->type = BLOCK_MENTION_BECH32;
return 1;
}
block->type = BLOCK_URL;
block->block.str.start = (const char *)start;
block->block.str.end = (const char *)cur->p;
return 1;
}
static int parse_invoice(struct cursor *cur, struct note_block *block) {
u8 *start, *end;
char *fail;
struct bolt11 *bolt11;
// optional
parse_str(cur, "lightning:");
start = cur->p;
if (!parse_str(cur, "lnbc"))
return 0;
if (!consume_until_whitespace(cur, 1)) {
cur->p = start;
return 0;
}
end = cur->p;
char str[end - start + 1];
str[end - start] = 0;
memcpy(str, start, end - start);
if (!(bolt11 = bolt11_decode(NULL, str, &fail))) {
cur->p = start;
return 0;
}
block->type = BLOCK_INVOICE;
block->block.invoice.invstr.start = (const char*)start;
block->block.invoice.invstr.end = (const char*)end;
block->block.invoice.bolt11 = bolt11;
cur->p = end;
return 1;
}
static int parse_mention_bech32(struct cursor *cur, struct note_block *block) {
u8 *start = cur->p;
parse_char(cur, '@');
parse_str(cur, "nostr:");
block->block.str.start = (const char *)cur->p;
if (!parse_nostr_bech32(cur, &block->block.mention_bech32.bech32)) {
cur->p = start;
return 0;
}
block->block.str.end = (const char *)cur->p;
block->type = BLOCK_MENTION_BECH32;
return 1;
}
static int add_text_then_block(struct cursor *cur, struct note_blocks *blocks, struct note_block block, u8 **start, const u8 *pre_mention)
{
if (!add_text_block(blocks, *start, pre_mention))
return 0;
*start = (u8*)cur->p;
if (!add_block(blocks, block))
return 0;
return 1;
}
int damus_parse_content(struct note_blocks *blocks, const char *content) {
int cp, c;
struct cursor cur;
struct note_block block;
u8 *start, *pre_mention;
blocks->words = 0;
blocks->num_blocks = 0;
make_cursor((u8*)content, (u8*)content + strlen(content), &cur);
start = cur.p;
while (cur.p < cur.end && blocks->num_blocks < MAX_BLOCKS) {
cp = peek_char(&cur, -1);
c = peek_char(&cur, 0);
// new word
if (is_whitespace(cp) && !is_whitespace(c)) {
blocks->words++;
}
pre_mention = cur.p;
if (cp == -1 || is_left_boundary(cp) || c == '#') {
if (c == '#' && (parse_mention_index(&cur, &block) || parse_hashtag(&cur, &block))) {
if (!add_text_then_block(&cur, blocks, block, &start, pre_mention))
return 0;
continue;
} else if ((c == 'h' || c == 'H') && parse_url(&cur, &block)) {
if (!add_text_then_block(&cur, blocks, block, &start, pre_mention))
return 0;
continue;
} else if ((c == 'l' || c == 'L') && parse_invoice(&cur, &block)) {
if (!add_text_then_block(&cur, blocks, block, &start, pre_mention))
return 0;
continue;
} else if ((c == 'n' || c == '@') && parse_mention_bech32(&cur, &block)) {
if (!add_text_then_block(&cur, blocks, block, &start, pre_mention))
return 0;
continue;
}
}
cur.p++;
}
if (cur.p - start > 0) {
if (!add_text_block(blocks, start, cur.p))
return 0;
}
return 1;
}
void blocks_init(struct note_blocks *blocks) {
blocks->blocks = malloc(sizeof(struct note_block) * MAX_BLOCKS);
blocks->num_blocks = 0;
}
void blocks_free(struct note_blocks *blocks) {
if (!blocks->blocks) {
return;
}
for (int i = 0; i < blocks->num_blocks; ++i) {
if (blocks->blocks[i].type == BLOCK_MENTION_BECH32) {
free(blocks->blocks[i].block.mention_bech32.bech32.buffer);
blocks->blocks[i].block.mention_bech32.bech32.buffer = NULL;
}
}
free(blocks->blocks);
blocks->num_blocks = 0;
}

View File

@@ -1,18 +0,0 @@
//
// damus.h
// damus
//
// Created by William Casarin on 2022-10-17.
//
#ifndef damus_h
#define damus_h
#include <stdio.h>
#include "block.h"
typedef unsigned char u8;
int damus_parse_content(struct note_blocks *blocks, const char *content);
#endif /* damus_h */

View File

@@ -1,84 +0,0 @@
/* CC0 (Public domain) - see LICENSE file for details */
#ifndef CCAN_HEX_H
#define CCAN_HEX_H
#include "config.h"
#include <stdbool.h>
#include <stdlib.h>
/**
* hex_decode - Unpack a hex string.
* @str: the hexadecimal string
* @slen: the length of @str
* @buf: the buffer to write the data into
* @bufsize: the length of
*
* Returns false if there are any characters which aren't 0-9, a-f or A-F,
* of the string wasn't the right length for @bufsize.
*
* Example:
* unsigned char data[20];
*
* if (!hex_decode(argv[1], strlen(argv[1]), data, 20))
* printf("String is malformed!\n");
*/
bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize);
/**
* hex_encode - Create a nul-terminated hex string
* @buf: the buffer to read the data from
* @bufsize: the length of buf
* @dest: the string to fill
* @destsize: the max size of the string
*
* Returns true if the string, including terminator, fit in @destsize;
*
* Example:
* unsigned char buf[] = { 0x1F, 0x2F };
* char str[5];
*
* if (!hex_encode(buf, sizeof(buf), str, sizeof(str)))
* abort();
*/
bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize);
/**
* hex_str_size - Calculate how big a nul-terminated hex string is
* @bytes: bytes of data to represent
*
* Example:
* unsigned char buf[] = { 0x1F, 0x2F };
* char str[hex_str_size(sizeof(buf))];
*
* hex_encode(buf, sizeof(buf), str, sizeof(str));
*/
static inline size_t hex_str_size(size_t bytes)
{
return 2 * bytes + 1;
}
/**
* hex_data_size - Calculate how many bytes of data in a hex string
* @strlen: the length of the string (with or without NUL)
*
* Example:
* const char str[] = "1F2F";
* unsigned char buf[hex_data_size(sizeof(str))];
*
* hex_decode(str, strlen(str), buf, sizeof(buf));
*/
static inline size_t hex_data_size(size_t strlen)
{
return strlen / 2;
}
static inline char hexchar(unsigned int val)
{
if (val < 10)
return '0' + val;
if (val < 16)
return 'a' + val - 10;
abort();
}
#endif /* CCAN_HEX_H */

View File

@@ -1,325 +0,0 @@
//
// nostr_bech32.c
// damus
//
// Created by William Casarin on 2023-04-09.
//
#include "nostr_bech32.h"
#include <stdlib.h>
#include "endian.h"
#include "cursor.h"
#include "bech32.h"
#include <stdbool.h>
#define MAX_TLVS 16
#define TLV_SPECIAL 0
#define TLV_RELAY 1
#define TLV_AUTHOR 2
#define TLV_KIND 3
#define TLV_KNOWN_TLVS 4
struct nostr_tlv {
u8 type;
u8 len;
const u8 *value;
};
struct nostr_tlvs {
struct nostr_tlv tlvs[MAX_TLVS];
int num_tlvs;
};
static int parse_nostr_tlv(struct cursor *cur, struct nostr_tlv *tlv) {
// get the tlv tag
if (!pull_byte(cur, &tlv->type))
return 0;
// unknown, fail!
if (tlv->type >= TLV_KNOWN_TLVS)
return 0;
// get the length
if (!pull_byte(cur, &tlv->len))
return 0;
// is the reported length greater then our buffer? if so fail
if (cur->p + tlv->len > cur->end)
return 0;
tlv->value = cur->p;
cur->p += tlv->len;
return 1;
}
static int parse_nostr_tlvs(struct cursor *cur, struct nostr_tlvs *tlvs) {
int i;
tlvs->num_tlvs = 0;
for (i = 0; i < MAX_TLVS; i++) {
if (parse_nostr_tlv(cur, &tlvs->tlvs[i])) {
tlvs->num_tlvs++;
} else {
break;
}
}
if (tlvs->num_tlvs == 0)
return 0;
return 1;
}
static int find_tlv(struct nostr_tlvs *tlvs, u8 type, struct nostr_tlv **tlv) {
*tlv = NULL;
for (int i = 0; i < tlvs->num_tlvs; i++) {
if (tlvs->tlvs[i].type == type) {
*tlv = &tlvs->tlvs[i];
return 1;
}
}
return 0;
}
static int parse_nostr_bech32_type(const char *prefix, enum nostr_bech32_type *type) {
// Parse type
if (strcmp(prefix, "note") == 0) {
*type = NOSTR_BECH32_NOTE;
return 1;
} else if (strcmp(prefix, "npub") == 0) {
*type = NOSTR_BECH32_NPUB;
return 1;
} else if (strcmp(prefix, "nsec") == 0) {
*type = NOSTR_BECH32_NSEC;
return 1;
} else if (strcmp(prefix, "nprofile") == 0) {
*type = NOSTR_BECH32_NPROFILE;
return 1;
} else if (strcmp(prefix, "nevent") == 0) {
*type = NOSTR_BECH32_NEVENT;
return 1;
} else if (strcmp(prefix, "nrelay") == 0) {
*type = NOSTR_BECH32_NRELAY;
return 1;
} else if (strcmp(prefix, "naddr") == 0) {
*type = NOSTR_BECH32_NADDR;
return 1;
}
return 0;
}
static int parse_nostr_bech32_note(struct cursor *cur, struct bech32_note *note) {
return pull_bytes(cur, 32, &note->event_id);
}
static int parse_nostr_bech32_npub(struct cursor *cur, struct bech32_npub *npub) {
return pull_bytes(cur, 32, &npub->pubkey);
}
static int parse_nostr_bech32_nsec(struct cursor *cur, struct bech32_nsec *nsec) {
return pull_bytes(cur, 32, &nsec->nsec);
}
static int tlvs_to_relays(struct nostr_tlvs *tlvs, struct relays *relays) {
struct nostr_tlv *tlv;
struct str_block *str;
relays->num_relays = 0;
for (int i = 0; i < tlvs->num_tlvs; i++) {
tlv = &tlvs->tlvs[i];
if (tlv->type != TLV_RELAY)
continue;
if (relays->num_relays + 1 > MAX_RELAYS)
break;
str = &relays->relays[relays->num_relays++];
str->start = (const char*)tlv->value;
str->end = (const char*)(tlv->value + tlv->len);
}
return 1;
}
static uint32_t decode_tlv_u32(const uint8_t *bytes) {
beint32_t *be32_bytes = (beint32_t*)bytes;
return be32_to_cpu(*be32_bytes);
}
static int parse_nostr_bech32_nevent(struct cursor *cur, struct bech32_nevent *nevent) {
struct nostr_tlvs tlvs;
struct nostr_tlv *tlv;
if (!parse_nostr_tlvs(cur, &tlvs))
return 0;
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
return 0;
if (tlv->len != 32)
return 0;
nevent->event_id = tlv->value;
if (find_tlv(&tlvs, TLV_AUTHOR, &tlv)) {
nevent->pubkey = tlv->value;
} else {
nevent->pubkey = NULL;
}
if(find_tlv(&tlvs, TLV_KIND, &tlv)) {
nevent->kind = decode_tlv_u32(tlv->value);
nevent->has_kind = true;
} else {
nevent->has_kind = false;
}
return tlvs_to_relays(&tlvs, &nevent->relays);
}
static int parse_nostr_bech32_naddr(struct cursor *cur, struct bech32_naddr *naddr) {
struct nostr_tlvs tlvs;
struct nostr_tlv *tlv;
if (!parse_nostr_tlvs(cur, &tlvs))
return 0;
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
return 0;
naddr->identifier.start = (const char*)tlv->value;
naddr->identifier.end = (const char*)tlv->value + tlv->len;
if (!find_tlv(&tlvs, TLV_AUTHOR, &tlv))
return 0;
naddr->pubkey = tlv->value;
if(!find_tlv(&tlvs, TLV_KIND, &tlv)) {
return 0;
}
naddr->kind = decode_tlv_u32(tlv->value);
return tlvs_to_relays(&tlvs, &naddr->relays);
}
static int parse_nostr_bech32_nprofile(struct cursor *cur, struct bech32_nprofile *nprofile) {
struct nostr_tlvs tlvs;
struct nostr_tlv *tlv;
if (!parse_nostr_tlvs(cur, &tlvs))
return 0;
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
return 0;
if (tlv->len != 32)
return 0;
nprofile->pubkey = tlv->value;
return tlvs_to_relays(&tlvs, &nprofile->relays);
}
static int parse_nostr_bech32_nrelay(struct cursor *cur, struct bech32_nrelay *nrelay) {
struct nostr_tlvs tlvs;
struct nostr_tlv *tlv;
if (!parse_nostr_tlvs(cur, &tlvs))
return 0;
if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv))
return 0;
nrelay->relay.start = (const char*)tlv->value;
nrelay->relay.end = (const char*)tlv->value + tlv->len;
return 1;
}
int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj) {
u8 *start, *end;
start = cur->p;
if (!consume_until_non_alphanumeric(cur, 1)) {
cur->p = start;
return 0;
}
end = cur->p;
size_t data_len;
size_t input_len = end - start;
if (input_len < 10 || input_len > 10000) {
return 0;
}
obj->buffer = malloc(input_len * 2);
if (!obj->buffer)
return 0;
u8 data[input_len];
char prefix[input_len];
if (bech32_decode_len(prefix, data, &data_len, (const char*)start, input_len) == BECH32_ENCODING_NONE) {
cur->p = start;
return 0;
}
obj->buflen = 0;
if (!bech32_convert_bits(obj->buffer, &obj->buflen, 8, data, data_len, 5, 0)) {
goto fail;
}
if (!parse_nostr_bech32_type(prefix, &obj->type)) {
goto fail;
}
struct cursor bcur;
make_cursor(obj->buffer, obj->buffer + obj->buflen, &bcur);
switch (obj->type) {
case NOSTR_BECH32_NOTE:
if (!parse_nostr_bech32_note(&bcur, &obj->data.note))
goto fail;
break;
case NOSTR_BECH32_NPUB:
if (!parse_nostr_bech32_npub(&bcur, &obj->data.npub))
goto fail;
break;
case NOSTR_BECH32_NSEC:
if (!parse_nostr_bech32_nsec(&bcur, &obj->data.nsec))
goto fail;
break;
case NOSTR_BECH32_NEVENT:
if (!parse_nostr_bech32_nevent(&bcur, &obj->data.nevent))
goto fail;
break;
case NOSTR_BECH32_NADDR:
if (!parse_nostr_bech32_naddr(&bcur, &obj->data.naddr))
goto fail;
break;
case NOSTR_BECH32_NPROFILE:
if (!parse_nostr_bech32_nprofile(&bcur, &obj->data.nprofile))
goto fail;
break;
case NOSTR_BECH32_NRELAY:
if (!parse_nostr_bech32_nrelay(&bcur, &obj->data.nrelay))
goto fail;
break;
}
return 1;
fail:
free(obj->buffer);
cur->p = start;
return 0;
}

View File

@@ -1,89 +0,0 @@
//
// nostr_bech32.h
// damus
//
// Created by William Casarin on 2023-04-09.
//
#ifndef nostr_bech32_h
#define nostr_bech32_h
#include <stdio.h>
#include "str_block.h"
#include "cursor.h"
#include <stdbool.h>
typedef unsigned char u8;
#define MAX_RELAYS 10
struct relays {
struct str_block relays[MAX_RELAYS];
int num_relays;
};
enum nostr_bech32_type {
NOSTR_BECH32_NOTE = 1,
NOSTR_BECH32_NPUB = 2,
NOSTR_BECH32_NPROFILE = 3,
NOSTR_BECH32_NEVENT = 4,
NOSTR_BECH32_NRELAY = 5,
NOSTR_BECH32_NADDR = 6,
NOSTR_BECH32_NSEC = 7,
};
struct bech32_note {
const u8 *event_id;
};
struct bech32_npub {
const u8 *pubkey;
};
struct bech32_nsec {
const u8 *nsec;
};
struct bech32_nevent {
struct relays relays;
const u8 *event_id;
const u8 *pubkey; // optional
uint32_t kind;
bool has_kind;
};
struct bech32_nprofile {
struct relays relays;
const u8 *pubkey;
};
struct bech32_naddr {
struct relays relays;
struct str_block identifier;
const u8 *pubkey;
uint32_t kind;
};
struct bech32_nrelay {
struct str_block relay;
};
typedef struct nostr_bech32 {
enum nostr_bech32_type type;
u8 *buffer; // holds strings and tlv stuff
size_t buflen;
union {
struct bech32_note note;
struct bech32_npub npub;
struct bech32_nsec nsec;
struct bech32_nevent nevent;
struct bech32_nprofile nprofile;
struct bech32_naddr naddr;
struct bech32_nrelay nrelay;
} data;
} nostr_bech32_t;
int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj);
#endif /* nostr_bech32_h */

View File

@@ -1,308 +0,0 @@
/* MIT (BSD) license - see LICENSE file for details */
/* SHA256 core code translated from the Bitcoin project's C++:
*
* src/crypto/sha256.cpp commit 417532c8acb93c36c2b6fd052b7c11b6a2906aa2
* Copyright (c) 2014 The Bitcoin Core developers
* Distributed under the MIT software license, see the accompanying
* file COPYING or http://www.opensource.org/licenses/mit-license.php.
*/
#include "sha256.h"
#include "compiler.h"
#include "endian.h"
#include <stdbool.h>
#include <assert.h>
#include <string.h>
static void invalidate_sha256(struct sha256_ctx *ctx)
{
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
ctx->c.md_len = 0;
#else
ctx->bytes = (size_t)-1;
#endif
}
static void check_sha256(struct sha256_ctx *ctx UNUSED)
{
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
assert(ctx->c.md_len != 0);
#else
assert(ctx->bytes != (size_t)-1);
#endif
}
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
void sha256_init(struct sha256_ctx *ctx)
{
SHA256_Init(&ctx->c);
}
void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size)
{
check_sha256(ctx);
SHA256_Update(&ctx->c, p, size);
}
void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
{
SHA256_Final(res->u.u8, &ctx->c);
invalidate_sha256(ctx);
}
#else
static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z)
{
return z ^ (x & (y ^ z));
}
static uint32_t Maj(uint32_t x, uint32_t y, uint32_t z)
{
return (x & y) | (z & (x | y));
}
static uint32_t Sigma0(uint32_t x)
{
return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
}
static uint32_t Sigma1(uint32_t x)
{
return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
}
static uint32_t sigma0(uint32_t x)
{
return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
}
static uint32_t sigma1(uint32_t x)
{
return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
}
/** One round of SHA-256. */
static void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t *d, uint32_t e, uint32_t f, uint32_t g, uint32_t *h, uint32_t k, uint32_t w)
{
uint32_t t1 = *h + Sigma1(e) + Ch(e, f, g) + k + w;
uint32_t t2 = Sigma0(a) + Maj(a, b, c);
*d += t1;
*h = t1 + t2;
}
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
static void Transform(uint32_t *s, const uint32_t *chunk)
{
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
Round(a, b, c, &d, e, f, g, &h, 0x428a2f98, w0 = be32_to_cpu(chunk[0]));
Round(h, a, b, &c, d, e, f, &g, 0x71374491, w1 = be32_to_cpu(chunk[1]));
Round(g, h, a, &b, c, d, e, &f, 0xb5c0fbcf, w2 = be32_to_cpu(chunk[2]));
Round(f, g, h, &a, b, c, d, &e, 0xe9b5dba5, w3 = be32_to_cpu(chunk[3]));
Round(e, f, g, &h, a, b, c, &d, 0x3956c25b, w4 = be32_to_cpu(chunk[4]));
Round(d, e, f, &g, h, a, b, &c, 0x59f111f1, w5 = be32_to_cpu(chunk[5]));
Round(c, d, e, &f, g, h, a, &b, 0x923f82a4, w6 = be32_to_cpu(chunk[6]));
Round(b, c, d, &e, f, g, h, &a, 0xab1c5ed5, w7 = be32_to_cpu(chunk[7]));
Round(a, b, c, &d, e, f, g, &h, 0xd807aa98, w8 = be32_to_cpu(chunk[8]));
Round(h, a, b, &c, d, e, f, &g, 0x12835b01, w9 = be32_to_cpu(chunk[9]));
Round(g, h, a, &b, c, d, e, &f, 0x243185be, w10 = be32_to_cpu(chunk[10]));
Round(f, g, h, &a, b, c, d, &e, 0x550c7dc3, w11 = be32_to_cpu(chunk[11]));
Round(e, f, g, &h, a, b, c, &d, 0x72be5d74, w12 = be32_to_cpu(chunk[12]));
Round(d, e, f, &g, h, a, b, &c, 0x80deb1fe, w13 = be32_to_cpu(chunk[13]));
Round(c, d, e, &f, g, h, a, &b, 0x9bdc06a7, w14 = be32_to_cpu(chunk[14]));
Round(b, c, d, &e, f, g, h, &a, 0xc19bf174, w15 = be32_to_cpu(chunk[15]));
Round(a, b, c, &d, e, f, g, &h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, &c, d, e, f, &g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, &b, c, d, e, &f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, &a, b, c, d, &e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, &h, a, b, c, &d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, &g, h, a, b, &c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, &f, g, h, a, &b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, &e, f, g, h, &a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, &d, e, f, g, &h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, &c, d, e, f, &g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, &b, c, d, e, &f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, &a, b, c, d, &e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, &h, a, b, c, &d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, &g, h, a, b, &c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, &f, g, h, a, &b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, &e, f, g, h, &a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
Round(a, b, c, &d, e, f, g, &h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, &c, d, e, f, &g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, &b, c, d, e, &f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, &a, b, c, d, &e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, &h, a, b, c, &d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, &g, h, a, b, &c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, &f, g, h, a, &b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, &e, f, g, h, &a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, &d, e, f, g, &h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, &c, d, e, f, &g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, &b, c, d, e, &f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, &a, b, c, d, &e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, &h, a, b, c, &d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, &g, h, a, b, &c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, &f, g, h, a, &b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, &e, f, g, h, &a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
Round(a, b, c, &d, e, f, g, &h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
Round(h, a, b, &c, d, e, f, &g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
Round(g, h, a, &b, c, d, e, &f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
Round(f, g, h, &a, b, c, d, &e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
Round(e, f, g, &h, a, b, c, &d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
Round(d, e, f, &g, h, a, b, &c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
Round(c, d, e, &f, g, h, a, &b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
Round(b, c, d, &e, f, g, h, &a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
Round(a, b, c, &d, e, f, g, &h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
Round(h, a, b, &c, d, e, f, &g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
Round(g, h, a, &b, c, d, e, &f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
Round(f, g, h, &a, b, c, d, &e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
Round(e, f, g, &h, a, b, c, &d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, &g, h, a, b, &c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, &f, g, h, a, &b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, &e, f, g, h, &a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
s[0] += a;
s[1] += b;
s[2] += c;
s[3] += d;
s[4] += e;
s[5] += f;
s[6] += g;
s[7] += h;
}
static bool alignment_ok(const void *p UNUSED, size_t n UNUSED)
{
#if HAVE_UNALIGNED_ACCESS
return true;
#else
return ((size_t)p % n == 0);
#endif
}
static void add(struct sha256_ctx *ctx, const void *p, size_t len)
{
const unsigned char *data = p;
size_t bufsize = ctx->bytes % 64;
if (bufsize + len >= 64) {
/* Fill the buffer, and process it. */
memcpy(ctx->buf.u8 + bufsize, data, 64 - bufsize);
ctx->bytes += 64 - bufsize;
data += 64 - bufsize;
len -= 64 - bufsize;
Transform(ctx->s, ctx->buf.u32);
bufsize = 0;
}
while (len >= 64) {
/* Process full chunks directly from the source. */
if (alignment_ok(data, sizeof(uint32_t)))
Transform(ctx->s, (const uint32_t *)data);
else {
memcpy(ctx->buf.u8, data, sizeof(ctx->buf));
Transform(ctx->s, ctx->buf.u32);
}
ctx->bytes += 64;
data += 64;
len -= 64;
}
if (len) {
/* Fill the buffer with what remains. */
memcpy(ctx->buf.u8 + bufsize, data, len);
ctx->bytes += len;
}
}
void sha256_init(struct sha256_ctx *ctx)
{
struct sha256_ctx init = SHA256_INIT;
*ctx = init;
}
void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size)
{
check_sha256(ctx);
add(ctx, p, size);
}
void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
{
static const unsigned char pad[64] = {0x80};
uint64_t sizedesc;
size_t i;
sizedesc = cpu_to_be64((uint64_t)ctx->bytes << 3);
/* Add '1' bit to terminate, then all 0 bits, up to next block - 8. */
add(ctx, pad, 1 + ((128 - 8 - (ctx->bytes % 64) - 1) % 64));
/* Add number of bits of data (big endian) */
add(ctx, &sizedesc, 8);
for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++)
res->u.u32[i] = cpu_to_be32(ctx->s[i]);
invalidate_sha256(ctx);
}
#endif
void sha256(struct sha256 *sha, const void *p, size_t size)
{
struct sha256_ctx ctx;
sha256_init(&ctx);
sha256_update(&ctx, p, size);
sha256_done(&ctx, sha);
}
void sha256_u8(struct sha256_ctx *ctx, uint8_t v)
{
sha256_update(ctx, &v, sizeof(v));
}
void sha256_u16(struct sha256_ctx *ctx, uint16_t v)
{
sha256_update(ctx, &v, sizeof(v));
}
void sha256_u32(struct sha256_ctx *ctx, uint32_t v)
{
sha256_update(ctx, &v, sizeof(v));
}
void sha256_u64(struct sha256_ctx *ctx, uint64_t v)
{
sha256_update(ctx, &v, sizeof(v));
}
/* Add as little-endian */
void sha256_le16(struct sha256_ctx *ctx, uint16_t v)
{
leint16_t lev = cpu_to_le16(v);
sha256_update(ctx, &lev, sizeof(lev));
}
void sha256_le32(struct sha256_ctx *ctx, uint32_t v)
{
leint32_t lev = cpu_to_le32(v);
sha256_update(ctx, &lev, sizeof(lev));
}
void sha256_le64(struct sha256_ctx *ctx, uint64_t v)
{
leint64_t lev = cpu_to_le64(v);
sha256_update(ctx, &lev, sizeof(lev));
}
/* Add as big-endian */
void sha256_be16(struct sha256_ctx *ctx, uint16_t v)
{
beint16_t bev = cpu_to_be16(v);
sha256_update(ctx, &bev, sizeof(bev));
}
void sha256_be32(struct sha256_ctx *ctx, uint32_t v)
{
beint32_t bev = cpu_to_be32(v);
sha256_update(ctx, &bev, sizeof(bev));
}
void sha256_be64(struct sha256_ctx *ctx, uint64_t v)
{
beint64_t bev = cpu_to_be64(v);
sha256_update(ctx, &bev, sizeof(bev));
}

View File

@@ -1,14 +0,0 @@
#ifndef PROTOVERSE_TYPEDEFS_H
#define PROTOVERSE_TYPEDEFS_H
#include <stdint.h>
typedef unsigned char u8;
typedef unsigned int u32;
typedef unsigned short u16;
typedef uint64_t u64;
typedef int64_t s64;
#endif /* PROTOVERSE_TYPEDEFS_H */

View File

@@ -1179,7 +1179,7 @@ static INLINE int parse_i64(struct cursor *read, uint64_t *val)
shift = 0;
do {
if (!pull_byte(read, &byte))
if (!cursor_pull_byte(read, &byte))
return 0;
*val |= (byte & 0x7FULL) << shift;
shift += 7;
@@ -1199,7 +1199,7 @@ static INLINE int uleb128_read(struct cursor *read, unsigned int *val)
*val = 0;
for (;;) {
if (!pull_byte(read, &byte))
if (!cursor_pull_byte(read, &byte))
return 0;
*val |= (0x7F & byte) << shift;
@@ -1222,7 +1222,7 @@ static INLINE int sleb128_read(struct cursor *read, signed int *val)
shift = 0;
do {
if (!pull_byte(read, &byte))
if (!cursor_pull_byte(read, &byte))
return 0;
*val |= ((byte & 0x7F) << shift);
shift += 7;
@@ -1241,21 +1241,21 @@ static INLINE int uleb128_read(struct cursor *read, unsigned int *val)
unsigned char p[6] = {0};
*val = 0;
if (pull_byte(read, &p[0]) && (p[0] & 0x80) == 0) {
if (cursor_pull_byte(read, &p[0]) && (p[0] & 0x80) == 0) {
*val = LEB128_1(unsigned int);
if (p[0] == 0x7F)
assert((int)*val == -1);
return 1;
} else if (pull_byte(read, &p[1]) && (p[1] & 0x80) == 0) {
} else if (cursor_pull_byte(read, &p[1]) && (p[1] & 0x80) == 0) {
*val = LEB128_2(unsigned int);
return 2;
} else if (pull_byte(read, &p[2]) && (p[2] & 0x80) == 0) {
} else if (cursor_pull_byte(read, &p[2]) && (p[2] & 0x80) == 0) {
*val = LEB128_3(unsigned int);
return 3;
} else if (pull_byte(read, &p[3]) && (p[3] & 0x80) == 0) {
} else if (cursor_pull_byte(read, &p[3]) && (p[3] & 0x80) == 0) {
*val = LEB128_4(unsigned int);
return 4;
} else if (pull_byte(read, &p[4]) && (p[4] & 0x80) == 0) {
} else if (cursor_pull_byte(read, &p[4]) && (p[4] & 0x80) == 0) {
if (!(p[4] & 0xF0)) {
*val = LEB128_5(unsigned int);
return 5;
@@ -1296,7 +1296,7 @@ static int parse_section_tag(struct cursor *cur, enum section_tag *section)
start = cur->p;
if (!pull_byte(cur, &byte)) {
if (!cursor_pull_byte(cur, &byte)) {
return 0;
}
@@ -1315,7 +1315,7 @@ static int parse_valtype(struct wasm_parser *p, enum valtype *valtype)
start = p->cur.p;
if (unlikely(!pull_byte(&p->cur, (unsigned char*)valtype))) {
if (unlikely(!cursor_pull_byte(&p->cur, (unsigned char*)valtype))) {
return parse_err(p, "valtype tag oob");
}
@@ -1416,7 +1416,7 @@ static int parse_export_desc(struct wasm_parser *p, enum exportdesc *desc)
{
unsigned char byte;
if (!pull_byte(&p->cur, &byte)) {
if (!cursor_pull_byte(&p->cur, &byte)) {
parse_err(p, "export desc byte eof");
return 0;
}
@@ -1523,7 +1523,7 @@ static int parse_name_subsection(struct wasm_parser *p, struct namesec *sec, u32
u8 tag;
u8 *start = p->cur.p;
if (!pull_byte(&p->cur, &tag))
if (!cursor_pull_byte(&p->cur, &tag))
return parse_err(p, "name subsection tag oob?");
if (!is_valid_name_subsection(tag))
@@ -1676,7 +1676,7 @@ static int parse_reftype(struct wasm_parser *p, enum reftype *reftype)
{
u8 tag;
if (!pull_byte(&p->cur, &tag)) {
if (!cursor_pull_byte(&p->cur, &tag)) {
parse_err(p, "reftype");
return 0;
}
@@ -1720,7 +1720,7 @@ static int parse_export_section(struct wasm_parser *p,
static int parse_limits(struct wasm_parser *p, struct limits *limits)
{
unsigned char tag;
if (!pull_byte(&p->cur, &tag)) {
if (!cursor_pull_byte(&p->cur, &tag)) {
return parse_err(p, "oob");
}
@@ -1803,7 +1803,7 @@ static void print_code(u8 *code, int code_len)
make_cursor(code, code + code_len, &c);
for (;;) {
if (!pull_byte(&c, &tag)) {
if (!cursor_pull_byte(&c, &tag)) {
break;
}
@@ -2169,7 +2169,7 @@ static int parse_const_expr(struct expr_parser *p, struct expr *expr)
expr->code = p->code->p;
while (1) {
if (unlikely(!pull_byte(p->code, &tag))) {
if (unlikely(!cursor_pull_byte(p->code, &tag))) {
return note_error(p->errs, p->code, "oob");
}
@@ -2332,7 +2332,7 @@ static int parse_instrs_until_at(struct expr_parser *p, u8 stop_instr,
p->code->p - p->code->start,
dbg_inst, instr_name(stop_instr));
for (;;) {
if (!pull_byte(p->code, &tag))
if (!cursor_pull_byte(p->code, &tag))
return note_error(p->errs, p->code, "oob");
if ((tag != i_if && tag == stop_instr) ||
@@ -2413,7 +2413,7 @@ static int parse_element(struct wasm_parser *p, struct elem *elem)
make_expr_parser(&p->errs, &p->cur, &expr_parser);
if (!pull_byte(&p->cur, &tag))
if (!cursor_pull_byte(&p->cur, &tag))
return parse_err(p, "tag");
if (tag > 7)
@@ -2545,7 +2545,7 @@ static int parse_wdata(struct wasm_parser *p, struct wdata *data)
struct expr_parser parser;
u8 tag;
if (!pull_byte(&p->cur, &tag)) {
if (!cursor_pull_byte(&p->cur, &tag)) {
return parse_err(p, "tag");
}
@@ -2700,7 +2700,7 @@ static int parse_importdesc(struct wasm_parser *p, struct importdesc *desc)
{
u8 tag;
if (!pull_byte(&p->cur, &tag)) {
if (!cursor_pull_byte(&p->cur, &tag)) {
parse_err(p, "oom");
return 0;
}
@@ -4134,7 +4134,7 @@ static int parse_blocktype(struct cursor *cur, struct errors *errs, struct block
{
unsigned char byte;
if (unlikely(!pull_byte(cur, &byte))) {
if (unlikely(!cursor_pull_byte(cur, &byte))) {
return note_error(errs, cur, "parse_blocktype: oob\n");
}
@@ -4656,7 +4656,7 @@ static int parse_bulk_op(struct cursor *code, struct errors *errs,
{
u8 tag;
if (unlikely(!pull_byte(code, &tag)))
if (unlikely(!cursor_pull_byte(code, &tag)))
return note_error(errs, code, "oob");
if (unlikely(tag < 10 || tag > 17))
@@ -6552,7 +6552,7 @@ static INLINE int interp_parse_instr(struct wasm_interp *interp,
{
u8 tag;
if (unlikely(!pull_byte(code, &tag))) {
if (unlikely(!cursor_pull_byte(code, &tag))) {
return interp_error(interp, "no more instrs to pull");
}

View File

@@ -27,6 +27,8 @@ static const unsigned char WASM_MAGIC[] = {0,'a','s','m'};
#define interp_error(p, fmt, ...) note_error(&((p)->errors), interp_codeptr(p), fmt, ##__VA_ARGS__)
#define parse_err(p, fmt, ...) note_error(&((p)->errs), &(p)->cur, fmt, ##__VA_ARGS__)
#include "short_types.h"
enum valtype {
val_i32 = 0x7F,
val_i64 = 0x7E,

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,49 @@
{
"originHash" : "1fc7e0b44329ba72cd285eeb022b5b92582cd01586b920d243cb0485c2e69dcc",
"pins" : [
{
"identity" : "codescanner",
"kind" : "remoteSourceControl",
"location" : "https://github.com/twostraws/CodeScanner.git",
"state" : {
"revision" : "9fa582f4b36c69c2a55bff5fb3377eb170ae273c"
}
},
{
"identity" : "cryptoswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
"state" : {
"revision" : "e74bbbfbef939224b242ae7c342a90e60b88b5ce"
}
},
{
"identity" : "emojikit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/tyiu/EmojiKit",
"state" : {
"revision" : "47a4b1402de26be0299dcb4d667c1faaf21a7874",
"version" : "0.2.0"
}
},
{
"identity" : "emojipicker",
"kind" : "remoteSourceControl",
"location" : "https://github.com/tyiu/EmojiPicker.git",
"state" : {
"revision" : "3f48903721eae223238ff0af17c22d6373d33813",
"version" : "0.2.0"
}
},
{
"identity" : "faviconfinder",
"kind" : "remoteSourceControl",
"location" : "https://github.com/will-lumley/FaviconFinder.git",
"state" : {
"revision" : "9279f4371f4877ca302ba3bf1015f3f58ae4a56c",
"version" : "5.1.4"
}
},
{
"identity" : "gsplayer",
"kind" : "remoteSourceControl",
@@ -14,17 +58,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/onevcat/Kingfisher",
"state" : {
"revision" : "415b1d97fb38bda1e5a6b2dde63354720832110b",
"version" : "7.6.1"
}
},
{
"identity" : "mcemojipicker",
"kind" : "remoteSourceControl",
"location" : "https://github.com/izyumkin/MCEmojiPicker",
"state" : {
"revision" : "e0b4903b75ae1cc418d276d84d1cb946b8a1d73c",
"version" : "1.2.3"
"revision" : "4c6b067f96953ee19526e49e4189403a2be21fb3",
"version" : "8.3.1"
}
},
{
@@ -35,6 +70,15 @@
"revision" : "40b4b38b3b1c83f7088c76189a742870e0ca06a9"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "ee97538f5b81ae89698fd95938896dec5217b148",
"version" : "1.1.1"
}
},
{
"identity" : "swift-markdown-ui",
"kind" : "remoteSourceControl",
@@ -60,7 +104,41 @@
"revision" : "74203046135342e4a4a627476dd6caf8b28fe11b",
"version" : "509.0.0"
}
},
{
"identity" : "swift-trie",
"kind" : "remoteSourceControl",
"location" : "https://github.com/tyiu/swift-trie",
"state" : {
"revision" : "4c50bff6c168f74425f70476be62a072980d2da7",
"version" : "0.1.2"
}
},
{
"identity" : "swiftsoup",
"kind" : "remoteSourceControl",
"location" : "https://github.com/scinfu/SwiftSoup.git",
"state" : {
"revision" : "bba848db50462894e7fc0891d018dfecad4ef11e",
"version" : "2.8.7"
}
},
{
"identity" : "swiftycrop",
"kind" : "remoteSourceControl",
"location" : "https://github.com/benedom/SwiftyCrop",
"state" : {
"revision" : "454d0a0d4faf6f3a19c8d817ab9d7d27524bd79f"
}
},
{
"identity" : "swipeactions",
"kind" : "remoteSourceControl",
"location" : "https://github.com/damus-io/SwipeActions.git",
"state" : {
"revision" : "33d99756c3112e1a07c1732e3cddc5ad5bd0c5f4"
}
}
],
"version" : 2
"version" : 3
}

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D703D7162C66E47100A400EA"
BuildableName = "HighlighterActionExtension.appex"
BlueprintName = "HighlighterActionExtension"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEE227F7A08100C66700"
BuildableName = "damus.app"
BlueprintName = "damus"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<RemoteRunnable
runnableDebuggingMode = "1"
BundleIdentifier = "com.apple.mobilesafari"
RemotePath = "/Library/Developer/CoreSimulator/Volumes/iOS_21F79/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.5.simruntime/Contents/Resources/RuntimeRoot/Applications/MobileSafari.app">
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEE227F7A08100C66700"
BuildableName = "damus.app"
BlueprintName = "damus"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
askForAppToLaunch = "Yes"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEE227F7A08100C66700"
BuildableName = "damus.app"
BlueprintName = "damus"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -40,7 +40,7 @@
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "YES">
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEFC27F7A08200C66700"
@@ -55,6 +55,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableAddressSanitizer = "YES"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

@@ -0,0 +1,75 @@
//
// AppAccessibilityIdentifiers.swift
// damus
//
// Created by Daniel DAquino on 2024-11-18.
//
import Foundation
/// A collection of app-wide identifier constants used to facilitate UI tests to find the element they are looking for.
///
/// ## Implementation notes
///
/// - This is not an exhaustive list. Add more identifiers as needed.
/// - Organize this by separating each category with `MARK` comment markers and a unique prefix, each category separated by 2 empty lines
enum AppAccessibilityIdentifiers: String {
// MARK: Login
// Prefix: `sign_in`
/// Sign in button at the very start of the app
case sign_in_option_button
/// A secure text entry field where the user can put their private key when logging in
case sign_in_nsec_key_entry_field
/// Button to sign in after entering private key
case sign_in_confirm_button
// MARK: Onboarding
// Prefix: `onboarding`
/// Any interest option button on the "select your interests" page during onboarding
case onboarding_interest_option_button
/// The "next" button on the onboarding interest page
case onboarding_interest_page_next_page
/// The "next" button on the onboarding content settings page
case onboarding_content_settings_page_next_page
/// The skip button on the onboarding sheet
case onboarding_sheet_skip_button
// MARK: Post composer
// Prefix: `post_composer`
/// The cancel post button
case post_composer_cancel_button
// MARK: Main interface layout
// Prefix: `main`
/// Profile picture item on the top toolbar, used to open the side menu
case main_side_menu_button
// MARK: Side menu
// Prefix: `side_menu`
/// The profile option in the side menu
case side_menu_profile_button
// MARK: Items specific to the user's own profile
// Prefix: `own_profile`
/// The edit profile button
case own_profile_edit_button
/// The button to edit the banner image on the profile
case own_profile_banner_image_edit_button
/// The button to pick the new banner image from URL
case own_profile_banner_image_edit_from_url
}

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 511 KiB

After

Width:  |  Height:  |  Size: 511 KiB

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xD7",
"green" : "0xD1",
"red" : "0xD1"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x13",
"green" : "0x11",
"red" : "0x11"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF9",
"green" : "0xF3",
"red" : "0xF3"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x25",
"green" : "0x22",
"red" : "0x22"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "244",
"green" : "218",
"red" : "244"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "92",
"green" : "45",
"red" : "93"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "236",
"green" : "194",
"red" : "238"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "109",
"green" : "49",
"red" : "111"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "197",
"green" : "67",
"red" : "204"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "255",
"green" : "194",
"red" : "255"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF2",
"green" : "0xD8",
"red" : "0xF4"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x45",
"green" : "0x17",
"red" : "0x47"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 187 KiB

View File

@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "profile-banner.jpeg",
"filename" : "damoose.jpeg",
"idiom" : "universal"
}
],

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 146 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 547 KiB

After

Width:  |  Height:  |  Size: 547 KiB

View File

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "alby.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "alby.svg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "alby.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 300 KiB

After

Width:  |  Height:  |  Size: 300 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "bbw.jpg",
"filename" : "blink.png",
"idiom" : "universal"
}
],

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

Before

Width:  |  Height:  |  Size: 215 KiB

After

Width:  |  Height:  |  Size: 215 KiB

View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "coinos.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tor.svg.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Some files were not shown because too many files have changed in this diff Show More