1
0
mirror of git://jb55.com/damus synced 2024-09-16 02:03:45 +00:00
Go to file
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
.github/workflows Run actions on pushes to the ci branch 2023-07-14 09:34:29 -07:00
damus Fix UI freeze after swiping back from profile (#1449) 2023-09-23 08:03:32 -07:00
damus-c damus-c: remove UTF-8 punctuation from hashtags 2023-09-15 12:31:17 -05:00
damus.xcodeproj v1.6 (18) 2023-09-21 18:05:59 -04:00
damusTests tests: add ndb support to tests 2023-09-21 09:10:06 -04:00
damusUITests initial commit 2022-04-02 16:57:42 -07:00
devtools script: fetch popular users 2023-05-24 18:26:18 -07:00
docs docs: people like centralized tools 2023-08-21 13:26:33 -07:00
flatbuffers add swift flatbuffers 2023-08-26 20:46:42 -07:00
nostrdb ndb: switch to case-insensitive profile searches 2023-09-21 18:03:22 -04:00
nostrscript ndb: switch to nostrdb notes 2023-08-03 13:20:36 -07:00
.envrc v1.6 changelog 2023-07-04 12:21:12 -07:00
.gitignore config: show git hash in version info 2023-08-01 09:29:09 -07:00
.mailmap update bad commit mailmap 2023-07-14 22:25:19 -07:00
.rgignore add .rgignore 2023-04-02 09:07:20 -07:00
CHANGELOG.md v1.6 (18) changelog 2023-09-21 18:08:56 -04:00
LICENSE add license 2022-04-16 15:11:03 -07:00
Makefile make: add tags target 2023-08-06 13:50:20 -07:00
Package.swift Replace Starscream with URLSessionWebSocketTask 2023-04-24 18:11:07 -07:00
README.md docs: add patch submission guidelines 2023-07-10 16:22:09 -07:00
shell.nix todo: add local todo helper 2023-08-06 13:50:20 -07:00
ss.png screenshots 2022-06-21 08:32:56 -07:00
TODO todo: add local todo helper 2023-08-06 13:50:20 -07:00
transifex.yml Fix localization issues, and export and import translations 2023-03-16 23:00:52 -04:00

Run Test Suite

damus

A twitter-like nostr client for iPhone, iPad and MacOS.

Spec Compliance

damus implements the following Nostr Implementation Possibilities

Getting Started on Damus

Damus iOS

  1. Get the Damus app on the iOS App Store: https://apps.apple.com/ca/app/damus/id1628663131

⚙️ Settings (gear icon, top right)

  • Relays: You can add more relays to send your notes to by tapping the "+".
  • 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!
    • Save your keys somewhere safe
  • Log out

🏠 Personal Feed (home icon, bottom navigation)

  • Feed from everyone you follow
  • Can post notes by tapping the blue + button

Notes (under 🏠 Personal Feed)

  • Sending a Note is easy and it goes to both your 🏠 Personal and 🔍 Global Feeds
  • To tag a user you must grab their pubkey:
    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.
  • 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
  • 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

🔍 Global Feed (magnify glass, bottom navigation)

  • View the Global Feed from all the relays you've added in ⚙️ Settings. Currently you can only search hashtags and user names and pubkeys

🔔 Notifications

  • All your notifications except 💬 DMs

👤 Change Your Profile (PFP) and Bio

  1. Go to your Profile Page on Damus app
  2. Tap on Edit button at the top
  3. You will see text fields to update your information and bio
  4. For PFP, insert a URL containing your image (support video: https://cdn.jb55.com/vid/pfp-editor.mp4)
  5. Save

Request Sats

(Sats or Satoshis are the smallest denomination of bitcoin)

Alby (browser extension)

  • Get the Alby browser extension and create your Alby address [yourname]@getalby.com or connect your existing Lightning wallet
  • Convert your Damus secret key from nsec to hex at https://damus.io/key then go to Settings in Alby and under the Nostr section at the bottom of the page add your private hex key. You can also generate new address in the extension
  • Click the Alby extension > click Receive > enter the amount of Sats > click Get Invoice > click Copy > then paste into Damus
  • Note: On Damus Web it will appear as a string of characters but on Damus iOS it will appear as a clickable image

Zeus (mobile app)

  • Download Zeus app (iOS, Google, APK)
  • Tap Get Started button > tap Connect a node > click on + sign (top right) > select Indhub > press Scan Lndhub QR > (from the Alby browser extension… click your account on the top left > click Manage Accounts > click 3-dot menu to right of your account and click Export Account to get a QR code then go back to Zeus app) > scan the QR Code and tap Save Node Config button
  • To create an invoice tap Lightning > tap Receive > type in amount > tap Create Invoice > tap Copy Invoice > paste into a new Damus note

Contributing

Contributors welcome! Start by examining known issues: https://github.com/damus-io/damus/issues.

Mailing lists

We have a few mailing lists that anyone can join to get involved in damus development:

  • dev - development discussions
  • patches - code submission and review
  • product - product discussions
  • design - design discussions

Contributing

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

Translations

Translators welcome! Join the Transifex project.

All user-facing strings must have a comment in order to provide context to translators. If a SwiftUI component has a comment parameter, use that. Otherwise, wrap your string with NSLocalizedString with the comment field populated.

Awards

There may be nostr badges awarded for contributors in the future... :)

First contributors:

  1. @randymcmillan
  2. @jcarucci27

git log bot

npub1fjtdwclt9lspjy8huu3qklr7eklp5uq90u6yh8mec290pqxraccqlufnas