fix: alignment issue in login page (#3399)

This commit is contained in:
Yijing Huang 2023-09-15 03:07:23 -05:00 committed by GitHub
parent f6f80b48c9
commit 936b49a63f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 81 deletions

View File

@ -11,7 +11,7 @@ class MobileSignInScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const spacing = 16; const double spacing = 16;
// Welcome to Appflowy // Welcome to Appflowy
final welcomeString = LocaleKeys.welcomeText.tr(); final welcomeString = LocaleKeys.welcomeText.tr();
final style = Theme.of(context); final style = Theme.of(context);
@ -24,7 +24,7 @@ class MobileSignInScreen extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text('Signing in...'), Text('Signing in...'),
VSpace(8), VSpace(spacing),
CircularProgressIndicator(), CircularProgressIndicator(),
], ],
), ),
@ -54,7 +54,7 @@ class MobileSignInScreen extends StatelessWidget {
style: style.textTheme.displayLarge, style: style.textTheme.displayLarge,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
const VSpace(16), const VSpace(spacing),
// TODO(yijing): confirm the subtitle before release app // TODO(yijing): confirm the subtitle before release app
Text( Text(
'You are in charge of your data and customizations.', 'You are in charge of your data and customizations.',
@ -65,7 +65,7 @@ class MobileSignInScreen extends StatelessWidget {
flex: 2, flex: 2,
), ),
const SignInAnonymousButton(), const SignInAnonymousButton(),
const VSpace(16), const VSpace(spacing),
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -80,9 +80,9 @@ class MobileSignInScreen extends StatelessWidget {
const Expanded(child: Divider()), const Expanded(child: Divider()),
], ],
), ),
const VSpace(16), const VSpace(spacing),
const ThirdPartySignInButtons(), const ThirdPartySignInButtons(),
const VSpace(16), const VSpace(spacing),
], ],
), ),
), ),

View File

@ -4,6 +4,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/sign_in_bloc.dart'; import 'package:appflowy/user/application/sign_in_bloc.dart';
import 'package:appflowy/user/presentation/presentation.dart';
import 'package:appflowy/util/platform_extension.dart'; import 'package:appflowy/util/platform_extension.dart';
import 'package:appflowy/workspace/application/appearance.dart'; import 'package:appflowy/workspace/application/appearance.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -13,73 +14,31 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
class ThirdPartySignInButtons extends StatelessWidget { class ThirdPartySignInButtons extends StatelessWidget {
/// Used in DesktopSignInScreen and MobileSignInScreen /// Used in DesktopSignInScreen, MobileSignInScreen and SettingThirdPartyLogin
const ThirdPartySignInButtons({ const ThirdPartySignInButtons({
super.key, super.key,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isMobile = PlatformExtension.isMobile;
// Get themeMode from AppearanceSettingsCubit // Get themeMode from AppearanceSettingsCubit
// When user changes themeMode, it changes the state in AppearanceSettingsCubit, but the themeMode for the MaterialApp won't change, it only got updated(get value from AppearanceSettingsCubit) when user open the app again. Thus, we should get themeMode from AppearanceSettingsCubit rather than MediaQuery. // When user changes themeMode, it changes the state in AppearanceSettingsCubit, but the themeMode for the MaterialApp won't change, it only got updated(get value from AppearanceSettingsCubit) when user open the app again. Thus, we should get themeMode from AppearanceSettingsCubit rather than MediaQuery.
final isDarkMode = final isDarkMode =
context.read<AppearanceSettingsCubit>().state.themeMode == context.read<AppearanceSettingsCubit>().state.themeMode ==
ThemeMode.dark; ThemeMode.dark;
if (isMobile) {
// ThirdPartySignInButtons in mobile
return Column(
children: [
_ThirdPartySignInButton(
isMobile: true,
icon: FlowySvgs.google_mark_xl,
labelText: LocaleKeys.signIn_LogInWithGoogle.tr(),
onPressed: () {
_signInWithGoogle(context);
},
),
const SizedBox(height: 8),
_ThirdPartySignInButton(
isMobile: true,
icon: isDarkMode
? FlowySvgs.github_mark_white_xl
: FlowySvgs.github_mark_black_xl,
labelText: LocaleKeys.signIn_LogInWithGithub.tr(),
onPressed: () {
_signInWithGithub(context);
},
),
const SizedBox(height: 8),
_ThirdPartySignInButton(
isMobile: true,
icon: isDarkMode
? FlowySvgs.discord_mark_white_xl
: FlowySvgs.discord_mark_blurple_xl,
labelText: LocaleKeys.signIn_LogInWithDiscord.tr(),
onPressed: () {
_signInWithDiscord(context);
},
),
],
);
}
// ThirdPartySignInButtons in desktop
return Column( return Column(
children: [ children: [
_ThirdPartySignInButton( _ThirdPartySignInButton(
key: const Key('signInWithGoogleButton'), key: const Key('signInWithGoogleButton'),
isMobile: false,
icon: FlowySvgs.google_mark_xl, icon: FlowySvgs.google_mark_xl,
labelText: LocaleKeys.signIn_LogInWithGoogle.tr(), labelText: LocaleKeys.signIn_LogInWithGoogle.tr(),
onPressed: () { onPressed: () {
_signInWithGoogle(context); _signInWithGoogle(context);
}, },
), ),
const SizedBox(height: 8), const VSpace(8),
_ThirdPartySignInButton( _ThirdPartySignInButton(
isMobile: false,
icon: isDarkMode icon: isDarkMode
? FlowySvgs.github_mark_white_xl ? FlowySvgs.github_mark_white_xl
: FlowySvgs.github_mark_black_xl, : FlowySvgs.github_mark_black_xl,
@ -88,9 +47,8 @@ class ThirdPartySignInButtons extends StatelessWidget {
_signInWithGithub(context); _signInWithGithub(context);
}, },
), ),
const SizedBox(height: 8), const VSpace(8),
_ThirdPartySignInButton( _ThirdPartySignInButton(
isMobile: false,
icon: isDarkMode icon: isDarkMode
? FlowySvgs.discord_mark_white_xl ? FlowySvgs.discord_mark_white_xl
: FlowySvgs.discord_mark_blurple_xl, : FlowySvgs.discord_mark_blurple_xl,
@ -105,15 +63,14 @@ class ThirdPartySignInButtons extends StatelessWidget {
} }
class _ThirdPartySignInButton extends StatelessWidget { class _ThirdPartySignInButton extends StatelessWidget {
/// Build button based on current Platform(mobile or desktop).
const _ThirdPartySignInButton({ const _ThirdPartySignInButton({
super.key, super.key,
required this.isMobile,
required this.icon, required this.icon,
required this.labelText, required this.labelText,
required this.onPressed, required this.onPressed,
}); });
final bool isMobile;
final FlowySvgData icon; final FlowySvgData icon;
final String labelText; final String labelText;
@ -122,14 +79,16 @@ class _ThirdPartySignInButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final style = Theme.of(context); final style = Theme.of(context);
final buttonSize = MediaQuery.of(context).size; final isMobile = PlatformExtension.isMobile;
if (isMobile) { if (isMobile) {
// Use LayoutBuilder to get the maxWidth of parent widget(Column) and set the icon occupied area to 1/4 of maxWidth.
return LayoutBuilder(
builder: (context, constraints) {
return SizedBox( return SizedBox(
width: double.infinity,
height: 48, height: 48,
child: OutlinedButton.icon( child: OutlinedButton.icon(
icon: Container( icon: Container(
width: buttonSize.width / 5.5, width: constraints.maxWidth / 4,
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: SizedBox( child: SizedBox(
width: 24, width: 24,
@ -147,14 +106,17 @@ class _ThirdPartySignInButton extends StatelessWidget {
onPressed: onPressed, onPressed: onPressed,
), ),
); );
},
);
} }
// In desktop, the width of button is limited by [AuthFormContainer]
return SizedBox( return SizedBox(
height: 48, height: 48,
width: double.infinity, width: AuthFormContainer.width,
child: OutlinedButton.icon( child: OutlinedButton.icon(
// In order to align all the labels vertically in a relatively centered position to the button, we use a fixed width container to wrap the icon(align to the right), then use another container to align the label to left. // In order to align all the labels vertically in a relatively centered position to the button, we use a fixed width container to wrap the icon(align to the right), then use another container to align the label to left.
icon: Container( icon: Container(
width: buttonSize.width / 8, width: AuthFormContainer.width / 4,
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: SizedBox( child: SizedBox(
// Some icons are not square, so we just use a fixed width here. // Some icons are not square, so we just use a fixed width here.

View File

@ -1,9 +1,8 @@
import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AuthFormContainer extends StatelessWidget { class AuthFormContainer extends StatelessWidget {
final List<Widget> children; final List<Widget> children;
static const double width = 340;
const AuthFormContainer({ const AuthFormContainer({
super.key, super.key,
required this.children, required this.children,
@ -11,9 +10,8 @@ class AuthFormContainer extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return SizedBox( return SizedBox(
width: min(size.width, 340), width: width,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: children, children: children,