TF-4178 Add color picker modal

This commit is contained in:
dab246
2025-11-26 16:07:07 +07:00
committed by Dat H. Pham
parent d3029ec4de
commit 8f1da20e54
19 changed files with 497 additions and 31 deletions
+8
View File
@@ -389,6 +389,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.2"
flutter_hsvcolor_picker:
dependency: transitive
description:
name: flutter_hsvcolor_picker
sha256: f3480d7beaf4d3a3b76512a0c149a3b698076c8cf721bc515cded30de37ded6a
url: "https://pub.dev"
source: hosted
version: "1.5.1"
flutter_image_compress:
dependency: transitive
description:
+3
View File
@@ -78,6 +78,7 @@ export 'presentation/views/responsive/responsive_widget.dart';
export 'presentation/views/list/tree_view.dart';
export 'presentation/views/button/icon_button_web.dart';
export 'presentation/views/button/tmail_button_widget.dart';
export 'presentation/views/button/default_close_button_widget.dart';
export 'presentation/views/image/avatar_builder.dart';
export 'presentation/views/list/sliver_grid_delegate_fixed_height.dart';
export 'presentation/views/list/no_stretch_scroll_behavior.dart';
@@ -90,6 +91,7 @@ export 'presentation/views/dialog/downloading_file_dialog_builder.dart';
export 'presentation/views/dialog/confirmation_dialog_builder.dart';
export 'presentation/views/dialog/edit_text_dialog_builder.dart';
export 'presentation/views/dialog/color_picker_dialog_builder.dart';
export 'presentation/views/dialog/modal_list_action_button_widget.dart';
export 'presentation/views/html_viewer/html_content_viewer_widget.dart';
export 'presentation/views/html_viewer/html_content_viewer_on_web_widget.dart';
export 'presentation/views/floating_button/scrolling_floating_button_animated.dart';
@@ -119,6 +121,7 @@ export 'presentation/views/shortcut/key_shortcut.dart';
export 'presentation/views/tooltip/iframe_tooltip_overlay.dart';
export 'presentation/views/color/color_circle_widget.dart';
export 'presentation/views/color/colors_map_widget.dart';
export 'presentation/views/color/color_picker_modal.dart';
// Resources
export 'presentation/resources/assets_paths.dart';
@@ -0,0 +1,333 @@
import 'dart:math' as math;
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/default_close_button_widget.dart';
import 'package:core/presentation/views/dialog/modal_list_action_button_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flex_color_picker/flex_color_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hsvcolor_picker/flutter_hsvcolor_picker.dart';
import 'package:get/get.dart';
typedef OnSelectColorCallback = void Function(Color? color);
class ColorPickerModal extends StatefulWidget {
final ImagePaths imagePaths;
final String modalTitle;
final String modalSubtitle;
final String negativeButtonText;
final String positiveButtonText;
final String hexColorText;
final Color? initialColor;
final OnSelectColorCallback onSelectColorCallback;
final VoidCallback? onNegativeAction;
const ColorPickerModal({
super.key,
required this.imagePaths,
required this.modalTitle,
required this.modalSubtitle,
required this.onSelectColorCallback,
this.negativeButtonText = 'Cancel',
this.positiveButtonText = 'Save',
this.hexColorText = 'Hex',
this.initialColor,
this.onNegativeAction,
});
@override
State<ColorPickerModal> createState() => _ColorPickerModalState();
}
class _ColorPickerModalState extends State<ColorPickerModal> {
static const Color _defaultColor = Colors.blue;
final TextEditingController _hexColorInputController =
TextEditingController();
final FocusNode _hexColorFocusNode = FocusNode();
final ValueNotifier<HSVColor> _hsvColorNotifier =
ValueNotifier(HSVColor.fromColor(_defaultColor));
@override
void initState() {
final currentColor = widget.initialColor ?? _defaultColor;
_hsvColorNotifier.value = HSVColor.fromColor(currentColor);
_hexColorInputController.text = currentColor.toHexTriplet();
super.initState();
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return LayoutBuilder(builder: (_, constraints) {
final currentScreenWidth = constraints.maxWidth;
final currentScreenHeight = constraints.maxHeight;
final isMobile = currentScreenWidth < ResponsiveUtils.minTabletWidth;
Widget bodyWidget = Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(16)),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.08),
blurRadius: 24,
offset: const Offset(0, 2),
),
BoxShadow(
color: Colors.black.withValues(alpha: 0.08),
blurRadius: 2,
),
],
),
width: math.min(
currentScreenWidth - 32,
554,
),
constraints: BoxConstraints(maxHeight: currentScreenHeight - 100),
clipBehavior: Clip.antiAlias,
child: Stack(
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 64,
alignment: Alignment.center,
padding: EdgeInsetsDirectional.only(
start: 32,
end: 32,
top: 16,
bottom: isMobile ? 0 : 16,
),
child: Text(
widget.modalTitle,
style: theme.textTheme.headlineSmall?.copyWith(
color: AppColor.m3SurfaceBackground,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Center(
child: Padding(
padding: const EdgeInsetsDirectional.only(
start: 32,
end: 32,
bottom: 24,
),
child: Text(
widget.modalSubtitle,
style: ThemeUtils.textStyleInter400.copyWith(
color: AppColor.steelGrayA540,
fontSize: 13,
height: 20 / 13,
),
textAlign: TextAlign.center,
),
),
),
Flexible(
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Padding(
padding: EdgeInsetsDirectional.only(
start: 32,
end: 32,
bottom: isMobile ? 0 : 16,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
padding: const EdgeInsetsDirectional.only(
bottom: 24,
),
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 12,
),
child: ValueListenableBuilder(
valueListenable: _hsvColorNotifier,
builder: (_, value, __) {
return PaletteHuePicker(
color: value,
onChanged: _onHsvColorChanged,
hueHeight: 32,
paletteHeight: 200,
palettePadding: const EdgeInsets.only(
bottom: 16,
),
paletteBorderRadius: const BorderRadius.all(
Radius.circular(8),
),
hueBorderRadius: const BorderRadius.all(
Radius.circular(8),
),
);
},
),
),
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
widget.hexColorText,
style: ThemeUtils.textStyleInter400.copyWith(
color: AppColor.steelGrayA540,
fontSize: 13,
height: 20 / 13,
letterSpacing: 0.0,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Container(
width: 107,
padding: const EdgeInsetsDirectional.only(
start: 12,
top: 6,
),
child: TextField(
controller: _hexColorInputController,
focusNode: _hexColorFocusNode,
style: theme.textTheme.bodySmall?.copyWith(
color: Colors.black,
),
cursorColor: AppColor.primaryColor,
decoration: InputDecoration(
border: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black.withValues(
alpha: 0.12,
),
width: 1,
),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black.withValues(
alpha: 0.12,
),
width: 1,
),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black.withValues(
alpha: 0.12,
),
width: 1,
),
),
isDense: true,
contentPadding: const EdgeInsets.only(
bottom: 2,
),
),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[0-9A-Fa-f#]'),
),
],
onChanged: _onHexColorChanged,
),
)
],
),
ModalListActionButtonWidget(
positiveLabel: widget.positiveButtonText,
negativeLabel: widget.negativeButtonText,
padding: const EdgeInsets.symmetric(vertical: 25),
onPositiveAction: _onPositiveAction,
onNegativeAction: _onNegativeAction,
),
],
),
),
),
),
],
),
DefaultCloseButtonWidget(
iconClose: widget.imagePaths.icCloseDialog,
onTapActionCallback: _onCloseModal,
),
],
),
);
bodyWidget = Center(child: bodyWidget);
if (PlatformInfo.isMobile) {
bodyWidget = GestureDetector(
onTap: _onCloseModal,
child: Scaffold(
backgroundColor: AppColor.blackAlpha20,
body: GestureDetector(
onTap: _clearInputFocus,
child: bodyWidget,
),
),
);
}
return bodyWidget;
});
}
void _onCloseModal() {
_clearInputFocus();
Get.back();
}
void _onNegativeAction() {
_clearInputFocus();
widget.onNegativeAction?.call();
Get.back();
}
void _onPositiveAction() {
_clearInputFocus();
final hexColorText = _hexColorInputController.text.trimmed;
if (hexColorText.isNotEmpty) {
widget.onSelectColorCallback(hexColorText.toColor);
}
Get.back();
}
void _clearInputFocus() {
_hexColorFocusNode.unfocus();
}
void _onHsvColorChanged(HSVColor hsvColor) {
_hsvColorNotifier.value = hsvColor;
_hexColorInputController.text = hsvColor.toColor().toHexTriplet();
}
void _onHexColorChanged(String value) {
_hsvColorNotifier.value = HSVColor.fromColor(value.toColor);
}
@override
void dispose() {
_hexColorFocusNode.dispose();
_hexColorInputController.dispose();
_hsvColorNotifier.dispose();
super.dispose();
}
}
@@ -2,15 +2,21 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/presentation/views/color/color_circle_widget.dart';
import 'package:core/presentation/views/color/color_picker_modal.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ColorsMapWidget extends StatefulWidget {
final Color? initialColor;
final ImagePaths imagePaths;
final Color? customColor;
final VoidCallback? onOpenColorPicker;
final OnSelectColorCallback? onSelectColorCallback;
const ColorsMapWidget({
super.key,
this.initialColor,
required this.imagePaths,
this.customColor,
this.onOpenColorPicker,
this.onSelectColorCallback,
});
@override
@@ -41,14 +47,21 @@ class _ColorsMapWidgetState extends State<ColorsMapWidget> {
Color(0xFF646580),
];
final _imagePaths = Get.find<ImagePaths>();
final ValueNotifier<Color?> _selectedColor = ValueNotifier(null);
List<Color> _colorList = <Color>[];
@override
void initState() {
super.initState();
_selectedColor.value = widget.initialColor;
_setUpColorList();
}
@override
void didUpdateWidget(covariant ColorsMapWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.customColor != widget.customColor) {
_setUpColorList();
}
}
@override
@@ -58,7 +71,7 @@ class _ColorsMapWidgetState extends State<ColorsMapWidget> {
runSpacing: 10,
children: [
TMailButtonWidget.fromIcon(
icon: _imagePaths.icCloseDialog,
icon: widget.imagePaths.icCloseDialog,
iconColor: AppColor.m3SurfaceBackground.withValues(alpha: 0.48),
iconSize: 18.46,
width: 40,
@@ -68,7 +81,7 @@ class _ColorsMapWidgetState extends State<ColorsMapWidget> {
border: Border.all(width: 2, color: AppColor.grayCDCDCD),
onTapActionCallback: _clearColor,
),
..._defaultColors
..._colorList
.map(
(color) => ValueListenableBuilder(
valueListenable: _selectedColor,
@@ -77,7 +90,7 @@ class _ColorsMapWidgetState extends State<ColorsMapWidget> {
color: color,
isSelected: color == value,
onTap: () => _selectColor(color),
imagePaths: _imagePaths,
imagePaths: widget.imagePaths,
);
},
),
@@ -99,30 +112,36 @@ class _ColorsMapWidgetState extends State<ColorsMapWidget> {
),
),
child: TMailButtonWidget.fromIcon(
icon: _imagePaths.icColorPicker,
icon: widget.imagePaths.icColorPicker,
iconColor: AppColor.textSecondary,
iconSize: 18.46,
width: 40,
height: 40,
width: 38,
height: 38,
borderRadius: 100,
backgroundColor: Colors.white,
onTapActionCallback: _openColorPicker,
onTapActionCallback: widget.onOpenColorPicker,
),
),
],
);
}
void _setUpColorList() {
final custom = widget.customColor;
_colorList = custom != null ? [custom, ..._defaultColors] : _defaultColors;
_selectedColor.value = custom;
}
void _selectColor(Color color) {
_selectedColor.value = color;
widget.onSelectColorCallback?.call(color);
}
void _clearColor() {
_selectedColor.value = null;
widget.onSelectColorCallback?.call(null);
}
void _openColorPicker() {}
@override
void dispose() {
_selectedColor.dispose();
+8
View File
@@ -382,6 +382,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.2"
flutter_hsvcolor_picker:
dependency: "direct main"
description:
name: flutter_hsvcolor_picker
sha256: f3480d7beaf4d3a3b76512a0c149a3b698076c8cf721bc515cded30de37ded6a
url: "https://pub.dev"
source: hosted
version: "1.5.1"
flutter_image_compress:
dependency: "direct main"
description:
+2
View File
@@ -107,6 +107,8 @@ dependencies:
sentry_dio: 9.8.0
flutter_hsvcolor_picker: 1.5.1
dev_dependencies:
flutter_test:
sdk: flutter
+8
View File
@@ -381,6 +381,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
flutter_hsvcolor_picker:
dependency: transitive
description:
name: flutter_hsvcolor_picker
sha256: f3480d7beaf4d3a3b76512a0c149a3b698076c8cf721bc515cded30de37ded6a
url: "https://pub.dev"
source: hosted
version: "1.5.1"
flutter_image_compress:
dependency: transitive
description:
@@ -1,12 +1,12 @@
import 'dart:math';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/default_close_button_widget.dart';
import 'package:core/presentation/views/checkbox/custom_icon_labeled_checkbox.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/model/filter_filter.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_autocomplete_input_field_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_date_drop_down_field_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_input_field_with_tab_key_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_label_field_widget.dart';
@@ -1,12 +1,12 @@
import 'dart:math';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/button/default_close_button_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rich_text_composer/views/keyboard_rich_text.dart';
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/base/widget/pop_back_barrier_widget.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart';
@@ -4,15 +4,16 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/default_close_button_widget.dart';
import 'package:core/presentation/views/color/color_picker_modal.dart';
import 'package:core/presentation/views/color/colors_map_widget.dart';
import 'package:core/presentation/views/dialog/modal_list_action_button_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:labels/extensions/list_label_extension.dart';
import 'package:labels/model/label.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/base/widget/label_input_field_builder.dart';
import 'package:tmail_ui_user/features/base/widget/modal_list_action_button_widget.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/duplicate_name_validator.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/empty_name_validator.dart';
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/name_with_space_only_validator.dart';
@@ -37,11 +38,14 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
final _imagePaths = Get.find<ImagePaths>();
final _verifyNameInteractor = Get.find<VerifyNameInteractor>();
final ValueNotifier<String?> _labelNameErrorText = ValueNotifier(null);
final ValueNotifier<String?> _labelNameErrorTextNotifier =
ValueNotifier(null);
final ValueNotifier<Color?> _labelSelectedColorNotifier = ValueNotifier(null);
final TextEditingController _nameInputController = TextEditingController();
final FocusNode _nameInputFocusNode = FocusNode();
List<String> _labelDisplayNameList = <String>[];
Color? _selectedColor;
@override
void initState() {
@@ -107,10 +111,10 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
),
Center(
child: Padding(
padding: EdgeInsetsDirectional.only(
padding: const EdgeInsetsDirectional.only(
start: 32,
end: 32,
bottom: isMobile ? 32 : 48,
bottom: 24,
),
child: Text(
appLocalizations.organizeYourInboxWithACustomCategory,
@@ -137,7 +141,7 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ValueListenableBuilder(
valueListenable: _labelNameErrorText,
valueListenable: _labelNameErrorTextNotifier,
builder: (_, errorText, __) {
return LabelInputFieldBuilder(
label: appLocalizations.labelName,
@@ -185,7 +189,18 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
start: 32,
end: 16,
),
child: const ColorsMapWidget(),
child: ValueListenableBuilder(
valueListenable: _labelSelectedColorNotifier,
builder: (_, value, __) {
return ColorsMapWidget(
imagePaths: _imagePaths,
customColor: value,
onOpenColorPicker: () =>
_openColorPickerModal(appLocalizations),
onSelectColorCallback: _updateLabelColor,
);
},
),
),
),
ModalListActionButtonWidget(
@@ -230,8 +245,13 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
}
void _onLabelNameInputChanged(
AppLocalizations appLocalizations, String value) {
_labelNameErrorText.value = _verifyLabelName(appLocalizations, value);
AppLocalizations appLocalizations,
String value,
) {
_labelNameErrorTextNotifier.value = _verifyLabelName(
appLocalizations,
value,
);
}
String? _verifyLabelName(AppLocalizations appLocalizations, String value) {
@@ -269,11 +289,35 @@ class _CreateNewLabelModalState extends State<CreateNewLabelModal> {
popBack();
}
void _updateLabelColor(Color? color) {
_selectedColor = color;
}
void _onLabelColorChanged(Color? color) {
_updateLabelColor(color);
_labelSelectedColorNotifier.value = color;
}
Future<void> _openColorPickerModal(AppLocalizations appLocalizations) async {
await Get.generalDialog(
barrierDismissible: true,
barrierLabel: 'color-picker-modal',
pageBuilder: (_, __, ___) => ColorPickerModal(
imagePaths: _imagePaths,
modalTitle: appLocalizations.chooseCustomColour,
modalSubtitle: appLocalizations.chooseAColourForThisLabel,
initialColor: _selectedColor,
onSelectColorCallback: _onLabelColorChanged,
),
);
}
@override
void dispose() {
_nameInputFocusNode.dispose();
_nameInputController.dispose();
_labelNameErrorText.dispose();
_labelNameErrorTextNotifier.dispose();
_labelSelectedColorNotifier.dispose();
_labelDisplayNameList = [];
super.dispose();
}
@@ -3,13 +3,13 @@ import 'dart:math' as math;
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/default_close_button_widget.dart';
import 'package:core/presentation/views/dialog/modal_list_action_button_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_button_arrow_down_field_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/base/widget/label_input_field_builder.dart';
import 'package:tmail_ui_user/features/base/widget/modal_list_action_button_widget.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_icon_widget.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/mailbox_creator_controller.dart';
@@ -1,9 +1,9 @@
import 'package:core/presentation/views/button/default_close_button_widget.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/quotas/domain/extensions/quota_extensions.dart';
import 'package:tmail_ui_user/features/quotas/presentation/quotas_controller.dart';
import 'package:tmail_ui_user/features/quotas/presentation/styles/quotas_banner_styles.dart';
@@ -4,7 +4,6 @@ import 'package:core/core.dart';
import 'package:core/presentation/views/dialog/confirm_dialog_button.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/base/widget/label_input_field_builder.dart';
import 'package:tmail_ui_user/features/base/widget/pop_back_barrier_widget.dart';
import 'package:tmail_ui_user/features/rules_filter_creator/presentation/extensions/handle_toggle_preview_rule_filter_extension.dart';
+12
View File
@@ -5243,5 +5243,17 @@
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"chooseCustomColour": "Choose custom colour",
"@chooseCustomColour": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"chooseAColourForThisLabel": "Choose a colour for this label",
"@chooseAColourForThisLabel": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
}
}
@@ -5569,4 +5569,18 @@ class AppLocalizations {
name: 'tagNameAlreadyExists',
);
}
String get chooseCustomColour {
return Intl.message(
'Choose custom colour',
name: 'chooseCustomColour',
);
}
String get chooseAColourForThisLabel {
return Intl.message(
'Choose a colour for this label',
name: 'chooseAColourForThisLabel',
);
}
}
+8
View File
@@ -389,6 +389,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.2"
flutter_hsvcolor_picker:
dependency: transitive
description:
name: flutter_hsvcolor_picker
sha256: f3480d7beaf4d3a3b76512a0c149a3b698076c8cf721bc515cded30de37ded6a
url: "https://pub.dev"
source: hosted
version: "1.5.1"
flutter_image_compress:
dependency: transitive
description:
+8
View File
@@ -789,6 +789,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.2"
flutter_hsvcolor_picker:
dependency: transitive
description:
name: flutter_hsvcolor_picker
sha256: f3480d7beaf4d3a3b76512a0c149a3b698076c8cf721bc515cded30de37ded6a
url: "https://pub.dev"
source: hosted
version: "1.5.1"
flutter_image_compress:
dependency: "direct main"
description: