Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/BasePlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default abstract class BasePlatform {

protected onAction(payload: ActionPayload): void {
switch (payload.action) {
case "on_client_not_viable":
case Action.ClientNotViable:
case Action.OnLoggedOut:
this.setNotificationCount(0);
break;
Expand Down
17 changes: 14 additions & 3 deletions src/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,9 @@ async function abortLogin(): Promise<void> {
}

/** Attempt to restore the session from localStorage or indexeddb.
*
* If the credentials are found, and the session is successfully restored,
* emits {@link Action.OnLoggedIn}, {@link Action.WillStartClient} and {@link Action.StartedClient}.
*
* @returns true if a session was found; false if no existing session was found.
*
Expand Down Expand Up @@ -787,6 +790,8 @@ async function createOidcTokenRefresher(credentials: IMatrixClientCreds): Promis
* optionally clears localstorage, persists new credentials
* to localstorage, starts the new client.
*
* Emits {@link Action.OnLoggedIn}, {@link Action.WillStartClient} and {@link Action.StartedClient}.
*
* @param {IMatrixClientCreds} credentials The credentials to use
* @param {Boolean} clearStorageEnabled True to clear storage before starting the new client
* @param {Boolean} isFreshLogin True if this is a fresh login, false if it is previous session being restored
Expand Down Expand Up @@ -1001,7 +1006,7 @@ export function softLogout(): void {
// Ensure that we dispatch a view change **before** stopping the client so
// so that React components unmount first. This avoids React soft crashes
// that can occur when components try to use a null client.
dis.dispatch({ action: "on_client_not_viable" }); // generic version of on_logged_out
dis.dispatch({ action: Action.ClientNotViable }); // generic version of on_logged_out
stopMatrixClient(/*unsetClient=*/ false);

// DO NOT CALL LOGOUT. A soft logout preserves data, logout does not.
Expand All @@ -1019,6 +1024,12 @@ export function isLoggingOut(): boolean {
* Starts the matrix client and all other react-sdk services that
* listen for events while a session is logged in.
*
* By the time this method is called, we have successfully logged in if necessary, and the client has been set up with
* the access token.
*
* Emits {@link Acction.WillStartClient} before starting the client, and {@link Action.ClientStarted} when the client has
* been started.
*
* @param client the matrix client to start
* @param startSyncing - `true` to actually start syncing the client.
* @param clientPegOpts - Options to pass through to {@link MatrixClientPeg.start}.
Expand All @@ -1034,7 +1045,7 @@ async function startMatrixClient(
// to add listeners for the 'sync' event so otherwise we'd have
// a race condition (and we need to dispatch synchronously for this
// to work).
dis.dispatch({ action: "will_start_client" }, true);
dis.dispatch({ action: Action.WillStartClient }, true);

// reset things first just in case
SdkContextClass.instance.typingStore.reset();
Expand Down Expand Up @@ -1080,7 +1091,7 @@ async function startMatrixClient(

// dispatch that we finished starting up to wire up any other bits
// of the matrix client that cannot be set prior to starting up.
dis.dispatch({ action: "client_started" });
dis.dispatch({ action: Action.ClientStarted });

if (isSoftLogout()) {
softLogout();
Expand Down
3 changes: 2 additions & 1 deletion src/Presence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { MatrixClientPeg } from "./MatrixClientPeg";
import dis from "./dispatcher/dispatcher";
import Timer from "./utils/Timer";
import { type ActionPayload } from "./dispatcher/payloads";
import { Action } from "./dispatcher/actions.ts";

// Time in ms after that a user is considered as unavailable/away
const UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
Expand Down Expand Up @@ -61,7 +62,7 @@ class Presence {
}

private onAction = (payload: ActionPayload): void => {
if (payload.action === "user_activity") {
if (payload.action === Action.UserActivity) {
this.setState(SetPresence.Online);
this.unavailableTimer?.restart();
}
Expand Down
5 changes: 2 additions & 3 deletions src/UserActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.

import dis from "./dispatcher/dispatcher";
import Timer from "./utils/Timer";
import { Action } from "./dispatcher/actions.ts";

// important these are larger than the timeouts of timers
// used with UserActivity.timeWhileActive*,
Expand Down Expand Up @@ -190,11 +191,9 @@ export default class UserActivity {
this.lastScreenY = event.screenY;
}

dis.dispatch({ action: "user_activity" });
dis.dispatch({ action: Action.UserActivity });
if (!this.activeNowTimeout.isRunning()) {
this.activeNowTimeout.start();
dis.dispatch({ action: "user_activity_start" });

UserActivity.runTimersUntilTimeout(this.attachedActiveNowTimers, this.activeNowTimeout);
} else {
this.activeNowTimeout.restart();
Expand Down
62 changes: 61 additions & 1 deletion src/Views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,67 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/

/** constants for MatrixChat.state.view */
/**
* Constants for MatrixChat.state.view.
*
* The `View` is the primary state machine of the application: it has different states for the various setup flows
* that the user may find themselves in. Once we have a functioning client, we can transition to the `LOGGED_IN` state
* which is the "normal" state of the application.
*
* An incomplete state transition diagram follows.
*
* (initial state)
* ┌─────────────────┐ Lock held by other instance ┌─────────────────┐
* │ LOADING │─────────────────────────────>│ CONFIRM_LOCK_ │
* │ │<─────────────────────────────│ THEFT │
* └─────────────────┘ Lock theft confirmed └─────────────────┘
* Session recovered │ │
* ┌────────────┘ └──────────────────────────────────┐
* │ │ No previous session
* │ ▼
* │ ┌─────────────────┐ ┌─────────────────┐
* │ │ SOFT_LOGOUT │ │ WELCOME │
* │ │ │ │ │
* │ └─────────────────┘ └─────────────────┘
* │ (transitions not shown) "Sign in" │ │ "Create Account"
* │ ┌───────┘ └─────┐
* │ │ │
* │ "Forgot ▼ "Create an ▼
* │ ┌─────────────────┐ password" ┌─────────────────┐ account" ┌─────────────────┐
* │ │ FORGOT_PASSWORD │<───────────────│ LOGIN │───────────────>│ REGISTER │
* │ │ │───────────────>│ │<───────────────│ │
* │ └─────────────────┘ Complete / └─────────────────┘ "Sign in here" └─────────────────┘
* │ "Sign in instead" │ │
* │ │ ┌──────────────────────┘
* │ ▼ ▼
* │ ┌───────────────────┐
* │ └───────────────────┘
* │ ┌────────────────────────────────────────┘ │ │
* │ │ ┌────────────────────┘ │
* │ │ E2EE not │ account has │ account lacks
* │ │ enabled │ cross-signing │ cross-signing
* │ │ │ keys │ keys
* │ │ ▼ ▼
* │ │ ┌─────────────────┐ ┌─────────────────┐
* │ │ │ COMPLETE_ │ │ E2E_SETUP │
* │ │ │ SECURITY │ │ │
* │ │ └─────────────────┘ └─────────────────┘
* │ │ ┌─────────────────────────┘ │
* │ │ │ ┌─────────────────────────────────────────────────┘
* │ │ │ │
* ▼ ▼ ▼ ▼
* ┌─────────────────┐
* │ LOGGED_IN │
* │ │
* └─────────────────┘
*
*
* (from all other states)
* ┌─────────────────┐
* │ LOCK_STOLEN │
* │ │
* └─────────────────┘
*/
enum Views {
// a special initial state which is only used at startup, while we are
// trying to re-animate a matrix client or register as a guest.
Expand Down
3 changes: 2 additions & 1 deletion src/components/structures/EmbeddedPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { MatrixClientPeg } from "../../MatrixClientPeg";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import AutoHideScrollbar from "./AutoHideScrollbar";
import { type ActionPayload } from "../../dispatcher/payloads";
import { Action } from "../../dispatcher/actions.ts";

interface IProps {
// URL to request embedded page content from
Expand Down Expand Up @@ -109,7 +110,7 @@ export default class EmbeddedPage extends React.PureComponent<IProps, IState> {

private onAction = (payload: ActionPayload): void => {
// HACK: Workaround for the context's MatrixClient not being set up at render time.
if (payload.action === "client_started") {
if (payload.action === Action.ClientStarted) {
this.forceUpdate();
}
};
Expand Down
Loading
Loading