Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 6d6cfcd

Browse files
authored
registration: redesign email verification page (#8554)
1 parent 438e66b commit 6d6cfcd

File tree

16 files changed

+382
-90
lines changed

16 files changed

+382
-90
lines changed

res/css/_components.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
@import "./structures/_ViewSource.scss";
5959
@import "./structures/auth/_CompleteSecurity.scss";
6060
@import "./structures/auth/_Login.scss";
61+
@import "./structures/auth/_Registration.scss";
6162
@import "./structures/auth/_SetupEncryptionBody.scss";
6263
@import "./views/audio_messages/_AudioPlayer.scss";
6364
@import "./views/audio_messages/_PlayPauseButton.scss";
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
.mx_Register_mainContent {
18+
display: flex;
19+
flex-direction: column;
20+
flex-grow: 1;
21+
min-height: 270px;
22+
23+
p {
24+
font-size: $font-14px;
25+
color: $authpage-primary-color;
26+
27+
&.secondary {
28+
color: $authpage-secondary-color;
29+
}
30+
}
31+
32+
> img:first-child {
33+
margin-bottom: 16px;
34+
width: max-content;
35+
}
36+
37+
.mx_Login_submit {
38+
margin-bottom: 0;
39+
}
40+
}
41+
42+
.mx_Register_footerActions {
43+
display: flex;
44+
flex-direction: row;
45+
justify-content: space-between;
46+
padding-top: 16px;
47+
margin-top: 16px;
48+
border-top: 1px solid rgba(141, 151, 165, 0.2);
49+
50+
> * {
51+
flex-basis: content;
52+
}
53+
}

res/css/views/auth/_AuthBody.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ limitations under the License.
2424
padding: 25px 60px;
2525
box-sizing: border-box;
2626

27+
&.mx_AuthBody_flex {
28+
display: flex;
29+
flex-direction: column;
30+
}
31+
2732
h2 {
2833
font-size: $font-24px;
2934
font-weight: 600;
@@ -139,7 +144,6 @@ limitations under the License.
139144
.mx_AuthBody_changeFlow {
140145
display: block;
141146
text-align: center;
142-
width: 100%;
143147

144148
> a {
145149
font-weight: $font-semi-bold;

res/css/views/auth/_AuthPage.scss

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ limitations under the License.
2828
border-radius: 4px;
2929
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.33);
3030
background-color: $authpage-modal-bg-color;
31-
}
3231

33-
@media only screen and (max-width: 480px) {
34-
.mx_AuthPage_modal {
32+
@media only screen and (max-height: 768px) {
33+
margin-top: 50px;
34+
}
35+
36+
@media only screen and (max-width: 480px) {
3537
margin-top: 0;
3638
}
3739
}

res/css/views/auth/_InteractiveAuthEntryComponents.scss

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,6 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
.mx_InteractiveAuthEntryComponents_emailWrapper {
18-
padding-right: 100px;
19-
position: relative;
20-
margin-top: 32px;
21-
margin-bottom: 32px;
22-
23-
&::before, &::after {
24-
position: absolute;
25-
width: 116px;
26-
height: 116px;
27-
content: "";
28-
right: -10px;
29-
}
30-
31-
&::before {
32-
background-color: rgba(244, 246, 250, 0.91);
33-
border-radius: 50%;
34-
top: -20px;
35-
}
36-
37-
&::after {
38-
background-image: url('$(res)/img/element-icons/email-prompt.svg');
39-
background-repeat: no-repeat;
40-
background-position: center;
41-
background-size: contain;
42-
top: -25px;
43-
}
44-
}
45-
4617
.mx_InteractiveAuthEntryComponents_msisdnWrapper {
4718
text-align: center;
4819
}
@@ -103,3 +74,21 @@ limitations under the License.
10374
margin-left: 5px;
10475
}
10576
}
77+
78+
.mx_InteractiveAuthEntryComponents_emailWrapper {
79+
// "Resend" button/link
80+
.mx_AccessibleButton_kind_link_inline {
81+
// We need this to be an inline-block so positioning works correctly
82+
display: inline-block !important;
83+
84+
// Spinner as end adornment of the "resend" button/link
85+
.mx_Spinner {
86+
// Spinners are usually block elements, but we need it as inline element
87+
display: inline-flex !important;
88+
// Spinners by default fill all available width, but we don't want that
89+
width: auto !important;
90+
// We need to center the spinner relative to the button/link
91+
vertical-align: middle !important;
92+
}
93+
}
94+
}

res/css/views/elements/_Tooltip.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ limitations under the License.
7676
border: 0;
7777
text-align: center;
7878

79+
&:not(.mx_Tooltip_noMargin) {
80+
margin-left: 6px;
81+
margin-right: 6px;
82+
}
83+
7984
.mx_Tooltip_chevron {
8085
display: none;
8186
}
Lines changed: 5 additions & 12 deletions
Loading

src/components/structures/InteractiveAuth.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ export default class InteractiveAuthComponent extends React.Component<IProps, IS
269269
setEmailSid={this.setEmailSid}
270270
showContinue={!this.props.continueIsManaged}
271271
onPhaseChange={this.onPhaseChange}
272+
requestEmailToken={this.authLogic.requestEmailToken}
272273
continueText={this.props.continueText}
273274
continueKind={this.props.continueKind}
274275
onCancel={this.onStageCancel}

src/components/structures/auth/Registration.tsx

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ limitations under the License.
1515
*/
1616

1717
import { createClient } from 'matrix-js-sdk/src/matrix';
18-
import React, { ReactNode } from 'react';
18+
import React, { Fragment, ReactNode } from 'react';
1919
import { MatrixClient } from "matrix-js-sdk/src/client";
2020
import classNames from "classnames";
2121
import { logger } from "matrix-js-sdk/src/logger";
@@ -36,6 +36,8 @@ import AuthBody from "../../views/auth/AuthBody";
3636
import AuthHeader from "../../views/auth/AuthHeader";
3737
import InteractiveAuth from "../InteractiveAuth";
3838
import Spinner from "../../views/elements/Spinner";
39+
import { AuthHeaderDisplay } from './header/AuthHeaderDisplay';
40+
import { AuthHeaderProvider } from './header/AuthHeaderProvider';
3941

4042
interface IProps {
4143
serverConfig: ValidatedServerConfig;
@@ -619,28 +621,37 @@ export default class Registration extends React.Component<IProps, IState> {
619621
{ regDoneText }
620622
</div>;
621623
} else {
622-
body = <div>
623-
<h2>{ _t('Create account') }</h2>
624-
{ errorText }
625-
{ serverDeadSection }
626-
<ServerPicker
627-
title={_t("Host account on")}
628-
dialogTitle={_t("Decide where your account is hosted")}
629-
serverConfig={this.props.serverConfig}
630-
onServerConfigChange={this.state.doingUIAuth ? undefined : this.props.onServerConfigChange}
631-
/>
632-
{ this.renderRegisterComponent() }
633-
{ goBack }
634-
{ signIn }
635-
</div>;
624+
body = <Fragment>
625+
<div className="mx_Register_mainContent">
626+
<AuthHeaderDisplay
627+
title={_t('Create account')}
628+
serverPicker={<ServerPicker
629+
title={_t("Host account on")}
630+
dialogTitle={_t("Decide where your account is hosted")}
631+
serverConfig={this.props.serverConfig}
632+
onServerConfigChange={this.state.doingUIAuth ? undefined : this.props.onServerConfigChange}
633+
/>}
634+
>
635+
{ errorText }
636+
{ serverDeadSection }
637+
</AuthHeaderDisplay>
638+
{ this.renderRegisterComponent() }
639+
</div>
640+
<div className="mx_Register_footerActions">
641+
{ goBack }
642+
{ signIn }
643+
</div>
644+
</Fragment>;
636645
}
637646

638647
return (
639648
<AuthPage>
640649
<AuthHeader />
641-
<AuthBody>
642-
{ body }
643-
</AuthBody>
650+
<AuthHeaderProvider>
651+
<AuthBody flex>
652+
{ body }
653+
</AuthBody>
654+
</AuthHeaderProvider>
644655
</AuthPage>
645656
);
646657
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import { createContext, Dispatch, ReducerAction, ReducerState } from "react";
18+
19+
import type { AuthHeaderReducer } from "./AuthHeaderProvider";
20+
21+
interface AuthHeaderContextType {
22+
state: ReducerState<AuthHeaderReducer>;
23+
dispatch: Dispatch<ReducerAction<AuthHeaderReducer>>;
24+
}
25+
26+
export const AuthHeaderContext = createContext<AuthHeaderContextType>(undefined);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import React, { Fragment, PropsWithChildren, ReactNode, useContext } from "react";
18+
19+
import { AuthHeaderContext } from "./AuthHeaderContext";
20+
21+
interface Props {
22+
title: ReactNode;
23+
icon?: ReactNode;
24+
serverPicker: ReactNode;
25+
}
26+
27+
export function AuthHeaderDisplay({ title, icon, serverPicker, children }: PropsWithChildren<Props>) {
28+
const context = useContext(AuthHeaderContext);
29+
if (!context) {
30+
return null;
31+
}
32+
const current = context.state.length ? context.state[0] : null;
33+
return (
34+
<Fragment>
35+
{ current?.icon ?? icon }
36+
<h2>{ current?.title ?? title }</h2>
37+
{ children }
38+
{ current?.hideServerPicker !== true && serverPicker }
39+
</Fragment>
40+
);
41+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import { ReactNode, useContext, useEffect } from "react";
18+
19+
import { AuthHeaderContext } from "./AuthHeaderContext";
20+
import { AuthHeaderActionType } from "./AuthHeaderProvider";
21+
22+
interface Props {
23+
title: ReactNode;
24+
icon?: ReactNode;
25+
hideServerPicker?: boolean;
26+
}
27+
28+
export function AuthHeaderModifier(props: Props) {
29+
const context = useContext(AuthHeaderContext);
30+
const dispatch = context ? context.dispatch : null;
31+
useEffect(() => {
32+
if (!dispatch) {
33+
return;
34+
}
35+
dispatch({ type: AuthHeaderActionType.Add, value: props });
36+
return () => dispatch({ type: AuthHeaderActionType.Remove, value: props });
37+
}, [props, dispatch]);
38+
return null;
39+
}

0 commit comments

Comments
 (0)