Update user list screen to properly support newer cubit logic
parent
5ee1dec6b5
commit
5f58022d42
|
@ -283,6 +283,8 @@
|
||||||
"account": "Account",
|
"account": "Account",
|
||||||
"send_registration_data": "Share login credentials",
|
"send_registration_data": "Share login credentials",
|
||||||
"could_not_fetch_users": "Couldn't fetch users list",
|
"could_not_fetch_users": "Couldn't fetch users list",
|
||||||
|
"could_not_fetch_description": "Please check your internet connection and try again",
|
||||||
|
"refresh_users": "Refresh users list",
|
||||||
"could_not_create_user": "Couldn't create user",
|
"could_not_create_user": "Couldn't create user",
|
||||||
"could_not_delete_user": "Couldn't delete user",
|
"could_not_delete_user": "Couldn't delete user",
|
||||||
"could_not_add_ssh_key": "Couldn't add SSH key"
|
"could_not_add_ssh_key": "Couldn't add SSH key"
|
||||||
|
|
|
@ -31,7 +31,6 @@ mixin UsersApi on ApiMap {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
print("Could not");
|
|
||||||
}
|
}
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,29 +9,41 @@ class ServicesState extends ServerInstallationDependendState {
|
||||||
|
|
||||||
final List<Service> services;
|
final List<Service> services;
|
||||||
bool get isPasswordManagerEnable => services
|
bool get isPasswordManagerEnable => services
|
||||||
.firstWhere((final service) => service.id == 'bitwarden',
|
.firstWhere(
|
||||||
orElse: () => Service.empty)
|
(final service) => service.id == 'bitwarden',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
.isEnabled;
|
.isEnabled;
|
||||||
bool get isCloudEnable => services
|
bool get isCloudEnable => services
|
||||||
.firstWhere((final service) => service.id == 'nextcloud',
|
.firstWhere(
|
||||||
orElse: () => Service.empty)
|
(final service) => service.id == 'nextcloud',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
.isEnabled;
|
.isEnabled;
|
||||||
bool get isGitEnable => services
|
bool get isGitEnable => services
|
||||||
.firstWhere((final service) => service.id == 'gitea',
|
.firstWhere(
|
||||||
orElse: () => Service.empty)
|
(final service) => service.id == 'gitea',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
.isEnabled;
|
.isEnabled;
|
||||||
bool get isSocialNetworkEnable => services
|
bool get isSocialNetworkEnable => services
|
||||||
.firstWhere((final service) => service.id == 'pleroma',
|
.firstWhere(
|
||||||
orElse: () => Service.empty)
|
(final service) => service.id == 'pleroma',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
.isEnabled;
|
.isEnabled;
|
||||||
bool get isVpnEnable => services
|
bool get isVpnEnable => services
|
||||||
.firstWhere((final service) => service.id == 'ocserv',
|
.firstWhere(
|
||||||
orElse: () => Service.empty)
|
(final service) => service.id == 'ocserv',
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
)
|
||||||
.isEnabled;
|
.isEnabled;
|
||||||
|
|
||||||
Service? getServiceById(final String id) {
|
Service? getServiceById(final String id) {
|
||||||
final service = services.firstWhere((final service) => service.id == id,
|
final service = services.firstWhere(
|
||||||
orElse: () => Service.empty);
|
(final service) => service.id == id,
|
||||||
|
orElse: () => Service.empty,
|
||||||
|
);
|
||||||
if (service.id == 'empty') {
|
if (service.id == 'empty') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
serverInstallationCubit,
|
serverInstallationCubit,
|
||||||
const UsersState(
|
const UsersState(
|
||||||
<User>[],
|
<User>[],
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Box<User> box = Hive.box<User>(BNames.usersBox);
|
Box<User> box = Hive.box<User>(BNames.usersBox);
|
||||||
|
@ -33,6 +34,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
emit(
|
emit(
|
||||||
UsersState(
|
UsersState(
|
||||||
loadedUsers,
|
loadedUsers,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -44,11 +46,15 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
if (serverInstallationCubit.state is! ServerInstallationFinished) {
|
if (serverInstallationCubit.state is! ServerInstallationFinished) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
emit(state.copyWith(isLoading: true));
|
||||||
|
// sleep for 10 seconds to simulate a slow connection
|
||||||
|
await Future<void>.delayed(const Duration(seconds: 10));
|
||||||
final List<User> usersFromServer = await api.getAllUsers();
|
final List<User> usersFromServer = await api.getAllUsers();
|
||||||
if (usersFromServer.isNotEmpty) {
|
if (usersFromServer.isNotEmpty) {
|
||||||
emit(
|
emit(
|
||||||
UsersState(
|
UsersState(
|
||||||
usersFromServer,
|
usersFromServer,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// Update the users it the box
|
// Update the users it the box
|
||||||
|
@ -57,6 +63,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
} else {
|
} else {
|
||||||
getIt<NavigationService>()
|
getIt<NavigationService>()
|
||||||
.showSnackBar('users.could_not_fetch_users'.tr());
|
.showSnackBar('users.could_not_fetch_users'.tr());
|
||||||
|
emit(state.copyWith(isLoading: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +117,9 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changeUserPassword(
|
Future<void> changeUserPassword(
|
||||||
final User user, final String newPassword) async {
|
final User user,
|
||||||
|
final String newPassword,
|
||||||
|
) async {
|
||||||
if (user.type == UserType.root) {
|
if (user.type == UserType.root) {
|
||||||
getIt<NavigationService>()
|
getIt<NavigationService>()
|
||||||
.showSnackBar('users.could_not_change_password'.tr());
|
.showSnackBar('users.could_not_change_password'.tr());
|
||||||
|
@ -120,7 +129,8 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
await api.updateUser(user.login, newPassword);
|
await api.updateUser(user.login, newPassword);
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
getIt<NavigationService>().showSnackBar(
|
getIt<NavigationService>().showSnackBar(
|
||||||
result.message ?? 'users.could_not_change_password'.tr());
|
result.message ?? 'users.could_not_change_password'.tr(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +170,7 @@ class UsersCubit extends ServerInstallationDependendCubit<UsersState> {
|
||||||
emit(
|
emit(
|
||||||
const UsersState(
|
const UsersState(
|
||||||
<User>[],
|
<User>[],
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
part of 'users_cubit.dart';
|
part of 'users_cubit.dart';
|
||||||
|
|
||||||
class UsersState extends ServerInstallationDependendState {
|
class UsersState extends ServerInstallationDependendState {
|
||||||
const UsersState(this.users);
|
const UsersState(this.users, this.isLoading);
|
||||||
|
|
||||||
final List<User> users;
|
final List<User> users;
|
||||||
|
final bool isLoading;
|
||||||
|
|
||||||
User get rootUser =>
|
User get rootUser =>
|
||||||
users.firstWhere((final user) => user.type == UserType.root);
|
users.firstWhere((final user) => user.type == UserType.root);
|
||||||
|
@ -15,13 +16,15 @@ class UsersState extends ServerInstallationDependendState {
|
||||||
users.where((final user) => user.type == UserType.normal).toList();
|
users.where((final user) => user.type == UserType.normal).toList();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [users];
|
List<Object> get props => [users, isLoading];
|
||||||
|
|
||||||
UsersState copyWith({
|
UsersState copyWith({
|
||||||
final List<User>? users,
|
final List<User>? users,
|
||||||
|
final bool? isLoading,
|
||||||
}) =>
|
}) =>
|
||||||
UsersState(
|
UsersState(
|
||||||
users ?? this.users,
|
users ?? this.users,
|
||||||
|
isLoading ?? this.isLoading,
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isLoginRegistered(final String login) =>
|
bool isLoginRegistered(final String login) =>
|
||||||
|
|
|
@ -31,3 +31,35 @@ class _NoUsers extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _CouldNotLoadUsers extends StatelessWidget {
|
||||||
|
const _CouldNotLoadUsers({required this.text});
|
||||||
|
|
||||||
|
final String text;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(BrandIcons.users, size: 50, color: BrandColors.grey7),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
BrandText.h2(
|
||||||
|
'users.could_not_fetch_users'.tr(),
|
||||||
|
style: const TextStyle(
|
||||||
|
color: BrandColors.grey7,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
BrandText.medium(
|
||||||
|
text,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: BrandColors.grey7,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import 'package:selfprivacy/logic/models/job.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/user.dart';
|
import 'package:selfprivacy/logic/models/hive/user.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart';
|
import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
|
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/brand_button/outlined_button.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
|
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
|
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
|
||||||
|
@ -46,10 +47,47 @@ class UsersPage extends StatelessWidget {
|
||||||
} else {
|
} else {
|
||||||
child = BlocBuilder<UsersCubit, UsersState>(
|
child = BlocBuilder<UsersCubit, UsersState>(
|
||||||
builder: (final BuildContext context, final UsersState state) {
|
builder: (final BuildContext context, final UsersState state) {
|
||||||
print('Rebuild users page');
|
final List<User> users = state.users
|
||||||
final primaryUser = state.primaryUser;
|
.where((final user) => user.type != UserType.root)
|
||||||
final users = [primaryUser, ...state.users];
|
.toList();
|
||||||
|
// final List<User> users = [];
|
||||||
|
users.sort(
|
||||||
|
(final User a, final User b) =>
|
||||||
|
a.login.toLowerCase().compareTo(b.login.toLowerCase()),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (users.isEmpty) {
|
||||||
|
if (state.isLoading) {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
context.read<UsersCubit>().refresh();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
_CouldNotLoadUsers(
|
||||||
|
text: 'users.could_not_fetch_description'.tr(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 18),
|
||||||
|
BrandOutlinedButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.read<UsersCubit>().refresh();
|
||||||
|
},
|
||||||
|
title: 'users.refresh_users'.tr(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
context.read<UsersCubit>().refresh();
|
context.read<UsersCubit>().refresh();
|
||||||
|
@ -59,7 +97,7 @@ class UsersPage extends StatelessWidget {
|
||||||
itemBuilder: (final BuildContext context, final int index) =>
|
itemBuilder: (final BuildContext context, final int index) =>
|
||||||
_User(
|
_User(
|
||||||
user: users[index],
|
user: users[index],
|
||||||
isRootUser: index == 0,
|
isRootUser: users[index].type == UserType.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue