import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/widgets/layouts/login_scaffold.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'login.dart'; class LoginView extends StatelessWidget { final LoginController controller; const LoginView(this.controller, {super.key}); @override Widget build(BuildContext context) { final homeserver = Matrix.of(context) .getLoginClient() .homeserver .toString() .replaceFirst('https://', ''); final title = L10n.of(context)!.logInTo(homeserver); final titleParts = title.split(homeserver); final textFieldFillColor = FluffyThemes.isColumnMode(context) ? Theme.of(context).colorScheme.surface // ignore: deprecated_member_use : Theme.of(context).colorScheme.surfaceVariant; return LoginScaffold( enforceMobileMode: Matrix.of(context).client.isLogged(), appBar: AppBar( leading: controller.loading ? null : const Center(child: BackButton()), automaticallyImplyLeading: !controller.loading, titleSpacing: !controller.loading ? 0 : null, title: Text.rich( TextSpan( children: [ TextSpan(text: titleParts.first), TextSpan( text: homeserver, style: const TextStyle(fontWeight: FontWeight.bold), ), TextSpan(text: titleParts.last), ], ), style: const TextStyle(fontSize: 18), ), ), body: Builder( builder: (context) { return AutofillGroup( child: ListView( padding: const EdgeInsets.symmetric(horizontal: 8), children: [ Image.asset('assets/banner_transparent.png'), const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: TextField( readOnly: controller.loading, autocorrect: false, autofocus: true, onChanged: controller.checkWellKnownWithCoolDown, controller: controller.usernameController, textInputAction: TextInputAction.next, keyboardType: TextInputType.emailAddress, autofillHints: controller.loading ? null : [AutofillHints.username], decoration: InputDecoration( prefixIcon: const Icon(Icons.account_box_outlined), errorText: controller.usernameError, errorStyle: const TextStyle(color: Colors.orange), fillColor: textFieldFillColor, hintText: L10n.of(context)!.emailOrUsername, ), ), ), const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: TextField( readOnly: controller.loading, autocorrect: false, autofillHints: controller.loading ? null : [AutofillHints.password], controller: controller.passwordController, textInputAction: TextInputAction.go, obscureText: !controller.showPassword, onSubmitted: (_) => controller.login(), decoration: InputDecoration( prefixIcon: const Icon(Icons.lock_outlined), errorText: controller.passwordError, errorStyle: const TextStyle(color: Colors.orange), fillColor: textFieldFillColor, suffixIcon: IconButton( onPressed: controller.toggleShowPassword, icon: Icon( controller.showPassword ? Icons.visibility_off_outlined : Icons.visibility_outlined, color: Colors.black, ), ), hintText: L10n.of(context)!.password, ), ), ), const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, foregroundColor: Theme.of(context).colorScheme.onPrimary, ), onPressed: controller.loading ? null : controller.login, icon: const Icon(Icons.login_outlined), label: controller.loading ? const LinearProgressIndicator() : Text(L10n.of(context)!.login), ), ), const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: TextButton.icon( onPressed: controller.loading ? () {} : controller.passwordForgotten, style: TextButton.styleFrom( foregroundColor: Theme.of(context).colorScheme.error, ), icon: const Icon(Icons.safety_check_outlined), label: Text(L10n.of(context)!.passwordForgotten), ), ), const SizedBox(height: 16), ], ), ); }, ), ); } }