-
Notifications
You must be signed in to change notification settings - Fork 3
Interfacing with Rust
This page is a draft, and can be renamed/updated anytime. I just want to start writing down what I have in mind so we can all discuss on something and iterate.
As it would be require a lot of housekeeping to have one page per view/screen, I will group them in features and list them with headings, in alphabetical order.
I also added priorities to requirements, so we can do what to do first.
Requirements:
- Form validation (low priority)
- A call to
ProseCore
to check if the JID is correct- Debounce keystrokes then
String -> Result<JID, JIDParsingError>
- Debounce keystrokes then
- A call to
- Log in button (high priority)
- A call to
ProseCore
with a JID and a password, sending back either a success or a failure.- Shape:
(JID, String) async -> Result<LoginRoute, AuthenticationError>
LoginRoute: .basic(BasicAuthState) | .mfa(MFAState) | .success(UserCredentials)
BasicAuthState: (String, String)
-
MFAState: .digits(String)
- Make it an
enum
, so we can support other types in the future
- Make it an
- Do we need an extra security for passing the password around?
- What do we need in
UserCredentials
? We'll see with other screens / XMPP spec (@valeriansaliou what do you think?)
- Shape:
- This triggers a login call on the backend, possibly asking for a MFA
- A call to
- Lost password (low priority)
- ??? (link?)
- No account (low priority)
- Read guide: link
Requirements:
- Confirmation code (low priority)
- A call to
ProseCore
with a JID (I don't know MFA, you probably have some kind of token for a request? @valeriansaliou) and the confirmation code- Shape:
(JID, String) async -> Result<LoginRoute, MFAError>
- Shape:
- A call to
- Code generation error (low priority)
- Link?
- No account yet (low priority)
route: LoginRoute = .basic(.init())
This is not a screen (although it could be), but rather an action handled by the
authenticationReducer
.
Requirements:
- Persist the credentials in the Keychain (@nesium or somewhere else?) (high priority)
- Add some kind of prefix, we might need to store multiple credentials on the same machine
- Start the main app (high priority)
- TODO (need access to
NSWindow
)
- TODO (need access to
This is not a screen (although it could be), but rather an action handled by the
authenticationReducer
.
Requirements:
- Request the user's vCard (@valeriansaliou if not already in the credentials?) (high priority)
- @valeriansaliou Is there a "public" and "private" vCard or is there only one version for everyone?
- Request the server's vCard (high priority)
- We will need it for account descriptions
- Shape:
(JIDDomain) async -> Result<VCard, ContactError>
- Request the user's contacts (to the server, not address book permision to the user) (high priority)
- @valeriansaliou can XMPP do this? Or is it only possible to have this from the previous conversations a user had?
- I guess it's what's called the "roster" https://datatracker.ietf.org/doc/html/rfc6121#section-2
- Shape:
(JID) async -> Result<[VCard], ContactError>
or(JID) async -> Stream<Result<VCard, ContactError>>
- @valeriansaliou Probably not a
JID
in input
- @valeriansaliou Probably not a
- @valeriansaliou can XMPP do this? Or is it only possible to have this from the previous conversations a user had?
- Start streaming incoming messages
- Shape:
(JID) -> AnyPublisher<Message, Never>
- @valeriansaliou Probably not a
JID
in input -
Message: (from: JID, to: JID, content: String, attachments: ???)
-
to
is required, as we need to know if the message goes to a group or in the DMs for example - How to know if it's in a thread? I don't remember the XEP
-
- @valeriansaliou Probably not a
- When receiving a message, the reducer:
- Adds a new entry in the unread stack
- Adds a new entry in the "Replies", "Direct messages" or "People & groups" depending on the origin of the message
- Adds a new entry in the correct conversation
- Shape:
- Subscribe to push notifications
- I don't know how this is handled
We're talking about the middle view, the chat with the bar.
Notes:
- Store the messages in a ring buffer, to avoid storing too many messages in memory
- Keep the unread count separated from the collection of messages, to allow emptying the collection (for memory cleanup) and to improve performance (no
reduce(0, +)
on all messages to find the count) - After some time, empty the message buffer, to free some memory?
- Reset the timer every time a new message arrives in this conversation, as the user might probably want to open the conversation after a notification
Requirements:
- When opening a chat
- Subscribe to "typing" notifications
- Shape:
(JID) -> AnyPublisher<JID, Never>
or(JID) -> AnyPublisher<String, Never>
- Store in a
SortedSet
, to avoid duplicates and keep typing order (otherwise it could look bad when updating the list)
- Shape:
- Subscribe to "typing" notifications
- When closing a chat
- Unsubscribe from "typing" notifications (we're not currently displaying it in the sidebar)
We're talking about the pane on the right side.
Requirements:
- When opening the pane
- Fetch the user/group vCard
- Subscribe to presence nofitications (XEP-0012/XEP-0256, which one?)
- This allow displaying "Active 1 min ago" for example
- On receive
- If the presence is "away" or "xa"
- Map the date to a string for the state (i.e. "Active 1 min ago")
- Depending on the scale (minutes/hours/days), start a recurring task which will update the state's message (i.e. "Active 2 mins ago")
- If the presence is "online" (not sure about this one)
- Change the state's message
- Cancel any timer updating the presence string
- If the presence is "away" or "xa"
- When closing the pane
- Unsubscribe from presence nofitications (XEP-0012/XEP-0256, which one?)
- Stop presence timer