Skip to content

Commit

Permalink
feat: added CAB start and end signaling (#82) (#442)
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 12, 2024
1 parent 6269d3a commit 151f24e
Show file tree
Hide file tree
Showing 62 changed files with 1,693 additions and 400 deletions.
21 changes: 1 addition & 20 deletions das_client/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,32 +1,13 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
always_use_package_imports: true
prefer_single_quotes: true
prefer_final_in_for_each: true
prefer_final_locals: true
prefer_final_fields: true
always_put_required_named_parameters_first: true

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
Expand Down
5 changes: 5 additions & 0 deletions das_client/assets/icons/icon_cab_end.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions das_client/assets/icons/icon_cab_start.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 50 additions & 1 deletion das_client/integration_test/test/train_journey_table_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
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/route_cell_body.dart';
import 'package:das_client/app/pages/journey/train_journey/widgets/table/curve_point_row.dart';
Expand Down Expand Up @@ -150,8 +151,11 @@ void main() {
expect(scrollableFinder, findsOneWidget);

final stopRouteRow = findDASTableRowByText('Bahnhof A');
final nonStoppingPassRouteRow = findDASTableRowByText('Haltestelle B');
expect(stopRouteRow, findsOneWidget);

await tester.dragUntilVisible(findDASTableRowByText('Haltestelle B'), scrollableFinder, const Offset(0, -50));

final nonStoppingPassRouteRow = findDASTableRowByText('Haltestelle B');
expect(nonStoppingPassRouteRow, findsOneWidget);

// check stop circles
Expand Down Expand Up @@ -418,6 +422,51 @@ void main() {
find.descendant(of: blockIntermediateSignalRow, matching: find.byKey(SignalRow.signalLineChangeIconKey));
expect(noLaneChangeIcon2, findsNothing);
});

testWidgets('test if CAB signaling 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);

// CAB segment with start outside train journey and end at 33.8 km
await tester.dragUntilVisible(find.text('29.7').first, scrollableFinder, const Offset(0, -50));
final rowsAtKm33_8 = findDASTableRowByText('33.8');
expect(rowsAtKm33_8, findsExactly(2));
final segment1CABStop = rowsAtKm33_8.last; // end should be after other elements at same location
final segment1CABStopIcon = find.descendant(of: segment1CABStop, matching: find.byKey(CABSignalingRow.cabSignalingEndIconKey));
expect(segment1CABStopIcon, findsOneWidget);

// Track equipment segment without ETCS level 2 should be ignored
await tester.dragUntilVisible(find.text('12.5').first, scrollableFinder, const Offset(0, -50));
final etcsL1LSEnd = findDASTableRowByText('10.1');
expect(etcsL1LSEnd, findsNothing);

// CAB segment between km 12.5 - km 39.9
final rowsAtKm12_5 = findDASTableRowByText('12.5');
expect(rowsAtKm12_5, findsExactly(2));
final segment2CABStart = rowsAtKm12_5.first; // start should be before other elements at same location
final segment2CABStartIcon = find.descendant(of: segment2CABStart, matching: find.byKey(CABSignalingRow.cabSignalingStartIconKey));
expect(segment2CABStartIcon, findsOneWidget);
await tester.dragUntilVisible(find.text('75.3'), scrollableFinder, const Offset(0, -50));
final trackEquipmentTypeChange = findDASTableRowByText('56.8');
expect(trackEquipmentTypeChange, findsNothing); // no CAB signaling at connecting ETCS L2 segments
await tester.dragUntilVisible(find.text('41.5'), scrollableFinder, const Offset(0, -50));
final rothristServicePointRow = findDASTableRowByText('46.2');
expect(rothristServicePointRow, findsOneWidget); // no CAB signaling at connecting ETCS L2 segments
final segment2CABEnd = findDASTableRowByText('39.9');
final segment2CABEndIcon = find.descendant(of: segment2CABEnd, matching: find.byKey(CABSignalingRow.cabSignalingEndIconKey));
expect(segment2CABEndIcon, findsOneWidget);

// CAB segment with end outside train journey and start at 8.3 km
await tester.dragUntilVisible(find.text('9.5'), scrollableFinder, const Offset(0, -50));
final segment3CABStart = findDASTableRowByText('8.3');
final segment3CABStartIcon = find.descendant(of: segment3CABStart, matching: find.byKey(CABSignalingRow.cabSignalingStartIconKey));
expect(segment3CABStartIcon, findsOneWidget);
});
});
}

Expand Down
2 changes: 1 addition & 1 deletion das_client/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: d9dad56c0cd0b4fd8b4fe3034a53fd42a0b990f6

COCOAPODS: 1.15.2
COCOAPODS: 1.16.1
2 changes: 1 addition & 1 deletion das_client/lib/app/bloc/train_journey_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class TrainJourneyCubit extends Cubit<TrainJourneyState> {

void reset() {
if (state is BaseTrainJourneyState) {
Fimber.i('Reseting TrainJourney cubit in state $state');
Fimber.i('Resetting TrainJourney cubit in state $state');
emit(SelectingTrainJourneyState(
trainNumber: (state as BaseTrainJourneyState).trainNumber,
date: DateTime.now(),
Expand Down
2 changes: 1 addition & 1 deletion das_client/lib/app/bloc/train_journey_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ part of 'train_journey_cubit.dart';
sealed class TrainJourneyState {}

final class SelectingTrainJourneyState extends TrainJourneyState {
SelectingTrainJourneyState({this.ru, this.trainNumber, required this.date, this.errorCode});
SelectingTrainJourneyState({required this.date, this.ru, this.trainNumber, this.errorCode});

final String? trainNumber;
final Ru? ru;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter/material.dart';

class ADLNotification extends StatelessWidget {
const ADLNotification({super.key, required this.message, this.margin});
const ADLNotification({required this.message, super.key, this.margin});

final String message;
final EdgeInsetsGeometry? margin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class AdditionalSpeedRestrictionRow extends BaseRowBuilder<AdditionalSpeedRestrictionData> {
static const Key additionalSpeedRestrictionIconKey = Key('addition_speed_restrction_icon_key');
static const Key additionalSpeedRestrictionIconKey = Key('addition_speed_restriction_icon_key');
static const Color additionalSpeedRestrictionColor = SBBColors.orange;
static const double rowHeight = 44.0;

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

@override
Expand All @@ -33,11 +34,12 @@ class AdditionalSpeedRestrictionRow extends BaseRowBuilder<AdditionalSpeedRestri
@override
DASTableCell iconsCell2(BuildContext context) {
return DASTableCell(
child: SvgPicture.asset(
AppAssets.iconAdditionalSpeedRestriction,
key: additionalSpeedRestrictionIconKey,
),
alignment: Alignment.center);
child: SvgPicture.asset(
AppAssets.iconAdditionalSpeedRestriction,
key: additionalSpeedRestrictionIconKey,
),
alignment: Alignment.center,
);
}

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

class BaseRowBuilder<T extends BaseData> extends DASTableRowBuilder {
static const double rowHeight = 44.0;

const BaseRowBuilder({
super.height = 44.0,
this.defaultAlignment = Alignment.bottomCenter,
this.rowColor,
required this.metadata,
required this.data,
super.height = rowHeight,
this.defaultAlignment = Alignment.bottomCenter,
this.rowColor,
});

final Alignment defaultAlignment;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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/cab_signaling.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class CABSignalingRow extends BaseRowBuilder<CABSignaling> {
static const Key cabSignalingStartIconKey = Key('cab_signaling_start_icon_key');
static const Key cabSignalingEndIconKey = Key('cab_signaling_end_icon_key');

CABSignalingRow({
required super.metadata,
required super.data,
});

@override
DASTableCell iconsCell1(BuildContext context) {
return DASTableCell(
child: SvgPicture.asset(
key: data.isStart ? cabSignalingStartIconKey : cabSignalingEndIconKey,
data.isStart ? AppAssets.iconCabStart : AppAssets.iconCabEnd,
),
alignment: Alignment.center,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class BracketStationBody extends StatelessWidget {
static const double _bracketStationFontSize = 12.0;

const BracketStationBody({
super.key,
required this.bracketStation,
required this.height
required this.height,
super.key,
});

final BracketStation bracketStation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@ class RouteCellBody extends StatelessWidget {
final isDarkTheme = SBBBaseStyle.of(context).brightness == Brightness.dark;
final lineColor = isDarkTheme ? SBBColors.white : SBBColors.black;
return Positioned(
key: isRouteStart
? routeStartKey
: isRouteEnd
? routeEndKey
: null,
key: _routeKey(),
top: isRouteStart ? height - sbbDefaultSpacing : -sbbDefaultSpacing,
bottom: isRouteEnd ? sbbDefaultSpacing : -sbbDefaultSpacing,
right: 0,
Expand Down Expand Up @@ -87,6 +83,13 @@ class RouteCellBody extends StatelessWidget {
),
);
}

Key? _routeKey() {
if (!isRouteStart && !isRouteEnd) {
return null;
}
return isRouteStart ? routeStartKey : routeEndKey;
}
}

class _RouteCircle extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import 'package:flutter_svg/flutter_svg.dart';

class ProtectionSectionRow extends BaseRowBuilder<ProtectionSection> {
static const Key protectionSectionKey = Key('protection_section_key');
static const double rowHeight = 44.0;

ProtectionSectionRow({
super.height = 44.0,
required super.metadata,
required super.data,
super.height = rowHeight,
}) : super(rowColor: SBBColors.peach);

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import 'package:flutter_svg/flutter_svg.dart';
class ServicePointRow extends BaseRowBuilder<ServicePoint> {
static const Key stopOnRequestKey = Key('stop_on_request_key');

static const double rowHeight = 64.0;

ServicePointRow({
super.height = 64.0,
required super.metadata,
required super.data,
super.height = rowHeight,
}) : super(rowColor: metadata.nextStop == data ? SBBColors.royal.withOpacity(0.2) : Colors.transparent);

@override
Expand Down Expand Up @@ -49,7 +51,7 @@ class ServicePointRow extends BaseRowBuilder<ServicePoint> {
if (data.bracketStation != null)
BracketStationBody(
bracketStation: data.bracketStation!,
height: height!,
height: height,
),
if (!data.mandatoryStop)
Align(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:das_client/app/bloc/train_journey_cubit.dart';
import 'package:das_client/app/i18n/i18n.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/connection_track_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/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 All @@ -12,6 +13,7 @@ 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/additional_speed_restriction_data.dart';
import 'package:das_client/model/journey/connection_track.dart';
import 'package:das_client/model/journey/cab_signaling.dart';
import 'package:das_client/model/journey/curve_point.dart';
import 'package:das_client/model/journey/datatype.dart';
import 'package:das_client/model/journey/journey.dart';
Expand Down Expand Up @@ -73,6 +75,11 @@ class TrainJourney extends StatelessWidget {
return ConnectionTrackRow(metadata: journey.metadata, data: rowData as ConnectionTrack).build(context);
case Datatype.speedChange:
return SpeedChangeRow(metadata: journey.metadata, data: rowData as SpeedChange).build(context);
case Datatype.cabSignaling:
return CABSignalingRow(
metadata: journey.metadata,
data: rowData as CABSignaling,
).build(context);
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion das_client/lib/app/widgets/app_version_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';

class AppVersionText extends StatelessWidget {
const AppVersionText({super.key, required this.color});
const AppVersionText({required this.color, super.key});

final Color color;

Expand Down
2 changes: 2 additions & 0 deletions das_client/lib/app/widgets/assets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ class AppAssets {
static const iconAdditionalSpeedRestriction = '$_iconsDir/icon_additional_speed_restriction.svg';
static const iconCurveStart = '$_iconsDir/icon_curve_start.svg';
static const iconSignalLaneChange = '$_iconsDir/icon_signal_line_change.svg';
static const iconCabStart = '$_iconsDir/icon_cab_start.svg';
static const iconCabEnd = '$_iconsDir/icon_cab_end.svg';
}
2 changes: 1 addition & 1 deletion das_client/lib/app/widgets/device_id_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter/material.dart';

class DeviceIdText extends StatelessWidget {
const DeviceIdText({super.key, required this.color});
const DeviceIdText({required this.color, super.key});

final Color color;

Expand Down
2 changes: 1 addition & 1 deletion das_client/lib/app/widgets/header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:design_system_flutter/design_system_flutter.dart';
import 'package:flutter/material.dart';

class Header extends StatelessWidget {
const Header({super.key, required this.child});
const Header({required this.child, super.key});

final Widget child;

Expand Down
Loading

0 comments on commit 151f24e

Please sign in to comment.