Compare commits

..

1648 Commits

Author SHA1 Message Date
eb889a7591 Optimize classify_url function
Changelog-Fixed: Optimized classify_url function
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2025-05-06 10:58:39 -04:00
c9696dd9c8 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-06 10:56:39 -04:00
212b4785fb 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-06 10:55:35 -04: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
6cd9d7b1da Remove unused Trie and UserSearchCache as they have been superseded by NostrDB 2024-06-09 11:04:06 -04:00
Daniel D’Aquino
2c84184dbd Improve UX feedback around notification mode setting
Changing the notification mode setting requires successfully sending or
revoking the device token to the server. As this is an action that might
fail, it is important to have a clear UX feedback in case this fails.

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.4
Damus: This commit
strfry-push-notify: d6c2ff289c80e0a90874a7499ed6408394659fc9
Coverage:
1. Checked that push notification mode setting is invisible when experimental push notifications mode is disabled
2. Checked that push notification mode setting is visible when experimental push notifications mode is enabled
3. Checked that switching between push and local notifications sends requests to the server
4. Checked that switching to push notification mode will cause local notifications to be suppressed and push notifications will be sent to the APNS server
5. Checked that switching back to local notification mode will cause local notifications to be displayed, and push notifications will NOT be sent to APNS
6. Checked that if the API server is off, switching from local to push notification modes is not possible and shows an error to the user.
7. Checked that sending APNS payload to Apple's test APNS page will actually deliver the push notification successfully.

Closes: https://github.com/damus-io/damus/issues/1704
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-24 16:49:09 -07:00
Daniel D’Aquino
901a6fc98f Revoke device token when user switches to local notification mode
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-24 16:49:09 -07:00
Daniel D’Aquino
a0f6bdd8d9 Send device token when switching to push notifications mode
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-24 16:49:09 -07:00
Daniel D’Aquino
8feb228ea0 Add NIP-98 authentication to push notification client
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-24 16:49:09 -07:00
Daniel D’Aquino
b148fb735e Move device token sending logic to its own component
This commit moves the device token logic to a new
PushNotificationClient, to move complexity from this specific feature
away from damusApp.swift

This commit also slightly improves the handling of device tokens, by
caching it on the client struct even if the user is using local
notifications, so that the device token can be sent to the server immediately after
switching to push notifications mode.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-24 16:49:09 -07:00
Daniel D’Aquino
0a9bcb6189 Add notification mode setting
This allows the user to switch between local and push notifications

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-24 16:49:09 -07:00
Daniel D’Aquino
5a68cfa448 Fallback push notification suppression while we do not have entitlement
We do not have the ability to suppress push notifications yet (we are
waiting to receive the entitlement from Apple)

In the meantime, attempt to fallback gracefully where possible

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-24 16:49:09 -07:00
alltheseas
c99aaea598 Add working email hyperlink
Closes: https://github.com/damus-io/damus/issues/2260
Closes: https://github.com/damus-io/damus/prs/2272
Changelog-Changed: Added first aid contact damus support email
Signed-off-by: elsat <npub1zafcms4xya5ap9zr7xxr0jlrtrattwlesytn2s42030lzu0dwlzqpd26k5>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-17 15:38:05 -07:00
Daniel D’Aquino
46185c55d1 Chunk home filters to avoid hitting max filter item limits
When a user is following several accounts, they may get a stale feed
caused by the subscription request being rejected by relays (due to max filter item limits).

This commit implements a fix that gets around the issue by
creating several chunked filters for the home feed event and contact
metadata subscriptions.

This is a short to medium-term practical fix, where we get around the
practical limitations imposed by most relays. In the future we should
work on longer-term solutions, which will likely require protocol improvements

Main Test
---------

Procedure:
1. Login with Elsat's npub (Or some account that follows about 2K people)
2. Check the home feed. There should be fresh notes.

REPRO:
Device: iPhone 15 simulator
iOS: 17.4
Damus: 1.9 (3) (0d9954290a)
Results:
- No fresh notes, most recent post is from several hours ago (Feed is stale)

FIX TEST:
Device: iPhone 15 simulator
iOS: 17.4
Damus: This commit
Results:
- Fresh notes appear, most recent post is from a few seconds ago.

Other testing:
--------------

- New automated test passing
- All other automated tests passing
- Tested scrolling down the feed on these conditions:
  - Device: iPhone 13 Mini
  - iOS: 17.4.1
  - Accounts:
    - One with about 160 contacts and 10 relays (Daniel D’Aquino)
    - One with about 1K+ contacts and 9 relays (Freedom Smuggler)
    - One with about 981 contacts and 6 relays (jb55)
    - Elsat's account (2K+ accounts and 8 relays)
  - Result: None of those were stale

Changelog-Fixed: Fix stale feed issue when follow list is too big
Closes: https://github.com/damus-io/damus/issues/2194
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-13 10:56:15 -07:00
William Casarin
52aefc8d64 nip10: simplify and fix reply-to-root bugs
This removes EventRefs alltogether and uses the form we use in Damus
Android.

This simplifies our ThreadReply logic and fixes a reply-to-root bug

Reported-by: NotBiebs <justinbieber@stemstr.app>
Changelog-Fixed: Fix thread bug where a quote isn't picked up as a reply
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-11 09:19:22 -07:00
William Casarin
8dbdff7ff0 1.9 (4)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-10 13:22:20 -07:00
Daniel D’Aquino
784fb20b4f Fix incorrect Privacy manifest plist key
Xcode entered the key description text instead of the actual key code on
our privacy manifest files.

This commit fixes that key.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240509233547.69137-1-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-10 09:22:03 -07:00
William Casarin
0d9954290a 1.9 (3)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 15:29:38 -07:00
William Casarin
13a7ee82d0 nip10: be nicer to deprecated nip10
to ease the transition, let's not add more than 2 etags or deprecated
nip10 gets confused

Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 15:28:16 -07:00
William Casarin
23138c5e03 v1.9 (2)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 15:03:58 -07:00
William Casarin
213a622dde version: damus versions should be inherited from the project
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 15:02:24 -07:00
William Casarin
4ac3da7612 events: try nostrdb cache if we don't have one in-memory
Our nip10 logic looks for notes only in the in-memory cache. This means
sometimes threads don't get fully loaded if for whatever reason it's in
the nostrdb cache but not in-memory.

Ideally we would just remove our in-memory cache, but for now let's just
hack it so it falls back to nostrdb and makes an owned note.

Changelog-Fixed: Fixed threads not loading sometimes
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 14:44:22 -07:00
William Casarin
bb1f912f78 nip10: consolidate event_ref logic into ThreadReply
These are overlapping concepts, lets slowly get rid of EventRef

Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 14:44:22 -07:00
William Casarin
a190a5e8fb nip10: handle invalid reply-with-no-root
I noticed a few clients do this even though its not valid. Let's handle it.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 13:49:06 -07:00
William Casarin
514a053dce nip10: marker replies
This should drastically increase compatibility for damus replies in
other clients.

Also filter non-pubkey references when replying so we don't run into the
q-tag bug.

Changelog-Added: Added nip10 marker replies
Changelog-Fixed: Fixed issue where some replies were including the q tag
Fixes: https://github.com/damus-io/damus/issues/2239
Fixes: https://github.com/damus-io/damus/issues/2233
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 13:33:04 -07:00
William Casarin
0b199a18b4 Revert "perf: debounce scroll queue"
This perf change was experimental and probably minor anyways

This reverts commit d49cf5a505.

Fixes: https://github.com/damus-io/damus/issues/2235
Changelog-Fixed: Fixed issue where timeline was scrolling when it isn't supposed to
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-09 11:11:29 -07:00
William Casarin
23a125ea0f test: add missing mute test file
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 18:13:23 -07:00
Daniel D’Aquino
f406d27507 Add basic word muting automated test
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 18:06:08 -07:00
Daniel D’Aquino
ceb6eb03fb Implement cache on MutelistManager
To filter muted events on a timeline, we need to check if an event is
muted. However, we need to do so in a very efficient manner, to avoid performance degradation.

This commit improves performance by caching mute statuses for as long as
the mutelist stays the same.

Testing
--------

PASS

Device: iPhone 13 Mini
iOS: 17.4.1
Damus: This commit
Damus baseline: bb8dba6df6e2534dfb193402399b31a4fae8052d
Steps:
1. Downgrade to baseline version, Run SwiftUI profiler on Xcode instruments
2. Scroll down home feed. Try to notice hangs and microhangs on the UI
3. Upgrade to version under test. Start the same profiler test.
4. Check that hangs/microhangs frequency and severity are roughly the same.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 18:05:45 -07:00
Daniel D’Aquino
b917b4e9d6 Apply mute rules to Timeline views by default
Mute rules were not applied in all timeline views. This commit adds code
to filter out muted events on timelines. It also provides an opt-out
parameter if there is ever a need to a timeline without mute filters

Testing
--------

PASS

Device: iPhone 13 Mini
iOS: 17.4.1
Damus: This commit
Coverage:
1. Add a muted keyword
2. Go to home view, check that events with that keyword are now not showing up

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 18:05:45 -07:00
Daniel D’Aquino
e981ae247e Mute: Add user_keypair to MutelistManager
The user keypair is necessary to determine whether or not a given event
is muted or not. Previously, the user keypair had to be passed on each
function call as an optional parameter, and word filtering would not
work unless the caller remembered to add the keypair parameter.

All usages of MutelistManager functions indicate that the desired base
keypair is always the same as the DamusState's keypair that owns the
MutelistManager. Therefore, it is simpler and less error prone to simply
pass the keypair to MutelistManager during its initialization.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 18:05:45 -07:00
William Casarin
dcd7b5b111 nip10: fix mixed nip10 markers
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 14:07:47 -07:00
William Casarin
a721256e9b nip10: add marker nip10 support when reading notes
We still need to add these when writing notes.

Changelog-Added: Add marker nip10 support when reading notes
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 14:07:39 -07:00
William Casarin
007bcc8687 test: disable broken auth test
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-07 14:07:14 -07:00
Daniel D’Aquino
ccb94e6d69 Merge pull request #2201 from tyiu/thai
Add Thai as a supported language
2024-05-06 13:06:55 -07:00
William Casarin
3c9fd36654 Merge commit 0a6e40798a ("docs: add NIP04 to readme for encrypted DM's") 2024-05-06 11:54:42 -07:00
Daniel D’Aquino
9a9b5d5f4f Merge Privacy report updates from release branch 'v1.8_relay_fix_and_video_player' 2024-05-06 11:25:52 -07:00
Daniel D’Aquino
d4f041aead Fill up missing Privacy report information for App submission
This commit adds missing privacy report information for both damus and
the notification extension.

It details the reason we use
- File timestamps
- UserDefaults

The reason codes were taken from Apple's documentation: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api

Testing
--------

PASS

Damus: this commit
Steps:
1. Build app for archival
2. Access the local archive and perform a secondary click
3. Click on "Generate Privacy Report"
4. Open the privacy report PDF. It should show no errors. PASS

Closes: https://github.com/damus-io/damus/issues/2184
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-06 11:21:35 -07:00
8133da82c1 Add Thai as a supported language 2024-05-03 21:02:47 -04:00
Daniel D’Aquino
fc8f211da2 Merge pull request #2199 from tyiu/tyiu/search-profile-sort
Refactor UserSearch profile sorting so that it can be used in SearchResultsView
2024-05-03 13:14:16 -07:00
Daniel D’Aquino
cea4922442 Merge release branch 'v1.8_relay_fix_and_video_player'
Manually fixed simple merge conflict in damus.xcodeproj/project.pbxproj
2024-05-03 12:36:58 -07:00
Daniel D’Aquino
669a313f92 Relays: Always respect user's local relay list when present
This commit fixes an issue where the Damus relay (Or other bootstrap relays) would be added to the user's relay list even though they explicitly removed it.

The root cause of the issue lies in the way we load bootstrap relays. The default bootstrap relays would be initially loaded even though the user already has a bootstrap list stored, just in case all the relays on the user list fails. This would cause the app to inadvertently connect to relays that the user did not select whenever there is a connectivity issue with all their listed relays.

The fix is to simply not add the default bootstrap list when the user already has a list stored. We do not need to use bootstrap relays in order to get our relay list, because that list is already stored in both UserDefaults as well as on NostrDB through the user's contact list event. (A contact list which is also locally loaded on startup since the fix related to https://github.com/damus-io/damus/issues/2057)

Issue reproduction + Testing
----------------------------

Procedure:
1. Disconnect from all relays, and disconnect from the Damus relay last.
2. Connect to a local relay (that you control). Connection should be successful.
3. Quit the app completely.
4. Stop the local relay.
5. Restart the app.
6. Go to the relay list view.
7. Check the relay list. It should list the one local relay selected by the user

Issue reproduction:
- Device: iPhone 15 simulator
- iOS: 17.4
- Damus: 1.8 (`97169f4fa276723bfab28ca304953ec206c904d2`)
- Result: ISSUE REPRODUCED
- Details: On step 7, the relay list only lists the Damus relay

Fix test:
- Device: iPhone 15 simulator
- iOS: 17.4
- Damus: This commit
- Result: PASS
- Details: On step 7, the local relay is listed even though connection is unsuccessful. No notes are loaded since no relays were able to connect successfully

Quick regression check
----------------------

PASS

Device: iPhone 15 simulator
iOS: 17.4
Damus: This commit
Steps:
1. Reinstall app from scratch
2. Create a new account, go through onboarding
3. Make sure that new account connects to bootstrap relays. PASS
4. Sign out
5. Sign in with previously existing account (The one from the previous test) (Notice no UserDefaults exists for this user at that point)
6. Make sure relay list is loaded to the latest relay list known to the bootstrap relays (i.e. connects only to the Damus relay) (It cannot recover the latest relay list pointing only to the local relay, since the bootstrap relays have no knowledge about that relay or the contact lists stored there.). PASS

Note: The behavior on step 6 is not a bug, it is an expected limitation. In fact, this behavior is privacy protecting, as the user may not want those public relays from knowing about its connection preference to the local relay (and its address)

Other information
------------------

Q: How is this test using local relays related or equivalent to Tor relay list described in #2186?
A: Those Tor relays need dedicated software (such as Orbot VPN) to be running successfully in order for Damus to make a successful connection to them. If at any moment that VPN stops working, it would trigger the same situation as described in the test above, where all relay connections fail at once.

Q: In #2186, the user reports that the Damus relay is added, but does not describe the Damus relay replacing existing relays. What is the difference?
A: I believe the difference is in the order in which relays are added or removed. We have to remember that the relay we just disconnected from will likely still have version N-1 of our contact list event, where it still includes itself on that list.

Changelog-Fixed: Fix issue where bootstrap relays would inadvertently be added to the user's list on connectivity issues
Closes: https://github.com/damus-io/damus/issues/2186
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-03 12:16:59 -07:00
William Casarin
ac7d6c65c7 Merge remote-tracking branch 'github/translations' 2024-05-03 10:53:36 -05:00
transifex-integration[bot]
c15f0454de Translate Localizable.stringsdict in th
100% translated source file: 'Localizable.stringsdict'
on 'th'.
2024-05-03 09:40:22 +00:00
6bddee0354 Refactor UserSearch profile sorting so that it can be used in SearchResultsView 2024-05-02 18:09:55 -04:00
transifex-integration[bot]
43fc662bf6 Translate Localizable.strings in th
100% translated source file: 'Localizable.strings'
on 'th'.
2024-05-02 13:59:49 +00:00
transifex-integration[bot]
d2b7878d03 Translate InfoPlist.strings in th
100% translated source file: 'InfoPlist.strings'
on 'th'.
2024-05-02 02:13:52 +00:00
Daniel D’Aquino
c6d9e0b3c9 Fix GIF uploads
This commit fixes GIF uploads and improves GIF support:
- MediaPicker will now skip location data removal processing, as it is not needed on GIF images and causes them to be converted to JPEG images
- The uploader now sets more accurate MIME types on the upload request

Issue Repro
-----------

Device: iPhone 13 Mini
iOS: 17.4.1
Damus: `ada99418f6fcdb1354bc5c1c3f3cc3b4db994ce6`
Steps:
1. Download a GIF from GIPHY to the iOS photo gallery
2. Upload that and attach into a post in Damus
3. Check if GIF is animated.
Results: GIF is not animated. Issue is reproduced.

Testing
-------

PASS

Device: iPhone 13 Mini
iOS: 17.4.1
Damus: this commit
Steps:
1. Create a new post
2. Upload the same GIF as the repro and post
3. Make sure GIF is animated. PASS
4. Create a new post
5. Upload a new GIF image (that has never been uploaded by the user on the app) and post
6. Make sure the GIF is animated on the post. PASS
7. Make sure that JPEGs can still be successfully uploaded. PASS
8. Make sure that MP4s can be uploaded.
9. Make a new post that contains 1 JPEG, 1 MP4 file, and 2 GIF files. Make sure they are all uploaded correctly and all GIF files are animated. PASS

Closes: https://github.com/damus-io/damus/issues/2157
Changelog-Fixed: Fix broken GIF uploads
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-01 10:27:05 -07:00
Daniel D’Aquino
97169f4fa2 Fix GIF uploads
This commit fixes GIF uploads and improves GIF support:
- MediaPicker will now skip location data removal processing, as it is not needed on GIF images and causes them to be converted to JPEG images
- The uploader now sets more accurate MIME types on the upload request

Issue Repro
-----------

Device: iPhone 13 Mini
iOS: 17.4.1
Damus: `ada99418f6fcdb1354bc5c1c3f3cc3b4db994ce6`
Steps:
1. Download a GIF from GIPHY to the iOS photo gallery
2. Upload that and attach into a post in Damus
3. Check if GIF is animated.
Results: GIF is not animated. Issue is reproduced.

Testing
-------

PASS

Device: iPhone 13 Mini
iOS: 17.4.1
Damus: this commit
Steps:
1. Create a new post
2. Upload the same GIF as the repro and post
3. Make sure GIF is animated. PASS
4. Create a new post
5. Upload a new GIF image (that has never been uploaded by the user on the app) and post
6. Make sure the GIF is animated on the post. PASS
7. Make sure that JPEGs can still be successfully uploaded. PASS
8. Make sure that MP4s can be uploaded.
9. Make a new post that contains 1 JPEG, 1 MP4 file, and 2 GIF files. Make sure they are all uploaded correctly and all GIF files are animated. PASS

Closes: https://github.com/damus-io/damus/issues/2157
Changelog-Fixed: Fix broken GIF uploads
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-01 10:25:19 -07:00
Daniel D’Aquino
862101a3f7 Fix Ghost notifications from Damus Purple Impending expiration
This commit fixes the "ghost notifications" experienced by Purple users
whose membership has expired (or about to expire).

It does that by using a similar mechanism as other notifications to keep
track of the last event date seen on the notifications tab in a
persistent way.

Testing
--------

iOS: 17.4
Device: iPhone 15 simulator
damus-api: bfe6c4240a0b3729724162896f0024a963586f7c
Damus: This commit
Setup:
1. Local Purple server
2. Damus running on local testing mode for Purple
3. An existing but expired Purple account (on the local server)

Steps:
1. Reopen app after pointing to the new server and setting things up.
2. Check that the bell icon shows there is a new notification. PASS
3. Check that purple expiration notifications are visible. PASS
4. Restart app.
5. Check the bell icon. This time there should be no new notifications. PASS
6. Using another account, engage with the primary test account to cause a new notification to appear.
7. After a second or two, the bell icon should indicate there is a new notification from the other user. PASS
8. Switch out and into the app. Check that the bell icon does not indicate any new notifications. PASS
9. Restart the app again. The bell icon should once again NOT indicate any new notifications. PASS

Changelog-Fixed: Fix ghost notifications caused by Purple impending expiration notifications
Closes: https://github.com/damus-io/damus/issues/2158
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-05-01 10:08:54 -07:00
Daniel D’Aquino
a9a2a52881 ui: add First Aid view to settings
also create the contact list reset First Aid action

Automatically detecting whether or not to create a blank contact list
when we could not find any is very tricky. It could mean that no contact
list exists, but it could also mean that a temporary network or relay
outage occurred.

Since resetting the contact list when one already exists is a
destructive action, we should make no assumptions. Instead, we should
provide users the tool to fix it based on their own judgement.

For that reason, the first aid view was created. It detects if no
contact list was found, and in those cases, it gives them an option to
reset (with appropriate warning messages).

Testing 1: Contact list creation robustness
-----------------------------

Setup:
1. Network Link Conditioner installed and configured to this profile:
  - DNS delay: 400 ms
  - Downlink bandwidth: 100 kbps
  - Uplink bandwidth: 50 kbps
  - Packets dropped: 50% (On both uplink and downlink)
  - Delay: 1000 ms (Both uplink and downlink)

Procedure:
1. Turn Network Link conditioner ON
2. Go through the account creation steps
3. At the moment the onboarding follow suggestions screen shows up, quit the app
3. Turn Network Link conditioner OFF
4. Start the app again
5. Verify the home screen. It should present notes from the Damus account (the default follow)
6. Follow someone and wait for 5 seconds
7. Restart app
8. Look at the home feed. Notes from user from step 6 should appear, and that user should appear as being followed by you.

- Repro details:
  - Damus version: ada99418f6
  - Device: iPhone 15 simulator
  - iOS: 17.4
  - Number of runs: 3 times
  - Result: FAILS (issue is reproduced) 3 out of 3 times
- Test details:
  - Damus version: This commit
  - Device: iPhone 15 simulator
  - iOS: 17.4
  - Number of runs: 3 times
  - Result: PASSES all criteria 3 out of 3 times

Testing 2: Contact list First Aid
------------------------------

Setup:
1. Reproduce the issue with the old version as outlined in "Testing 1" above
2. Upgrade to the version in this commit

Steps:
1. Go to Settings > First Aid
2. A button to reset the contact list (and some text for context) should appear. PASS
3. Click on the button. A warning message should appear. PASS
4. Click "cancel". The action should be cancelled and nothing should have changed. PASS
5. Click on the reset button again.
6. Click "Continue" on the warning prompt. The reset button will now show "Contact list has been reset" with a green checkmark. PASS
5. Go back to the home tab. Notes from the Damus account should immediately appear. PASS
6. Try to follow someone and restart the app. Follows should now stick persistently. PASS
7. Go to the First Aid screen again. The reset option should no longer be present. PASS

Changelog-Added: Add First Aid solution for users who do not have a contact list created for their account
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240422230912.65056-4-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-01 10:01:12 -07:00
Daniel D’Aquino
c8aba00f85 contacts: save first list to storage during onboarding
This commit adds a mechanism to add the contact list to storage as soon
as it is generated, and thus it reduces the risk of poor network
conditions causing issues.

Changelog-Fixed: Improve reliability of contact list creation during onboarding
Closes: https://github.com/damus-io/damus/issues/2057
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240422230912.65056-3-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-01 09:56:44 -07:00
Daniel D’Aquino
bb321b6e8a contacts: save the users' latest contact event ID
... to a persistent setting, and try to load it from NostrDB on app start.

This commit causes the user's contact list event ID to be saved
persistently as a user-specific setting, and to be loaded immediately
after startup from the local NostrDB instance.

This helps improve reliability around contact lists, since we previously
relied on fetching that contact list from other relays.

Eventually we will not need the event ID to be stored at all, as we will
be able to query NostrDB, but for now having the latest event ID
persistently stored will allow us to get around this limitation in the
cleanest possible way (i.e. without having to store the event itself
into another mechanism, and migrating it later to NostrDB)

Other notes:

- It uses a mechanism similar to other user settings, so it is
  pubkey-specific and should handle login/logout cases

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240422230912.65056-2-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-05-01 09:56:30 -07:00
Daniel D’Aquino
6d5a152c17 Fix Ghost notifications from Damus Purple Impending expiration
This commit fixes the "ghost notifications" experienced by Purple users
whose membership has expired (or about to expire).

It does that by using a similar mechanism as other notifications to keep
track of the last event date seen on the notifications tab in a
persistent way.

Testing
--------

iOS: 17.4
Device: iPhone 15 simulator
damus-api: bfe6c4240a0b3729724162896f0024a963586f7c
Damus: This commit
Setup:
1. Local Purple server
2. Damus running on local testing mode for Purple
3. An existing but expired Purple account (on the local server)

Steps:
1. Reopen app after pointing to the new server and setting things up.
2. Check that the bell icon shows there is a new notification. PASS
3. Check that purple expiration notifications are visible. PASS
4. Restart app.
5. Check the bell icon. This time there should be no new notifications. PASS
6. Using another account, engage with the primary test account to cause a new notification to appear.
7. After a second or two, the bell icon should indicate there is a new notification from the other user. PASS
8. Switch out and into the app. Check that the bell icon does not indicate any new notifications. PASS
9. Restart the app again. The bell icon should once again NOT indicate any new notifications. PASS

Changelog-Fixed: Fix ghost notifications caused by Purple impending expiration notifications
Closes: https://github.com/damus-io/damus/issues/2158
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
2024-04-29 17:04:06 -07:00
transifex-integration[bot]
4544d1548c Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2024-04-27 09:31:26 +00:00
transifex-integration[bot]
e1b787c7ed Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2024-04-27 09:31:21 +00:00
transifex-integration[bot]
108456fb59 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2024-04-27 09:31:13 +00:00
transifex-integration[bot]
0982bfbb56 Translate Localizable.stringsdict in zh_TW
100% translated source file: 'Localizable.stringsdict'
on 'zh_TW'.
2024-04-27 08:44:47 +00:00
transifex-integration[bot]
a9e563663a Translate Localizable.stringsdict in zh_HK
100% translated source file: 'Localizable.stringsdict'
on 'zh_HK'.
2024-04-27 08:44:44 +00:00
transifex-integration[bot]
986cc715fa Translate Localizable.stringsdict in zh_CN
100% translated source file: 'Localizable.stringsdict'
on 'zh_CN'.
2024-04-27 08:44:30 +00:00
William Casarin
76529f69d0 Revert "Cache videos"
This reverts commit 26d2627a1c.
2024-04-25 14:56:49 -07:00
William Casarin
052ea9b727 Revert "Custom video loader caching technique"
This reverts commit ba494f94ab.
2024-04-25 14:56:29 -07:00
transifex-integration[bot]
ea4c2a1d1c Translate Localizable.stringsdict in vi
100% translated source file: 'Localizable.stringsdict'
on 'vi'.
2024-04-25 20:05:12 +00:00
transifex-integration[bot]
3c77d58b11 Translate Localizable.strings in vi
100% translated source file: 'Localizable.strings'
on 'vi'.
2024-04-25 20:05:02 +00:00
transifex-integration[bot]
3cea556827 Translate Localizable.strings in es_ES
100% translated source file: 'Localizable.strings'
on 'es_ES'.
2024-04-25 15:47:20 -04:00
transifex-integration[bot]
c5bdb22a86 Translate Localizable.strings in es_ES
100% translated source file: 'Localizable.strings'
on 'es_ES'.
2024-04-25 15:47:20 -04:00
transifex-integration[bot]
3142fd5700 Translate Localizable.strings in es_ES
100% translated source file: 'Localizable.strings'
on 'es_ES'.
2024-04-25 15:47:19 -04:00
William Casarin
95cf45073d Merge translations 2024-04-25 12:41:12 -07:00
transifex-integration[bot]
efd3c95c10 Translate Localizable.stringsdict in es_ES
100% translated source file: 'Localizable.stringsdict'
on 'es_ES'.
2024-04-25 19:08:23 +00:00
transifex-integration[bot]
d198206cc2 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-04-25 18:13:02 +00:00
transifex-integration[bot]
0b0bcedb1e Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-04-25 17:57:59 +00:00
transifex-integration[bot]
5f7855d6d3 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-04-25 17:56:48 +00:00
transifex-integration[bot]
e3db84778a Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2024-04-25 17:22:18 +00:00
transifex-integration[bot]
5363a0313f Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-04-25 17:21:37 +00:00
transifex-integration[bot]
cb116b0f85 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-04-25 16:20:39 +00:00
transifex-integration[bot]
62e40d2824 Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2024-04-25 15:31:39 +00:00
e0b1985df5 Fix localization issues 2024-04-25 09:30:27 -04:00
be585e914d Add Finnish translations 2024-04-24 23:34:50 -04:00
transifex-integration[bot]
e515bf7322 Translate Localizable.strings in fa
100% translated source file: 'Localizable.strings'
on 'fa'.
2024-04-24 23:11:36 -04:00
transifex-integration[bot]
050f38feac Translate Localizable.strings in ko
100% translated source file: 'Localizable.strings'
on 'ko'.
2024-04-24 23:11:36 -04:00
transifex-integration[bot]
b94a435a9b Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2024-04-24 23:11:35 -04:00
Daniel D’Aquino
279854a9fd ui: add First Aid view to settings
also create the contact list reset First Aid action

Automatically detecting whether or not to create a blank contact list
when we could not find any is very tricky. It could mean that no contact
list exists, but it could also mean that a temporary network or relay
outage occurred.

Since resetting the contact list when one already exists is a
destructive action, we should make no assumptions. Instead, we should
provide users the tool to fix it based on their own judgement.

For that reason, the first aid view was created. It detects if no
contact list was found, and in those cases, it gives them an option to
reset (with appropriate warning messages).

Testing 1: Contact list creation robustness
-----------------------------

Setup:
1. Network Link Conditioner installed and configured to this profile:
  - DNS delay: 400 ms
  - Downlink bandwidth: 100 kbps
  - Uplink bandwidth: 50 kbps
  - Packets dropped: 50% (On both uplink and downlink)
  - Delay: 1000 ms (Both uplink and downlink)

Procedure:
1. Turn Network Link conditioner ON
2. Go through the account creation steps
3. At the moment the onboarding follow suggestions screen shows up, quit the app
3. Turn Network Link conditioner OFF
4. Start the app again
5. Verify the home screen. It should present notes from the Damus account (the default follow)
6. Follow someone and wait for 5 seconds
7. Restart app
8. Look at the home feed. Notes from user from step 6 should appear, and that user should appear as being followed by you.

- Repro details:
  - Damus version: ada99418f6
  - Device: iPhone 15 simulator
  - iOS: 17.4
  - Number of runs: 3 times
  - Result: FAILS (issue is reproduced) 3 out of 3 times
- Test details:
  - Damus version: This commit
  - Device: iPhone 15 simulator
  - iOS: 17.4
  - Number of runs: 3 times
  - Result: PASSES all criteria 3 out of 3 times

Testing 2: Contact list First Aid
------------------------------

Setup:
1. Reproduce the issue with the old version as outlined in "Testing 1" above
2. Upgrade to the version in this commit

Steps:
1. Go to Settings > First Aid
2. A button to reset the contact list (and some text for context) should appear. PASS
3. Click on the button. A warning message should appear. PASS
4. Click "cancel". The action should be cancelled and nothing should have changed. PASS
5. Click on the reset button again.
6. Click "Continue" on the warning prompt. The reset button will now show "Contact list has been reset" with a green checkmark. PASS
5. Go back to the home tab. Notes from the Damus account should immediately appear. PASS
6. Try to follow someone and restart the app. Follows should now stick persistently. PASS
7. Go to the First Aid screen again. The reset option should no longer be present. PASS

Changelog-Added: Add First Aid solution for users who do not have a contact list created for their account
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240422230912.65056-4-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-23 16:41:01 -07:00
Daniel D’Aquino
19ba020bd0 contacts: save first list to storage during onboarding
This commit adds a mechanism to add the contact list to storage as soon
as it is generated, and thus it reduces the risk of poor network
conditions causing issues.

Changelog-Fixed: Improve reliability of contact list creation during onboarding
Closes: https://github.com/damus-io/damus/issues/2057
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240422230912.65056-3-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-23 16:40:50 -07:00
Daniel D’Aquino
43a5bbd53a contacts: save the users' latest contact event ID
... to a persistent setting, and try to load it from NostrDB on app start.

This commit causes the user's contact list event ID to be saved
persistently as a user-specific setting, and to be loaded immediately
after startup from the local NostrDB instance.

This helps improve reliability around contact lists, since we previously
relied on fetching that contact list from other relays.

Eventually we will not need the event ID to be stored at all, as we will
be able to query NostrDB, but for now having the latest event ID
persistently stored will allow us to get around this limitation in the
cleanest possible way (i.e. without having to store the event itself
into another mechanism, and migrating it later to NostrDB)

Other notes:

- It uses a mechanism similar to other user settings, so it is
  pubkey-specific and should handle login/logout cases

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240422230912.65056-2-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-23 16:40:25 -07:00
William Casarin
43630cbfa6 zaps: don't verify deschash
seems like most clients don't do this and apparently simplfies some
zapper implementations. It's not a huge deal for us since people can
fake bolt11s anyways.

Suggested-by: bumi, calle
Link: 20240418230321.1907519-1-jb55@jb55.com
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-23 09:05:13 -07:00
ae2f48484a Change reactions to use a native looking emoji picker
Changelog-Changed: Change reactions to use a native looking emoji picker
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-22 17:24:14 -07:00
William Casarin
2c9b280a04 translations: only translate kind 1s
Deepl-Savings: 8k/year
Reported-by: Semisol
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-22 17:11:19 -07:00
Daniel D’Aquino
ba494f94ab Custom video loader caching technique
This commit brings significant improvements to the video cache feature.

Previously, the cache would merely download the video when requested, in
parallel with AVPlayer which also triggers a video download.

The video cache has been updated to tap into the AVPlayer loading
process, removing the download duplication.

Here is how that works:
1. The player requests an AVAsset from the cache.
2. The cache will return a cached asset if possible, or a special AVURLAsset with a custom `AVAssetResourceLoaderDelegate`.
3. The video player will start sending loading requests to this loader delegate.
4. Upon receiving the first request, the loader delegate begins to download the video data on the background.
5. Upon receiving these requests, the loader delegate will also record the requests, so that it can serve them once possible
6. The loader delegate keeps track of all video data chunks as it receives them from the download task, through the `URLSessionDataDelegate` and `URLSessionTaskDelegate` protocols
7. As it receives data, it checks all pending loading requests from the AVPlayer, and fulfills them as soon as possible
8. If the download fails (e.g. timeout errors, loss of connection), it attempts to restart the download.
9. If the download succeeds, it saves the video to the cache on disk.

Closes: https://github.com/damus-io/damus/issues/1717
Changelog-Added: Add video cache to save network bandwidth
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240411004129.84436-4-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-17 15:06:12 -07:00
Daniel D’Aquino
26d2627a1c Cache videos
This commit implements a simple but functional video cache.

It works by providing a method called `maybe_cached_url`, where a video
URL can be passed in, and this method will either return the URL of a
cached version of this video if available, or the original URL if not. It also
downloads new video URLs on the background into the cache folder for use
next time.

Functional testing
-------------------

PASS

Device: iPhone 15 simulator
iOS: 17.4
Damus: Approximately this commit
Setup:
- Debug connection
- Expiry time locally changed to 5 minutes

Steps:
1. Basic functionality
  1. Go to a profile with lots of videos
  2. Scroll down
  3. Filter logs to only logs that start with "Loading video with URL"
  4. Check that most videos are being loaded from external URLs. PASS
  5. Now restart the app and go to that same profile
  6. Scroll down and watch logs. Videos should now be loaded with an internal file URL. PASS
2. Automatic cache refresh after expiry
  1. Go to the video-heavy profile, make note of the external URL.
  2. Go to a different screen and then come back to that video. Make sure the file was loaded from cache. PASS
  3. Now go to a different screen and wait 5 minutes.
  4. Come back to the same video. It should be loaded from the external URL. PASS
3. "Clear cache" button functionality
  1. Go to the video-heavy profile, make note of the external URL.
  2. Go to a different screen and then come back to that video. Make sure the file was loaded from cache. PASS
  3. Now quit the app (to ensure file is not in use when trying to delete it)
  4. Clear cache in settings
  5. Go back to the same video. It should now be loaded from the external URL. PASS

Performance testing
-----------------------

Device: iPhone 13 mini
iOS: 17.3.1
Damus: This commit
Baseline: 87de88861adb3b41d73998452e7c876ab5ee06bf
Setup:
- Debug connection
- Expiry time locally changed to 5 minutes
- Running on Profile mode, with XCode Instruments

Steps:
1. Start recording network activity with XCode Instruments
2. Go to a video-heavy profile (e.g. Julian Figueroa)
3. Scroll down to a specific video (Make sure to scroll through at least 5 videos)
4. Stop recording and measure the "Bytes In" from "Network connections"
5. Repeat this for all test configurations

Results:
- Baseline (No caching support): 26.74 MiB
- This commit (First run, cleared cache): 40.52 MiB
- This commit (Second run, cache filled with videos): 8.13 MiB

Automated test coverage
------------------------

PASS

Device: iPhone 15 simulator
iOS: 17.4
Damus: This commit
Coverage:
- Ran new automated tests multiple times. PASS 3/3 times
- Ran all other automated tests. PASS

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240411004129.84436-3-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-17 15:06:12 -07:00
Daniel D’Aquino
c2918aaf16 Remove no-op performance tests that were causing issues
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-04-17 15:05:35 -07:00
ericholguin
e332a7f82c ui: Longform Improvements
This patch improves longform previews by including the image title and tags.
In addition with minor UI touch ups.

Testing:

iPhone 15 Pro Max (17.3.1) Dark Mode:
https://v.nostr.build/9zgvv.mp4

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

Closes: https://github.com/damus-io/damus/issues/1742
Changelog-Added: Added title image and tags to longform events
Signed-off-by: ericholguin <ericholguin@apache.org>
Link: 20240415031636.68846-1-ericholguin@apache.org
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-17 15:04:38 -07:00
William Casarin
8fbc9dc773 nwc: disable mutinywallet button for now
async nwc with mutiny is wayyy too complicated for the average user.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-13 17:51:00 -07:00
Daniel D’Aquino
90c68fedfc Bump version to 1.9
This commit bumps up the version to 1.9 to differentiate from 1.8 — which is now tracked on a separate release branch
2024-04-12 18:23:30 -07:00
William Casarin
ada99418f6 eden.nostr.land -> nostr.land
Suggested-by: Semisol
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-12 13:38:38 -07:00
ericholguin
5492d9f499 ux: Relay Detail Redesign
This patch redesigns the relay detail view. The first step needed to
further improve how relays are viewed. In addition, Fees are added to
the relay metadata to present to the user the admission, subscription,
or publication fees a relay may have.

There are various changes made, but mainly several relay details are
moved outside of the main RelayDetail view for easier tracking and
updates.

With this design we will be able to add ratings and relay previews, as
this patch is large enough I will submit that improvement in the future.

iPhone 15 Pro Max (17.3.1) Dark Mode:
https://i.nostr.build/VwVvq.png
https://i.nostr.build/KGO0v.png

iPhone SE (3rd generation) (16.4) Light Mode:
https://i.nostr.build/M5V26.png
https://i.nostr.build/gZKw3.png

Changelog-Added: Relay fees metadata
Changelog-Changed: Relay detail design
Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-04 10:33:28 -07:00
ericholguin
faec79d45d ui: fix cut off emoji reaction
This patch is a simple fix to emoji reactions being cut off.

Fixes: https://github.com/damus-io/damus/issues/1728
Changelog-Fixed: Fix emoji reactions being cut off
Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-04 10:33:28 -07:00
ericholguin
846a786fd0 ux: fix image indicators
Changelog-Fixed: Fix image indicators to limit number of dots to not spill screen beyond visible margins
Closes: https://github.com/damus-io/damus/issues/1227
Closes: https://github.com/damus-io/damus/issues/1295
Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-04 10:33:28 -07:00
Sean Kibler
517f3714e8 postview: add haptic feedback on media upload result
Closes: https://github.com/damus-io/damus/pull/2115
Signed-off-by: Sean Kibler <skibler@protonmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-04-04 10:33:28 -07:00
alltheseas
b733799567 Update issue templates
Added feature request template
2024-03-25 10:12:13 -05:00
alltheseas
db8dfc5edc Update issue templates
Modified issue bug report template.
2024-03-25 10:08:51 -05:00
William Casarin
07c504f701 relay: use hostname in relay list instead of full URL
We already have the full relay URL under the name, we don't need to
repeat it and this is a bit cleaner.

Before:

wss://damus.io
wss://damus.io

After:

damus.io
wss://damus.io

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-25 09:51:01 +00:00
William Casarin
d58d777541 docs: specify that we are referring to Damus not the kernel 2024-03-25 10:34:00 +01:00
Daniel D’Aquino
e951370a76 Fix relay URL trailing slash issues
This commit tries to replace all usage of `String` to represent relay
URLs and use `RelayURL` which automatically converts strings to a
canonical relay URL format that is more reliable and avoids issues related to
trailing slashes.

Test 1: Main issue fix
-----------------------

PASS

Device: iPhone 15 Simulator
iOS: 17.4
Damus: This commit
Steps:
1. Delete all connected relays
2. Add `wss://relay.damus.io/` (with the trailing slash) to the relay list
3. Try to post. Post should succeed. PASS
4. Try removing this newly added relay. Relay should be removed successfully. PASS

Test 2: Persistent relay list after upgrade
--------------------------------------------

PASS

Device: iPhone 15 Simulator
iOS: 17.4
Damus: 1.8 (1) `247f313b` + This commit
Steps:
1. Downgrade to old version
2. Add some relays to the list, some without a trailing slash, some with
3. Upgrade to this commit
4. All relays added in step 2 should still be there, and ones with a trailing slash should have been corrected to remove the trailing slash

Test 3: Miscellaneous regression tests
--------------------------------------

Device: iPhone 15 Simulator
iOS: 17.4
Damus: This commit
Coverage:
1. Posting works
2. Search works
3. Relay connection status works
4. Adding relays work
5. Removing relays work
6. Adding relay with trailing slashes works (it fixes itself to remove the trailing slash)
7. Adding relays with different paths works (e.g. wss://yabu.me/v1 and wss://yabu.me/v2)
8. Adding duplicate relay (but with trailing slash) gets rejected as expected
9. Relay details page works. All items on that view loads correctly
10. Relay logs work
11. Getting follower counts and seeing follow lists on profiles still work
12. Relay list changes persist after app restart
13. Notifications view still work
14. Copying the user's pubkey and profile link works
15. Share note + copy link button still works
16. Connecting NWC wallet works
17. One-tap zaps work
18. Onboarding works
19. Unit tests all passing

Closes: https://github.com/damus-io/damus/issues/2072
Changelog-Fixed: Fix bug that would cause connection issues with relays defined with a trailing slash URL, and an inability to delete them.
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-25 09:24:17 +01:00
ericholguin
b18941383f wallet: add callbackuri for mutiny wallet nwc
Changelog-Added: Added callbackuri for a better ux when connecting mutiny wallet nwc
Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-25 08:58:05 +01:00
ericholguin
f71957e061 ui: update zeus logo for wallet selector
Changelog-Changed: Updated Zeus logo
Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-25 08:58:04 +01:00
William Casarin
68409f3440 docs: simplify contributing
Date: Fri, 22 Mar 2024 10:02:00 +0100
From: William Casarin <jb55@jb55.com>
To: dev@damus.io
Subject: Moving away from email code submissions

Hey there,

Since there are more people joining these days and the idea of training
everyone on how to do email code review is effectively impossible in
2024, I've decided to move away from them. I have scripts that can
convert github pull requests to do offline review on my end, so I no
longer need people to directly email them to me.

You of course can, but if you prefer to use github PRs then that is now
perfectly fine. I still may not use GitHub's code review interface, but
that is just me.

I want to encourage more code review from people other than me, if noone
is set up to do that via email then I would rather not encourage it.

Cheers,

        Will

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-22 10:15:00 +01:00
William Casarin
247f313b54 Merge branch 'video-controls' 2024-03-20 10:19:41 +00:00
Daniel D’Aquino
79fef51f68 Improve Video visibility tracking and automatic play/pause
The DamusAVPlayerView (along with other classes) play or pause based on
their Y position relative to the user's viewport. This is ideal for a
vertical feed of notes.

However, this does not work well on a horizontal carousel, such as when
viewing videos on the full-screen carousel and swiping left/right.

This commit adds a new tracking method based on onAppear/onDisappear
triggers from a lazy stack (which only loads when it is visible), and
applied it to videos shown on a full screen carousel, so that videos
pause when we swipe away from the video.

Incidentally, this also fixes an issue I was seeing where a full screen
video would disappear as soon as I rotated the phone to landscape mode.

Testing
--------

Device: iPhone 13 Mini
iOS: 17.3.1
Damus: This version
Coverage:
1. Scroll down a feed full of videos and make sure videos still autoplay when passing through them. PASS
2. Check videos on the feed are muted by default. PASS
3. Check mute button on the video still works. PASS
4. Check clicking on the video brings it to a full-screen carousel view. PASS
5. Check that videos play unmuted by default on full-screen carousel view. PASS
6. Check that all playback controls work on the full-screen carousel view. PASS
7. Check that clicking outside the video shows/hides the carousel overlays. PASS
8. Check that a summary of the note shows up. PASS
9. Check that clicking on that note takes the user to the thread view. PASS
10. Check that changing phone orientation between portrait and landscape on both full-screen carousel AND full-screen video modes will work as expected. PASS
11. Check close button on full-screen carousel works. PASS
12. Check that swiping the video away exits full-screen carousel. PASS
13. Check that full-screen carousel works with images. PASS
14. Check that a carousel with multiple images/videos can be swiped left and right. PASS
15. Check that swiping away from a video on a full-screen carousel will pause it. PASS
16. Check that clicking on an unmuted video on the feed won't cause double-audio issues. PASS
17. Check that full-screen carousel view looks good on both dark and light modes. PASS

Closes: https://github.com/damus-io/damus/issues/1530
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240318222048.14226-6-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-20 09:55:48 +00:00
Daniel D’Aquino
181d894df0 Improve SwiftUI previews around full-screen carousel
This is a minor SwiftUI preview improvement

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240318222048.14226-5-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-20 09:55:48 +00:00
Daniel D’Aquino
250efd9755 Add event text to full-screen Carousel view
The full screen carousel looks quite empty. When viewing videos, it
looks like the video is being played full screen, when it is really not.

Alas, SwiftUI/UIKit does not provide an API for programmatically
bringing a video player full screen. The closest we can do is show the
system native playback controls.

This can cause confusion to users, and is not the best UX. To get around
these limitations and improve UX, event information and content is added to the full
screen carousel overlay, so that:

- Users can see a piece of the post while they are browsing images and videos
- Users can more clearly tell when the video is being displayed on the full screen carousel or on full screen
- Users have a way to directly go to the thread view within the full screen carousel

Changelog-Added: Add event content preview to the full screen carousel
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240318222048.14226-4-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-20 09:55:48 +00:00
Daniel D’Aquino
671b0b67ce Add playback controls to videos
This commit includes several UX changes to give users better control
over video playback. It also, by design, work arounds a SwiftUI quirk*

Here are the changes to the UX:

1. Videos on the feed only have a mute/unmute button
2. When the user clicks on the video, they are taken to a full screen carousel view (similar to when you click on an image)
3. The full-screen carousel view shows all video playback controls (through a specific SwiftUI hack)
4. If the carousel has multiple videos/images, the user can swipe between them normally as expected

Other UI changes that were made:

- The full screen carousel now uses dark mode (black background, white close button)

* The SwiftUI quirk is that when video views are placed within a TabView with ".page" tab view style, the tabview consumes most of the user gestures, making the video playback controls unusable.

Changelog-Changed: Improve UX around video playback
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240318222048.14226-3-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-20 09:55:48 +00:00
Daniel D’Aquino
98eddf1337 Small tweak to resolve build error
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240318222048.14226-2-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-20 09:55:48 +00:00
William Casarin
b31b917b70 Merge remote-tracking branch 'github/quote-reposts'
This adds quote repost listing support to Damus!

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-17 09:33:29 +00:00
William Casarin
c521998158 ui: add quoted reposts view to threads
This adds quote reposts as an additional detail view on threads. It will
list quoted reposts that have the `q` tag. Not all clients have updated
to this yet (like primal), but hopefully they will soon.

Changelog-Added: Show list of quoted reposts in threads
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-17 08:54:35 +00:00
William Casarin
3f1f257df2 model: upgrade EventsModel to support quote reposts queries
We also switch to using an eventholder because that is a bit nicer
when it comes to rendering quotes in timelines.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-17 08:54:35 +00:00
William Casarin
1339ec3ded note: add is_quote_repost helper
This will be used for excluding quote repost notes from threads

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-17 08:54:35 +00:00
William Casarin
770a845b36 filters: add ContentFilters helper constructor
This is slightly faster for timeline code that needs default filters

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-17 08:54:35 +00:00
William Casarin
68dd47130e eventsmodel: remove inheritence in Reactions/Reposts model
Simplify with new EventsModel constructors. This is slightly less
typesafe but its not a big deal, I hate inheritence more.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-17 08:54:35 +00:00
William Casarin
8cdbc84093 home: add quote repost counter and handler
This adds the initial support code for counting and handling
quote reposts.

Eventually we are going to replace all of the event counts by stats
within nostrdb, but we do this in the meantime now.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-17 08:54:35 +00:00
William Casarin
6111e244de filter: add reposts query filter helper
Add a filter helper to easily query quote repost queries.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-16 12:03:08 +00:00
William Casarin
0043f0059d strings: add pluralized quoted_repost_count string
We will be using this for translating "Quote{,s}" pluralization. For now
we add the english version.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-16 11:59:56 +00:00
alltheseas
4413ec0ec5 Update README.md
added reference to nip-04 encrypted DM support, including link to nostr-protocol nip-04 page
2024-03-13 10:06:01 -05:00
Fonta1n3
0a6e40798a docs: add NIP04 to readme for encrypted DM's 2024-03-13 09:23:18 +08:00
ericholguin
9a83872a22 ui: Add proxy view to selected events
This patch adds the proxy view to selected events.

Fixes: https://github.com/damus-io/damus/issues/2033
Changelog-Added: Proxy Tags are now viewable on Selected Events
Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-12 09:35:28 +00:00
ericholguin
988da17b06 Minor Fixes
This adds the recommended parameter to the relay view used in Wallet view.

Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-12 09:34:21 +00:00
ericholguin
5e530bfc9c ui: Wallet View redesign + Mutiny Wallet integration
This patch redesigns the wallet view to more closely match Rob's design.
In addition this patch allows users to connect to Mutiny Wallet by clicking a button.

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

iPhone 15 Pro Max Light Mode:
https://v.nostr.build/9mKA.mp4

Connected Alby Wallet:
https://i.nostr.build/kyd5.png

Changelog-Added: Connect to Mutiny Wallet Button
Changelog-Changed: Moved paste nwc button to main wallet view
Changelog-Changed: Errors with an NWC will show as an alert
Changelog-Fixed: Issue where NWC Scanner view would not dismiss after a failed scan/paste
Signed-off-by: ericholguin <ericholguin@apache.org>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240310223713.4541-1-ericholguin@apache.org
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-11 10:12:05 +00:00
ericholguin
0719e94fbc ux: Relay View Improvements
This patch removes the Recommended Relay View and the old representation of recommended relays.
Adds a tab view style to the Relay Config View allowing the user to switch between their connected relays
and recommended relays. They can add and remove from the recommended view as well. For users logged in with
a pubkey the add button will no longer be displayed.

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

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

Changelog-Changed: Relay config view user interface

Signed-off-by: ericholguin <ericholguin@apache.org>
Link: 20240307152808.47929-1-ericholguin@apache.org
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-11 10:03:49 +00:00
William Casarin
122775e586 Kick off v1.8 (1)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-11 09:59:21 +00:00
William Casarin
d83d618829 Merge branch 'v1.7-madeira-release' 2024-03-11 09:58:50 +00:00
William Casarin
669ca0d91c v1.7.2
Fix a few appstore iap-subscription purple ux issues

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-11 09:38:29 +00:00
Daniel D’Aquino
ad8d30ded1 Improve mechanism of IAP verification with the server right after purchase
It was observed that sending the receipt to the server right after
performing the StoreKit purchase caused issues due to the receipt not
being completely ready when it got sent, causing rejections by the
server.

This commit, in conjuction with backend changes, implements purchase
verification through transaction IDs directly.

Testing
--------

PASS

Device: iPhone 13 Mini (physical device)
iOS: 17.3.1
Damus: This commit
damus-api: `a878da5598a9344a4d351f9a9da16712ce0615b7`
Setup:
- Local server Setup
- Local testing mode on Damus developer settings
- Clean Sandbox account (Create new sandbox account if clearing purchase history does not work)
- Fresh DB
- App is closed before starting.
- Run app on release target
- MOCK_VERIFY=false on server, with all IAP environment correctly setup
Steps:
1. Make Purple IAP purchase. Make sure that:
    - Server logs indicate `/apple-iap/transaction-id` is being hit and returning HTTP 200. PASS
    - No errors appear on the iOS side. After purchase the welcome sheet should appear, and then the account info. PASS

Part of: https://github.com/damus-io/damus/issues/2036
Changelog-Fixed: Fix in-app purchase issue that would trigger an error on purchase before confirming the account information.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-11 09:29:02 +00:00
Daniel D’Aquino
f738aaf358 Increase verbosity of IAP-related logs
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-03-11 09:28:15 +00:00
William Casarin
5f4c342131 Revert "Merge remote-tracking branch 'github/translations'"
Reverting due to CI error:

```
damus file:///Volumes/workspace/repository/damus/cs.lproj/Localizable.stringsdict

validation failed: Couldn't parse property list because the input data
was in an invalid format (1)
```

This reverts commit fa738c4303, reversing
changes made to 9511ba767a.
2024-03-04 18:31:55 +00:00
William Casarin
fa738c4303 Merge remote-tracking branch 'github/translations'
034f31797e Translate Localizable.strings in de
adb6f66a4f Translate Localizable.strings in zh_TW
a5f438b9c7 Translate Localizable.strings in zh_HK
d7f04d9ab9 Translate Localizable.strings in zh_HK
0b2ea46ef4 Translate Localizable.strings in zh_HK
331ed96d57 Translate Localizable.strings in zh_CN
701a747ed6 Translate Localizable.strings in cs
118c2bf2b2 Translate Localizable.stringsdict in cs
7a4f82c97b Translate Localizable.strings in de
d1e3a06cc6 Translate Localizable.strings in de
b9d960b54b Translate InfoPlist.strings in cs
2024-03-04 17:36:52 +00:00
William Casarin
9511ba767a Merge branch 'v1.7-madeira-release' 2024-03-04 17:28:01 +00:00
William Casarin
d9f78cf805 v1.7.1 (12)
subscriber EULA and privacy policy notices on purple subscription
page

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-04 16:40:55 +00:00
William Casarin
c2d81828d6 purple: mention privacy policy and eula
This is required to be accepted by the appstore

Suggested-by: Apple store reviewer
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-04 16:29:02 +00:00
William Casarin
8da3ab30a5 preview: add purple backdrop to IAPProductStateView
Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-04 16:28:30 +00:00
William Casarin
4e8359458f preview: use PurpleBackdrop in MarketingContentView preview
This improves the preview a bit

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-04 14:04:56 +00:00
William Casarin
c6e37bd864 refactor: introduce PurpleBackdrop
We mainly want to use this to improve previews for now, but might be
useful in the future.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-04 14:03:53 +00:00
William Casarin
8a95e40e0c Merge branch 'translations'
* branch `translations` of https://github.com/damus-io/damus:
  Translate Localizable.strings in de
  Translate Localizable.strings in zh_TW
  Translate Localizable.strings in zh_HK
  Translate Localizable.strings in zh_HK
  Translate Localizable.strings in zh_HK
  Translate Localizable.strings in zh_CN
  Translate Localizable.strings in cs
  Translate Localizable.stringsdict in cs
  Translate Localizable.strings in de
  Translate Localizable.strings in de
  Translate InfoPlist.strings in cs
2024-03-02 09:19:50 +00:00
William Casarin
184fc865bb Bump to 1.7.1
Nothing has changed, but we need to submit a new minor version with
the subscription products since we missed those in the 1.7 appstore
release.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-03-02 09:16:07 +00:00
transifex-integration[bot]
034f31797e Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-02-29 17:35:11 +00:00
kernelkind
556a5bcf4d use camera controller in EditPictureControl
Modify EditPictureControl to use the CameraController exactly as
PostView does.

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Link: 20240228033235.66935-3-kernelkind@gmail.com
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-29 12:12:22 +00:00
kernelkind
6de44223f2 add performance upgrades to media picker
- Use jpeg instead of png data when processing a UIImage.
- Make processing of media occur after user confirms upload selection when possible for better responsiveness.
- Reduce redundant data fetching.

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Link: 20240228033235.66935-2-kernelkind@gmail.com
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-29 12:12:22 +00:00
William Casarin
75d87fee9d Merge tag 'v1.7-rc2'
v1.7 Madeira release RC2

55c26d22cb v1.7 (11)
4c8134908c Enable IAP feature for release
3ac7d75235 Add UI error message when IAP succeeds but receipt verification fails
b49a5f4d29 Purple: Improve UX on Damus Purple renewals
3569919eaf Add Damus Purple impending expiry notification support
2024-02-29 03:11:15 -08:00
Daniel D’Aquino
f6a295dcda Update changelog 2024-02-28 23:56:13 -08:00
Daniel D’Aquino
55c26d22cb v1.7 (11) 2024-02-28 23:41:56 -08:00
Daniel D’Aquino
4c8134908c Enable IAP feature for release
Changelog-Changed: Add support for Apple In-App purchases
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-02-28 23:21:48 -08:00
Daniel D’Aquino
3ac7d75235 Add UI error message when IAP succeeds but receipt verification fails
This should not be visible to end-users on normal circumstances, but we
should regardless show an error message if something goes wrong with the
IAP receipt verification, to prompt them to contact support.

Testing
-------

PASS

Device: iPhone simulator
iOS: 17.2
Damus: This commit
damus-api: d3801376fa204433661be6de8b7974f12b0ad25f
Setup:
- Local Testing server
- Xcode StoreKit environment
Steps:
1. Set MOCK_VERIFY to false on the server (that means receipt verification will fail on Xcode environment)
2. Try to make IAP purchase. Error should appear on UI
3. Set MOCK_VERIFY to true on the server and restart StoreKit environment (Receipt validation will always work)
5. Try to make IAP purchase. Onboarding flow should go as normal with no error messages. PASS

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-02-28 23:21:34 -08:00
Daniel D’Aquino
b49a5f4d29 Purple: Improve UX on Damus Purple renewals
This commit changes when the Damus Purple onboarding gets triggered. Now
it only shows the onboarding if it is the first time they are purchasing
Damus Purple for a Nostr account. If it is not the first they see the
onboarding, they are directed to a sheet that displays their new account
info (e.g. a renewal)

However, if the website links to `damus:purple:welcome` links, the app
will still show the onboarding. This will be addressed on the
website-side by taking them to `damus:purple:landing` instead when it is
a renewal.

Testing
---------

PASS

Device: iPhone 13 mini (Physical device)
iOS: 17.3.1
Damus: This commit
damus-api: d3801376fa204433661be6de8b7974f12b0ad25f
damus-website: 6bb425e324c318ca474417cbd2b2f8bb74f9505f
Setup:
- iOS configured to use a local test environment
- Local damus-api server and local damus-website server setup and properly configured
- Fresh db (i.e. Delete mdb files before starting)
Coverage:
1. LN flow with switching to the app instead of clicking "continue". PASS
  a. Ensure that first purchase will result in onboarding being shown. PASS
  b. Ensure that second purchase will result in onboarding NOT being shown (User should be taken to the account info screen). PASS
  c. Restart app completely. Ensure third purchase will result in onboarding NOT being shown (only account info screen). PASS
2. LN flow with clicking continue (Since website changes are not ready, we will simulate them by manually generally appropriate "continue" URL QR codes)
  a. Note: Clear DB again before starting this portion, and completely restart app.
  b. Ensure that first purchase will result in onboarding being shown. PASS
  c. Ensure that second purchase (with continue URL manually hard-coded to `damus:purple:landing`) results in account info being shown with updated info. PASS
  d. Restart app completely and repeat test 2(c). PASS

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-02-28 23:21:14 -08:00
Daniel D’Aquino
3569919eaf Add Damus Purple impending expiry notification support
This commit adds Damus Purple expiry notification support.

How it works: Whenever the app initiates or enters the foreground, it
checks the user's account expiry, and calculates what notifications to
display (It is functional, not imperative, to better match how
the notifications view works)

The notification handlers work the same as every other notification
handler for Nostr events. However, local iOS notifications were not
implemented to maintain these reminders more discreet.

Current limitations:
- Notifications cannot be dismissed
- Notifications are dismissed only when Damus Purple is extended
- After making a purchase, notifications are not dismissed right away
- Bell icon with purple badge shows up on every app restart if user's account is expired

Testing
-------

Device: iPhone 13 Mini
iOS: 17.3.1
Damus: This commit
damus-api: d3801376fa204433661be6de8b7974f12b0ad25f
Setup:
- Local servers Setup
- Debug endpoints enabled for changing expiry date on the fly
Coverage:
1. Expired account
  1. Starting the app on home screen shows bell icon with purple badge. PASS
  2. 4 notifications appear on notifications view (7,3,1,0 days to expiry). PASS
  3. Notifications appear in correct chronological order. PASS
  4. Notifications look consistent in appearance. PASS
  5. Expiry notifications' text size follows text size settings. PASS
  6. Clicking on notification CTA takes user to account info page. PASS
2. Non-expired account (set expiry, restart app)
  1. No expiry notifications, no bell icon. PASS
3. Expiry in 6 days (set expiry, restart app)
  1. Starting the app on home screen shows bell icon with purple badge. PASS
  2. Starting the app on the notification screen renders notifications the same way. PASS
  3. Only one notification (7 days remaining) appears. PASS
4. Expiry in 2 days. PASS
5. General
  1. Clicking bell icon clears away "new notifications" badge. PASS
  2. Performance of notifications view does not seem affected. PASS
  3. Performance of app on startup does not seem affected. PASS
6. IAP
  1. Active IAP + expiry date in 2 days does not trigger reminder notification (Because it is auto-renewed). PASS

Closes: https://github.com/damus-io/damus/issues/1973
Changelog-Added: Notification reminders for Damus Purple impending expiration
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2024-02-28 23:20:48 -08:00
William Casarin
55000e9d4d Merge improved mute functionality from Charlie
This merge adds a bunch of new features from charlie's work on the new
mutelist changes:

- Muted words

- Mute performance optimizations

- New mute list UI

I needed to make a few changes to fix the tests in this merge. Otherwise
it seems to work ok!

Thank to Charlie for getting all of this working after many rounds of
review!

* branch `mute` of https://github.com/damus-io/damus:
  mute: fix bug with duplicate Indefinite items in MuteDurationMenu
  mute: fix mute hashtag from search view if no existing mutelist
  mute: integrate new MutelistManager
  mute: adding MutelistManager.swift
  mute: add maybe_get_content function to NdbNote
  mute: fix bug where mutes can't be added without existing mutelist
  mute: fix issue with not being able to change mute duration
  mute: don't mutate string when adding hashtag
  mute: implement fast MuteItem decoder
  tags: add u64 decoding function
  mute: migrating muted_threads to new mute list
  mute: adding ability to mute hashtag from SearchView
  mute: updating UI to support new mute list
  mute: adding filtering support for MuteItem events
  mute: receiving New Mute List Type
  mute: migrate Lists.swift to use new MuteItem
  mute: add new UI views for new mute list
  mute: adding new structs/enums for new mute list

Changelog-Added: Add ability to mute words, add new mutelist interface (Charlie)
2024-02-26 12:02:41 -08:00
Charlie Fish
68a18f5e40 mute: fix bug with duplicate Indefinite items in MuteDurationMenu
The `Indefinite` was added to DamusDuration in "Fixing issue with not
being able to change mute duration” so this needs to be removed so that
there isn’t a repeative item in the menu.

Lighting-Address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240210163650.42884-6-contact@charlie.fish
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-26 11:31:04 -08:00
Charlie Fish
a18f50f250 mute: fix mute hashtag from search view if no existing mutelist
There is a bug where if a user creates a new account and tries to mute a
hashtag from the search view it will fail silently. This is due to the
fact that the user has no existing mutelist.

Lighting-Address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240210163650.42884-5-contact@charlie.fish
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-26 11:30:21 -08:00
Charlie Fish
1d4d2b0204 mute: integrate new MutelistManager
This patch is slightly large (I think still within the guidelines tho) ,
but also pretty straightforward. I thought for a while about how I could
split this up in a straightforward way, and I couldn’t come up with
anything without breaking intermediate builds.

- Deleted a lot of old/unnecessary code (ie. the Collection extension
  for MuteItem, since we’re now using the MutelistManager sets)

- Changed damus_state.contacts to damus_state.mutelist_manager for all
  mute list manager work

- Updated MutelistView to take advantage of new code (this is probably
  the largest change in this patch)

Lighting-Address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240210163650.42884-4-contact@charlie.fish
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-26 11:30:03 -08:00
Charlie Fish
a9baef7a21 mute: adding MutelistManager.swift
This patch adds MutelistManager which contains separate sets for each
type of muted item.

Whenever we receive a new event we parse it into those sets.

When checking to see if an event is muted, we simply check in each of
those sets if it contains the given mute. For words/phrases we have to
loop through each item in the set to see if the event contains the given
word.

In future patches I will be implementing and integrating this new
MutelistManager.

Lighting-Address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240210163650.42884-3-contact@charlie.fish
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-26 11:29:41 -08:00
Charlie Fish
96ed6b7cc7 mute: add maybe_get_content function to NdbNote
This patch adds a maybe_get_content method to NdbNote which returns an
optional string instead of “*failed to decrypt content*” on DM
decryption failure.

This method will be used by the MutelistManager in future patches.

Lighting-Address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240210163650.42884-2-contact@charlie.fish
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-26 11:29:30 -08:00
William Casarin
94f7e4d1e1 Merge branch 'iap-improvements'
Pull a few patches from v1.7-rc1

purple: show welcome sheet after ln payment
iap: add loading spinner to purchase actions
2024-02-26 10:23:27 -08:00
Daniel D’Aquino
bdc811aa82 purple: show welcome sheet after ln payment
Automatically show welcome sheet for people who completed a Lightning
checkout but did not click on the "Continue" button

Some people get confused in the last step of the lightning checkout and
they do not click on the "Continue in app", which causes the welcome
screen to not show up and the translation setting to not be setup.

This ticket addresses this issue to ensure they get the welcome screen
in such cases.

This is how it works:

- When they go through the mandatory checkout verification step, the
  verify screen registers that there is a checkout in progress (and
  which checkout is in progress) on the DamusPurple struct

- Every time the app enters the foreground, it checks for that flag:

  - If there are no checkouts in progress, it does nothing

  - If there is one or multiple checkouts in progress, it checks the
    checkout status for those. If any checkout is freshly completed and
    successful, and the account is now active, it shows the welcome
    screen and onboarding

- Once the welcome screen is shown, those checkouts are marked
  internally as handled (so that we only show it once)

===========
Testing
===========

PASS

Damus: This commit
Device: iPhone 13 Mini (real physical device)
iOS: 17.3.1
damus-api: 044150fedddc5ba4135a80579e41e9c1c5743fc0
damus-website: af8089128159e25df31141be624b4090c66d6ddf
Setup:
- Local test Setup
- Clean db before starting

PART 1: LN flow without clicking on the link
---------------------------------------------

Steps:

1. Go through the normal LN flow, EXCEPT at the last step. On the last
   step, instead of clicking "continue in the app", just switch to the
   app.

2. Ensure the welcome screen and onboarding shows up, and the purple
   screen updates to show account info. PASS

3. Switch out and into the app again. Welcome screen should NOT show up
   again. PASS

4. Close the app completely and open the app again. Purple welcome
   screen should NOT show up again. PASS

PART 2: Normal LN flow
---------------------------------------------
Steps:

1. Reset the entire test setup

2. Go through the normal LN flow (this time click on "continue in app").
   The welcome screen should show up without issues or glitches. PASS

PART 3: Crazy flow with multiple incomplete checkouts
---------------------------------------------
(This is to simulate a confused user who accidentally opens multiple new
checkouts, but in the end only completes one of them)

Steps:
1. Reset the entire test setup

2. Open 5 LN checkouts and verify npub with all of them.

3. Only pay one of those checkouts (to make it more confusing, don't pay
   the first or last one, but a random one in between)

4. Go to the app directly (Do not use the link, just go directly to the app)

Related: https://github.com/damus-io/damus/issues/1892
Changelog-Fixed: Fix welcome screen not showing if the user enters the app directly after a successful checkout without going through the link
Closes: https://github.com/damus-io/damus/issues/2021
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240223212945.37384-2-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-26 09:54:07 -08:00
Daniel D’Aquino
003348c103 iap: add loading spinner to purchase actions
Apple In-app purchases do not respond immediately. This commit adds a
loading spinner element, to improve the UX and avoid the appearance of a
broken/unresponsive element.

Testing
--------

Device: iPhone 15 simulator
iOS: 17.2
Damus: This commit
Setup:
- Using the sandbox environment
- No tx to start with
- IAP experimental support enabled on developer settings in Damus
Steps:
1. Click "purchase" in any option on the damus purple screen
2. It should show a loading spinner while the purchase action is loading. PASS
3. On the confirmation screen, cancel the purchase.
4. Purchase buttons should show again. PASS

Closes: https://github.com/damus-io/damus/issues/2020
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Link: 20240223212945.37384-1-daniel@daquino.me
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-26 09:53:58 -08:00
kernelkind
1214f1839d media: fix gif upload regression
Uploaded gifs now upload as gifs again instead of still images.

Fixes: 904ae6c24d ("Fix gif upload as still images")
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240220234818.27472-1-kernelkind@gmail.com
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-21 09:56:00 -08:00
kernelkind
7f6540b0c0 translate: remove redundant translation call
When auto-translate is enabled, translations are saved in cache through
preload_event in EventCache so it's redundant and wasteful to call
translate() as an async task

Closes: https://github.com/damus-io/damus/issues/1940
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-20 11:20:31 -08:00
kernelkind
2be83560bc refactor: rename ImagePicker -> MediaPicker
The responsibility of MediaPicker is to 'pick' all sorts of media, not
just images.

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-20 11:19:21 -08:00
kernelkind
4c0c8b6678 privacy: always strip GPS data from images
Images selected from the photo library will automatically have their
gps data stripped regardless of whether the user toggles the 'Location'
button in the system level photo library view.

Changelog-Changed: Always strip GPS data from images
Closes: https://github.com/damus-io/damus/issues/1990
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-20 11:19:01 -08:00
kernelkind
904ae6c24d picker: upgrade to newer image picker controller
Upgrade the ImagePicker to use PHPickerViewController instead of
UIImagePickerController for the photo library since the
PHPickerViewController allows for more options for how the user
shares their media, such as whether location data should be
included.

Create a CameraController since PHPickerViewController is only used for
the photo library. After capturing media with the camera, it will be
saved to the user's photo library and the photo library view will
appear for the user to select the media they captured. The user can then
toggle whether they would like apple to strip their media of location
data before handing it off to Damus.

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-20 11:18:05 -08:00
kernelkind
8d815fe4d6 privacy: add function to strip location data from photos
Add a function to strip GPS data from images before uploading to
hosting service.

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-20 11:17:57 -08:00
kernelkind
58326f679e translate: implement string distance for close matches
Implement the levenshtein string distance algorithm for determining
if the translation is too similar to the original content.

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

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240214032018.57812-1-kernelkind@gmail.com
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-19 13:10:13 -08:00
ericholguin
90180202b6 nip48: initial support
This patch adds a new ProxyView which is added to the Event Shell
whenever an event has the proxy tag. It includes images of the protocol
logos that are listed in the NIP docs.

Reviewed-by: William Casarin <jb55@jb55>.com
Link: 20240205032400.7069-1-ericholguin@apache.org
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-19 12:11:47 -08:00
Daniel D’Aquino
4a4a58c7b5 iap: handle login and logout
This commit adapts the functionality around login/logout with relation
to Damus Purple In-App purchases (IAP). Due to (apparent) limitations on
Renewable subscription In-app purchases (It seems that there can only be
one active IAP subscription per device or Apple ID), these changes add
support for only one IAP subscription at a time.

To prevent confusion, a customer who logs out and logs into a separate
account will see a message indicating the limitation. Any other Nostr
account won't be able to manage IAP on a device that contains an IAP
registered to a different user.

To make this feature possible, the following changes were made to the
code:

1. IAP purchases are now associated with an account UUID. This account
   UUID is generated by the server. Each npub gets one and only one UUID
   for this purpose.

2. This UUID is used to determine which npub owns the IAP on the device.
   It is used as the source of truth when determining whether a
   particular Purple account is manageable on a device or not

3. `DamusPurple` was changed to adhere to a new IAP flow API design
   changes. Previously, the client would create an (inactive) account,
   and then send the IAP receipt to the server for activation. Now, the
   client fetches the npub's UUID from the server, associates it with an
   IAP during purchase, and sends the IAP receipt to the server. The
   server will then bump the expiry (if it's a renewal) or create a new
   active account (if it's the first time).

4. Several changes were made to the StoreKit handling code to improve
   handling:

  a. The `DamusPurple.StoreKitManager` class now records all purchased
     product updates, and sends them to the delegate each time the
     delegate is updated. This helps ensure we do not miss purchased
     product updates regardless of when and if `DamusPurpleView` is ever
     instantiated.

  b. `DamusPurple.StoreKitManager` is now used by `DamusPurple` in a
     singleton pattern via `DamusPurple.StoreKitManager.standard`. This
     helps maintain the local purchase history consistent (and avoid
     losing such data) after `DamusState` or its `DamusPurple` are
     destroyed and re-initialized.

  c. Added logs (using the logger) to help us debug/troubleshoot
     problems in the future

5. Changed the views around DamusPurple, to only show IAP
   purchase/management options if applicable to a particular account. It
   also shows instructive messages in other scenarios.

Testing
-------

damus: This commit
damus-api: d3956ee004a358a39c8570fdbd481d2f5f6f94ab
Device: iPhone 15 simulator
iOS: 17.2
Setup:

- Xcode (local) StoreKit environment
- All StoreKit transactions deleted before starting
- Running `damus` app target (which contains test StoreKit products)

- Local damus-api server running with `npm run dev` and
  `MOCK_VERIFY=true` to disable real receipt verification

- Damus setup with experimental IAP support enabled, and Purple
  environment set to "Test (local)" (localhost)

- Two `nsecs` readily available for account switching
- Clean DB (Delete db files before starting)

Steps:
1. Open the app and sign in to the first account

2. Go to Damus Purple screen. Marketing screen with buttons to purchase
   products should be visible. PASS

3. Buy a product and monitor server logs as well as the screen.
  a. IAP confirmation dialog should appear. PASS

  b. After confirmation, server logs should show a receipt was sent
     IMMEDIATELY and the response should be an HTTP 200. PASS

  c. The welcome and onboarding screens should appear as normal. PASS

  d. Once the onboarding sheet goes away, the Purple screen should now
     show the account information. PASS

  e. The account information should be correct. PASS

  f. Under the account information, there should be a "manage" button. PASS

4. Click on "manage" and verify that the iOS subscription management
   screen appears. PASS

5. Now log out and sign in to the second account

6. Go to Damus Purple screen.
  a. Marketing screen should be visible. PASS

  b. There should be no purchase buttons. instead, there should be a
     message indicating that there can only be one active subscription
     at a time, and that the app is unable to manage subscription for
     this second acocunt. PASS

7. Log out and sign in to the first account. Go to the Purple screen.
  a. Account info with the manage button should be visible like before. PASS

8. Through Xcode, delete transactions, and restart the app. This will
   simulate the case where the user bought the subscription externally.

9. Go to the Purple screen.
  a. Account info should be visible and correct. PASS
  b. Below the account info, there should be a small note telling the
     user to visit the website to manage their billing. PASS

Closes: https://github.com/damus-io/damus/issues/1815
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-19 10:38:59 -08:00
Daniel D’Aquino
d694c26b83 iap: move StoreKit logic out of DamusPurpleView and into a new PurpleStoreKitManager
This commit moves most of StoreKit-specific logic that was embedded into
DamusPurpleView and places it into a new PurpleStoreKitManager struct,
to make code more reusable and readable by separating view concerns from
StoreKit-specific concerns.

Most of the code here should be in feature parity with the previous
behavior. However, a few logical improvements were made alongside this
refactoring:

- Improved StoreKit transaction update monitoring logic: Previously the
  view would stop listening for purchase updates after the first update.
  However, I made the program continuously listen for purchase updates,
  as recommended by Apple's documentation
  (https://developer.apple.com/documentation/storekit/transaction/3851206-updates)

- Improved/simplified logic around getting extra information from the
  products: Information and the handling of product information was
  spread in a few separate places. I incorporated those bits of
  information into central and uniform interfaces on DamusPurpleType, to
  simplify logic and future changes.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-19 10:38:43 -08:00
Daniel D’Aquino
2525799c8a refactor: split views from DamusPurpleView into separate files
This refactoring commit splits several view blocks from DamusPurpleView
into separate files.

- New view structs were defined within the DamusPurpleView namespace, to
  avoid polluting the global namespace

- No logical changes were made. The functionality should have stayed
  equivalent

- Changes were made conservatively, and as semantically as possible, to
  make the code easier to work with.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-19 10:38:21 -08:00
Daniel D’Aquino
b3b6fdc29e refactor: move primitive views from DamusPurpleView into a separate file
This refactoring commit moves primitive, low complexity, helper views
from DamusPurpleView into a separate file, to reduce complexity on
DamusPurpleView.swift.

Although functions were changed into View structs, no logical changes
were made. (New version is functionally equivalent)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-19 10:38:13 -08:00
Daniel D’Aquino
1a131cd179 refactor: re-order items in DamusPurpleView
This is a purely non-functional refactor of DamusPurpleView consisting
only of code mark section comments, and re-ordering for better
organization and to facilitate further refactoring.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-19 10:37:55 -08:00
transifex-integration[bot]
adb6f66a4f Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2024-02-13 07:39:33 +00:00
transifex-integration[bot]
a5f438b9c7 Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2024-02-13 07:34:28 +00:00
transifex-integration[bot]
d7f04d9ab9 Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2024-02-13 07:34:05 +00:00
transifex-integration[bot]
0b2ea46ef4 Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2024-02-13 07:29:25 +00:00
transifex-integration[bot]
331ed96d57 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2024-02-13 07:29:00 +00:00
transifex-integration[bot]
701a747ed6 Translate Localizable.strings in cs
100% translated source file: 'Localizable.strings'
on 'cs'.
2024-02-12 06:16:42 +00:00
William Casarin
ab529c43eb profile: fix bug where profile does not update
Changelog-Fixed: Fix profile not updating bug
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-11 09:05:41 -08:00
William Casarin
b486d5e102 add some more close guards
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-11 08:52:29 -08:00
William Casarin
881dae0954 v1.7 (10)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-11 08:52:03 -08:00
transifex-integration[bot]
118c2bf2b2 Translate Localizable.stringsdict in cs
100% translated source file: 'Localizable.stringsdict'
on 'cs'.
2024-02-09 19:28:54 +00:00
transifex-integration[bot]
7a4f82c97b Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-02-09 17:59:18 +00:00
transifex-integration[bot]
d1e3a06cc6 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-02-09 17:58:50 +00:00
transifex-integration[bot]
b9d960b54b Translate InfoPlist.strings in cs
100% translated source file: 'InfoPlist.strings'
on 'cs'.
2024-02-09 10:05:08 +00:00
Daniel D’Aquino
da82663634 Add option for custom test host in Damus Purple developer settings
This commit adds a developer setting that allows the use of a custom
host for testing. This was added to allow testing on real devices
without the need for pushing changes into staging.

========
Testing
========

Test 1: Production not affected
-------------------------------

PASS

Device: iPhone 13 Mini
iOS: 17.3
Damus: This version
Steps:
1. Run app on a device logged into a real Damus Purple account
2. Scroll down the home feed. Make sure that other Purple members still show up with a star next to their profile. PASS
3. Go to the Damus Purple screen. Ensure that account info shows up and is correct. PASS
4. Ensure auto-translations appear. PASS

Test 2: Check custom test URL
-----------------------------

PASS

(Continued from test 1)
1. Run local damus-api and damus-website on the same computer
2. Change developer purple env setting to local test
3. Set the host url to the local IP address of the test server
4. Go through LN purchase flow. Ensure it works correctly. PASS

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-08 10:08:59 -08:00
Daniel D’Aquino
aeafdccb02 Non-functional auto-formatter refactor
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-08 10:08:24 -08:00
William Casarin
f37957f47e Merge remote-tracking branch 'github/translations' 2024-02-06 10:14:55 -08:00
alltheseas
b5f31ef714 Update README.md
added how Damus and nostr win
2024-02-06 10:06:07 -06:00
alltheseas
907a49813f Update README.md
added funding disclosure
2024-02-06 09:57:36 -06:00
alltheseas
eb383c6bf0 Update README.md
grammar, typos
2024-02-06 09:54:36 -06:00
alltheseas
e72e7b7196 Update README.md
-added purple
-added DM privacy warning
-updated NIPs
-added comparison vs twitter
2024-02-06 09:53:08 -06:00
transifex-integration[bot]
449b9f9f1e Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2024-02-06 06:28:48 +00:00
Daniel D’Aquino
035181b02a Fix local test Purple landing page URL
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-05 11:40:02 -08:00
transifex-integration[bot]
0ab5040caa Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2024-02-03 18:58:08 -05:00
transifex-integration[bot]
21cafc8f23 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-02-03 18:58:07 -05:00
transifex-integration[bot]
6c0ea0bb17 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-02-03 18:58:07 -05:00
transifex-integration[bot]
a1f3c481c5 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2024-02-03 18:58:07 -05:00
transifex-integration[bot]
cee5bd1a97 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2024-02-03 18:58:07 -05:00
transifex-integration[bot]
a43fa7349c Translate Localizable.strings in sv_SE
100% translated source file: 'Localizable.strings'
on 'sv_SE'.
2024-02-03 18:58:07 -05:00
611cef712f Fix localization issues and export strings for translation 2024-02-03 18:58:07 -05:00
William Casarin
28f292f692 nostrscript: fix nscripts not loading
This was broken by the recent nip19 changes, let's fix it again

Fixes: cb4adf06f1 ("nip19: added swift enums")
Changelog-Fixed: Fix nostrscripts not loading
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-02 12:02:21 -08:00
William Casarin
4defab73d0 v1.7 (9)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 11:28:32 -08:00
William Casarin
3d190a7388 purple: fix crash in account cache
otherwise there is contention and tends to crash

Fixes: f06b882139 ("purple: consolidate UserBadgeInfo with Account")
Changelog-Fixed: Fix crash when accessing cached purple accounts
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 11:08:07 -08:00
William Casarin
4a40c9987d v1.7 (8)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 10:46:21 -08:00
William Casarin
9735a28b44 mention: add note about text suggestion mention inteference
Also doing this so I can add a changelog entry

Changelog-Changed: Disable inline text suggestions on 17.0 as they interfere with mention generation
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 10:46:21 -08:00
kernelkind
48e8c11929 media: remove minWidth on Load Media formatting
Minimum width is not needed since we rely on maxWidth set to .infinity
to fill the screen bounds.

Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Link: 20240131165008.61990-1-kernelkind@gmail.com
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 10:42:02 -08:00
kernelkind
6ca6a76fdb repost: hide member signup date
The purple membership badge should be displayed as compact view
everywhere except the user's profile.

Lightning-address: kernelkind@getalby.com
Changelog-Fixed: Hide member signup date on reposts
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 09:52:49 -08:00
ericholguin
504b21e91c note: fix previews not rendering
Fixes: dfcef0ba95 ("Fix previews not rendering")
Closes: https://github.com/damus-io/damus/issues/1932
Changelog-Fixed: Fixed previews not rendering
Signed-off-by: ericholguin <ericholguin@apache.org>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 09:51:29 -08:00
kernelkind
afec694432 post: disable inline text prediction
Inline text suggestions interfere with mentions generation so they
should be disabled.

Closes: https://github.com/damus-io/damus/issues/1970
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-02-01 09:51:18 -08:00
William Casarin
3c24e707fc translate: disable translate DMs
It's just a bad idea until we have local translations

Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-31 09:34:15 -08:00
William Casarin
28d6715fda v1.7 (7)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-31 09:24:55 -08:00
William Casarin
b25d7d1c0d enable purple
Changelog-Added: Damus Purple membership!
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-31 09:24:46 -08:00
William Casarin
528d1b89b6 profile: show subscriber date instead of number
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 19:02:24 -08:00
William Casarin
f05cd1b7e6 split up date formatting
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 19:01:31 -08:00
William Casarin
b73b1da46e purple: prevent screen dismiss on purple welcome view
Suggested-by: Daniel Daquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 17:38:42 -08:00
William Casarin
f06b882139 purple: consolidate UserBadgeInfo with Account
Rename get_account to fetch_account to make it clear that it is always a
call to the server.

Add get_maybe_cached_account method that checks cached before calling
fetch_account.

Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 17:30:12 -08:00
William Casarin
fe177bdb9e purple: speed up continue button fade-in
Cc: Daniel Daquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 16:31:55 -08:00
William Casarin
dd498cdee2 purple: add "continue" button to checkout verification step
Cc: Daniel Daquino <daniel@daquino.me>
Suggested-by: Vanessa Gray <vanessa@damus.io>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 16:27:22 -08:00
William Casarin
66f17ecd96 v1.7 (6)
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 16:26:23 -08:00
kernelkind
86e9ee16a0 ui: truncate visible media URL
The URL shown to the user before they click the 'Load Media' button can
take up a large portion of the screen, and doesn't offer any value to
the user.

This patch features a naive approach to truncate the URL to be a certain
number of characters if it is greater than the specified value. Right
now the maximum number of characters is set to 80.

Closes: https://github.com/damus-io/damus/issues/1950
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Link: 20240130183525.50446-1-kernelkind@gmail.com
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:43:15 -08:00
Daniel D’Aquino
5f9477d55b purple: notify main DamusPurpleView when user gets a subsscription
Previously, if the user had the DamusPurpleView open and bought the
subscription, the DamusPurpleView would not change. It would stay in the
marketing pitch screen.

This commit makes sure that this view is automatically updated as soon
as the user sees the welcome screen, so that they can see their account
info in case they have DamusPurpleView open.

Testing
--------

PASS

iOS: 17.2
Damus: This commit
damus-api: Varying versions around `9a6af62`
Coverage:
1. Checked the entire LN flow through the local test environment using the simulator
2. Checked all LN flow views on both light and dark mode to ensure it looks good
3. Checked the entire LN flow using the staging environment using a physical iOS device

Closes: https://github.com/damus-io/damus/issues/1899
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:49 -08:00
Daniel D’Aquino
1421c34aeb purple: fix dark mode issues
Some views appeared broken when iOS was in dark mode, with a white
background. This commit fixes that and makes sure the background is
always dark.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:49 -08:00
Daniel D’Aquino
263389b2e6 purple: add translation setup view the onboarding
This commit changes the welcome view into a multi-step onboarding
process, where it makes it more clear that translations are unlocked,
and provides the user with some choices to set it up or not.

This flow also makes the translation setup possible on the LN flow

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:49 -08:00
Daniel D’Aquino
cdd5327829 purple: disable apple IAP ui by default
We do not have Apple In-app purchases ready for the upcoming release.

This commit hides IAP UI/UX behind a developer feature flag which is off
by default, and shows a link inviting the user to visit the website to
learn more.

It also makes the link go to the normal Damus website.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:48 -08:00
Daniel D’Aquino
e649c49981 purple: adapt to integrate better with the LN flow
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:48 -08:00
Daniel D’Aquino
a6b430284f purple: feature flag management
Originally the Damus Purple feature was gated behind a setting which
served as a feature flag.

However, when we release, we need to enable Purple features for all
users running on a particular version.

This commit improves feature flag management by replacing the setting
with a computed property (which still points to the setting, but can be
very easily replaced)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:48 -08:00
Daniel D’Aquino
dd240899cf purple: improve environment handling
This commit improves the handling of different Purple environments:

- 3 environments were added (test, staging, production) to fulfill all
  testing needs

- Damus website constants were also added (This will become important
  for the next few commits)

- Toggle settings were replaced with a picker, where the user can select
  one of the 3 environments (test, staging, production)

- Damus purple page and website address links can now be obtained
  directly from the DamusPurple struct, which improves flexibility and
  reduces complexity for code that consumes these constants.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:48 -08:00
kernelkind
992b0f2eba ui: fix load media formatting on small screens
On small screens, specifically the iPhone 12 Mini in this case, the
'Load Media' has a minimum width which is too high so it causes
formatting problems when viewing replies.

The minimum width of the frame was arbitrarily decreased from 300 to
200.

Changelog-Fixed: Fix load media formatting on small screens
Closes: https://github.com/damus-io/damus/issues/1944
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:48 -08:00
kernelkind
9d91856ea3 nip19: do not include tag for nevent mention
When creating an NostrEvent with an nevent1 mention, don't include the
nevent mentions in the event's tags. This matches the behavior for
note1 mentions.

Tests for content with npub1 and note1 mentions were added to confirm
tag generation behavior. Test for nevent mention tag generation was
modified to be the same as note1.

Closes: https://github.com/damus-io/damus/issues/1941
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:29:48 -08:00
kernelkind
7cc2825d89 nip19: fix shared nevents that are too long
There comes a point when the sharing a Nip19 mention becomes unwieldy
when there is too much TLV data. This patch features a naive approach to
making sure the relay portion of the TLV data doesn't contribute too
much data to the mention.

It adds a maximum number of relays that should be shared in the mention,
right now it is set to four.

Changelog-Fixed: Fix shared nevents that are too long
Lightning-address: kernelkind@getalby.com
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-30 10:27:12 -08:00
William Casarin
5c76ffda8c fix build 2024-01-29 13:04:54 -08:00
William Casarin
f5f42528af txn: fix potential crash from transaction in view closure 2024-01-29 12:50:12 -08:00
William Casarin
ff6b19578e purple: switch local testing to staging testing 2024-01-28 17:32:44 -08:00
William Casarin
0c63f2ee26 purple: add staging option to DamusPurpleURL
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-28 16:09:14 -08:00
William Casarin
500f8bc2ec purple: add querystring helper
We will be pulling out more things so this simplifies querystring
lookups a bit

Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-28 16:09:14 -08:00
William Casarin
7a3be720b2 Revert "profile: rename Following to Frens"
This reverts commit 85e14de12d.
2024-01-28 16:09:14 -08:00
Daniel D’Aquino
854036b413 purple: add subscriber number on the Purple supporter badge
This change adds an subscriber number to the supporter badge.

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.2
Damus: This commit
damus-api: `53fd7fef1c8c0bbf82bb28d1d776e45379433d23`
Setup:
- `damus-api` running on `npm run dev` mode
- Damus configured to enable experimental Purple support + localhost mode
Test steps:
1. Wipe local database and rerun server
2. Purchase purple using In-app purchase (Xcode environment) flow
3. Make sure that badge to the side of the user's name on the event shows a golden star without any ordinal numbers
4. Make sure that the badge to the side of the user's name on the profile page shows a golden star with the text "1st"
5. Repeat steps 2–4 and make sure the text says "2nd"
6. Look at the SupporterBadge view previews. Ordinals should show up correctly for all previews (They should always show up, no matter the number)

Closes: https://github.com/damus-io/damus/issues/1873
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-28 15:43:13 -08:00
William Casarin
838ce26c64 test: fix test build error
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-28 15:43:13 -08:00
William Casarin
83d2fbf7fd project: remove TXNDEBUG 2024-01-28 15:13:55 -08:00
Charlie Fish
d5606aabca mute: fix bug where mutes can't be added without existing mutelist
There is currently an issue where if a user doesn’t have an existing
mutelist it won’t let the user add new mute items. This patch fixes that
by not including the existing mutelist variable in the guard statement.

Lighting-address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-27 21:01:46 -08:00
Charlie Fish
a6b508c25a mute: fix issue with not being able to change mute duration
This patch fixes an issue where the user can’t change the mute duration
when adding a new mute item.

The problem was that `expiration` was nil for indefinite which isn’t
really allowed for a Picker.

I fixed this by adding an indefinite case to DamusDuration.

Closes: https://github.com/damus-io/damus/issues/1907
Lighting-address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-27 19:50:38 -08:00
Charlie Fish
a4f0eeadec mute: don't mutate string when adding hashtag
Currently there is an issue where if you try to mute a hashtag, it will
mutate the `new_text` variable. This patch fixes that so that we aren’t
mutating `new_text`.

Lighting-address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-27 19:46:47 -08:00
ericholguin
e2361c1176 ux: Onboarding improvements
This patch removes the EULA view from the onboarding flow and can be
viewed from the create account view if the user so chooses.

This also removes the need to copy the public key in the save keys view,
now only the copying of the private key is required.

Finally it fixes minor issues with the onboarding views, such as padding
and spacing, where components were not aligned properly.

Testing

iPhone 15 Pro Max (17.0) Light Mode:
https://video.nostr.build/7c1d38c75069262a56a93fcf7cc447fa8808ed7fbbd18a8169b583913248b741.mp4

iPhone SE (3rd generation) (16.4) Dark Mode:
https://video.nostr.build/100085c84d84a75f41c45e3dc5347e5b4c35a8149b1b8a5edb9e6c059adc5949.mp4

Lightning-Address: eriic@getalby.com
Closes: https://github.com/damus-io/damus/issues/1902
Changelog-Added: Fixed minor spacing and padding issues in onboarding views
Changelog-Changed: EULA is not shown by default
Changelog-Removed: Removed copying public key action

Signed-off-by: ericholguin <ericholguin@apache.org>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-27 18:47:37 -08:00
William Casarin
9d87bc11dd friendfilter: extend to friend-of-friends
Suggested-by: Semisol
2024-01-26 18:11:54 -08:00
William Casarin
85e14de12d profile: rename Following to Frens
Suggested-by: Marie
2024-01-26 18:11:34 -08:00
William Casarin
beb3605411 v1.7 (5) 2024-01-26 14:06:21 -08:00
William Casarin
e3642b92d1 txn: fix subtle transaction inheritence bugs
This fixes subtle bugs with transaction inheritence. Since we were not
passing the inherited state to moved value, we were sometimes committing
transactions more than once.

Changelog-Fixed: Fix many nostrdb transaction related crashes
2024-01-26 14:03:49 -08:00
William Casarin
f190b6414c debug: enable txndebug 2024-01-26 14:02:29 -08:00
William Casarin
6ae326d193 ndb: use is_closed which also check nil ptrs
not an issue atm, but maybe in the future
2024-01-26 14:02:03 -08:00
William Casarin
851bffed0f damus_state: switch to class instead of struct
This was obscuring many state issues
2024-01-26 13:52:48 -08:00
William Casarin
5b820d6920 1.7 (4) 2024-01-26 12:00:27 -08:00
William Casarin
d04a29405d txn: don't attempt to close transactions from older db generations 2024-01-26 12:00:26 -08:00
William Casarin
d3c75ce42b Revert "lmdb: fix weird crash in lmdb. need to follow up upstream"
This reverts commit 4686b7aca6.
2024-01-26 12:00:26 -08:00
William Casarin
6731471c17 fix build 2024-01-26 11:15:46 -08:00
William Casarin
98359beb04 v1.7 (3) 2024-01-26 11:14:44 -08:00
William Casarin
4686b7aca6 lmdb: fix weird crash in lmdb. need to follow up upstream
I may be something dumb, so asking the LMDB why this is crashing here
might enlighten us.
2024-01-26 11:13:52 -08:00
William Casarin
b80bab35b8 ndb: fix crash with Ndb garbage collection on de-init 2024-01-26 10:57:50 -08:00
William Casarin
bfb0dbac56 txn: do another guard check before query just in case
probably won't do anything
2024-01-26 10:55:33 -08:00
William Casarin
fbdc5446f0 project: clean up some stuff 2024-01-26 10:55:16 -08:00
William Casarin
6e0ba3206d debug: add some transaction debugging 2024-01-26 10:55:05 -08:00
kernelkind
010d71d9ed mentions: fix regression on char handling after mention
Previously, when a post is being sent, the next character after a
mention was checked. If it wasn't a space, a space was added. This
implementation was insufficient because there are times where a
character immediately following a mention is desired, especially for
punctuation.

This was possible in the past because the C code counts anything non
alphanumeric as being part of the mention if it starts with 'nostr:'.

The fix included follows similar logic. If the character following the
mention is non alphanumeric, it allows it. Otherwise, a space is added
so that the C code can correctly parse the mention.

A test was added which verifies non alphanumeric characters after
mentions don't get whitespace added before them.

Fixes: af75eed ("mention: fix broken mentions when there is text is directly after")
Closes: https://github.com/damus-io/damus/issues/1915
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 14:11:31 -08:00
William Casarin
deedf5577d Revert "camera: switch to new custom view"
This reverts commit ca779d472d.
2024-01-25 14:11:31 -08:00
William Casarin
4ddf647d5f Revert "camera: add ability to preview media taken with camera"
This reverts commit c67741983e.
2024-01-25 14:11:31 -08:00
William Casarin
e999e81e8f mute: implement fast MuteItem decoder
Just using strings is really bad performance wise, and is not the
proper way to implement a TagConvertible. The whole point of this
protocol is to parse tags efficiently.
2024-01-25 12:13:15 -08:00
William Casarin
3cce42eea1 tags: add u64 decoding function
This will be used for decoding expiries.
2024-01-25 12:13:15 -08:00
Charlie Fish
71c9bd63fc mute: migrating muted_threads to new mute list
This patch depends on: Adding ability to mute hashtag from SearchView

This is the last patch for the new mute list feature

- Removing MutedThreadsManager
- Adding system to migrate existing muted threads to new mute list

Closes: https://github.com/damus-io/damus/issues/1718
Closes: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:59 -08:00
Charlie Fish
89f7c3ff30 mute: adding ability to mute hashtag from SearchView
This patch depends on: Updating UI to support new mute list

- Adding the ability to mute a hashtag from SearchView

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting-address: fishcharlie@strike.me
Changelog-Added: Add ability to mute hashtag from SearchView
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:59 -08:00
Charlie Fish
6003a501c1 mute: updating UI to support new mute list
This patch depends on: Adding filtering support for MuteItem events

- Gives more specific mute reason in EventMutedBoxView
- Showing all types of mutes in MutelistView
- Allowing for adding mutes directly from MutelistView
- Allowing for choosing duration of mute in EventMenu

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:59 -08:00
Charlie Fish
7aaea97de0 mute: adding filtering support for MuteItem events
This patch depends on: Receiving New Mute List Type

- Changes NewMutesNotify, NewUnmutesNotify & MuteNotify to use MuteItem instead of Pubkey
- Changes is_muted in Contacts.swift to take in a MuteItem instead of a Pubkey
    - A lot of changes here were just modifying callers of that to accept the new parameter type

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:59 -08:00
Charlie Fish
07b3146026 mute: receiving New Mute List Type
This patch depends on: Migrate Lists.swift to use new MuteItem

- Makes request for new mute list type (kind:10000)
- Processing new mute list type (kind:10000)

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:59 -08:00
Charlie Fish
f36646116e mute: migrate Lists.swift to use new MuteItem
This patch depends on: Adding new structs/enums for new mute list

- Rewrites Lists.swift to use new mute list option
    - This leads to a lot of changes for changing the type from RefId to the new MuteItem
- Update & relay new mute list in AddMuteItemView.swift (fixing previous patch TODO)
- Renames `list` to `list_deprecated`
    - We need to keep this since existing users might have an old mute list

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:59 -08:00
Charlie Fish
6d2c382469 mute: add new UI views for new mute list
- Adding MuteDurationMenu & AddMuteItemView
    - In a future patch I will update AddMuteItemView to actually update and relay the new mute list

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:59 -08:00
Charlie Fish
068b89d087 mute: adding new structs/enums for new mute list
- Adding MuteItem & DamusDuration
- Changing RefId hashtag associated type from TagElem to Hashtag
    - This is done because in MuteItem, we can not create a RefId.hashtag TagElem instance since we don’t have a note associated with a given hashtag mute item.

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-25 12:12:57 -08:00
William Casarin
f13267aeb2 Revert "mute: adding new structs/enums for new mute list"
This reverts commit 50f45288ce.
2024-01-25 12:11:34 -08:00
William Casarin
e6598928d0 Revert "mute: add new UI views for new mute list"
This reverts commit 9f332a148f.
2024-01-25 12:10:34 -08:00
William Casarin
a4253a613c Revert "mute: migrate Lists.swift to use new MuteItem"
This reverts commit 0f05123ef8.
2024-01-25 12:10:22 -08:00
William Casarin
66fd1dd444 Revert "mute: receiving New Mute List Type"
This reverts commit 2861ee2c12.
2024-01-25 12:10:15 -08:00
William Casarin
b5c384da43 Revert "mute: adding filtering support for MuteItem events"
This reverts commit 61a9e44898.
2024-01-25 12:10:08 -08:00
William Casarin
356ef45b91 Revert "mute: updating UI to support new mute list"
This reverts commit 75d66434f3.
2024-01-25 12:10:03 -08:00
William Casarin
f5d1401032 Revert "mute: adding ability to mute hashtag from SearchView"
This reverts commit ace8a7081b.
2024-01-25 12:09:56 -08:00
William Casarin
719cec449c Revert "mute: migrating muted_threads to new mute list"
This reverts commit f341a37902.
2024-01-25 12:09:49 -08:00
William Casarin
56b1efc6f1 txn: do not close txn if database is already closed
This is a potential fix for some of the crash reports that have been
streaming in. They all seem to be crashing within ndb_close_txn. I
suspect this means that the transactions are trying to get closed when
ndb is already closed. Closing Ndb will close the transactions
automatically, so it looks like we might be trying to close twice.
2024-01-25 12:09:15 -08:00
William Casarin
0f307ab8d5 project: only bump damus build from project 2024-01-24 10:01:00 -08:00
William Casarin
ecc880ac85 Revert "project: add 'updates files in place' to info.plist"
This reverts commit 7894cad4f4.
2024-01-24 10:00:51 -08:00
William Casarin
26e2c98e72 project: fix invalid info.plist entry
Looks like this was added accidentally
2024-01-24 09:57:53 -08:00
William Casarin
d2f6b40625 v1.7 (2) changelog 2024-01-24 09:45:40 -08:00
William Casarin
63ad13a2d5 v1.7 (2) 2024-01-24 09:41:14 -08:00
William Casarin
7894cad4f4 project: add 'updates files in place' to info.plist
xcode seems to be complaining about this. We technically open the LMDB
file in place? Maybe this is what it detected and is complaining about.
2024-01-24 09:39:59 -08:00
William Casarin
44bcae1485 project: upgrade to recommended settings
since xcode was complaining
2024-01-24 09:39:42 -08:00
William Casarin
d455d86a05 mention: fix missing @ on mentions
Fixes: d07ad67778 ("nip19: add bech32 TLV url parsing")
2024-01-22 15:00:20 -08:00
Suhail Saqan
c67741983e camera: add ability to preview media taken with camera
Closes: https://github.com/damus-io/damus/pull/1254
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Added: Add ability to preview media taken with camera
2024-01-22 14:20:20 -08:00
Suhail Saqan
ca779d472d camera: switch to new custom view
Closes: https://github.com/damus-io/damus/pull/1254
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Added: Added a custom camera view
2024-01-22 14:20:05 -08:00
Charlie Fish
f341a37902 mute: migrating muted_threads to new mute list
This patch depends on: Adding ability to mute hashtag from SearchView

This is the last patch for the new mute list feature

- Removing MutedThreadsManager
- Adding system to migrate existing muted threads to new mute list

Closes: https://github.com/damus-io/damus/issues/1718
Closes: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 12:55:03 -08:00
Charlie Fish
ace8a7081b mute: adding ability to mute hashtag from SearchView
This patch depends on: Updating UI to support new mute list

- Adding the ability to mute a hashtag from SearchView

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting-address: fishcharlie@strike.me
Changelog-Added: Add ability to mute hashtag from SearchView
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 12:55:03 -08:00
Charlie Fish
75d66434f3 mute: updating UI to support new mute list
This patch depends on: Adding filtering support for MuteItem events

- Gives more specific mute reason in EventMutedBoxView
- Showing all types of mutes in MutelistView
- Allowing for adding mutes directly from MutelistView
- Allowing for choosing duration of mute in EventMenu

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 12:55:03 -08:00
Charlie Fish
61a9e44898 mute: adding filtering support for MuteItem events
This patch depends on: Receiving New Mute List Type

- Changes NewMutesNotify, NewUnmutesNotify & MuteNotify to use MuteItem instead of Pubkey
- Changes is_muted in Contacts.swift to take in a MuteItem instead of a Pubkey
    - A lot of changes here were just modifying callers of that to accept the new parameter type

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 11:03:06 -08:00
Charlie Fish
2861ee2c12 mute: receiving New Mute List Type
This patch depends on: Migrate Lists.swift to use new MuteItem

- Makes request for new mute list type (kind:10000)
- Processing new mute list type (kind:10000)

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 11:03:06 -08:00
Charlie Fish
0f05123ef8 mute: migrate Lists.swift to use new MuteItem
This patch depends on: Adding new structs/enums for new mute list

- Rewrites Lists.swift to use new mute list option
    - This leads to a lot of changes for changing the type from RefId to the new MuteItem
- Update & relay new mute list in AddMuteItemView.swift (fixing previous patch TODO)
- Renames `list` to `list_deprecated`
    - We need to keep this since existing users might have an old mute list

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 11:03:06 -08:00
Charlie Fish
9f332a148f mute: add new UI views for new mute list
- Adding MuteDurationMenu & AddMuteItemView
    - In a future patch I will update AddMuteItemView to actually update and relay the new mute list

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 11:03:06 -08:00
Charlie Fish
50f45288ce mute: adding new structs/enums for new mute list
- Adding MuteItem & DamusDuration
- Changing RefId hashtag associated type from TagElem to Hashtag
    - This is done because in MuteItem, we can not create a RefId.hashtag TagElem instance since we don’t have a note associated with a given hashtag mute item.

Related: https://github.com/damus-io/damus/issues/1718
Related: https://github.com/damus-io/damus/issues/856
Lighting Address: fishcharlie@strike.me

Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 11:03:06 -08:00
kernelkind
5840b85213 nip19: generate nip19 data in ellipsis & share menus
In the ellipsis menu, when the user selects the 'Copy user public key',
an nprofile Bech32 entity will be generated which will include TLV data
with the user's public key and entire relay list, if available.
The nprofile will be added to the user's copy clipboard.

When the user presses the share menu on an event and clicks the 'copy
link' button, a damus link with the nevent for the note will be
generated and copied to the user's clipboard.

Closes: https://github.com/damus-io/damus/issues/1844
Changelog-Changed: Generate nprofile/nevent links in share menus
Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:50:52 -08:00
kernelkind
0650a62791 nip19: add search functionality for naddr, nprofile & nevent
The user is able to search for naddr, nprofile & nevent bech32 entities.
Additionally, these entities and others are able to have prefixes such
as damus:nostr: and damus.io links.

Closes: https://github.com/damus-io/damus/issues/1841
Closes: https://github.com/damus-io/damus/issues/1650
Changelog-Added: Add ability to search for naddr, nprofiles, nevents
Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:50:25 -08:00
kernelkind
a4a0465605 nip19: add naddr link support
Add functionality for when user taps on naddr link they get redirected
to the proper note.

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

Changelog-Added: Add naddr link support
Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:50:03 -08:00
kernelkind
3056ab9bfb nip19: add EventLoaderView for nevent mentions
Allow nevent mentions to be loaded in the MentionView since they are
just a note with extra metadata.

Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:49:51 -08:00
kernelkind
d07ad67778 nip19: add bech32 TLV url parsing
Create shortened URLs for bech32 with TLV data strings. Additionally,
upon clicking on an nevent URL the user is directed to the note.

Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:49:33 -08:00
kernelkind
af75eed83a mention: fix broken mentions when there is text is directly after
If a user adds text right after a mention without a space, a space gets
added so the mention can be parsed correctly after posting.

Closes: https://github.com/damus-io/damus/issues/1872
Changelog-Fixed: Fix broken mentions when there is text is directly after
Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:40:17 -08:00
kernelkind
aa1f75ad58 purple: polish UI/UX flow
Contributes to closing https://github.com/damus-io/damus/issues/1847.

- Fixes (1), the black bar at the top of the view is removed.
- Fixes (2), Scrolling down does not reveal an unappealing navigation bar
- Fixes (3), After the user presses 'continue', the user is taken back to
DamusPurpleView. If the user is shown a confirmation dialog, it waits
for user interaction, and after it dismisses DamusPurpleView to go back
to the home screen. If the user isn't shown the confirmation dialog, the
user is brought to the home screen straight away.
- May or may not fix (4)
- Fixes (5), the theme persists in light and dark mode

Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:39:40 -08:00
kernelkind
f9bfa9dfa5 carousel: save current viewed image index when switching to fullscreen
When scrolling through the media carousel, the currently viewed media
should persist between fullscreen and carousel view instead of resetting
to the first index.

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

Changelog-Fixed: Save current viewed image index when switching to fullscreen
Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:38:01 -08:00
kernelkind
71b33fcd0b mention: allow mentioning users with punctuation characters in their names
Finds the range of characters which represents a mention the user is
typing in PostView. Previously the tokenizer used the standard
granularity UITextGranularity.word, but this is insufficient for our use
case for detecting when a mention ends.

The criteria is simple: a mention starts with the '@' character and ends
when there is a space, line break, or @, instead of when there is a new
word.

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

Changelog-Fixed: Allow mentioning users with punctuation characters in their names
Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-22 10:37:03 -08:00
Daniel D’Aquino
534969e616 purple: add support for LN checkout flow
This commit adds support for the LN checkout flow, and the Purple
landing page:

1. It adds a "learn more" button on the Damus Purple view, where the
   user can learn more
2. It adds new `damus:purple` urls to enable the LN checkout flow

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-18 10:13:01 -08:00
alltheseas
75a9b4df7f menu: move mute thread further away from bookmark
Closes: https://github.com/damus-io/damus/pull/1886
Closes: https://github.com/damus-io/damus/pull/1878
Changelog-Changed: Move mute thread in menu so it's not clicked by accident
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-16 21:04:51 -08:00
kernelkind
a9e9701243 nip19: add high level bech32 encoding method
Add encode method for converting Bech32Object to a bech32 encoded
string. This will be useful for generalized conversion of Bech32Objects
to its string representation.

Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-16 16:55:31 -08:00
kernelkind
cb4adf06f1 nip19: added swift enums
Add enums to reflect Bech32 with TLV encoded data. Update parse method
to call C library for generalized parsing of bech32 data.

Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-16 16:55:31 -08:00
kernelkind
97fc415b8c nip19: add kind to naddr & nevent
Add support for type KIND for bech32-encoded entities naddr and nevent
as specified in NIP-19.

LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G

Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-16 16:55:24 -08:00
William Casarin
d49cf5a505 perf: debounce scroll queue 2024-01-16 16:51:28 -08:00
William Casarin
89e01d823a debouncer: add new debounce methods 2024-01-16 16:03:10 -08:00
William Casarin
6edb3b1a40 timeline: remove dubious button styling setting 2024-01-11 13:05:26 -08:00
William Casarin
d591dc0a7a perf: reduce the number of swiftui updates in ImageCarousel
not sure if it helps much, but just trying to see reduce the number of
updates overall. Trying to fix swiftui scroll performance :(
2024-01-11 11:47:44 -08:00
William Casarin
3b436f9d58 perf: fix gif decoding performance issues
Preload as much as possible so that gif's don't use as much CPU

Changelog-Fixed: Fix performance issue with gifs
2024-01-11 11:07:03 -08:00
William Casarin
4cf92756f1 close nostrdb and disconnect from relays on logout
This was causing crashing and corruption issues. This should have been
handled by the garbage collector, but for some reason old references
still hang around.

Add a "close" method to DamusState which disconnects from relays and
closes nostrdb.

Changelog-Fixed: Fix crash when logging out and switching accounts
Changelog-Fixed: Fix persistent local notifications even after logout
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 16:25:07 -08:00
William Casarin
6834367386 ndb: fix crashed when trying to process client event on a closed db 2024-01-10 15:38:31 -08:00
William Casarin
afe3dcf039 test: switch test to use failable transactions 2024-01-10 15:38:21 -08:00
William Casarin
091a8ae090 test: fix crashing in AUTH test 2024-01-10 15:37:52 -08:00
William Casarin
ed30b123db notifications: don't hold onto note ref outside of txn
It's never safe to return an unsafeUnownedValue

Fixes: c4f0e833ff ("Reuse local notification logic with push notifications")
Cc: Daniel DAquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 14:43:47 -08:00
William Casarin
bfad2ab42d ndb/txn: make transactions failable
Since there may be situations where we close and re-open the database,
we need to make sure transactions fail when the database is not open.

Make NdbTxn an init?() constructor and check for ndb.closed. If it's
closed, then fail transaction construction.

This fixes crashes during high database activity when switching from
background to foreground and vice-versa.

Fixes: da2bdad18d ("nostrdb: close database when backgrounded")
2024-01-10 14:27:02 -08:00
William Casarin
227734d286 Revert "Revert "nostrdb: close database when backgrounded""
This reverts commit 26bd50c948.
2024-01-10 13:19:36 -08:00
William Casarin
909701ce7b profile: partially fix performance regression
This will be completely fixed once we switch to stored note blocks
2024-01-10 11:52:30 -08:00
Daniel D’Aquino
54674104ea Change DamusUserDefaults to mirror settings from app container
... to shared container instead of migrating

This commit is a reimplementation of DamusUserDefaults that mirrors
settings from the app to the shared container (instead of migrating
values over).

This new implementation brings the benefit of being backwards compatible
with the user's settings. That is, even if the user upgrades or
downgrades between various versions and changes settings along the way,
the main settings in the app will stay consistent between Damus versions
— that is, changes to the settings would not be lost between
downgrades/upgrades

General settings test
----------------------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Setup: A device with non-standard settings
Steps:
1. Flash Damus on the device
2. Check any non-default settings that were there before. Ensure that settings remained the same. PASS
3. Change one setting (any setting) to a non-default value
4. Restart Damus
5. Ensure settings change in step 3 persisted on the device

Notification settings test
--------------------------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Setup:
- Two phones running Damus on different accounts
- Local relay with strfry-push-notify test setup
- Apple push notification test tool

Coverage:
1. Mention notifications
2. DM notifications
3. Reaction notifications
4. Repost notifications

Steps for each notification type:
1. Use the secondary phone to generate a push notification
2. Trigger the push notification (Send push notification from test tool)
3. Ensure that the notification is received on the other device
4. Turn off notifications for that notification type on settings
5. Trigger the same push notification (Resend push notification from test tool)
6. Ensure that the notification is not received on the other device
7. Turn on notifications for that notification type on settings
8. Trigger the same push notification (Resend from test tool)
9. Ensure that notification appears on the device

Result: PASS (notifications are received when enabled and not received when disabled)
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:07:01 -08:00
Daniel D’Aquino
aab9e97a25 Fix test target build error
Unit tests
-----------

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit

Steps: Run unit tests
Result: No regressions found (Tests either pass or they were already failing before the patches)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:32 -08:00
Daniel D’Aquino
c10ce4b1ba Do not show notifications from muted users
Muted users + unfollowed users test
------------------------------------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Setup:
- Two phones running Damus on different accounts
- Local relay with strfry-push-notify test setup
- Apple push notification test tool

Steps:
1. Unfollow the user who is the author of the saved notifications
2. Disable notifications for people you don't follow
3. Trigger a push notification (Resend push notification from test tool)
4. Ensure that the notification is not received on the other device
5. Enable notifications for people you don't follow
6. Trigger a push notification (Resend push notification from test tool)
7. Ensure that the notification is received on the other device
8. Mute the user who is the author of the saved notifications
9. Trigger a push notification (Resend push notification from test tool)
10. Ensure that the notification is not received on the other device
11. Unmute the user who is the author of the saved notifications
12. Trigger a push notification (Resend push notification from test tool)
13. Ensure that the notification is received on the other device

Result: PASS

Closes: https://github.com/damus-io/damus/issues/1705
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:32 -08:00
Daniel D’Aquino
88801c2762 Fix user setting access issue in the notification extension
Notification settings test
--------------------------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Setup:
- Two phones running Damus on different accounts
- Local relay with strfry-push-notify test setup
- Apple push notification test tool

Coverage:
1. Mention notifications
2. DM notifications
3. Reaction notifications
4. Repost notifications

Steps for each notification type:
1. Trigger a push notification (Resend push notification from test tool)
2. Ensure that the notification is received on the other device
3. Turn off notifications for that type on settings
4. Trigger a push notification (Resend push notification from test tool)
5. Ensure that the notification is not received on the other device

Result: PASS (notifications are received when enabled and not received when disabled)

Closes: https://github.com/damus-io/damus/issues/1764
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:32 -08:00
Daniel D’Aquino
003482c971 Implement zap notification support for push notifications
The code paths for generating zap notifications were very different from
the paths used by most other notifications. In this commit, I include
the logic and data structures necessary for formatting zap notifications
in the same fashion as local notifications.

A good amount of refactoring and moving functions/structures around was
necessary to reuse zap local notification logic. I also attempted to
make the notification generation process more consistent between zaps
and other notifications, without changing too much of existing logic to
avoid even more regression risk.

General push notifications + local notifications test
-----------------------------------------------------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Setup:
- Two phones running Damus on different accounts
- Local relay with strfry-push-notify test setup
- Apple push notification test tool

Coverage:
1. Mention notifications
2. DM notifications
3. Reaction notifications
4. Repost notifications

Steps for each notification type:
1. Trigger a notification (local and then push)
2. Ensure that the notification is received on the other device
3. Ensure that the notification is formatted correctly
4. Ensure that DMs are decrypted correctly
5. Ensure that profile names are unfurled correctly
6. Click on the notification and ensure that the app opens to the correct screen

Result: PASS (all notifications received and formatted correctly)

Notes:
- For some reason my relay is not receiving zap events, so I could not
  test zap notifications yet.

- Reply notifications do not seem to be implemented yet

- These apply to the tests below as well

Changelog-Added: Zap notification support for push notifications
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:32 -08:00
Daniel D’Aquino
c4f0e833ff Reuse local notification logic with push notifications
Testing
-------

Conditional pass

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Coverage:

1. Mention notification works (local and push). PASS

2. Thread replies do not appear (but upon code inspection it seems like
   it was not supported before). PASS?

3. DM notification works with decryption (local and push). PASS

4. Zaps not yet implemented. Coming later.

Closes: https://github.com/damus-io/damus/issues/1702
Closes: https://github.com/damus-io/damus/issues/1703
Changelog-Changed: Improve push notification support to match local notification support
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:32 -08:00
Daniel D’Aquino
5db22ae244 Migrate setting and key stores to shared UserDefaults
This is needed to allow the notification extension to process push notifications, respect user's notification settings, and decrypt DMs on the push notification

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:32 -08:00
Daniel D’Aquino
88f938d11c Bring local notification logic into the push notification target
This commit brings key local notification logic into the notification
extension target to allow the extension to reuse much of the
functionality surrounding the processing and formatting of
notifications. More specifically, the functions
`process_local_notification` and `create_local_notification` were
brought into the extension target.

This will enable us to reuse much of the pre-existing notification logic
(and avoid having to reimplement all of that)

However, those functions had high dependencies on other parts of the
code, so significant refactorings were needed to make this happen:

- `create_local_notification` and `process_local_notification` had its
  function signatures changed to avoid the need to `DamusState` (which
  pulls too many other dependecies)

- Other necessary dependencies, such as `Profiles`, `UserSettingsStore`
  had to be pulled into the extension target. Subsequently,
  sub-dependencies of those items had to be pulled in as well

- In several cases, files were split to avoid pulling too many
  dependencies (e.g. Some Model files depended on some functions in View
  files, so in those cases I moved those functions into their own
  separate file to avoid pulling in view logic into the extension
  target)

- Notification processing logic was changed a bit to remove dependency
  on `EventCache` in favor of using ndb directly (As instructed in a
  TODO comment in EventCache, and because EventCache has too many other
  dependencies)

tldr: A LOT of things were moved around, a bit of logic was changed
around local notifications to avoid using `EventCache`, but otherwise
this commit is meant to be a no-op without any new features or
user-facing functional changes.

Testing
-------

Device: iPhone 15 Pro
iOS: 17.0.1
Damus: This commit
Coverage:

1. Ran unit tests to check for regressions (none detected)

2. Launched the app and navigated around and did some interactions to
   perform a quick functional smoke test (no regressions found)

3. Sent a few push notifications to check they still work as expected (PASS)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:30 -08:00
Daniel D’Aquino
4171252b18 Unfurl profile name on remote push notifications
This commit adds support for the unfurling of author profile names on remote push notifications

It also makes the following changes:
- Notification extension now uses NdbNote
- Some of the logic between push notifications and local notifications was unified

Testing
-------

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Coverage:
1. Basic smoke tests on the app by browsing different notes and different tabs
2. Sent test push notifications for mentions and DMs to check the unfurling of profile names
3. Ran unit tests

Closes: https://github.com/damus-io/damus/issues/1703
Changelog-Added: Unfurl profile name on remote push notifications
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 10:37:45 -08:00
vuittont60
460f536fa3 docs: fix typos
Closes: https://github.com/damus-io/damus/pull/1856
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 10:06:15 -08:00
William Casarin
c3e94f367c docs: update CONTRIBUTING to mention v2 patch series
I realized we didn't have this in the contributor docs. Noone will read
it, but at least we'll have something to point to for future contributors.

Cc: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 09:56:19 -08:00
bf78c0a3a0 translation: add workaround to reduce wasteful translation requests
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Fixed: Add workaround to fix note language recognition and reduce wasteful translation requests
2024-01-08 12:28:33 -08:00
Charlie Fish
eb41846bb9 search: prioritize friends when autocompleting
Lightning-Address: fishcharlie@strike.me
Closes: https://github.com/damus-io/damus/issues/1620
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Changed: Prioritize friends when autocompleting
2024-01-08 12:28:29 -08:00
Charlie Fish
f7946b1a7c relay: fix case where content is empty when adding relay
Lightning-Address: fishcharlie@strike.me
Closes: https://github.com/damus-io/damus/issues/1849
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Fixed: Fix issue where adding relays might not work on corrupted contact lists
2024-01-08 12:28:24 -08:00
Charlie Fish
84cfeb1604 nip42: add initial relay auth support
Lightning-Invoice: lnbc1pjcpaakpp5gjs4f626hf8w6slx84xz3wwhlf309z503rjutckdxv6wwg5ldavsdqqcqzpgxqrrs0fppqjaxxw43p7em4g59vedv7pzl76kt0qyjfsp5qcp9de7a7t8h6zs5mcssfaqp4exrnkehqtg2hf0ary3z5cjnasvs9qyyssq55523e4h3cazhkv7f8jqf5qp0n8spykls49crsu5t3m636u3yj4qdqjkdl2nxf6jet5t2r2pfrxmm8rjpqjd3ylrzqq89m4gqt5l6ycqf92c7h
Closes: https://github.com/damus-io/damus/issues/940
Signed-off-by: Charlie Fish <contact@charlie.fish>
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Added: Add NIP-42 relay auth support
2024-01-05 10:36:03 -08:00
Charlie Fish
4c37bfc128 profile: filter events that don’t match pubkey
Closes: https://github.com/damus-io/damus/issues/1846
Lightning-Invoice: lnbc1pjef2gupp5ffv0he47r6s6us9s2pfxy023mx8lutwlh3sq365rzgmmj6efl8nsdqqcqzpgxqrrs0fppq65gwnyvf5pn5zj5ryx9s4n7y58clk7yqsp5v7pa2ges4rgvtt0nh6lnt4cevm8n2ql9p7kqstwfp4wutf8faa8q9qyyssqwx8t9kk0m3jj6vu0kvftl3nc8zqyfl5l8ne058q5dnqyad3cqfz8vdnna5g0vy9f2ttwugc0sr20p0hsem84g8xd85ptnwgmryrf4lqqmygv34
Signed-off-by: Charlie Fish <contact@charlie.fish>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Fixed: Fixed bug where sometimes notes from other profiles appear on profile pages
2024-01-05 10:36:02 -08:00
kernelkind
548af2bf9d localization: add support for purple strings
Add string localizations so the purple landing pages can have multi language support.

LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G

Closes: https://github.com/damus-io/damus/issues/1816
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Reviewed-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-05 10:36:02 -08:00
kernelkind
692146fe00 add comma as disallowed char at end of url
Do not include comma as part of a URL if it is followed by whitespace.
This allows users to make lists of URLs.

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

LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G

Signed-off-by: kernelkind <kernelkind@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-02 12:07:55 -08:00
William Casarin
40134b4365 Merge translations 2024-01-01 14:54:50 -08:00
Daniel D’Aquino
9a547077c1 Hook up Damus Purple translation service
This commit integrates the Damus Purple translation service:
- Automatically handles translation settings change after purchase
- Asks for permission to override translation settings if the user already has translation setup
- Translation settings can be changed with Damus Purple, if desired
- Translation requests working with the Damus API server

Testing
--------

PASS

Device: iPhone 15 simulator
iOS: 17.2
Damus: This commit
Damus Purple API server: `9397201d7d55ddcec4c18fcd337f759b61dce697` running on Ubuntu 22.04 LTS VM (npm run dev)
iOS setting: English set as the only preferred language.
Steps:
1. Enable Damus Purple feature flag on developer settings, set purple localhost mode, and restart app
2. Set translation setting to something other than none (e.g. DeepL)
3. Simulate Damus Purple purchase
4. Check that when dismissing welcome view, a confirmation prompt will ask the user whether they want to switch translator to Damus Purple. PASS
5. Click "Yes".
6. Go to translation settings. Check that translation settings are set to "Purple". PASS
7. Go to a non-English profile. Check that translations appear with "Mock translation" (Which is the translation text provided by the mock translation server). PASS
8. Reinstall app
9. Repeat the test, but this time starting with no translation settings. Make sure that translation settings will automatically switch to Damus Purple. PASS

Feature flag testing
--------------------

PASS

Preconditions: Same as above
Steps:
1. Turn off translation
2. Turn off Damus Purple feature flag
3. Go to translation settings. Make sure that Damus Purple is not an option. PASS

Closes: https://github.com/damus-io/damus/issues/1836
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-01 04:44:24 -08:00
transifex-integration[bot]
0d71cc18ad Translate Localizable.stringsdict in sv_SE
100% translated source file: 'Localizable.stringsdict'
on 'sv_SE'.
2023-12-31 07:59:57 +00:00
transifex-integration[bot]
d10554ab6c Translate InfoPlist.strings in sv_SE
100% translated source file: 'InfoPlist.strings'
on 'sv_SE'.
2023-12-31 07:58:53 +00:00
transifex-integration[bot]
2656c30832 Translate Localizable.strings in sv_SE
100% translated source file: 'Localizable.strings'
on 'sv_SE'.
2023-12-31 07:56:49 +00:00
Daniel D’Aquino
39b6dfb47e purple: update client to work with damus-api post express refactor
these changes were made to adapt the client-side to the new improvements
done to the Purple API server (See
https://github.com/damus-io/api/issues/1)

Testing
-------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.2
Damus: This commit
damus-api: bda56590be7eb47e21dfd61ab94b17f6a8595d0c
Server: Ubuntu 22.04 (VM)
Setup:
1. On the server, delete the `mdb` database files to start from scratch
2. Enable subscriptions support via developer settings with localhost
   test mode and restart app
3. Get Damus Purple (Purchase it via Xcode test environment)
4. Start server with mock parameters (Run `npm run dev`)
5. Restart app

Steps
-----

1. Post something
2. Gold star should appear beside your name
3. Look at the server logs. There should be some requests to create the
   account (POST), to send the receipt (POST), and to get account
   status. Those three requests should have returned HTTP status 200.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-27 18:42:38 -08:00
Daniel D’Aquino
5ca5420ce2 Damus Purple: Add npub authentication for account management API calls
Testing
---------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.2
Damus: This commit
damus-api: 626fb9665d8d6c576dd635d5224869cd9b69d190
Server: Ubuntu 22.04 (VM)
Setup:
1. On the server, delete the `mdb` database files to start from scratch
2. In iOS, reinstall the app if necessary to make sure there are no in-app purchases
3. Enable subscriptions support via developer settings with localhost test mode and restart app
4. Start server with mock parameters (Run `npm run dev`)

Steps:
1. Open top bar and click on "Purple"
2. Purple screen should appear and show both benefits and the purchase options. PASS
3. Click on "monthly". An Apple screen to confirm purchase should appear. PASS
4. Welcome screen with animation should appear. PASS
5. Click continue and restart app (Due to known issue tracked at damus-io#1814)
6. Post something
7. Gold star should appear beside your name
8. Look at the server logs. There should be some requests to create the account (POST), to send the receipt (POST), and to get account status
9. Go to purple view. There should be some information about the subscription, as well as a "manage" button. PASS
10. Click on "manage" button. An iOS sheet should appear allow the user to unsubscribe or manage their subscription to Damus Purple.

Closes: https://github.com/damus-io/damus/issues/1809
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-24 09:30:26 -08:00
Daniel D’Aquino
4703ed80a7 Damus Purple initial Proof-of-Concept support
This commit includes various code changes necessary to get a basic proof of concept of the feature working.

This is NOT a full working feature yet, only a preliminary prototype/PoC. It includes:
- [X] Basic Storekit configuration
- [X] Basic purchase mechanism
- [X] Basic layout and copywriting
- [X] Basic design
- [X] Manage button (To help user cancel their subscription)
- [X] Thank you confirmation + special welcome view
- [X] Star badge on profile (by checking the Damus Purple API)
- [X] Connection to Damus purple API for fetching account info, registering for an account and sending over the App Store receipt data

The feature sits behind a feature flag which is OFF by default (it can be turned ON via Settings --> Developer settings --> Enable experimental Purple API and restarting the app)

Testing
---------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
damus-api: 59ce44a92cff1c1aaed9886f9befbd5f1053821d
Server: Ubuntu 22.04 (VM)
Setup:
1. On the server, delete the `mdb` database files to start from scratch
2. In iOS, reinstall the app if necessary to make sure there are no in-app purchases
3. Enable subscriptions support via developer settings with localhost test mode and restart app
4. Start server with mock parameters (Run `npm run dev`)

Steps:
1. Open top bar and click on "Purple"
2. Purple screen should appear and show both benefits and the purchase options. PASS
3. Click on "monthly". An Apple screen to confirm purchase should appear. PASS
4. Welcome screen with animation should appear. PASS
5. Click continue and restart app (Due to known issue tracked at https://github.com/damus-io/damus/issues/1814)
6. Post something
7. Gold star should appear beside your name
8. Look at the server logs. There should be some requests to create the account (POST), to send the receipt (POST), and to get account status
9. Go to purple view. There should be some information about the subscription, as well as a "manage" button. PASS
10. Click on "manage" button. An iOS sheet should appear allow the user to unsubscribe or manage their subscription to Damus Purple.

Feature flag testing
--------------------

PASS

Preconditions: Continue from above test
Steps:
1. Disable Damus Purple experiment support on developer settings. Restart the app.
2. Check your post. There should be no star beside your profile name. PASS
3. Check side menu. There should be no "Damus Purple" option. PASS
4. Check server logs. There should be no new requests being done to the server. PASS

Closes: https://github.com/damus-io/damus/issues/1422
2023-12-24 09:30:26 -08:00
Daniel D’Aquino
f7e407e030 Fix crash on very large notes
This commit fixes a crash that occured on large notes with several artifacts.

The crash was caused by an empirically observed limitation on the amount
of `Text` objects that can be added together. Adding several `Text`
objects together causes a infinite recursion and subsequent stack
overflow.

The fix applied changes the `CompatibleText` class to store several
items in a list, which concatenates attributed strings when possible to
reducethe amount of `Text` objects used.

This commit also:

- Changes the structure to avoid storing SwiftUI objects on a variable,
  but making it into a computed property instead.

- Renders a nice error message when the note is too large to be rendered
  (instead of crashing)

With this new commit, we can render much larger notes, and the only ones
that will not be displayed are those containing more than 50 custom
hashtags.

Since we do not even have 50 custom hashtag types, the only notes that
won't be rendered are spammy notes that repeat the same hashtags over
and over again.

Testing
-------

PASS

Device: iPhone 13 Mini (Physical device)
iOS: 17.2
Damus: This commit
Setup:

- Local test relay and a test account running on a simulator to post
  those long test notes.

- Local web page server to serve a link to the problematic note.
  (nostr:note1ttfgneka3lt6yuutmr0uls5xd6z975fgdzpfkxwwf40dd38pjcqqvzvxaj)

Steps
-----

1. Click on the link to open the note
2. Check that no crash occurs and that the note is rendered correctly. PASS
3. Click on the note to render the SelectableText view (Different code
   path). Make sure that no crash occurs and that it is rendered
   correctly. PASS
4. On the simulator, post a note with 50 "#bitcoin" hashtags displayed
   (100 items).
5. Open the note on the physical iPhone. Make sure that no crash occurs
   and that the note is rendered correctly. PASS
6. Ensure that the hashtag and hashtag icons are rendered. PASS
7. Click on the note and make sure that the SelectableText view is
   rendered correctly. PASS[1]
8. On the simulator, post a note with 51 "#bitcoin" hashtags displayed
   (102 items).
9. Open the note on the physical iPhone. Make sure that a nice error
   message is displayed. PASS
10. Click on the note and make sure that the SelectableText view is
    rendered correctly. PASS[1]

Notes

[1] On the SelectableText view, special hashtags always render with the
purple color. This behavior was already present before the changes, so
it is not a regression.

Changelog-Fixed: Fix crash on very large notes
Closes: https://github.com/damus-io/damus/issues/1826
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-24 09:27:46 -08:00
kernelkind
e547e26d99 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.

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

LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G

Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-22 14:00:15 -08:00
kunigaku
f6044a9eea Fix Issue #1820 Hashtags including U+5009 to U+500D are not correctly parsed
Closes: https://github.com/damus-io/damus/pull/1830
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-22 13:59:31 -08:00
Daniel D’Aquino
26bd50c948 Revert "nostrdb: close database when backgrounded"
This reverts commit da2bdad18d.

This commit was reverted because it was causing crashes (Occasional `EXC_BAD_ACCESS` errors when accessing database transactions), and because the push notification extension uses Ndb in a read-only manner, which means we no longer need these changes

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2023-12-22 13:57:21 -08:00
Daniel D’Aquino
6e0af0ba10 tests: Disable NostrScriptTests.test_bool_set to reduce noise on CI/CD
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-22 13:56:57 -08:00
transifex-integration[bot]
44b7ae2054 Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2023-12-21 15:15:36 +00:00
transifex-integration[bot]
9cc21fc860 Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2023-12-21 15:10:49 +00:00
transifex-integration[bot]
c9526b7aa6 Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2023-12-21 15:09:44 +00:00
transifex-integration[bot]
055b7af1a3 Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2023-12-21 15:09:26 +00:00
transifex-integration[bot]
de0b1dbda2 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2023-12-21 15:06:43 +00:00
transifex-integration[bot]
7605af84b5 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2023-12-21 14:58:13 +00:00
transifex-integration[bot]
d45eadef35 Translate Localizable.stringsdict in zh_HK
100% translated source file: 'Localizable.stringsdict'
on 'zh_HK'.
2023-12-21 14:54:30 +00:00
transifex-integration[bot]
9cae934062 Translate InfoPlist.strings in zh_HK
100% translated source file: 'InfoPlist.strings'
on 'zh_HK'.
2023-12-21 14:54:10 +00:00
transifex-integration[bot]
7fb5cdf6c0 Translate InfoPlist.strings in zh_TW
100% translated source file: 'InfoPlist.strings'
on 'zh_TW'.
2023-12-21 14:53:43 +00:00
transifex-integration[bot]
49bbe62d2a Translate Localizable.stringsdict in zh_TW
100% translated source file: 'Localizable.stringsdict'
on 'zh_TW'.
2023-12-21 14:51:53 +00:00
transifex-integration[bot]
705accd309 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2023-12-21 12:49:48 +00:00
transifex-integration[bot]
3375ccc4fa Translate InfoPlist.strings in zh_CN
100% translated source file: 'InfoPlist.strings'
on 'zh_CN'.
2023-12-21 12:25:37 +00:00
transifex-integration[bot]
a9fecc3047 Translate Localizable.stringsdict in zh_CN
100% translated source file: 'Localizable.stringsdict'
on 'zh_CN'.
2023-12-21 12:23:51 +00:00
transifex-integration[bot]
31b3ad9825 Translate Localizable.strings in fa
100% translated source file: 'Localizable.strings'
on 'fa'.
2023-12-20 18:13:21 +00:00
transifex-integration[bot]
2bde3a9217 Translate Localizable.stringsdict in fa
100% translated source file: 'Localizable.stringsdict'
on 'fa'.
2023-12-20 15:26:19 +00:00
transifex-integration[bot]
6050116314 Translate InfoPlist.strings in fa
100% translated source file: 'InfoPlist.strings'
on 'fa'.
2023-12-20 15:23:11 +00:00
kernelkind
a2cac142c0 Remove private key leak warning
Remove the private key leak warning in the DMChatView and PostView since
they are no longer needed since nsec is automatically converted into
npub.

Changelog-Removed: Removed old nsec key warning, nsec automatically convert to npub when posting
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-18 10:28:31 -08:00
kernelkind
8a20e5845e Remove line break at the end of direct messages
Closes: https://github.com/damus-io/damus/issues/1599
Changelog-Fixed: Remove extra space at the end of DM messages
Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-18 10:24:10 -08:00
William Casarin
641e2564fb Merge remote-tracking branch 'github/translations' 2023-12-18 10:24:01 -08:00
transifex-integration[bot]
50810033c0 Translate Localizable.stringsdict in es_ES
100% translated source file: 'Localizable.stringsdict'
on 'es_ES'.
2023-12-17 16:51:02 +00:00
transifex-integration[bot]
fab4e231b6 Translate Localizable.strings in es_ES
100% translated source file: 'Localizable.strings'
on 'es_ES'.
2023-12-17 16:50:15 +00:00
transifex-integration[bot]
42ff49a803 Translate Localizable.strings in es_ES
100% translated source file: 'Localizable.strings'
on 'es_ES'.
2023-12-17 16:50:09 +00:00
transifex-integration[bot]
8c878cbc4c Translate InfoPlist.strings in es_ES
100% translated source file: 'InfoPlist.strings'
on 'es_ES'.
2023-12-17 16:16:51 +00:00
transifex-integration[bot]
face4268bf Translate Localizable.strings in es_419
100% translated source file: 'Localizable.strings'
on 'es_419'.
2023-12-17 16:12:23 +00:00
transifex-integration[bot]
fed6c47835 Translate Localizable.strings in es_419
100% translated source file: 'Localizable.strings'
on 'es_419'.
2023-12-17 16:09:43 +00:00
transifex-integration[bot]
8e9fb308f9 Translate Localizable.strings in es_419
100% translated source file: 'Localizable.strings'
on 'es_419'.
2023-12-17 16:08:55 +00:00
transifex-integration[bot]
89b48db92d Translate Localizable.stringsdict in es_419
100% translated source file: 'Localizable.stringsdict'
on 'es_419'.
2023-12-17 16:06:28 +00:00
transifex-integration[bot]
9581cc994d Translate Localizable.strings in es_419
100% translated source file: 'Localizable.strings'
on 'es_419'.
2023-12-17 16:05:30 +00:00
kernelkind
34e32bc930 handle extra slashes for relay url
Closes: https://github.com/damus-io/damus/issues/1766

Signed-off-by: kernelkind <kernelkind@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-16 17:43:00 -08:00
ericholguin
dfcef0ba95 refactor: rename show image references to blur images
Closes: https://github.com/damus-io/damus/pull/1745
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-13 11:02:15 -08:00
William Casarin
3c11ba53ce add transifex mailmap 2023-12-13 11:02:15 -08:00
transifex-integration[bot]
9759787c95 Translate Localizable.stringsdict in hu_HU
100% translated source file: 'Localizable.stringsdict'
on 'hu_HU'.
2023-12-12 12:09:45 +00:00
transifex-integration[bot]
eef428ce4f Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2023-12-12 12:09:10 +00:00
transifex-integration[bot]
d69647e071 Translate InfoPlist.strings in hu_HU
100% translated source file: 'InfoPlist.strings'
on 'hu_HU'.
2023-12-12 11:47:23 +00:00
Daniel D’Aquino
c22f5e90a3 Add regional relay suggestions to Relay Config View
This patch makes sure that regional relays (e.g. Japan relays) are suggested to the relevant users on the Relay configuration view.

It also makes some small improvements to the recommended relays view layout, to allow it to comfortably show more than 4 relay suggestions without "squeezing" items.

Testing
-------

PASS

Devices:
- iPhone 15 Pro simulator running iOS 17.0.1
- iPad Air 5th generation running iOS 16.4
Damus: This commit
Configuration: No relays selected, region set to Canada
Steps:
1. Go to Relay Config view
2. Check that recommended relays are: Damus, nos.lol, nostr.wine, nostr.land. PASS
3. Change region to Japan on settings
4. Open relay config view again
5. Check that Japan relays are suggested on top of the list presented in step 2. PASS
6. Check that layout looks ok, not broken. PASS
7. Check that it is possible to scroll horizontally to see all the options. PASS
8. Add some relays. Check that it is possible to add relays. PASS
9. Check that borders of the recommended relay view fades away nicely (not just clip). PASS
10. Remove some relays. Check that they return to the suggested relays list. PASS

Real device smoke test
----------------------

Device: iPhone 13 mini running iOS 17.1
Damus: This commit
Configuration: Several relays selected. Region set to Canada.
Steps:
1. Check relay config view does not look broken. PASS
2. Remove some recommended relays. Check that they display nicely on the recommended view. PASS
3. Scroll horizontally. Scrolling should work and layout should not be broken. PASS
4. Add those recommended relays again. Should work. PASS

Closes: https://github.com/damus-io/damus/issues/1730
Changelog-Added: Add regional relay recommendations to Relay configuration view (currently for Japanese users only)
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-11 14:59:56 -08:00
ericholguin
f2fe02032e refactor: add customizable properties to neutral button style
Closes: https://github.com/damus-io/damus/pull/1805
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-11 14:59:33 -08:00
William Casarin
da2bdad18d nostrdb: close database when backgrounded
Otherwise iOS gets mad because we are holding onto a lockfile in a
shared container which is apparently not allowed.

Fixes: a1e6be214e ("Migrate NostrDB files to shared app group file container")
2023-12-11 14:59:33 -08:00
William Casarin
c7cc8df5ba nostrdb: don't begin query if we have a bad lmdb env
In some weird multithreaded situations after we close the database,
this can be an issue.
2023-12-11 14:59:33 -08:00
William Casarin
92df446d72 Update Translations 2023-12-11 14:59:33 -08:00
transifex-integration[bot]
7ea2af6172 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2023-12-11 16:24:29 +00:00
transifex-integration[bot]
184eea6e68 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2023-12-11 09:54:47 +00:00
transifex-integration[bot]
82372d1bf5 Translate InfoPlist.strings in pl_PL
100% translated source file: 'InfoPlist.strings'
on 'pl_PL'.
2023-12-11 09:53:49 +00:00
transifex-integration[bot]
39f59eb798 Translate Localizable.stringsdict in ja
100% translated source file: 'Localizable.stringsdict'
on 'ja'.
2023-12-11 06:13:42 +00:00
transifex-integration[bot]
639deec1a2 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2023-12-11 06:12:32 +00:00
transifex-integration[bot]
18780002bb Translate Localizable.stringsdict in fi
100% translated source file: 'Localizable.stringsdict'
on 'fi'.
2023-12-10 16:32:31 +00:00
transifex-integration[bot]
722180bb9a Translate Localizable.stringsdict in fi
100% translated source file: 'Localizable.stringsdict'
on 'fi'.
2023-12-10 16:32:24 +00:00
transifex-integration[bot]
366a584934 Translate Localizable.stringsdict in fi
100% translated source file: 'Localizable.stringsdict'
on 'fi'.
2023-12-10 16:32:15 +00:00
transifex-integration[bot]
9ee09c3b59 Translate Localizable.stringsdict in fi
100% translated source file: 'Localizable.stringsdict'
on 'fi'.
2023-12-10 16:32:03 +00:00
transifex-integration[bot]
e8caf3a7f4 Translate Localizable.stringsdict in fi
100% translated source file: 'Localizable.stringsdict'
on 'fi'.
2023-12-10 16:31:50 +00:00
transifex-integration[bot]
b4ff6ee614 Translate Localizable.stringsdict in fi
100% translated source file: 'Localizable.stringsdict'
on 'fi'.
2023-12-10 16:31:35 +00:00
transifex-integration[bot]
ed652db3d3 Translate InfoPlist.strings in es_419
100% translated source file: 'InfoPlist.strings'
on 'es_419'.
2023-12-09 23:36:14 +00:00
transifex-integration[bot]
3d01c29148 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-12-09 17:39:48 +00:00
transifex-integration[bot]
1c1bb599ed Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-12-09 17:39:42 +00:00
transifex-integration[bot]
25e6c77d9b Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-12-09 17:39:18 +00:00
transifex-integration[bot]
5aae81c47d Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-12-09 17:39:10 +00:00
transifex-integration[bot]
6b2fd4cec1 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-12-09 17:37:59 +00:00
transifex-integration[bot]
d486af6704 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2023-12-09 17:22:50 +00:00
transifex-integration[bot]
323f920848 Translate InfoPlist.strings in fi
100% translated source file: 'InfoPlist.strings'
on 'fi'.
2023-12-09 15:08:51 +00:00
transifex-integration[bot]
c58c200acb Translate Localizable.strings in fi
100% translated source file: 'Localizable.strings'
on 'fi'.
2023-12-09 15:06:07 +00:00
transifex-integration[bot]
c3786bf849 Translate Localizable.stringsdict in vi
100% translated source file: 'Localizable.stringsdict'
on 'vi'.
2023-12-09 14:56:42 +00:00
transifex-integration[bot]
a0e882db64 Translate InfoPlist.strings in vi
100% translated source file: 'InfoPlist.strings'
on 'vi'.
2023-12-09 14:55:29 +00:00
transifex-integration[bot]
eedf734dae Translate Localizable.strings in vi
100% translated source file: 'Localizable.strings'
on 'vi'.
2023-12-09 14:55:06 +00:00
transifex-integration[bot]
cfa06797b7 Translate Localizable.stringsdict in ko
100% translated source file: 'Localizable.stringsdict'
on 'ko'.
2023-12-09 11:43:35 +00:00
transifex-integration[bot]
824279742c Translate Localizable.strings in ko
100% translated source file: 'Localizable.strings'
on 'ko'.
2023-12-09 11:42:54 +00:00
transifex-integration[bot]
2cdbadd09d Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2023-12-09 10:25:50 +00:00
transifex-integration[bot]
1ea70c8427 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2023-12-09 10:25:31 +00:00
transifex-integration[bot]
09876c06d0 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2023-12-09 08:49:20 +00:00
transifex-integration[bot]
7a063f8aa0 Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2023-12-09 08:49:02 +00:00
transifex-integration[bot]
b8ac026a3d Translate InfoPlist.strings in de
100% translated source file: 'InfoPlist.strings'
on 'de'.
2023-12-09 08:48:06 +00:00
transifex-integration[bot]
c18853c957 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-12-09 08:45:58 +00:00
transifex-integration[bot]
0a09dbfe1c Translate InfoPlist.strings in ko
100% translated source file: 'InfoPlist.strings'
on 'ko'.
2023-12-09 08:10:15 +00:00
transifex-integration[bot]
78e840734a Translate InfoPlist.strings in nl
100% translated source file: 'InfoPlist.strings'
on 'nl'.
2023-12-08 10:06:05 +00:00
transifex-integration[bot]
1ccb300dd1 Translate InfoPlist.strings in nl
100% translated source file: 'InfoPlist.strings'
on 'nl'.
2023-12-08 10:05:59 +00:00
transifex-integration[bot]
049a32db41 Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2023-12-08 10:05:15 +00:00
transifex-integration[bot]
d82add1080 Translate InfoPlist.strings in ja
100% translated source file: 'InfoPlist.strings'
on 'ja'.
2023-12-08 08:01:06 +00:00
9d42715d76 Fix localization issues and export strings for translation 2023-12-07 15:13:57 -08:00
transifex-integration[bot]
14fd06c052 Translate Localizable.strings in cs
100% translated source file: 'Localizable.strings'
on 'cs'.
2023-12-07 14:46:17 -08:00
transifex-integration[bot]
e2ab3a41b4 Translate InfoPlist.strings in cs
100% translated source file: 'InfoPlist.strings'
on 'cs'.
2023-12-07 14:46:17 -08:00
transifex-integration[bot]
6d7c2af504 Translate Localizable.strings in zh_HK
100% translated source file: 'Localizable.strings'
on 'zh_HK'.
2023-12-07 14:46:17 -08:00
transifex-integration[bot]
f5fbd1d3c1 Translate Localizable.stringsdict in zh_HK
100% translated source file: 'Localizable.stringsdict'
on 'zh_HK'.
2023-12-07 14:46:16 -08:00
transifex-integration[bot]
c4333280dd Translate Localizable.stringsdict in zh_TW
100% translated source file: 'Localizable.stringsdict'
on 'zh_TW'.
2023-12-07 14:46:16 -08:00
transifex-integration[bot]
6b6a98b71f Translate Localizable.stringsdict in zh_CN
100% translated source file: 'Localizable.stringsdict'
on 'zh_CN'.
2023-12-07 14:46:15 -08:00
ericholguin
3e5029a4ad ui: allow users to collapse suggested hashtag view
Closes: https://github.com/damus-io/damus/pull/1789
Changelog-Added: Add ability to hide suggested hashtags
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-05 13:56:52 -08:00
ericholguin
05b2cb6376 ux: minor improvements to qrcode scanning in images
Closes: https://github.com/damus-io/damus/pull/1787
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-05 13:56:52 -08:00
William Casarin
c4af40e64f textsearch: don't clear results if we get no results while typing
When you are searching for results, don't wipe the current result set if
there are some previous results and the current query is returning 0
results. This is pretty common when you start typing, it's weird for the
results to randomly clear when looking for stuff.
2023-12-05 12:33:16 -08:00
William Casarin
afc42d1952 nostrdb/writer: make sure we don't write a note if we already have it
I'm noticing duplicate notes in the database, which might happen when
the ingester and writer get spammed with the same note rapidly. Add a
sanity check during the write so that we only ever write a note once.

Fixes: 1cf898e0b2 ("ndb: update nostrdb")
Changelog-Fixed: Fix duplicate notes getting written to nostrdb
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-04 14:54:28 -08:00
William Casarin
579303f741 ndb: fix minor text search result bug 2023-12-04 14:51:58 -08:00
William Casarin
104f490e86 v1.7
Set the version at the project level so that our extension inherits it
as well
2023-12-04 13:26:24 -08:00
William Casarin
a07b78e47f ndb: add safemode so we don't instantly crash on bad dbs
Fixes: https://github.com/damus-io/damus/issues/1741
2023-12-04 13:26:24 -08:00
William Casarin
4e447ddbed ndb/txn: inherit active transactions on the same thread
Many different parts of the codebase could be opening transactions when
somewhere higher in the heirarchy on the main thread might already have
an active transaction. This can lead to failed transaction opening which
is bad.

Instead of relying on passing down the transaction to subviews, lets
keep track of the active transactions in a thread-local dictionary. That
way whenever we create a new transaction we can inherit the one that is
already active in the current thread.

Inherited transactions don't end the query when they are garbage
collected, we still expect the first-opened query to do this.
2023-12-04 13:26:24 -08:00
William Casarin
f6b59b3f5d search: debounce when searching
so we don't spawn tons of searching tasks for no reason
2023-12-04 13:26:24 -08:00
William Casarin
e40d5b3e83 damus/c: fix a few warnings 2023-12-04 13:26:24 -08:00
William Casarin
4bf8a68c9c search: add damus search ui 2023-12-03 22:13:46 -08:00
William Casarin
0a9ac9cb0d ndb: more dumb results building 2023-12-03 22:13:11 -08:00
William Casarin
9c3b052de2 ndb/note: always track note size, add to_owned 2023-12-03 22:12:31 -08:00
William Casarin
59cde41764 build: fix a few warnings 2023-12-03 22:12:00 -08:00
William Casarin
9502fc30ba ndb: add initial search interface
Still needs updating because of the tuple array
2023-12-02 15:05:15 -08:00
William Casarin
6b8cf51720 nostrdb/search: fix another newest-first bug
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 15:04:23 -08:00
William Casarin
f72b297d77 nostrdb: add cpu helper 2023-12-02 13:47:17 -08:00
William Casarin
dd78272a5e Ndb: update to use new nostrdb config struct 2023-12-02 13:44:03 -08:00
William Casarin
65be56ba7c fix some incompatibility between nostrdb and damus' 2023-12-02 13:44:03 -08:00
William Casarin
8e361a9586 nostrdb/search: fix subtle bug with some newest-first text search
Due to the way the range queries work for newest-first searches, we can
have a situation where the MDB_SET_RANGE gets placed on either the
correct place or just after the correct place. To position the cursor
correctly, we jump back one if the search result prefix doesn't match.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
9bbeffe320 nostrdb/search: also index longform
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
3e5d7581ba nostrdb/refactor: move search key printer in case we need it
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
06445de197 nostrdb/search: make sure we break instead of return
so the cursor has a chance to close

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
e537c7cef4 nostrdb/search: allow searching from newest-to-oldest and oldest-to-newest
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
01c239c0eb nostrdb/search: add limit param
If we only care to have a certain number of results

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
bec92249f9 nostrdb/search: remove result printing, move to util/ndb
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
hakkadaikon
aa0b9bde8f nostrdb/Delete unuse argument (destsize)
Closes: https://github.com/damus-io/nostrdb/pull/18
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
4e4e8ed460 nostrdb/rename get_physical_cores to get_cpu_cores
less wrong

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
3605edad8b nostrdb/config: fix ingester thread settings
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
04c207a11a nostrdb/ingest: add configurable ingest filter
This allows users of nostrdb to selectively filter notes of any kind during
ingest.

Contact lists too big? Create a filter to reject them.

You only care about notes with specific kinds? Reject everything else.

Damus will use this for rejecting large events that might take up too
much space for storage, such as contact lists.

This commit also switched to ndb_config for configuring nostrdb, because
the arguments to ndb_init were getting out of hand.

Changelog-Added: Added ingest filter setting
Changelog-Changed: Switch to ndb_config for per-session ndb settings
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
9d208284c6 nostrdb/search: phrase searching working
This changes the search algorithm to be much smarter and more efficient
at searching phrases.

It is also much simpler, using less intermediate data structures.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
213a26cd01 nostrdb/flag: add ndb config flag for skipping note verification
makes some large imports a bit faster

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
b74bde5cc4 nostrdb/search: fix infinite loop when parsing some notes
Our word parser gets stuck on some notes with utf8 chars. Make sure we
are always advancing so we don't get stuck.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
0e0c53145f nostrdb/segfault: fix weird crash in ispunct
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
76aa1d3450 nostrdb/db: remove the DUPFIXED flag from the fulltext db
I don't think this technically makes any sense

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
fa0d5e7d03 nostrdb/debug: fix some debug-mode compile issues
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
8446db7cbc nostrdb/search: prepare text search for accurate phrase results
This patch sets the stage for phrase searching. It collects data into
result sets based on words and the word's associated key. We can use
this data to select the best search results based on adjacent
word_indices.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
8679c9f293 nostrdb/search: make search case insensitive
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
d541153e4c nostrdb/Add fulltext search index
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
53fc1b6945 nostrdb/Fix invalid db selection when writing kind index
Fixes: ebe92071af18 ("index: write kind index when processing notes")
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
ff60f8a2db nostrdb/index: write kind index when processing notes
We have a kind index database now, so write to it when processing notes

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
bfd78c01ca nostrdb/refactor: move write id index to its own function
We will be writing more indices so I'm trying to clean this up a bit
before this function gets too messy

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
a2af030367 nostrdb/refactor: move profile index writing to its own function
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
3c2e8b728f nostrdb/index: create kind+timestamp index database
We don't build the index yet, but create the database like the others.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
8269ca59cd nostrdb/index: add u64_timestamp lmdb comparator
custom kind+timestamp comparison function. This is used by lmdb to
perform b+ tree searches over the kind+timestamp index.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
0f9d55d4f9 nostrdb/debug: use mdb_strerror in more places
instead of codes

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
4109649dc2 nostrdb/filter: make sure we only match single chars
Without this, we could accidently match `pr` for `#p` filters

Fixes: 30ed801285dd ("filters: add initial filter interface")
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
466dfcb7d7 nostrdb/filters: add initial filter interface
This adds a way to construct filters and match them against notes. This
will be used by our query interface in the future.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-02 13:44:03 -08:00
William Casarin
27905d24b4 cursor: add cursor_memset 2023-12-02 13:44:03 -08:00
Kieran
7a5aef94a8 relays: Publish kind 10_002
Closes: https://github.com/damus-io/damus/pull/1783
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-12-01 09:58:07 -08:00
Jing维
9e4f0122f5 update testdata URL path
Closes: https://github.com/damus-io/damus/pull/1767
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-26 13:06:10 -08:00
ericholguin
a80ddc08ec settings: add media previews setting
Closes: https://github.com/damus-io/damus/pull/1757
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-23 10:57:23 -08:00
Daniel D’Aquino
6daa4f7e13 Add regional relays for Thailand and Germany.
This commit adds region-specific relays for Thailand and Germany. The list was blindly copied and pasted from the tickets.

Testing
-------

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: A locally modded version combining these changes with changes made in #1730 (A bit hacky, but makes testing faster)
Steps:
1. Change region to Canada. Only international relays should be shown in recommended relay list. PASS
2. Change region to Japan. International + Japanese relays should be shown in the recommended list. PASS
3. Repeat step (2) for Thailand and Germany. International + corresponding regional relays should be shown. PASS

Changelog-Added: Add regional relays for Thailand
Closes: https://github.com/damus-io/damus/issues/1698
Changelog-Added: Add regional relays for Germany
Closes: https://github.com/damus-io/damus/issues/1750
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-23 10:42:18 -08:00
ericholguin
9686f82e8f ux: only handle one qr code in an image and add copy functionality
Closes: https://github.com/damus-io/damus/pull/1758
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-22 12:52:25 -08:00
Daniel D’Aquino
a1e6be214e Migrate NostrDB files to shared app group file container
This change was made so that NostrDB data can be accessed from different build targets such as the notification service extension.

Upon initialization of NostrDB, it will check both DB file locations (the old documents directory, and the new shared app group container). If it sees the DB is present on the old location, and not on the new location, it will move the files to the new location. In any other condition it will keep the files intact to prevent data loss.

In order to avoid any conflicts between the damusApp's Ndb instance and the extension's Ndb instance when writing or moving the file, a new parameter called "owns_db_file" was added, and set to "false" for the extension. This ensures that the extension will not attempt to move DB files or create a new DB file on its own. Only the main app can move or create the DB file.

Testing
-------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Steps:
1. Run with the debugger attached to the extension target.
2. Using Apple's push notification testing dashboard, send a test push notification with a real payload (that includes the nostr event under `nostr_event`. Payload generated by strfry-push-notify).
3. Watch logs. It should show a message like "Got push notification from <DISPLAY_NAME>", where `DISPLAY_NAME` is the correct profile name of the user who generated the event. PASS

Regression testing
------------------

Device: iPhone 13 Mini (Real device)
iOS: 17.1.1
Damus: This commit
Other preconditions:
- Damus is at 1.6 (29) at the start of the test
- NostrDB filled with real data on the old location
Steps:
1. Flash (upgrade) the new Damus version (this commit) (This will be the first time upgrading, shared file container is empty)
2. Try to use the app normally. Scroll and navigate to several locations. Interact with some notes. App should be stable, work, and appear to have profile names already (i.e. It shouldn't start with a bunch of npubs in the place of profile names on known contacts). PASS
3. Downgrade back to the App store version (v1.6 (29))
4. Try to use the app normally. Scroll and navigate, interact, etc. App should work and be stable, but profile name cache is expected to be lost (i.e. shows npubs for a bit until profile is reloaded into NostrDB). PASS
5. Upgrade app again to the version in this commit.
6. Repeat step 2. Everything should work as normal and all profiles should be preloaded from the start. PASS

Closes: https://github.com/damus-io/damus/issues/1744
2023-11-21 10:39:27 -08:00
Daniel D’Aquino
87860a7151 Make NostrDB (and related) code build under the new extension target as well.
This change includes several source files related to NostrDB into the extension target as well, so that we can use it from that context (and thus enable more advanced push notification formatting and suppression)

To make this change possible, I had to split some source files as well as to move some functions to different files, to ensure we don't have to pull too much unnecessary code into the extension.

Testing
-------

PASS

Device: iPhone 15 Pro simulator
iOS: 17.0.1
Damus: This commit
Test steps:
1. Build DamusNotificationService. Should succeed. PASS
2. Build Damus (the app). PASS
3. Run app, scroll around some notes, go to a few different views, post a note. Should work as normal. PASS
2023-11-21 10:39:27 -08:00
Daniel D’Aquino
ad75d8546c Add experimental push notification support
I added support for the experimental push notifications feature. There are many improvements to be made, so this feature is currently opt-in only. If the user does not opt-in, their device tokens will not be sent out and thus they will receive no push notifications.

We should perform more testing on real-life staging environments before fully releasing this feature.

Testing
-------

Testing was done gradually during development.

Device: iOS simulators
iOS: 17
Damus version: A few different but recent prototypes
Rough coverage:
1. Checked that no device tokens are sent out when setting is off
2. Checked that I can successfully receive device tokens when feature is ON and set to localhost.
3. Checked sending test push notifications of types "note" (kind: 1), reaction (kind: 7) and DMs (kind 4) works and shows a generic but reasonable push notification message
4. Checked that clicking on the notifications above take the user to the correct screen

Closes: https://github.com/damus-io/damus/issues/67
Changelog-Added: Add experimental push notification support
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-20 10:32:33 -08:00
Daniel D’Aquino
878b1caa95 Fix onboarding post view not being dismissed
This commit fixes the issue where clicking "post" on the onboarding sheet does not dismisses itself under certain device/iOS combos.

The root cause is that the behavior of `dismiss` calls under a deeply nested view (i.e. not a direct subview of the sheet) is inconsistent depending on the device or iOS.

This fix does two things:
1. It upgrades the usage of `presentationMode` (which is deprecated) to the new `dismiss` API
2. It makes the onboarding sheet view (A direct subview of the sheet) to listen to signals from the post view and use that to also call `dismiss()`, which is explicitly supported by Apple in their docs (https://developer.apple.com/documentation/swiftui/environmentvalues/dismiss)

Testing
-------

PASS

Device: iPhone 13 mini (physical device)
iOS: 17.1
Damus: This commit (Local build, no local mods)
Setting: "Always show onboarding" is set to ON
Coverage:
1. Clicking "post" on onboarding post view publishes the post and dismisses the view. PASS
2. Clicking "cancel" on onboarding post view dismisses the view without publishing. PASS
3. Dragging the onboarding post view down dismisses the view without publishing. PASS
4. Making a normal post (I replied to a thread) still publishes the post and dismisses the normal post view sheet. PASS

Testing on other Device/iOS combos
---------------------------------

PASS

Preconditions:
- iPhone 15 Pro (simulator) on iOS 17.0.1
- iPhone SE 3rd gen (simulator) on iOS 16.4
Damus: This commit (Local build, no local mods)
Setting: "Always show onboarding" is set to ON
Coverage:
1. Clicking "post" on onboarding post view publishes the post and dismisses the view. PASS

Closes: https://github.com/damus-io/damus/issues/1726
Changelog-Fixed: Fix onboarding post view not being dismissed under certain conditions
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-20 08:35:37 -08:00
William Casarin
1fcbba5041 parser: fix url parse regression 2023-11-17 08:57:36 -08:00
William Casarin
20299615ba parser: always convert damus.io links to bech32 mentions
Update our note parse to always interpret damus.io links as bech32
mentions (nostr:npub...)

This means links will get converted to nostr: on post composition, and
if we ever see a link it will also get converted to nostr: visually

Changelog-Added: Always convert damus.io links to inline mentions
Fixes: https://github.com/damus-io/damus/issues/690
2023-11-17 08:09:28 -08:00
William Casarin
972a183ed8 damus-c: add cursor_skip helper
This is a cursor util for skipping over bytes
2023-11-17 08:07:53 -08:00
William Casarin
f976f23854 v1.6 (29)
Almost there!!!
2023-11-15 12:50:44 -08:00
William Casarin
cf13e1ca61 Actually fix camera descriptions 2023-11-15 12:48:56 -08:00
William Casarin
309cbaccce Manually update camera description translation
Just so we can get on the appstore.
2023-11-15 12:23:41 -08:00
William Casarin
d8640e2a1e Update Translations 2023-11-15 12:02:45 -08:00
William Casarin
bc330ab5de update nostrdb
to include potential ingester thread crash fix
2023-11-14 10:26:09 -08:00
William Casarin
41c76d9de0 tests: disable snapshot tests for now
Until they are working on macos and xcode cloud
2023-11-14 07:13:51 -08:00
William Casarin
eaaf802157 test: attempt to fix broken tests 2023-11-13 15:03:17 -08:00
William Casarin
bf59b5850c ci: remove xcode github action
We're using xcode cloud now which seems much more reliable
2023-11-13 15:02:00 -08:00
William Casarin
2585a375ab v1.6 (28) 2023-11-13 10:31:28 -08:00
William Casarin
29fa4ecf2e build: fix invalid function name 2023-11-13 10:31:28 -08:00
William Casarin
518fdffce9 ndb: potential fix for a crash in some nostrdb queries 2023-11-13 10:31:28 -08:00
William Casarin
289e051202 v1.6 (26) 2023-11-13 10:31:28 -08:00
Daniel D’Aquino
2a6c4d0b61 storage: Set more aggressive cache expiration values
I am setting the expiration values lower because it seems that the previous values were not keeping storage usage low enough.

Testing: Testing will be performed as a long-term test on Github issue #1689 (https://github.com/damus-io/damus/issues/1689)
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-11 20:23:37 -08:00
Daniel D’Aquino
386a28455a permissions: Update camera usage string to be more accurate
This changes the text that appears on the camera permission dialog, and makes it clear that camera access is also needed for the scanning of QR codes. This change was made to address a concern raised during the Apple app review process.

Testing
-------

PASS

Device: iPhone 13 Mini (physical)
iOS: 17.1
Damus: This commit
Special remarks: I locally modified the bundle identifier to be able to install a fresh copy of Damus from scratch and go through the prompt, without having to uninstall my own copy of Damus

Steps:
1. Install a fresh copy of Damus
2. On account creation, try to scan an nsec.
3. Make sure the camera usage prompt message is modified to the new string.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-11 20:23:34 -08:00
Daniel D’Aquino
b2e555284b Add "Always show onboarding suggestions" developer setting
This commit adds a new setting that can be used by developers to test onboarding suggestions without having to make local changes to code or reinstall the app.

Testing
-------

Device: iPhone 15 Pro (Simulator)
iOS: 17.0.1
Damus: This commit
Coverage:
1. Starting the existing app under the default setting does not show onboarding suggestions
2. Turning the setting ON causes the app to show onboarding suggestions on every app restart
3. Turning the setting back OFF causes the app to no longer show onboarding suggestions

Changelog-Added: Add "Always show onboarding suggestions" developer setting
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-11 20:23:29 -08:00
William Casarin
cc385d3c3f nostrdb: add migration to fix local japanese profile names 2023-11-02 14:17:17 +09:00
ericholguin
2895c374c0 fix: relay filter button fix
Closes: https://github.com/damus-io/damus/pull/1678
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-11-02 13:21:19 +09:00
William Casarin
6863e74c0f nostrdb: fix japanese profile names not loading
update flatcc, including the patch that fixes japanese usenames

Changelog-Fixed: Fix japanese profiles names not loading
2023-11-02 10:20:40 +09:00
William Casarin
280d889f25 v1.6 (25) changelog 2023-10-31 10:27:55 +09:00
William Casarin
d1d830fca1 v1.6 (25) 2023-10-31 10:26:12 +09:00
Daniel D’Aquino
d2bb013db7 relays: automatically load extra regional bootstrap relays
Depending on user's locale. currently only supported for Japanese users.

This change allows Japanese users to automatically connect with popular
Japanese regional relays during account creation, thus allowing Japanese
users to better connect with the Japanese Nostr community.

More specifically, 3 Japanese regional relays will be automatically
added to the user's relay list (on top of the usual relays) under the
following conditions:

1. User's region (As configured in iOS settings) is Japan, AND
2. The user is creating a new Nostr account through Damus.

In the case the Nostr account is not new, Damus will not add any
regional relays (It will respect the user's relay list).

Testing
-------

PASS

Device: iPhone 15 Pro (Simulator)
iOS: 17.0.1
Damus: This commit
Test steps:

1. With the US region set, install Damus
2. Go through onboarding and create a new account.
3. Once the onboarding is complete, look at the connected relays. Should only be connected with popular international relays. PASS
4. Uninstall Damus
5. On iOS settings, go to Location & Region settings and change the region to Japan.
6. Install Damus
7. Go through onboarding and create a new account.
8. Once the onboarding is complete, look at the connected relays. User should be connected with intl relays as well as Japanese relays. PASS
9. Quit Damus and restart
10. Ensure the Japanese relays are still on the list. PASS
11. Quit Damus
12. Change region back to US
13. Restart Damus and check the relay list. Relay list should not be affected. PASS
14. Reinstall Damus
15. Check relay list. Only intl relays should be shown. PASS
16. Change region to Japan (JP)
17. Restart Damus and check the relay list. Relay list should not be affected. PASS
18. Reinstall Damus
19. This time, login with a pre-existing account (One that is not connected to Japanese relays).
20. After onboarding, check relay list. The relay list should be unaffected (i.e. Japanese relays should not have been added since this account is pre-existing). PASS

Note: The actual network connection with some of the Japanese relays
failed, but that is likely due to the Geo-based IP restrictions imposed
by some of those Japanese relays. The relay list has been copied
verbatim from @mattn's suggestions.

Reference ticket: https://github.com/damus-io/damus/issues/1447

Changelog-Changed: Automatically load extra regional Japanese relays during account creation if user's region is set to Japan.
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-31 10:03:13 +09:00
ericholguin
c437a05ec0 ux: add long press to profile to navigate to profile page
Closes: https://github.com/damus-io/damus/pull/1665
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-30 11:59:13 +09:00
ericholguin
a2fdb61013 ui: change post view background to be all black
Closes: https://github.com/damus-io/damus/pull/1666
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-30 11:59:10 +09:00
ericholguin
4dd800e6b9 ui: make qrcode view font color white
Currently when in light mode the font is black which blends into the background
Changelog-Fixed: use white font color in qrcode view

Closes: https://github.com/damus-io/damus/pull/1653
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-30 11:59:07 +09:00
ericholguin
34c0728f21 ui: update the customize zap view
This PR updates the customize zap view by:

- replacing the old gradient button to the pink style
- show cursor on text field
- show textfield by default
- change custom zap grid to 4x2 instead of 3x3

Changelog-Changed: Updated customize zap view
Closes: https://github.com/damus-io/damus/pull/1656
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-30 11:58:36 +09:00
ericholguin
ec604664d8 ui: status view fixes for smaller screen devices
Changelog-Added: Tap to dismiss keyboard on user status view
Closes: https://github.com/damus-io/damus/pull/1652
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-27 09:21:43 +08:00
William Casarin
7710839261 noting: users are now notified when you quote repost them
Changelog-Changed: Users are now notified when you quote repost them
2023-10-27 09:02:05 +08:00
William Casarin
4389cc2128 load_profiles: add context for debugging
This is useful to see where the load_profiles request is coming from

We may need to switch to a central dispatch for profile loading, I
suspect there is a lot of redundancy between requests.
2023-10-24 13:02:41 +08:00
William Casarin
76508dbbfd perf: don't continuously attempt to fetch old profiles
Changelog-Changed: Save bandwidth by only fetching new profiles after a certain amount of time
2023-10-24 13:02:41 +08:00
Daniel D’Aquino
bbccc27a26 ui: Add setting that allows users to optionally disable profile action sheets.
Tested on iOS 17.0.1 on an iPhone 15 Pro simulator.

Closes: https://github.com/damus-io/damus/issues/1641
Changelog-Added: Add setting that allows users to optionally disable the new profile action sheet feature
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-24 12:18:20 +08:00
Daniel D’Aquino
9969e70b5f ui: Add follow button to profile action sheet
Testing: Tested on iPhone 15 Pro simulator with iOS 17.0.1

Closes: https://github.com/damus-io/damus/issues/1636
Changelog-Added: Add follow button to profile action sheet
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-24 12:18:20 +08:00
Daniel D’Aquino
692d29942b zaps: Implement single-tap zap on profile action sheet and fix zap fallthrough on default settings
This commit implements a single-tap zap on the profile action sheet and fixes an issue where zapping would silently fail on default settings if the user had no lightning wallet installed in their system.

Testing
-------

Configurations:
- iPhone 13 Mini (physical device) on iOS 17.0.2 with NWC wallet attached
- iPhone 15 Pro (simulator) on iOS 17.0.1 with no lightning wallet nor NWC

Damus: This commit

Coverage:
- Zapping using NWC connected wallet: PASS (Zaps and shows UX feedback of the completed action)
- Zapping under default settings and no lightning wallet: PASS (Shows the wallet selector invoice view)
- Long press on zap button brings custom zap view

Regression testing
------------------

Preconditions: iPhone 15 Pro (simulator) on iOS 17.0.1 with no lightning wallet nor NWC

Coverage:
- Zapping user on their full profile shows wallet selector. PASS
- On-post invoice shows wallet selector. PASS

Closes: https://github.com/damus-io/damus/issues/1634
Changelog-Changed: Zap button on profile action sheet now zaps with a single click, while a long press brings custom zap view
Changelog-Fixed: Fixed an issue where zapping would silently fail on default settings if the user does not have a lightning wallet preinstalled on their device.
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-24 12:18:20 +08:00
Daniel D’Aquino
139df33cb7 Rename ZapButton to NoteZapButton and ZapButtonView to ProfileZapLinkView (no-op)
This is a non-functional refactor to rename two views with similar names, to avoid confusion.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-24 12:18:20 +08:00
William Casarin
a324523b85 ndb: new methods for profile fetched_at
This adds a few methods to Ndb for reading and writing fetched_at stats.
These are a way of tracking when we last tried to fetch profiles so that
we don't need to keep fetching them.
2023-10-23 10:44:54 +08:00
William Casarin
1cf898e0b2 ndb: update nostrdb
This includes the new profile fetched_at logic and reaction stats.

When receiving new profiles, nostrdb will record when it was last
received in a new database. This database is a mapping from Pubkey to
timestamp.

You can manually read/write to this table using:

ndb_read_last_profile_fetch
ndb_write_last_profile_fetch

This patch also includes the new reaction counting metadata table. It is
not used yet (but reactions are still counted!)

Changelog-Added: Added reaction counters to nostrdb
Changelog-Added: Record when profile is last fetched in nostrdb
2023-10-23 10:40:11 +08:00
William Casarin
502ceee6d4 ndb: update bindings
This adds new bindings from nostrdb related to tracking reaction stats.
We aren't using this yet but it's a part of the latest nostrdb update.
2023-10-23 10:39:27 +08:00
William Casarin
4f628ec733 Merge remote-tracking branch 'github/translations' 2023-10-23 09:18:45 +08:00
William Casarin
29915159db v1.6 (24) changelog 2023-10-22 14:27:56 +08:00
William Casarin
2b102671e5 smol fix 2023-10-22 10:41:36 +08:00
Daniel D’Aquino
e70f270c5c zaps: Improve discoverability of profile zaps
via zappability badges and profile action sheets

This commit improves discoverability of zaps with the following changes:

1. New zap icon appears on profile pictures of events where the author of such event has zaps setup
2. Clicking on a profile picture from an event shows an action sheet that makes it easier to see a preview of their profile, and a zap button

Testing
-------

Devices:
- iPhone 14 Pro simulator
- iPad 10 simulator

iOS:
- 17.0.1
- 16.4

Damus: This commit

Coverage:
1. Checked that zap icon appears on profile pictures on events in different feeds and threads
2. Checked that this zap icon only appears for profiles that have zaps enabled
3. Checked that profile action sheet looks good on both light mode and dark mode
4. Checked that long descriptions are truncated and the "see more" "see less" buttons work
5. Checked that clicking "see more" or "see less" adapts the size of the action sheet (on iPhone)
6. Checked that action sheet looks good whether or not the user has a website link setup
7. Checked that long presses on the zap button in the action sheet bring the same options as the normal profile view
8. Checked all the buttons in the action sheet take the user to the expected place
9. Checked that the original profile view looks good (on both light and dark mode)

Notes:
- Action sheet cannot be resized on iPad.
- Could not test on Mac Catalyst because there seems to be a crash on the creation of a new account

Reference ticket: https://github.com/damus-io/damus/issues/1596

Changelog-Added: Improve discoverability of profile zaps with zappability badges and profile action sheets
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-22 10:40:31 +08:00
William Casarin
4ed79ff3c3 ui: reduce size of event menu hitbox
Changelog-Fixed: Reduce size of event menu hitbox
2023-10-22 10:40:29 +08:00
William Casarin
17331301da Clarified camera and mic usage strings
Fixes: https://github.com/damus-io/damus/issues/1628
2023-10-22 10:25:03 +08:00
Davide De Rosa
45904e1bf2 nav: compare searches for navigation decisions
In 7c98489, routes are compared to the stack top before push.
Problem is, search comparison is not looking at the NostrFilter.

Instead, hash value involves two UUID-based fields (sub_id,
profiles_subid), so equality will always fail and result in a
"duplicated push".

As I do not know the context of such fields to deliberately
drop them, this patch is sent as a draft.

The basic idea is using the filter for comparison, so I added
a Hashable extension to NostrFilter where the subject of the
comparison may be fine-tuned.

Adding `hashtag` resolves #1367 but it's only a starting point.

Signed-off-by: Davide De Rosa <keeshux@gmail.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-22 08:56:42 +08:00
Daniel D’Aquino
7ae66b8490 ui: Add suggested hashtags to universe view
This commit adds a suggested hashtag section to the universe view tab. The method for suggesting hashtags is currently simple:
1. It contains a list of many possible hashtags that we could recommend
2. It calculates how many users have been talking about it in the events fetched by the Universe tab
3. It selects the Top-N most mentioned suggested hashtags in the Universe tab

This has the following properties:
1. It has some spam resistance as it ranks by unique users mentioning the tag (instead of events)
2. It is a simple way to curate good hashtags
3. It shows the ones with the most amount of people talking about it among the notes fecthed in the Universe view

Testing
-------

PASS

Device: iPhone 14 Pro simulator
iOS: 17.0
Damus: This commit
Coverage:

1. Suggested hashtags are displayed
2. Layout looks similar to Figma
3. User count goes up (does not stay at zero)
4. Clicking on a suggested hashtag takes you to that hashtag view
5. Only the top 5 hashtags are displayed

Notes: The counts seem low, probably because there are not enough notes loaded in Universe View

Changelog-Added: Add suggested hashtags to universe view
Closes: https://github.com/damus-io/damus/issues/1569
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-21 08:42:00 +08:00
Daniel D’Aquino
bf43842590 onboarding: Suggest first post during onboarding
Testing of standard flow
------------------------

PASS

Device: iPhone 14 Pro simulator
iOS: 17.0
Damus: This commit
Steps:
1. Delete and reinstall Damus
2. Go through onboarding until suggested users appear
3. Click "continue". Should slide into the post view. PASS
4. Post view should look similar to the Figma design file, but with examples as placeholders. PASS
5. Examples should switch every 3 seconds. PASS
6. Typing a first character causes the #introductions hashtag to be automatically added. PASS
7. Uploading an image makes progress view show up and not break layout. PASS
8. Clicking on "post" should post this note and dismiss onboarding view. PASS

Testing of other flows
----------------------

PASS

Device: iPhone 14 Pro simulator
iOS: 17.0
Damus: This commit
Special remark: Made local change to always show the onboarding suggestions, and speed up testing
Coverage:

1. Clicking "skip" on suggested users view will skip into the post view. PASS
2. Clicking "cancel" on post view and then going to the normal post view reveals a blank draft. PASS
3. Clicking "cancel" dismisses onboarding view and does not post anything. PASS
4. Normal post view looks normal (not broken). PASS
5. Changing initial suggested post during onboarding, cancelling the post, and then re-entering normal post view reveals the draft with user modifications. PASS

Changelog-Added: Suggest first post during onboarding
Closes: https://github.com/damus-io/damus/issues/1338
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-21 08:42:00 +08:00
Davide De Rosa
7c98489904 nav: fix pushing duplicate routes
Skip push if matches top route.

Fixes: https://github.com/damus-io/damus/issues/104
Closes: https://github.com/damus-io/damus/pull/1625
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-20 12:41:53 +08:00
transifex-integration[bot]
0277303da7 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2023-10-19 19:16:26 +00:00
transifex-integration[bot]
63fee80c53 Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2023-10-19 19:16:15 +00:00
transifex-integration[bot]
2aaedd077e Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2023-10-19 19:16:01 +00:00
Daniel D’Aquino
06eb9d4a0e dm: Do not show DMs from muted users
This commits causes DMs from muted users to be filtered out. It also fixes an issue where the DM list would appear completely blank in certain scenarios.

Testing
-------

CONDITIONAL PASS

Device: iPhone 14 Pro simulator
iOS: 17.0
Damus: This commit
Setup:
- Three test accounts (A, B, and C). "A" will be the account running on the device under test.
- Account "A" should start with no DMs

1. Send a direct message from "B" to "A", and reply from "A".
2. Go to DMs -> DMs tab. Conversation with "B" should appear. PASS
3. Mute user "B" (I did it via profiles page).
4. Go back to DMs view via back button. DMs from "B" should not appear. PASS
5. Since there are no DMs, the screen should display "Nothing to see here". PASS
5. Close Damus app via iOS app switcher and reopen Damus
6. Check DMs list. Should only show "Nothing to see here". PASS
7. Send a DM from account "C" to "A" and reply.
8. Go back to DMs -> DMs tab. Only the message from account "C" should appear.
9. Unmute user "B"
10. Go back to DMs. Messages from "B" and "C" should appear. PASS

Notes:
- There was one instance when the first DM from account "C" appeared in the "DMs" tab (Not "requests") momentarily. After a bit it went into requests as expected.
- When unmuting user "B", I had to refresh the DM list by switching tabs, meaning that the view did not immediately update.

Upon inspection, the two behaviors above are not caused by this change, so this is a conditional pass.

Closes: https://github.com/damus-io/damus/issues/1350
Changelog-Fixed: Do not show DMs from muted users
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-18 07:04:17 +08:00
Daniel D’Aquino
3b76fcb743 test: Add basic snapshot test coverage for EventView
This commit adds a basic snapshot test for EventView, and also adds some testing infrastructure to help with mocking NostrDB behavior.

Test
----

PASS

Device: iOS 17.0 Simulator
iOS: 17.0
Damus: This commit
Steps: Run `EventViewTests`
Results: Snapshot matches baseline reference added
2023-10-16 03:13:28 +02:00
Daniel D’Aquino
edb23e4e70 ui: prefix username with @ character, fix spacing
Closes: https://github.com/damus-io/damus/issues/1559
Changelog-Fixed: Add more spacing between display name and username, and prefix username with `@` character
2023-10-16 03:13:28 +02:00
Daniel D’Aquino
82fba88cc4 storage: set disk cache expiry dates for images
This commit adds expiry dates for images added to the Kingfisher cache.
The expiry date depends on the context of the image:

- Images from notes expire after a week
- Images from profile banners expire after two weeks
- Profile pictures never expire.

Test
----

Device: iPhone 14 Pro (Simulator), iOS: 17.0
Special remarks: Requires minor local mods and debugger connection
Steps:

1. Locally change the note image expiry to 5 seconds
2. Set a breakpoint in `removeExpiredValues` function in `DiskStorage.swift` in Kingfisher
3. Disable breakpoints for now
4. Start Damus and go to the profile feed of someone new
5. Scroll down through the images for about a minute
6. Turn on breakpoints
7. Switch to a different app in the simulator (Make Damus go to background mode)
8. Wait for a few seconds. Debugger should hit the breakpoint set. PASS
9. Take note of the fileURLs of the images being deleted
10. Go to that directory where the fileURLs are in via Finder
11. Look at some of the images being deleted. Perhaps save a copy for comparison.
12. Turn off breakpoints, resume execution and go back to Damus
13. Scroll back up. Some images there should match the images being automatically deleted from the cache. PASS

Closes: https://github.com/damus-io/damus/issues/1565
Changelog-Added: Add expiry date for images in cache to be auto-deleted after a preset time to save space on storage
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-16 03:13:28 +02:00
Jericho Hasselbush
439f9974c5 login: add nsec qr-scanning
- Allow scanning of QR codes, and if detects a nsec, will provide it to
  the login prompt.

- If nsec is found, provides option to keep nsec in keychain; default is
  to not store

- User stays logged in until they logout, or app is force-quit if nsec
  is not stored.

damusApp.swift:
  Obtains keypair from the notification generated to allow login.

LoginView.swift:
  New views allowing for adding and logic handling the QR reader in
  QRScanNSECView.swift to enable QR scan for nsec.

QRScanNSECView.swift:
  New view to scan for QR code. The sparkling magnifying glass is enabled
  if the view calling the QR view changes the privKeyFound bound variable.

Tipjar: npub1el277q4kesp8vhs7rq6qkwnhpxfp345u7tnuxykwr67d9wg0wvyslam5n0
Closes: https://github.com/damus-io/damus/issues/1291
Changelog-Added: Add QR scan nsec logins.
Signed-off-by: Jericho Hasselbush <jericho@sal-et-lucem.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-16 03:12:53 +02:00
ericholguin
cf243e39c9 ui: improve status view
Changelog-Changed: Improved status view design
Closes: https://github.com/damus-io/damus/pull/1606
2023-10-16 02:51:07 +02:00
ericholguin
76f6ed0f86 colors: add an adapatable white color 2023-10-16 02:50:25 +02:00
transifex-integration[bot]
ef035b6300 Translate Localizable.stringsdict in lv_LV
100% translated source file: 'Localizable.stringsdict'
on 'lv_LV'.
2023-10-11 17:28:36 +00:00
transifex-integration[bot]
769f03943c Translate Localizable.strings in lv_LV
100% translated source file: 'Localizable.strings'
on 'lv_LV'.
2023-10-11 17:19:54 +00:00
transifex-integration[bot]
6cdf2dca53 Translate InfoPlist.strings in lv_LV
100% translated source file: 'InfoPlist.strings'
on 'lv_LV'.
2023-10-11 16:19:17 +00:00
ericholguin
05dee129b5 relays: allow users to hide the recommended relay view
Closes: https://github.com/damus-io/damus/pull/1587
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-10 22:07:57 -07:00
Daniel D’Aquino
7bed47c919 test: Setup Snapshot testing library and add a snapshot test (testTextWrapperViewWillWrapText)
This change adds `https://github.com/pointfreeco/swift-snapshot-testing` as a package dependency and links it to the `damusTests` target.
It also adds one snapshot test to demonstrate its usefulness, by adding coverage to one particular aspect that we have never been able to test before: Whether or not the post text editor will wrap the text once the text gets long.

Testing of the test
-------------------

PASS

iOS: 17.0
Device: Simulator
Damus: This commit
Test steps:

1. Run `testTextWrapperViewWillWrapText`. PASS
2. Change TextViewWrapper.swift and remove this line:
```
textView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
```
3. Rerun. It fails. PASS (This is expected)

Closes: https://github.com/damus-io/damus/issues/1562
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-10 22:05:45 -07:00
transifex-integration[bot]
7f5707294c Translate Localizable.stringsdict in pl_PL
100% translated source file: 'Localizable.stringsdict'
on 'pl_PL'.
2023-10-08 13:47:07 +00:00
William Casarin
7a6a6dffbc camera: actually add CameraPreview to project 2023-10-07 17:00:25 -07:00
Suhail Saqan
472f81b311 add CameraModel and CameraService for interacting with the camera 2023-10-07 16:52:38 -07:00
Daniel D’Aquino
7744787c51 storage: Improve clear cache functionality
This patch improves clear cache functionality by:
- Reducing kingfisher cache removal to one command (The two commands running async was leading to warning logs. One was a subset of the other)
- Removing all files under the cache folder where not currently used by other processes

Full Functionality test
-----------------------

PASS

Device: iPhone 13 mini (Physical device)
iOS: 17.0.3
Damus: This commit
Special remarks:
- I had to locally delete other unit tests to be able to build the test target
- Unit test run on an earlier version of the patch. Test coverage should still apply since this newer patch is a subset of the previous.

Setup: Run Damus with debugger connection to Xcode

Test steps:

1. Follow multiple active accounts (Skip if local Damus is already filled up with GBs of data)
2. Scroll down on the feed for a couple of minutes (or until you have seen at least a few images, a few videos, and link previews) (Skip if local Damus is filled up with GBs of data)
3. In Xcode, download a storage container (Window > Devices and Simulators > Select the device > Select Damus > click on (...) > Download container)
    - Note: Even though you see the file, it does not download instantly. Monitor the file size until it roughly reaches the size reported in iOS storage settings, as the download may still be in progress. This may take a few minutes in some cases.
    - Also take note of storage usage in iOS settings
4. Open the app data package using terminal
5. Run `du -h . | sort -hr`
6. Clear cache and check logs. Logs should indicate the caches being cleared, and there should be no storage-related warning/error logs. PASS
7. Download a new storage container. Remember to wait until it completes download.
8. Run `du -h . | sort -hr` on it.
9. Compare. There should be much less data. Also check iOS settings storage usage. PASS
10. Go back to the home feed and start scrolling, browsing, follow some other people, etc. Look at your own profile as well. Everything should appear to be working as expected with no crashes or important data loss
11. Check bookmarks are still present. PASS
12. Run `DamusCacheManagerTests`. Should pass. PASS* (*See special remarks)

Results:
- Storage usage goes from 3.9GB to 394.7MB
- Damus works as normal after clearing cache, and after restarting the app as well. It becomes slower for a moment, but after a bit it loads as normal again.
- No warning or error logs pertaining to clearing cache
- Unit test passes

My storage container disk usage stats after clearing cache:
```
% du -h | sort -hr
359M	./AppData
359M	.
336M	./AppData/Documents
 23M	./AppData/Library
 20M	./AppData/Library/Caches
7.9M	./AppData/Library/Caches/com.jb55.damus2
2.4M	./AppData/Library/SplashBoard/Snapshots
2.4M	./AppData/Library/SplashBoard
1.8M	./AppData/Library/SplashBoard/Snapshots/com.jb55.damus2 - {DEFAULT GROUP}
1.6M	./AppData/Library/Caches/com.jb55.damus2/fsCachedData
636K	./AppData/Library/SplashBoard/Snapshots/sceneID:com.jb55.damus2-ecc156b1-eb9c-4439-b219-e1eebf2b4c36
596K	./AppData/Library/Caches/com.apple.WebKit.GPU/com.apple.metal
596K	./AppData/Library/Caches/com.apple.WebKit.GPU
452K	./AppData/Library/Caches/com.jb55.damus2/com.apple.metal
296K	./AppData/Library/SplashBoard/Snapshots/sceneID:com.jb55.damus2-ecc156b1-eb9c-4439-b219-e1eebf2b4c36/downscaled
224K	./AppData/Library/HTTPStorages/com.jb55.damus2
224K	./AppData/Library/HTTPStorages
164K	./AppData/Library/Caches/com.onevcat.Kingfisher.ImageCache.default
156K	./AppData/Library/Caches/RelayLogs
112K	./AppData/Library/Caches/com.apple.dyld
 92K	./AppData/Library/Preferences
 60K	./AppData/Library/Caches/com.jb55.damus2/com.apple.metal/archiveUsage.db
 12K	./AppData/Library/Saved Application State/com.jb55.damus2.savedState
 12K	./AppData/Library/Saved Application State
8.0K	./AppData/StoreKit
8.0K	./AppData/Library/Saved Application State/com.jb55.damus2.savedState/ecc156b1-eb9c-4439-b219-e1eebf2b4c36
4.0K	./AppData/Library/Saved Application State/com.jb55.damus2.savedState/KnownSceneSessions
4.0K	./AppData/Library/LanguageModeling/en-dynamic.lm
4.0K	./AppData/Library/LanguageModeling
4.0K	./AppData/Library/Cookies
  0B	./AppData/SystemData/com.apple.SafariViewService/Library/WebKit/WebsiteData
  0B	./AppData/SystemData/com.apple.SafariViewService/Library/WebKit
  0B	./AppData/SystemData/com.apple.SafariViewService/Library
  0B	./AppData/SystemData/com.apple.SafariViewService
```

Biggest storage used remaining is in the Documents folder where NostrDB is stored. However, we do not want to clear NostrDB, so this is expected behavior.

Changelog-Changed: Improve clear cache functionality
Closes: https://github.com/damus-io/damus/issues/1472
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-07 16:42:08 -07:00
ericholguin
5d90b497f0 images: add scan for qr code to image context menu
Closes: https://github.com/damus-io/damus/pull/1566
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-07 15:27:52 -07:00
Daniel D’Aquino
a06be64894 network: Broadcast quoted notes when posting a note with quotes
This change addresses an issue where notes with quotes sometimes are not loaded correctly because the quoted note was not available in the same relay. Now whenever a user posts a note with a quoted note, the quoted note is also broadcast to the user's selected relays.

Issue repro
-----------

ISSUE REPRODUCED

Device: iPhone 14 Pro Simulator
iOS: 17.0
Damus: `1fabd4c0fe98d1f47b1fa0f76984ad78095bd49c`
Setup:
- Make sure you have a debugger connected
- Have a test note that you can quote

Steps:

1. Start Damus and let logs settle
2. Observe where the last log is
3. Quote the test note
4. Copy newly generated logs and paste on a text editor.
5. Analyze those logs. Pay attention to the new note id, as well as the note id of the quoted event (`["q", <QUOTED_NOTE_ID>]`)

Results: Logs show that the newly posted event is being flushed to the relays, but not the note that is being quoted.

Testing of the fix
------------------

PASS

Device: iPhone 14 Pro Simulator
iOS: 17.0
Damus: This commit
Setup:
- Make sure you have a debugger connected
- Have a test note that you can quote

Steps:

1. Start Damus and let logs settle
2. Observe where the last log is
3. Quote the test note
4. Copy newly generated logs and paste on a text editor.
5. Analyze those logs. Pay attention to the new note id, as well as the note id of the quoted event (`["q", <QUOTED_NOTE_ID>]`)

Results:
- Logs show the new event being flushed to the relays. PASS
- Logs show the quoted event also being flushed to the relays. PASS

Closes: https://github.com/damus-io/damus/issues/1495
Changelog-Fixed: Broadcast quoted notes when posting a note with quotes
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-07 14:49:53 -07:00
Daniel D’Aquino
0f9e87cb37 test: temporarily disable UserCacheManagerTests
Resolves build errors on the test target while we work on #1586

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-07 14:35:24 -07:00
William Casarin
1fabd4c0fe v1.6 (23) changelog 2023-10-06 12:57:54 -07:00
William Casarin
f90a485b5e v1.6 (23) final 2023-10-06 12:56:31 -07:00
Daniel D’Aquino
a18304f4a3 ui: Add merch store button to sidebar menu
Features:
- Merch button on sidebar menu
- Damus icon at the top opens sidebar
- Merch link passes `ref` param, to help with website analytics

Testing
-------

1. Ensured that link appears correctly with image on both iOS versions
2. Ensured that link takes user to the store
3. Ensured that ref param is passed to the store
4. Ensured that Damus icon opens sidebar menu
5. Ensured that when sidebar is open, clicking where the damus icon would be does not close the sidebar menu (it is behind the sidebar menu)

Closes: https://github.com/damus-io/damus/issues/845
Changelog-Added: Added merch store button to sidebar menu
Changelog-Changed: Damus icon now opens sidebar
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-06 12:54:51 -07:00
Daniel D’Aquino
5e3afd0b16 ui: keep location in timeline when returning from a thread
Stop tab buttons from causing the root view to scroll to the top unless
user is coming from another tab or already at the root view

This fixes an issue where if you navigated within a tab and then clicked
the tab button, it would scroll to the top. Users want to be able to
navigate back to the root of a given tab without losing the scroll
position.

Now tab buttons only scroll to the top if:

- User is coming from a different tab
- User is already at the root view of the tab, and they click on the tab button again.

Issue repro
----------

1. Scroll down the home feed a bit
2. Click on one of the posts
3. Click on the home tab button at the bottom left.

**Desired behavior:**
1. First click on home button should go to home view but not scroll to top
2. Clicking on home button should only scroll to top when user is already at the root home feed view

**Current behavior:** Clicking on home button scrolls to top on step 3 (shouldn't have)

Fix testing
-----------

Steps:

1. Scroll down the home feed a bit
2. Click on one of the posts.
3. Click on the home tab button. Should go back to home view but keep scroll position. PASS
4. Click on the home tab button again. Should scroll to the top. PASS
5. Scroll down on the home tab.
6. Switch to another tab, then switch back to the home tab. Should scroll to the top of the home view. PASS
7. Scroll down on the home tab
8. Click on the home tab button. Should scroll to the top. PASS
9. Repeat steps 1–8 for DMs, Universe view, and notifications. PASS

Closes: https://github.com/damus-io/damus/issues/1580
Changelog-Fixed: Stop tab buttons from causing the root view to scroll to the top unless user is coming from another tab or already at the root view
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-06 12:50:45 -07:00
William Casarin
b1c7ef9bd9 Fix profiles not updating
Timestamped IDs were not being initialized properly when writing profile
indices. This means that every profile was indexed with timestamp 0.
derp. Fix this!

Changelog-Fixed: Fix profiles not updating
2023-10-06 10:42:17 -07:00
William Casarin
7ecb9aad62 nostrdb: only process sent note events, not subs 2023-10-06 10:42:17 -07:00
William Casarin
d0daa9fafa nostrdb: add last fetched records for profiles 2023-10-06 10:42:17 -07:00
William Casarin
76f3cd4edc 21 2023-10-06 10:42:17 -07:00
transifex-integration[bot]
04917cfbe4 Translate Localizable.strings in pt_PT
100% translated source file: 'Localizable.strings'
on 'pt_PT'.
2023-10-05 23:18:35 +00:00
transifex-integration[bot]
641b255a71 Translate InfoPlist.strings in pt_PT
100% translated source file: 'InfoPlist.strings'
on 'pt_PT'.
2023-10-05 21:35:08 +00:00
transifex-integration[bot]
9f2eafc3cb Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-10-05 20:26:25 +00:00
transifex-integration[bot]
e62ee11b06 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-10-05 20:23:46 +00:00
Daniel D’Aquino
bd94b76d1e ui: remove unnecessary url string manipulations
This is a follow up commit to `768ab3e9e4f55b872253d55c53983c19ab4c3d8b` in issue #1531

Testing
-------

**Device:** iPhone 14 Pro simulator
**iOS:** 17.0
**Damus:** This commit

**Steps:**
1. Remove all relays.
2. Add the Damus relay.
3. Add `wss://relay.snort.social/` relay **(with trailing slash)**. Shows up on the relay list. (PASS)
4. Add `wss://relay.snort.social/v1` and `wss://relay.snort.social/v2` to the list. Both show up as separate relays (PASS)
4. Watch logs and wait for the relay list event to be sent out
5. Restart Damus (to help ensure the repro is stable)
6. Try removing the Snort relay by swiping. Relay is removed successfully (PASS)
7. Try removing the "v1" relay by clicking on "Disconnect relay" in the detail page. "v1" relay (and NOT "v2") is removed (PASS)
8. Try adding `nos.lol` from the recommended list. Added successfully. (PASS)
9. Remove `nos.lol` with a long press. (PASS)

Changelog-Fixed: Fix issue where relays with trailing slashes cannot be removed (#1531)
Closes: https://github.com/damus-io/damus/issues/1531
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-04 15:28:10 -07:00
William Casarin
5fa138d050 v1.6 (20) changelog 2023-10-04 14:55:47 -07:00
William Casarin
deb75df54e v1.6 (20) 2023-10-04 14:54:48 -07:00
transifex-integration[bot]
3365c72832 Translate Localizable.strings in es_419
100% translated source file: 'Localizable.strings'
on 'es_419'.
2023-10-04 16:54:02 +00:00
transifex-integration[bot]
ca2960cc73 Translate Localizable.stringsdict in es_419
100% translated source file: 'Localizable.stringsdict'
on 'es_419'.
2023-10-04 16:52:27 +00:00
transifex-integration[bot]
ce5855fe3d Translate InfoPlist.strings in es_419
100% translated source file: 'InfoPlist.strings'
on 'es_419'.
2023-10-04 16:52:02 +00:00
transifex-integration[bot]
f56b35972d Translate Localizable.strings in es_419
100% translated source file: 'Localizable.strings'
on 'es_419'.
2023-10-04 16:51:33 +00:00
Daniel D’Aquino
24c2be02bb ui: Improve UX around clearing cache
Testing
-------

PASS

Device: iPhone 14 Pro simulator
iOS: Tested on iOS 17.0 and 16.4
Steps:

1. Go to appearance settings
2. Enable animations. Shows confirmation dialog. PASS
3. Click cancel. Setting is toggled back. PASS
4. Enable animations again. This time click "OK". Setting stays at what was set, and cache is visibly cleared. PASS
5. Restart app. Changes are persistent. PASS
6. Disable animations. Dialog appears like before. PASS
7. Cancel. Toggles back as expected. PASS
8. Disable animations again. This time click "OK". Cache is cleared. PASS
7. Restart app. Changes are persistent. PASS
9. Click on "clear cache". Confirmation dialog appears. PASS
10. Cancel action. We do not see cache being cleared. PASS
11. Click on "clear cache" and click "OK" this time.
12. We can see the cache being visibly cleared. It shows a loading spinner and "clearing cache", and then we see a checkmark icon with a "cache cleared" indicator. We cannot click the button again for now. PASS
13. Go to home view, scroll through some views, then come back to the setting. Clear cache button is visible again.

Closes: https://github.com/damus-io/damus/issues/1301
Changelog-Changed: Improve UX around clearing cache
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-03 19:17:22 -07:00
transifex-integration[bot]
5395c45df2 Translate InfoPlist.strings in sw
100% translated source file: 'InfoPlist.strings'
on 'sw'.
2023-10-03 13:51:03 +00:00
Daniel D’Aquino
1150a144bc composer: Make text editor more robust
This change makes the text editor/composer more robust and simple and solves Github issue #1558

It builds on the changes made for #1211, and on Jericho's (Jericho Hasselbush <jericho@sal-et-lucem.com>) discovery during his work on #1544

It uses setContentCompressionResistance, disabled text box scrolling, and dynamic height adjustments (based on more accurate layout calculations) to allow several improvements:
- It ensures lines get wrapped and not overflown
- It uses system native "scroll cursor into view" when typing, eliminating the need to a ghost caret
- It ensures we do not have a scroll view within a scroll view (which is confusing)
- It ensures that we set the height of the text box to its ideal value using a native layout calculation (Removes some issues with copying and pasting larger text)
- It resolves other small issues, such as #1558

Issue #1558 repro
-----------------

Result: VERIFIED

Device: iPhone 14 Pro Simulator
iOS: 17.0
Damus: `476f52562a70c2615ad084640dd1a0ba5c4c12e3`

Issue #1558 steps:

1. Type "hello world, hello @da"
2. Select "Damus" in contact list
3. Try moving cursor to the end of "world". Cursor should have gone there, but it immediately goes back to the end of "@damus " instead.

Testing for #1558
-----------------

Result: PASS

Device: iPhone 14 Pro Simulator
iOS: 17.0
Damus: This commit
Steps:

1. Type "hello world, hello @da"
2. Select "Damus" in contact list
3. Try moving cursor to the end of "world". Cursor goes there.

General functionality testing
-----------------------------

Result: CONDITIONAL PASS.
Summary: Behaviour is improved from #1211 patch, and #1558 is fixed. There are a few remaining issues, but they do not look like regressions from these changes. More details below.

Device: iPhone 14 Pro Simulator
iOS: 17.0
Damus: This commit
Coverage:

1. Basic typing works. PASS
2. Basic user tagging works. PASS
3. Typing long text line wraps the line. PASS
4. Adding newlines to the end of the text works and text is visible (i.e. Text box is expanding with text). PASS
5. Adding lots of newlines causes the text box and inner PostView content to expand, and those contents can be scrolled. PASS
6. Typing text when cursor is out of view (both up and down) causes PostView to scroll the cursor into view. PASS
7. Tagging user on a line positioned at the middle of the screen causes view to scroll cursor into view. PASS
8. Tagging user on a very long line positioned causes view to scroll cursor into view. PASS
9. Pasting very long text (5 paragraphs of Lorem Ipsum) expands the text box as necessary, wraps all long lines, scrolls cursor at the end into view. PASS
10. Scrolling through very long text shows that there is only one scroll view active (PostView's). PASS
11. Typing text that expands text box does not cause jitters. PASS
12. Typing mentions do not cause jitter. PASS
13. Adding newline from the end of a mid paragraph unfortunately still causes cursor to jump to the end of the text. This is an existing bug (https://github.com/damus-io/damus/issues/1521). EXISTING ISSUE.
14. Tagging a user at the end of a line when there are other lines below it may cause the cursor to jump a few characters forward. It is unclear whether this is a regression because prior to this change the cursor would get stuck at the end of the mention. But since this is a very specific edge case that might not be a regression, it might be a good idea to address this on a separate ticket. CONDITIONAL PASS
15. Could not run PostView unit tests due to various build errors on the test target.

Closes: https://github.com/damus-io/damus/issues/1558
Changelog-Fixed: Fix situations where the note composer cursor gets stuck in one place after tagging a user
Changelog-Fixed: Fix some note composer issues, such as when copying/pasting larger text, and make the post composer more robust.
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 13:30:08 -07:00
Daniel D’Aquino
89acde1b90 filters: Add filter to hashtag search timeline view (#1412)
Applied the content filters to the hashtag search timeline view, to filter out #nsfw-tagged posts on that view if the user has that setting enabled.

Testing of the fix
------------------

**PASS**

**iOS:** 17.0 (iPhone 14 Pro simulator)
**Damus:** This commit
**Test steps:**
1. Search for #sauna hashtag
2. Pick one post from results that contains multiple hashtags
3. Locally change nsfw filter in the code to another hashtag (I picked #homestead in this example) (This is to make testing easier)
4. Run app on simulator
5. Disable nsfw filtering
6. Search for the #sauna hashtag
7. Ensure that the post from step 2 is there
8. Turn on nsfw filtering
9. Search for the #sauna hashtag again. Ensure that post from step 2 is no longer visible
10. Switch keyword back to #nsfw in the code. Re-run app
11. Search for the #nsfw hashtag. No posts appear (timeline view is empty). (Not sure if this is the desired behavior, but seems reasonable)
12. Turn off nsfw filtering
13. Search for the #nsfw hashtag again. #nsfw posts should appear.

Closes: https://github.com/damus-io/damus/issues/1412
Changelog-Fixed: Apply filters to hashtag search timeline view
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
transifex-integration[bot]
ed98fd06e6 Update translations
- Translate Localizable.strings in pl_PL
- Translate Localizable.strings in sv_SE
- Translate Localizable.strings in nl
- Translate Localizable.strings in ja
- Translate Localizable.strings in hu_HU
- Translate Localizable.strings in es_ES
- Translate Localizable.strings in el_GR
- Translate Localizable.strings in de
- Translate Localizable.stringsdict in sv_SE
- Translate Localizable.stringsdict in nl
- Translate Localizable.stringsdict in ja
- Translate Localizable.stringsdict in hu_HU
- Translate Localizable.stringsdict in es_ES
- Translate Localizable.stringsdict in el_GR
- Translate Localizable.stringsdict in de
- Translate InfoPlist.strings in sv_SE
- Translate InfoPlist.strings in pl_PL
- Translate InfoPlist.strings in nl
- Translate InfoPlist.strings in ja
- Translate InfoPlist.strings in hu_HU
- Translate InfoPlist.strings in es_ES
- Translate InfoPlist.strings in el_GR
- Translate InfoPlist.strings in de
2023-10-02 12:34:08 -07:00
Fishcake
35c581066a fix video size detection, and audio track detection to work with HLS, add live stream indicator
Closes: https://github.com/damus-io/damus/pull/1560
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
Fishcake
d6c72403a3 include m3u8 files for video playback
Closes: https://github.com/damus-io/damus/pull/1560
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
Daniel D’Aquino
768ab3e9e4 ui: Fix issue where relays with trailing slashes cannot be removed (#1531)
Summary
-------

This fixes the issue at Github #1531 where relays with trailing slashes cannot be removed.

The root cause (Identified by @fishcakeday) was that for a relay to be removed, a certain dictionary entry containing the relay url needed to be removed prior to sending the updated relay list. However those dictionary keys used `String` objects, which cannot tell that two URLs are the same with or without a trailing slash.

To fix the issue, I have used a dictionary with the type `[RelayURL: RelayInfo]`, and made the necessary protocol conformance implementations for RelayURL. This way, URLs are handled with higher accuracy (e.g. Trailing slashes do not matter, URLs that resolve to the same location will match no matter what).

This allows us to leverage the existing parsing and handling logic that comes with the `URL` type, instead of manually handling URL strings.

Generally speaking it is preferrable to work with higher level `URL` or `RelayURL` objects than handle URLs via `String`. There is an opportunity to refactor more code, but I intentionally kept the changes to `RelayURL` limited to the functionality in this issue, because otherwise the changeset becomes very big and risky.

Issue reproduction
------------------

**Device:** iPhone 14 Pro simulator
**iOS:** 17.0
**Damus:** Local build from `476f52562` with the following local change:
``` diff

Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
Daniel D’Aquino
66d731ad0a ui: Filter out reposts where the inner event is from a person whom the user has muted. (#1216)
Issue reproduction
------------------

**Device:** iPhone 14 Pro simulator
**iOS:** 17.0
**Damus:** `bb2eb904cc`
**Steps:**

1. Repost a note from another account (Account "B")
2. Mute user "B"
3. Check home page and your own profile page. Repost shows up with a muted box.

Fix

Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
Daniel D’Aquino
0f86a41c4a ui: Hide quoted or reposted notes from people whom the user has muted. (#1216)
Summary
-------

This patch fixes the issue where the user might see notes from users that they have muted, if such note has been reposted or quoted.

Furthermore, this patch introduces some improvements on some of the associated views, making them more reusable.

Testing of the fix
------------------

**PASS**

**Device:** iPhone 14 Pro simulator
**iOS:** 17.0
**Damus:** This commit
**Test steps:**

1. Create two test accounts (if not created already). We will use test account "A". Test account "B" is an external test account
2. Make some notes from test account "B" (if non existent)
3. Switch to account "A"
4. Under test account "A", follow account "B"
5. Repost a note from account "B", and quote another note from account "B"
6. Access "account B"'s timeline. Repost and quoted note should all be visible. Layout should look as usual
7. Click on the reposted note. Should appear and it should look normal
8. Click on the note with the quote. Should appear and it should look normal
9. Click on the quoted note. Should appear and it should look normal
10. Now mute account "B"
12. Go back to account "A"'s timeline
13. Repost should appear, but the reposted content should be hidden behind a mute box. Clicking on show/hide should show or hide muted content
14. Note with quoted content should appear, but the quoted content should be hidden behind a mute box. Clicking on show/hide should work as expected
15. Make sure that the layout in steps 13 and 14 look good.
16. Click on the repost to access the thread view. Should be muted as expected.
17. Add a comment to the repost. Comment should appear even if the mute box hides the main note
18. Click on the note with quote to open its thread view. Comments should appear, main note should appear, but quoted content should be behind the mute box
19. Under account "B", add a comment to the quoted notes
20. Under account "A", check in the thread view that "B"'s reply is behind a mute box
21. Reply to the note with the quote. Check that the note appears correctly and that quoted content is behind the mute box (in the post composer view)
22. Find on Nostr a post where one of the replies contains a quoted note. Mute the user of the quoted content, and check that quoted content is now in a mute box

Smoke sanity test
-----------------

**PASS**

**Device:** iPhone 14 pro simulator
**iOS:** 16.4
**Test steps:** Browse a timeline filled with real notes and comments. Go through different notes and threads, mute some users, just to make sure nothing else appears obsviously broken.

Other notes
-----------

I removed this code:

```
.frame(maxWidth: .infinity, minHeight: PFP_SIZE)
```

from `EventShell`, because it was causing the layout to break on "threaded" style event view with muted quoted content (e.g. in a reply with quoted content).

The line of code dates back to `495859e07f`, but I am not sure why this line existed in the first place, or if removing it has any negative impact.

Closes: https://github.com/damus-io/damus/issues/1216
Changelog-Fixed: Hide quoted or reposted notes from people whom the user has muted. (#1216)
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
Mazin
957ac1dc03 Add translate.nostr.wine to available translation services
Closes: https://github.com/damus-io/damus/pull/1113
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
a58ca2918a Remove nonfunctional LibreTranslate servers
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
Daniel D’Aquino
b86bac2e42 ui: Show muted thread replies at the bottom of the thread view (#1522)
Testing
-------

**PASS**

**Device:** iPhone 14 Pro simulator
**iOS:** 17.0
**Damus:** This commit
**Steps:**

1. Setup accounts "A" and "B" that you control. Account "A" will be on our device under test.
2. Post something
3. Make a reply using Account A (Reply 1)
4. Make a reply using Account B (Reply 2)
5. Make another reply using account A (Reply 3)
6. Order of replies should be (top to bottom): 1, 2, 3
7. Mute user B
8. Order of replies should be: 1, 3, 2

Performance check
-----------------

**Device:** iPhone 14 Pro simulator
**iOS:** 17.0
**Damus:** This commit
**Steps:**

1. Locally change the code and add a print statement right before the sorting begins. In that print statement, include the number of events that will be sorted
2. Run Damus and go to a busy thread (I found one with 45 replies)
3. Go to the thread, and monitor the logs.
4. Navigate a bit between replies and monitor logs.

**Results:** I only saw a few print statements being printed with each navigation action, which indicates that we are not constantly re-sorting this object (which would be inefficient). Therefore, it seems like performance/efficiency would not be a problem.

Changelog-Changed: Show muted thread replies at the bottom of the thread view (#1522)
Closes: https://github.com/damus-io/damus/issues/1522
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-10-02 12:34:08 -07:00
Suhail Saqan
8a2e87718b camera: add CameraPreview for displaying the view the camera is reading 2023-10-02 12:34:08 -07:00
Suhail Saqan
88b3c6fe8d camera: add PhotoCaptureProcessor and VideoCaptureProcessor 2023-10-02 12:34:08 -07:00
transifex-integration[bot]
94d448e8d4 Translate InfoPlist.strings in zh_TW
100% translated source file: 'InfoPlist.strings'
on 'zh_TW'.
2023-10-02 18:06:45 +00:00
transifex-integration[bot]
dda94cc1c1 Translate Localizable.strings in zh_TW
100% translated source file: 'Localizable.strings'
on 'zh_TW'.
2023-10-02 18:06:25 +00:00
transifex-integration[bot]
7f3cc8b7a1 Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2023-10-02 18:02:15 +00:00
transifex-integration[bot]
077d1aa1fd Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2023-10-02 18:00:07 +00:00
transifex-integration[bot]
7297db946d Translate Localizable.strings in zh_CN
100% translated source file: 'Localizable.strings'
on 'zh_CN'.
2023-10-02 17:59:57 +00:00
transifex-integration[bot]
cc59e149d5 Translate InfoPlist.strings in zh_HK
100% translated source file: 'InfoPlist.strings'
on 'zh_HK'.
2023-10-02 17:46:53 +00:00
transifex-integration[bot]
aca7dde889 Translate InfoPlist.strings in zh_CN
100% translated source file: 'InfoPlist.strings'
on 'zh_CN'.
2023-10-02 17:46:19 +00:00
transifex-integration[bot]
b2584476ac Translate Localizable.strings in es_ES
100% translated source file: 'Localizable.strings'
on 'es_ES'.
2023-09-30 00:34:41 +00:00
transifex-integration[bot]
88fc8e41f7 Translate InfoPlist.strings in es_ES
100% translated source file: 'InfoPlist.strings'
on 'es_ES'.
2023-09-30 00:27:25 +00:00
transifex-integration[bot]
a955b7beb8 Translate Localizable.stringsdict in es_ES
100% translated source file: 'Localizable.stringsdict'
on 'es_ES'.
2023-09-30 00:05:03 +00:00
transifex-integration[bot]
36c0307ebd Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2023-09-29 09:32:25 +00:00
transifex-integration[bot]
c0377d630b Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2023-09-29 09:32:15 +00:00
transifex-integration[bot]
7390808630 Translate Localizable.strings in pl_PL
100% translated source file: 'Localizable.strings'
on 'pl_PL'.
2023-09-29 09:32:07 +00:00
transifex-integration[bot]
7444656043 Translate Localizable.strings in el_GR
100% translated source file: 'Localizable.strings'
on 'el_GR'.
2023-09-29 09:16:08 +00:00
transifex-integration[bot]
481280f006 Translate InfoPlist.strings in el_GR
100% translated source file: 'InfoPlist.strings'
on 'el_GR'.
2023-09-29 08:55:24 +00:00
transifex-integration[bot]
aaf587c3a9 Translate InfoPlist.strings in pl_PL
100% translated source file: 'InfoPlist.strings'
on 'pl_PL'.
2023-09-29 08:55:05 +00:00
transifex-integration[bot]
641049f6b4 Translate Localizable.stringsdict in el_GR
100% translated source file: 'Localizable.stringsdict'
on 'el_GR'.
2023-09-29 08:50:47 +00:00
transifex-integration[bot]
433d186f67 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2023-09-28 08:55:56 +00:00
transifex-integration[bot]
d157d72ca1 Translate Localizable.stringsdict in sv_SE
100% translated source file: 'Localizable.stringsdict'
on 'sv_SE'.
2023-09-27 06:03:31 +00:00
transifex-integration[bot]
3a459c83df Translate Localizable.strings in sv_SE
100% translated source file: 'Localizable.strings'
on 'sv_SE'.
2023-09-27 06:03:00 +00:00
transifex-integration[bot]
945604afce Translate InfoPlist.strings in sv_SE
100% translated source file: 'InfoPlist.strings'
on 'sv_SE'.
2023-09-27 05:50:30 +00:00
transifex-integration[bot]
3945f20ae4 Translate Localizable.strings in hu_HU
100% translated source file: 'Localizable.strings'
on 'hu_HU'.
2023-09-26 12:07:48 +00:00
transifex-integration[bot]
f3449ecaed Translate InfoPlist.strings in hu_HU
100% translated source file: 'InfoPlist.strings'
on 'hu_HU'.
2023-09-26 11:58:14 +00:00
transifex-integration[bot]
19857c12b7 Translate Localizable.stringsdict in hu_HU
100% translated source file: 'Localizable.stringsdict'
on 'hu_HU'.
2023-09-26 11:56:49 +00:00
transifex-integration[bot]
61612121f4 Translate InfoPlist.strings in nl
100% translated source file: 'InfoPlist.strings'
on 'nl'.
2023-09-25 15:37:45 +00:00
transifex-integration[bot]
9dac31d713 Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2023-09-25 15:37:24 +00:00
transifex-integration[bot]
9540016eee Translate Localizable.stringsdict in de
100% translated source file: 'Localizable.stringsdict'
on 'de'.
2023-09-25 09:37:28 +00:00
transifex-integration[bot]
22fe9f3dfd Translate InfoPlist.strings in de
100% translated source file: 'InfoPlist.strings'
on 'de'.
2023-09-25 09:36:14 +00:00
transifex-integration[bot]
c469e07ff7 Translate Localizable.strings in de
100% translated source file: 'Localizable.strings'
on 'de'.
2023-09-25 09:35:22 +00:00
transifex-integration[bot]
201e4420d1 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2023-09-25 03:20:17 +00:00
transifex-integration[bot]
e7a948d362 Translate InfoPlist.strings in ja
100% translated source file: 'InfoPlist.strings'
on 'ja'.
2023-09-25 03:08:33 +00:00
transifex-integration[bot]
375d454b16 Translate Localizable.stringsdict in ja
100% translated source file: 'Localizable.stringsdict'
on 'ja'.
2023-09-25 03:06:37 +00:00
William Casarin
476f52562a nostrdb: fix profiles not updating
Send relay pool events to nostrdb as well

Whenever we send events to relays, make sure we send them to nostrdb
at the same time.

Changelog-Fixed: Fix profile not updating
2023-09-24 17:07:09 -07:00
William Casarin
f591ad2dff ndb: add process_client_event helper
This is a quick helper for the new client event processing functionality
2023-09-24 17:06:35 -07:00
William Casarin
dacade299d ndb: bump nostrdb to support client->relay note processing 2023-09-24 17:06:04 -07:00
Suhail Saqan
cdacbcfdca util: add ImageResizer to change size of images 2023-09-24 11:58:16 -07:00
Daniel D’Aquino
41e036cff2 Remove toolbar background from profile view for better looks
Device: iPhone 13 mini (Physical device)
iOS: iOS 17.0.1
Remarks: Some entitlements removed locally to be able to build to device without access to development certificate

Steps
-----

1. Go to the home timeline view.
2. Click on a profile on any post
3. Swipe back to the home timeline view (Do not press "back" button)
4. Click on that same profile again
5. Scroll down the profile
6. Make sure that toolbar looks good (Does not have a white background)

Results: Swiping back from profile does not cause any issues. View layout of the custom navbar looks good

Changelog-Fixed: Fix small graphical toolbar bug when scrolling profiles
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-24 11:55:31 -07:00
eb901a4d84 Fix localization issues and export strings for translation
Changelog-Fixed: Fix localization issues and export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-24 11:33:51 -07:00
William Casarin
9f15688699 v1.6 (19) 2023-09-24 11:33:40 -07:00
Daniel D’Aquino
6d055be3cd Fix UI freeze after swiping back from profile (#1449)
On iOS 17.0, swiping back from a view that uses
`.navigationBarHidden(true)` caused the `NavigationStack` view to
freeze. This fixes the issue by creating a custom toolbar using
`.toolbar` instead.

Issue reproduction steps
------------------------

I found a very good clue to reproduce this issue from
[https://damus.io/note162rt4fctxepnj9cdtr9a82k7jtw3e33hj742ejly3q84tkwsfars4k9glr](https://damus.io/note162rt4fctxepnj9cdtr9a82k7jtw3e33hj742ejly3q84tkwsfars4k9glr)

**Device:** iPhone 13 mini (Physical device)
**iOS:** 17.0.1
**Damus:** 1.6 (18) 4377cf28ef
**Steps:**
1. Go to the home timeline view.
2. Click on a profile on any post
3. Swipe back to the home timeline view (Do not press "back" button)
4. Click on that same profile again

**Ideal behaviour:** On step 4, you should be taken to the profile view
**Actual behaviour:** The whole timeline view, top bar, etc seems to "freeze" and no longer respond.

Root causing investigation
--------------------------

I attempted various things until I could narrow it down. Here is a
summary of what I discovered:
1. First I attempted to investigate where the deadlock would live, by
   analyzing the thread states in the debugger. However:
    1. I did not find much differences between the thread states of a
       normal app running and the app running after the issue
    2. **I noticed that the tab bar at the bottom was still working, so
       unless those views are running on different threads, it might not
       have been a deadlock**
    3. NostrDB ingested and writer threads seemed to be waiting on a
       mutex most of the time I paused execution, but that also happened
       under normal conditions
    4. The crux of what made this difficult is that most of the UI
       related threads were in assembly, which was harder to interpret.
       However, the top of the stack in those threads were usually
       `mach_msg_trap`, which I believe is just the debugger
       interrupting execution. Below it, there were usually normal
       assembly instructions being run, such as `mov` and `ldp`
       instructions _(Move value and load a pair of registers)_, and
       stepping through some of those seemed to move the program
       counter. So I believe that the threads are running
    5. Running `thread info` on some of the threads (e.g. main) revealed
       that it seemed to be waiting on `mach_msg2_trap`, which again I
       believe is just the debugger pausing execution.
2. **After some more testing, I realized that swiping back only breaks
   when swiping back from the `ProfileView`, but not other views**
2. I tried to check if the issue was incorrect hashing of `Router`
   objects: `NavigationStack` uses `NavigationPath`, which needs a
   collection of hashable elements. I thought that if hashing was done
   incorrectly, the NavigationStack might have issues managing views.
   But that did not seem to be it either.
    1. I tried experimenting with the hashing logic for the Profile
       router. No changes
    2. I tried purposefully messing up with the hashing logic of a good,
       working view by adding random numbers into the hash. No issues on
       swiping out of that view either.
3. That lead me to the possibility that the issue is within the
   `ProfileView` body. I commented parts of the code out and tested each
   portion of it in a binary search fashion, and narrowed it down a
   specific line:

```
.navigationBarHidden(true)
```

Whenever I remove this line or set this to `false`, the freezing no
longer occurs. According to the Apple developer docs, this is
deprecated:
[https://developer.apple.com/documentation/swiftui/view/navigationbarhidden(_:)](https://developer.apple.com/documentation/swiftui/view/navigationbarhidden(_:))

I tried to replace it with its newer replacement: `.toolbar(.hidden,
for: .automatic)`, but that also causes the freeze.

So, just removing that line fixes the freeze, however it breaks the
layout by showing the unwanted back button.

Fix
---

I was able to fix it by implementing the custom toolbar under `.toolbar`
modifier, and hiding the back button (as opposed to the whole nav bar)

Testing of the fix
------------------

**PASS**

**Device:** iPhone 13 mini (Physical device)
**iOS:** iOS 17.0.1
**Damus:** This commit

**Special remarks:** Some entitlements removed locally to be able to
build to device without access to development certificate

**Test steps:** Same as reproduction steps

**Results:** Swiping back from profile does not cause any issues. View
layout of the custom navbar is unaltered in appearance.

iOS 16 smoke test
-----------------

**PASS**

**Device:** iPhone 14 Pro simulator
**iOS:** 16.4
**Damus:** This commit
**Special remarks:** Same as test above

**Test steps:** Same as reproduction steps. However here we are not
checking the freezing (as it was not reproducible in the simulator). We
are checking that the changes did not break navigation, nor layout, nor
caused any build issues.

**Results:** Working as expected

Closes: https://github.com/damus-io/damus/issues/1449
Changelog-Fixed: Fix UI freeze after swiping back from profile (#1449)
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-23 08:03:32 -07:00
William Casarin
01c6e3e9ab v1.6 (18) changelog 2023-09-21 18:08:56 -04:00
William Casarin
4377cf28ef v1.6 (18) 2023-09-21 18:05:59 -04:00
William Casarin
6f67c159ff ndb: switch to case-insensitive profile searches 2023-09-21 18:03:22 -04:00
William Casarin
7a85ae29ca search: switch to nostrdb profile searching
Changelog-Changed: Switch to nostrdb for @'s and user search
2023-09-21 13:19:22 -04:00
William Casarin
fafe3b4b3e ndb: add nostrdb migrations 2023-09-21 09:10:06 -04:00
William Casarin
69c7acea76 tests: add ndb support to tests
stops it from crashing
2023-09-21 09:10:06 -04:00
William Casarin
22d635d850 ndb: don't verify flatbuffers in release builds 2023-09-21 09:10:06 -04:00
William Casarin
fc9b9f2940 ndb: switch profile queries to use transactions
this should ensure no crashing occurs when querying profiles
2023-09-21 09:10:06 -04:00
William Casarin
622a436589 ndb: add NdbTxn transaction class
This will be used for transactions
2023-09-21 09:10:06 -04:00
William Casarin
9398877415 nostrdb/c: update to include transaction support 2023-09-21 09:10:06 -04:00
William Casarin
129d3ff101 ids: introduce NoteKey
These will be used to reference nostr notes from nostrdb
2023-09-21 09:10:06 -04:00
William Casarin
bb4fd75576 nostrdb: add profiles to nostrdb
This adds profiles to nostrdb

- Remove in-memory Profiles caches, nostrdb is as fast as an in-memory cache
- Remove ProfileDatabase and just use nostrdb directly

Changelog-Changed: Use nostrdb for profiles
2023-09-21 09:10:06 -04:00
Daniel D’Aquino
8586eed635 ui: add followed hashtags to FollowingView
When users view who a certain person follows, now they will see an extra
tab to see the hashtags that they follow.

This new tab contains a list of followed hashtags, each of which
includes an option to follow/unfollow the hashtag, as well as the
ability to visit the hashtag timeline

Testing

**iOS:** 17.0 (iPhone 14 Pro Simulator)
**Damus:** (This commit)
**Test steps:**
1. Go to search view, search for a couple of hashtags: #apple, #orange, #kiwi
2. Go to the test accounts own profile via the drawer menu
3. Click on "Following". Make sure there are two tabs now.
4. Scroll down, switch tabs between "People" and "Hashtags". Make sure that scrolling and switching tabs work
5. Unfollow and follow a user. Make sure that this still works
6. Make sure that #apple, #orange, #kiwi hashtags are visible under the "Hashtags" tab
7. Unfollow "#kiwi". Check that the button label now switches from "Unfollow" to "Follow"
8. Click on "#kiwi". Make sure that it takes you to the page where posts with that hashtag appears
9. Go to @jb55's profile
10. Click on "Following"
11. Ensure that there is a "Hashtags" tab
12. Check that @jb55's followed hashtags are shown (not your own)
13. Follow one of the same hashtags as @jb55's
14. Go back to your own profile and go to your own following view again.
15. Make sure that this newly added tag is present on the list, and that #kiwi is not.

Closes: https://github.com/damus-io/damus/issues/606
Changelog-Added: Add followed hashtags to your following list
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-21 09:10:06 -04:00
William Casarin
440e37c1d3 filters: generalize ContentFilter
This simplifies our content filters so that it is a bit more flexible
for future additions.

Fixes: 0957cc896cc8 ("Add "Do not show #nsfw tagged posts" setting")
2023-09-21 09:10:06 -04:00
Daniel D’Aquino
49283f2bb2 filters: add "Do not show #nsfw tagged posts" setting
This commit adds a setting where the user can choose to hide notes with
a #nsfw hashtag. This setting was implemented to allow users to filter
out adult or other unsafe content.

I moved the code logic for content filtering into a new file, and
defined a protocol for content filters. Although the logic is still
simple, this might help in developing a flexible API in case we have
more complex filtering needs in the future.

I also modified the name of the "Appearance" setting to "Appearance and
filters", to make it easier for users to intuitively find this setting.
(Note: Re-translations of this string might be necessary)

**PASS**
**iOS:**
- iOS 17.0 (iPhone 14 Pro)

**Damus:** (This commit)
**Steps:**
1. Follow another account that you control (Account B)
2. On account B, post a note saying "#test this is a test". This note should show up on the home feed.
3. On account B, post a note saying "#nsfw this is a test". This note should NOT show up on the home feed
4. Go to settings and disable the NSFW filter. Go back to the home view. The #nsfw post should now show up.
5. Close app and reopen. NSFW post should still show up (i.e. Setting should be persistent)
6. Unfollow account B
7. Close app and reopen.
8. Follow the "#grownostr" hashtag
9. Turn on the NSFW filter
10. On account B, post a note saying "#grownostr this is a test". This note should show up on the home view.
11. On account B, post a note saying "#grownostr #nsfw this is a test". This note should NOT show up.
12. Double-check the "notes and replies" tab. Note should NOT show up there either.
12. Turn off NSFW filter
13. Note from step 11 should now show up.
14. Go to Universe view and find a post with a hashtag. Remember where the post is.
14. Locally change the tag keyword from "nsfw" to that hashtag (Note: I had to test this way because my posts were not showing up in the Universe view)
15. Turn off the filter. Check post is there, in the Universe view.
16. Turn on the filter. Check post is no longer there in the Universe view. (Check the neighboring posts are the same, to make sure)
17. Bring back the code to its normal state.
18. Search for "#nsfw". Make sure that #nsfw appears (I believe this is ok, because it means the person is purposefully searching for it)

Closes: https://github.com/damus-io/damus/issues/1412
Changelog-Added: Add "Do not show #nsfw tagged posts" setting
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-21 09:10:06 -04:00
William Casarin
305ee03b0e relays: fix tld extraction performance issues
This uses a simpler variant that doesn't require a library. It is also
much faster and doesn't cause a delay when you open the relay view.

Not sure why I needed to touch other parts of the code to make the build
work. Probably xcode beta thing?
2023-09-21 09:10:06 -04:00
William Casarin
a88f5db10b Revert "deps: add tldextract"
This reverts commit 4263b9690f.
2023-09-21 08:48:20 -04:00
Suhail Saqan
d39a3da3b7 util: add separate_images and separate_invoices 2023-09-21 08:37:42 -04:00
ericholguin
40459e247e relays: user relay design 2023-09-16 14:15:27 -05:00
ericholguin
fff4549933 relays: remove usage of show action button binding 2023-09-16 14:15:27 -05:00
ericholguin
c4dfae9ede relays: update relay view to use new design
Changelog-Changed: Updated relay view
Closes: https://github.com/damus-io/damus/pull/1543
2023-09-16 14:15:27 -05:00
Daniel D’Aquino
bfda0d1b74 ui: increase size of the hitbox on note ellipsis button
Changelog-Changed: Increase size of the hitbox on note ellipsis button
Closes: https://github.com/damus-io/damus/issues/1454
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-16 14:15:20 -05:00
Daniel D’Aquino
01b8e43a6e compose: fix text wrapping issue when mentioning npub
Closes: https://github.com/damus-io/damus/issues/1211
Changelog-Fixed: Fix text composer wrapping issue when mentioning npub
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-16 13:58:27 -05:00
Jon Marrs
aa4ecc2139 test: add test cases for ASCII and UTF-8 characters in hashtags
Closes: https://github.com/damus-io/damus/pull/1546
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-15 12:31:17 -05:00
Jon Marrs
617dee3e6b damus-c: remove UTF-8 punctuation from hashtags
Check for UTF-8 punctuation (such as ellipsis) in addition to regular punctuation in hashtags.

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

Closes: https://github.com/damus-io/damus/pull/1546
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-15 12:31:17 -05:00
Daniel D’Aquino
510432bb98 ui: make blurred videos viewable by allowing blur to disappear once tapped
Closes: https://github.com/damus-io/damus/issues/1247
Changelog-Fixed: Make blurred videos viewable by allowing blur to disappear once tapped
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-15 12:31:05 -05:00
Jericho Hasselbush
c4a9f2fdb2 ui: hold tap to preview status URL
Applied a WKWebkitView inside a .contextMenu to show preview status for
URL links in user status messages.

Closes: https://github.com/damus-io/damus/issues/1523
Changelog-Added: Hold tap to preview status URL
Signed-off-by: Jericho Hasselbush <jericho@sal-et-lucem.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-15 12:30:26 -05:00
Daniel D’Aquino
b1e0a62109 nwc: fix parsing issue with NIP-47 compliant NWC urls without double-slashes
Closes: https://github.com/damus-io/damus/issues/1547
Changelog-Fixed: Fix parsing issue with NIP-47 compliant NWC urls without double-slashes
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-13 12:59:21 -06:00
William Casarin
1fc5ceff3b relays: fix withAnimation on older versions
Maybe this is an iOS17 thing?
2023-09-13 05:41:08 -07:00
William Casarin
16edc3fe13 relays: bouncy edit animation 2023-09-11 14:39:44 -07:00
William Casarin
6a88ca2777 relays: fix crash in new RelayPicView 2023-09-11 14:36:08 -07:00
William Casarin
e3ccf95780 ui: fix padding of username next to pfp on some views
Changelog-Fixed: Fix padding of username next to pfp on some views
2023-09-11 14:36:08 -07:00
Bryan Montz
9bac83352b ui: improve bottom spacing for ImageView's tab indicator dots
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-11 14:36:08 -07:00
Bryan Montz
0803594553 ui: make ImageView's tab indicator dots tappable
Changelog-Changed: Make carousel tab dots tappable
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-11 14:35:50 -07:00
Jericho Hasselbush
8dad8e6703 posting: fix issue with username and multiple emojis
Fixes issue where username with multiple emojis would place cursor in
strange position. Now properly moves the cursor to space past the
multiple emoji user name.

Any amount would be great. Not a complex issue to fix!

Tipjar: lnbc1pj0eddtpp5km07jgrfm47nfswqqp33ngv374gzad2hshkra7zm3l0cmpusnp3qdqqcqzzsxqyz5vqsp5rklkzj9upf32z3c3nmc9xg4pdlz5p5mp3s332ygefexf79tq8ucs9qyyssqxfh4kz3sg9zczsnj49w23aw35z87jwyx9m5su8kkyxlspyjk4ajy7vhxuw2rzw4lz8vfutfakm2rggvpzhzs9ehfus4nl683dl99f4sqgm9zkq
Changelog-Fixed: Fixes issue where username with multiple emojis would place cursor in strange position.
Signed-off-by: Jericho Hasselbush <jericho@sal-et-lucem.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-11 07:48:36 -07:00
William Casarin
e30d38e69f router: use tap gestures instead of nav links
I was hoping this would fix something but it did not
2023-09-10 18:27:37 -07:00
William Casarin
c13f29e98c router: hash bytes for a quick sanity check
probably a no-op
2023-09-10 18:27:37 -07:00
William Casarin
5b901656f3 perf: fix weird lag when switching timelines 2023-09-10 18:25:35 -07:00
William Casarin
36acdf420e perf: remove zstack on profile pictures
helps a bit? I think?
2023-09-10 18:25:35 -07:00
William Casarin
76a6dbc406 perf: remove unused zstack on like button 2023-09-10 18:25:35 -07:00
William Casarin
1b1d4bd6d1 perf: use plain images for actionbar buttons
The action bar is really slow to render for some reason, start
removing stuff
2023-09-10 18:25:35 -07:00
William Casarin
14586b616c log: remove some verbose preload logs 2023-09-10 18:25:35 -07:00
ericholguin
7baf7e66dc relays: add relay pic view for displaying relay icons 2023-09-10 09:54:35 -07:00
William Casarin
4263b9690f deps: add tldextract
This is needed for the new relay view
2023-09-10 09:52:54 -07:00
Suhail Saqan
7f6a702412 emojis: make width dynamic and font bigger
add calculateOverlayWidth to support this

Closes: https://github.com/damus-io/damus/pull/1542
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-09 10:24:14 -07:00
ericholguin
6f35de65f9 relays: add icon field to metadata 2023-09-09 09:48:18 -07:00
ericholguin
65f3651896 ui: dont display globe image for free relay types 2023-09-09 09:45:45 -07:00
ericholguin
94ce604b9d components: add neutral button style component 2023-09-09 09:45:16 -07:00
ericholguin
b934d66f64 components: add lighter gradient 2023-09-09 09:45:16 -07:00
ericholguin
20b6627799 colors: add variables for the new color assets 2023-09-09 09:45:16 -07:00
ericholguin
3e15f15a57 colors: add color sets from figma 2023-09-09 09:45:15 -07:00
petrikaj
5c87b8e610 transations: add finnish translation
Changelog-Added: Finnish translations
Closes: https://github.com/damus-io/damus/pull/1535
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-07 10:33:37 -07:00
William Casarin
42234b1cf3 remove timeline render logs 2023-09-07 10:33:37 -07:00
Bryan Montz
54ba64535d video: remove GSPlayer dependency
Changelog-Fixed: Fixed audio in video playing twice
Closes: https://github.com/damus-io/damus/pull/1539
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-07 10:33:34 -07:00
Bryan Montz
9cf53a9e93 video: remove VideoPlayer and switch to VideoController for cache
Closes: https://github.com/damus-io/damus/pull/1539
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-07 10:33:31 -07:00
Bryan Montz
3569da5687 video: switch player to use new view model
pass VideoController through containing views

Closes: https://github.com/damus-io/damus/pull/1539
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-07 10:33:19 -07:00
Bryan Montz
f1f3abfb98 video: add DamusVideoPlayerViewModel
Closes: https://github.com/damus-io/damus/pull/1539
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-07 10:33:14 -07:00
Bryan Montz
dec07df2c1 video: add VideoController, which hold cached metadata and mute states
Closes: https://github.com/damus-io/damus/pull/1539
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-07 10:33:12 -07:00
Bryan Montz
53734ea483 video: add AVPlayerView, a simple wrapper for AVPlayerViewController
Closes: https://github.com/damus-io/damus/pull/1539
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-07 10:33:07 -07:00
Grimless
fb8c470e9d Separate NIP-05 and username/display name onto their own lines.
Closes: https://github.com/damus-io/damus/pull/1534
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-05 10:45:35 -07:00
Grimless
b18a0c573e profile: move the "Follow you" badge into the profile header
Move the "Follow you" badge into the profile header he profile header
out-of-line with the often long and already space-constrained
username/display name text

Changelog-Changed: Move the "Follow you" badge into the profile header
Closes: https://github.com/damus-io/damus/pull/1529
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-03 18:02:54 -07:00
Grimless
f6f7d13f12 Properly implement top-level tests and fix one test using the wrong Block conversion property
Closes: https://github.com/damus-io/damus/pull/1528
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-03 18:02:32 -07:00
Grimless
6ee0be40e9 Create helper extensions for Block and update tests for the Block helper model
Closes: https://github.com/damus-io/damus/pull/1528
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-03 18:02:32 -07:00
Grimless
a64f898df7 Move the Block helper type to its own file, collapse the various standalone functions for parsing block data, and refactor consumers to initialize a Block with given data and access its members as needed.
Closes: https://github.com/damus-io/damus/pull/1528
Signed-off-by: William Casarin <jb55@jb55.com>
2023-09-03 18:02:32 -07:00
Jon Marrs
dd29e87146 test: pass keypair instead of privkey for test cases
Tests were not building due to recent changes in the Damus source code that replaced privkey with keypair. This patch extends those changes to the test cases, allowing the tests to build and pass.

Signed-off-by: Jon Marrs <jdmarrs@gmail.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-31 08:52:28 -07:00
William Casarin
c71b0ee916 blocks: pass keypair instead of privkey to avoid pubkey gen
Generating a pubkey is quite slow, so pass a keypair instead of privkey
2023-08-28 11:47:29 -07:00
William Casarin
8e92e28faf test: optionally remove lmdb db
otherwise tests fail on CI
2023-08-28 10:34:37 -07:00
William Casarin
5657512370 ndb: restore escaped slash fix 2023-08-28 10:09:49 -07:00
William Casarin
882f6e2534 ndb: update nostrdb, fix alignment issues 2023-08-28 08:19:03 -07:00
William Casarin
2f60888fb1 ndb: remove patch from copy script, just use sed 2023-08-28 08:18:25 -07:00
William Casarin
ba6792640d flatbuffers: update bindings, add verifier 2023-08-28 08:17:25 -07:00
William Casarin
984c7b6932 ndb: ensure profile flatbuffers are not copied
These are pointers into LMDB's virtual memory map of the database. No
copy required.
2023-08-28 08:00:45 -07:00
William Casarin
0bbc2c6348 ndb: save in documents instead of cache dir
This is more long term storage
2023-08-28 08:00:45 -07:00
William Casarin
c44c0d0863 profile: remove deleted flag
it's not used anymore
2023-08-28 08:00:45 -07:00
William Casarin
50d55572be Fix crash when long pressing custom reactions
Changelog-Fixed: Fix crash when long pressing custom reactions
2023-08-28 08:00:45 -07:00
William Casarin
caffa0398b nostrdb: profile flatbuffers in nostrdb working! 2023-08-26 20:46:42 -07:00
William Casarin
92bbc9766d project: disable compile warnings for lmdb and nostrdb 2023-08-26 20:46:42 -07:00
William Casarin
699f77d9e1 add extended virtual memory entitlement
This will allow larger nostrdb databases
2023-08-26 20:46:42 -07:00
William Casarin
4c0166bd31 add swift flatbuffers 2023-08-26 20:46:42 -07:00
William Casarin
35b67dc08d nostrdb: initial Ndb class 2023-08-26 17:11:41 -07:00
William Casarin
1f5f1e28a4 nostrdb: pull latest, adding flatcc and lmdb 2023-08-25 19:05:34 -07:00
William Casarin
f30f93f65c Revert "Move the Block helper type to its own file"
This fixes the broken tests

This reverts commit 286ae68fd6.
2023-08-25 19:05:34 -07:00
William Casarin
7255481705 v1.6 (17) changelog 2023-08-23 17:49:30 -07:00
William Casarin
16fa701509 v1.6 (17) 2023-08-23 17:48:32 -07:00
William Casarin
2c6999e15c status: support clickable status urls
Changelog-Added: Add support for status URLs
2023-08-23 17:46:31 -07:00
William Casarin
981d500c25 status: click music urls to display in spotify
Changelog-Added: Click music statuses to display in spotify
2023-08-23 17:17:53 -07:00
William Casarin
d02fc9142d status: add settings for disabling statuses in the UI
Suggested-by: Tanel
Changelog-Added: Add settings for disabling user statuses
2023-08-23 16:43:55 -07:00
William Casarin
db59f74970 status: add missing status to some thread event views 2023-08-23 16:31:10 -07:00
William Casarin
bf3ca4a186 status: truncate statuses to a single line
Changelog-Fixed: Fix long status lines
2023-08-23 16:23:18 -07:00
William Casarin
53c2b3a48d status: clear statuses if they only contain whitespace
Changelog-Changed: clear statuses if they only contain whitespace
2023-08-23 16:19:19 -07:00
William Casarin
23a8d6fb6b status: fix status events not expiring locally
Changelog-Fixed: Fix status events not expiring locally
2023-08-23 16:11:48 -07:00
William Casarin
042b7da315 status: ignore processing expired events 2023-08-23 15:56:41 -07:00
William Casarin
e62ba5826b v1.6-16 changelog 2023-08-23 13:31:41 -07:00
William Casarin
1d11bb40b5 v1.6 (16) 2023-08-23 13:30:38 -07:00
William Casarin
0338297bfe Live Music & Generic Statuses
Changelog-Added: Added live music statuses
Changelog-Added: Added generic user statuses
2023-08-23 13:26:55 -07:00
William Casarin
59cf8056bd sidemenu: split out profile section
We will be adding to this and it is getting messy
2023-08-23 09:52:50 -07:00
William Casarin
d34d417fcc home: collapse guard statement
small nit refactor
2023-08-23 09:27:09 -07:00
William Casarin
b665a40a11 fix build 2023-08-23 09:25:47 -07:00
gladiusKatana
5caa4a6e97 videos: improve precision & sensitivity of auto-pause mechanism
Closes: https://github.com/damus-io/damus/pull/1308
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-23 09:24:13 -07:00
Grimless
c5d8e4a4a1 Simplify and inline Report event logic.
Closes: https://github.com/damus-io/damus/pull/1498
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-23 09:13:38 -07:00
tappu75e@duck.com
8b600a9774 Avoid notification for zap from mute profiles
Changelog-Fixed: Avoid notification for zaps from muted profiles
Closes: https://github.com/damus-io/damus/pull/1494
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-23 09:10:22 -07:00
Grimless
286ae68fd6 Move the Block helper type to its own file
Collapse the various standalone functions for parsing block data, and
refactor consumers to initialize a Block with given data and access its
members as needed.

Closes: https://github.com/damus-io/damus/pull/1496
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-21 17:11:43 -07:00
William Casarin
6ab893a617 profile: remove redundant view builder 2023-08-21 13:26:33 -07:00
William Casarin
9bfb59c4cc docs: people like centralized tools
This was confusing people, make it clear that github PRs are fine
2023-08-21 13:26:33 -07:00
Daniel D’Aquino
dcb94635ea Fix text editing issues on characters added right after mention link
Changelog-Fixed: Fix text editing issues on characters added right after mention link
Closes: https://github.com/damus-io/damus/issues/1375
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Tested-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-20 17:25:06 -07:00
Fishcake
c464a26151 use nostr.build api v2 with optional nip98 support
Closes: https://github.com/damus-io/damus/pull/1471
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-20 16:29:33 -07:00
Fishcake
9104ddb051 add function to create nip98 http authorization header
Closes: https://github.com/damus-io/damus/pull/1471
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-20 16:29:33 -07:00
Fishcake
1432087edf add nostr event 27235 (nip-98)
Closes: https://github.com/damus-io/damus/pull/1471
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-20 16:29:33 -07:00
William Casarin
ae2f7255a7 Mute hellthreads everywhere
Changelog-Fixed: Mute hellthreads everywhere
Fixes: https://damus.io/note1rn3ckl76myga6xcefr0le52d8czd0wqe8apguewqknyv7m55mmpq3rv3hv
2023-08-20 11:45:25 -07:00
William Casarin
d5b944170f actually build 15 because reasons 2023-08-20 11:25:01 -07:00
William Casarin
9fb1cc5b57 v1.16 (13) changelog 2023-08-18 11:20:51 -07:00
William Casarin
2e512317e7 v1.6 (13) 2023-08-18 10:10:18 -07:00
tappu75e@duck.com
f9eb669132 replies: fix bug where it would sometimes show -1
Changelog-Fixed: Fix bug where it would sometimes show -1 in replies
Closes: https://github.com/damus-io/damus/pull/1476
2023-08-18 08:41:21 -07:00
Daniel D‘Aquino
066b3cdde8 Fix image links appearing with escaped slashes
Changelog-Fixed: Fix images and links occasionally appearing with escaped slashes
Closes: https://github.com/damus-io/damus/issues/1468
Signed-off-by: Daniel D‘Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
Rewarded-sats: 50000
2023-08-18 08:41:21 -07:00
William Casarin
7f313dcbd4 nostrscript: add comment about iOS virtual memory allocs
I'm really just doing this because I forgot a changelog entry

Changelog-Fixed: Fixed nostrscript not working on smaller phones
2023-08-18 08:41:21 -07:00
William Casarin
1dabd88355 nostrscript: reduce size of wasm page allocation
smaller phones don't like this
2023-08-11 07:47:15 -07:00
Suhail Saqan
4f33641244 change button scale effect
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-11 07:08:44 -07:00
William Casarin
006a6ef16f Show possibly invalid zaps if we don't have the event in cache
Changelog-Fixed: Fix zaps sometimes not appearing
2023-08-10 10:32:57 -07:00
William Casarin
7467a9d5b1 Fix empty lines in profile and reposting-the-wrong-thing bugs
Changelog-Fixed: Fixed issue where reposts would sometimes repost the wrong thing
Changelog-Fixed: Fixed issues where sometimes there would be empty entries on your profile
2023-08-09 09:16:29 -07:00
William Casarin
9f01cab2be simplify reduce_text_block 2023-08-08 17:09:45 -07:00
William Casarin
502917012c v1.6 (11) changelog 2023-08-07 08:46:23 -07:00
William Casarin
916f7d789e v1.6 (11) 2023-08-07 08:45:07 -07:00
William Casarin
21eda288c4 timeline: show renotes in Notes timelines
Changelog-Changed: Show renotes in Notes timeline
Fixes: https://github.com/damus-io/damus/issues/676
2023-08-07 08:24:02 -07:00
William Casarin
25e022d933 reply: ensure the person you're replying to is the first entry in the reply description
Suggested-by: Tanel
Changelog-Fixed: Ensure the person you're replying to is the first entry in the reply description
2023-08-06 15:37:32 -07:00
William Casarin
e642913944 notifications: don't cutoff text
Changelog-Fixed: don't cutoff text in notifications
2023-08-06 14:58:32 -07:00
cr0bar
967785392f note: fix paragraphs not appearing on iOS17
In some edge cases, the inflated UiTextView didn't render properly
causing a black screen which needed the user to scroll. Dropped the
inflate size and now only set where selectedTextHeight is .zero, seems
more reliable.

Closes: https://github.com/damus-io/damus/pull/1427
Changelog-Fixed: Fix paragraphs not appearing on iOS17
2023-08-06 14:23:11 -07:00
William Casarin
9e6fbeefcd url: smartparens hack
support urls like (https://jb55.com/something)
2023-08-06 14:16:43 -07:00
William Casarin
de58e52199 dms: move timestamp outside of bubble 2023-08-06 14:07:04 -07:00
William Casarin
53e9269da6 urls: fix wikipedia url detection with parenthesis
Fixes: f0df4aa218 ("Strip common punctuations from URLs")
Fixes: https://github.com/damus-io/damus/issues/1027
Closes: https://github.com/damus-io/damus/pull/1063
Changelog-Fixed: Fix wikipedia url detection with parenthesis
2023-08-06 13:53:28 -07:00
Joel Klabo
85930df8e3 tests: add url parens tests 2023-08-06 13:51:39 -07:00
William Casarin
cf3a9a576d test: move existing url tests to UrlTests 2023-08-06 13:50:20 -07:00
William Casarin
e397fc069b make: add tags target 2023-08-06 13:50:20 -07:00
William Casarin
2529797dfb todo: add local todo helper 2023-08-06 13:50:20 -07:00
William Casarin
bd2193251f build: fix some build issues with the last revert
Fixes: 1a2ac976a3 ("Fix old notifications always appearing on first start")
2023-08-06 11:30:28 -07:00
William Casarin
1a2ac976a3 Fix old notifications always appearing on first start
Revert "home: debounce last notified"

This is technically incorrect, as debouncing can prevent saving
important events.

The proper way to do this is to save it locally in memory, and then
debouncing the saving itself. Will do this soon.

Reverts: a9b4cfd424
Fixes: https://github.com/damus-io/damus/issues/1439
Changelog-Fixed: Fixed old notifications always appearing on first start
2023-08-06 09:22:28 -07:00
William Casarin
d4faacb99f relays: strip trailing / from relay urls
Fixes: https://github.com/damus-io/damus/issues/1443
Changelog-Fixed: Fix issue with slashes on relay urls causing relay connection problems
2023-08-06 09:07:33 -07:00
William Casarin
a73271e3d4 debug: remove note size debug
ThreadSanitizer was complaining about a data race
2023-08-06 09:07:33 -07:00
William Casarin
624a7b4e88 notifications: fix rare crash with local notification
This shouldn't happen, but I found a log that crashed here, so we will
fix this anyways.

Changelog-Fixed: Fix rare crash triggered by local notifications
2023-08-06 08:33:51 -07:00
William Casarin
5b9803d234 script: add build-git-hash.txt build output
Otherwise we get warnings
2023-08-06 07:54:23 -07:00
William Casarin
3098d4b4fa bar: fix crash when long pressing emoji selection
Changelog-Fixed: Fix crash when long-pressing reactions
2023-08-06 07:10:01 -07:00
William Casarin
0178478199 decoding: fix decoding of large events like nostr reports
I was trying to do an initial malloc that was somewhat efficient. Looks
like our ndb_builder needs a bit more space when allocating the
ndb_note.

Changelog-Fixed: Fixed nostr reporting decoding
2023-08-06 06:56:24 -07:00
William Casarin
d489bcc586 test: add test for failing nostr report event 2023-08-06 06:56:24 -07:00
William Casarin
453d540255 search: find_event_with_subid
I needed this to find a bug in event decoding
2023-08-06 06:56:24 -07:00
Suhail Saqan
5ded564bdc settings: change settings order: Reactions -> Developer
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-05 18:48:44 -07:00
Suhail Saqan
3908192fe2 reactions: add close button to custom reactions
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Added: Add close button to custom reactions
2023-08-05 18:48:35 -07:00
Suhail Saqan
92020e551b reactions: add ability to change order of emojis
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Added: Add ability to change order of custom reactions
2023-08-05 18:48:30 -07:00
Suhail Saqan
ccd52a09d8 reactions: remove some left padding from add and remove buttons
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-05 18:48:24 -07:00
Suhail Saqan
ced3c76996 reactions: only allow copy emoji when editing
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-05 18:48:16 -07:00
Suhail Saqan
29bba15230 qr: dismiss qrcode fullScreenCover on scan
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Fixed: Dismiss qr screen on scan
2023-08-05 18:48:11 -07:00
Suhail Saqan
fb179ac1d4 qr: show QRCameraView regardless of same user
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Fixed: Show QRCameraView regardless of same user
2023-08-05 18:48:11 -07:00
Suhail Saqan
7900865c02 bar: wiggle long press reactions
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Fixed: Fix wiggle when long press reactions
2023-08-05 18:48:01 -07:00
Suhail Saqan
0350809e82 bar: fix reaction button breaking scrolling
Signed-off-by: William Casarin <jb55@jb55.com>
Changelog-Fixed: Fix reaction button breaking scrolling
2023-08-05 18:44:54 -07:00
Bryan Montz
cddb88b890 fix: crash when muting threads
Fixes a crash when the user mutes a thread. UserDefaults didn't know how
to serialize a NoteId for storage, so we'll convert it to the hex id
first.

Changelog-Fixed: Crash when muting threads
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-04 09:35:35 -07:00
William Casarin
14ba33674b setting: adjustable font size for jack the zapper
Changelog-Added: Adjustable font size
2023-08-03 18:38:20 -07:00
William Casarin
c0f4e3fe03 v1.6 (9) 2023-08-03 17:25:52 -07:00
William Casarin
dae2e8ef56 Revert "Fix for missing bottom half of a note"
This reverts commit 39dce64131.
2023-08-03 17:23:53 -07:00
William Casarin
b2d2fbee0d v1.6-8 changelog 2023-08-03 13:36:24 -07:00
William Casarin
cebd1f48ca ndb: switch to nostrdb notes
This is a refactor of the codebase to use a more memory-efficient
representation of notes. It should also be much faster at decoding since
we're using a custom C json parser now.

Changelog-Changed: Improved memory usage and performance when processing events
2023-08-03 13:20:36 -07:00
William Casarin
55bbe8f855 disable nostrscript test for now 2023-08-03 13:15:32 -07:00
cr0bar
39dce64131 Fix for missing bottom half of a note
Strange fix, but by increasing the height of a UiTextView past the size
of any legitimate content, then re-sizes back to the correct size
displaying the full content.

Changelog-Fixed: Fixed disappearing text on iOS17
2023-08-03 12:34:18 -07:00
William Casarin
b556257edd util: add structured logger 2023-08-03 12:17:56 -07:00
Daniel D‘Aquino
cdc4a7b7a4 Fix UTF support for hashtags
Changelog-Fixed: Fix UTF support for hashtags
Closes: https://github.com/damus-io/damus/issues/1411
Signed-off-by: Daniel D‘Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-03 12:17:32 -07:00
Daniel D‘Aquino
ef5a3030a6 Add unit tests surrounding creation of posts with non-latin hashtags, as well as the rendering of non-latin hashtag
Signed-off-by: Daniel D‘Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-03 12:17:32 -07:00
Daniel D‘Aquino
f0b8dcc5e9 Split view previews in NoteContentView to make both variants visible
Signed-off-by: Daniel D‘Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-03 12:17:32 -07:00
Daniel D‘Aquino
72b60573de Fix compilation error on test target in UserSearchCacheTests
Changelog-Fixed: Fix compilation error on test target in UserSearchCacheTests
Signed-off-by: Daniel D‘Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-08-03 12:17:32 -07:00
William Casarin
6e6c1eb7b6 ndb: make AsciiCharacter a CustomStringConvertible 2023-08-01 21:53:19 -07:00
William Casarin
07dfa3b1fb ndb: update nostrdb
This include various fixes for parsing and key decoding
2023-08-01 21:53:19 -07:00
William Casarin
88306d00a3 key: generate a FullKeypair when generating new keys 2023-08-01 21:53:19 -07:00
William Casarin
616de2eebc state: improve damus state init
It's a bit cleaner now
2023-08-01 21:53:19 -07:00
William Casarin
709aab549b nav: fix nav crashes and buggyness
just use the hashable for equality

Changelog-Fixed: Fix nav crashing and buggyness
2023-08-01 21:53:05 -07:00
William Casarin
15ab9f7135 scroll: allow any hashable target 2023-08-01 21:52:23 -07:00
William Casarin
d4aa8a5602 config: show git hash in version info
This will be useful for sanity checks and bisecting
2023-08-01 09:29:09 -07:00
William Casarin
a9b4cfd424 home: debounce last notified
Calling UserDefaults fast in a loop is not good
2023-07-31 05:38:19 -07:00
William Casarin
2b99f94d13 profiledb: disable database lookups for now
This is causing extremely bad lag in the UI
2023-07-31 05:38:19 -07:00
William Casarin
66e204eb91 notifications: don't do expensive id calculation 2023-07-31 05:38:19 -07:00
William Casarin
7040235605 refactor: add Pubkey, Privkey, NoteId string aliases
This is a non-behavioral change in preparation for the actual switchover
from Strings to Ids. The purpose of this kit is to reduce the size of
the switchover commit which is going to be very large.
2023-07-31 05:38:19 -07:00
William Casarin
f9d21ef901 test: rename test_event to test_note 2023-07-31 05:38:19 -07:00
William Casarin
a08d0a5a19 ndb: more id transition helpers 2023-07-31 04:08:07 -07:00
William Casarin
ff20cc4767 tests: enable code coverage 2023-07-31 03:25:50 -07:00
William Casarin
aacb336002 Update Translations 2023-07-30 11:57:18 -07:00
William Casarin
b40c595a7c notify: switch over to new typesafe notifications 2023-07-30 11:02:44 -07:00
William Casarin
80063af19a notify: add typesafe notifications 2023-07-30 11:02:44 -07:00
William Casarin
df3b94a1fc notify: add typesafe notify class 2023-07-30 11:02:44 -07:00
William Casarin
06a66a3709 add some type aliases to make the ndb move more incremental 2023-07-30 10:52:02 -07:00
William Casarin
1463ce5e3a profile: don't notify on notice
this is just a waste of cpu at this point and could cause main thread
blocking issues
2023-07-30 10:52:02 -07:00
Joel Klabo
480921db20 Suggested Users to Follow
ui: Add Suggested Users Views and Helpers
ui: Add Logic to Launch Suggested User Screen

Changelog-Added: Suggested Users to Follow
2023-07-29 10:25:24 -07:00
doffing.brett
f0de8721c7 Center and Pad buttons in EULA 2023-07-29 10:11:38 -07:00
Suhail Saqan
d11cd76e6a Add multiple reaction support
Changelog-Added: Add support for multiple reactions
Closes: https://github.com/damus-io/damus/issues/1335
2023-07-29 10:03:55 -07:00
Daniel D'Aquino' via patches
815f4d4a96 Allow relay logs to be opened in dev mode even if relay is disconnected
Changelog-Fixed: Allow relay logs to be opened in dev mode even if relay
Closes: https://github.com/damus-io/damus/issues/1368
Signed-off-by: Daniel D'Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-29 09:44:36 -07:00
Bryan Montz
4fecf72963 fix: endless connection attempt loop after user removes relay
This patch fixes an issue where, after the user removes a misbehaving
relay, the RelayConnection will keep trying to reconnect endlessly. You
can reproduce the issue prior to this change by adding the relay
wss://brb.io. It will fail to connect over and over. Then remove the
relay in the UI. In the console, you will see that it keeps trying to
connect, and the corresponding RelayConnection never gets deallocated.
After the change, it stops connecting and deallocates the
RelayConnection.

Changelog-Fixed: endless connection attempt loop after user removes relay
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-29 09:18:03 -07:00
William Casarin
593d0e2abe ndb: sync up a few remaining NdbNote tag differences 2023-07-25 16:22:25 -07:00
William Casarin
2f8aa29e92 ndb: make NostrEvents immutable
Since we can't mutate NdbNotes, let's update the existing codebase to
generate and sign ids on NostrEvent constructions. This will allow us to
match NdbNote's constructor
2023-07-25 15:34:05 -07:00
William Casarin
e3c04465fc ndb: move to uint32 for kind and created_at 2023-07-25 15:24:26 -07:00
William Casarin
54d40f7ffd ndb: move hexchar into header
since it's used in a few places
2023-07-25 15:23:36 -07:00
William Casarin
2053033b25 ndb: make note equatble
We need this for the switchover
2023-07-24 13:09:27 -07:00
William Casarin
45801f3e6c ndb: rename NostrEvent to NostrEventOld
This facilitates the switch to NdbNote by allowing us to switch back and
forth to fix things.
2023-07-24 13:08:55 -07:00
William Casarin
2d44f2744b ndb: switch to computed property for tags
this will allows us to change less code on the switchover
2023-07-24 13:08:18 -07:00
William Casarin
04e408bfea ndb: implement a few more event things
We're basically done. Time to try the switch-over
2023-07-24 12:41:12 -07:00
William Casarin
b3c87bdc07 test: remove unused var 2023-07-24 12:40:04 -07:00
William Casarin
b5dd90b36a notes: generalize event_is_reply a bit
so that it works with NdbNote as well
2023-07-24 12:39:55 -07:00
William Casarin
6fa9149939 ndb: avoid double constructor on References 2023-07-24 11:05:18 -07:00
William Casarin
1e9e4a7f3a ndb: implement eventref building from ndb notes 2023-07-24 10:55:34 -07:00
William Casarin
c8e236b6d5 ndb/test: add more test coverage on char iter 2023-07-23 12:21:36 -07:00
William Casarin
e8d0f1db8d test: fix some ndb test warnings 2023-07-23 12:12:42 -07:00
William Casarin
99b5dc94cb ndb: copy over perf improvements 2023-07-23 12:11:08 -07:00
William Casarin
e34351ca37 ndb: fix iterators, pack id tags, more tests 2023-07-23 11:55:36 -07:00
William Casarin
1a33d639ed test: remove some unused perf tests 2023-07-23 11:54:58 -07:00
William Casarin
5c1043b4e5 ndb: add cchar constructors to AsciiCharacter
This will be used for the cchar iterator
2023-07-23 11:54:07 -07:00
William Casarin
23b5763a6b git: ignore perf baselines
this is system-dependent
2023-07-23 11:50:02 -07:00
William Casarin
dd65209a20 Revert "ndb: remove TagIterators and just use sequences"
This reverts commit f0d07c3663.
2023-07-23 10:56:12 -07:00
William Casarin
f0d07c3663 ndb: remove TagIterators and just use sequences
Still learning...
2023-07-22 21:12:53 -07:00
William Casarin
b3119fa41e test: small test fix 2023-07-22 17:23:11 -07:00
William Casarin
7ec8da6c73 ndb: start implementing existing NostrEvent functionality
We eventually want to switch over to NdbNote instead of NostrEvent. To
facilitate this, the plan is to eventually make NostrEvent an alias of
NdbNote. For this to work, let's make sure the NostrEvent extensions are
implemented on NdbNote.

We will likely switch away from string properties as well, but for now
we will try to emulate as much as possible to make sure everything is
working first.
2023-07-22 17:19:47 -07:00
William Casarin
9e659c49b5 ndb/test: add a few more tests 2023-07-22 17:19:47 -07:00
William Casarin
c72666b352 ndb: add subscript and count for TagsSequence
These are helpful
2023-07-22 17:19:47 -07:00
William Casarin
1854e10486 mentions: add ndb mention parser 2023-07-22 17:19:47 -07:00
William Casarin
58e2fb40ef iter: make safer by using NdbNote instead of unsafe pointers
If we have an owned note, we could lose track of the lifetime and then
crash. Let's make sure we always have an NdbNote instead
2023-07-22 17:19:47 -07:00
William Casarin
af7ea7024f misc: don't immediately hex encode event commitment
keep it separate for now, since we're moving to more low level. We
probably won't even use this, but this is cleaner logicwise anyway.
2023-07-22 17:19:47 -07:00
William Casarin
0263c11a94 ndb: add content and owned_size 2023-07-22 17:19:47 -07:00
William Casarin
6d43754e71 ndb: add pubkey to NdbNote 2023-07-22 17:19:47 -07:00
William Casarin
4da23390f8 ndb: update lib 2023-07-22 17:19:47 -07:00
William Casarin
c74993366b move copyndb to the right folder 2023-07-22 17:19:47 -07:00
William Casarin
ad0e1f28b7 test: fix build and tests 2023-07-21 15:26:03 -07:00
William Casarin
61051ee853 nostrdb: add initial swift integration 2023-07-21 15:02:01 -07:00
William Casarin
dc7826c4e5 c: add nostrdb c lib 2023-07-21 15:02:01 -07:00
William Casarin
4eee715bcd c: add jsmn json parser
This is used by the nostrdb lib. Let's add it here.
This doesn't unescape things, so we'll still need to do that manually.
2023-07-21 14:56:24 -07:00
William Casarin
08bea16be0 c: add new cursor util
this is used by nostrdb as well. so add it here ahead of time.
2023-07-21 14:55:54 -07:00
William Casarin
8f04b12a90 c: add copy nostrdb devtool 2023-07-21 14:55:54 -07:00
William Casarin
9cfed9f3aa c: update protoverse_cursor to jb55_cursor
Will be using this in the new db implementation
2023-07-21 14:39:21 -07:00
William Casarin
123ca3b802 test: add my contact list for as json parsing test data 2023-07-21 14:39:21 -07:00
William Casarin
5e7b1f4ff3 event: separate logic from data using extensions
I'm not a huge fan of this pattern but it's getting messy in here
2023-07-21 14:39:11 -07:00
12594e35c1 Update translations
47	Translate Localizable.stringsdict in de
6	Translate Localizable.strings in de
3	Translate Localizable.strings in zh_CN
2	Translate Localizable.strings in sv_SE
2	Translate Localizable.strings in es_419
1	Translate Localizable.stringsdict in zh_TW
1	Translate Localizable.stringsdict in zh_HK
1	Translate Localizable.stringsdict in zh_CN
1	Translate Localizable.stringsdict in sv_SE
1	Translate Localizable.stringsdict in pl_PL
1	Translate Localizable.stringsdict in es_419
1	Translate Localizable.strings in zh_TW
1	Translate Localizable.strings in zh_HK
1	Translate Localizable.strings in pl_PL
1	Translate Localizable.strings in nl

Closes: https://github.com/damus-io/damus/pull/1373
2023-07-19 10:11:42 -07:00
ab92f7b561 Update localization issues and export strings for translation 2023-07-19 10:08:30 -07:00
William Casarin
11b9062865 test: fix some warnings 2023-07-19 10:04:25 -07:00
William Casarin
5c5b55bf67 v1.6 (7) changelog 2023-07-17 14:39:27 -07:00
William Casarin
dd6c082a8e v1.6 (7) 2023-07-17 14:35:54 -07:00
William Casarin
2a4ee6c48c zaps: don't spam lnurls when validate zaps
lnurls.lookup_or_fetch not fetched lnurl1dp68gurn8ghj7um9dej8xct5wvhxcmmv9uh8wetvdskkkmn0wahz7mrww4excup0df3r2dg3mj444
fetching static payreq lnurl1dp68gurn8ghj7um9dej8xct5wvhxcmmv9uh8wetvdskkkmn0wahz7mrww4excup0df3r2dg3mj444
lnurls.lookup_or_fetch already fetching lnurl1dp68gurn8ghj7um9dej8xct5wvhxcmmv9uh8wetvdskkkmn0wahz7mrww4excup0df3r2dg3mj444
lnurls.lookup_or_fetch already fetching lnurl1dp68gurn8ghj7um9dej8xct5wvhxcmmv9uh8wetvdskkkmn0wahz7mrww4excup0df3r2dg3mj444
lnurls.lookup_or_fetch already fetching lnurl1dp68gurn8ghj7um9dej8xct5wvhxcmmv9uh8wetvdskkkmn0wahz7mrww4excup0df3r2dg3mj444
lnurls.lookup_or_fetch already fetching lnurl1dp68gurn8ghj7um9dej8xct5wvhxcmmv9uh8wetvdskkkmn0wahz7mrww4excup0df3r2dg3mj444

Changelog-Fixed: Don't spam lnurls when validating zaps
2023-07-17 14:12:41 -07:00
William Casarin
fa520d48d3 zap: remove unnecessary main thread dispatches when zapping 2023-07-17 14:11:23 -07:00
William Casarin
160b293359 performance: don't spam nip05 validation on startup
Since we don't show these on events anymore, we don't need to spam nip05
validation. We can just check when we go to the profile page

Changelog-Fixed: Eliminate nostr address validation bandwidth on startup
2023-07-17 13:25:56 -07:00
William Casarin
7d17b9b476 nip05: hide nip05 username if it matches the username 2023-07-17 13:25:56 -07:00
William Casarin
d04f1c6867 login: allow user to login to deleted profile
If they every change their mind.

Changelog-Fixed: Allow user to login to deleted profile
2023-07-17 13:25:56 -07:00
William Casarin
5c87dd5bbb nip05: remove clickable option
they're always clickable now
2023-07-17 13:25:56 -07:00
William Casarin
12febf9671 view: extract ProfileEditButton to its own file
profile view file is getting cray cray
2023-07-17 13:25:56 -07:00
William Casarin
4033ad66ba test: fix crash in ci 2023-07-17 13:25:56 -07:00
William Casarin
2c0296cce3 project: bump deployment target
not sure how this is different than the previous setting that was
updated.

Cc: Bryan Montz <bryanmontz@me.com>
2023-07-17 13:25:56 -07:00
William Casarin
080aaf2d1b nip05: show username and support _ usernames
Changelog-Added: Show nostr address username and support abbreviated _ usernames
2023-07-17 11:01:57 -07:00
William Casarin
0e55b08b6c Revert removing nip05 badges on profiles
Changelog-Added: Re-add nip05 badges to profiles

This partially reverts commit 7ae7584135.
2023-07-17 10:52:20 -07:00
William Casarin
ff70cb7ebf posting: don't prepad user tag if its a newline
This fixes one more edgecase with the tag prepend logic.
2023-07-17 10:45:05 -07:00
William Casarin
fe82134a75 posting: switch to new tested composition logic
This switches to the new post composition logic in the post view. It
adds a space at the begging of a mention if it is needed.

We still need to make the state in these view more pure so we can test
more of the posting logic like cursor positions after posting, etc.

Changelog-Added: Add space when tagging users in posts if needed
Changelog-Fixed: Fix issue where typing cc@bob would produce brokenb ccnostr:bob mention
2023-07-17 10:25:09 -07:00
William Casarin
60a0c21272 test: add post composition tests
This adds post composition tests so that we can avoid composition bugs.
This still does not capture all of the dynamics of post composition,
because it ignores much of the mutable cursor position and related state
when editing posts.

We will need to make post editing more pure and less mutable in the
future to get test coverage on those.
2023-07-17 10:25:09 -07:00
William Casarin
8242ca27d2 profile: make constructor args optional
This makes it easier to create one-off profiles for testing. eg:

Profile(name: "jb55")
2023-07-17 10:25:09 -07:00
William Casarin
c7baa153af posting: add some functions for appending mention tags
These are easy-to-test functions for appending user tags to attributed
strings. We will use these in the next couple of commits to replace the
existing buggy functionality.
2023-07-17 10:25:09 -07:00
William Casarin
ff654c4e11 test: add text attribute testing function
This will be used for testing attributed strings
2023-07-17 10:25:09 -07:00
William Casarin
deaf5f042a search: refactor appendUserTag to make logic more clear
ocd mostly
2023-07-17 10:25:09 -07:00
William Casarin
4f56ff3dfb longform: add padding under words count
Changelog-Added: Added padding under word count on longform account
2023-07-17 10:25:09 -07:00
William Casarin
fd59407171 test: fix old markdown tests 2023-07-17 10:25:09 -07:00
William Casarin
9b759247ee v1.6 (6) changelog 2023-07-16 15:34:40 -07:00
William Casarin
cd7998b69d v1.6 (6) 2023-07-16 15:33:00 -07:00
William Casarin
bd4c29604f Fix broken markdown renderer
This switches away from the old markdown renderer to the new one at
https://github.com/damus-io/swift-markdown-ui

Changelog-Fixed: Fix broken markdown renderer
2023-07-16 15:27:24 -07:00
William Casarin
bf1175f22c markdown: add some helpers for counting markdown words
Will use this in the new word counter
2023-07-16 15:27:06 -07:00
William Casarin
064888f78d markdown: use a real-world longform preview 2023-07-16 15:26:31 -07:00
William Casarin
fc640b85ed add swift-markdown-ui
We will be using this lib which is much better than the builtin
framework for markdown rendering. We use a modified version that removes
html tag rendering which looks horrible.
2023-07-16 15:25:09 -07:00
William Casarin
d5766253cf build: fix unused variable warning 2023-07-16 15:24:06 -07:00
William Casarin
571ed39d52 Fixed issue where hashtags were leaking in DMs
Now we never add any tags to DMs, we only add the p tag of the user
you're talking to.

Changelog-Fixed: Fixed issue where hashtags were leaking in DMs
2023-07-16 15:24:06 -07:00
cr0bar
16d81ed40f Hide nsec when logging in
Fix for Hide nsec when logging in & add hide/show toggle

Closes: https://github.com/damus-io/damus/issues/1206
Changelog-Changed: Hide nsec when logging in
2023-07-16 13:05:18 -07:00
William Casarin
1135c19fea test: add setting property tests
Some initial UserSettingsStore property tests
2023-07-16 13:05:18 -07:00
William Casarin
77331644cb Fix issue with emojis next to hashtags and urls
Treat utf8 bytes next to hashtags and urls as boundary conditions

Changelog-Fixed: Fix issue with emojis next to hashtags and urls
2023-07-16 11:46:23 -07:00
William Casarin
8d14fdffb5 content: add utf8 char at url left boundary test 2023-07-16 11:46:23 -07:00
William Casarin
0c95071de7 project: rename parse_mentions to parse_note_content
This is more accurate
2023-07-16 11:46:23 -07:00
William Casarin
da78a217a3 docs: clarify the section on using -v2,v3, etc
Some patches are still not getting sent with version information. Let's
clarify that in the contribution docs.

Cc: dev@damus.io
2023-07-16 10:05:57 -07:00
William Casarin
f53b824122 docs: patch changelogs when submitting patches
This adds a section on creating patch changelogs when submitting
patches. It helps reviewers know what changed between many different
versions of a patch
2023-07-16 09:44:27 -07:00
Bryan Montz
45ab394b09 fixed: relay detail view is not immediately available after adding new relay
Changelog-Fixed: relay detail view is not immediately available after adding new relay
Closes: https://github.com/damus-io/damus/issues/1369
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-16 07:56:18 -07:00
Bryan Montz
47e7505573 fix typos
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-16 07:37:55 -07:00
Bryan Montz
0f1390f412 Swift cleanup: remove duplicate or unnecessary initializers using default values
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-16 07:37:55 -07:00
Bryan Montz
6bf5293701 Swift cleanup: don't capture case values only to ignore them in switch statements
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-16 07:37:55 -07:00
Bryan Montz
3d6909bf62 Swift cleanup: simplify "Task.init {}" to "Task {}"
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-16 07:37:55 -07:00
Bryan Montz
ecd8b64b8b Swift cleanup: prefer case list over fallthrough in switch statements
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-16 07:37:55 -07:00
Bryan Montz
0c627ae0a0 Swift cleanup: "init (" -> "init("
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-16 07:37:55 -07:00
William Casarin
16c86c1d1c update bad commit mailmap 2023-07-14 22:25:19 -07:00
Daniel D'Aquino' via patches
29140d956b Add feedback message when user adds a relay already in the list
Changelog-Added: Added feedback when user adds a relay that is already on the list
Closes: https://github.com/damus-io/damus/issues/1053
Signed-off-by: Daniel D'Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-14 22:11:34 -07:00
William Casarin
7ae7584135 ui: remove nip05 badge on events
Changelog-Changed: Remove nip05 on events
2023-07-14 17:31:28 -07:00
William Casarin
139be9eef2 Fix nostr: mention prefix bugs
The zero-width space was causing parsing issues. Not sure why we need
this so I just removed it.

Changelog-Fixed: Fix nostr:nostr:... bugs
2023-07-14 17:28:24 -07:00
William Casarin
72a060c7b3 nip05: rename nip05 to Nostr Address in search
Forgot this one
2023-07-14 17:05:01 -07:00
William Casarin
9db81fd6b8 views: refactor post_changed in PostView
Use some helper functions instead of the full switch
2023-07-14 15:54:17 -07:00
William Casarin
f08efd7e30 nip05: rename nip05 verification to nostr address
nip05 identifiers and nip05 verification is too confusing, and also
wrong. Let's use the "nostr address" terminology.

Suggested-by: Derek Ross
Suggested-by: Semisol <hi@semisol.dev>
Changelog-Changed: Rename NIP05 to "nostr address"
2023-07-14 13:26:10 -07:00
William Casarin
fb2a69acd8 project: fix test fixtures 2023-07-14 13:07:52 -07:00
8a9e3ea76b Fix localization issues and export strings for translation
Changelog-Fixed: Fix localization issues and export strings for translation
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-14 09:34:29 -07:00
William Casarin
4830a6f3b7 Run actions on pushes to the ci branch 2023-07-14 09:34:29 -07:00
William Casarin
9879c78e41 build 5 because I broked something 2023-07-13 15:43:21 -07:00
William Casarin
05e73a3711 actually subscribe to likes. oops 2023-07-13 11:43:52 -07:00
William Casarin
731fdb108b build: fix a few warnings and errors 2023-07-13 11:17:00 -07:00
William Casarin
2f3737c2b5 v1.6-4 changelog 2023-07-13 11:14:29 -07:00
William Casarin
e36747a81a v1.6 (4) 2023-07-13 11:13:50 -07:00
William Casarin
505ce0bd39 Add the ability to follow hashtags
Changelog-Added: Add the ability to follow hashtags
2023-07-13 11:10:53 -07:00
William Casarin
31fa63debf home: hide users and hashtags from home timeline when you unfollow
Add the ability to resubscribe to home filters so that it will be
updated when you follow and unfollow people

Changelog-Fixed: Hide users and hashtags from home timeline when you unfollow
2023-07-13 11:08:09 -07:00
William Casarin
122655bea3 home: separate home filters
we will want to resubscribe to these, so pull them out
2023-07-13 11:08:09 -07:00
William Casarin
9a714943fd contacts: get followed hashtags function
todo: cache these
2023-07-13 11:08:09 -07:00
William Casarin
17df2972d9 ui: add follow hashtag ui on search view 2023-07-13 11:08:04 -07:00
William Casarin
bebaffd247 contacts: unify following logic
We are about to add hashtag following, so let's prepare handle_follow
for this. Generalize pubkey following to ReferenceId follows in the
handle_{follow,unfollow} functions.

We also split out the notification part into its own function.
2023-07-13 09:32:42 -07:00
William Casarin
0fae54a98d components: make GradientButtonStyle padding configurable
There is too much padding on the follow hashtag button so we need to fix
that
2023-07-13 09:04:55 -07:00
William Casarin
90818c12e8 components: create PinkGradientView and use PinkGradient directly
Still need to do this for the other gradients as well but this is fine
for now.
2023-07-13 09:04:55 -07:00
William Casarin
1136808afa contacts: generalize following to allow any reference
I noticed we are not using the PostBox when following new users. Not
good! This is probably why following users sometimes does not work.

Changelog-Fixed: Fixed a bug where following a user might not work due to poor connectivity
2023-07-13 09:04:55 -07:00
William Casarin
b7d139ffb3 refid: add .t helper
This is used for quickly creating hashtag refs
2023-07-13 09:04:55 -07:00
William Casarin
7fc270725f test: add newline mention test
This is currently passing but it shouldn't be. This is because we are
not testing the build_post function directly. We will do this soon.
2023-07-13 07:32:27 -07:00
William Casarin
7b73a54de5 test: switch to test data file
We only added the file before, let's actually use it now
2023-07-13 07:32:27 -07:00
Bryan Montz
fdaf785869 fixed: icon color for developer mode setting is incorrect in low-light mode
Changelog-Fixed: icon color for developer mode setting is incorrect in low-light mode
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-13 07:24:44 -07:00
William Casarin
c0f9b0a8c0 views: allow embeddable views at top of timeline
This allows you to put stuff at the top of a timeline inside the scroll
view. We could also remove the scrollview from the timeline
eventually... but this works for now.
2023-07-13 06:56:23 -07:00
William Casarin
7123b225a1 search: make model an ObjservedObject
This should not be a state object because the data is passed in
elsewhere
2023-07-13 06:56:23 -07:00
William Casarin
b6f25a85f8 Fix nip05 badge icon 2023-07-13 06:56:23 -07:00
William Casarin
7046fe0d4f ui: add DamusBackground helper
We will be using this in more places
2023-07-13 06:56:23 -07:00
William Casarin
201e9a427f post: extract build_post from post view
I need to test this function because there is a bug with nostr: mentions
2023-07-13 06:56:23 -07:00
William Casarin
6481f96488 add bech32_pubkey_decode
I need this for a test
2023-07-13 06:56:23 -07:00
William Casarin
3845d32074 test: add test data file
We can organize test data in here
2023-07-13 06:56:23 -07:00
William Casarin
c1c33518ea don't follow jb55 by default
This was funny initially but it confuses people.

Changelog-Removed: Remove following Damus Will by default
2023-07-12 14:42:23 -07:00
William Casarin
f2cf30a728 Scroll to top for longform events only
Fixes: ad6a1962 ("Scroll to top of event instead of bottom")
2023-07-12 08:23:53 -07:00
William Casarin
69922b1d77 Remove LoadMoreButton
Was an old unused thing
2023-07-12 08:21:44 -07:00
William Casarin
7343fcd399 Allow longform content to be long
Changelog-Changed: Remove note size restriction for longform events
2023-07-12 05:38:48 -07:00
ericholguin
5571052cfd Update nav to use adaptable color for dark and light modes
Changelog-Fixed: Fixed nav bar color on login, eula, and account creation
Closes: https://github.com/damus-io/damus/pull/1361
2023-07-12 05:38:10 -07:00
William Casarin
de63e96664 v1.6-3 changelog
A few longform fixes
2023-07-11 12:59:09 -07:00
William Casarin
7f9371d85f v1.6 (3) 2023-07-11 12:58:15 -07:00
William Casarin
de4e8e5748 Only show longform preview in notifications
Changelog-Fixed: Show longform previews in notifications instead of the entire post
2023-07-11 12:56:30 -07:00
William Casarin
ad6a1962bb Scroll to top of event instead of bottom
This is pretty important for longform events

Changelog-Changed: Start at top when reading longform events
2023-07-11 12:55:54 -07:00
William Casarin
828e417726 Allow reposting and quote reposting multiple times
Changelog-Changed: Allow reposting and quote reposting multiple times
2023-07-11 12:28:38 -07:00
William Casarin
d2374aa6ec I broked dms. i fixed. 2023-07-11 12:28:38 -07:00
William Casarin
495859e07f Fix various padding issues related to longform posts
1. Make a proper threaded EventShell variant
2. Fix padding everywhere

Changelog-Fixed: Fix padding on longform events
2023-07-11 12:17:59 -07:00
William Casarin
d96ea593a5 search: allow searching longform articles by hashtag 2023-07-11 12:17:22 -07:00
William Casarin
7514a741c0 docs: make note to replace old bech32 parser 2023-07-11 12:17:09 -07:00
William Casarin
dc7b0004bc Hide action bar in longform quote reposts
Changelog-Fixed: Fix action bar appearing on quoted longform previews
2023-07-11 10:26:29 -07:00
William Casarin
8e33d5f6b9 v1.6-2 changelog 2023-07-11 09:22:39 -07:00
William Casarin
db2ec0a00a Fix npub mention bugs, fix slowness when parsing large posts
Switch the post parser to use the same code as the content parser. This
was causing many issues, including performance issues.

Changelog-Fixed: Fix lag when creating large posts
Changelog-Fixed: Fix npub mentions failing to parse in some cases
Changelog-Added: Add r tag when mentioning a url
Changelog-Removed: Remove old @ and & hex key mentions
2023-07-11 09:15:13 -07:00
cr0bar
dc21b6139c Add support for multilingual hashtags
Changelog-Added: Add support for multilingual hashtags
Reviewed-by: William Casarin <jb55@jb55.com>
Closes: https://github.com/damus-io/damus/issues/949
2023-07-11 07:22:44 -07:00
William Casarin
031c7823ae refactor: move hashtag tests to their own file 2023-07-11 07:21:16 -07:00
cr0bar
ac2b5b26bb Added non-latin test and amended emoji test to include emoji in hashtag 2023-07-11 06:39:12 -07:00
cr0bar
c1220f50af Handle percent encoding of colon for some hashtags 2023-07-11 06:39:12 -07:00
cr0bar
2353f97114 Change to is_hashtag_chat to support non-latin characters 2023-07-11 06:39:12 -07:00
cr0bar
e83e110adb Fix to is_boundary to support non-latin characters 2023-07-11 06:39:12 -07:00
William Casarin
aae97c5cb7 git: add .mailmap file
This ensures that author emails are correct when using various git tools
2023-07-11 06:39:05 -07:00
William Casarin
45d9121ed7 fix project issues 2023-07-10 20:56:52 -07:00
4c774f2dda Fix PostView initial string to skip mentioning self when on own profile
Changelog-Fixed: Fix PostView initial string to skip mentioning self when on own profile
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
2023-07-10 20:16:18 -07:00
b8ec3493dc Fix freezing bug when tapping Developer settings menu
Changelog-Fixed: Fix freezing bug when tapping Developer settings menu
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
2023-07-10 20:16:18 -07:00
William Casarin
e299389866 Add initial longform note support
Changelog-Added: Add initial longform note support
2023-07-10 18:29:18 -07:00
William Casarin
374610a21a artifacts: allow unseparated note artifacts
This is needed for longform events. Right now we treat unseparated note
artifacts as a list of blocks, but we will likely need to render these
blocks into lists of attributed texts with image blocks inbetween.
2023-07-10 18:24:43 -07:00
William Casarin
4d995fd04c Longform Notes 2023-07-10 17:39:13 -07:00
William Casarin
518886912c refactor: carve out TextEvent body into EventShell
We'll need this for other event types
2023-07-10 17:39:13 -07:00
William Casarin
ab5eea330a options: add no_mentions to event view options
We don't need mentions in longform previews so we'll need this
2023-07-10 17:39:13 -07:00
William Casarin
41de715067 query: add longform kind, add to home filter 2023-07-10 17:39:13 -07:00
William Casarin
6ca9bda01e notes: count words in notes during artifact parsing 2023-07-10 17:39:13 -07:00
William Casarin
fe077fa5c2 reposts: don't always show text events in reposts
This will allow longform reposts to work properly

Changelog-Fixed: Don't always show text events in reposts
2023-07-10 17:39:13 -07:00
William Casarin
cb2380e218 docs: add git-contacts example
git-contacts is a great way to cc people who have touched the same hunk
of code before.

Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-10 17:38:54 -07:00
Joel Klabo
196cfdec4b Fix Image Orientation 2023-07-10 17:27:51 -07:00
Joel Klabo
bfb47c0f85 Update Control Style to Stand Out More 2023-07-10 17:27:51 -07:00
Joel Klabo
9e7e128d9a Refactoring Edit Picture Views 2023-07-10 17:27:51 -07:00
Joel Klabo
bf95a8b328 Banner Image Upload
Changelog-Added: Enable banner image editing
2023-07-10 17:27:42 -07:00
William Casarin
e316d5d635 docs: move security.md to docs subdir 2023-07-10 16:37:45 -07:00
William Casarin
37a5abc9e3 gitignore: add tags 2023-07-10 16:35:43 -07:00
William Casarin
cf83ac1fe8 docs: add patch submission guidelines 2023-07-10 16:22:09 -07:00
cr0bar
7a1269bd68 Fix for test issue due to recently implemented RelayPool change 2023-07-10 13:49:07 -07:00
William Casarin
acb4e6d17e wasm: fix intptr warning 2023-07-10 11:14:03 -07:00
William Casarin
e957c3b703 wasm: fix clz64 warning 2023-07-10 11:14:03 -07:00
William Casarin
82fc4ff15e wasm: comment out some unnused code for now
fixes some warnings
2023-07-10 11:14:03 -07:00
William Casarin
15d633a42f project: update to recommend settings 2023-07-10 11:08:20 -07:00
William Casarin
7158f07bb1 Translate all the things 2023-07-10 08:20:28 -07:00
Bryan Montz
07abc5c04b Fix issue where first row is always selected on Form views
Changlog-Fixed: Fix issue where first row is always selected on Form views
Signed-off-by: Bryan Montz <bryanmontz@me.com>
2023-07-10 07:54:47 -07:00
transifex-integration[bot]
79fb352d96 Translate Localizable.strings in el_GR
100% translated source file: 'Localizable.strings'
on 'el_GR'.
2023-07-10 08:46:21 +00:00
transifex-integration[bot]
94ef9bb42a Translate Localizable.strings in el_GR
100% translated source file: 'Localizable.strings'
on 'el_GR'.
2023-07-10 08:46:09 +00:00
transifex-integration[bot]
78a64165e1 Translate Localizable.stringsdict in el_GR
100% translated source file: 'Localizable.stringsdict'
on 'el_GR'.
2023-07-10 08:43:55 +00:00
transifex-integration[bot]
ad216b1f11 Translate Localizable.strings in nl
100% translated source file: 'Localizable.strings'
on 'nl'.
2023-07-10 08:35:54 +00:00
transifex-integration[bot]
4abd227cf7 Translate Localizable.stringsdict in nl
100% translated source file: 'Localizable.stringsdict'
on 'nl'.
2023-07-10 08:35:46 +00:00
transifex-integration[bot]
800ce44f5e Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2023-07-10 08:12:11 +00:00
transifex-integration[bot]
0e9e44d8f2 Translate Localizable.stringsdict in ja
100% translated source file: 'Localizable.stringsdict'
on 'ja'.
2023-07-10 07:51:47 +00:00
transifex-integration[bot]
3eba4b0af9 Translate Localizable.strings in ja
100% translated source file: 'Localizable.strings'
on 'ja'.
2023-07-10 07:51:06 +00:00
140c3505ba Update translations 2023-07-09 15:36:35 -04:00
fcd7d2beab Fix localization issues and export strings for translation 2023-07-09 15:33:15 -04:00
William Casarin
83ef50586a zaps/refactor: use guard instead of if block
not a fan of unncessary nesting
2023-07-09 07:44:33 -07:00
William Casarin
87992f4bb9 Add RelayLog in developer mode
Changelog-Added: Add relay log in developer mode
2023-07-09 07:41:45 -07:00
Bryan Montz
faaa3e3bd9 only show the relay log in developer mode
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
Bryan Montz
2d9f7128ee fix crash when adding line to log from background thread
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
Bryan Montz
51d71f11c1 replace RelayMetadatas with RelayModelCache in DamusState
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
Bryan Montz
f619fef410 add RelayModel and RelayModelCache classes
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
Bryan Montz
91f02ccff5 add RelayLog to the bottom of the RelayDetailView
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
Bryan Montz
a63ea1e22b add network state changes to RelayLogs
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
Bryan Montz
40e5e4a026 add a RelayLog to each RelayConnection and send events to it
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
Bryan Montz
ef4aeb40e0 add RelayLog class
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-09 07:40:39 -07:00
William Casarin
13f98659a4 Prevent forged profile zap attacks
The fake note zap attack made me realize that there is a way to do fake
profile zaps using a similar technique. Since damus only checks the
first ptag if it is a profile zap, this means you could include multiple
ptags, the first one being the fake profile with the fake zapper, and
the second p tag as the real target.

This would allow a fake zapper to create a fake a zap, while the zap
notification would still appear for the second ptag because damus
listens for zap events via #p, and that would match the second ptag.

To fix this, ensure that zaps only have at most 1 ptag and 0 or 1 etag.
my CLN zapper checks this but if we don't check this here as well then
we run into fake zap issues.

Changelog-Fixed: Fix potential fake profile zap attacks
Cc: Tony Giorgio <tonygiorgio@protonmail.com>
Cc: benthecarman <benthecarman@live.com>
Cc: Vitor Pamplona <vitor@vitorpamplona.com>
2023-07-08 22:10:34 -07:00
William Casarin
f5ba909784 zaps: move pubkey check into standalone function 2023-07-08 22:09:30 -07:00
William Casarin
6031fe0847 Fix fake note zaps with forged p-tags
This fixes a zap issue where someone could send a fake zap with a zapper
that doesn't match the user's nostrPubkey zapper. This is possible
because damus looks up the zapper via the ptag on note zaps.

Fix this by first looking up the cached event's ptag instead. This
prevents zappers from trying to trick Damus into picking the wrong
zapper.

Fixes: #1357
Changelog-Fixed: Fix issue where malicious zappers can send fake zaps to another user's posts
Reported-by: benthecarman <benthecarman@live.com>
Cc: Tony Giorgio <tonygiorgio@protonmail.com>
2023-07-08 21:22:58 -07:00
William Casarin
1be2a9e1b1 ui: remove invalid zap text 2023-07-08 20:47:11 -07:00
cr0bar
4478348d10 Fix profile post button mentions
Fix for second part of issue #1352 where if you submit a reply from the
+ on a profile, it uses the hex nostr url rather than the bech32
version. When typing the @ manually it uses the bech32 so updated to
mirror this.

Changelog-Fixed: Fix profile post button mentions
Closes: #1355
2023-07-08 19:24:35 -07:00
Anthony de Broise
cf4131f867 Minor update to ConfigView.swift to fix key and search icon
Replaced icon names with names existing in assets to avoid them being left blank.

Changelog-Fixed: Fix icons on settings view
Closes: #1353
2023-07-08 08:14:26 -07:00
Bryan Montz
81b69bc2ea add explanatory footer to Developer Mode setting view
Signed-off-by: Bryan Montz <bryanmontz@me.com>
Reviewed-by: William Casarin <jb55@jb55.com>
2023-07-08 08:06:52 -07:00
William Casarin
0c736a18a9 docs: annotate might be causing issues for some people
suhail was having trouble when this option was enabled. let's remove it
just in case.
2023-07-07 09:25:33 -07:00
Bryan Montz
d2efe06610 make "Copy Note JSON" a developer mode setting
Signed-off-by: Bryan Montz <bryanmontz@me.com>
2023-07-07 09:02:52 -07:00
Bryan Montz
ebcfe3c25f add developer mode view and setting
Signed-off-by: Bryan Montz <bryanmontz@me.com>
2023-07-07 09:02:52 -07:00
William Casarin
6dfda93ff9 Fix Invalid Zap bug in reposts
Changelog-Fixed: Fix Invalid Zap bug in reposts
2023-07-04 13:48:49 -07:00
William Casarin
ea50f9214a Switch to navigation stack in BuilderEventView 2023-07-04 13:48:49 -07:00
William Casarin
6c8cf8421c zaps: make zap setting private 2023-07-04 13:47:44 -07:00
Ben Harvie
cbbe203d84 Create SECURITY.md 2023-07-04 12:45:15 -07:00
William Casarin
19217f47a4 v1.6 changelog 2023-07-04 12:21:12 -07:00
William Casarin
3451e7d88f v1.6 2023-07-04 12:18:33 -07:00
William Casarin
b5ea1e011e Revert "profile: make profile loading more lightweight for now"
Changelog-Fixed: Load more content on profile view
2023-07-04 11:51:07 -07:00
William Casarin
a04a401292 nscript: load script view
This allows you to open and run scripts for testing purposes, but only
from external links such as nostr:nscript...
2023-07-04 11:48:27 -07:00
640fbf23ea Fix UI bug with user search and fix race conditions on profiles NIP-05 cache
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-04 09:09:14 -07:00
William Casarin
3d0448a929 smaller nostrscript 2023-07-03 17:10:57 -07:00
William Casarin
30e33a01c1 nostrscript: add a helper function 2023-07-03 16:59:50 -07:00
William Casarin
a6cbf50def settings: record bool option keys
so that NostrScripts know which bool settings can be set
2023-07-03 16:28:25 -07:00
prprhyt
94bd194287 Added event id validation 2023-07-03 15:03:33 -07:00
William Casarin
97f10e865f NostrScript
NostrScript is a WebAssembly implementation that interacts with Damus.
It enables dynamic scripting that can be used to power custom list views,
enabling pluggable algorithms.

The web has JavaScript, Damus has NostrScript. NostrScripts can be
written in any language that compiles to WASM.

This commit adds a WASM interpreter I've written as a mostly-single C
file for portability and embeddability. In the future we could
JIT-compile these for optimal performance if NostrScripts get large and
complicated. For now an interpreter is simple enough for algorithm list
view plugins.

Changelog-Added: Add initial NostrScript implementation
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-03 14:31:38 -07:00
0c0c58c0cc Fix bug with Trie search
Exact matches were not being returned first in the array of results

Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
2023-07-03 13:37:52 -07:00
William Casarin
7d49d3d9f1 refactor: make guard statement a bit more readible
It's a bit confusing to guard on a negative boolean expression
2023-07-03 12:48:25 -07:00
cb1e16b1a4 Fix reports to conform to NIP-56
Changelog-Fixed: Fix reports to conform to NIP-56
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Tested-by: William Casarin <jb55@jb55.com>
2023-07-03 12:25:12 -07:00
6e964f71ff Add trie-based user search cache to replace non-performant linear scans
Changelog-Added: Speed up user search
Tested-by: William Casarin <jb55@jb55.com>
Fixes: #1219
Closes: #1342
2023-07-03 12:06:01 -07:00
4b7444f338 Fix profile navigation bugs from muted users list and relay list views
Changelog-Fixed: Fix profile navigation bugs from muted users list and relay list views
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
2023-07-03 08:59:28 -07:00
57159f7df9 Fix build warnings
Signed-off-by: Terry Yiu <git@tyiu.xyz>
Reviewed-by: William Casarin <jb55@jb55.com>
2023-07-03 08:50:17 -07:00
4712c6b288 Fix navigation to translation settings view
Changelog-Fixed: Fix navigation to translation settings view
Signed-off-by: Terry Yiu <git@tyiu.xyz>
2023-07-03 08:25:04 -07:00
922 changed files with 117633 additions and 13156 deletions

2
.envrc
View File

@@ -1,4 +1,4 @@
#use nix
use nix
export TODO_FILE=$PWD/TODO

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_

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve
title: 'Bug: '
labels: bug, Needs recreation
assignees: ''
---
**What happens**
When I perform action ___, _____ happens.
**What I expect to happen**
I expect _______ to happen.
**Link to noteID, npub**
Provide link to relevant noteID, npub etc.
**Screenshots/video recording**
If applicable, add screenshots to help explain your problem.
** Versions **
Damus version: [e.g. 1.7.2 (1()]
Operating system version: [e.g. iOS 17.2.1]
Device: e.g. iPhone 13 Pro
**Steps To Reproduce**
Steps to reproduce the behavior:
1. Open Damus
2. Tap on ___
3. Action ____
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,27 @@
---
name: Feature request
about: Suggest an idea for this project
title: 'Feature Request:'
labels: feature
assignees: ''
---
## Have a go at filling out the User Story template below
As a Damus user who is _____________, I would like to _________________, so that I achieve ___________.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
** When does this problem happen? **
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request 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.]_

View File

@@ -1,31 +0,0 @@
name: Run Test Suite
run-name: Testing ${{ github.ref }} by @${{ github.actor }}
on:
push:
branches:
- "master"
pull_request:
branches:
- "*"
jobs:
run_tests:
runs-on: macos-12
strategy:
matrix:
include:
- xcode: "14.2"
ios: "16.2"
name: Test iOS (${{ matrix.ios }})
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Select Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode }}
- name: Run Tests
run: xcodebuild test -scheme damus -project damus.xcodeproj -destination 'platform=iOS Simulator,name=iPhone 14,OS=${{ matrix.ios }}' | xcpretty && exit ${PIPESTATUS[0]}

3
.gitignore vendored
View File

@@ -1,5 +1,8 @@
xcuserdata
/.direnv
damus/TestingPrivate.swift
damus.xcodeproj/xcshareddata/xcbaselines
.DS_Store
TODO.bak
tags
build-git-hash.txt

7
.mailmap Normal file
View File

@@ -0,0 +1,7 @@
Terry Yiu <git@tyiu.xyz> <963907+tyiu@users.noreply.github.com>
Ben Weeks <ben.weeks@knowall.ai> <ben.weeks@outlook.com>
Suhail Saqan <suhail.saqan@gmail.com> <43693074+suhailsaqan@users.noreply.github.com>
cr0bar <cr0bar@cr0.bar> <cr0bar@users.noreply.github.com>
Swift <scoder1747@gmail.com> <120697811+scoder1747@users.noreply.github.com>
Daniel D'Aquino <daniel@daquino.me> <patches@damus.io>
Transifex <transifex@transifex.com> <43880903+transifex-integration[bot]@users.noreply.github.com>

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,759 @@
## [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
- Add support for Apple In-App purchases (Daniel DAquino)
- Notification reminders for Damus Purple impending expiration (Daniel DAquino)
- Damus Purple membership! (William Casarin)
- Fixed minor spacing and padding issues in onboarding views (ericholguin)
### Changed
- Disable inline text suggestions on 17.0 as they interfere with mention generation (William Casarin)
- EULA is not shown by default (ericholguin)
### Fixed
- Fix welcome screen not showing if the user enters the app directly after a successful checkout without going through the link (Daniel DAquino)
- Fix profile not updating bug (William Casarin)
- Fix nostrscripts not loading (William Casarin)
- Fix crash when accessing cached purple accounts (William Casarin)
- Hide member signup date on reposts (kernelkind)
- Fixed previews not rendering (ericholguin)
- Fix load media formatting on small screens (kernelkind)
- Fix shared nevents that are too long (kernelkind)
- Fix many nostrdb transaction related crashes (William Casarin)
### Removed
- Removed copying public key action (ericholguin)
[1.7-rc2]: https://github.com/damus-io/damus/releases/tag/v1.7-rc2
## [1.7-2] - 2024-01-24
### Added
- New fulltext search engine (William Casarin)
- Add "Always show onboarding suggestions" developer setting (Daniel DAquino)
- Add NIP-42 relay auth support (Charlie Fish)
- Add ability to hide suggested hashtags (ericholguin)
- Add ability to mute hashtag from SearchView (Charlie Fish)
- Add ability to preview media taken with camera (Suhail Saqan)
- Add ability to search for naddr, nprofiles, nevents (kernelkind)
- Add experimental push notification support (Daniel DAquino)
- Add naddr link support (kernelkind)
- Add regional relay recommendations to Relay configuration view (currently for Japanese users only) (Daniel DAquino)
- Add regional relays for Germany (Daniel DAquino)
- Add regional relays for Thailand (Daniel DAquino)
- Added a custom camera view (Suhail Saqan)
- Always convert damus.io links to inline mentions (William Casarin)
- Unfurl profile name on remote push notifications (Daniel DAquino)
- Zap notification support for push notifications (Daniel DAquino)
### Changed
- Generate nprofile/nevent links in share menus (kernelkind)
- Improve push notification support to match local notification support (Daniel DAquino)
- Move mute thread in menu so it's not clicked by accident (alltheseas)
- Prioritize friends when autocompleting (Charlie Fish)
### Fixed
- Add workaround to fix note language recognition and reduce wasteful translation requests (Terry Yiu)
- Allow mentioning users with punctuation characters in their names (kernelkind)
- Fix broken mentions when there is text is directly after (kernelkind)
- Fix crash on very large notes (Daniel DAquino)
- Fix crash when logging out and switching accounts (William Casarin)
- Fix duplicate notes getting written to nostrdb (William Casarin)
- Fix issue where adding relays might not work on corrupted contact lists (Charlie Fish)
- Fix onboarding post view not being dismissed under certain conditions (Daniel DAquino)
- Fix performance issue with gifs (William Casarin)
- Fix persistent local notifications even after logout (William Casarin)
- Fixed bug where sometimes notes from other profiles appear on profile pages (Charlie Fish)
- Remove extra space at the end of DM messages (kernelkind)
- Save current viewed image index when switching to fullscreen (kernelkind)
### Removed
- Removed old nsec key warning, nsec automatically convert to npub when posting (kernelkind)
[1.7-2]: https://github.com/damus-io/damus/releases/tag/v1.7-2
## [1.6-25] - 2023-10-31
### Added
- Tap to dismiss keyboard on user status view (ericholguin)
- Add setting that allows users to optionally disable the new profile action sheet feature (Daniel DAquino)
- Add follow button to profile action sheet (Daniel DAquino)
- Added reaction counters to nostrdb (William Casarin)
- Record when profile is last fetched in nostrdb (William Casarin)
### Changed
- Automatically load extra regional Japanese relays during account creation if user's region is set to Japan. (Daniel DAquino)
- Updated customize zap view (ericholguin)
- Users are now notified when you quote repost them (William Casarin)
- Save bandwidth by only fetching new profiles after a certain amount of time (William Casarin)
- Zap button on profile action sheet now zaps with a single click, while a long press brings custom zap view (Daniel DAquino)
### Fixed
- Use white font color in qrcode view (ericholguin)
- Fixed an issue where zapping would silently fail on default settings if the user does not have a lightning wallet preinstalled on their device. (Daniel DAquino)
[1.6-25]: https://github.com/damus-io/damus/releases/tag/v1.6-25
## [1.6-24] - 2023-10-22 - AppStore Rejection Cope
### Added
- Improve discoverability of profile zaps with zappability badges and profile action sheets (Daniel DAquino)
- Add suggested hashtags to universe view (Daniel DAquino)
- Suggest first post during onboarding (Daniel DAquino)
- Add expiry date for images in cache to be auto-deleted after a preset time to save space on storage (Daniel DAquino)
- Add QR scan nsec logins. (Jericho Hasselbush)
### Changed
- Improved status view design (ericholguin)
- Improve clear cache functionality (Daniel DAquino)
### Fixed
- Reduce size of event menu hitbox (William Casarin)
- Do not show DMs from muted users (Daniel DAquino)
- Add more spacing between display name and username, and prefix username with `@` character (Daniel DAquino)
- Broadcast quoted notes when posting a note with quotes (Daniel DAquino)
[1.6-24]: https://github.com/damus-io/damus/releases/tag/v1.6-24
## [1.6-23] - 2023-10-06 - Appstore Release
### Added
- Added merch store button to sidebar menu (Daniel DAquino)
### Changed
- Damus icon now opens sidebar (Daniel DAquino)
### Fixed
- Stop tab buttons from causing the root view to scroll to the top unless user is coming from another tab or already at the root view (Daniel DAquino)
- Fix profiles not updating (William Casarin)
- Fix issue where relays with trailing slashes cannot be removed (#1531) (Daniel DAquino)
[1.6-23]: https://github.com/damus-io/damus/releases/tag/v1.6-23
## [1.6-20] - 2023-10-04
### Changed
- Improve UX around clearing cache (Daniel DAquino)
- Show muted thread replies at the bottom of the thread view (#1522) (Daniel DAquino)
### Fixed
- Fix situations where the note composer cursor gets stuck in one place after tagging a user (Daniel DAquino)
- Fix some note composer issues, such as when copying/pasting larger text, and make the post composer more robust. (Daniel DAquino)
- Apply filters to hashtag search timeline view (Daniel DAquino)
- Hide quoted or reposted notes from people whom the user has muted. (#1216) (Daniel DAquino)
- Fix profile not updating (William Casarin)
- Fix small graphical toolbar bug when scrolling profiles (Daniel DAquino)
- Fix localization issues and export strings for translation (Terry Yiu)
[1.6-20]: https://github.com/damus-io/damus/releases/tag/v1.6-20
## [1.6-18] - 2023-09-21
### Added
- Add followed hashtags to your following list (Daniel DAquino)
- Add "Do not show #nsfw tagged posts" setting (Daniel DAquino)
- Hold tap to preview status URL (Jericho Hasselbush)
- Finnish translations (etrikaj)
### Changed
- Switch to nostrdb for @'s and user search (William Casarin)
- Use nostrdb for profiles (William Casarin)
- Updated relay view (ericholguin)
- Increase size of the hitbox on note ellipsis button (Daniel DAquino)
- Make carousel tab dots tappable (Bryan Montz)
- Move the "Follow you" badge into the profile header (Grimless)
### Fixed
- Fix text composer wrapping issue when mentioning npub (Daniel DAquino)
- Make blurred videos viewable by allowing blur to disappear once tapped (Daniel DAquino)
- Fix parsing issue with NIP-47 compliant NWC urls without double-slashes (Daniel DAquino)
- Fix padding of username next to pfp on some views (William Casarin)
- Fixes issue where username with multiple emojis would place cursor in strange position. (Jericho Hasselbush)
- Fixed audio in video playing twice (Bryan Montz)
- Fix crash when long pressing custom reactions (William Casarin)
- Fix random crashom due to old profile database (William Casarin)
[1.6-18]: https://github.com/damus-io/damus/releases/tag/v1.6-18
## [1.6-17] - 2023-08-23
### Added
- Add support for status URLs (William Casarin)
- Click music statuses to display in spotify (William Casarin)
- Add settings for disabling user statuses (William Casarin)
### Changed
- clear statuses if they only contain whitespace (William Casarin)
### Fixed
- Fix long status lines (William Casarin)
- Fix status events not expiring locally (William Casarin)
[1.6-17]: https://github.com/damus-io/damus/releases/tag/v1.6-17
## [1.6-16] - 2023-08-23
### Added
- Added live music statuses (William Casarin)
- Added generic user statuses (William Casarin)
### Fixed
- Avoid notification for zaps from muted profiles (tappu75e@duck.com)
- Fix text editing issues on characters added right after mention link (Daniel DAquino)
- Mute hellthreads everywhere (William Casarin)
[1.6-16]: https://github.com/damus-io/damus/releases/tag/v1.6-16
## [1.6-13] - 2023-08-18
### Fixed
- Fix bug where it would sometimes show -1 in replies (tappu75e@duck.com)
- Fix images and links occasionally appearing with escaped slashes (Daniel DAquino)
- Fixed nostrscript not working on smaller phones (William Casarin)
- Fix zaps sometimes not appearing (William Casarin)
- Fixed issue where reposts would sometimes repost the wrong thing (William Casarin)
- Fixed issue where sometimes there would be empty entries on your profile (William Casarin)
[1.6-13]: https://github.com/damus-io/damus/releases/tag/v1.6-13
## [1.6-11]: "Bugfix Sunday" - 2023-08-07
### Added
- Add close button to custom reactions (Suhail Saqan)
- Add ability to change order of custom reactions (Suhail Saqan)
- Adjustable font size (William Casarin)
### Changed
- Show renotes in Notes timeline (William Casarin)
### Fixed
- Ensure the person you're replying to is the first entry in the reply description (William Casarin)
- Don't cutoff text in notifications (William Casarin)
- Fix wikipedia url detection with parenthesis (William Casarin)
- Fixed old notifications always appearing on first start (William Casarin)
- Fix issue with slashes on relay urls causing relay connection problems (William Casarin)
- Fix rare crash triggered by local notifications (William Casarin)
- Fix crash when long-pressing reactions (William Casarin)
- Fixed nostr reporting decoding (William Casarin)
- Dismiss qr screen on scan (Suhail Saqan)
- Show QRCameraView regardless of same user (Suhail Saqan)
- Fix wiggle when long press reactions (Suhail Saqan)
- Fix reaction button breaking scrolling (Suhail Saqan)
- Fix crash when muting threads (Bryan Montz)
[1.6-11]: https://github.com/damus-io/damus/releases/tag/v1.6-11
## [1.6-8]: "nostrdb prep" 2023-08-03
### Added
- Suggested Users to Follow (Joel Klabo)
- Add support for multiple reactions (Suhail Saqan)
### Changed
- Improved memory usage and performance when processing events (William Casarin)
### Fixed
- Fixed disappearing text on iOS17 (cr0bar)
- Fix UTF support for hashtags (Daniel DAquino)
- Fix compilation error on test target in UserSearchCacheTests (Daniel DAquino)
- Fix nav crashing and buggyness (William Casarin)
- Allow relay logs to be opened in dev mode even if relay (Daniel D'Aquino)
- endless connection attempt loop after user removes relay (Bryan Montz)
[1.6-8]: https://github.com/damus-io/damus/releases/tag/v1.6-8
## 1.6 (7): "Less bad" - 2023-07-16
### Added
- Show nostr address username and support abbreviated _ usernames (William Casarin)
- Re-add nip05 badges to profiles (William Casarin)
- Add space when tagging users in posts if needed (William Casarin)
- Added padding under word count on longform account (William Casarin)
### Fixed
- Don't spam lnurls when validating zaps (William Casarin)
- Eliminate nostr address validation bandwidth on startup (William Casarin)
- Allow user to login to deleted profile (William Casarin)
- Fix issue where typing cc@bob would produce brokenb ccnostr:bob mention (William Casarin)
[1.6-7]: https://github.com/damus-io/damus/releases/tag/v1.6-7
## [1.6-6] - 2023-07-16
### Added
- New markdown renderer (William Casarin)
- Added feedback when user adds a relay that is already on the list (Daniel D'Aquino)
### Changed
- Hide nsec when logging in (cr0bar)
- Remove nip05 on events (William Casarin)
- Rename NIP05 to "nostr address" (William Casarin)
### Fixed
- Fixed issue where hashtags were leaking in DMs (William Casarin)
- Fix issue with emojis next to hashtags and urls (William Casarin)
- relay detail view is not immediately available after adding new relay (Bryan Montz)
- Fix nostr:nostr:... bugs (William Casarin)
[1.6-6]: https://github.com/damus-io/damus/releases/tag/v1.6-6
## [1.6-4] - 2023-07-13
### Added
- Add the ability to follow hashtags (William Casarin)
### Changed
- Remove note size restriction for longform events (William Casarin)
### Fixed
- Hide users and hashtags from home timeline when you unfollow (William Casarin)
- Fixed a bug where following a user might not work due to poor connectivity (William Casarin)
- Icon color for developer mode setting is incorrect in low-light mode (Bryan Montz)
- Fixed nav bar color on login, eula, and account creation (ericholguin)
### Removed
- Remove following Damus Will by default (William Casarin)
[1.6-4]: https://github.com/damus-io/damus/releases/tag/v1.6-4
## [1.6-3] - 2023-07-11
### Changed
- Start at top when reading longform events (William Casarin)
- Allow reposting and quote reposting multiple times (William Casarin)
### Fixed
- Show longform previews in notifications instead of the entire post (William Casarin)
- Fix padding on longform events (William Casarin)
- Fix action bar appearing on quoted longform previews (William Casarin)
[1.6-3]: https://github.com/damus-io/damus/releases/tag/v1.6-3
## [1.6-2] - 2023-07-11
### Added
- Add support for multilingual hashtags (cr0bar)
- Add r tag when mentioning a url (William Casarin)
- Add initial longform note support (William Casarin)
- Enable banner image editing (Joel Klabo)
- Add relay log in developer mode (Bryan Montz)
### Fixed
- Fix lag when creating large posts (William Casarin)
- Fix npub mentions failing to parse in some cases (William Casarin)
- Fix PostView initial string to skip mentioning self when on own profile (Terry Yiu)
- Fix freezing bug when tapping Developer settings menu (Terry Yiu)
- Fix potential fake profile zap attacks (William Casarin)
- Fix issue where malicious zappers can send fake zaps to another user's posts (William Casarin)
- Fix profile post button mentions (cr0bar)
- Fix icons on settings view (cr0bar)
- Fix Invalid Zap bug in reposts (William Casarin)
### Removed
- Remove old @ and & hex key mentions (William Casarin)
[1.6-2]: https://github.com/damus-io/damus/releases/tag/v1.6-2
## [1.6] - 2023-07-04
### Added
- Speed up user search (Terry Yiu)
- Add post button to profile pages (William Casarin)
- Add post button when logged in with private key and on own profile view (Terry Yiu)
### Changed
- Drop iOS15 support (Scott Penrose)
### Fixed
- Load more content on profile view (William Casarin)
- Fix reports to conform to NIP-56 (Terry Yiu)
- Fix profile navigation bugs from muted users list and relay list views (Terry Yiu)
- Fix navigation to translation settings view (Terry Yiu)
- Fixed all navigation issues (Scott Penrose)
- Disable post button when media upload in progress (Terry Yiu)
- Fix taps on mentions in note drafts to not redirect to other Nostr clients (Terry Yiu)
- Fix missing profile zap notification text (Terry Yiu)
[1.6]: https://github.com/damus-io/damus/releases/tag/v1.6
## [1.5-5] - 2023-06-24
### Fixed
@@ -1279,4 +2035,3 @@
[0.1.2]: https://github.com/damus-io/damus/releases/tag/v0.1.2

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<array>
<string>group.com.damus</string>
</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

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.usernotifications.service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,45 @@
//
// NotificationExtensionState.swift
// DamusNotificationService
//
// Created by Daniel DAquino on 2023-11-27.
//
import Foundation
struct NotificationExtensionState: HeadlessDamusState {
let ndb: Ndb
let settings: UserSettingsStore
let contacts: Contacts
let mutelist_manager: MutelistManager
let keypair: Keypair
let profiles: Profiles
let zaps: Zaps
let lnurls: LNUrls
init?() {
guard let ndb = Ndb(owns_db_file: false) else { return nil }
self.ndb = ndb
guard let keypair = get_saved_keypair() else { return nil }
// dumb stuff needed for property wrappers
UserSettingsStore.pubkey = keypair.pubkey
self.settings = UserSettingsStore()
self.contacts = Contacts(our_pubkey: keypair.pubkey)
self.mutelist_manager = MutelistManager(user_keypair: keypair)
self.keypair = keypair
self.profiles = Profiles(ndb: ndb)
self.zaps = Zaps(our_pubkey: keypair.pubkey)
self.lnurls = LNUrls()
}
@discardableResult
func add_zap(zap: Zapping) -> Bool {
// store generic zap mapping
self.zaps.add_zap(zap: zap)
return true
}
}

View File

@@ -0,0 +1,143 @@
//
// NotificationFormatter.swift
// DamusNotificationService
//
// Created by Daniel DAquino on 2023-11-13.
//
import Foundation
import UserNotifications
struct NotificationFormatter {
static var shared = NotificationFormatter()
// MARK: - Formatting with NdbNote
func format_message(event: NdbNote) -> UNMutableNotificationContent? {
let content = UNMutableNotificationContent()
if let event_json_data = try? JSONEncoder().encode(event), // Must be encoded, as the notification completion handler requires this object to conform to `NSSecureCoding`
let event_json_string = String(data: event_json_data, encoding: .utf8) {
content.userInfo = [
NDB_NOTE_JSON_USER_INFO_KEY: event_json_string
]
}
switch event.known_kind {
case .text:
content.title = NSLocalizedString("Someone posted a note", comment: "Title label for push notification where someone posted a note")
content.body = event.content
break
case .dm:
content.title = NSLocalizedString("New message", comment: "Title label for push notifications where a direct message was sent to the user")
content.body = NSLocalizedString("(Contents are encrypted)", comment: "Label on push notification indicating that the contents of the message are encrypted")
break
case .like:
guard let reactionEmoji = to_reaction_emoji(ev: event) else {
content.title = NSLocalizedString("Someone reacted to your note", comment: "Generic title label for push notifications where someone reacted to the user's post")
break
}
content.title = NSLocalizedString("New note reaction", comment: "Title label for push notifications where someone reacted to the user's post with a specific emoji")
content.body = String(format: NSLocalizedString("Someone reacted to your note with %@", comment: "Body label for push notifications where someone reacted to the user's post with a specific emoji"), reactionEmoji)
break
case .zap:
content.title = NSLocalizedString("Someone zapped you ⚡️", comment: "Title label for a push notification where someone zapped the user")
break
default:
return nil
}
return content
}
// MARK: - Formatting with LocalNotification
func format_message(displayName: String, notify: LocalNotification) -> (content: UNMutableNotificationContent, identifier: String)? {
let content = UNMutableNotificationContent()
var title = ""
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"
case .repost:
title = String(format: NSLocalizedString("Reposted by %@", comment: "Reposted by heading in local notification"), displayName)
identifier = "myBoostNotification"
case .like:
title = String(format: NSLocalizedString("%@ reacted with %@", comment: "Reacted by heading in local notification"), displayName, to_reaction_emoji(ev: notify.event) ?? "")
identifier = "myLikeNotification"
case .dm:
title = displayName
identifier = "myDMNotification"
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
content.sound = UNNotificationSound.default
content.userInfo = notify.to_lossy().to_user_info()
return (content, identifier)
}
func format_message(displayName: String, notify: LocalNotification, state: HeadlessDamusState) async -> (content: UNMutableNotificationContent, identifier: String)? {
// Try sync method first and return if it works
if let sync_formatted_message = self.format_message(displayName: displayName, notify: notify) {
return sync_formatted_message
}
// 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()
return (content, "myZapNotification")
default:
// The sync method should have taken care of this.
return nil
}
}
// MARK: - Formatting zap utility notifications
static func zap_notification_title(_ zap: Zap) -> String {
if zap.private_request != nil {
return NSLocalizedString("Private Zap", comment: "Title of notification when a private zap is received.")
} else {
return NSLocalizedString("Zap", comment: "Title of notification when a non-private zap is received.")
}
}
static func zap_notification_body(profiles: Profiles, zap: Zap, locale: Locale = Locale.current) -> String {
let src = zap.request.ev
let pk = zap.is_anon ? ANON_PUBKEY : src.pubkey
let profile_txn = profiles.lookup(id: pk)
let profile = profile_txn?.unsafeUnownedValue
let name = Profile.displayName(profile: profile, pubkey: pk).displayName.truncate(maxLength: 50)
let sats = NSNumber(value: (Double(zap.invoice.amount) / 1000.0))
let formattedSats = format_msats_abbrev(zap.invoice.amount)
if src.content.isEmpty {
let format = localizedStringFormat(key: "zap_notification_no_message", locale: locale)
return String(format: format, locale: locale, sats.decimalValue as NSDecimalNumber, formattedSats, name)
} else {
let format = localizedStringFormat(key: "zap_notification_with_message", locale: locale)
return String(format: format, locale: locale, sats.decimalValue as NSDecimalNumber, formattedSats, name, src.content)
}
}
}

View File

@@ -0,0 +1,323 @@
//
// NotificationService.swift
// DamusNotificationService
//
// 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,
let nostr_event = NdbNote.owned_from_json(json: nostr_event_json)
else {
// No nostr event detected. Just display the original notification
contentHandler(request.content)
return;
}
// 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() 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.
contentHandler(UNNotificationContent())
return
}
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) {
// We cannot really suppress muted notifications until we have the notification supression entitlement.
// The best we can do if we ever get those muted notifications (which we generally won't due to server-side processing) is to obscure the details
let content = UNMutableNotificationContent()
content.title = NSLocalizedString("Muted event", comment: "Title for a push notification which has been muted")
content.body = NSLocalizedString("This is an event that has been muted according to your mute list rules. We cannot suppress this notification, but we obscured the details to respect your preferences", comment: "Description for a push notification which has been muted, and explanation that we cannot suppress it")
content.sound = UNNotificationSound.default
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 {
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 {
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)
}
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
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

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>1C8F.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>

13
Makefile Normal file
View File

@@ -0,0 +1,13 @@
all: nostrscript/primal.wasm
nostrscript/%.wasm: nostrscript/%.ts nostrscript/nostr.ts Makefile
asc $< --runtime stub --outFile $@ --optimize
tags:
find damus-c -name '*.c' -or -name '*.h' | xargs ctags
clean:
rm nostrscript/*.wasm
.PHONY: tags

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"),
]
)

27
PrivacyInfo.xcprivacy Normal file
View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>1C8F.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>

125
Purple.storekit Normal file
View File

@@ -0,0 +1,125 @@
{
"identifier" : "64C21A2D",
"nonRenewingSubscriptions" : [
],
"products" : [
],
"settings" : {
"_applicationInternalID" : "1628663131",
"_developerTeamID" : "XK7H4JAB3D",
"_failTransactionsEnabled" : false,
"_lastSynchronizedDate" : 704848066.26849198,
"_locale" : "en_US",
"_storefront" : "USA",
"_storeKitErrors" : [
{
"current" : null,
"enabled" : false,
"name" : "Load Products"
},
{
"current" : null,
"enabled" : false,
"name" : "Purchase"
},
{
"current" : null,
"enabled" : false,
"name" : "Verification"
},
{
"current" : null,
"enabled" : false,
"name" : "App Store Sync"
},
{
"current" : null,
"enabled" : false,
"name" : "Subscription Status"
},
{
"current" : null,
"enabled" : false,
"name" : "App Transaction"
},
{
"current" : null,
"enabled" : false,
"name" : "Manage Subscriptions Sheet"
},
{
"current" : null,
"enabled" : false,
"name" : "Refund Request Sheet"
},
{
"current" : null,
"enabled" : false,
"name" : "Offer Code Redeem Sheet"
}
]
},
"subscriptionGroups" : [
{
"id" : "21283177",
"localizations" : [
],
"name" : "Purple",
"subscriptions" : [
{
"adHocOffers" : [
],
"codeOffers" : [
],
"displayPrice" : "6.99",
"familyShareable" : false,
"groupNumber" : 1,
"internalID" : "6446591615",
"introductoryOffer" : null,
"localizations" : [
{
"description" : "Support damus development with Damus Purple!",
"displayName" : "Damus Purple",
"locale" : "en_CA"
}
],
"productID" : "purple",
"recurringSubscriptionPeriod" : "P1M",
"referenceName" : "Purple",
"subscriptionGroupID" : "21283177",
"type" : "RecurringSubscription"
},
{
"adHocOffers" : [
],
"codeOffers" : [
],
"displayPrice" : "69.99",
"familyShareable" : false,
"groupNumber" : 2,
"internalID" : "6448764101",
"introductoryOffer" : null,
"localizations" : [
],
"productID" : "purpleyearly",
"recurringSubscriptionPeriod" : "P1Y",
"referenceName" : "Purple Yearly",
"subscriptionGroupID" : "21283177",
"type" : "RecurringSubscription"
}
]
}
],
"version" : {
"major" : 3,
"minor" : 0
}
}

View File

@@ -2,26 +2,56 @@
# damus
A twitter-like [nostr][nostr] client for iPhone, iPad and MacOS.
A twitter-like [nostr][nostr] client for iPhone, iPad and MacOS.
<img src="./ss.png" width="50%" height="50%" />
[nostr]: https://github.com/fiatjaf/nostr
## 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.\
There are no ads.\
You don't have to reveal sensitive personal information to sign up.\
No email is required. \
No phone number is required. \
Damus is free and open source software. \
There is no Big Tech moat. Therefore, seamless interoperability with thousands or millions of other nostr apps is possible, and is how [Damus and nostr win](https://www.youtube.com/watch?v=qTixqS-W1yo).
## If there are no ads, how is Damus funded?
Damus offers a paid subscription 🟣 purple 🟣 https://damus.io/purple/. \
Initial benefits include a unique subscriber number, subscriber badge, and auto-translate powered by DeepL.
Damus has also graciously received donations or grants from hundreds of Damus users, [Opensats](https://opensats.org/), and the [Human Rights Foundation](https://hrf.org/).
## Spec Compliance
damus implements the following [Nostr Implementation Possibilities][nips]
- [NIP-01: Basic protocol flow][nip01]
- [NIP-04: Encrypted direct message][nip04]
- [NIP-08: Mentions][nip08]
- [NIP-10: Reply conventions][nip10]
- [NIP-12: Generic tag queries (hashtags)][nip12]
- [NIP-19: bech32-encoded entities][NIP19]
- [NIP-21: nostr: URI scheme][NIP21]
- [NIP-25: Reactions][NIP25]
- [NIP-42: Authentication of clients to relays][nip42]
- [NIP-56: Reporting][nip56]
[nips]: https://github.com/nostr-protocol/nips
[nip01]: https://github.com/nostr-protocol/nips/blob/master/01.md
[nip04]: https://github.com/nostr-protocol/nips/blob/master/04.md
[nip08]: https://github.com/nostr-protocol/nips/blob/master/08.md
[nip10]: https://github.com/nostr-protocol/nips/blob/master/10.md
[nip12]: https://github.com/nostr-protocol/nips/blob/master/12.md
[nip19]: https://github.com/nostr-protocol/nips/blob/master/19.md
[nip21]: https://github.com/nostr-protocol/nips/blob/master/21.md
[nip25]: https://github.com/nostr-protocol/nips/blob/master/25.md
[nip42]: https://github.com/nostr-protocol/nips/blob/master/42.md
[nip56]: https://github.com/nostr-protocol/nips/blob/master/56.md
## Getting Started on Damus
@@ -32,7 +62,7 @@ damus implements the following [Nostr Implementation Possibilities][nips]
- Relays: You can add more relays to send your notes to by tapping the "+".
- Find more relays to add: https://nostr.info/relays/
- Public Key (pubkey): Your public, personal address and how people can find and tag you
- Secret Key: Your *private* key unique to you. Never share your private key publically and share with other clients at your own risk!
- Secret Key: Your *private* key unique to you. Never share your private key publicly and share with other clients at your own risk!
- Save your keys somewhere safe
- Log out
@@ -46,19 +76,15 @@ damus implements the following [Nostr Implementation Possibilities][nips]
1. Search their username in the search bar at the top of the 🔍 Global Feed and click their profile
2. Tap the 🔑 icon which will copy their pubkey to your clipboard
3. Go back to your 🏠 Personal Feed and tap the blue + button to compose your Note
4. Add @ direcly followed by the pubkey (e.g., `@npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s`)
- You can also long-press a Note to grab their User ID aka pubkey or Note ID to link directly to a Note.
4. Add @ directly followed by the pubkey (e.g., `@npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s`)
- You can also tap the ellipsis menu of a Note (three dots in top right of note) to grab their User ID aka pubkey or Note ID to link directly to a Note.
- Currently you can't delete your Notes in the iOS app
- Share images by pasting the image url which you can grab from imgbb, imgur, etc. (i.e., `https://i.ibb.co/2SHZbwm/alpha60.jpg`). Currently images only load for people you follow in the 🏠 Personal Feed. Images are not automatically loaded in 🔍 Global Feed
- Share images by pasting the image url which you can grab from nostr.build, imgbb, imgur, etc. (i.e., `https://i.ibb.co/2SHZbwm/alpha60.jpg`). Currently images only load for people you follow in the 🏠 Personal Feed. Images are not automatically loaded in 🔍 Global Feed
- Engaging with Notes
- 💬 Replying to a Note: Tap the chat icon underneath the note. This will show up in the users notifications and in your 🏠 Personal and 🔍 Global Feeds
- ♺ Reposts: Tap the repost icon which will show up in your 🏠 Personal and 🔍 Global Feeds
- ♡ Likes: Tap the heart icon. Users will not get a notification, and cannot see who liked their note (currently, web clients can see your pfp only)
- Formatting Notes (may not format as intended in other web clients)
- Italics: 1 asterisk `*italic*`
- Bold: 2 asterisk `**bold**`
- Strikethrough: 1 tildes `~strikethrough~`
- Code: 1 back-tick `` `code` ``
#### 💬 Encrypted DMs (chat app, bottom navigation)
- Tap the chat icon and you'll notice there's nothing to see at first. Go to a user profile and tap the 💬 chat icon next to the follow button to begin a DM
@@ -76,7 +102,9 @@ damus implements the following [Nostr Implementation Possibilities][nips]
4. For PFP, insert a URL containing your image (support video: https://cdn.jb55.com/vid/pfp-editor.mp4)
5. Save
#### ⚡️ Request Sats
Paste an invoice from your favorite LN wallet.
(Sats or Satoshis are the smallest denomination of bitcoin)
**Alby (browser extension)**
@@ -108,26 +136,17 @@ We have a few mailing lists that anyone can join to get involved in damus develo
[product-list]: https://damus.io/list/product
[design-list]: https://damus.io/list/design
### Code
### Contributing
[Email patches][git-send-email] to patches@damus.io are preferred, but I accept PRs on GitHub as well. Patches sent via email may include a bolt11 lightning invoice, choosing the price you think the patch is worth, and I will pay it once the patch is accepted and if I think the price isn't unreasonable. You can also send an any-amount invoice and I will pay what I think it's worth if you prefer not to choose. You can include the bolt11 in the commit body or email so that it can be paid once it is applied.
Recommended settings when submitting code via email:
```
$ git config sendemail.to "patches@damus.io"
$ git config format.subjectPrefix "PATCH damus"
$ git config --global sendemail.annotate yes
$ git config format.signOff yes
```
[git-send-email]: http://git-send-email.io
See [docs/CONTRIBUTING.md](./docs/CONTRIBUTING.md)
### Privacy
Your internet protocol (IP) address is exposed to the relays you connect to, and third party media hosters (e.g. nostr.build, imgur.com, giphy.com, youtube.com etc.) that render on Damus. If you want to improve your privacy, consider utilizing a service that masks your IP address (e.g. a VPN) from trackers online.
The relay also learns which public keys you are requesting, meaning your public key will be tied to your IP address.
It is public information which other profiles (npubs) you are exchanging DMs with. The content of the DMs is encrypted.
### Translations
Translators welcome! Join the [Transifex][transifex] project.
@@ -138,8 +157,10 @@ All user-facing strings must have a comment in order to provide context to trans
### Awards
Damus lead dev and founder Will awards developers with satoshis!
There may be nostr badges awarded for contributors in the future... :)
First contributors:
1. @randymcmillan

1
TODO Normal file
View File

@@ -0,0 +1 @@
Fix q tags

View File

@@ -35,7 +35,7 @@ typedef struct mention_bech32_block {
struct nostr_bech32 bech32;
} mention_bech32_block_t;
typedef struct block {
typedef struct note_block {
enum block_type type;
union {
struct str_block str;
@@ -45,12 +45,13 @@ typedef struct block {
} block;
} block_t;
typedef struct blocks {
typedef struct note_blocks {
int words;
int num_blocks;
struct block *blocks;
struct note_block *blocks;
} blocks_t;
void blocks_init(struct blocks *blocks);
void blocks_free(struct blocks *blocks);
void blocks_init(struct note_blocks *blocks);
void blocks_free(struct note_blocks *blocks);
#endif /* block_h */

View File

@@ -1,94 +1,131 @@
//
// cursor.h
// damus
//
// Created by William Casarin on 2023-04-09.
//
#ifndef cursor_h
#define cursor_h
#ifndef JB55_CURSOR_H
#define JB55_CURSOR_H
#include "typedefs.h"
#include "varint.h"
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
typedef unsigned char u8;
#define unlikely(x) __builtin_expect((x),0)
#define likely(x) __builtin_expect((x),1)
struct cursor {
const u8 *p;
const u8 *start;
const u8 *end;
unsigned char *start;
unsigned char *p;
unsigned char *end;
};
static inline int is_whitespace(char c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
}
struct array {
struct cursor cur;
unsigned int elem_size;
};
static inline int is_boundary(char c) {
return !isalnum(c);
}
static inline int is_invalid_url_ending(char c) {
return c == '!' || c == '?' || c == ')' || c == '.' || c == ',' || c == ';';
}
static inline int is_alphanumeric(char c) {
return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
}
static inline void make_cursor(struct cursor *c, const u8 *content, size_t len)
static inline void reset_cursor(struct cursor *cursor)
{
c->start = content;
c->end = content + len;
c->p = content;
cursor->p = cursor->start;
}
static inline int consume_until_boundary(struct cursor *cur) {
char c;
while (cur->p < cur->end) {
c = *cur->p;
if (is_boundary(c))
return 1;
cur->p++;
}
static inline void wipe_cursor(struct cursor *cursor)
{
reset_cursor(cursor);
memset(cursor->start, 0, cursor->end - cursor->start);
}
static inline void make_cursor(u8 *start, u8 *end, struct cursor *cursor)
{
cursor->start = start;
cursor->p = start;
cursor->end = end;
}
static inline void make_array(struct array *a, u8* start, u8 *end, unsigned int elem_size)
{
make_cursor(start, end, &a->cur);
a->elem_size = elem_size;
}
static inline int cursor_eof(struct cursor *c)
{
return c->p == c->end;
}
static inline void *cursor_malloc(struct cursor *mem, unsigned long size)
{
void *ret;
if (mem->p + size > mem->end) {
return NULL;
}
ret = mem->p;
mem->p += size;
return ret;
}
static inline void *cursor_alloc(struct cursor *mem, unsigned long size)
{
void *ret;
if (!(ret = cursor_malloc(mem, size))) {
return 0;
}
memset(ret, 0, size);
return ret;
}
static inline int cursor_slice(struct cursor *mem, struct cursor *slice, size_t size)
{
u8 *p;
if (!(p = cursor_alloc(mem, size))) {
return 0;
}
make_cursor(p, mem->p, slice);
return 1;
}
static inline void copy_cursor(struct cursor *src, struct cursor *dest)
{
dest->start = src->start;
dest->p = src->p;
dest->end = src->end;
}
static inline int cursor_skip(struct cursor *cursor, int n)
{
if (cursor->p + n >= cursor->end)
return 0;
cursor->p += n;
return 1;
}
static inline int consume_until_whitespace(struct cursor *cur, int or_end) {
char c;
int consumedAtLeastOne = 0;
while (cur->p < cur->end) {
c = *cur->p;
if (is_whitespace(c))
return consumedAtLeastOne;
cur->p++;
consumedAtLeastOne = 1;
}
return or_end;
static inline int pull_byte(struct cursor *cursor, u8 *c)
{
if (unlikely(cursor->p >= cursor->end))
return 0;
*c = *cursor->p;
cursor->p++;
return 1;
}
static inline int consume_until_non_alphanumeric(struct cursor *cur, int or_end) {
char c;
int consumedAtLeastOne = 0;
static inline int parse_byte(struct cursor *cursor, u8 *c)
{
if (unlikely(cursor->p >= cursor->end))
return 0;
while (cur->p < cur->end) {
c = *cur->p;
*c = *cursor->p;
//cursor->p++;
if (!is_alphanumeric(c))
return consumedAtLeastOne;
cur->p++;
consumedAtLeastOne = 1;
}
return or_end;
return 1;
}
static inline int parse_char(struct cursor *cur, char c) {
@@ -110,16 +147,312 @@ static inline int peek_char(struct cursor *cur, int ind) {
return *(cur->p + ind);
}
static inline int cursor_pull_c_str(struct cursor *cursor, const char **str)
{
*str = (const char*)cursor->p;
static inline int pull_byte(struct cursor *cur, u8 *byte) {
if (cur->p >= cur->end)
return 0;
*byte = *cur->p;
cur->p++;
return 1;
for (; cursor->p < cursor->end; cursor->p++) {
if (*cursor->p == 0) {
cursor->p++;
return 1;
}
}
return 0;
}
static inline int cursor_push_byte(struct cursor *cursor, u8 c)
{
if (unlikely(cursor->p + 1 > cursor->end)) {
return 0;
}
*cursor->p = c;
cursor->p++;
return 1;
}
static inline int cursor_pull(struct cursor *cursor, u8 *data, int len)
{
if (unlikely(cursor->p + len > cursor->end)) {
return 0;
}
memcpy(data, cursor->p, len);
cursor->p += len;
return 1;
}
static inline int pull_data_into_cursor(struct cursor *cursor,
struct cursor *dest,
unsigned char **data,
int len)
{
int ok;
if (unlikely(dest->p + len > dest->end)) {
printf("not enough room in dest buffer\n");
return 0;
}
ok = cursor_pull(cursor, dest->p, len);
if (!ok) return 0;
*data = dest->p;
dest->p += len;
return 1;
}
static inline int cursor_dropn(struct cursor *cur, int size, int n)
{
if (n == 0)
return 1;
if (unlikely(cur->p - size*n < cur->start)) {
return 0;
}
cur->p -= size*n;
return 1;
}
static inline int cursor_drop(struct cursor *cur, int size)
{
return cursor_dropn(cur, size, 1);
}
static inline unsigned char *cursor_topn(struct cursor *cur, int len, int n)
{
n += 1;
if (unlikely(cur->p - len*n < cur->start)) {
return NULL;
}
return cur->p - len*n;
}
static inline unsigned char *cursor_top(struct cursor *cur, int len)
{
if (unlikely(cur->p - len < cur->start)) {
return NULL;
}
return cur->p - len;
}
static inline int cursor_top_int(struct cursor *cur, int *i)
{
u8 *p;
if (unlikely(!(p = cursor_top(cur, sizeof(*i))))) {
return 0;
}
*i = *((int*)p);
return 1;
}
static inline int cursor_pop(struct cursor *cur, u8 *data, int len)
{
if (unlikely(cur->p - len < cur->start)) {
return 0;
}
cur->p -= len;
memcpy(data, cur->p, len);
return 1;
}
static inline int cursor_push(struct cursor *cursor, u8 *data, int len)
{
if (unlikely(cursor->p + len >= cursor->end)) {
return 0;
}
if (cursor->p != data)
memcpy(cursor->p, data, len);
cursor->p += len;
return 1;
}
static inline int cursor_push_int(struct cursor *cursor, int i)
{
return cursor_push(cursor, (u8*)&i, sizeof(i));
}
static inline size_t cursor_count(struct cursor *cursor, size_t elem_size)
{
return (cursor->p - cursor->start)/elem_size;
}
/* TODO: push_varint */
static inline int push_varint(struct cursor *cursor, int n)
{
int ok, len;
unsigned char b;
len = 0;
while (1) {
b = (n & 0xFF) | 0x80;
n >>= 7;
if (n == 0) {
b &= 0x7F;
ok = cursor_push_byte(cursor, b);
len++;
if (!ok) return 0;
break;
}
ok = cursor_push_byte(cursor, b);
len++;
if (!ok) return 0;
}
return len;
}
/* TODO: pull_varint */
static inline int pull_varint(struct cursor *cursor, int *n)
{
int ok, i;
unsigned char b;
*n = 0;
for (i = 0;; i++) {
ok = pull_byte(cursor, &b);
if (!ok) return 0;
*n |= ((int)b & 0x7F) << (i * 7);
/* is_last */
if ((b & 0x80) == 0) {
return i+1;
}
if (i == 4) return 0;
}
return 0;
}
static inline int cursor_pull_int(struct cursor *cursor, int *i)
{
return cursor_pull(cursor, (u8*)i, sizeof(*i));
}
static inline int cursor_push_u32(struct cursor *cursor, uint32_t i) {
return cursor_push(cursor, (unsigned char*)&i, sizeof(i));
}
static inline int cursor_push_u16(struct cursor *cursor, u16 i)
{
return cursor_push(cursor, (u8*)&i, sizeof(i));
}
static inline void *index_cursor(struct cursor *cursor, unsigned int index, int elem_size)
{
u8 *p;
p = &cursor->start[elem_size * index];
if (unlikely(p >= cursor->end))
return NULL;
return (void*)p;
}
static inline int push_sized_str(struct cursor *cursor, const char *str, int len)
{
return cursor_push(cursor, (u8*)str, len);
}
static inline int cursor_push_lowercase(struct cursor *cur, const char *str, int len)
{
int i;
if (unlikely(cur->p + len >= cur->end))
return 0;
for (i = 0; i < len; i++)
cur->p[i] = tolower(str[i]);
cur->p += len;
return 1;
}
static inline int cursor_push_str(struct cursor *cursor, const char *str)
{
return cursor_push(cursor, (u8*)str, (int)strlen(str));
}
static inline int cursor_push_c_str(struct cursor *cursor, const char *str)
{
return cursor_push_str(cursor, str) && cursor_push_byte(cursor, 0);
}
/* TODO: push varint size */
static inline int push_prefixed_str(struct cursor *cursor, const char *str)
{
int ok, len;
len = (int)strlen(str);
ok = push_varint(cursor, len);
if (!ok) return 0;
return push_sized_str(cursor, str, len);
}
static inline int pull_prefixed_str(struct cursor *cursor, struct cursor *dest_buf, const char **str)
{
int len, ok;
ok = pull_varint(cursor, &len);
if (!ok) return 0;
if (unlikely(dest_buf->p + len > dest_buf->end)) {
return 0;
}
ok = pull_data_into_cursor(cursor, dest_buf, (unsigned char**)str, len);
if (!ok) return 0;
ok = cursor_push_byte(dest_buf, 0);
return 1;
}
static inline int cursor_remaining_capacity(struct cursor *cursor)
{
return (int)(cursor->end - cursor->p);
}
#define max(a,b) ((a) > (b) ? (a) : (b))
static inline void cursor_print_around(struct cursor *cur, int range)
{
unsigned char *c;
printf("[%ld/%ld]\n", cur->p - cur->start, cur->end - cur->start);
c = max(cur->p - range, cur->start);
for (; c < cur->end && c < (cur->p + range); c++) {
printf("%02x", *c);
}
printf("\n");
c = max(cur->p - range, cur->start);
for (; c < cur->end && c < (cur->p + range); c++) {
if (c == cur->p) {
printf("^");
continue;
}
printf(" ");
}
printf("\n");
}
#undef max
static inline int pull_bytes(struct cursor *cur, int count, const u8 **bytes) {
if (cur->p + count > cur->end)
return 0;
@@ -152,5 +485,262 @@ static inline int parse_str(struct cursor *cur, const char *str) {
return 1;
}
static inline int is_whitespace(int c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
}
#endif /* cursor_h */
static inline int next_char_is_whitespace(unsigned char *curChar, unsigned char *endChar) {
unsigned char * next = curChar + 1;
if(next > endChar) return 0;
else if(next == endChar) return 1;
return is_whitespace(*next);
}
static int char_disallowed_at_end_url(char c){
return c == '.' || c == ',';
}
static inline int is_final_url_char(unsigned char *curChar, unsigned char *endChar){
if(is_whitespace(*curChar)){
return 1;
}
else if(next_char_is_whitespace(curChar, endChar)) {
// next char is whitespace so this char could be the final char in the url
return char_disallowed_at_end_url(*curChar);
}
else{
// next char isn't whitespace so it can't be a final char
return 0;
}
}
static inline int is_underscore(int c) {
return c == '_';
}
static inline int is_utf8_byte(u8 c) {
return c & 0x80;
}
static inline int parse_utf8_char(struct cursor *cursor, unsigned int *code_point, unsigned int *utf8_length)
{
u8 first_byte;
if (!parse_byte(cursor, &first_byte))
return 0; // Not enough data
// Determine the number of bytes in this UTF-8 character
int remaining_bytes = 0;
if (first_byte < 0x80) {
*code_point = first_byte;
return 1;
} else if ((first_byte & 0xE0) == 0xC0) {
remaining_bytes = 1;
*utf8_length = remaining_bytes + 1;
*code_point = first_byte & 0x1F;
} else if ((first_byte & 0xF0) == 0xE0) {
remaining_bytes = 2;
*utf8_length = remaining_bytes + 1;
*code_point = first_byte & 0x0F;
} else if ((first_byte & 0xF8) == 0xF0) {
remaining_bytes = 3;
*utf8_length = remaining_bytes + 1;
*code_point = first_byte & 0x07;
} else {
remaining_bytes = 0;
*utf8_length = 1; // Assume 1 byte length for unrecognized UTF-8 characters
// TODO: We need to gracefully handle unrecognized UTF-8 characters
printf("Invalid UTF-8 byte: %x\n", *code_point);
*code_point = ((first_byte & 0xF0) << 6); // Prevent testing as punctuation
return 0; // Invalid first byte
}
// Peek at remaining bytes
for (int i = 0; i < remaining_bytes; ++i) {
signed char next_byte;
if ((next_byte = peek_char(cursor, i+1)) == -1) {
*utf8_length = 1;
return 0; // Not enough data
}
// Debugging lines
//printf("Cursor: %s\n", cursor->p);
//printf("Codepoint: %x\n", *code_point);
//printf("Codepoint <<6: %x\n", ((*code_point << 6) | (next_byte & 0x3F)));
//printf("Remaining bytes: %x\n", remaining_bytes);
//printf("First byte: %x\n", first_byte);
//printf("Next byte: %x\n", next_byte);
//printf("Bitwise AND result: %x\n", (next_byte & 0xC0));
if ((next_byte & 0xC0) != 0x80) {
*utf8_length = 1;
return 0; // Invalid byte in sequence
}
*code_point = (*code_point << 6) | (next_byte & 0x3F);
}
return 1;
}
/**
* Checks if a given Unicode code point is a punctuation character
*
* @param codepoint The Unicode code point to check. @return true if the
* code point is a punctuation character, false otherwise.
*/
static inline int is_punctuation(unsigned int codepoint) {
// Check for underscore (underscore is not treated as punctuation)
if (is_underscore(codepoint))
return 0;
// Check for ASCII punctuation
if (ispunct(codepoint))
return 1;
// Check for Unicode punctuation exceptions (punctuation allowed in hashtags)
if (codepoint == 0x301C || codepoint == 0xFF5E) // Japanese Wave Dash / Tilde
return 0;
// Check for Unicode punctuation
// NOTE: We may need to adjust the codepoint ranges in the future,
// to include/exclude certain types of Unicode characters in hashtags.
// Unicode Blocks Reference: https://www.compart.com/en/unicode/block
return (
// Latin-1 Supplement No-Break Space (NBSP): U+00A0
(codepoint == 0x00A0) ||
// Latin-1 Supplement Punctuation: U+00A1 to U+00BF
(codepoint >= 0x00A1 && codepoint <= 0x00BF) ||
// General Punctuation: U+2000 to U+206F
(codepoint >= 0x2000 && codepoint <= 0x206F) ||
// Currency Symbols: U+20A0 to U+20CF
(codepoint >= 0x20A0 && codepoint <= 0x20CF) ||
// Supplemental Punctuation: U+2E00 to U+2E7F
(codepoint >= 0x2E00 && codepoint <= 0x2E7F) ||
// CJK Symbols and Punctuation: U+3000 to U+303F
(codepoint >= 0x3000 && codepoint <= 0x303F) ||
// Ideographic Description Characters: U+2FF0 to U+2FFF
(codepoint >= 0x2FF0 && codepoint <= 0x2FFF)
);
}
static inline int is_right_boundary(int c) {
return is_whitespace(c) || is_punctuation(c);
}
static inline int is_left_boundary(char c) {
return is_right_boundary(c) || is_utf8_byte(c);
}
static inline int is_alphanumeric(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
}
static inline int consume_until_boundary(struct cursor *cur) {
unsigned int c;
unsigned int char_length = 1;
unsigned int *utf8_char_length = &char_length;
while (cur->p < cur->end) {
c = *cur->p;
*utf8_char_length = 1;
if (is_whitespace(c))
return 1;
// Need to check for UTF-8 characters, which can be multiple bytes long
if (is_utf8_byte(c)) {
if (!parse_utf8_char(cur, &c, utf8_char_length)) {
if (!is_right_boundary(c)){
// TODO: We should work towards handling all UTF-8 characters.
printf("Invalid UTF-8 code point: %x\n", c);
}
}
}
if (is_right_boundary(c))
return 1;
// Need to use a variable character byte length for UTF-8 (2-4 bytes)
if (cur->p + *utf8_char_length <= cur->end)
cur->p += *utf8_char_length;
else
cur->p++;
}
return 1;
}
static inline int consume_until_whitespace(struct cursor *cur, int or_end) {
char c;
int consumedAtLeastOne = 0;
while (cur->p < cur->end) {
c = *cur->p;
if (is_whitespace(c))
return consumedAtLeastOne;
cur->p++;
consumedAtLeastOne = 1;
}
return or_end;
}
static inline int consume_until_end_url(struct cursor *cur, int or_end) {
char c;
int consumedAtLeastOne = 0;
while (cur->p < cur->end) {
c = *cur->p;
if (is_final_url_char(cur->p, cur->end))
return consumedAtLeastOne;
cur->p++;
consumedAtLeastOne = 1;
}
return or_end;
}
static inline int consume_until_non_alphanumeric(struct cursor *cur, int or_end) {
char c;
int consumedAtLeastOne = 0;
while (cur->p < cur->end) {
c = *cur->p;
if (!is_alphanumeric(c))
return consumedAtLeastOne;
cur->p++;
consumedAtLeastOne = 1;
}
return or_end;
}
static inline int cursor_memset(struct cursor *cursor, unsigned char c, int n)
{
if (cursor->p + n >= cursor->end)
return 0;
memset(cursor->p, c, n);
cursor->p += n;
return 1;
}
#endif

View File

@@ -5,3 +5,9 @@
#include "damus.h"
#include "bolt11.h"
#include "amount.h"
#include "nostr_bech32.h"
#include "wasm.h"
#include "nostrscript.h"
#include "nostrdb.h"
#include "lmdb.h"

View File

@@ -28,9 +28,9 @@ static int parse_digit(struct cursor *cur, int *digit) {
}
static int parse_mention_index(struct cursor *cur, struct block *block) {
static int parse_mention_index(struct cursor *cur, struct note_block *block) {
int d1, d2, d3, ind;
const u8 *start = cur->p;
u8 *start = cur->p;
if (!parse_str(cur, "#["))
return 0;
@@ -59,9 +59,9 @@ static int parse_mention_index(struct cursor *cur, struct block *block) {
return 1;
}
static int parse_hashtag(struct cursor *cur, struct block *block) {
static int parse_hashtag(struct cursor *cur, struct note_block *block) {
int c;
const u8 *start = cur->p;
u8 *start = cur->p;
if (!parse_char(cur, '#'))
return 0;
@@ -81,7 +81,7 @@ static int parse_hashtag(struct cursor *cur, struct block *block) {
return 1;
}
static int add_block(struct blocks *blocks, struct block block)
static int add_block(struct note_blocks *blocks, struct note_block block)
{
if (blocks->num_blocks + 1 >= MAX_BLOCKS)
return 0;
@@ -90,9 +90,9 @@ static int add_block(struct blocks *blocks, struct block block)
return 1;
}
static int add_text_block(struct blocks *blocks, const u8 *start, const u8 *end)
static int add_text_block(struct note_blocks *blocks, const u8 *start, const u8 *end)
{
struct block b;
struct note_block b;
if (start == end)
return 1;
@@ -104,8 +104,74 @@ static int add_text_block(struct blocks *blocks, const u8 *start, const u8 *end)
return add_block(blocks, b);
}
static int parse_url(struct cursor *cur, struct block *block) {
const u8 *start = cur->p;
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;
@@ -121,15 +187,58 @@ static int parse_url(struct cursor *cur, struct block *block) {
return 0;
}
}
if (!consume_until_whitespace(cur, 1)) {
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;
}
// strip any unwanted characters
while(is_invalid_url_ending(peek_char(cur, -1))) cur->p--;
// 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;
@@ -137,8 +246,8 @@ static int parse_url(struct cursor *cur, struct block *block) {
return 1;
}
static int parse_invoice(struct cursor *cur, struct block *block) {
const u8 *start, *end;
static int parse_invoice(struct cursor *cur, struct note_block *block) {
u8 *start, *end;
char *fail;
struct bolt11 *bolt11;
// optional
@@ -177,12 +286,12 @@ static int parse_invoice(struct cursor *cur, struct block *block) {
}
static int parse_mention_bech32(struct cursor *cur, struct block *block) {
const u8 *start = cur->p;
if (!parse_str(cur, "nostr:"))
return 0;
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)) {
@@ -197,7 +306,7 @@ static int parse_mention_bech32(struct cursor *cur, struct block *block) {
return 1;
}
static int add_text_then_block(struct cursor *cur, struct blocks *blocks, struct block block, const u8 **start, const u8 *pre_mention)
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;
@@ -210,22 +319,28 @@ static int add_text_then_block(struct cursor *cur, struct blocks *blocks, struct
return 1;
}
int damus_parse_content(struct blocks *blocks, const char *content) {
int damus_parse_content(struct note_blocks *blocks, const char *content) {
int cp, c;
struct cursor cur;
struct block block;
const u8 *start, *pre_mention;
struct note_block block;
u8 *start, *pre_mention;
blocks->words = 0;
blocks->num_blocks = 0;
make_cursor(&cur, (const u8*)content, strlen(content));
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_whitespace(cp) || c == '#') {
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;
@@ -238,7 +353,7 @@ int damus_parse_content(struct blocks *blocks, const char *content) {
if (!add_text_then_block(&cur, blocks, block, &start, pre_mention))
return 0;
continue;
} else if (c == 'n' && parse_mention_bech32(&cur, &block)) {
} else if ((c == 'n' || c == '@') && parse_mention_bech32(&cur, &block)) {
if (!add_text_then_block(&cur, blocks, block, &start, pre_mention))
return 0;
continue;
@@ -256,12 +371,12 @@ int damus_parse_content(struct blocks *blocks, const char *content) {
return 1;
}
void blocks_init(struct blocks *blocks) {
blocks->blocks = malloc(sizeof(struct block) * MAX_BLOCKS);
void blocks_init(struct note_blocks *blocks) {
blocks->blocks = malloc(sizeof(struct note_block) * MAX_BLOCKS);
blocks->num_blocks = 0;
}
void blocks_free(struct blocks *blocks) {
void blocks_free(struct note_blocks *blocks) {
if (!blocks->blocks) {
return;
}

View File

@@ -9,10 +9,10 @@
#define damus_h
#include <stdio.h>
#include "nostr_bech32.h"
#include "block.h"
typedef unsigned char u8;
int damus_parse_content(struct blocks *blocks, const char *content);
int damus_parse_content(struct note_blocks *blocks, const char *content);
#endif /* damus_h */

15
damus-c/debug.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef PROTOVERSE_DEBUG_H
#define PROTOVERSE_DEBUG_H
#include <stdio.h>
#define unusual(...) fprintf(stderr, "UNUSUAL: " __VA_ARGS__)
#ifdef DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
#endif /* PROTOVERSE_DEBUG_H */

34
damus-c/error.c Normal file
View File

@@ -0,0 +1,34 @@
#include "error.h"
#include <stdlib.h>
#include <stdarg.h>
int note_error_(struct errors *errs_, struct cursor *p, const char *fmt, ...)
{
static char buf[512];
struct error err;
struct cursor *errs;
va_list ap;
errs = &errs_->cur;
if (errs_->enabled == 0)
return 0;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
err.msg = buf;
err.pos = p ? (int)(p->p - p->start) : 0;
if (!cursor_push_error(errs, &err)) {
fprintf(stderr, "arena OOM when recording error, ");
fprintf(stderr, "errs->p at %ld, remaining %ld, strlen %ld\n",
errs->p - errs->start, errs->end - errs->p, strlen(buf));
}
return 0;
}

33
damus-c/error.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef PROTOVERSE_ERROR_H
#define PROTOVERSE_ERROR_H
#include "cursor.h"
struct error {
int pos;
const char *msg;
};
struct errors {
struct cursor cur;
int enabled;
};
#define note_error(errs, p, fmt, ...) note_error_(errs, p, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
static inline int cursor_push_error(struct cursor *cur, struct error *err)
{
return cursor_push_int(cur, err->pos) &&
cursor_push_c_str(cur, err->msg);
}
static inline int cursor_pull_error(struct cursor *cur, struct error *err)
{
return cursor_pull_int(cur, &err->pos) &&
cursor_pull_c_str(cur, &err->msg);
}
int note_error_(struct errors *errs, struct cursor *p, const char *fmt, ...);
#endif /* PROTOVERSE_ERROR_H */

View File

@@ -39,15 +39,6 @@ bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize)
return slen == 0 && bufsize == 0;
}
static char hexchar(unsigned int val)
{
if (val < 10)
return '0' + val;
if (val < 16)
return 'a' + val - 10;
abort();
}
bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize)
{
size_t i;

View File

@@ -70,4 +70,15 @@ 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

@@ -52,9 +52,13 @@
*/
#define unlikely(cond) __builtin_expect(!!(cond), 0)
#else
#ifndef likely
#define likely(cond) (!!(cond))
#endif
#ifndef unlikely
#define unlikely(cond) (!!(cond))
#endif
#endif
#else /* CCAN_LIKELY_DEBUG versions */
#include <ccan/str/str.h>

View File

@@ -7,8 +7,10 @@
#include "nostr_bech32.h"
#include <stdlib.h>
#include "endian.h"
#include "cursor.h"
#include "bech32.h"
#include <stdbool.h>
#define MAX_TLVS 16
@@ -91,6 +93,9 @@ static int parse_nostr_bech32_type(const char *prefix, enum nostr_bech32_type *t
} 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;
@@ -116,6 +121,10 @@ 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;
@@ -138,6 +147,11 @@ static int tlvs_to_relays(struct nostr_tlvs *tlvs, struct relays *relays) {
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;
@@ -159,6 +173,13 @@ static int parse_nostr_bech32_nevent(struct cursor *cur, struct bech32_nevent *n
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);
}
@@ -180,6 +201,11 @@ static int parse_nostr_bech32_naddr(struct cursor *cur, struct bech32_naddr *nad
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);
}
@@ -218,7 +244,7 @@ static int parse_nostr_bech32_nrelay(struct cursor *cur, struct bech32_nrelay *n
}
int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj) {
const u8 *start, *end;
u8 *start, *end;
start = cur->p;
@@ -257,7 +283,7 @@ int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj) {
}
struct cursor bcur;
make_cursor(&bcur, obj->buffer, obj->buflen);
make_cursor(obj->buffer, obj->buffer + obj->buflen, &bcur);
switch (obj->type) {
case NOSTR_BECH32_NOTE:
@@ -268,6 +294,10 @@ int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj) {
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;

View File

@@ -11,6 +11,8 @@
#include <stdio.h>
#include "str_block.h"
#include "cursor.h"
#include <stdbool.h>
typedef unsigned char u8;
#define MAX_RELAYS 10
@@ -26,6 +28,7 @@ enum nostr_bech32_type {
NOSTR_BECH32_NEVENT = 4,
NOSTR_BECH32_NRELAY = 5,
NOSTR_BECH32_NADDR = 6,
NOSTR_BECH32_NSEC = 7,
};
struct bech32_note {
@@ -36,10 +39,16 @@ 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 {
@@ -51,6 +60,7 @@ struct bech32_naddr {
struct relays relays;
struct str_block identifier;
const u8 *pubkey;
uint32_t kind;
};
struct bech32_nrelay {
@@ -65,6 +75,7 @@ typedef struct nostr_bech32 {
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;

42
damus-c/parser.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef CURSOR_PARSER
#define CURSOR_PARSER
#include "cursor.h"
static int consume_bytes(struct cursor *cursor, const unsigned char *match, int len)
{
int i;
if (cursor->p + len > cursor->end) {
fprintf(stderr, "consume_bytes overflow\n");
return 0;
}
for (i = 0; i < len; i++) {
if (cursor->p[i] != match[i])
return 0;
}
cursor->p += len;
return 1;
}
static inline int consume_byte(struct cursor *cursor, unsigned char match)
{
if (unlikely(cursor->p >= cursor->end))
return 0;
if (*cursor->p != match)
return 0;
cursor->p++;
return 1;
}
static inline int consume_u32(struct cursor *cursor, unsigned int match)
{
return consume_bytes(cursor, (unsigned char*)&match, sizeof(match));
}
#endif /* CURSOR_PARSER */

14
damus-c/typedefs.h Normal file
View File

@@ -0,0 +1,14 @@
#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 */

14
damus-c/varint.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef PROTOVERSE_VARINT_H
#define PROTOVERSE_VARINT_H
#define VARINT_MAX_LEN 9
#include <stddef.h>
#include <stdint.h>
size_t varint_put(unsigned char buf[VARINT_MAX_LEN], uint64_t v);
size_t varint_size(uint64_t v);
size_t varint_get(const unsigned char *p, size_t max, int64_t *val);
#endif /* PROTOVERSE_VARINT_H */

7299
damus-c/wasm.c Normal file

File diff suppressed because it is too large Load Diff

850
damus-c/wasm.h Normal file
View File

@@ -0,0 +1,850 @@
#ifndef PROTOVERSE_WASM_H
#define PROTOVERSE_WASM_H
static const unsigned char WASM_MAGIC[] = {0,'a','s','m'};
#define WASM_VERSION 0x01
#define MAX_U32_LEB128_BYTES 5
#define MAX_U64_LEB128_BYTES 10
#define MAX_CUSTOM_SECTIONS 32
#define MAX_BUILTINS 64
#define BUILTIN_SUSPEND 42
#define FUNC_TYPE_TAG 0x60
#include "cursor.h"
#include "error.h"
#ifdef NOINLINE
#define INLINE __attribute__((noinline))
#else
#define INLINE inline
#endif
#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__)
enum valtype {
val_i32 = 0x7F,
val_i64 = 0x7E,
val_f32 = 0x7D,
val_f64 = 0x7C,
val_ref_null = 0xD0,
val_ref_func = 0x70,
val_ref_extern = 0x6F,
};
enum const_instr {
ci_const_i32 = 0x41,
ci_const_i64 = 0x42,
ci_const_f32 = 0x43,
ci_const_f64 = 0x44,
ci_ref_null = 0xD0,
ci_ref_func = 0xD2,
ci_global_get = 0x23,
ci_end = 0x0B,
};
enum limit_type {
limit_min = 0x00,
limit_min_max = 0x01,
};
struct limits {
u32 min;
u32 max;
enum limit_type type;
};
enum section_tag {
section_custom,
section_type,
section_import,
section_function,
section_table,
section_memory,
section_global,
section_export,
section_start,
section_element,
section_code,
section_data,
section_data_count,
section_name,
num_sections,
};
enum name_subsection_tag {
name_subsection_module,
name_subsection_funcs,
name_subsection_locals,
num_name_subsections,
};
enum reftype {
funcref = 0x70,
externref = 0x6F,
};
struct resulttype {
unsigned char *valtypes; /* enum valtype */
u32 num_valtypes;
};
struct functype {
struct resulttype params;
struct resulttype result;
};
struct table {
enum reftype reftype;
struct limits limits;
};
struct tablesec {
struct table *tables;
u32 num_tables;
};
enum elem_mode {
elem_mode_passive,
elem_mode_active,
elem_mode_declarative,
};
struct expr {
u8 *code;
u32 code_len;
};
struct refval {
u32 addr;
};
struct table_inst {
struct refval *refs;
enum reftype reftype;
u32 num_refs;
};
struct numval {
union {
int i32;
u32 u32;
int64_t i64;
uint64_t u64;
float f32;
double f64;
};
};
struct val {
enum valtype type;
union {
struct numval num;
struct refval ref;
};
};
struct elem_inst {
struct val val;
u16 elem;
u16 init;
};
struct elem {
struct expr offset;
u32 tableidx;
struct expr *inits;
u32 num_inits;
enum elem_mode mode;
enum reftype reftype;
struct val val;
};
struct customsec {
const char *name;
unsigned char *data;
u32 data_len;
};
struct elemsec {
struct elem *elements;
u32 num_elements;
};
struct memsec {
struct limits *mems; /* memtype */
u32 num_mems;
};
struct funcsec {
u32 *type_indices;
u32 num_indices;
};
enum mut {
mut_const,
mut_var,
};
struct globaltype {
enum valtype valtype;
enum mut mut;
};
struct globalsec {
struct global *globals;
u32 num_globals;
};
struct typesec {
struct functype *functypes;
u32 num_functypes;
};
enum import_type {
import_func,
import_table,
import_mem,
import_global,
};
struct importdesc {
enum import_type type;
union {
u32 typeidx;
struct limits tabletype;
struct limits memtype;
struct globaltype globaltype;
};
};
struct import {
const char *module_name;
const char *name;
struct importdesc desc;
int resolved_builtin;
};
struct importsec {
struct import *imports;
u32 num_imports;
};
struct global {
struct globaltype type;
struct expr init;
struct val val;
};
struct local_def {
u32 num_types;
enum valtype type;
};
/* "code" */
struct wasm_func {
struct expr code;
struct local_def *local_defs;
u32 num_local_defs;
};
enum func_type {
func_type_wasm,
func_type_builtin,
};
struct func {
union {
struct wasm_func *wasm_func;
struct builtin *builtin;
};
u32 num_locals;
struct functype *functype;
enum func_type type;
const char *name;
u32 idx;
};
struct codesec {
struct wasm_func *funcs;
u32 num_funcs;
};
enum exportdesc {
export_func,
export_table,
export_mem,
export_global,
};
struct wexport {
const char *name;
u32 index;
enum exportdesc desc;
};
struct exportsec {
struct wexport *exports;
u32 num_exports;
};
struct nameassoc {
u32 index;
const char *name;
};
struct namemap {
struct nameassoc *names;
u32 num_names;
};
struct namesec {
const char *module_name;
struct namemap func_names;
int parsed;
};
struct wsection {
enum section_tag tag;
};
enum bulk_tag {
i_memory_copy = 10,
i_memory_fill = 11,
i_table_init = 12,
i_elem_drop = 13,
i_table_copy = 14,
i_table_grow = 15,
i_table_size = 16,
i_table_fill = 17,
};
enum instr_tag {
/* control instructions */
i_unreachable = 0x00,
i_nop = 0x01,
i_block = 0x02,
i_loop = 0x03,
i_if = 0x04,
i_else = 0x05,
i_end = 0x0B,
i_br = 0x0C,
i_br_if = 0x0D,
i_br_table = 0x0E,
i_return = 0x0F,
i_call = 0x10,
i_call_indirect = 0x11,
/* parametric instructions */
i_drop = 0x1A,
i_select = 0x1B,
i_selects = 0x1C,
/* variable instructions */
i_local_get = 0x20,
i_local_set = 0x21,
i_local_tee = 0x22,
i_global_get = 0x23,
i_global_set = 0x24,
i_table_get = 0x25,
i_table_set = 0x26,
/* memory instructions */
i_i32_load = 0x28,
i_i64_load = 0x29,
i_f32_load = 0x2A,
i_f64_load = 0x2B,
i_i32_load8_s = 0x2C,
i_i32_load8_u = 0x2D,
i_i32_load16_s = 0x2E,
i_i32_load16_u = 0x2F,
i_i64_load8_s = 0x30,
i_i64_load8_u = 0x31,
i_i64_load16_s = 0x32,
i_i64_load16_u = 0x33,
i_i64_load32_s = 0x34,
i_i64_load32_u = 0x35,
i_i32_store = 0x36,
i_i64_store = 0x37,
i_f32_store = 0x38,
i_f64_store = 0x39,
i_i32_store8 = 0x3A,
i_i32_store16 = 0x3B,
i_i64_store8 = 0x3C,
i_i64_store16 = 0x3D,
i_i64_store32 = 0x3E,
i_memory_size = 0x3F,
i_memory_grow = 0x40,
/* numeric instructions */
i_i32_const = 0x41,
i_i64_const = 0x42,
i_f32_const = 0x43,
i_f64_const = 0x44,
i_i32_eqz = 0x45,
i_i32_eq = 0x46,
i_i32_ne = 0x47,
i_i32_lt_s = 0x48,
i_i32_lt_u = 0x49,
i_i32_gt_s = 0x4A,
i_i32_gt_u = 0x4B,
i_i32_le_s = 0x4C,
i_i32_le_u = 0x4D,
i_i32_ge_s = 0x4E,
i_i32_ge_u = 0x4F,
i_i64_eqz = 0x50,
i_i64_eq = 0x51,
i_i64_ne = 0x52,
i_i64_lt_s = 0x53,
i_i64_lt_u = 0x54,
i_i64_gt_s = 0x55,
i_i64_gt_u = 0x56,
i_i64_le_s = 0x57,
i_i64_le_u = 0x58,
i_i64_ge_s = 0x59,
i_i64_ge_u = 0x5A,
i_f32_eq = 0x5B,
i_f32_ne = 0x5C,
i_f32_lt = 0x5D,
i_f32_gt = 0x5E,
i_f32_le = 0x5F,
i_f32_ge = 0x60,
i_f64_eq = 0x61,
i_f64_ne = 0x62,
i_f64_lt = 0x63,
i_f64_gt = 0x64,
i_f64_le = 0x65,
i_f64_ge = 0x66,
i_i32_clz = 0x67,
i_i32_ctz = 0x68,
i_i32_popcnt = 0x69,
i_i32_add = 0x6A,
i_i32_sub = 0x6B,
i_i32_mul = 0x6C,
i_i32_div_s = 0x6D,
i_i32_div_u = 0x6E,
i_i32_rem_s = 0x6F,
i_i32_rem_u = 0x70,
i_i32_and = 0x71,
i_i32_or = 0x72,
i_i32_xor = 0x73,
i_i32_shl = 0x74,
i_i32_shr_s = 0x75,
i_i32_shr_u = 0x76,
i_i32_rotl = 0x77,
i_i32_rotr = 0x78,
i_i64_clz = 0x79,
i_i64_ctz = 0x7A,
i_i64_popcnt = 0x7B,
i_i64_add = 0x7C,
i_i64_sub = 0x7D,
i_i64_mul = 0x7E,
i_i64_div_s = 0x7F,
i_i64_div_u = 0x80,
i_i64_rem_s = 0x81,
i_i64_rem_u = 0x82,
i_i64_and = 0x83,
i_i64_or = 0x84,
i_i64_xor = 0x85,
i_i64_shl = 0x86,
i_i64_shr_s = 0x87,
i_i64_shr_u = 0x88,
i_i64_rotl = 0x89,
i_i64_rotr = 0x8A,
i_f32_abs = 0x8b,
i_f32_neg = 0x8c,
i_f32_ceil = 0x8d,
i_f32_floor = 0x8e,
i_f32_trunc = 0x8f,
i_f32_nearest = 0x90,
i_f32_sqrt = 0x91,
i_f32_add = 0x92,
i_f32_sub = 0x93,
i_f32_mul = 0x94,
i_f32_div = 0x95,
i_f32_min = 0x96,
i_f32_max = 0x97,
i_f32_copysign = 0x98,
i_f64_abs = 0x99,
i_f64_neg = 0x9a,
i_f64_ceil = 0x9b,
i_f64_floor = 0x9c,
i_f64_trunc = 0x9d,
i_f64_nearest = 0x9e,
i_f64_sqrt = 0x9f,
i_f64_add = 0xa0,
i_f64_sub = 0xa1,
i_f64_mul = 0xa2,
i_f64_div = 0xa3,
i_f64_min = 0xa4,
i_f64_max = 0xa5,
i_f64_copysign = 0xa6,
i_i32_wrap_i64 = 0xa7,
i_i32_trunc_f32_s = 0xa8,
i_i32_trunc_f32_u = 0xa9,
i_i32_trunc_f64_s = 0xaa,
i_i32_trunc_f64_u = 0xab,
i_i64_extend_i32_s = 0xac,
i_i64_extend_i32_u = 0xad,
i_i64_trunc_f32_s = 0xae,
i_i64_trunc_f32_u = 0xaf,
i_i64_trunc_f64_s = 0xb0,
i_i64_trunc_f64_u = 0xb1,
i_f32_convert_i32_s = 0xb2,
i_f32_convert_i32_u = 0xb3,
i_f32_convert_i64_s = 0xb4,
i_f32_convert_i64_u = 0xb5,
i_f32_demote_f64 = 0xb6,
i_f64_convert_i32_s = 0xb7,
i_f64_convert_i32_u = 0xb8,
i_f64_convert_i64_s = 0xb9,
i_f64_convert_i64_u = 0xba,
i_f64_promote_f32 = 0xbb,
i_i32_reinterpret_f32 = 0xbc,
i_i64_reinterpret_f64 = 0xbd,
i_f32_reinterpret_i32 = 0xbe,
i_f64_reinterpret_i64 = 0xbf,
i_i32_extend8_s = 0xc0,
i_i32_extend16_s = 0xc1,
i_i64_extend8_s = 0xc2,
i_i64_extend16_s = 0xc3,
i_i64_extend32_s = 0xc4,
i_ref_null = 0xD0,
i_ref_is_null = 0xD1,
i_ref_func = 0xD2,
i_bulk_op = 0xFC,
/* TODO: more instrs */
};
enum blocktype_tag {
blocktype_empty,
blocktype_valtype,
blocktype_index,
};
struct blocktype {
enum blocktype_tag tag;
union {
enum valtype valtype;
int type_index;
};
};
struct instrs {
unsigned char *data;
u32 len;
};
struct block {
struct blocktype type;
struct expr instrs;
};
struct memarg {
u32 offset;
u32 align;
};
struct br_table {
u32 num_label_indices;
u32 label_indices[512];
u32 default_label;
};
struct call_indirect {
u32 tableidx;
u32 typeidx;
};
struct table_init {
u32 tableidx;
u32 elemidx;
};
struct table_copy {
u32 from;
u32 to;
};
struct bulk_op {
enum bulk_tag tag;
union {
struct table_init table_init;
struct table_copy table_copy;
u32 idx;
};
};
struct select_instr {
u8 *valtypes;
u32 num_valtypes;
};
struct instr {
enum instr_tag tag;
int pos;
union {
struct br_table br_table;
struct bulk_op bulk_op;
struct call_indirect call_indirect;
struct memarg memarg;
struct select_instr select;
struct block block;
struct expr else_block;
double f64;
float f32;
int i32;
u32 u32;
int64_t i64;
u64 u64;
unsigned char memidx;
enum reftype reftype;
};
};
enum datamode {
datamode_active,
datamode_passive,
};
struct wdata_active {
u32 mem_index;
struct expr offset_expr;
};
struct wdata {
struct wdata_active active;
u8 *bytes;
u32 bytes_len;
enum datamode mode;
};
struct datasec {
struct wdata *datas;
u32 num_datas;
};
struct startsec {
u32 start_fn;
};
struct module {
unsigned int parsed;
unsigned int custom_sections;
struct func *funcs;
u32 num_funcs;
struct customsec custom_section[MAX_CUSTOM_SECTIONS];
struct typesec type_section;
struct funcsec func_section;
struct importsec import_section;
struct exportsec export_section;
struct codesec code_section;
struct tablesec table_section;
struct memsec memory_section;
struct globalsec global_section;
struct startsec start_section;
struct elemsec element_section;
struct datasec data_section;
struct namesec name_section;
};
// make sure the struct is packed so that
struct label {
u32 instr_pos; // resolved status is stored in HOB of pos
u32 jump;
};
struct callframe {
struct cursor code;
struct val *locals;
struct func *func;
u16 prev_stack_items;
};
struct resolver {
u16 label;
u8 end_tag;
u8 start_tag;
};
struct global_inst {
struct val val;
};
struct module_inst {
struct table_inst *tables;
struct global_inst *globals;
struct elem_inst *elements;
u32 num_tables;
u32 num_globals;
u32 num_elements;
int start_fn;
unsigned char *globals_init;
};
struct wasi {
int argc;
const char **argv;
int environc;
const char **environ;
};
struct wasm_interp;
struct builtin {
const char *name;
int (*fn)(struct wasm_interp *);
int (*prepare_args)(struct wasm_interp *);
};
struct wasm_interp {
struct module *module;
struct module_inst module_inst;
struct wasi wasi;
void *context;
struct builtin builtins[MAX_BUILTINS];
int num_builtins;
int prev_resolvers, quitting;
struct errors errors; /* struct error */
size_t ops;
struct cursor callframes; /* struct callframe */
struct cursor stack; /* struct val */
struct cursor mem; /* u8/mixed */
struct cursor memory; /* memory pages (65536 blocks) */
struct cursor locals; /* struct val */
struct cursor labels; /* struct labels */
struct cursor num_labels;
// resolve stack for the current function. every time a control
// instruction is encountered, the label index is pushed. When an
// instruction is popped, we can resolve the label
struct cursor resolver_stack; /* struct resolver */
struct cursor resolver_offsets; /* int */
};
struct wasm_parser {
struct module module;
struct builtin *builtins;
u32 num_builtins;
struct cursor cur;
struct cursor mem;
struct errors errs;
};
int run_wasm(unsigned char *wasm, unsigned long len, int argc, const char **argv, char **env, int *retval);
int parse_wasm(struct wasm_parser *p);
int wasm_interp_init(struct wasm_interp *interp, struct module *module);
void wasm_parser_free(struct wasm_parser *parser);
void wasm_parser_init(struct wasm_parser *p, u8 *wasm, size_t wasm_len, size_t arena_size, struct builtin *, int num_builtins);
void wasm_interp_free(struct wasm_interp *interp);
int interp_wasm_module(struct wasm_interp *interp, int *retval);
int interp_wasm_module_resume(struct wasm_interp *interp, int *retval);
void print_error_backtrace(struct errors *errors);
void setup_wasi(struct wasm_interp *interp, int argc, const char **argv, char **env);
void print_callstack(struct wasm_interp *interp);
// builtin helpers
int get_params(struct wasm_interp *interp, struct val** vals, u32 num_vals);
int get_var_params(struct wasm_interp *interp, struct val** vals, u32 *num_vals);
u8 *interp_mem_ptr(struct wasm_interp *interp, u32 ptr, int size);
static INLINE struct callframe *top_callframe(struct cursor *cur)
{
return (struct callframe*)cursor_top(cur, sizeof(struct callframe));
}
static INLINE struct cursor *interp_codeptr(struct wasm_interp *interp)
{
struct callframe *frame;
if (unlikely(!(frame = top_callframe(&interp->callframes))))
return 0;
return &frame->code;
}
static INLINE int mem_ptr_str(struct wasm_interp *interp, u32 ptr,
const char **str)
{
// still technically unsafe if the string runs over the end of memory...
if (!(*str = (const char*)interp_mem_ptr(interp, ptr, 1))) {
return interp_error(interp, "int memptr");
}
return 1;
}
static INLINE int mem_ptr_i32(struct wasm_interp *interp, u32 ptr, int **i)
{
if (!(*i = (int*)interp_mem_ptr(interp, ptr, sizeof(int))))
return interp_error(interp, "int memptr");
return 1;
}
static INLINE int cursor_pushval(struct cursor *cur, struct val *val)
{
return cursor_push(cur, (u8*)val, sizeof(*val));
}
static INLINE int cursor_push_i32(struct cursor *stack, int i)
{
struct val val;
val.type = val_i32;
val.num.i32 = i;
return cursor_pushval(stack, &val);
}
static INLINE int stack_push_i32(struct wasm_interp *interp, int i)
{
return cursor_push_i32(&interp->stack, i);
}
static INLINE struct callframe *top_callframes(struct cursor *cur, int top)
{
return (struct callframe*)cursor_topn(cur, sizeof(struct callframe), top);
}
static INLINE int was_section_parsed(struct module *module,
enum section_tag section)
{
if (section == section_custom)
return module->custom_sections > 0;
return module->parsed & (1 << section);
}
#endif /* PROTOVERSE_WASM_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,40 @@
{
"originHash" : "06318d35ee2e6bd681b95591e67da33a9461b48a3c652e58bd9d1a6f0d82bdac",
"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" : "gsplayer",
"kind" : "remoteSourceControl",
@@ -14,8 +49,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/onevcat/Kingfisher",
"state" : {
"revision" : "415b1d97fb38bda1e5a6b2dde63354720832110b",
"version" : "7.6.1"
"revision" : "4c6b067f96953ee19526e49e4189403a2be21fb3",
"version" : "8.3.1"
}
},
{
@@ -25,7 +60,67 @@
"state" : {
"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",
"location" : "https://github.com/damus-io/swift-markdown-ui",
"state" : {
"revision" : "76bb7971da7fbf429de1c84f1244adf657242fee"
}
},
{
"identity" : "swift-snapshot-testing",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-snapshot-testing",
"state" : {
"revision" : "5b356adceabff6ca027f6574aac79e9fee145d26",
"version" : "1.14.1"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"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" : "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,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1520"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D79C4C132AFEB061003A41B4"
BuildableName = "DamusNotificationService.appex"
BlueprintName = "DamusNotificationService"
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.jb55.damus2"
RemotePath = "/Users/danielnogueira/Library/Developer/CoreSimulator/Devices/99E60B35-CE5D-4B45-AC35-00818C0AF3CB/data/Containers/Bundle/Application/7D0A5302-D07E-4C7C-B509-A7C552BD5A65/damus.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

@@ -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

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1420"
LastUpgradeVersion = "1520"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1420"
LastUpgradeVersion = "1520"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,7 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
@@ -39,7 +40,7 @@
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "YES">
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEFC27F7A08200C66700"
@@ -70,6 +71,9 @@
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<StoreKitConfigurationFileReference
identifier = "../../Purple.storekit">
</StoreKitConfigurationFileReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 KiB

View File

@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x1A",
"green" : "0x93",
"red" : "0xF7"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

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" : "0xFF",
"green" : "0xFF",
"red" : "0xFF"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x00",
"green" : "0x00",
"red" : "0x00"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

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

View File

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

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xEE",
"green" : "0xE8",
"red" : "0xF7"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x35",
"green" : "0x04",
"red" : "0x8B"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x3D",
"green" : "0x07",
"red" : "0x9C"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x44",
"green" : "0x06",
"red" : "0xB2"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x2D",
"green" : "0x05",
"red" : "0x75"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xD8",
"green" : "0xC2",
"red" : "0xFF"
}
},
"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

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

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xE3",
"green" : "0xE1",
"red" : "0xDD"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x2A",
"green" : "0x26",
"red" : "0x23"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x59",
"green" : "0x53",
"red" : "0x4A"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x85",
"green" : "0x7A",
"red" : "0x6A"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xE4",
"green" : "0xF1",
"red" : "0xD6"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x38",
"green" : "0x5C",
"red" : "0x12"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x5A",
"green" : "0xAB",
"red" : "0x04"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x64",
"green" : "0xBF",
"red" : "0x03"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF0",
"green" : "0xF7",
"red" : "0xE8"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x1F",
"green" : "0x33",
"red" : "0x0A"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x34",
"green" : "0x64",
"red" : "0x02"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x3F",
"green" : "0x79",
"red" : "0x02"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x1F",
"green" : "0x3C",
"red" : "0x01"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xE4",
"green" : "0xFF",
"red" : "0xAD"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x06",
"green" : "0x85",
"red" : "0xC6"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x03",
"green" : "0x93",
"red" : "0xDD"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x04",
"green" : "0x6A",
"red" : "0x9F"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xCC",
"green" : "0xF5",
"red" : "0xFF"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"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

@@ -0,0 +1,328 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="500"
height="130"
viewBox="0 0 132.29166 34.395832"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r15371"
sodipodi:docname="ActivityPub-logo.svg">
<title
id="title4590">ActivityPub logo</title>
<defs
id="defs2">
<linearGradient
id="AP-4-0"
osb:paint="solid">
<stop
style="stop-color:#5e5e5e;stop-opacity:1;"
offset="0"
id="stop5660" />
</linearGradient>
<linearGradient
id="linearGradient5640"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop5638" />
</linearGradient>
<linearGradient
id="linearGradient5634"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop5632" />
</linearGradient>
<linearGradient
id="linearGradient5628"
osb:paint="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop5626" />
</linearGradient>
<linearGradient
id="AP-3-7"
osb:paint="solid">
<stop
style="stop-color:#c678c5;stop-opacity:1;"
offset="0"
id="stop5498" />
</linearGradient>
<linearGradient
id="AP-2-3"
osb:paint="solid">
<stop
style="stop-color:#6d6d6d;stop-opacity:1;"
offset="0"
id="stop5230" />
</linearGradient>
<linearGradient
id="AP1-5"
osb:paint="solid">
<stop
style="stop-color:#f1007e;stop-opacity:1;"
offset="0"
id="stop5212" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#AP-3-7"
id="linearGradient5749"
gradientUnits="userSpaceOnUse"
x1="3319.292"
y1="-1291.2802"
x2="3344.3645"
y2="-1291.2802" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP1-5"
id="linearGradient7297-7"
gradientUnits="userSpaceOnUse"
x1="3241.6836"
y1="-1355.4329"
x2="3254.9529"
y2="-1355.4329" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP-2-3"
id="linearGradient7303-7"
gradientUnits="userSpaceOnUse"
x1="3225.7603"
y1="-1355.4329"
x2="3239.0295"
y2="-1355.4329" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP1-5"
id="linearGradient8308"
gradientUnits="userSpaceOnUse"
x1="3241.6836"
y1="-1355.4329"
x2="3254.9529"
y2="-1355.4329" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP1-5"
id="linearGradient8310"
gradientUnits="userSpaceOnUse"
x1="3241.6836"
y1="-1355.4329"
x2="3254.9529"
y2="-1355.4329" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP1-5"
id="linearGradient8312"
gradientUnits="userSpaceOnUse"
x1="3241.6836"
y1="-1355.4329"
x2="3254.9529"
y2="-1355.4329" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP-2-3"
id="linearGradient8314"
gradientUnits="userSpaceOnUse"
x1="3225.7603"
y1="-1355.4329"
x2="3239.0295"
y2="-1355.4329"
gradientTransform="matrix(3.7000834,0,0,3.7000834,-11935.582,4544.6634)" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP-2-3"
id="linearGradient5188"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.42732603,0,0,0.42732603,-1363.3009,454.91899)"
x1="3269.126"
y1="-1354.6217"
x2="3322.1943"
y2="-1354.6217" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP-2-3"
id="linearGradient4523"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.5811973,0,0,3.5811973,-11532.084,4918.1922)"
x1="3269.126"
y1="-1354.6217"
x2="3322.1943"
y2="-1354.6217" />
<linearGradient
inkscape:collect="always"
xlink:href="#AP1-5"
id="linearGradient4526"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.5811973,0,0,3.5811973,-11528.758,4918.1922)"
x1="3323.9951"
y1="-1356.5363"
x2="3349.0676"
y2="-1356.5363" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.14509804"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.5"
inkscape:cx="395.506"
inkscape:cy="-201.19903"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-global="true"
showguides="false"
inkscape:guide-bbox="true"
showborder="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="false"
borderlayer="false"
units="px">
<inkscape:grid
type="xygrid"
id="grid4572"
enabled="false"
originx="7.1437514"
originy="-404.28382" />
<inkscape:grid
type="axonomgrid"
id="grid4574"
units="mm"
empspacing="12"
originx="7.1437514"
originy="-404.28382"
enabled="false" />
<sodipodi:guide
position="3278.981,1256.5057"
orientation="0,1"
id="guide5059"
inkscape:locked="false" />
<sodipodi:guide
position="3278.981,1238.2495"
orientation="0,1"
id="guide5061"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>ActivityPub logo</dc:title>
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
<dc:date>2017-04-15</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Robert Martinez</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>ActivityPub</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
style="opacity:1"
transform="translate(7.1437516,141.67967)">
<path
style="fill:#000000;stroke-width:0.26458335"
d=""
id="path5497"
inkscape:connector-curvature="0" />
<g
id="g5197"
transform="translate(1.3229166)">
<g
id="g5132-90"
style="fill:url(#linearGradient7297-7);fill-opacity:1"
transform="matrix(0.9789804,0,0,0.9789804,-3157.9561,1202.4422)">
<g
transform="matrix(0.2553682,0,0,0.2553682,2615.9213,-1125.3113)"
id="g5080-78"
style="fill:url(#linearGradient8312);fill-opacity:1">
<path
inkscape:connector-curvature="0"
id="path5404-0-0"
d="m 2450.431,-937.13662 51.9615,30 v 12 l -51.9615,30 v -12 l 41.5693,-24 -41.5692,-24 z"
style="fill:url(#linearGradient8308);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
sodipodi:nodetypes="cccccccc" />
<path
sodipodi:nodetypes="cccc"
style="fill:url(#linearGradient8310);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 2450.431,-913.13662 20.7847,12 -20.7847,12 z"
id="path5406-6-3"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5127-1"
style="fill:url(#linearGradient7303-7);fill-opacity:1"
transform="matrix(0.9789804,0,0,0.9789804,-3157.9561,1202.4422)">
<path
id="path5467-2-0"
transform="matrix(0.27026418,0,0,0.27026418,3225.7603,-1228.2597)"
d="M 49.097656,-504.56641 0,-476.2207 v 11.33789 l 39.277344,-22.67578 v 45.35351 l 9.820312,5.66992 z m -19.638672,34.01563 -19.6406246,11.33789 19.6406246,11.33789 z"
style="fill:url(#linearGradient8314);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.25000042px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5203"
transform="matrix(2.2173353,0,0,2.2173353,-35.445741,150.88402)">
<g
id="g4523">
<path
sodipodi:nodetypes="scscscscsscscscscscccccccccccccccscsccccscscccccccccccscsccccscsccccccccccccscscccsccccscscsccccscccccccccccccccccccccccccccccscssccccccccc"
inkscape:connector-curvature="0"
id="text5037-6"
transform="matrix(0.1193249,0,0,0.1193249,12.763965,-131.94382)"
d="m 263.22656,34.349609 c -1.66644,0 -2.95278,0.477436 -3.85742,1.429688 -0.90464,0.904639 -1.35742,2.069669 -1.35742,3.498047 0,1.428378 0.45278,2.59536 1.35742,3.5 0.90464,0.857027 2.19098,1.285156 3.85742,1.285156 1.66644,0 2.99818,-0.428129 3.99805,-1.285156 0.99986,-0.857027 1.5,-2.024009 1.5,-3.5 0,-1.475991 -0.50014,-2.665673 -1.5,-3.570313 -0.99987,-0.904639 -2.33161,-1.357422 -3.99805,-1.357422 z m 43.95117,0 c -1.66644,0 -2.95082,0.477436 -3.85546,1.429688 -0.90464,0.904639 -1.35743,2.069669 -1.35743,3.498047 0,1.428378 0.45279,2.59536 1.35743,3.5 0.90464,0.857027 2.18902,1.285156 3.85546,1.285156 1.66645,0 3.00014,-0.428129 4,-1.285156 0.99987,-0.857027 1.5,-2.024009 1.5,-3.5 0,-1.475991 -0.50013,-2.665673 -1.5,-3.570313 -0.99986,-0.904639 -2.33355,-1.357422 -4,-1.357422 z m -118.46166,0.357422 -14.49805,50.351563 h 8.92774 l 2.92773,-11.285156 h 11.78516 l 3.07031,11.285156 h 9.42773 L 195.78638,34.707031 Z m 58.71166,5.285157 -8.49804,2.642578 v 6.71289 h -3.92774 v 7.570313 h 3.92774 v 18.71289 c 0,3.713784 0.66684,6.356519 2,7.927735 1.38076,1.571216 3.42866,2.355468 6.14258,2.355468 1.5236,0 2.9747,-0.189411 4.35546,-0.570312 1.38077,-0.333288 2.59511,-0.761418 3.64258,-1.285156 L 254,77.273438 c -0.66658,0.285675 -1.28607,0.49974 -1.85742,0.642578 -0.57135,0.142837 -1.2155,0.214843 -1.92969,0.214843 -1.04748,0 -1.78438,-0.430082 -2.21289,-1.287109 -0.3809,-0.857027 -0.57227,-2.308127 -0.57227,-4.355469 V 56.917969 h 6.92774 v -7.570313 h -6.92774 z m 80.23243,0 -8.49805,2.642578 v 6.71289 h -3.92969 v 7.570313 h 3.92969 v 18.71289 c 0,3.713784 0.66489,6.356519 1.99805,7.927735 1.38076,1.571216 3.42866,2.355468 6.14257,2.355468 1.52361,0 2.97666,-0.189411 4.35743,-0.570312 1.38076,-0.333288 2.5951,-0.761418 3.64257,-1.285156 l -1.07226,-6.785156 c -0.66658,0.285675 -1.28607,0.49974 -1.85742,0.642578 -0.57135,0.142837 -1.21355,0.214843 -1.92774,0.214843 -1.04747,0 -1.78437,-0.430082 -2.21289,-1.287109 -0.3809,-0.857027 -0.57226,-2.308127 -0.57226,-4.355469 V 56.917969 h 6.92773 v -7.570313 h -6.92773 z m -135.65894,6.855468 h 0.28516 l 1.14453,7.857422 2.85547,11.640625 h -8.2832 l 2.78515,-11.570312 z m 31.94605,1.572266 c -4.33275,0 -7.61963,1.570458 -9.85743,4.71289 -2.23779,3.142433 -3.35546,7.833061 -3.35546,14.070313 0,2.856756 0.21406,5.452139 0.64257,7.785156 0.47613,2.285405 1.23768,4.261293 2.28516,5.927735 1.04748,1.618828 2.38117,2.880516 4,3.785156 1.66644,0.857027 3.71238,1.285156 6.14062,1.285156 1.66645,0 3.33356,-0.238718 5,-0.714844 1.66645,-0.476126 3.09485,-1.190326 4.28516,-2.142578 l -1.78516,-6.570312 c -0.71418,0.476126 -1.50039,0.881555 -2.35742,1.214844 -0.80941,0.285675 -1.80968,0.427734 -3,0.427734 -2.23779,0 -3.88025,-1.022971 -4.92773,-3.070313 -0.99987,-2.047342 -1.5,-4.690077 -1.5,-7.927734 0,-3.856621 0.50013,-6.641415 1.5,-8.355469 0.99986,-1.761666 2.50027,-2.642578 4.5,-2.642578 1.09509,0 2.02335,0.117406 2.78515,0.355469 0.80942,0.19045 1.64298,0.501174 2.5,0.929687 l 2,-7.070312 c -1.04747,-0.571351 -2.26181,-1.048787 -3.64257,-1.429688 -1.33316,-0.3809 -3.07033,-0.570312 -5.21289,-0.570312 z m 35.06445,0.927734 v 35.710938 h 8.5 V 49.347656 Z m 11.05469,0 12.64257,36.066406 h 5.7129 l 11.99804,-36.066406 h -9.14062 l -4.42774,18.570313 -0.78711,5.71289 h -0.28515 l -0.85742,-5.642578 -4.92774,-18.640625 z m 32.89843,0 v 35.710938 h 8.49805 V 49.347656 Z m 33.53125,0 12.42774,35.710938 c -0.28568,1.571216 -0.64375,2.832904 -1.07227,3.785156 -0.42851,0.952252 -0.92865,1.641799 -1.5,2.070312 -0.52374,0.476127 -1.11858,0.714844 -1.78515,0.714844 -0.61897,0.04761 -1.23846,-0.04905 -1.85743,-0.287109 l -1.42773,7.285156 c 0.66658,0.380901 1.45278,0.642319 2.35742,0.785156 0.95225,0.190451 1.92787,0.28711 2.92774,0.28711 1.42837,0 2.64271,-0.430083 3.64257,-1.28711 1.04748,-0.809414 1.97575,-1.999096 2.78516,-3.570312 0.80941,-1.571216 1.57097,-3.475098 2.28516,-5.712891 0.71419,-2.237792 1.47574,-4.761168 2.28515,-7.570312 l 8.92774,-32.210938 h -8.71289 l -4.14258,19.998047 -0.64258,5.642578 h -0.35742 l -0.92774,-5.572265 -5,-20.06836 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:8.52205467px;line-height:2.53632545px;font-family:'PT Sans Narrow';-inkscape-font-specification:'PT Sans Narrow Bold Condensed';letter-spacing:0.22319667px;word-spacing:2.60024095px;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4523);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.27365798px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
id="text5065-3"
transform="matrix(0.1193249,0,0,0.1193249,12.763965,-131.94382)"
d="m 386.9082,34.349609 c -2.04734,0 -4.09523,0.119359 -6.14258,0.357422 -2.04734,0.190451 -3.92657,0.476521 -5.64062,0.857422 v 49.494141 h 8.99805 V 67.845703 c 0.19045,0.04761 0.49922,0.09497 0.92773,0.142578 l 1.42969,0.142578 h 1.35742 0.92773 c 2.04735,0 4.02324,-0.30877 5.92774,-0.927734 1.95212,-0.618964 3.66659,-1.619234 5.14258,-3 1.47599,-1.380766 2.64102,-3.165289 3.49804,-5.355469 0.90464,-2.19018 1.35743,-4.857568 1.35743,-8 0,-3.47572 -0.52284,-6.285167 -1.57032,-8.427734 -1.04747,-2.19018 -2.40582,-3.879997 -4.07226,-5.070313 -1.66644,-1.190315 -3.57033,-1.976521 -5.71289,-2.357421 -2.09496,-0.428514 -4.23756,-0.642579 -6.42774,-0.642579 z m 51.72461,0.714844 v 48.564453 c 1.14271,0.571352 2.76052,1.09614 4.85547,1.572266 2.14257,0.476126 4.47653,0.71289 7,0.71289 4.61842,0 8.25948,-1.570458 10.92578,-4.71289 2.66631,-3.190045 4,-8.164791 4,-14.925781 0,-6.237252 -0.95292,-10.761169 -2.85742,-13.570313 -1.85689,-2.809144 -4.47497,-4.214844 -7.85547,-4.214844 -3.19004,0 -5.64141,1.047624 -7.35547,3.142578 h -0.21484 V 35.064453 Z m -50.86719,7.285156 c 0.99987,0 1.95279,0.142059 2.85743,0.427735 0.90464,0.285675 1.68889,0.761158 2.35547,1.427734 0.71418,0.618964 1.26167,1.477176 1.64257,2.572266 0.42852,1.09509 0.64258,2.428784 0.64258,4 0,1.856891 -0.21406,3.402697 -0.64258,4.640625 -0.42851,1.190315 -1.02335,2.143233 -1.78515,2.857422 -0.71419,0.666576 -1.54775,1.142058 -2.5,1.427734 -0.95225,0.285676 -1.95057,0.429687 -2.99805,0.429687 -0.28568,10e-7 -0.83316,-0.02465 -1.64258,-0.07227 -0.7618,-0.09522 -1.28659,-0.189931 -1.57226,-0.285156 v -17.06836 c 0.95225,-0.238063 2.16658,-0.357422 3.64257,-0.357422 z m 20.31836,6.998047 v 23.210938 c 0,2.666306 0.21407,4.880911 0.64258,6.642578 0.42852,1.714054 1.04606,3.070448 1.85547,4.070312 0.80942,0.999865 1.78699,1.691365 2.92969,2.072266 1.1427,0.428513 2.45174,0.642578 3.92773,0.642578 2.28541,0 4.18929,-0.547488 5.71289,-1.642578 1.57122,-1.09509 2.81021,-2.476137 3.71485,-4.142578 h 0.21289 l 1.5,4.857422 h 6.42773 c -0.3809,-1.523604 -0.64232,-3.215374 -0.78515,-5.072266 -0.14284,-1.904504 -0.21485,-3.833039 -0.21485,-5.785156 V 49.347656 h -8.49804 v 23.853516 c -0.38091,1.380765 -1.02505,2.572401 -1.92969,3.572266 -0.90464,0.952252 -2.02232,1.427734 -3.35547,1.427734 -1.38077,0 -2.33368,-0.547488 -2.85742,-1.642578 -0.52374,-1.09509 -0.78516,-3.046325 -0.78516,-5.855469 V 49.347656 Z m 43.83204,6.927735 c 1.61882,0 2.80851,0.858211 3.57031,2.572265 0.7618,1.666441 1.14258,4.307223 1.14258,7.925782 0,4.094684 -0.47549,7.023489 -1.42774,8.785156 -0.95225,1.714054 -2.3333,2.572265 -4.14258,2.572265 -1.61882,0 -2.92787,-0.26337 -3.92773,-0.787109 V 59.990234 c 0.80941,-2.475855 2.40453,-3.714843 4.78516,-3.714843 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:8.52205467px;line-height:2.53632545px;font-family:'PT Sans Narrow';-inkscape-font-specification:'PT Sans Narrow Bold Condensed';letter-spacing:0.22319667px;word-spacing:2.60024095px;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4526);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.24196777px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

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