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
18 changes: 18 additions & 0 deletions das_client/app/lib/extension/journey_point_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:sfera/component.dart';

extension JourneyPointListExtension on List<JourneyPoint> {
int indexOfElementOrCollapsedGroup(JourneyPoint point, List<int> expandedGroups) {
for (int i = 0; i < length; i++) {
final current = this[i];
if (current == point) {
return i;
} else if (current is GroupedJourneyPoint) {
final isExpanded = expandedGroups.contains(current.order);
if (!isExpanded && current.groupedElements.contains(point)) {
return i;
}
}
}
return -1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class CollapsibleRowsViewModel {

final fromIndex = journey.data.indexOf(lastPosition);
final toIndex = journey.data.indexOf(currentPosition);
if (fromIndex > toIndex) return;

final passedCollapsibleData = journey.data.sublist(fromIndex, toIndex).where((data) => data.isCollapsible);

final collapsedRows = _rxCollapsedRows.value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:app/pages/journey/train_journey/journey_position/journey_position_model.dart';
import 'package:app/pages/journey/train_journey/widgets/reduced_overview/cells/reduced_time_cell_body.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/route_cell_body.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/route_chevron.dart';
import 'package:app/pages/journey/train_journey/widgets/table/service_point_row.dart';
import 'package:app/theme/theme_util.dart';
import 'package:app/widgets/table/das_table_cell.dart';
Expand Down Expand Up @@ -51,7 +50,7 @@ class ReducedServicePointRow extends ServicePointRow {
isRouteStart: metadata.journeyStart == data,
isRouteEnd: metadata.journeyEnd == data,
isStopOnRequest: !data.mandatoryStop,
chevronPosition: RouteChevron.positionFromHeight(height),
chevronPosition: chevronPosition,
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ class BaliseLevelCrossingGroupRow extends CellRowBuilder<BaliseLevelCrossingGrou
}
}

@override
bool get isCurrentPosition {
final isGroupPosition = !isExpanded && data.groupedElements.contains(journeyPosition?.currentPosition);
return super.isCurrentPosition || isGroupPosition;
}

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

int get _levelCrossingCount => data.groupedElements.whereType<LevelCrossing>().length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,17 @@ class CellRowBuilder<T extends JourneyPoint> extends DASTableRowBuilder<T> {
alignment: null,
clipBehaviour: Clip.none,
child: RouteCellBody(
isCurrentPosition: journeyPosition?.currentPosition == data,
isCurrentPosition: isCurrentPosition,
isRouteStart: metadata.journeyStart == data,
isRouteEnd: metadata.journeyEnd == data,
chevronAnimationData: config.chevronAnimationData,
chevronPosition: RouteChevron.positionFromHeight(height),
chevronPosition: chevronPosition,
),
);
}

bool get isCurrentPosition => journeyPosition?.currentPosition == data;

DASTableCell trackEquipment(BuildContext context) {
if (config.trackEquipmentRenderData == null) {
return DASTableCell.empty(color: specialCellColor);
Expand Down Expand Up @@ -264,6 +266,8 @@ class CellRowBuilder<T extends JourneyPoint> extends DASTableRowBuilder<T> {

ShowSpeedBehavior get showSpeedBehavior => ShowSpeedBehavior.never;

bool get _isNextStop => journeyPosition?.nextStop == data;

static double rowHeightForData(BaseData data, BreakSeries? currentBreakSeries) {
switch (data.type) {
case Datatype.servicePoint:
Expand All @@ -273,5 +277,22 @@ class CellRowBuilder<T extends JourneyPoint> extends DASTableRowBuilder<T> {
}
}

bool get _isNextStop => journeyPosition?.nextStop == data;
double get chevronPosition => CellRowBuilder.calculateChevronPosition(data, height);

static double calculateChevronPosition(BaseData data, double height) {
switch (data.type) {
case Datatype.servicePoint:
final servicePoint = data as ServicePoint;
if (servicePoint.isStop) {
return RouteCellBody.routeCirclePosition - RouteChevron.chevronHeight;
} else {
return RouteCellBody.routeCirclePosition + RouteChevron.chevronHeight;
}
case Datatype.baliseLevelCrossingGroup:
return height * 0.5;
default:
// additional -1.5 because line overdraws a bit from rotation
return height - RouteChevron.chevronHeight - 1.5;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ class RouteChevron extends StatefulWidget {

final ChevronAnimationData? chevronAnimationData;

// additional -1.5 because line overdraws a bit from rotation
static double positionFromHeight(double height) => height - chevronHeight - 1.5;

@override
State<RouteChevron> createState() => _RouteChevronState();
}
Expand Down Expand Up @@ -51,12 +48,14 @@ class _RouteChevronState extends State<RouteChevron> {
if (widget.chevronAnimationData != null && controller?.animation != null) {
final start = widget.chevronAnimationData!.startOffset;
final end = widget.chevronAnimationData!.endOffset;
final reversed = start > end;
final diff = (start - end).abs();

setState(() {
if (controller?.currentPosition == widget.chevronAnimationData?.currentPosition &&
controller?.lastPosition == widget.chevronAnimationData?.lastPosition) {
currentOffsetValue = start + (diff * controller!.animation!.value);
currentOffsetValue =
start + (reversed ? -(diff * controller!.animation!.value) : (diff * controller!.animation!.value));
} else {
currentOffsetValue = end;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:app/extension/journey_point_extension.dart';
import 'package:app/pages/journey/train_journey/journey_position/journey_position_model.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cell_row_builder.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/route_cell_body.dart';
Expand All @@ -24,20 +25,34 @@ class ChevronAnimationData {
Metadata metadata,
BaseData currentRow,
BreakSeries? currentBreakSeries,
List<int> expandedGroups,
) {
final currentPosition = journeyPosition?.currentPosition;
final lastPosition = journeyPosition?.lastPosition;
if (currentPosition == null || lastPosition == currentPosition || currentRow is! JourneyPoint) {
if (currentPosition == null ||
lastPosition == null ||
lastPosition == currentPosition ||
currentRow is! JourneyPoint) {
return null;
}

// handle no position update
if (lastPosition == null) return _handleNoPositionUpdate(rows, currentPosition, currentRow, currentBreakSeries);
var toIndex = rows.indexOfElementOrCollapsedGroup(currentPosition, expandedGroups);
final currentIndex = rows.indexOf(currentRow);

final fromIndex = rows.indexOf(lastPosition);
final toIndex = rows.indexOf(currentPosition);
var fromIndex = rows.indexOfElementOrCollapsedGroup(lastPosition, expandedGroups);

bool reversed = false;
if (fromIndex > toIndex) {
reversed = true;
final temp = fromIndex;
fromIndex = toIndex;
toIndex = temp;
}

if (fromIndex == -1 || toIndex == -1) {
return null;
}

final currentIndex = rows.indexOf(currentRow);
if (currentIndex < fromIndex || currentIndex > toIndex) {
return null;
}
Expand All @@ -48,7 +63,7 @@ class ChevronAnimationData {
// First row chevron to end of cell
final startRow = rows[fromIndex];
final startRowHeight = CellRowBuilder.rowHeightForData(startRow, currentBreakSeries);
final startRowChevronPosition = RouteChevron.positionFromHeight(startRowHeight);
final startRowChevronPosition = CellRowBuilder.calculateChevronPosition(startRow, startRowHeight);

endOffset += startRowHeight - startRowChevronPosition;

Expand All @@ -58,7 +73,7 @@ class ChevronAnimationData {
final rowHeight = CellRowBuilder.rowHeightForData(currentRow, currentBreakSeries);
if (currentIndex == i) {
// swap startOffset when current cell is passed over
final chevronPosition = RouteChevron.positionFromHeight(rowHeight);
final chevronPosition = CellRowBuilder.calculateChevronPosition(currentRow, rowHeight);
endOffset += chevronPosition;
startOffset = endOffset * -1;
endOffset = rowHeight - chevronPosition;
Expand All @@ -72,40 +87,29 @@ class ChevronAnimationData {
final endRowHeight = CellRowBuilder.rowHeightForData(endRow, currentBreakSeries);
final chevronPosition = metadata.journeyEnd == endRow
? RouteCellBody.routeCirclePosition - RouteChevron.chevronHeight
: RouteChevron.positionFromHeight(endRowHeight);
: CellRowBuilder.calculateChevronPosition(endRow, endRowHeight);
endOffset += chevronPosition;

if (currentRow == currentPosition) {
if (currentIndex == toIndex && !reversed) {
startOffset = -endOffset;
endOffset = 0.0;
}

if (reversed) {
if (currentIndex == toIndex) {
endOffset = -endOffset;
} else {
final temp = startOffset;
startOffset = endOffset;
endOffset = temp;
}
}

return ChevronAnimationData(
startOffset: startOffset,
endOffset: endOffset,
lastPosition: lastPosition,
currentPosition: currentPosition,
);
}

/// returns static animation data for position row and next row overlapped with chevron.
static ChevronAnimationData? _handleNoPositionUpdate(
List<JourneyPoint> rows,
JourneyPoint currentPosition,
JourneyPoint currentRow,
BreakSeries? currentBreakSeries,
) {
final positionIndex = rows.indexOf(currentPosition);
final overlappingRowIndex = positionIndex + 1;
final currentIndex = rows.indexOf(currentRow);

if (currentIndex == positionIndex) {
return ChevronAnimationData(startOffset: 0.0, endOffset: 0.0, currentPosition: currentPosition);
} else if (currentIndex == overlappingRowIndex) {
final overlappedRow = rows[overlappingRowIndex];
final offset = -CellRowBuilder.rowHeightForData(overlappedRow, currentBreakSeries);
return ChevronAnimationData(startOffset: offset, endOffset: offset, currentPosition: currentPosition);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import 'package:app/extension/station_sign_extension.dart';
import 'package:app/pages/journey/train_journey/journey_position/journey_position_model.dart';
import 'package:app/pages/journey/train_journey/journey_position/journey_position_view_model.dart';
import 'package:app/pages/journey/train_journey/widgets/detail_modal/service_point_modal/service_point_modal_tab.dart';
import 'package:app/pages/journey/train_journey/widgets/detail_modal/service_point_modal/service_point_modal_view_model.dart';
import 'package:app/pages/journey/train_journey/widgets/table/arrival_departure_time/arrival_departure_time_view_model.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cell_row_builder.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/route_cell_body.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/route_chevron.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/show_speed_behaviour.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/time_cell_body.dart';
import 'package:app/pages/journey/train_journey/widgets/table/cells/track_equipment_cell_body.dart';
Expand Down Expand Up @@ -121,25 +119,20 @@ class ServicePointRow extends CellRowBuilder<ServicePoint> {

@override
DASTableCell routeCell(BuildContext context) {
final positionViewModel = context.read<JourneyPositionViewModel>();
return DASTableCell(
color: specialCellColor,
padding: EdgeInsets.all(0.0),
alignment: null,
clipBehaviour: Clip.none,
child: StreamBuilder(
stream: positionViewModel.model,
initialData: positionViewModel.modelValue,
builder: (context, snapshot) => RouteCellBody(
isStop: data.isStop,
isCurrentPosition: snapshot.data?.currentPosition == data,
isRouteStart: metadata.journeyStart == data,
isRouteEnd: metadata.journeyEnd == data,
isStopOnRequest: !data.mandatoryStop,
chevronAnimationData: config.chevronAnimationData,
chevronPosition: RouteChevron.positionFromHeight(height),
routeColor: _isNextStop && specialCellColor == null ? Colors.white : null,
),
child: RouteCellBody(
isStop: data.isStop,
isCurrentPosition: isCurrentPosition,
isRouteStart: metadata.journeyStart == data,
isRouteEnd: metadata.journeyEnd == data,
isStopOnRequest: !data.mandatoryStop,
chevronAnimationData: config.chevronAnimationData,
chevronPosition: chevronPosition,
routeColor: _isNextStop && specialCellColor == null ? Colors.white : null,
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ class TrainJourney extends StatelessWidget {
.expand((it) => it)
.toList();

final journeyPoints = rows.whereType<JourneyPoint>().toList();

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

Expand All @@ -191,11 +193,12 @@ class TrainJourney extends StatelessWidget {
),
bracketStationRenderData: BracketStationRenderData.from(rowData, journey.metadata),
chevronAnimationData: ChevronAnimationData.from(
journey.journeyPoints,
journeyPoints,
journeyPosition,
journey.metadata,
rowData,
currentBreakSeries,
settings.expandedGroups,
),
);

Expand Down
Loading
Loading