Skip to content

Commit

Permalink
fix: UI when strategies are missing #65 (#73)
Browse files Browse the repository at this point in the history
* fix: make ui behave in absence of strategies #65

* fix: pr changes

---------

Co-authored-by: Simon Lightfoot <[email protected]>
  • Loading branch information
shinyford and slightfoot committed Dec 20, 2024
1 parent 5b9e87f commit 9290362
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 95 deletions.
32 changes: 27 additions & 5 deletions packages/clerk_auth/lib/src/models/environment/environment.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import 'package:clerk_auth/clerk_auth.dart';
import 'package:json_annotation/json_annotation.dart';

import 'auth_config.dart';
import 'display_config.dart';
import 'organization_settings.dart';
import 'user_settings.dart';

part 'environment.g.dart';

/// [Environment] Clerk object
Expand Down Expand Up @@ -44,6 +40,32 @@ class Environment {
/// empty [Environment]
static const empty = Environment();

/// Do we have [Strategy.password] configured?
bool get hasPasswordStrategy =>
config.firstFactors.contains(Strategy.password);

/// [Iterable] of identification strategies
Iterable<Strategy> get identificationStrategies =>
config.identificationStrategies.where((i) => i.isOauth == false);

/// Do we have identification strategies?
bool get hasIdentificationStrategies => identificationStrategies.isNotEmpty;

/// [Iterable] of oauth strategies
Iterable<Strategy> get oauthStrategies =>
config.identificationStrategies.where((i) => i.isOauth);

/// Do we have oauth strategies?
bool get hasOauthStrategies => oauthStrategies.isNotEmpty;

/// [Iterable] of other strategies
/// i.e. strategies that are neither oauth nor password-based
Iterable<Strategy> get otherStrategies =>
config.firstFactors.where((f) => f.isOtherStrategy);

/// Do we have other strategies?
bool get hasOtherStrategies => otherStrategies.isNotEmpty;

/// fromJson
static Environment fromJson(Map<String, dynamic> json) =>
_$EnvironmentFromJson(json);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,37 @@ class _ClerkAuthenticationWidgetState extends State<ClerkAuthenticationWidget> {
constraints: const BoxConstraints(minHeight: 530.0),
child: ClerkVerticalCard(
topPortion: _TopPortion(state: _state),
middlePortion: Column(
children: [
ClerkAuthBuilder(
builder: (context, auth) {
return Closeable(
closed: auth.isSigningIn || auth.isSigningUp,
child: const ClerkSSOPanel(),
);
},
),
Closeable(
closed: _state.isSigningIn == false,
child: const ClerkSignInPanel(),
),
Closeable(
closed: _state.isSigningUp == false,
child: const ClerkSignUpPanel(),
),
],
middlePortion: ClerkAuthBuilder(
builder: (context, auth) {
final env = auth.env;
return Padding(
padding: horizontalPadding32,
child: Column(
children: [
if (env.hasOauthStrategies) //
Closeable(
closed: auth.isSigningIn || auth.isSigningUp,
child: const ClerkSSOPanel(),
),
if (env.hasIdentificationStrategies) ...[
if (env.hasOauthStrategies) //
const Padding(
padding: verticalPadding24,
child: OrDivider(),
),
Closeable(
closed: _state.isSigningIn == false,
child: const ClerkSignInPanel(),
),
Closeable(
closed: _state.isSigningUp == false,
child: const ClerkSignUpPanel(),
),
],
],
),
);
},
),
bottomPortion: _BottomPortion(
state: _state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,22 @@ class _ClerkSignInPanelState extends State<ClerkSignInPanel> {
final auth = ClerkAuth.of(context);
final translator = auth.translator;
final env = auth.env;
final otherStrategies =
env.config.firstFactors.where((f) => f.isOtherStrategy);
final hasPasswordStrategy =
env.config.firstFactors.contains(clerk.Strategy.password);
final identifiers = env.config.identificationStrategies
.where((i) => i.isOauth == false)
final identifiers = env.identificationStrategies
.map((i) => i.toString().replaceAll('_', ' '));
final factor = auth.client.signIn?.supportedFirstFactors
.firstWhereOrNull((f) => f.strategy == _strategy);
final safeIdentifier = factor?.safeIdentifier;

if (identifiers.isEmpty) {
return emptyWidget;
}

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: horizontalPadding32 + bottomPadding8,
padding: bottomPadding8,
child: ClerkTextFormField(
key: const Key('identifier'),
label: translator.alternatives(identifiers.toList()).capitalized,
Expand All @@ -97,28 +96,27 @@ class _ClerkSignInPanelState extends State<ClerkSignInPanel> {
Closeable(
key: const Key('emailLinkMessage'),
closed: _strategy != clerk.Strategy.emailLink,
child: Padding(
padding: horizontalPadding32,
child: Text(
translator.translate(
'Click on the link that‘s been sent to ### and then check back here',
substitution: _identifier,
),
maxLines: 2,
style: ClerkTextStyle.inputLabel,
child: Text(
translator.translate(
'Click on the link that‘s been sent to ### and then check back here',
substitution: _identifier,
),
maxLines: 2,
style: ClerkTextStyle.inputLabel,
),
),
Closeable(
closed: _strategy.requiresCode == false,
child: Padding(
padding: horizontalPadding32 + verticalPadding8,
padding: verticalPadding8,
child: ClerkCodeInput(
key: const Key('code'),
title: translator.translate(
'Enter code sent to ###',
substitution: safeIdentifier,
),
title: safeIdentifier is String
? translator.translate(
'Enter the code sent to ###',
substitution: safeIdentifier,
)
: translator.translate('Enter the code sent to you'),
onSubmit: (code) async {
await _continue(auth, code: code, strategy: _strategy);
return false;
Expand All @@ -131,7 +129,7 @@ class _ClerkSignInPanelState extends State<ClerkSignInPanel> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (hasPasswordStrategy)
if (env.hasPasswordStrategy)
Padding(
padding: horizontalPadding32 + verticalPadding8,
child: ClerkTextFormField(
Expand All @@ -142,13 +140,13 @@ class _ClerkSignInPanelState extends State<ClerkSignInPanel> {
_continue(auth, strategy: clerk.Strategy.password),
),
),
if (otherStrategies.isNotEmpty) ...[
if (hasPasswordStrategy)
if (env.hasOtherStrategies) ...[
if (env.hasPasswordStrategy)
const Padding(
padding: horizontalPadding32,
child: OrDivider(),
),
for (final strategy in otherStrategies)
for (final strategy in env.otherStrategies)
if (StrategyButton.supports(strategy))
Padding(
padding: topPadding4 + horizontalPadding32,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class _ClerkSignUpPanelState extends State<ClerkSignUpPanel> {
Closeable(
closed: auth.signUp?.unverified(clerk.Field.phoneNumber) != true,
child: Padding(
padding: horizontalPadding32 + verticalPadding8,
padding: verticalPadding8,
child: ClerkCodeInput(
key: const Key('phone_code'),
title: translator.translate('Verify your phone number'),
Expand All @@ -91,7 +91,7 @@ class _ClerkSignUpPanelState extends State<ClerkSignUpPanel> {
Closeable(
closed: auth.signUp?.unverified(clerk.Field.emailAddress) != true,
child: Padding(
padding: horizontalPadding32 + verticalPadding8,
padding: verticalPadding8,
child: ClerkCodeInput(
key: const Key('email_code'),
title: translator.translate('Verify your email address'),
Expand All @@ -113,7 +113,7 @@ class _ClerkSignUpPanelState extends State<ClerkSignUpPanel> {
children: [
for (final attribute in attributes)
Padding(
padding: horizontalPadding32 + bottomPadding24,
padding: bottomPadding24,
child: attribute.isPhoneNumber
? ClerkPhoneNumberFormField(
initial: _values[attribute.attr],
Expand All @@ -138,19 +138,16 @@ class _ClerkSignUpPanelState extends State<ClerkSignUpPanel> {
],
),
),
Padding(
padding: horizontalPadding32,
child: ClerkMaterialButton(
onPressed: () => _continue(auth),
label: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Center(child: Text(translator.translate('Continue'))),
horizontalMargin4,
const Icon(Icons.arrow_right_sharp),
],
),
ClerkMaterialButton(
onPressed: () => _continue(auth),
label: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Center(child: Text(translator.translate('Continue'))),
horizontalMargin4,
const Icon(Icons.arrow_right_sharp),
],
),
),
verticalMargin32,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,29 @@ class _ClerkSSOPanelState extends State<ClerkSSOPanel> {
@override
Widget build(BuildContext context) {
final auth = ClerkAuth.of(context);
final env = auth.env;
final oauthStrategies =
env.config.identificationStrategies.where((i) => i.isOauth);
final socialConnections = env.user.socialSettings.values.where(
(s) => oauthStrategies.contains(s.strategy),
);
return Column(
final oauthStrategies = auth.env.config.identificationStrategies //
.where((i) => i.isOauth)
.toList();
final socialConnections = auth.env.user.socialSettings.values //
.where((s) => oauthStrategies.contains(s.strategy))
.toList();

if (socialConnections.isEmpty) {
return emptyWidget;
}

return Row(
children: [
Padding(
padding: horizontalPadding32 + bottomPadding24,
child: Row(
children: [
for (final connection in socialConnections) //
Expanded(
child: Padding(
padding: const EdgeInsets.all(4),
child: SocialConnectionButton(
key: ValueKey<clerk.SocialConnection>(connection),
connection: connection,
),
),
),
],
for (final (index, connection) in socialConnections.indexed) ...[
Expanded(
child: SocialConnectionButton(
key: ValueKey<clerk.SocialConnection>(connection),
connection: connection,
),
),
),
const OrDivider(),
verticalMargin24,
if (index < socialConnections.length - 1) //
horizontalMargin8,
],
],
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class ClerkCodeInput extends StatelessWidget {
title,
textAlign: TextAlign.start,
maxLines: 2,
style: ClerkTextStyle.title,
style: subtitle is String
? ClerkTextStyle.title
: ClerkTextStyle.subtitleDark,
),
),
if (subtitle case String subtitle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,6 @@ class _MultiDigitCodeInputState extends State<MultiDigitCodeInput>
const color = ClerkColors.midGrey;

bool isSmall = widget.isSmall;
if (isSmall == false) {
final viewQuery = MediaQueryData.fromView(View.of(context));
viewQuery.size.height - viewQuery.viewInsets.bottom < 400.0;
}

final boxSize = isSmall ? 18.0 : 38.0;
final cursorHeight = isSmall ? 1.0 : 2.0;
Expand Down

0 comments on commit 9290362

Please sign in to comment.