Fix decryption errors + root cause, with new top-level state management
Background
Previously, the Circles app's top-level state management was one of the last -- maybe the last? -- real messes in the codebase. Lots of it was left over from the first days of the transition from matrix-ios-sdk to Matrix.swift, and it's apparent how fuzzy of an idea I had at the time re: how to organize things.
Problem
This all came to a head recently when I made what I thought was a simple fix, to not require login after registration. Instead, the new code just goes directly from signup -> setup -> logged in. Unfortunately, I tripped over some of this mess in doing so, and somehow the app no longer starts syncing when you re-open it to a signed-in account. This manifests mainly as decryption errors, but also as failure to post new messages.
Solution
This MR cleans up the top-level state management significantly. Now we have a set of well-defined states that our main CirclesStore can be in. And we have a very nearly linear flow from starting out with nothing, to being fully logged in and online with a user account, keys, Space hierarchy, and everything.
It works kind of like an Elm app (or a React app?) in that we have much cleaner separation of powers:
- The SwiftUI Views display the UI based on the current state, and where appropriate, they call functions to mutate the state
- Each function handles one state transition.
The second one is critical. We don't try to handle going from "I have nothing", to "I found credentials", to "I'm connected with the server", to "I have secret storage keys" etc, all in one fell swoop. Now we have fewer chances to miss something.
Other fixes
This MR also pulls in related updates from the latest Matrix.swift, including more modularization of the crypto functions, which get called more often after sending a message, so we don't accidentally leave something un-sent.
Closes #222 (closed)
Should also get #221 (closed)
(I was hoping this would get #223 (closed) as well, but no.)