|
|
@ -1,7 +1,9 @@ |
|
|
|
|
|
|
|
import 'dart:math'; |
|
|
|
|
|
|
|
import 'dart:ui'; |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
|
|
|
|
import 'package:info_tren/components/badge.dart'; |
|
|
|
import 'package:info_tren/components/loading/loading.dart'; |
|
|
|
import 'package:info_tren/components/loading/loading.dart'; |
|
|
|
import 'package:info_tren/components/refresh_future_builder.dart'; |
|
|
|
import 'package:info_tren/components/refresh_future_builder.dart'; |
|
|
|
import 'package:flutter/src/widgets/framework.dart'; |
|
|
|
|
|
|
|
import 'package:info_tren/models/station_data.dart'; |
|
|
|
import 'package:info_tren/models/station_data.dart'; |
|
|
|
import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.dart'; |
|
|
|
import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.dart'; |
|
|
|
|
|
|
|
|
|
|
@ -48,64 +50,240 @@ class ViewStationPageStateMaterial extends ViewStationPageState { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
Widget buildStationArrivalItem(BuildContext context, StationArrival item) { |
|
|
|
Widget buildStationArrivalItem(BuildContext context, StationArrDep item) { |
|
|
|
return ListTile( |
|
|
|
return InkWell( |
|
|
|
leading: Text('${item.time.toLocal().hour.toString().padLeft(2, '0')}:${item.time.toLocal().minute.toString().padLeft(2, '0')}'), |
|
|
|
onTap: () => onTrainTapped(item.train.number), |
|
|
|
title: Text.rich( |
|
|
|
child: Row( |
|
|
|
TextSpan( |
|
|
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
|
|
children: [ |
|
|
|
children: [ |
|
|
|
TextSpan( |
|
|
|
Padding( |
|
|
|
text: item.train.rank, |
|
|
|
padding: const EdgeInsets.all(8), |
|
|
|
style: TextStyle( |
|
|
|
child: Column( |
|
|
|
color: item.train.rank.startsWith('IR') ? Color.fromARGB(255, 255, 0, 0) : null, |
|
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
|
|
|
|
|
|
children: [ |
|
|
|
|
|
|
|
Text( |
|
|
|
|
|
|
|
'${item.time.toLocal().hour.toString().padLeft(2, '0')}:${item.time.toLocal().minute.toString().padLeft(2, '0')}', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
fontFeatures: [ |
|
|
|
|
|
|
|
FontFeature.tabularFigures(), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
decoration: item.status.delay != 0 ? TextDecoration.lineThrough : null, |
|
|
|
|
|
|
|
fontSize: item.status.delay != 0 ? 12 : null, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
if (item.status.delay != 0) Builder( |
|
|
|
|
|
|
|
builder: (context) { |
|
|
|
|
|
|
|
final newTime = item.time.add(Duration(minutes: item.status.delay)); |
|
|
|
|
|
|
|
final delay = item.status.delay > 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Text( |
|
|
|
|
|
|
|
'${newTime.toLocal().hour.toString().padLeft(2, '0')}:${newTime.toLocal().minute.toString().padLeft(2, '0')}', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
fontFeatures: [ |
|
|
|
|
|
|
|
FontFeature.tabularFigures(), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
color: delay ? Colors.red : Colors.green, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
Expanded( |
|
|
|
|
|
|
|
child: IgnorePointer( |
|
|
|
|
|
|
|
child: ListTile( |
|
|
|
|
|
|
|
isThreeLine: item.status.delay != 0, |
|
|
|
|
|
|
|
title: Text.rich( |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
children: [ |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
text: item.train.rank, |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
color: item.train.rank.startsWith('IR') ? Color.fromARGB(255, 255, 0, 0) : null, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
TextSpan(text: ' '), |
|
|
|
|
|
|
|
TextSpan(text: item.train.number,), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
subtitle: Text.rich( |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
children: [ |
|
|
|
|
|
|
|
TextSpan(text: item.time.add(Duration(minutes: max(0, item.status.delay))).compareTo(DateTime.now()) < 0 ? ViewStationPageState.arrivedFrom : ViewStationPageState.arrivesFrom), |
|
|
|
|
|
|
|
TextSpan(text: ' '), |
|
|
|
|
|
|
|
TextSpan(text: item.train.terminus), |
|
|
|
|
|
|
|
if (item.status.delay != 0) ...[ |
|
|
|
|
|
|
|
TextSpan(text: '\n'), |
|
|
|
|
|
|
|
if (item.status.delay.abs() >= 60) ...[ |
|
|
|
|
|
|
|
TextSpan(text: (item.status.delay.abs() ~/ 60).toString()), |
|
|
|
|
|
|
|
TextSpan(text: item.status.delay.abs() >= 120 ? ' ore' : ' oră'), |
|
|
|
|
|
|
|
if (item.status.delay.abs() % 60 != 0) |
|
|
|
|
|
|
|
TextSpan(text: ' și '), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
TextSpan(text: (item.status.delay.abs() % 60).toString()), |
|
|
|
|
|
|
|
TextSpan(text: item.status.delay.abs() > 1 ? ' minute' : ' minut'), |
|
|
|
|
|
|
|
TextSpan(text: ' '), |
|
|
|
|
|
|
|
if (item.status.delay > 0) |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
text: 'întârziere', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
color: Colors.red, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
text: 'mai devreme', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
color: Colors.green, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
TextSpan(text: ' '), |
|
|
|
), |
|
|
|
TextSpan(text: item.train.number,), |
|
|
|
if (item.status.platform != null) |
|
|
|
], |
|
|
|
IntrinsicHeight( |
|
|
|
), |
|
|
|
child: AspectRatio( |
|
|
|
), |
|
|
|
aspectRatio: 1, |
|
|
|
subtitle: Text.rich( |
|
|
|
child: MaterialBadge( |
|
|
|
TextSpan( |
|
|
|
text: item.status.platform!, |
|
|
|
children: [ |
|
|
|
caption: 'Linia', |
|
|
|
TextSpan(text: item.time.compareTo(DateTime.now()) < 0 ? ViewStationPageState.arrivedFrom : ViewStationPageState.arrivesFrom), |
|
|
|
isOnTime: item.status.real && item.status.delay <= 0, |
|
|
|
TextSpan(text: ' '), |
|
|
|
isDelayed: item.status.real && item.status.delay > 0, |
|
|
|
TextSpan(text: item.train.origin), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
|
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
onTap: () => onTrainTapped(item.train.number), |
|
|
|
|
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
Widget buildStationDepartureItem(BuildContext context, StationDeparture item) { |
|
|
|
Widget buildStationDepartureItem(BuildContext context, StationArrDep item) { |
|
|
|
return ListTile( |
|
|
|
return InkWell( |
|
|
|
leading: Text('${item.time.toLocal().hour.toString().padLeft(2, '0')}:${item.time.toLocal().minute.toString().padLeft(2, '0')}'), |
|
|
|
onTap: () => onTrainTapped(item.train.number), |
|
|
|
title: Text.rich( |
|
|
|
child: Row( |
|
|
|
TextSpan( |
|
|
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
|
|
children: [ |
|
|
|
children: [ |
|
|
|
TextSpan( |
|
|
|
Padding( |
|
|
|
text: item.train.rank, |
|
|
|
padding: const EdgeInsets.all(8), |
|
|
|
style: TextStyle( |
|
|
|
child: Column( |
|
|
|
color: item.train.rank.startsWith('IR') ? Color.fromARGB(255, 255, 0, 0) : null, |
|
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
|
|
|
|
|
|
children: [ |
|
|
|
|
|
|
|
Text( |
|
|
|
|
|
|
|
'${item.time.toLocal().hour.toString().padLeft(2, '0')}:${item.time.toLocal().minute.toString().padLeft(2, '0')}', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
fontFeatures: [ |
|
|
|
|
|
|
|
FontFeature.tabularFigures(), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
decoration: item.status.delay != 0 ? TextDecoration.lineThrough : null, |
|
|
|
|
|
|
|
fontSize: item.status.delay != 0 ? 12 : null, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
if (item.status.delay != 0) Builder( |
|
|
|
|
|
|
|
builder: (context) { |
|
|
|
|
|
|
|
final newTime = item.time.add(Duration(minutes: item.status.delay)); |
|
|
|
|
|
|
|
final delay = item.status.delay > 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Text( |
|
|
|
|
|
|
|
'${newTime.toLocal().hour.toString().padLeft(2, '0')}:${newTime.toLocal().minute.toString().padLeft(2, '0')}', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
fontFeatures: [ |
|
|
|
|
|
|
|
FontFeature.tabularFigures(), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
color: delay ? Colors.red : Colors.green, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
Expanded( |
|
|
|
|
|
|
|
child: IgnorePointer( |
|
|
|
|
|
|
|
child: ListTile( |
|
|
|
|
|
|
|
isThreeLine: item.status.delay != 0, |
|
|
|
|
|
|
|
title: Text.rich( |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
children: [ |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
text: item.train.rank, |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
color: item.train.rank.startsWith('IR') ? Color.fromARGB(255, 255, 0, 0) : null, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
TextSpan(text: ' '), |
|
|
|
|
|
|
|
TextSpan(text: item.train.number,), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
subtitle: Text.rich( |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
children: [ |
|
|
|
|
|
|
|
TextSpan(text: item.time.add(Duration(minutes: max(0, item.status.delay))).compareTo(DateTime.now()) < 0 ? ViewStationPageState.departedTo : ViewStationPageState.departsTo), |
|
|
|
|
|
|
|
TextSpan(text: ' '), |
|
|
|
|
|
|
|
TextSpan(text: item.train.terminus), |
|
|
|
|
|
|
|
if (item.status.delay != 0) ...[ |
|
|
|
|
|
|
|
TextSpan(text: '\n'), |
|
|
|
|
|
|
|
if (item.status.delay.abs() >= 60) ...[ |
|
|
|
|
|
|
|
TextSpan(text: (item.status.delay.abs() ~/ 60).toString()), |
|
|
|
|
|
|
|
TextSpan(text: item.status.delay.abs() >= 120 ? ' ore' : ' oră'), |
|
|
|
|
|
|
|
if (item.status.delay.abs() % 60 != 0) |
|
|
|
|
|
|
|
TextSpan(text: ' și '), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
TextSpan(text: (item.status.delay.abs() % 60).toString()), |
|
|
|
|
|
|
|
TextSpan(text: item.status.delay.abs() > 1 ? ' minute' : ' minut'), |
|
|
|
|
|
|
|
TextSpan(text: ' '), |
|
|
|
|
|
|
|
if (item.status.delay > 0) |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
text: 'întârziere', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
color: Colors.red, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
TextSpan( |
|
|
|
|
|
|
|
text: 'mai devreme', |
|
|
|
|
|
|
|
style: TextStyle( |
|
|
|
|
|
|
|
inherit: true, |
|
|
|
|
|
|
|
color: Colors.green, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
TextSpan(text: ' '), |
|
|
|
), |
|
|
|
TextSpan(text: item.train.number,), |
|
|
|
if (item.status.platform != null) |
|
|
|
], |
|
|
|
IntrinsicHeight( |
|
|
|
), |
|
|
|
child: AspectRatio( |
|
|
|
), |
|
|
|
aspectRatio: 1, |
|
|
|
subtitle: Text.rich( |
|
|
|
child: MaterialBadge( |
|
|
|
TextSpan( |
|
|
|
text: item.status.platform!, |
|
|
|
children: [ |
|
|
|
caption: 'Linia', |
|
|
|
TextSpan(text: item.time.compareTo(DateTime.now()) < 0 ? ViewStationPageState.departedTo : ViewStationPageState.departsTo), |
|
|
|
isOnTime: item.status.real && item.status.delay <= 0, |
|
|
|
TextSpan(text: ' '), |
|
|
|
isDelayed: item.status.real && item.status.delay > 0, |
|
|
|
TextSpan(text: item.train.destination), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
|
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
onTap: () => onTrainTapped(item.train.number), |
|
|
|
|
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|