1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-10-23 15:03:22 +00:00
comunicmobile/lib/ui/screens/update_conversation_screen.dart

281 lines
9.3 KiB
Dart

import 'package:comunic/helpers/conversations_helper.dart';
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/conversation.dart';
import 'package:comunic/models/new_conversation.dart';
import 'package:comunic/models/user.dart';
import 'package:comunic/ui/dialogs/color_picker_dialog.dart';
import 'package:comunic/ui/routes/main_route/main_route.dart';
import 'package:comunic/ui/tiles/simple_user_tile.dart';
import 'package:comunic/ui/widgets/async_screen_widget.dart';
import 'package:comunic/ui/widgets/comunic_back_button_widget.dart';
import 'package:comunic/ui/widgets/pick_user_widget.dart';
import 'package:comunic/utils/color_utils.dart';
import 'package:comunic/utils/dart_color.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/log_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
/// Create / Update conversation screen
///
/// @author Pierre HUBERT
enum _MembersMenuChoices { REMOVE }
class UpdateConversationScreen extends StatefulWidget {
final convID;
const UpdateConversationScreen({
Key key,
this.convID,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _UpdateConversationScreen();
}
class _UpdateConversationScreen extends State<UpdateConversationScreen> {
Conversation _conversation;
TextEditingController _nameController = TextEditingController();
TextEditingController _colorController = TextEditingController();
UsersList _members = UsersList();
Set<int> _admins = Set();
bool _followConversation = true;
bool _canEveryoneAddMembers = true;
String get _conversationColor => _colorController.text;
Color get _color {
if (_conversationColor == null || _conversationColor.isEmpty) return null;
try {
return HexColor(_conversationColor);
} catch (e, s) {
logError(e, s);
return null;
}
}
get isUpdating => widget.convID != null;
get isAdmin => !isUpdating || _conversation.isAdmin;
bool get _canAddMembers => isAdmin || _conversation.canEveryoneAddMembers;
get _isValid => _members.length > 0;
Future<void> _init() async {
if (!isUpdating) return;
_conversation =
await ConversationsHelper().getSingle(widget.convID, force: true);
_nameController.text = _conversation.name ?? "";
_colorController.text =
_conversationColor == null ? "" : "#${_conversation.color}";
_members = await UsersHelper().getList(_conversation.membersID);
_admins = _conversation.adminsID;
_followConversation = _conversation.following;
_canEveryoneAddMembers = _conversation.canEveryoneAddMembers;
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
leading: ComunicBackButton(),
title: Text(isUpdating
? tr("Update conversation")
: tr("Create a conversation")),
actions: [
IconButton(
icon: Icon(Icons.check),
onPressed: _isValid ? _submitForm : null)
],
),
body: AsyncScreenWidget(
onReload: _init,
onBuild: _buildBody,
errorMessage: tr("Failed to load conversation settings!"),
),
);
Widget _buildBody() {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
// Conversation name
TextField(
controller: _nameController,
decoration: InputDecoration(
labelText: tr("Conversation name (optional)"),
alignLabelWithHint: true,
enabled: isAdmin,
),
),
// Conversation color
TextField(
controller: _colorController,
onChanged: (s) => setState(() {}),
decoration: InputDecoration(
labelText: tr("Conversation color (optional)"),
alignLabelWithHint: true,
enabled: isAdmin,
suffixIcon: IconButton(
icon: Icon(Icons.colorize),
color: _color,
onPressed: isAdmin ? _pickColor : null,
)),
),
// Follow conversation ?
Row(
children: <Widget>[
Switch.adaptive(
value: _followConversation,
onChanged: (b) => setState(() {
_followConversation = b;
}),
),
Text(tr("Follow conversation"))
],
),
// Allow every members of the conversation to add users ?
Row(
children: <Widget>[
Switch.adaptive(
value: _canEveryoneAddMembers,
onChanged: isAdmin
? (b) => setState(() {
_canEveryoneAddMembers = b;
})
: null,
),
Text(tr("Allow all members of the conversation to add users"))
],
),
// Add a member to the conversation
PickUserWidget(
resetOnChoose: true,
keepFocusOnChoose: true,
label: tr("Add member"),
enabled: _canAddMembers,
onSelectUser: (user) => setState(() {
if (!_members.contains(user)) _members.insert(0, user);
}),
),
//Conversation members
Column(
children: _members
.map((f) => SimpleUserTile(
user: f,
trailing: _canAddMembers
? PopupMenuButton<_MembersMenuChoices>(
captureInheritedThemes: false,
onSelected: (choice) =>
_membersMenuItemSelected(f, choice),
itemBuilder: (c) =>
<PopupMenuEntry<_MembersMenuChoices>>[
PopupMenuItem(
child: Text(tr("Remove")),
value: _MembersMenuChoices.REMOVE,
enabled: isAdmin ||
(_canEveryoneAddMembers &&
!_conversation.membersID
.contains(f.id)),
)
],
)
: null,
))
.toList(),
),
],
),
),
);
}
void _pickColor() async {
final color = await showColorPickerDialog(context, _color);
setState(() =>
_colorController.text = color == null ? "" : "#${colorToHex(color)}");
}
/// An option of the members menu has been selected
void _membersMenuItemSelected(User user, _MembersMenuChoices choice) {
if (choice == null) return;
if (choice == _MembersMenuChoices.REMOVE)
setState(() {
_members.removeWhere((u) => u.id == user.id);
});
}
/// Submit the conversation
Future<void> _submitForm() async {
try {
// Create the conversation
if (!isUpdating) {
final conversationID = await ConversationsHelper.createConversation(
NewConversation(
name: _nameController.text,
members: _members.map((element) => element.id).toList(),
follow: _followConversation,
canEveryoneAddMembers: _canEveryoneAddMembers,
color: _color));
MainController.of(context).popPage();
MainController.of(context).openConversation(conversationID);
}
// TODO : reimplement
/* final settings = Conversation(
id: isUpdating ? widget.initialSettings.id : 0,
ownerID: isUpdating ? widget.initialSettings.ownerID : 0,
name: _nameController.text,
following: _followConversation,
members: _members.usersID,
canEveryoneAddMembers: _canEveryoneAddMembers,
// Give random value to these fields as they are ignored here
lastActive: 0,
sawLastMessage: true);
// Create the conversation
var conversationID = settings.id;
bool error = false;
if (isUpdating)
error = !(await ConversationsHelper().updateConversation(settings));
else {
conversationID = await ConversationsHelper().createConversation(settings);
if (conversationID < 1) error = true;
}
// Check for errors
if (error)
return Scaffold.of(context).showSnackBar(SnackBar(
content: Text(isUpdating
? tr("Could not update the conversation!")
: tr("Could not create the conversation!")),
duration: Duration(seconds: 1),
));
// Open the conversation
MainController.of(context).popPage();
if (!isUpdating)
MainController.of(context).openConversation(conversationID);*/
} catch (e, s) {
logError(e, s);
snack(context, tr("Failed to update conversation settings!"));
}
}
}