diff --git a/mobile-app/lib/ui/views/login/native_login_view.dart b/mobile-app/lib/ui/views/login/native_login_view.dart index 492439816..08ba7324d 100644 --- a/mobile-app/lib/ui/views/login/native_login_view.dart +++ b/mobile-app/lib/ui/views/login/native_login_view.dart @@ -62,29 +62,42 @@ class NativeLoginView extends StatelessWidget { child: Container( constraints: const BoxConstraints(minHeight: 50), margin: const EdgeInsets.all(16), - child: ElevatedButton( - style: buttonStyle, - onPressed: () { - model.auth.login(context, 'google-oauth2'); - }, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/google-logo.png', - height: 25, - width: 25, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - context.t.login_with_google, - style: textStyle, + child: Tooltip( + message: context.t.login_with_google, + child: ElevatedButton( + style: buttonStyle, + onPressed: () { + model.auth.login(context, 'google-oauth2'); + }, + child: Semantics( + button: true, + enabled: true, + label: context.t.login_with_google, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Semantics( + image: true, + label: 'Google logo', + child: Image.asset( + 'assets/images/google-logo.png', + height: 25, + width: 25, + semanticLabel: 'Google logo', + ), ), - ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + context.t.login_with_google, + style: textStyle, + ), + ), + ), + ], ), - ], + ), ), ), ), @@ -97,29 +110,42 @@ class NativeLoginView extends StatelessWidget { child: Container( constraints: const BoxConstraints(minHeight: 50), margin: const EdgeInsets.all(16), - child: ElevatedButton( - style: buttonStyle, - onPressed: () { - model.auth.login(context, 'github'); - }, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/github-logo.png', - height: 25, - width: 25, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - context.t.login_with_github, - style: textStyle, + child: Tooltip( + message: context.t.login_with_github, + child: ElevatedButton( + style: buttonStyle, + onPressed: () { + model.auth.login(context, 'github'); + }, + child: Semantics( + button: true, + enabled: true, + label: context.t.login_with_github, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Semantics( + image: true, + label: 'GitHub logo', + child: Image.asset( + 'assets/images/github-logo.png', + height: 25, + width: 25, + semanticLabel: 'GitHub logo', + ), ), - ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + context.t.login_with_github, + style: textStyle, + ), + ), + ), + ], ), - ], + ), ), ), ), @@ -132,29 +158,42 @@ class NativeLoginView extends StatelessWidget { child: Container( margin: const EdgeInsets.all(16), constraints: const BoxConstraints(minHeight: 50), - child: ElevatedButton( - style: buttonStyle, - onPressed: () { - model.auth.login(context, 'apple'); - }, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Image.asset( - 'assets/images/apple-logo.png', - height: 25, - width: 25, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - context.t.login_with_apple, - style: textStyle, + child: Tooltip( + message: context.t.login_with_apple, + child: ElevatedButton( + style: buttonStyle, + onPressed: () { + model.auth.login(context, 'apple'); + }, + child: Semantics( + button: true, + enabled: true, + label: context.t.login_with_apple, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Semantics( + image: true, + label: 'Apple logo', + child: Image.asset( + 'assets/images/apple-logo.png', + height: 25, + width: 25, + semanticLabel: 'Apple logo', + ), ), - ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + context.t.login_with_apple, + style: textStyle, + ), + ), + ), + ], ), - ], + ), ), ), ), @@ -164,14 +203,20 @@ class NativeLoginView extends StatelessWidget { buildDivider(), Container( padding: const EdgeInsets.all(16), - child: TextFormField( + child: Semantics( + textField: true, + label: context.t.email, enabled: !model.showOTPfield, - controller: model.emailController, - keyboardType: TextInputType.emailAddress, - decoration: InputDecoration( - hintText: context.t.email, - border: const OutlineInputBorder( - borderSide: BorderSide(width: 2, color: Colors.white), + child: TextFormField( + enabled: !model.showOTPfield, + controller: model.emailController, + keyboardType: TextInputType.emailAddress, + decoration: InputDecoration( + labelText: context.t.email, + hintText: context.t.email, + border: const OutlineInputBorder( + borderSide: BorderSide(width: 2, color: Colors.white), + ), ), ), ), @@ -179,19 +224,25 @@ class NativeLoginView extends StatelessWidget { model.showOTPfield ? Container( padding: const EdgeInsets.all(16), - child: TextFormField( - autofocus: model.showOTPfield, - controller: model.otpController, - keyboardType: TextInputType.number, - decoration: InputDecoration( - hintText: context.t.email_enter_sign_in_code, - errorText: model.incorrectOTP - ? context.t.email_invalid_code - : null, - errorMaxLines: 5, - border: const OutlineInputBorder( - borderSide: - BorderSide(width: 2, color: Colors.white), + child: Semantics( + textField: true, + label: context.t.email_enter_sign_in_code, + enabled: true, + child: TextFormField( + autofocus: model.showOTPfield, + controller: model.otpController, + keyboardType: TextInputType.number, + decoration: InputDecoration( + labelText: context.t.email_enter_sign_in_code, + hintText: context.t.email_enter_sign_in_code, + errorText: model.incorrectOTP + ? context.t.email_invalid_code + : null, + errorMaxLines: 5, + border: const OutlineInputBorder( + borderSide: + BorderSide(width: 2, color: Colors.white), + ), ), ), ), @@ -203,23 +254,31 @@ class NativeLoginView extends StatelessWidget { Expanded( child: Container( margin: const EdgeInsets.all(16), - child: ElevatedButton( - style: ctaButtonStyle.copyWith( - padding: const WidgetStatePropertyAll( - EdgeInsets.symmetric(vertical: 8), + child: Tooltip( + message: 'Submit and sign in to freeCodeCamp', + child: ElevatedButton( + style: ctaButtonStyle.copyWith( + padding: const WidgetStatePropertyAll( + EdgeInsets.symmetric(vertical: 8), + ), ), - ), - onPressed: model.otpFieldIsValid - ? () { - model.verifyOTP(context); - } - : null, - child: Text( - 'Submit and sign in to freeCodeCamp', - style: TextStyle( - fontSize: 20, + onPressed: model.otpFieldIsValid + ? () { + model.verifyOTP(context); + } + : null, + child: Semantics( + button: true, + enabled: model.otpFieldIsValid, + label: 'Submit and sign in to freeCodeCamp', + child: Text( + 'Submit and sign in to freeCodeCamp', + style: TextStyle( + fontSize: 20, + ), + textAlign: TextAlign.center, + ), ), - textAlign: TextAlign.center, ), ), ), @@ -229,27 +288,39 @@ class NativeLoginView extends StatelessWidget { child: Container( margin: const EdgeInsets.all(16), constraints: const BoxConstraints(minHeight: 50), - child: ElevatedButton( - style: ctaButtonStyle, - onPressed: model.emailFieldIsValid - ? () { - model.sendOTPtoEmail(); - } - : null, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Align( - child: Text( - context.t.email_submit_code, - style: TextStyle( - fontSize: 20, + child: Tooltip( + message: context.t.email_submit_code, + child: ElevatedButton( + style: ctaButtonStyle, + onPressed: model.emailFieldIsValid + ? () { + model.sendOTPtoEmail(); + } + : null, + child: Semantics( + button: true, + enabled: model.emailFieldIsValid, + label: context.t.email_submit_code, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Align( + child: Text( + context.t.email_submit_code, + style: TextStyle( + fontSize: 20, + ), + textAlign: TextAlign.center, + ), ), - textAlign: TextAlign.center, ), ), ), ), ), + ) + ), + ), + ), ), ], ), diff --git a/mobile-app/lib/ui/widgets/drawer_widget/drawer_tile.dart b/mobile-app/lib/ui/widgets/drawer_widget/drawer_tile.dart index d47b13de2..b7f7cf676 100644 --- a/mobile-app/lib/ui/widgets/drawer_widget/drawer_tile.dart +++ b/mobile-app/lib/ui/widgets/drawer_widget/drawer_tile.dart @@ -22,30 +22,52 @@ class _DrawerTileState extends State { Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(10.0), - child: ListTile( - dense: true, - leading: widget.icon != '' - ? Icon( - widget.icon, - color: widget.textColor, - ) - : Image.asset( - 'assets/images/logo.png', - width: 30, - height: 30, - color: Colors.white, - ), - title: Text( - widget.component, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: widget.textColor, - letterSpacing: 0.5), + child: Tooltip( + message: widget.component, + child: Semantics( + button: true, + enabled: true, + label: widget.component, + onTap: () { + widget.route(); + }, + child: ListTile( + dense: true, + leading: widget.icon != '' + ? Semantics( + image: true, + label: widget.component, + child: Icon( + widget.icon, + color: widget.textColor, + semanticLabel: widget.component, + ), + ) + : Semantics( + image: true, + label: 'freeCodeCamp logo', + child: Image.asset( + 'assets/images/logo.png', + width: 30, + height: 30, + color: Colors.white, + semanticLabel: 'freeCodeCamp logo', + ), + ), + title: Text( + widget.component, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: widget.textColor, + letterSpacing: 0.5), + semanticsLabel: widget.component, + ), + onTap: () { + widget.route(); + }, + ), ), - onTap: () { - widget.route(); - }, ), ); } diff --git a/mobile-app/lib/ui/widgets/drawer_widget/drawer_web_buttton.dart b/mobile-app/lib/ui/widgets/drawer_widget/drawer_web_buttton.dart index 2f140c5f4..db18e8610 100644 --- a/mobile-app/lib/ui/widgets/drawer_widget/drawer_web_buttton.dart +++ b/mobile-app/lib/ui/widgets/drawer_widget/drawer_web_buttton.dart @@ -58,22 +58,39 @@ class _CustomTabButtonState extends State { Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(10.0), - child: ListTile( - dense: true, - onTap: () { - widget.startCustomTabs(widget.url); - }, - leading: Icon( - widget.icon, - color: Colors.white, - ), - title: Text( - widget.component, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Colors.white, - letterSpacing: 0.5, + child: Tooltip( + message: widget.component, + child: Semantics( + button: true, + enabled: true, + label: widget.component, + onTap: () { + widget.startCustomTabs(widget.url); + }, + child: ListTile( + dense: true, + onTap: () { + widget.startCustomTabs(widget.url); + }, + leading: Semantics( + image: true, + label: widget.component, + child: Icon( + widget.icon, + color: Colors.white, + semanticLabel: widget.component, + ), + ), + title: Text( + widget.component, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Colors.white, + letterSpacing: 0.5, + ), + semanticsLabel: widget.component, + ), ), ), ), diff --git a/mobile-app/lib/ui/widgets/drawer_widget/drawer_widget_view.dart b/mobile-app/lib/ui/widgets/drawer_widget/drawer_widget_view.dart index baf6e95c2..b6a31981f 100644 --- a/mobile-app/lib/ui/widgets/drawer_widget/drawer_widget_view.dart +++ b/mobile-app/lib/ui/widgets/drawer_widget/drawer_widget_view.dart @@ -35,10 +35,15 @@ class DrawerWidgetView extends StatelessWidget { children: [ ListTile( contentPadding: const EdgeInsets.all(16), - leading: Image.asset( - 'assets/images/placeholder-profile-img.png', - width: 75, - height: 75, + leading: Semantics( + image: true, + label: 'User profile picture', + child: Image.asset( + 'assets/images/placeholder-profile-img.png', + width: 75, + height: 75, + semanticLabel: 'User profile picture', + ), ), title: model.loggedIn ? FutureBuilder( @@ -47,24 +52,45 @@ class DrawerWidgetView extends StatelessWidget { if (snapshot.hasData) { FccUserModel user = snapshot.data as FccUserModel; - return Text( - user.name.isEmpty - ? user.username - : user.name, + String userName = user.name.isEmpty + ? user.username + : user.name; + return Semantics( + label: 'User name: $userName', + child: Text( + userName, + semanticsLabel: userName, + ), ); } - return Text( - context.t.anonymous_user, + return Semantics( + label: context.t.anonymous_user, + child: Text( + context.t.anonymous_user, + semanticsLabel: context.t.anonymous_user, + ), ); }) - : Text( - context.t.anonymous_user, + : Semantics( + label: context.t.anonymous_user, + child: Text( + context.t.anonymous_user, + semanticsLabel: context.t.anonymous_user, + ), ), - subtitle: Text( - model.loggedIn + subtitle: Semantics( + label: model.loggedIn ? context.t.coolest_camper : context.t.login_save_progress, + child: Text( + model.loggedIn + ? context.t.coolest_camper + : context.t.login_save_progress, + semanticsLabel: model.loggedIn + ? context.t.coolest_camper + : context.t.login_save_progress, + ), ), isThreeLine: true, onTap: () {