Factor out post-login splash screen to a new component (#12103)
* Factor out post-login splash screen to a new component * Move CSS classes to per-component file * Rename CSS classes ... to reflect the component that uses them * code review
This commit is contained in:
parent
baaf8ad68b
commit
fd64eccd4a
7 changed files with 220 additions and 37 deletions
|
@ -92,6 +92,7 @@
|
|||
@import "./structures/auth/_CompleteSecurity.pcss";
|
||||
@import "./structures/auth/_ConfirmSessionLockTheftView.pcss";
|
||||
@import "./structures/auth/_Login.pcss";
|
||||
@import "./structures/auth/_LoginSplashView.pcss";
|
||||
@import "./structures/auth/_Registration.pcss";
|
||||
@import "./structures/auth/_SessionLockStolenView.pcss";
|
||||
@import "./structures/auth/_SetupEncryptionBody.pcss";
|
||||
|
|
|
@ -19,13 +19,6 @@ limitations under the License.
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_splashButtons {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_wrapper {
|
||||
display: flex;
|
||||
|
||||
|
@ -50,18 +43,6 @@ limitations under the License.
|
|||
min-height: 0;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_syncError {
|
||||
color: $accent-fg-color;
|
||||
background-color: #df2a8b; /* Only used here */
|
||||
border-radius: 5px;
|
||||
display: table;
|
||||
padding: 30px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
/* not the left panel, and not the resize handle, so the roomview and friends */
|
||||
.mx_MatrixChat > :not(.mx_LeftPanel):not(.mx_SpacePanel):not(.mx_ResizeHandle):not(.mx_LeftPanel_outerWrapper) {
|
||||
background-color: $background;
|
||||
|
|
34
res/css/structures/auth/_LoginSplashView.pcss
Normal file
34
res/css/structures/auth/_LoginSplashView.pcss
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2015-2024 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.
|
||||
*/
|
||||
|
||||
.mx_LoginSplashView_splashButtons {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
}
|
||||
|
||||
.mx_LoginSplashView_syncError {
|
||||
color: $accent-fg-color;
|
||||
background-color: #df2a8b; /* Only used here */
|
||||
border-radius: 5px;
|
||||
display: table;
|
||||
padding: 30px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2015-2022 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2015-2024 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.
|
||||
|
@ -60,7 +60,6 @@ import { _t, _td, getCurrentLanguage } from "../../languageHandler";
|
|||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import ThemeController from "../../settings/controllers/ThemeController";
|
||||
import { startAnyRegistrationFlow } from "../../Registration";
|
||||
import { messageForSyncError } from "../../utils/ErrorUtils";
|
||||
import ResizeNotifier from "../../utils/ResizeNotifier";
|
||||
import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils";
|
||||
import DMRoomMap from "../../utils/DMRoomMap";
|
||||
|
@ -113,7 +112,7 @@ import { PosthogAnalytics } from "../../PosthogAnalytics";
|
|||
import { initSentry } from "../../sentry";
|
||||
import LegacyCallHandler from "../../LegacyCallHandler";
|
||||
import { showSpaceInvite } from "../../utils/space";
|
||||
import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton";
|
||||
import { ButtonEvent } from "../views/elements/AccessibleButton";
|
||||
import { ActionPayload } from "../../dispatcher/payloads";
|
||||
import { SummarizedNotificationState } from "../../stores/notifications/SummarizedNotificationState";
|
||||
import Views from "../../Views";
|
||||
|
@ -147,6 +146,7 @@ import { Filter } from "../views/dialogs/spotlight/Filter";
|
|||
import { checkSessionLockFree, getSessionLock } from "../../utils/SessionLock";
|
||||
import { SessionLockStolenView } from "./auth/SessionLockStolenView";
|
||||
import { ConfirmSessionLockTheftView } from "./auth/ConfirmSessionLockTheftView";
|
||||
import { LoginSplashView } from "./auth/LoginSplashView";
|
||||
|
||||
// legacy export
|
||||
export { default as Views } from "../../Views";
|
||||
|
@ -2119,22 +2119,12 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
|||
);
|
||||
} else {
|
||||
// we think we are logged in, but are still waiting for the /sync to complete
|
||||
let errorBox;
|
||||
if (this.state.syncError && !isStoreError) {
|
||||
errorBox = (
|
||||
<div className="mx_MatrixChat_syncError">{messageForSyncError(this.state.syncError)}</div>
|
||||
);
|
||||
}
|
||||
// Suppress `InvalidStoreError`s here, since they have their own error dialog.
|
||||
view = (
|
||||
<div className="mx_MatrixChat_splash">
|
||||
{errorBox}
|
||||
<Spinner />
|
||||
<div className="mx_MatrixChat_splashButtons">
|
||||
<AccessibleButton kind="link_inline" onClick={this.onLogoutClick}>
|
||||
{_t("action|logout")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>
|
||||
<LoginSplashView
|
||||
onLogoutClick={this.onLogoutClick}
|
||||
syncError={isStoreError ? null : this.state.syncError}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (this.state.view === Views.WELCOME) {
|
||||
|
|
58
src/components/structures/auth/LoginSplashView.tsx
Normal file
58
src/components/structures/auth/LoginSplashView.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2015-2024 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 React from "react";
|
||||
|
||||
import { messageForSyncError } from "../../../utils/ErrorUtils";
|
||||
import Spinner from "../../views/elements/Spinner";
|
||||
import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton";
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* A callback function. Will be called if the user clicks the "logout" button on the splash screen.
|
||||
*
|
||||
* @param event - The click event
|
||||
*/
|
||||
onLogoutClick: (event: ButtonEvent) => void;
|
||||
|
||||
/**
|
||||
* Error that caused `/sync` to fail. If set, an error message will be shown on the splash screen.
|
||||
*/
|
||||
syncError: Error | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The view that is displayed after we have logged in, before the first /sync is completed.
|
||||
*/
|
||||
export function LoginSplashView(props: Props): React.JSX.Element {
|
||||
let errorBox: React.JSX.Element | undefined;
|
||||
|
||||
if (props.syncError) {
|
||||
errorBox = <div className="mx_LoginSplashView_syncError">{messageForSyncError(props.syncError)}</div>;
|
||||
}
|
||||
return (
|
||||
<div className="mx_MatrixChat_splash">
|
||||
{errorBox}
|
||||
<Spinner />
|
||||
<div className="mx_LoginSplashView_splashButtons">
|
||||
<AccessibleButton kind="link_inline" onClick={props.onLogoutClick}>
|
||||
{_t("action|logout")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
49
test/components/structures/auth/LoginSplashView-test.tsx
Normal file
49
test/components/structures/auth/LoginSplashView-test.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright 2024 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 { render, RenderResult } from "@testing-library/react";
|
||||
import React, { ComponentProps } from "react";
|
||||
|
||||
import { LoginSplashView } from "../../../../src/components/structures/auth/LoginSplashView";
|
||||
|
||||
describe("<LoginSplashView />", () => {
|
||||
function getComponent(props: Partial<ComponentProps<typeof LoginSplashView>> = {}): RenderResult {
|
||||
const defaultProps = {
|
||||
onLogoutClick: () => {},
|
||||
syncError: null,
|
||||
};
|
||||
return render(<LoginSplashView {...defaultProps} {...props} />);
|
||||
}
|
||||
|
||||
it("Renders a spinner", () => {
|
||||
const rendered = getComponent();
|
||||
expect(rendered.getByTestId("spinner")).toBeInTheDocument();
|
||||
expect(rendered.asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Renders an error message", () => {
|
||||
const rendered = getComponent({ syncError: new Error("boohoo") });
|
||||
expect(rendered.asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("Calls onLogoutClick", () => {
|
||||
const onLogoutClick = jest.fn();
|
||||
const rendered = getComponent({ onLogoutClick });
|
||||
expect(onLogoutClick).not.toHaveBeenCalled();
|
||||
rendered.getByRole("button", { name: "Logout" }).click();
|
||||
expect(onLogoutClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,70 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<LoginSplashView /> Renders a spinner 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_MatrixChat_splash"
|
||||
>
|
||||
<div
|
||||
class="mx_Spinner"
|
||||
>
|
||||
<div
|
||||
aria-label="Loading…"
|
||||
class="mx_Spinner_icon"
|
||||
data-testid="spinner"
|
||||
role="progressbar"
|
||||
style="width: 32px; height: 32px;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginSplashView_splashButtons"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Logout
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
||||
exports[`<LoginSplashView /> Renders an error message 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="mx_MatrixChat_splash"
|
||||
>
|
||||
<div
|
||||
class="mx_LoginSplashView_syncError"
|
||||
>
|
||||
<div>
|
||||
Unable to connect to Homeserver. Retrying…
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_Spinner"
|
||||
>
|
||||
<div
|
||||
aria-label="Loading…"
|
||||
class="mx_Spinner_icon"
|
||||
data-testid="spinner"
|
||||
role="progressbar"
|
||||
style="width: 32px; height: 32px;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mx_LoginSplashView_splashButtons"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_link_inline"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Logout
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
Loading…
Reference in a new issue