Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ class _PreparationSection extends StatelessWidget {
Expanded(
child: PreparationFormCreateList(
preparationNameState: preparationNameState,
enableDismissible: true,
onNameChanged: ({required int index, required String value}) {
context.read<PreparationFormBloc>().add(
PreparationFormPreparationStepNameChanged(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,39 @@ import 'package:on_time_front/presentation/onboarding/preparation_name_select/co
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart';
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_list_field.dart';
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_reorderable_list.dart';
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_reorderable_list_dissmissible.dart';
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart';

class PreparationFormCreateList extends StatelessWidget {
const PreparationFormCreateList(
{super.key,
required this.preparationNameState,
required this.onNameChanged,
required this.onCreationRequested,
this.enableDismissible = false});
required this.onCreationRequested});

final PreparationFormState preparationNameState;
final void Function({required int index, required String value})
onNameChanged;
final VoidCallback onCreationRequested;
final bool enableDismissible;

@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
enableDismissible
? PreparationFormReorderableListDismissible(
preparationStepList: preparationNameState.preparationStepList,
onNameChanged: (index, value) {
onNameChanged(index: index, value: value);
},
onTimeChanged: (index, value) => context
.read<PreparationFormBloc>()
.add(PreparationFormPreparationStepTimeChanged(
index: index, preparationStepTime: value)),
onReorder: (oldIndex, newIndex) => context
.read<PreparationFormBloc>()
.add(PreparationFormPreparationStepOrderChanged(
oldIndex: oldIndex, newIndex: newIndex)),
)
: PreparationFormReorderableList(
preparationStepList: preparationNameState.preparationStepList,
onNameChanged: (index, value) {
onNameChanged(index: index, value: value);
},
onTimeChanged: (index, value) => context
.read<PreparationFormBloc>()
.add(PreparationFormPreparationStepTimeChanged(
index: index, preparationStepTime: value)),
onReorder: (oldIndex, newIndex) => context
.read<PreparationFormBloc>()
.add(PreparationFormPreparationStepOrderChanged(
oldIndex: oldIndex, newIndex: newIndex)),
),
PreparationFormReorderableList(
preparationStepList: preparationNameState.preparationStepList,
onNameChanged: (index, value) {
onNameChanged(index: index, value: value);
},
onTimeChanged: (index, value) => context
.read<PreparationFormBloc>()
.add(PreparationFormPreparationStepTimeChanged(
index: index, preparationStepTime: value)),
onReorder: (oldIndex, newIndex) => context
.read<PreparationFormBloc>()
.add(PreparationFormPreparationStepOrderChanged(
oldIndex: oldIndex, newIndex: newIndex)),
),
preparationNameState.status == PreparationFormStatus.adding
? BlocProvider<PreparationStepFormCubit>(
create: (context) => PreparationStepFormCubit(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_swipe_action_cell/core/cell.dart';
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart';
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_list_field.dart';
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart';

class _SwipeActionContent extends StatelessWidget {
const _SwipeActionContent({
required this.icon,
required this.color,
});

final Widget icon;
final Color color;

@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: color,
),
padding: const EdgeInsets.all(18.0),
child: icon,
);
}
}

class PreparationFormReorderableList extends StatelessWidget {
const PreparationFormReorderableList({
super.key,
Expand Down Expand Up @@ -40,16 +65,44 @@ class PreparationFormReorderableList extends StatelessWidget {
physics: NeverScrollableScrollPhysics(),
itemCount: preparationStepList.length,
itemBuilder: (context, index) {
return PreparationFormListField(
key: ValueKey<String>(preparationStepList[index].id),
index: index,
preparationStep: preparationStepList[index],
onNameChanged: (value) {
onNameChanged(index, value);
},
onPreparationTimeChanged: (value) {
onTimeChanged(index, value);
},
final step = preparationStepList[index];
final theme = Theme.of(context);

return SwipeActionCell(
key: ValueKey<String>(step.id),
backgroundColor: Colors.transparent,
trailingActions: [
SwipeAction(
onTap: (controller) {
if (preparationStepList.length <= 1) return;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swipe action cell stays open when delete is prevented

When preparationStepList.length <= 1, the onTap handler returns early without using the controller to close the SwipeActionCell. This leaves the swipe action in its open state (red delete button visible) after the user taps it, but the deletion is prevented. The original Dismissible implementation properly handled this case by returning false from confirmDismiss, which would animate the item back to closed. The controller parameter should be used to close the cell when the delete action is not performed.

Fix in Cursor Fix in Web

context.read<PreparationFormBloc>().add(
PreparationFormPreparationStepRemoved(
preparationStepId: step.id,
),
);
},
color: Colors.transparent,
content: _SwipeActionContent(
icon: const Icon(
Icons.delete,
color: Colors.white,
size: 24,
),
color: theme.colorScheme.error,
),
),
],
child: PreparationFormListField(
key: ValueKey<String>('field_${step.id}'),
index: index,
preparationStep: step,
onNameChanged: (value) {
onNameChanged(index, value);
},
onPreparationTimeChanged: (value) {
onTimeChanged(index, value);
},
),
);
},
onReorder: (int oldIndex, int newIndex) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ class _ScheduleSpareAndPreparingTimeFormState
Padding(
padding: const EdgeInsets.only(top: 8.0, left: 16.0),
child: MessageBubble(
message: state.getOverlapMessage(context)!,
message: state.getOverlapMessage(context)!,
type: state.isOverlapError
? MessageBubbleType.error
: MessageBubbleType.warning,
),
),
),
],
);
Expand Down
3 changes: 2 additions & 1 deletion lib/presentation/shared/router/go_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ GoRouter goRouterConfig(AuthBloc authBloc, ScheduleBloc scheduleBloc) {
GoRoute(
path: '/preparationEdit',
builder: (context, state) => PreparationEditForm(
preparationEntity: state.extra as PreparationEntity)),
preparationEntity: (state.extra as PreparationEntity?) ??
const PreparationEntity(preparationStepList: []))),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silent fallback masks missing navigation data errors

The change from state.extra as PreparationEntity to (state.extra as PreparationEntity?) ?? const PreparationEntity(preparationStepList: []) silently provides an empty entity when navigation occurs without proper data. The calling code in ScheduleSpareAndPreparingTimeForm passes state.preparation which can be null. Previously this would crash (making the bug obvious); now users may see an unexpectedly empty form. This change doesn't appear related to the PR's stated purpose of removing the non-dismissible option, and could mask navigation bugs.

Fix in Cursor Fix in Web

GoRoute(
path: '/scheduleStart',
name: 'scheduleStart',
Expand Down