/* * Copyright (c) 2024-2025 Fabian Freund. * * This file is part of WebLibre * (see https://weblibre.eu). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ import 'package:flutter/material.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:weblibre/core/filesystem.dart'; import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/features/user/domain/presentation/dialogs/quit_browser_dialog.dart'; import 'package:weblibre/features/user/domain/presentation/utils/profile_switch_handler.dart'; import 'package:weblibre/features/user/domain/repositories/profile.dart'; import 'package:weblibre/presentation/widgets/failure_widget.dart'; import 'package:weblibre/utils/exit_app.dart'; /// Bottom sheet widget to select a user profile. class SelectProfileDialog extends HookConsumerWidget { const SelectProfileDialog(); @override Widget build(BuildContext context, WidgetRef ref) { final usersAsync = ref.watch(profileRepositoryProvider); return SafeArea( child: Padding( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'Users', style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 16), usersAsync.when( skipLoadingOnReload: true, data: (profiles) => Column( mainAxisSize: MainAxisSize.min, children: profiles.map((profile) { final isSelected = filesystem.selectedProfile == profile.uuidValue; return ListTile( key: ValueKey(profile.id), enabled: !isSelected, trailing: !isSelected ? const Icon(MdiIcons.accountSwitch) : null, title: Text(profile.name), subtitle: isSelected ? const Text('Active') : null, onTap: () async { await handleSwitchProfile(context, ref, profile); }, ); }).toList(), ), error: (error, stackTrace) => Center( child: FailureWidget( title: 'Failed to load Profiles', exception: error, ), ), loading: () => const Center(child: CircularProgressIndicator()), ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextButton.icon( icon: const Icon(MdiIcons.power), iconAlignment: IconAlignment.start, label: const Text('Quit Browser'), onPressed: () async { final result = await showQuitBrowserDialog(context); if (result == true) { await exitApp(ref.container); } }, ), TextButton.icon( icon: const Icon(MdiIcons.accountGroup), iconAlignment: IconAlignment.end, label: const Text('Manage'), onPressed: () async { await ProfileListRoute().push(context); }, ), ], ), ], ), ), ); } }