relatica/lib/screens/group_editor_screen.dart

174 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:result_monad/result_monad.dart';
import '../controls/padding.dart';
import '../controls/responsive_max_width.dart';
import '../controls/standard_appbar.dart';
import '../globals.dart';
import '../models/group_data.dart';
import '../services/connections_manager.dart';
import '../utils/active_profile_selector.dart';
import '../utils/snackbar_builder.dart';
class GroupEditorScreen extends StatefulWidget {
final String groupId;
GroupEditorScreen({super.key, required this.groupId});
@override
State<GroupEditorScreen> createState() => _GroupEditorScreenState();
}
class _GroupEditorScreenState extends State<GroupEditorScreen> {
final groupTextController = TextEditingController();
var processingUpdate = false;
var allowNameEditing = false;
late GroupData groupData;
Future<void> updateGroupName(
BuildContext context, ConnectionsManager manager) async {
processingUpdate = true;
final updated = groupTextController.text;
if (groupTextController.text != groupData.name) {
final confirm = await showYesNoDialog(
context, 'Change the group name from ${groupData.name} to $updated?');
if (context.mounted && confirm == true) {
await manager.renameGroup(widget.groupId, updated).match(
onSuccess: (updatedGroupData) {
groupData = updatedGroupData;
setState(() {
allowNameEditing = false;
});
}, onError: (error) {
if (mounted) {
buildSnackbar(context, 'Error renaming group: $error');
}
});
} else {
groupTextController.text = groupData.name;
}
}
processingUpdate = false;
}
Future<void> deleteGroup(ConnectionsManager manager) async {
final confirm = await showYesNoDialog(context,
"Permanently delete group ${groupData.name}? This can't be undone.");
if (context.mounted && confirm == true) {
await manager.deleteGroup(groupData).match(
onSuccess: (_) => context.canPop() ? context.pop() : null,
onError: (error) =>
buildSnackbar(context, 'Error trying to delete group: $error'),
);
}
}
@override
void initState() {
super.initState();
final manager =
getIt<ActiveProfileSelector<ConnectionsManager>>().activeEntry.value;
groupData = manager
.getMyGroups()
.where(
(g) => g.id == widget.groupId,
)
.first;
groupTextController.text = groupData.name;
}
@override
Widget build(BuildContext context) {
final manager = context
.watch<ActiveProfileSelector<ConnectionsManager>>()
.activeEntry
.value;
return Scaffold(
appBar: StandardAppBar.build(
context,
'Group Editor',
withHome: false,
actions: [
IconButton(
onPressed: () => deleteGroup(manager),
icon: const Icon(Icons.delete),
),
],
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: RefreshIndicator(
onRefresh: () async {
manager.refreshGroups();
},
child: ResponsiveMaxWidth(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextFormField(
enabled: allowNameEditing,
readOnly: !allowNameEditing,
onEditingComplete: () async {
if (processingUpdate) {
return;
}
updateGroupName(context, manager);
},
onTapOutside: (_) async {
if (processingUpdate) {
return;
}
updateGroupName(context, manager);
},
controller: groupTextController,
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(
labelText: 'Group Name',
border: OutlineInputBorder(
borderSide: const BorderSide(),
borderRadius: BorderRadius.circular(5.0),
),
),
),
),
const HorizontalPadding(),
IconButton(
onPressed: () {
if (allowNameEditing) {
groupTextController.text = groupData.name;
}
setState(() {
allowNameEditing = !allowNameEditing;
});
},
icon: const Icon(Icons.edit),
),
],
),
),
Expanded(
child: ListView.separated(
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) {
return ListTile(
title: Text("User"),
);
},
separatorBuilder: (_, __) => const Divider(),
itemCount: 1,
),
),
],
),
),
),
));
}
}