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>
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>
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>
- 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>
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>
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>
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>
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>
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>
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
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
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>
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>
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>
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>
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>
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>
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>
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>
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>
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
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
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>
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>
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
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>
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>
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>
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>
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>
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>
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
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>
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>
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>
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>
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>
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
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
... 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>
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>
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>
... 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>
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>
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>
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>
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>