diff --git a/res/css/views/login/_InteractiveAuthEntryComponents.scss b/res/css/views/login/_InteractiveAuthEntryComponents.scss index 183b5cd251..e2ea7d86fb 100644 --- a/res/css/views/login/_InteractiveAuthEntryComponents.scss +++ b/res/css/views/login/_InteractiveAuthEntryComponents.scss @@ -35,8 +35,24 @@ limitations under the License. margin-bottom: 5px; } +.mx_InteractiveAuthEntryComponents_termsSubmit { + margin-top: 20px; + margin-bottom: 5px; + display: block; + width: 100%; +} + // XXX: This should be a common button class .mx_InteractiveAuthEntryComponents_msisdnSubmit:disabled { background-color: $light-fg-color; cursor: default; } + +.mx_InteractiveAuthEntryComponents_termsSubmit:disabled { + background-color: $accent-color-50pct; + cursor: default; +} + +.mx_InteractiveAuthEntryComponents_termsPolicy { + display: block; +} \ No newline at end of file diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index 8ab338790e..d0594d820c 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -12,6 +12,7 @@ $light-fg-color: #747474; // button UI (white-on-green in light skin) $accent-fg-color: $primary-bg-color; $accent-color: #76CFA6; +$accent-color-50pct: #76CFA67F; $selection-fg-color: $primary-fg-color; diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index c7fd38259c..a6f28fd14b 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -18,6 +18,7 @@ $focus-bg-color: #dddddd; // button UI (white-on-green in light skin) $accent-fg-color: #ffffff; $accent-color: #76CFA6; +$accent-color-50pct: #76CFA67F; $selection-fg-color: $primary-bg-color; diff --git a/src/Registration.js b/src/Registration.js index 070178fecb..f86c9cc618 100644 --- a/src/Registration.js +++ b/src/Registration.js @@ -45,7 +45,7 @@ export async function startAnyRegistrationFlow(options) { // caution though. const hasIlagFlow = flows.some((flow) => { return flow.stages.every((stage) => { - return ['m.login.dummy', 'm.login.recaptcha'].includes(stage); + return ['m.login.dummy', 'm.login.recaptcha', 'm.login.terms'].includes(stage); }); }); diff --git a/src/components/structures/InteractiveAuth.js b/src/components/structures/InteractiveAuth.js index 8428e3c714..2883c8cca4 100644 --- a/src/components/structures/InteractiveAuth.js +++ b/src/components/structures/InteractiveAuth.js @@ -68,6 +68,11 @@ export default React.createClass({ // If true, poll to see if the auth flow has been completed // out-of-band poll: PropTypes.bool, + + // If true, components will be told that the 'Continue' button + // is managed by some other party and should not be managed by + // the component itself. + continueIsManaged: PropTypes.bool, }, getInitialState: function() { @@ -128,6 +133,12 @@ export default React.createClass({ } }, + tryContinue: function() { + if (this.refs.stageComponent && this.refs.stageComponent.tryContinue) { + this.refs.stageComponent.tryContinue(); + } + }, + _authStateUpdated: function(stageType, stageState) { const oldStage = this.state.authStage; this.setState({ @@ -192,6 +203,7 @@ export default React.createClass({ fail={this._onAuthStageFailed} setEmailSid={this._setEmailSid} makeRegistrationUrl={this.props.makeRegistrationUrl} + showContinue={!this.props.continueIsManaged} /> ); }, diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index c6427001ad..fb892c4a0a 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -101,6 +101,9 @@ export default React.createClass({ }, onSubmit: function(ev) { + if (this.refs.uiAuth) { + this.refs.uiAuth.tryContinue(); + } this.setState({ doingUIAuth: true, }); @@ -217,6 +220,8 @@ export default React.createClass({ onAuthFinished={this._onUIAuthFinished} inputs={{}} poll={true} + ref="uiAuth" + continueIsManaged={true} />; } const inputClasses = classnames({ diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js index 481cdc60b2..73b46959b0 100644 --- a/src/components/views/login/InteractiveAuthEntryComponents.js +++ b/src/components/views/login/InteractiveAuthEntryComponents.js @@ -222,6 +222,7 @@ export const TermsAuthEntry = React.createClass({ stageParams: PropTypes.object.isRequired, errorText: PropTypes.string, busy: PropTypes.bool, + showContinue: PropTypes.bool, }, componentWillMount: function() { @@ -275,19 +276,30 @@ export const TermsAuthEntry = React.createClass({ }); }, - _trySubmit: function(policyId) { + tryContinue: function() { + this._trySubmit(); + }, + + _togglePolicy: function(policyId) { const newToggles = {}; - let allChecked = true; for (const policy of this.state.policies) { let checked = this.state.toggledPolicies[policy.id]; if (policy.id === policyId) checked = !checked; newToggles[policy.id] = checked; + } + this.setState({"toggledPolicies": newToggles}); + }, + + _trySubmit: function() { + let allChecked = true; + for (const policy of this.state.policies) { + let checked = this.state.toggledPolicies[policy.id]; allChecked = allChecked && checked; } - this.setState({"toggledPolicies": newToggles}); if (allChecked) this.props.submitAuthDict({type: TermsAuthEntry.LOGIN_TYPE}); + else this.setState({errorText: _t("Please review and accept all of the homeserver's policies")}); }, render: function() { @@ -303,27 +315,35 @@ export const TermsAuthEntry = React.createClass({ allChecked = allChecked && checked; checkboxes.push( -