mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			186 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:auto_route/auto_route.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| import 'package:flutter_hooks/flutter_hooks.dart';
 | |
| import 'package:hive/hive.dart';
 | |
| import 'package:hooks_riverpod/hooks_riverpod.dart';
 | |
| import 'package:immich_mobile/constants/hive_box.dart';
 | |
| import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart';
 | |
| import 'package:immich_mobile/shared/providers/asset.provider.dart';
 | |
| import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
 | |
| import 'package:immich_mobile/shared/providers/backup.provider.dart';
 | |
| import 'package:immich_mobile/shared/ui/immich_toast.dart';
 | |
| 
 | |
| class LoginForm extends HookConsumerWidget {
 | |
|   const LoginForm({Key? key}) : super(key: key);
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context, WidgetRef ref) {
 | |
|     final usernameController = useTextEditingController.fromValue(TextEditingValue.empty);
 | |
|     final passwordController = useTextEditingController.fromValue(TextEditingValue.empty);
 | |
|     final serverEndpointController = useTextEditingController(text: 'http://your-server-ip:2283');
 | |
|     final isSaveLoginInfo = useState<bool>(false);
 | |
| 
 | |
|     useEffect(() {
 | |
|       var loginInfo = Hive.box<HiveSavedLoginInfo>(hiveLoginInfoBox).get(savedLoginInfoKey);
 | |
| 
 | |
|       if (loginInfo != null) {
 | |
|         usernameController.text = loginInfo.email;
 | |
|         passwordController.text = loginInfo.password;
 | |
|         serverEndpointController.text = loginInfo.serverUrl;
 | |
|         isSaveLoginInfo.value = loginInfo.isSaveLogin;
 | |
|       }
 | |
| 
 | |
|       return null;
 | |
|     }, []);
 | |
| 
 | |
|     return Center(
 | |
|       child: ConstrainedBox(
 | |
|         constraints: const BoxConstraints(maxWidth: 300),
 | |
|         child: SingleChildScrollView(
 | |
|           child: Wrap(
 | |
|             spacing: 16,
 | |
|             runSpacing: 16,
 | |
|             alignment: WrapAlignment.center,
 | |
|             children: [
 | |
|               const Image(
 | |
|                 image: AssetImage('assets/immich-logo-no-outline.png'),
 | |
|                 width: 100,
 | |
|                 filterQuality: FilterQuality.high,
 | |
|               ),
 | |
|               Text(
 | |
|                 'IMMICH',
 | |
|                 style: TextStyle(
 | |
|                   fontFamily: 'SnowburstOne',
 | |
|                   fontWeight: FontWeight.bold,
 | |
|                   fontSize: 48,
 | |
|                   color: Theme.of(context).primaryColor,
 | |
|                 ),
 | |
|               ),
 | |
|               EmailInput(controller: usernameController),
 | |
|               PasswordInput(controller: passwordController),
 | |
|               ServerEndpointInput(controller: serverEndpointController),
 | |
|               CheckboxListTile(
 | |
|                 activeColor: Theme.of(context).primaryColor,
 | |
|                 contentPadding: const EdgeInsets.symmetric(horizontal: 8),
 | |
|                 dense: true,
 | |
|                 side: const BorderSide(color: Colors.grey, width: 1.5),
 | |
|                 shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
 | |
|                 enableFeedback: true,
 | |
|                 title: const Text(
 | |
|                   "Save login",
 | |
|                   style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey),
 | |
|                 ),
 | |
|                 value: isSaveLoginInfo.value,
 | |
|                 onChanged: (switchValue) {
 | |
|                   if (switchValue != null) {
 | |
|                     isSaveLoginInfo.value = switchValue;
 | |
|                   }
 | |
|                 },
 | |
|               ),
 | |
|               LoginButton(
 | |
|                 emailController: usernameController,
 | |
|                 passwordController: passwordController,
 | |
|                 serverEndpointController: serverEndpointController,
 | |
|                 isSavedLoginInfo: isSaveLoginInfo.value,
 | |
|               ),
 | |
|             ],
 | |
|           ),
 | |
|         ),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| class ServerEndpointInput extends StatelessWidget {
 | |
|   final TextEditingController controller;
 | |
| 
 | |
|   const ServerEndpointInput({Key? key, required this.controller}) : super(key: key);
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return TextFormField(
 | |
|       controller: controller,
 | |
|       decoration: const InputDecoration(
 | |
|           labelText: 'Server Endpoint URL', border: OutlineInputBorder(), hintText: 'http://your-server-ip:port'),
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| class EmailInput extends StatelessWidget {
 | |
|   final TextEditingController controller;
 | |
| 
 | |
|   const EmailInput({Key? key, required this.controller}) : super(key: key);
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return TextFormField(
 | |
|       controller: controller,
 | |
|       decoration:
 | |
|           const InputDecoration(labelText: 'Email', border: OutlineInputBorder(), hintText: 'youremail@email.com'),
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| class PasswordInput extends StatelessWidget {
 | |
|   final TextEditingController controller;
 | |
| 
 | |
|   const PasswordInput({Key? key, required this.controller}) : super(key: key);
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return TextFormField(
 | |
|       obscureText: true,
 | |
|       controller: controller,
 | |
|       decoration: const InputDecoration(labelText: 'Password', border: OutlineInputBorder(), hintText: 'password'),
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| class LoginButton extends ConsumerWidget {
 | |
|   final TextEditingController emailController;
 | |
|   final TextEditingController passwordController;
 | |
|   final TextEditingController serverEndpointController;
 | |
|   final bool isSavedLoginInfo;
 | |
| 
 | |
|   const LoginButton({
 | |
|     Key? key,
 | |
|     required this.emailController,
 | |
|     required this.passwordController,
 | |
|     required this.serverEndpointController,
 | |
|     required this.isSavedLoginInfo,
 | |
|   }) : super(key: key);
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context, WidgetRef ref) {
 | |
|     return ElevatedButton(
 | |
|         style: ButtonStyle(
 | |
|           visualDensity: VisualDensity.standard,
 | |
|           padding: MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.symmetric(vertical: 10, horizontal: 25)),
 | |
|         ),
 | |
|         onPressed: () async {
 | |
|           // This will remove current cache asset state of previous user login.
 | |
|           ref.watch(assetProvider.notifier).clearAllAsset();
 | |
| 
 | |
|           var isAuthenticated = await ref
 | |
|               .read(authenticationProvider.notifier)
 | |
|               .login(emailController.text, passwordController.text, serverEndpointController.text, isSavedLoginInfo);
 | |
| 
 | |
|           if (isAuthenticated) {
 | |
|             // Resume backup (if enable) then navigate
 | |
|             ref.watch(backupProvider.notifier).resumeBackup();
 | |
|             AutoRouter.of(context).pushNamed("/tab-controller-page");
 | |
|           } else {
 | |
|             ImmichToast.show(
 | |
|               context: context,
 | |
|               msg: "Error logging you in, check server url, email and password!",
 | |
|               toastType: ToastType.error,
 | |
|             );
 | |
|           }
 | |
|         },
 | |
|         child: const Text(
 | |
|           "Login",
 | |
|           style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
 | |
|         ));
 | |
|   }
 | |
| }
 |