mirror of
https://github.com/immich-app/immich.git
synced 2024-12-22 01:47:08 +02:00
Implemented remembering login data with radio button (#126)
This commit is contained in:
parent
c1ccf026f0
commit
da9eb61532
@ -3,9 +3,9 @@ const String userInfoBox = "immichBoxUserInfo"; // Box
|
|||||||
const String accessTokenKey = "immichBoxAccessTokenKey"; // Key 1
|
const String accessTokenKey = "immichBoxAccessTokenKey"; // Key 1
|
||||||
const String deviceIdKey = 'immichBoxDeviceIdKey'; // Key 2
|
const String deviceIdKey = 'immichBoxDeviceIdKey'; // Key 2
|
||||||
|
|
||||||
// SERVER ENDPOINT
|
// Server endpoint
|
||||||
const String serverEndpointKey = 'immichBoxServerEndpoint';
|
const String serverEndpointKey = 'immichBoxServerEndpoint';
|
||||||
|
|
||||||
// KEY
|
// Login Info
|
||||||
const String hiveAllAsssetKey = "allAssets";
|
const String hiveLoginInfoBox = "immichLoginInfoBox";
|
||||||
const String hiveBackupProgressKey = "backupProgressAssets";
|
const String savedLoginInfoKey = "immichSavedLoginInfoKey";
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/immich_colors.dart';
|
import 'package:immich_mobile/constants/immich_colors.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/shared/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/routing/tab_navigation_observer.dart';
|
import 'package:immich_mobile/routing/tab_navigation_observer.dart';
|
||||||
@ -15,7 +16,9 @@ import 'constants/hive_box.dart';
|
|||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
await Hive.initFlutter();
|
await Hive.initFlutter();
|
||||||
|
Hive.registerAdapter(HiveSavedLoginInfoAdapter());
|
||||||
await Hive.openBox(userInfoBox);
|
await Hive.openBox(userInfoBox);
|
||||||
|
await Hive.openBox<HiveSavedLoginInfo>(hiveLoginInfoBox);
|
||||||
|
|
||||||
SystemChrome.setSystemUIOverlayStyle(
|
SystemChrome.setSystemUIOverlayStyle(
|
||||||
const SystemUiOverlayStyle(
|
const SystemUiOverlayStyle(
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
|
|
||||||
|
part 'hive_saved_login_info.model.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: 0)
|
||||||
|
class HiveSavedLoginInfo {
|
||||||
|
@HiveField(0)
|
||||||
|
String email;
|
||||||
|
|
||||||
|
@HiveField(1)
|
||||||
|
String password;
|
||||||
|
|
||||||
|
@HiveField(2)
|
||||||
|
String serverUrl;
|
||||||
|
|
||||||
|
@HiveField(3)
|
||||||
|
bool isSaveLogin;
|
||||||
|
|
||||||
|
HiveSavedLoginInfo({required this.email, required this.password, required this.serverUrl, required this.isSaveLogin});
|
||||||
|
}
|
Binary file not shown.
@ -4,6 +4,7 @@ import 'package:hive/hive.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/hive_box.dart';
|
import 'package:immich_mobile/constants/hive_box.dart';
|
||||||
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
|
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
|
||||||
|
import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart';
|
||||||
import 'package:immich_mobile/modules/login/models/login_response.model.dart';
|
import 'package:immich_mobile/modules/login/models/login_response.model.dart';
|
||||||
import 'package:immich_mobile/shared/services/backup.service.dart';
|
import 'package:immich_mobile/shared/services/backup.service.dart';
|
||||||
import 'package:immich_mobile/shared/services/device_info.service.dart';
|
import 'package:immich_mobile/shared/services/device_info.service.dart';
|
||||||
@ -36,7 +37,7 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
|
|||||||
final BackupService _backupService = BackupService();
|
final BackupService _backupService = BackupService();
|
||||||
final NetworkService _networkService = NetworkService();
|
final NetworkService _networkService = NetworkService();
|
||||||
|
|
||||||
Future<bool> login(String email, String password, String serverEndpoint) async {
|
Future<bool> login(String email, String password, String serverEndpoint, bool isSavedLoginInfo) async {
|
||||||
// Store server endpoint to Hive and test endpoint
|
// Store server endpoint to Hive and test endpoint
|
||||||
if (serverEndpoint[serverEndpoint.length - 1] == "/") {
|
if (serverEndpoint[serverEndpoint.length - 1] == "/") {
|
||||||
var validUrl = serverEndpoint.substring(0, serverEndpoint.length - 1);
|
var validUrl = serverEndpoint.substring(0, serverEndpoint.length - 1);
|
||||||
@ -76,6 +77,20 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
|
|||||||
userId: payload.userId,
|
userId: payload.userId,
|
||||||
userEmail: payload.userEmail,
|
userEmail: payload.userEmail,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isSavedLoginInfo) {
|
||||||
|
// Save login info to local storage
|
||||||
|
Hive.box<HiveSavedLoginInfo>(hiveLoginInfoBox).put(
|
||||||
|
savedLoginInfoKey,
|
||||||
|
HiveSavedLoginInfo(
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
isSaveLogin: true,
|
||||||
|
serverUrl: Hive.box(userInfoBox).get(serverEndpointKey)),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Hive.box<HiveSavedLoginInfo>(hiveLoginInfoBox).delete(savedLoginInfoKey);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.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/shared/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/modules/login/providers/authentication.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/providers/backup.provider.dart';
|
||||||
@ -12,22 +15,36 @@ class LoginForm extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final usernameController = useTextEditingController(text: 'testuser@email.com');
|
final usernameController = useTextEditingController.fromValue(TextEditingValue.empty);
|
||||||
final passwordController = useTextEditingController(text: 'password');
|
final passwordController = useTextEditingController.fromValue(TextEditingValue.empty);
|
||||||
final serverEndpointController = useTextEditingController(text: 'http://192.168.1.216:2283');
|
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(
|
return Center(
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 300),
|
constraints: const BoxConstraints(maxWidth: 300),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 32,
|
spacing: 16,
|
||||||
runSpacing: 32,
|
runSpacing: 16,
|
||||||
alignment: WrapAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Image(
|
const Image(
|
||||||
image: AssetImage('assets/immich-logo-no-outline.png'),
|
image: AssetImage('assets/immich-logo-no-outline.png'),
|
||||||
width: 128,
|
width: 100,
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
@ -42,10 +59,29 @@ class LoginForm extends HookConsumerWidget {
|
|||||||
EmailInput(controller: usernameController),
|
EmailInput(controller: usernameController),
|
||||||
PasswordInput(controller: passwordController),
|
PasswordInput(controller: passwordController),
|
||||||
ServerEndpointInput(controller: serverEndpointController),
|
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(
|
LoginButton(
|
||||||
emailController: usernameController,
|
emailController: usernameController,
|
||||||
passwordController: passwordController,
|
passwordController: passwordController,
|
||||||
serverEndpointController: serverEndpointController,
|
serverEndpointController: serverEndpointController,
|
||||||
|
isSavedLoginInfo: isSaveLoginInfo.value,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -104,29 +140,34 @@ class LoginButton extends ConsumerWidget {
|
|||||||
final TextEditingController emailController;
|
final TextEditingController emailController;
|
||||||
final TextEditingController passwordController;
|
final TextEditingController passwordController;
|
||||||
final TextEditingController serverEndpointController;
|
final TextEditingController serverEndpointController;
|
||||||
|
final bool isSavedLoginInfo;
|
||||||
|
|
||||||
const LoginButton(
|
const LoginButton({
|
||||||
{Key? key,
|
Key? key,
|
||||||
required this.emailController,
|
required this.emailController,
|
||||||
required this.passwordController,
|
required this.passwordController,
|
||||||
required this.serverEndpointController})
|
required this.serverEndpointController,
|
||||||
: super(key: key);
|
required this.isSavedLoginInfo,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
visualDensity: VisualDensity.standard,
|
||||||
|
padding: MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.symmetric(vertical: 10, horizontal: 25)),
|
||||||
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
// This will remove current cache asset state of previous user login.
|
// This will remove current cache asset state of previous user login.
|
||||||
ref.watch(assetProvider.notifier).clearAllAsset();
|
ref.watch(assetProvider.notifier).clearAllAsset();
|
||||||
|
|
||||||
var isAuthenticated = await ref
|
var isAuthenticated = await ref
|
||||||
.read(authenticationProvider.notifier)
|
.read(authenticationProvider.notifier)
|
||||||
.login(emailController.text, passwordController.text, serverEndpointController.text);
|
.login(emailController.text, passwordController.text, serverEndpointController.text, isSavedLoginInfo);
|
||||||
|
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
// Resume backup (if enable) then navigate
|
// Resume backup (if enable) then navigate
|
||||||
ref.watch(backupProvider.notifier).resumeBackup();
|
ref.watch(backupProvider.notifier).resumeBackup();
|
||||||
// AutoRouter.of(context).pushNamed("/home-page");
|
|
||||||
AutoRouter.of(context).pushNamed("/tab-controller-page");
|
AutoRouter.of(context).pushNamed("/tab-controller-page");
|
||||||
} else {
|
} else {
|
||||||
ImmichToast.show(
|
ImmichToast.show(
|
||||||
@ -136,6 +177,9 @@ class LoginButton extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: const Text("Login"));
|
child: const Text(
|
||||||
|
"Login",
|
||||||
|
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user