@@ -7,12 +7,12 @@ import 'package:flowy_infra/theme.dart';
77import 'package:flowy_infra_ui/flowy_infra_ui.dart' ;
88import 'package:flowy_infra_ui/style_widget/button.dart' ;
99import 'package:flowy_infra_ui/style_widget/text.dart' ;
10+ import 'package:flowy_infra_ui/widget/rounded_input_field.dart' ;
1011import 'package:flowy_infra_ui/widget/spacing.dart' ;
1112import 'package:flowy_sdk/log.dart' ;
1213import 'package:flutter/material.dart' ;
1314import 'package:flutter_bloc/flutter_bloc.dart' ;
1415import 'package:app_flowy/generated/locale_keys.g.dart' ;
15- import 'field_name_input.dart' ;
1616import 'field_type_option_editor.dart' ;
1717
1818class FieldEditor extends StatefulWidget {
@@ -44,6 +44,12 @@ class _FieldEditorState extends State<FieldEditor> {
4444 super .initState ();
4545 }
4646
47+ @override
48+ void dispose () {
49+ popoverMutex.dispose ();
50+ super .dispose ();
51+ }
52+
4753 @override
4854 Widget build (BuildContext context) {
4955 return BlocProvider (
@@ -58,28 +64,38 @@ class _FieldEditorState extends State<FieldEditor> {
5864 return ListView (
5965 shrinkWrap: true ,
6066 children: [
61- FlowyText .medium (LocaleKeys .grid_field_editProperty.tr (),
62- fontSize: 12 ),
63- const VSpace (10 ),
64- const _FieldNameCell (),
65- const VSpace (10 ),
66- _DeleteFieldButton (
67- popoverMutex: popoverMutex,
68- onDeleted: () {
69- state.field.fold (
70- () => Log .error ('Can not delete the field' ),
71- (field) => widget.onDeleted? .call (field.id),
72- );
73- },
67+ FlowyText .medium (
68+ LocaleKeys .grid_field_editProperty.tr (),
69+ fontSize: 12 ,
7470 ),
7571 const VSpace (10 ),
72+ _FieldNameTextField (popoverMutex: popoverMutex),
73+ ..._addDeleteFieldButton (state),
7674 _FieldTypeOptionCell (popoverMutex: popoverMutex),
7775 ],
7876 );
7977 },
8078 ),
8179 );
8280 }
81+
82+ List <Widget > _addDeleteFieldButton (FieldEditorState state) {
83+ if (widget.onDeleted == null ) {
84+ return [];
85+ }
86+ return [
87+ const VSpace (10 ),
88+ _DeleteFieldButton (
89+ popoverMutex: popoverMutex,
90+ onDeleted: () {
91+ state.field.fold (
92+ () => Log .error ('Can not delete the field' ),
93+ (field) => widget.onDeleted? .call (field.id),
94+ );
95+ },
96+ ),
97+ ];
98+ }
8399}
84100
85101class _FieldTypeOptionCell extends StatelessWidget {
@@ -111,25 +127,89 @@ class _FieldTypeOptionCell extends StatelessWidget {
111127 }
112128}
113129
114- class _FieldNameCell extends StatelessWidget {
115- const _FieldNameCell ({Key ? key}) : super (key: key);
130+ class _FieldNameTextField extends StatefulWidget {
131+ final PopoverMutex popoverMutex;
132+ const _FieldNameTextField ({
133+ required this .popoverMutex,
134+ Key ? key,
135+ }) : super (key: key);
136+
137+ @override
138+ State <_FieldNameTextField > createState () => _FieldNameTextFieldState ();
139+ }
140+
141+ class _FieldNameTextFieldState extends State <_FieldNameTextField > {
142+ late String name;
143+ FocusNode focusNode = FocusNode ();
144+ VoidCallback ? _popoverCallback;
145+ TextEditingController controller = TextEditingController ();
146+
147+ @override
148+ void initState () {
149+ focusNode.addListener (() {
150+ if (focusNode.hasFocus) {
151+ widget.popoverMutex.close ();
152+ }
153+ });
154+
155+ super .initState ();
156+ }
116157
117158 @override
118159 Widget build (BuildContext context) {
119- return BlocBuilder <FieldEditorBloc , FieldEditorState >(
120- builder: (context, state) {
121- return FieldNameTextField (
122- name: state.name,
123- errorText: context.read <FieldEditorBloc >().state.errorText,
124- onNameChanged: (newName) {
125- context
126- .read <FieldEditorBloc >()
127- .add (FieldEditorEvent .updateName (newName));
128- },
129- );
160+ final theme = context.watch <AppTheme >();
161+
162+ controller.text = context.read <FieldEditorBloc >().state.name;
163+ return BlocListener <FieldEditorBloc , FieldEditorState >(
164+ listenWhen: (previous, current) => previous.name != current.name,
165+ listener: (context, state) {
166+ controller.text = state.name;
130167 },
168+ child: BlocBuilder <FieldEditorBloc , FieldEditorState >(
169+ builder: (context, state) {
170+ listenOnPopoverChhanged (context);
171+
172+ return RoundedInputField (
173+ height: 36 ,
174+ autoFocus: true ,
175+ focusNode: focusNode,
176+ style: const TextStyle (fontSize: 13 , fontWeight: FontWeight .w500),
177+ controller: controller,
178+ normalBorderColor: theme.shader4,
179+ errorBorderColor: theme.red,
180+ focusBorderColor: theme.main1,
181+ cursorColor: theme.main1,
182+ errorText: context.read <FieldEditorBloc >().state.errorText,
183+ onChanged: (newName) {
184+ context
185+ .read <FieldEditorBloc >()
186+ .add (FieldEditorEvent .updateName (newName));
187+ },
188+ );
189+ },
190+ ),
131191 );
132192 }
193+
194+ void listenOnPopoverChhanged (BuildContext context) {
195+ if (_popoverCallback != null ) {
196+ widget.popoverMutex.removePopoverStateListener (_popoverCallback! );
197+ }
198+ _popoverCallback = widget.popoverMutex.listenOnPopoverStateChanged (() {
199+ if (focusNode.hasFocus) {
200+ final node = FocusScope .of (context);
201+ node.unfocus ();
202+ }
203+ });
204+ }
205+
206+ @override
207+ void didUpdateWidget (covariant _FieldNameTextField oldWidget) {
208+ controller.selection = TextSelection .fromPosition (
209+ TextPosition (offset: controller.text.length));
210+
211+ super .didUpdateWidget (oldWidget);
212+ }
133213}
134214
135215class _DeleteFieldButton extends StatelessWidget {
@@ -171,12 +251,10 @@ class _DeleteFieldButton extends StatelessWidget {
171251 popupBuilder: (popupContext) {
172252 return PopoverAlertView (
173253 title: LocaleKeys .grid_field_deleteFieldPromptMessage.tr (),
174- cancel: () => popoverMutex.state ? . close () ,
254+ cancel: () {} ,
175255 confirm: () {
176256 onDeleted? .call ();
177- popoverMutex.state? .close ();
178257 },
179- popoverMutex: popoverMutex,
180258 );
181259 },
182260 child: widget,
0 commit comments