diff --git a/lib/ui/dialogs/color_picker_dialog.dart b/lib/ui/dialogs/color_picker_dialog.dart new file mode 100644 index 0000000..4672b66 --- /dev/null +++ b/lib/ui/dialogs/color_picker_dialog.dart @@ -0,0 +1,54 @@ +import 'package:comunic/utils/intl_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart'; + +/// Color picker dialog +/// +/// @author Pierre Hubert + +Future showColorPickerDialog( + BuildContext context, Color initialColor) async => + await showDialog( + context: context, + builder: (c) => _ColorPickerDialog(initialColor: initialColor), + ); + +class _ColorPickerDialog extends StatefulWidget { + final Color initialColor; + + const _ColorPickerDialog({Key key, @required this.initialColor}) + : super(key: key); + + @override + __ColorPickerDialogState createState() => __ColorPickerDialogState(); +} + +class __ColorPickerDialogState extends State<_ColorPickerDialog> { + Color _newColor; + + @override + void initState() { + _newColor = widget.initialColor; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + content: MaterialPicker( + pickerColor: _newColor ?? Colors.blue.shade900, + onColorChanged: (c) => setState(() => _newColor = c), + ), + actions: [ + MaterialButton( + onPressed: () => Navigator.pop(context, widget.initialColor), + child: Text(tr("Cancel").toUpperCase()), + ), + MaterialButton( + onPressed: () => Navigator.pop(context, _newColor), + child: Text(tr("Ok").toUpperCase()), + ), + ], + ); + } +} diff --git a/lib/ui/screens/update_conversation_screen.dart b/lib/ui/screens/update_conversation_screen.dart index 885f23c..1e43ea3 100644 --- a/lib/ui/screens/update_conversation_screen.dart +++ b/lib/ui/screens/update_conversation_screen.dart @@ -1,9 +1,13 @@ import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/conversation.dart'; import 'package:comunic/models/user.dart'; +import 'package:comunic/ui/dialogs/color_picker_dialog.dart'; import 'package:comunic/ui/tiles/simple_user_tile.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:flutter/material.dart'; /// Create / Update conversation screen @@ -28,10 +32,24 @@ class UpdateConversationScreen extends StatefulWidget { class _UpdateConversationScreen extends State { TextEditingController _nameController = TextEditingController(); + TextEditingController _colorController = TextEditingController(); UsersList _members = UsersList(); 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.initialSettings != null; get isAdmin => !isUpdating || widget.initialSettings.isAdmin; @@ -64,12 +82,27 @@ class _UpdateConversationScreen extends State { TextField( controller: _nameController, decoration: InputDecoration( - labelText: tr("Conversation name (optionnal)"), + 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: [ @@ -149,6 +182,12 @@ class _UpdateConversationScreen extends State { ); } + 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; diff --git a/lib/utils/color_utils.dart b/lib/utils/color_utils.dart new file mode 100644 index 0000000..05988fe --- /dev/null +++ b/lib/utils/color_utils.dart @@ -0,0 +1,13 @@ +import 'dart:ui'; + +/// Color utilities +/// +/// @author Pierre Hubert + +String colorToHex(Color color) { + if (color == null) return ""; + + return color.red.toRadixString(16).padLeft(2, '0') + + color.green.toRadixString(16).padLeft(2, '0') + + color.blue.toRadixString(16).padLeft(2, '0'); +} diff --git a/pubspec.lock b/pubspec.lock index eaa93bc..7886f57 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -237,6 +237,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + flutter_colorpicker: + dependency: "direct main" + description: + name: flutter_colorpicker + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.5" flutter_emoji: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 73afd3e..ddde390 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -121,6 +121,9 @@ dependencies: # Emojies picker emoji_picker: ^0.1.0 + # Color picker + flutter_colorpicker: ^0.3.5 + dev_dependencies: flutter_test: sdk: flutter