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