import 'package:easy_localization/easy_localization.dart'; import 'package:hive/hive.dart'; import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/config/hive_config.dart'; import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server.dart'; import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart'; import 'package:selfprivacy/logic/models/hive/user.dart'; export 'package:provider/provider.dart'; part 'users_state.dart'; class UsersCubit extends ServerInstallationDependendCubit { UsersCubit(final ServerInstallationCubit serverInstallationCubit) : super( serverInstallationCubit, const UsersState( [], false, ), ); Box box = Hive.box(BNames.usersBox); Box serverInstallationBox = Hive.box(BNames.serverInstallationBox); final ServerApi api = ServerApi(); @override Future load() async { if (serverInstallationCubit.state is! ServerInstallationFinished) { return; } final List loadedUsers = box.values.toList(); if (loadedUsers.isNotEmpty) { emit( UsersState( loadedUsers, false, ), ); } refresh(); } Future refresh() async { if (serverInstallationCubit.state is! ServerInstallationFinished) { return; } emit(state.copyWith(isLoading: true)); final List usersFromServer = await api.getAllUsers(); if (usersFromServer.isNotEmpty) { emit( UsersState( usersFromServer, false, ), ); // Update the users it the box await box.clear(); await box.addAll(usersFromServer); } else { getIt() .showSnackBar('users.could_not_fetch_users'.tr()); emit(state.copyWith(isLoading: false)); } } Future createUser(final User user) async { // If user exists on server, do nothing if (state.users .any((final User u) => u.login == user.login && u.isFoundOnServer)) { return; } final String? password = user.password; if (password == null) { getIt() .showSnackBar('users.could_not_create_user'.tr()); return; } // If API returned error, do nothing final UserMutationResult result = await api.createUser(user.login, password); final User? createdUser = result.user; if (!result.success || createdUser == null) { getIt() .showSnackBar(result.message ?? 'users.could_not_create_user'.tr()); return; } final List loadedUsers = List.from(state.users); loadedUsers.add(createdUser); await box.clear(); await box.addAll(loadedUsers); emit(state.copyWith(users: loadedUsers)); } Future deleteUser(final User user) async { // If user is primary or root, don't delete if (user.type != UserType.normal) { getIt() .showSnackBar('users.could_not_delete_user'.tr()); return; } final List loadedUsers = List.from(state.users); final GenericMutationResult result = await api.deleteUser(user.login); if (result.success) { loadedUsers.removeWhere((final User u) => u.login == user.login); await box.clear(); await box.addAll(loadedUsers); emit(state.copyWith(users: loadedUsers)); } else { getIt() .showSnackBar(result.message ?? 'users.could_not_delete_user'.tr()); } } Future changeUserPassword( final User user, final String newPassword, ) async { if (user.type == UserType.root) { getIt() .showSnackBar('users.could_not_change_password'.tr()); return; } final UserMutationResult result = await api.updateUser(user.login, newPassword); if (!result.success) { getIt().showSnackBar( result.message ?? 'users.could_not_change_password'.tr(), ); } } Future addSshKey(final User user, final String publicKey) async { final UserMutationResult result = await api.addSshKey(user.login, publicKey); if (result.success) { final User updatedUser = result.user!; final int index = state.users.indexWhere((final User u) => u.login == user.login); await box.putAt(index, updatedUser); emit( state.copyWith( users: box.values.toList(), ), ); } else { getIt() .showSnackBar(result.message ?? 'users.could_not_add_ssh_key'.tr()); } } Future deleteSshKey(final User user, final String publicKey) async { final UserMutationResult result = await api.removeSshKey(user.login, publicKey); if (result.success) { final User updatedUser = result.user!; final int index = state.users.indexWhere((final User u) => u.login == user.login); await box.putAt(index, updatedUser); emit( state.copyWith( users: box.values.toList(), ), ); } } @override void clear() async { emit( const UsersState( [], false, ), ); } }