Skip to content

Commit

Permalink
feat: added visualization of non standard track equipment (#82) (#470)
Browse files Browse the repository at this point in the history
Co-authored-by: u221711 <[email protected]>
  • Loading branch information
rawi-coding and Grodien authored Dec 19, 2024
1 parent cd84c85 commit c4f83eb
Show file tree
Hide file tree
Showing 20 changed files with 650 additions and 47 deletions.
87 changes: 81 additions & 6 deletions das_client/integration_test/test/train_journey_table_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
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/cab_signaling_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/bracket_station_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/bracket_station_cell_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/route_cell_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/track_equipment_cell_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/curve_point_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/protection_section_row.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/service_point_row.dart';
Expand Down Expand Up @@ -224,7 +225,7 @@ void main() {
it is Container &&
it.decoration is BoxDecoration &&
(it.decoration as BoxDecoration).color == AdditionalSpeedRestrictionRow.additionalSpeedRestrictionColor));
expect(coloredCells, findsNWidgets(11));
expect(coloredCells, findsNWidgets(12));
});

testWidgets('test other rows are displayed correctly', (tester) async {
Expand All @@ -241,7 +242,7 @@ void main() {

final testRows = ['Genève', 'km 32.2', 'Lengnau', 'WANZ'];

//Scroll to the table and search inside it
// Scroll to the table and search inside it
for (final rowText in testRows) {
final rowFinder = find.descendant(of: tableFinder, matching: find.text(rowText));
await tester.dragUntilVisible(rowFinder, tableFinder, const Offset(0, -50));
Expand All @@ -257,7 +258,7 @@ void main() {
it.decoration is BoxDecoration &&
(it.decoration as BoxDecoration).color ==
AdditionalSpeedRestrictionRow.additionalSpeedRestrictionColor));
expect(coloredCells, findsNWidgets(3));
expect(coloredCells, findsNWidgets(4));
}
});

Expand Down Expand Up @@ -453,9 +454,9 @@ void main() {

// check if the bracket station widget is displayed
final bracketStationDWidget =
find.descendant(of: bracketStationD, matching: find.byKey(BracketStationBody.bracketStationKey));
find.descendant(of: bracketStationD, matching: find.byKey(BracketStationCellBody.bracketStationKey));
final bracketStationD1Widget =
find.descendant(of: bracketStationD1, matching: find.byKey(BracketStationBody.bracketStationKey));
find.descendant(of: bracketStationD1, matching: find.byKey(BracketStationCellBody.bracketStationKey));
expect(bracketStationDWidget, findsOneWidget);
expect(bracketStationD1Widget, findsOneWidget);

Expand Down Expand Up @@ -612,9 +613,83 @@ void main() {
find.descendant(of: segment3CABStart, matching: find.byKey(CABSignalingRow.cabSignalingStartIconKey));
expect(segment3CABStartIcon, findsOneWidget);
});

testWidgets('test if track equipment is displayed correctly', (tester) async {
await prepareAndStartApp(tester);

// load train journey by filling out train selection page
await _loadTrainJourney(tester, trainNumber: 'T1');

final scrollableFinder = find.byType(ListView);
expect(scrollableFinder, findsOneWidget);

// check ExtendedSpeedReversingPossible from Genève-Aéroport to Gland
_checkTrackEquipmentOnServicePoint('Genève-Aéroport', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
_checkTrackEquipmentOnServicePoint('Genève', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
_checkTrackEquipmentOnServicePoint('Gland', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
final segment1CABStop = findDASTableRowByText('33.8').last;
final segment1CABStopTrackEquipment = find.descendant(
of: segment1CABStop, matching: find.byKey(TrackEquipmentCellBody.extendedSpeedReversingPossibleKey));
expect(segment1CABStopTrackEquipment, findsOneWidget);

// check ConventionalSpeedReversingImpossible from Morges to Onnens-Bonvillars
await tester.dragUntilVisible(find.text('Onnens-Bonvillars'), scrollableFinder, const Offset(0, -50));
final segment2CABStart = findDASTableRowByText('12.5').first;
final segment2CABStartTrackEquipment = find.descendant(
of: segment2CABStart, matching: find.byKey(TrackEquipmentCellBody.conventionalSpeedReversingImpossible));
expect(segment2CABStartTrackEquipment, findsOneWidget);
_checkTrackEquipmentOnServicePoint('Morges', TrackEquipmentCellBody.conventionalSpeedReversingImpossible);
_checkTrackEquipmentOnServicePoint(
'Yverdon-les-Bains', TrackEquipmentCellBody.conventionalSpeedReversingImpossible);
_checkTrackEquipmentOnServicePoint(
'Onnens-Bonvillars', TrackEquipmentCellBody.conventionalSpeedReversingImpossible);

// check ExtendedSpeedReversingPossibleKey from Neuchâtel to Rothrist
await tester.dragUntilVisible(find.text('Grenchen Süd'), scrollableFinder, const Offset(0, -50));
_checkTrackEquipmentOnServicePoint('Neuchâtel', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey,
hasConvExtSpeedBorder: true);
_checkTrackEquipmentOnServicePoint('Biel/Bienne', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
_checkTrackEquipmentOnServicePoint('Lengnau', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
_checkTrackEquipmentOnServicePoint('Grenchen Süd', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
await tester.dragUntilVisible(find.text('Rothrist'), scrollableFinder, const Offset(0, -50));
_checkTrackEquipmentOnServicePoint('Solothurn', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
_checkTrackEquipmentOnServicePoint('WANZ', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
_checkTrackEquipmentOnServicePoint('Rothrist', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);

// check ExtendedSpeedReversingPossibleKey in Olten
await tester.dragUntilVisible(find.text('Aarau'), scrollableFinder, const Offset(0, -50));
_checkTrackEquipmentOnServicePoint('Olten', TrackEquipmentCellBody.conventionalSpeedReversingImpossible,
hasConvExtSpeedBorder: true);
final segment2CABEnd = findDASTableRowByText('39.9').first;
final segment2CABEndTrackEquipment = find.descendant(
of: segment2CABEnd, matching: find.byKey(TrackEquipmentCellBody.conventionalSpeedReversingImpossible));
expect(segment2CABEndTrackEquipment, findsOneWidget);

// check ExtendedSpeedReversingImpossibleKey from Zürich HB to Opfikon Süd
await tester.dragUntilVisible(find.text('Flughafen'), scrollableFinder, const Offset(0, -50));
final segment3CABStart = findDASTableRowByText('8.3').first;
final segment3CABStartTrackEquipment = find.descendant(
of: segment3CABStart, matching: find.byKey(TrackEquipmentCellBody.extendedSpeedReversingImpossibleKey));
expect(segment3CABStartTrackEquipment, findsOneWidget);
_checkTrackEquipmentOnServicePoint('Zürich HB', TrackEquipmentCellBody.extendedSpeedReversingImpossibleKey);
_checkTrackEquipmentOnServicePoint('Opfikon Süd', TrackEquipmentCellBody.extendedSpeedReversingImpossibleKey);

// check ExtendedSpeedReversingImpossibleKey in Flughafen
_checkTrackEquipmentOnServicePoint('Flughafen', TrackEquipmentCellBody.extendedSpeedReversingPossibleKey);
});
});
}

void _checkTrackEquipmentOnServicePoint(String name, Key expectedKey, {bool hasConvExtSpeedBorder = false}) {
final servicePointRow = findDASTableRowByText(name);
final trackEquipment = find.descendant(of: servicePointRow, matching: find.byKey(expectedKey));
expect(trackEquipment, findsOneWidget);

final convExtSpeedBorder = find.descendant(
of: servicePointRow, matching: find.byKey(TrackEquipmentCellBody.conventionalExtendedSpeedBorderKey));
expect(convExtSpeedBorder, hasConvExtSpeedBorder ? findsOneWidget : findsNothing);
}

/// Verifies, that SBB is selected and loads train journey with [trainNumber]
Future<void> _loadTrainJourney(WidgetTester tester, {required String trainNumber}) async {
// verify we have ru SBB selected.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart';
class AdditionalSpeedRestrictionRow extends BaseRowBuilder<AdditionalSpeedRestrictionData> {
static const Key additionalSpeedRestrictionIconKey = Key('addition_speed_restriction_icon_key');
static const Color additionalSpeedRestrictionColor = SBBColors.orange;
static const double rowHeight = 44.0;

AdditionalSpeedRestrictionRow({
required super.metadata,
required super.data,
required super.settings,
super.height = rowHeight,
super.trackEquipmentRenderData,
}) : super(rowColor: additionalSpeedRestrictionColor);

@override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:das_client/app/model/train_journey_settings.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/cells/route_cell_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/track_equipment_cell_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/cells/track_equipment_render_data.dart';
import 'package:das_client/app/widgets/table/das_table_cell.dart';
import 'package:das_client/app/widgets/table/das_table_row.dart';
import 'package:das_client/model/journey/additional_speed_restriction.dart';
Expand All @@ -16,6 +18,7 @@ class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
required this.data,
required this.settings,
super.height = rowHeight,
this.trackEquipmentRenderData = const TrackEquipmentRenderData(),
this.defaultAlignment = Alignment.bottomCenter,
this.rowColor,
});
Expand All @@ -24,6 +27,7 @@ class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
final Color? rowColor;
final Metadata metadata;
final T data;
final TrackEquipmentRenderData trackEquipmentRenderData;
final TrainJourneySettings settings;

@override
Expand All @@ -35,6 +39,7 @@ class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
kilometreCell(context),
timeCell(context),
routeCell(context),
trackEquipment(context),
iconsCell1(context),
informationCell(context),
iconsCell2(context),
Expand Down Expand Up @@ -78,6 +83,17 @@ class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
);
}

DASTableCell trackEquipment(BuildContext context) {
return DASTableCell(
color: specialCellColor,
padding: EdgeInsets.all(0.0),
alignment: null,
child: TrackEquipmentCellBody(
renderData: trackEquipmentRenderData,
),
);
}

DASTableCell timeCell(BuildContext context) {
return DASTableCell.empty(color: specialCellColor);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class CABSignalingRow extends BaseRowBuilder<CABSignaling> {
required super.metadata,
required super.data,
required super.settings,
super.trackEquipmentRenderData,
});

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import 'package:das_client/model/journey/bracket_station.dart';
import 'package:sbb_design_system_mobile/sbb_design_system_mobile.dart';
import 'package:flutter/material.dart';

class BracketStationBody extends StatelessWidget {
class BracketStationCellBody extends StatelessWidget {
static const Key bracketStationKey = Key('bracketStationKey');
static const double _bracketStationWidth = 16.0;
static const double _bracketStationFontSize = 12.0;

const BracketStationBody({
const BracketStationCellBody({
required this.bracketStation,
required this.height,
super.key,
Expand All @@ -34,9 +34,10 @@ class BracketStationBody extends StatelessWidget {
child: Text(
bracketStation.mainStationAbbreviation ?? '',
style: SBBTextStyles.extraSmallBold.copyWith(
color: SBBColors.white,
fontSize: _bracketStationFontSize,
height: _bracketStationWidth / _bracketStationFontSize),
color: SBBColors.white,
fontSize: _bracketStationFontSize,
height: _bracketStationWidth / _bracketStationFontSize,
),
),
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ class RouteCellBody extends StatelessWidget {
return LayoutBuilder(
builder: (context, constraints) {
final height = constraints.maxHeight;
final width = constraints.maxWidth;
return Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
_routeLine(context, height),
_routeLine(context, height, width),
if (isCurrentPosition) _chevron(context),
if (isStop) _circle(context),
],
Expand All @@ -50,15 +51,16 @@ class RouteCellBody extends StatelessWidget {
);
}

Positioned _routeLine(BuildContext context, double height) {
Widget _routeLine(BuildContext context, double height, double width) {
final isDarkTheme = SBBBaseStyle.of(context).brightness == Brightness.dark;
final lineColor = isDarkTheme ? SBBColors.white : SBBColors.black;
final horizontalBorderWidth =
DASTableTheme.of(context)?.data.tableBorder?.horizontalInside.width ?? sbbDefaultSpacing;
return Positioned(
key: _routeKey(),
top: isRouteStart ? height - sbbDefaultSpacing : -sbbDefaultSpacing,
bottom: isRouteEnd ? sbbDefaultSpacing : -sbbDefaultSpacing,
right: 0,
left: 0,
top: isRouteStart ? height - sbbDefaultSpacing : 0,
bottom: isRouteEnd ? sbbDefaultSpacing : -horizontalBorderWidth,
left: (width / 2) - (lineThickness / 2),
child: VerticalDivider(thickness: lineThickness, color: lineColor),
);
}
Expand Down
Loading

0 comments on commit c4f83eb

Please sign in to comment.