Enhance SubspaceNameDisplayWidget to handle duplicate names during editing. Introduced logic to check for existing subspace names and provide user feedback. Refactored state management for editing and submission processes, improving overall user experience and code clarity.

This commit is contained in:
Faris Armoush
2025-07-03 12:04:03 +03:00
parent c221c8499f
commit d47dc349bc

View File

@ -18,7 +18,9 @@ class SubspaceNameDisplayWidget extends StatefulWidget {
class _SubspaceNameDisplayWidgetState extends State<SubspaceNameDisplayWidget> { class _SubspaceNameDisplayWidgetState extends State<SubspaceNameDisplayWidget> {
late final TextEditingController _controller; late final TextEditingController _controller;
late final FocusNode _focusNode; late final FocusNode _focusNode;
bool isEditing = false; bool _isEditing = false;
bool _hasDuplicateName = false;
@override @override
void initState() { void initState() {
_controller = TextEditingController(text: widget.subSpace.name); _controller = TextEditingController(text: widget.subSpace.name);
@ -33,6 +35,41 @@ class _SubspaceNameDisplayWidgetState extends State<SubspaceNameDisplayWidget> {
super.dispose(); super.dispose();
} }
bool _checkForDuplicateName(String name) {
final bloc = context.read<SpaceDetailsModelBloc>();
return bloc.state.subspaces
.where((s) => s.uuid != widget.subSpace.uuid)
.any((s) => s.name.toLowerCase() == name.toLowerCase());
}
void _handleNameChange(String value) {
setState(() {
_hasDuplicateName = _checkForDuplicateName(value);
});
}
void _tryToFinishEditing() {
if (!_hasDuplicateName) {
_onFinishEditing();
}
}
void _tryToSubmit(String value) {
if (_hasDuplicateName) return;
final bloc = context.read<SpaceDetailsModelBloc>();
bloc.add(
UpdateSpaceDetailsSubspaces(
bloc.state.subspaces
.map(
(e) => e.uuid == widget.subSpace.uuid ? e.copyWith(name: value) : e,
)
.toList(),
),
);
_onFinishEditing();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textStyle = context.textTheme.bodySmall?.copyWith( final textStyle = context.textTheme.bodySmall?.copyWith(
@ -40,7 +77,7 @@ class _SubspaceNameDisplayWidgetState extends State<SubspaceNameDisplayWidget> {
); );
return InkWell( return InkWell(
onTap: () { onTap: () {
setState(() => isEditing = true); setState(() => _isEditing = true);
_focusNode.requestFocus(); _focusNode.requestFocus();
}, },
child: Chip( child: Chip(
@ -49,36 +86,48 @@ class _SubspaceNameDisplayWidgetState extends State<SubspaceNameDisplayWidget> {
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
label: Visibility( label: Visibility(
visible: isEditing, visible: _isEditing,
replacement: Text( replacement: Text(
widget.subSpace.name, widget.subSpace.name,
style: textStyle, style: textStyle,
), ),
child: SizedBox( child: Column(
width: context.screenWidth * 0.065, mainAxisSize: MainAxisSize.min,
height: context.screenHeight * 0.025, crossAxisAlignment: CrossAxisAlignment.start,
child: TextField( children: [
focusNode: _focusNode, SizedBox(
controller: _controller, width: context.screenWidth * 0.065,
style: textStyle, height: context.screenHeight * 0.025,
decoration: const InputDecoration.collapsed(hintText: ''), child: TextField(
onTapOutside: (_) => _onFinishEditing(), focusNode: _focusNode,
onSubmitted: (value) { controller: _controller,
final bloc = context.read<SpaceDetailsModelBloc>(); style: textStyle?.copyWith(
bloc.add( color: _hasDuplicateName ? Colors.red : null,
UpdateSpaceDetailsSubspaces(
bloc.state.subspaces
.map(
(e) => e.uuid == widget.subSpace.uuid
? e.copyWith(name: value)
: e,
)
.toList(),
), ),
); decoration: const InputDecoration.collapsed(
_onFinishEditing(); hintText: '',
}, ),
), onChanged: _handleNameChange,
onTapOutside: (_) => _tryToFinishEditing(),
onSubmitted: _tryToSubmit,
),
),
if (_hasDuplicateName)
AnimatedSwitcher(
duration: const Duration(milliseconds: 250),
child: Visibility(
key: ValueKey(_hasDuplicateName),
visible: _hasDuplicateName,
child: Text(
'Name already exists',
style: textStyle?.copyWith(
color: Colors.red,
fontSize: 8,
),
),
),
),
],
), ),
), ),
), ),
@ -86,7 +135,10 @@ class _SubspaceNameDisplayWidgetState extends State<SubspaceNameDisplayWidget> {
} }
void _onFinishEditing() { void _onFinishEditing() {
setState(() => isEditing = false); setState(() {
_isEditing = false;
_hasDuplicateName = false;
});
_focusNode.unfocus(); _focusNode.unfocus();
} }
} }