# Remote desktop / mobile implementation details

This follows the previous RFC for [remote profiles](./2023-09-12-remote-profile.md).

Code uses terms remote controller and remote host to designate the roles, and CLI client can support both.

This document uses the terms "mobile" to mean remote host and "desktop" to mean remote controller, mobile apps will only support "remote host" role (via UI, and, possibly, via the compilation flag to remove this functionality from the code), and desktop will only support "remote controller" role.

## Mobile (host)

UX is described [here](./2023-09-12-remote-profile.md#on-a-mobile-device).

When mobile is connected to the remote desktop it will receive no events from the core (other than remote session connection status changes), and the core will accept no commands from the UI (other than to terminate the remote session).

As currently mobile maintains the list of connection statuses for all profiles, this state will have to be maintained in Haskell to be able to send it to the remote desktop UI when it is connected. It will also be used to update mobile UI when control is returned to the mobile.

The switching between remote host role and local UI role should prevent the possibility of any race conditions.

To swith to remote host role:
- UI: will show the screen with "connected" status and "cancel" button, with disabled sleep timer on iOS, as iOS app will have to stay in foregro. Android will be able to function in background in this state.
- core: stop adding events to the output queues (via some flag).
- UI: process remaining events in the output queue and stop receiving them.
- core: stop sending events to and accepting commands from UI.
- core: send current list of profiles, coversations, and connections statuses to the remote desktop.
- core: start sending events to and accepting commands from remote desktop.
- core: start adding events to remote output queue.

To switch back to local UI role:
- core: stop adding events to the output queues.
- core: stop receiving commands from and sending events to remote desktop.
- remote desktop: receive pending events and stop processing them.
- UI: load current list of profiles, conversations, and connection statuses from the core.
- UI: start receiving events
- core: start sending events to and accepting commands from local UI.
- core: start adding events to UI local remote output queue.

Possibly, there is a simpler way to switch, but it is important that the new events are applied to the loaded state, to avoid state being out of sync.

## Desktop (controller)

Desktop can either control local profiles ("local host" term is used) or remote host(s)/mobile(s). Only one host, local or remote, can be controlled at a time. It is important though to be able to receive notifications from multiple hosts, at the very least from local and mobile, as the important use case is this:

- mobile device only has contacts and important groups to save the traffic and battery.
- desktop has large public groups.

So while reading large public groups the users should be able to receive notifications from both mobile device and local profile(s).

That means that while only one host can be active in desktop, multiple hosts can be connected.

Current UI model contains:
- the list of the conversations for the chosen profile.
- the list of the user profiles.
- the statuses of connections across all profiles - this is maintained because the core does not track connection statuses.

As the core will start maintaining the connection statuses, as a possible optimisation we could reduce the connections in the UI to only the current profile and reset it every time the profile is switched.

In addition to the above, the UI model will need to contain the list of connected remote hosts (mobiles), so that the user can switch between them.

Switching profile currently updates the list of conversations. If connection statuses are narrowed to the current profile only, they will have to be updated as well.

When switching host (whether to local or to remote), the UI will have to:
- update the list of profiles
- update the list of conversations for the active profile in the host
- update connection statuses, either for all profiles or for the active profile only - TBC

When connected to remote host, or possibly always, UI will have to use the extended FFI to indicate the host in all commands (e.g., to allow automatic file reception in inactive hosts) - as the core cannot simply assume which host is active. Probably, some of the commands (most of them) should require the host to match the currently active host in the core, file reception will not require that.

### Onboarding and "only-remote" desktop

Majority of the users want to use desktop in "remote-only" role, when there is no local profile. Currently, it is a global assumption that the core has an active profile for most commands. Possible solutions to that are:

- update core to allow functioning without local profile.
- create an invisible phantom profile that won't be shown in the UI but will be used by the core to process commands related to remote hosts (connected mobiles).

The 2nd option seems simpler. The phantom profile will use an empty string as display name, and, possibly an additional flag to mark it as phantom. Once a real profile is created this phatom one can be removed (or can be just abandoned). It might be better to block most commands for this phantom profile?

Onboarding on desktop will need to be re-implemented to offer connecting to mobile as primary option and creating a local profile as secondary, and from the users' point of view they will not be creating any local profiles.

## Loading files

Currently active UI, either remote (desktop) or local (mobile), will be making the decision to auto-receive file, based on its own local settings. It seems a better trade-off than alternatives, and also allows for different auto-receive configurations based on the device.

Forwarding received and uploading sent files to/from desktop is already implemented.

It is still required to implement both commands API in FFI layer and, possibly, HTTP API to download files to desktop when they are:
- shown in the UI for images.
- played for voice and video messages.
- saved for any other files.
