b0392b8fc3
* Warn users on unsupported browsers before they lack features Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update Learn more link Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update toast styles to match Figma Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Remove test code Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * update tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update snapshots --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
135 lines
5.1 KiB
TypeScript
135 lines
5.1 KiB
TypeScript
/*
|
|
Copyright 2017-2021 The Matrix.org Foundation C.I.C.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
import { SyncState } from "matrix-js-sdk/src/matrix";
|
|
import { MINIMUM_MATRIX_VERSION, SUPPORTED_MATRIX_VERSIONS } from "matrix-js-sdk/src/version-support";
|
|
import { logger } from "matrix-js-sdk/src/logger";
|
|
|
|
import { Action } from "../dispatcher/actions";
|
|
import dis from "../dispatcher/dispatcher";
|
|
import { ActionPayload } from "../dispatcher/payloads";
|
|
import { DoAfterSyncPreparedPayload } from "../dispatcher/payloads/DoAfterSyncPreparedPayload";
|
|
import { AsyncStore } from "./AsyncStore";
|
|
import { MatrixClientPeg } from "../MatrixClientPeg";
|
|
import ToastStore from "./ToastStore";
|
|
import { _t } from "../languageHandler";
|
|
import SdkConfig from "../SdkConfig";
|
|
import GenericToast from "../components/views/toasts/GenericToast";
|
|
|
|
interface IState {
|
|
deferredAction: ActionPayload | null;
|
|
}
|
|
|
|
const INITIAL_STATE: IState = {
|
|
deferredAction: null,
|
|
};
|
|
|
|
/**
|
|
* A class for storing application state to do with authentication. This is a simple
|
|
* store that listens for actions and updates its state accordingly, informing any
|
|
* listeners (views) of state changes.
|
|
*/
|
|
class LifecycleStore extends AsyncStore<IState> {
|
|
public constructor() {
|
|
super(dis, INITIAL_STATE);
|
|
}
|
|
|
|
protected onDispatch(payload: ActionPayload | DoAfterSyncPreparedPayload<ActionPayload>): void {
|
|
switch (payload.action) {
|
|
case Action.DoAfterSyncPrepared:
|
|
this.updateState({
|
|
deferredAction: payload.deferred_action,
|
|
});
|
|
break;
|
|
case "cancel_after_sync_prepared":
|
|
this.updateState({
|
|
deferredAction: null,
|
|
});
|
|
break;
|
|
case "MatrixActions.sync": {
|
|
if (payload.state === SyncState.Syncing && payload.prevState !== SyncState.Syncing) {
|
|
// We've reconnected to the server: update server version support
|
|
// This is async but we don't care about the result, so just fire & forget.
|
|
checkServerVersions();
|
|
}
|
|
|
|
if (payload.state !== "PREPARED") {
|
|
break;
|
|
}
|
|
if (!this.state.deferredAction) break;
|
|
const deferredAction = Object.assign({}, this.state.deferredAction);
|
|
this.updateState({
|
|
deferredAction: null,
|
|
});
|
|
dis.dispatch(deferredAction);
|
|
break;
|
|
}
|
|
case "on_client_not_viable":
|
|
case Action.OnLoggedOut:
|
|
this.reset();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function checkServerVersions(): Promise<void> {
|
|
try {
|
|
const client = MatrixClientPeg.get();
|
|
if (!client) return;
|
|
for (const version of SUPPORTED_MATRIX_VERSIONS) {
|
|
// Check if the server supports this spec version. (`isVersionSupported` caches the response, so this loop will
|
|
// only make a single HTTP request).
|
|
// Note that although we do this on a reconnect, we cache the server's versions in memory
|
|
// indefinitely, so it will only ever trigger the toast on the first connection after a fresh
|
|
// restart of the client.
|
|
if (await client.isVersionSupported(version)) {
|
|
// we found a compatible spec version
|
|
return;
|
|
}
|
|
}
|
|
|
|
// This is retrospective doc having debated about the exactly what this toast is for, but
|
|
// our guess is that it's a nudge to update, or ask your HS admin to update your Homeserver
|
|
// after a new version of Element has come out, in a way that doesn't lock you out of all
|
|
// your messages.
|
|
const toastKey = "LEGACY_SERVER";
|
|
ToastStore.sharedInstance().addOrReplaceToast({
|
|
key: toastKey,
|
|
title: _t("unsupported_server_title"),
|
|
props: {
|
|
description: _t("unsupported_server_description", {
|
|
version: MINIMUM_MATRIX_VERSION,
|
|
brand: SdkConfig.get().brand,
|
|
}),
|
|
primaryLabel: _t("action|ok"),
|
|
onPrimaryClick: () => {
|
|
ToastStore.sharedInstance().dismissToast(toastKey);
|
|
},
|
|
},
|
|
component: GenericToast,
|
|
priority: 98,
|
|
});
|
|
} catch (e) {
|
|
logger.warn("Failed to check server versions", e);
|
|
}
|
|
}
|
|
|
|
let singletonLifecycleStore: LifecycleStore | null = null;
|
|
if (!singletonLifecycleStore) {
|
|
singletonLifecycleStore = new LifecycleStore();
|
|
}
|
|
export default singletonLifecycleStore!;
|