Finished custom sorting of deliveries

This commit is contained in:
Dennis Nemec
2026-01-07 15:19:34 +01:00
parent 9111dc92db
commit 622967e5c1
8 changed files with 369 additions and 41 deletions

View File

@ -1,4 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_state.dart';
import 'package:hl_lieferservice/feature/delivery/overview/model/sorting_information.dart';
import 'package:hl_lieferservice/model/delivery.dart';
import 'delivery_item.dart';
@ -6,11 +10,13 @@ import 'delivery_item.dart';
class DeliveryList extends StatefulWidget {
final List<Delivery> deliveries;
final Map<String, double> distances;
final List<SortingInformation> sortingInformation;
const DeliveryList({
super.key,
required this.deliveries,
required this.distances,
required this.sortingInformation,
});
@override
@ -26,16 +32,32 @@ class _DeliveryListState extends State<DeliveryList> {
);
}
return ListView.separated(
separatorBuilder: (context, index) => const Divider(height: 0),
itemBuilder: (context, index) {
Delivery delivery = widget.deliveries[index];
return DeliveryListItem(
delivery: delivery,
distance: widget.distances[delivery.id] ?? 0.0,
);
return BlocBuilder<TourBloc, TourState>(
builder: (context, state) {
final currentState = state;
if (currentState is TourLoaded) {
List<SortingInformation> sorted = [...currentState.sortingInformation.sorting];
sorted.sort((a, b) => a.position.compareTo(b.position));
return ListView.separated(
separatorBuilder: (context, index) => const Divider(height: 0),
itemBuilder: (context, index) {
SortingInformation info = sorted[index];
Delivery delivery = currentState.tour.deliveries.firstWhere(
(delivery) => info.deliveryId == delivery.id,
);
return DeliveryListItem(
delivery: delivery,
distance: currentState.distances?[delivery.id] ?? 0.0,
);
},
itemCount: sorted.length,
);
}
return Center(child: CircularProgressIndicator());
},
itemCount: widget.deliveries.length,
);
}
}

View File

@ -10,6 +10,7 @@ import 'package:hl_lieferservice/model/tour.dart';
import '../../../../model/delivery.dart';
import '../../../authentication/bloc/auth_bloc.dart';
import '../../../authentication/bloc/auth_state.dart';
import '../bloc/tour_state.dart';
class DeliveryOverview extends StatefulWidget {
const DeliveryOverview({
@ -186,6 +187,10 @@ class _DeliveryOverviewState extends State<DeliveryOverview> {
Expanded(
child: DeliveryList(
distances: widget.distances,
sortingInformation:
(context.read<TourBloc>().state as TourLoaded)
.sortingInformation
.sorting,
deliveries:
_deliveries
.where(

View File

@ -1,7 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_event.dart';
import 'package:hl_lieferservice/feature/delivery/overview/bloc/tour_state.dart';
import 'package:hl_lieferservice/model/delivery.dart';
import '../model/sorting_information.dart';
class CustomSortDialog extends StatefulWidget {
const CustomSortDialog({super.key});
@ -11,6 +15,21 @@ class CustomSortDialog extends StatefulWidget {
}
class _CustomSortDialogState extends State<CustomSortDialog> {
late List<SortingInformation> _localSortedList;
@override
void initState() {
super.initState();
final state = context.read<TourBloc>().state;
if (state is TourLoaded) {
_localSortedList = [...state.sortingInformation.sorting];
_localSortedList.sort((a, b) => a.position.compareTo(b.position));
} else {
_localSortedList = [];
}
}
Widget _information() {
return Padding(
padding: EdgeInsets.only(top: 15),
@ -47,33 +66,51 @@ class _CustomSortDialogState extends State<CustomSortDialog> {
if (currentState is TourLoaded) {
return Expanded(
child: ReorderableListView(
onReorder: (oldIndex, newIndex) {},
children: currentState.tour.deliveries.indexed.fold([], (
acc,
current,
) {
final delivery = current.$2;
final index = current.$1;
onReorder: (oldIndex, newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final SortingInformation item = _localSortedList.removeAt(oldIndex);
_localSortedList.insert(newIndex, item);
});
acc.add(
ListTile(
leading: CircleAvatar(
backgroundColor: Theme.of(context).primaryColor,
child: Text(
"${index + 1}",
style: TextStyle(
color: Theme.of(context).colorScheme.onSecondary,
),
),
),
title: Text(delivery.customer.name),
subtitle: Text(delivery.customer.address.toString(), style: TextStyle(fontSize: 11),),
trailing: Icon(Icons.drag_handle),
key: Key("reorder-item-${delivery.id}"),
context.read<TourBloc>().add(
ReorderDeliveryEvent(
newPosition: newIndex,
oldPosition: oldIndex,
),
);
return acc;
}),
},
children:
_localSortedList.map((info) {
Delivery delivery = currentState.tour.deliveries.firstWhere(
(delivery) => delivery.id == info.deliveryId,
);
SortingInformation information = currentState
.sortingInformation
.sorting
.firstWhere((info) => info.deliveryId == delivery.id);
return ListTile(
leading: CircleAvatar(
backgroundColor: Theme.of(context).primaryColor,
child: Text(
"${information.position + 1}",
style: TextStyle(
color: Theme.of(context).colorScheme.onSecondary,
),
),
),
title: Text(delivery.customer.name),
subtitle: Text(
delivery.customer.address.toString(),
style: TextStyle(fontSize: 11),
),
trailing: Icon(Icons.drag_handle),
key: Key("reorder-item-${delivery.id}"),
);
}).toList(),
),
);
}