Skip to content

Commit

Permalink
feat: add group logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Grodien committed Jan 14, 2025
1 parent dd11431 commit 3a6f5fc
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 54 deletions.
4 changes: 4 additions & 0 deletions das_client/lib/app/bloc/train_journey_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ class TrainJourneyCubit extends Cubit<TrainJourneyState> {
void updateBreakSeries(BreakSeries selectedBreakSeries) {
_settingsSubject.add(_settingsSubject.value.copyWith(selectedBreakSeries: selectedBreakSeries));
}

void updateExpandedGroups(List<int> expandedGroups) {
_settingsSubject.add(_settingsSubject.value.copyWith(expandedGroups: expandedGroups));
}
}

extension ContextBlocExtension on BuildContext {
Expand Down
5 changes: 4 additions & 1 deletion das_client/lib/app/model/train_journey_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import 'package:das_client/model/journey/break_series.dart';
class TrainJourneySettings {
TrainJourneySettings({
this.selectedBreakSeries,
this.expandedGroups = const [],
});

final BreakSeries? selectedBreakSeries;
final List<int> expandedGroups;

TrainJourneySettings copyWith({BreakSeries? selectedBreakSeries}) {
TrainJourneySettings copyWith({BreakSeries? selectedBreakSeries, List<int>? expandedGroups}) {
return TrainJourneySettings(
selectedBreakSeries: selectedBreakSeries ?? this.selectedBreakSeries,
expandedGroups: expandedGroups ?? this.expandedGroups,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import 'package:das_client/app/i18n/i18n.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/base_row_builder.dart';
import 'package:das_client/app/widgets/assets.dart';
import 'package:das_client/app/widgets/table/das_table_cell.dart';
import 'package:das_client/model/journey/balise.dart';
import 'package:das_client/model/journey/balise_level_crossing_group.dart';
import 'package:das_client/model/journey/level_crossing.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart';

class BaliseLevelCrossingGroupRow extends BaseRowBuilder<BaliseLevelCrossingGroup> {
static const Key baliseIconKey = Key('balise_icon_key');

BaliseLevelCrossingGroupRow({
required super.metadata,
required super.data,
required super.settings,
super.trackEquipmentRenderData,
super.onTap,
});

@override
DASTableCell informationCell(BuildContext context) {
if (_baliseCount == 0) {
return DASTableCell(
child: Text('$_levelCrossingCount ${context.l10n.p_train_journey_table_level_crossing}'),
alignment: Alignment.centerLeft,
);
} else if (_baliseCount == 1 && _levelCrossingCount > 1) {
return DASTableCell(
child: Text('($_levelCrossingCount ${context.l10n.p_train_journey_table_level_crossing})'),
alignment: Alignment.centerRight,
);
} else {
return DASTableCell(
child: Row(
children: [
Text(_levelCrossingCount > 0 ? context.l10n.p_train_journey_table_level_crossing : ''),
Spacer(),
Text(_baliseCount.toString()),
],
),
alignment: Alignment.centerRight,
);
}
}

@override
DASTableCell iconsCell2(BuildContext context) {
if (_baliseCount > 0) {
return DASTableCell(
padding: EdgeInsets.all(sbbDefaultSpacing * 0.25),
child: SvgPicture.asset(
AppAssets.iconBalise,
key: baliseIconKey,
),
alignment: Alignment.centerLeft,
);
} else {
return DASTableCell.empty();
}
}

int get _baliseCount => data.groupedElements.whereType<Balise>().length;

int get _levelCrossingCount => data.groupedElements.whereType<LevelCrossing>().length;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,23 @@ class BaliseRow extends BaseRowBuilder<Balise> {
required super.data,
required super.settings,
super.trackEquipmentRenderData,
super.isGrouped,
});

@override
DASTableCell kilometreCell(BuildContext context) {
return isGrouped ? DASTableCell.empty() : super.kilometreCell(context);
}

@override
DASTableCell timeCell(BuildContext context) {
if (!isGrouped) {
return DASTableCell.empty();
}

return DASTableCell(color: specialCellColor, child: Text(data.kilometre[0].toStringAsFixed(3)));
}

@override
DASTableCell informationCell(BuildContext context) {
return DASTableCell(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
this.trackEquipmentRenderData = const TrackEquipmentRenderData(),
this.defaultAlignment = Alignment.bottomCenter,
this.rowColor,
this.onTap,
this.isGrouped = false,
});

final Alignment defaultAlignment;
Expand All @@ -29,12 +31,15 @@ class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
final T data;
final TrackEquipmentRenderData trackEquipmentRenderData;
final TrainJourneySettings settings;
final VoidCallback? onTap;
final bool isGrouped;

@override
DASTableRow build(BuildContext context) {
return DASTableRow(
height: height,
color: rowColor,
onTap: onTap,
cells: [
kilometreCell(context),
timeCell(context),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:das_client/app/pages/journey/train_journey/widgets/table/service
import 'package:das_client/model/journey/base_data.dart';
import 'package:das_client/model/journey/cab_signaling.dart';
import 'package:das_client/model/journey/datatype.dart';
import 'package:das_client/model/journey/journey.dart';
import 'package:das_client/model/journey/metadata.dart';
import 'package:das_client/model/journey/track_equipment.dart';

/// Data class to hold all the information to visualize the track equipment.
Expand All @@ -23,30 +23,29 @@ class TrackEquipmentRenderData {
final bool isConventionalExtendedSpeedBorder;
final TrackEquipmentType? trackEquipmentType;

factory TrackEquipmentRenderData.from(Journey journey, int index) {
final data = journey.data[index];
final nonStandardTrackEquipmentSegments = journey.metadata.nonStandardTrackEquipmentSegments;
factory TrackEquipmentRenderData.from(List<BaseData> rowData, Metadata metadata, int index) {
final data = rowData[index];
final nonStandardTrackEquipmentSegments = metadata.nonStandardTrackEquipmentSegments;
final trackEquipment = nonStandardTrackEquipmentSegments.appliesToOrder(data.order).firstOrNull;
if (trackEquipment == null || !trackEquipment.isEtcsL2Segment) return TrackEquipmentRenderData();

return TrackEquipmentRenderData(
trackEquipmentType: trackEquipment.type,
cumulativeHeight: _calculateTrackEquipmentCumulativeHeight(journey, trackEquipment, index),
isConventionalExtendedSpeedBorder: _isConventionalExtendedSpeedBorder(journey, index),
cumulativeHeight: _calculateTrackEquipmentCumulativeHeight(rowData, metadata, trackEquipment, index),
isConventionalExtendedSpeedBorder: _isConventionalExtendedSpeedBorder(rowData, metadata, index),
isCABStart: data is CABSignaling ? data.isStart : false,
isCABEnd: data is CABSignaling ? data.isEnd : false,
);
}

/// calculates the cumulative height of the track equipment "line" of previous rows with the same type as given [trackEquipment].
static double _calculateTrackEquipmentCumulativeHeight(
Journey journey, NonStandardTrackEquipmentSegment trackEquipment, int index) {
List<BaseData> rowData, Metadata metadata, NonStandardTrackEquipmentSegment trackEquipment, int index) {
var cumulativeHeight = 0.0;
var searchIndex = index - 1;
while (searchIndex >= 0) {
final data = journey.data[searchIndex];
final testTrackEquipment =
journey.metadata.nonStandardTrackEquipmentSegments.appliesToOrder(data.order).firstOrNull;
final data = rowData[searchIndex];
final testTrackEquipment = metadata.nonStandardTrackEquipmentSegments.appliesToOrder(data.order).firstOrNull;

if (testTrackEquipment == null || testTrackEquipment.type != trackEquipment.type) {
break;
Expand All @@ -55,7 +54,7 @@ class TrackEquipmentRenderData {
cumulativeHeight += _rowHeight(data);

// if is conventional extended speed border, reduce by it's height as it is not part of the dashed line.
if (_isConventionalExtendedSpeedBorder(journey, searchIndex)) {
if (_isConventionalExtendedSpeedBorder(rowData, metadata, searchIndex)) {
cumulativeHeight -= TrackEquipmentCellBody.conventionalExtendedSpeedBorderSpace;
}

Expand All @@ -77,12 +76,12 @@ class TrackEquipmentRenderData {
}

/// checks if between current and previous track equipment is a border between extended and conventional speed.
static bool _isConventionalExtendedSpeedBorder(Journey journey, int index) {
static bool _isConventionalExtendedSpeedBorder(List<BaseData> rowData, Metadata metadata, int index) {
if (index < 1) return false;

final nonStandardTrackEquipmentSegments = journey.metadata.nonStandardTrackEquipmentSegments;
final currentData = journey.data[index];
final previousData = journey.data[index - 1];
final nonStandardTrackEquipmentSegments = metadata.nonStandardTrackEquipmentSegments;
final currentData = rowData[index];
final previousData = rowData[index - 1];

final trackEquipment = nonStandardTrackEquipmentSegments.appliesToOrder(currentData.order).firstOrNull;
final previousTrackEquipment = nonStandardTrackEquipmentSegments.appliesToOrder(previousData.order).firstOrNull;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,28 @@ class LevelCrossingRow extends BaseRowBuilder<LevelCrossing> {
required super.data,
required super.settings,
super.trackEquipmentRenderData,
super.isGrouped,
});

@override
DASTableCell kilometreCell(BuildContext context) {
return isGrouped ? DASTableCell.empty() : super.kilometreCell(context);
}

@override
DASTableCell timeCell(BuildContext context) {
if (!isGrouped) {
return DASTableCell.empty();
}

return DASTableCell(color: specialCellColor, child: Text(data.kilometre[0].toStringAsFixed(3)));
}

@override
DASTableCell informationCell(BuildContext context) {
return DASTableCell(
child: Text(context.l10n.p_train_journey_table_level_crossing),
alignment: Alignment.centerRight,
alignment: Alignment.centerLeft,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:das_client/app/i18n/i18n.dart';
import 'package:das_client/app/model/train_journey_settings.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/break_series_selection.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/additional_speed_restriction_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/balise_level_crossing_group_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/balise_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cab_signaling_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/track_equipment_render_data.dart';
Expand All @@ -18,9 +19,10 @@ import 'package:das_client/app/pages/journey/train_journey/widgets/table/whistle
import 'package:das_client/app/widgets/table/das_table.dart';
import 'package:das_client/app/widgets/table/das_table_column.dart';
import 'package:das_client/app/widgets/table/das_table_row.dart';
import 'package:das_client/model/journey/whistles.dart';
import 'package:das_client/model/journey/additional_speed_restriction_data.dart';
import 'package:das_client/model/journey/balise.dart';
import 'package:das_client/model/journey/balise_level_crossing_group.dart';
import 'package:das_client/model/journey/base_data_extension.dart';
import 'package:das_client/model/journey/break_series.dart';
import 'package:das_client/model/journey/cab_signaling.dart';
import 'package:das_client/model/journey/connection_track.dart';
Expand All @@ -33,6 +35,7 @@ import 'package:das_client/model/journey/service_point.dart';
import 'package:das_client/model/journey/signal.dart';
import 'package:das_client/model/journey/speed_change.dart';
import 'package:das_client/model/journey/tram_area.dart';
import 'package:das_client/model/journey/whistles.dart';
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart';
Expand Down Expand Up @@ -72,10 +75,15 @@ class TrainJourney extends StatelessWidget {
}

List<DASTableRow> _rows(BuildContext context, Journey journey, TrainJourneySettings settings) {
return List.generate(journey.data.length, (index) {
final rowData = journey.data[index];
final rows = journey.data.groupBaliseAndLeveLCrossings(settings);

final groupedRows =
rows.whereType<BaliseLevelCrossingGroup>().map((it) => it.groupedElements).expand((it) => it).toList();

final renderData = TrackEquipmentRenderData.from(journey, index);
return List.generate(rows.length, (index) {
final rowData = rows[index];

final renderData = TrackEquipmentRenderData.from(rows, journey.metadata, index);
switch (rowData.type) {
case Datatype.servicePoint:
return ServicePointRow(
Expand Down Expand Up @@ -138,7 +146,8 @@ class TrainJourney extends StatelessWidget {
metadata: journey.metadata,
data: rowData as Balise,
settings: settings,
trackEquipmentRenderData: renderData)
trackEquipmentRenderData: renderData,
isGrouped: groupedRows.contains(rowData))
.build(context);
case Datatype.whistle:
return WhistleRow(
Expand All @@ -152,7 +161,8 @@ class TrainJourney extends StatelessWidget {
metadata: journey.metadata,
data: rowData as LevelCrossing,
settings: settings,
trackEquipmentRenderData: renderData)
trackEquipmentRenderData: renderData,
isGrouped: groupedRows.contains(rowData))
.build(context);
case Datatype.tramArea:
return TramAreaRow(
Expand All @@ -161,6 +171,14 @@ class TrainJourney extends StatelessWidget {
settings: settings,
trackEquipmentRenderData: renderData)
.build(context);
case Datatype.baliseLevelCrossingGroup:
return BaliseLevelCrossingGroupRow(
metadata: journey.metadata,
data: rowData as BaliseLevelCrossingGroup,
settings: settings,
trackEquipmentRenderData: renderData,
onTap: () => _onBaliseLevelCrossingGroupTap(context, rowData, settings),
).build(context);
}
});
}
Expand Down Expand Up @@ -202,6 +220,20 @@ class TrainJourney extends StatelessWidget {
];
}

void _onBaliseLevelCrossingGroupTap(
BuildContext context, BaliseLevelCrossingGroup group, TrainJourneySettings settings) {
final trainJourneyCubit = context.trainJourneyCubit;

final newList = List<int>.from(settings.expandedGroups);
if (settings.expandedGroups.contains(group.order)) {
newList.remove(group.order);
} else {
newList.add(group.order);
}

trainJourneyCubit.updateExpandedGroups(newList);
}

void _onBreakSeriesTap(BuildContext context, Journey journey, TrainJourneySettings settings) {
final trainJourneyCubit = context.trainJourneyCubit;

Expand Down
19 changes: 11 additions & 8 deletions das_client/lib/app/widgets/table/das_table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class DASTable extends StatelessWidget {
return DASTableThemeData(
backgroundColor: isDarkTheme ? SBBColors.charcoal : SBBColors.white,
headingTextStyle: SBBTextStyles.smallLight,
dataTextStyle: SBBTextStyles.largeLight,
dataTextStyle: SBBTextStyles.largeLight.copyWith(fontWeight: FontWeight.w400),
headingRowBorder: Border(bottom: BorderSide(width: 2, color: borderColor)),
tableBorder: TableBorder(
horizontalInside: BorderSide(width: 1, color: borderColor),
Expand Down Expand Up @@ -139,13 +139,16 @@ class DASTable extends StatelessWidget {
Widget _dataRow(DASTableRow row) {
final visibleColumns = columns.where((column) => column.isVisible).toList(growable: false);
final visibleCells = row.cells.whereIndexed((index, _) => columns[index].isVisible).toList(growable: false);
return _FixedHeightRow(
height: row.height,
children: List.generate(visibleColumns.length, (index) {
final cell = visibleCells[index];
final column = visibleColumns[index];
return _dataCell(cell, column, row, isLast: visibleColumns.length - 1 == index);
}),
return InkWell(
onTap: row.onTap,
child: _FixedHeightRow(
height: row.height,
children: List.generate(visibleColumns.length, (index) {
final cell = visibleCells[index];
final column = visibleColumns[index];
return _dataCell(cell, column, row, isLast: visibleColumns.length - 1 == index);
}),
),
);
}

Expand Down
Loading

0 comments on commit 3a6f5fc

Please sign in to comment.