Browse Source

v2.6.0

Added ability to view yesterday data for trains that didn't depart yet today.
Fixed iOS status bar color.
tmp v2.6.0
Dan Cojocaru 3 years ago
parent
commit
2b6c073bf7
  1. 4
      CHANGELOG.TXT
  2. 3
      ios/Runner.xcodeproj/project.pbxproj
  3. 7
      lib/api/train_data.dart
  4. 8
      lib/components/refresh_future_builder.dart
  5. 2
      lib/pages/station_arrdep_page/view_station/view_station.dart
  6. 2
      lib/pages/station_arrdep_page/view_station/view_station_cupertino.dart
  7. 2
      lib/pages/station_arrdep_page/view_station/view_station_material.dart
  8. 27
      lib/pages/train_info_page/view_train/train_info.dart
  9. 52
      lib/pages/train_info_page/view_train/train_info_cupertino.dart
  10. 6
      lib/pages/train_info_page/view_train/train_info_cupertino_DisplayTrainStation.dart
  11. 48
      lib/pages/train_info_page/view_train/train_info_material.dart
  12. 7
      pubspec.lock
  13. 3
      pubspec.yaml

4
CHANGELOG.TXT

@ -1,3 +1,7 @@
v2.6.0
Added ability to view yesterday data for trains that didn't depart yet today.
Fixed iOS status bar color.
v2.5.0
Initial arrivals/departures support

3
ios/Runner.xcodeproj/project.pbxproj

@ -288,6 +288,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 2.0.7;
DEVELOPMENT_TEAM = NF9A3KMT8Q;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -417,6 +418,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 2.0.7;
DEVELOPMENT_TEAM = NF9A3KMT8Q;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -440,6 +442,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 2.0.7;
DEVELOPMENT_TEAM = NF9A3KMT8Q;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (

7
lib/api/train_data.dart

@ -2,7 +2,10 @@ import 'package:http/http.dart' as http;
import 'package:info_tren/api/common.dart';
import 'package:info_tren/models/train_data.dart';
Future<TrainData> getTrain(String trainNumber) async {
final response = await http.get(Uri.https(authority, 'v2/train/$trainNumber'));
Future<TrainData> getTrain(String trainNumber, {DateTime? date}) async {
date ??= DateTime.now();
final response = await http.get(Uri.https(authority, 'v2/train/$trainNumber', {
'date': date.toIso8601String(),
}),);
return trainDataFromJson(response.body);
}

8
lib/components/refresh_future_builder.dart

@ -3,7 +3,7 @@ import 'package:flutter/widgets.dart';
class RefreshFutureBuilder<T> extends StatefulWidget {
final Future<T> Function()? futureCreator;
final T? initialData;
final Widget Function(BuildContext context, Future Function() refresh, RefreshFutureBuilderSnapshot<T> snapshot) builder;
final Widget Function(BuildContext context, Future Function() refresh, Future Function(Future<T> Function()) replaceFuture, RefreshFutureBuilderSnapshot<T> snapshot) builder;
const RefreshFutureBuilder({ Key? key, this.futureCreator, this.initialData, required this.builder }) : super(key: key);
@ -84,6 +84,11 @@ class _RefreshFutureBuilderState<T> extends State<RefreshFutureBuilder<T>> {
}
}
Future replaceFutureCreator(Future<T> Function() newFutureCreator) {
futureCreator = newFutureCreator;
return runFuture();
}
@override
void dispose() {
_disposed = true;
@ -95,6 +100,7 @@ class _RefreshFutureBuilderState<T> extends State<RefreshFutureBuilder<T>> {
return widget.builder(
context,
runFuture,
replaceFutureCreator,
snapshot,
);
}

2
lib/pages/station_arrdep_page/view_station/view_station.dart

@ -60,7 +60,7 @@ abstract class ViewStationPageState extends State<ViewStationPage> {
futureCreator = () => getStationData(stationName);
}
Widget buildContent(BuildContext context, Future Function() refresh, RefreshFutureBuilderSnapshot<StationData> snapshot);
Widget buildContent(BuildContext context, Future Function() refresh, Future Function(Future<StationData> Function() newFutureBuilder) _, RefreshFutureBuilderSnapshot<StationData> snapshot);
Widget buildStationArrivalItem(BuildContext context, StationArrival item);
Widget buildStationDepartureItem(BuildContext context, StationDeparture item);

2
lib/pages/station_arrdep_page/view_station/view_station_cupertino.dart

@ -8,7 +8,7 @@ import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.da
class ViewStationPageStateCupertino extends ViewStationPageState {
@override
Widget buildContent(BuildContext context, Future Function() refresh, RefreshFutureBuilderSnapshot<StationData> snapshot) {
Widget buildContent(BuildContext context, Future Function() refresh, Future Function(Future<StationData> Function()) _, RefreshFutureBuilderSnapshot<StationData> snapshot) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(snapshot.hasData ? snapshot.data!.stationName : stationName),

2
lib/pages/station_arrdep_page/view_station/view_station_material.dart

@ -7,7 +7,7 @@ import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.da
class ViewStationPageStateMaterial extends ViewStationPageState {
@override
Widget buildContent(BuildContext context, Future Function() refresh, RefreshFutureBuilderSnapshot<StationData> snapshot) {
Widget buildContent(BuildContext context, Future Function() refresh, Future Function(Future<StationData> Function()) _, RefreshFutureBuilderSnapshot<StationData> snapshot) {
return Scaffold(
appBar: AppBar(
title: Text(snapshot.hasData ? snapshot.data!.stationName : stationName),

27
lib/pages/train_info_page/view_train/train_info.dart

@ -25,7 +25,10 @@ class TrainInfo extends StatelessWidget {
return RefreshFutureBuilder<TrainData>(
futureCreator: () => getTrain(trainNumber),
builder: (context, refresh, snapshot) {
builder: (context, refresh, replaceFutureBuilder, snapshot) {
void onViewYesterdayTrain() {
replaceFutureBuilder(() => getTrain(trainNumber, date: DateTime.now().subtract(const Duration(days: 1))));
}
switch (uiDesign) {
case UiDesign.MATERIAL:
@ -36,7 +39,11 @@ class TrainInfo extends StatelessWidget {
return TrainInfoErrorMaterial(title: '$trainNumber - Error', error: snapshot.error!, refresh: refresh,);
}
return TrainInfoMaterial(trainData: snapshot.data!, refresh: refresh,);
return TrainInfoMaterial(
trainData: snapshot.data!,
refresh: refresh,
onViewYesterdayTrain: onViewYesterdayTrain,
);
case UiDesign.CUPERTINO:
if ([RefreshFutureBuilderState.none, RefreshFutureBuilderState.waiting].contains(snapshot.state)) {
return TrainInfoLoadingCupertino(title: trainNumber.toString(), loadingText: "Se încarcă...",);
@ -45,7 +52,12 @@ class TrainInfo extends StatelessWidget {
return TrainInfoErrorCupertino(title: '$trainNumber - Error', error: snapshot.error!, refresh: refresh,);
}
return TrainInfoCupertino(trainData: snapshot.data!, refresh: refresh, isRefreshing: snapshot.state == RefreshFutureBuilderState.refreshing,);
return TrainInfoCupertino(
trainData: snapshot.data!,
refresh: refresh,
isRefreshing: snapshot.state == RefreshFutureBuilderState.refreshing,
onViewYesterdayTrain: onViewYesterdayTrain,
);
default:
throw UnmatchedUiDesignException(uiDesign);
}
@ -68,3 +80,12 @@ abstract class TrainInfoError extends StatelessWidget {
TrainInfoError({required this.title, required this.error, this.refresh});
}
abstract class DisplayTrainYesterdayWarningCommon extends StatelessWidget {
static const trainDidNotDepart = 'Acest tren nu a plecat încă din prima gară.';
static const seeYesterdayTrain = 'Apasă aici pentru a vedea trenul care a plecat ieri.';
final void Function() onViewYesterdayTrain;
DisplayTrainYesterdayWarningCommon(this.onViewYesterdayTrain);
}

52
lib/pages/train_info_page/view_train/train_info_cupertino.dart

@ -1,6 +1,7 @@
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:info_tren/components/cupertino_divider.dart';
import 'package:info_tren/components/sliver_persistent_header_padding.dart';
import 'package:info_tren/models/train_data.dart' hide State;
@ -71,11 +72,13 @@ class TrainInfoCupertino extends StatelessWidget {
final TrainData trainData;
final Future Function()? refresh;
final bool? isRefreshing;
final void Function()? onViewYesterdayTrain;
TrainInfoCupertino({
required this.trainData,
this.refresh,
this.isRefreshing,
this.onViewYesterdayTrain,
});
@override
@ -259,6 +262,16 @@ class TrainInfoCupertino extends StatelessWidget {
color: FOREGROUND_WHITE,
),
),
if (onViewYesterdayTrain != null && trainData.stations.first.departure!.scheduleTime.compareTo(DateTime.now()) > 0) ...[
SliverToBoxAdapter(
child: DisplayTrainYesterdayWarningCupertino(onViewYesterdayTrain!),
),
SliverToBoxAdapter(
child: CupertinoDivider(
color: FOREGROUND_WHITE,
),
),
],
DisplayTrainStations(
trainData: trainData,
),
@ -586,7 +599,7 @@ class DisplayTrainLastInfo extends StatelessWidget {
style:
CupertinoTheme.of(context).textTheme.textStyle.copyWith(
fontSize: 12,
color: CupertinoColors.activeGreen,
color: CupertinoColors.systemGreen,
),
);
}
@ -753,8 +766,8 @@ class DisplayTrainDestination extends StatelessWidget {
text: '$arrivalWithDelayString',
style: TextStyle(
color: delay > 0
? CupertinoColors.destructiveRed
: CupertinoColors.activeGreen,
? CupertinoColors.systemRed
: CupertinoColors.systemGreen,
),
),
]
@ -881,6 +894,39 @@ class DisplayTrainRouteDuration extends StatelessWidget {
}
}
class DisplayTrainYesterdayWarningCupertino extends DisplayTrainYesterdayWarningCommon {
DisplayTrainYesterdayWarningCupertino(void Function() onViewYesterdayTrain) : super(onViewYesterdayTrain);
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text.rich(
TextSpan(
children: [
TextSpan(text: DisplayTrainYesterdayWarningCommon.trainDidNotDepart,),
TextSpan(text: '\n'),
TextSpan(
text: DisplayTrainYesterdayWarningCommon.seeYesterdayTrain,
style: TextStyle(
color: CupertinoColors.link,
),
recognizer: TapGestureRecognizer()
..onTap = onViewYesterdayTrain,
),
],
),
textAlign: TextAlign.center,
),
),
],
);
}
}
class DisplayTrainStations extends StatelessWidget {
final TrainData trainData;

6
lib/pages/train_info_page/view_train/train_info_cupertino_DisplayTrainStation.dart

@ -297,7 +297,7 @@ class ArrivalTime extends StatelessWidget {
Text(
"${newDate.hour.toString().padLeft(2, '0')}:${newDate.minute.toString().padLeft(2, '0')}",
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(
color: CupertinoColors.activeGreen,
color: CupertinoColors.systemGreen,
),
),
],
@ -430,7 +430,7 @@ class DepartureTime extends StatelessWidget {
Text(
"${newDate.hour.toString().padLeft(2, '0')}:${newDate.minute.toString().padLeft(2, '0')}",
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(
color: CupertinoColors.activeGreen,
color: CupertinoColors.systemGreen,
),
),
],
@ -472,7 +472,7 @@ class Delay extends StatelessWidget {
return Text(
"${-delay} ${delay == -1 ? 'minut' : 'minute'} mai devreme",
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(
color: CupertinoColors.activeGreen,
color: CupertinoColors.systemGreen,
fontSize: 14,
fontStyle: FontStyle.italic,
),

48
lib/pages/train_info_page/view_train/train_info_material.dart

@ -1,3 +1,4 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:info_tren/components/slim_app_bar.dart';
import 'package:info_tren/models/train_data.dart' hide State;
@ -60,8 +61,9 @@ bool isSmallScreen(BuildContext context) => MediaQuery.of(context).size.height <
class TrainInfoMaterial extends StatelessWidget {
final TrainData trainData;
final Future Function()? refresh;
final void Function()? onViewYesterdayTrain;
TrainInfoMaterial({required this.trainData, this.refresh,});
TrainInfoMaterial({required this.trainData, this.refresh, this.onViewYesterdayTrain,});
@override
Widget build(BuildContext context) {
@ -144,6 +146,17 @@ class TrainInfoMaterial extends StatelessWidget {
height: isSmallScreen(context) ? 8 : 16,
),
),
if (onViewYesterdayTrain != null && trainData.stations.first.departure!.scheduleTime.compareTo(DateTime.now()) > 0) ...[
SliverToBoxAdapter(
child: DisplayTrainYesterdayWarningMaterial(onViewYesterdayTrain!),
),
SliverToBoxAdapter(
child: Divider(
color: Colors.white70,
height: isSmallScreen(context) ? 8 : 16,
),
),
],
DisplayTrainStations(
trainData: trainData,
),
@ -672,6 +685,39 @@ class DisplayTrainRouteDuration extends StatelessWidget {
}
}
class DisplayTrainYesterdayWarningMaterial extends DisplayTrainYesterdayWarningCommon {
DisplayTrainYesterdayWarningMaterial(void Function() onViewYesterdayTrain) : super(onViewYesterdayTrain);
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text.rich(
TextSpan(
children: [
TextSpan(text: DisplayTrainYesterdayWarningCommon.trainDidNotDepart,),
TextSpan(text: '\n'),
TextSpan(
text: DisplayTrainYesterdayWarningCommon.seeYesterdayTrain,
style: TextStyle(
color: Colors.blue,
),
recognizer: TapGestureRecognizer()
..onTap = onViewYesterdayTrain,
),
],
),
textAlign: TextAlign.center,
),
),
],
);
}
}
class DisplayTrainStations extends StatelessWidget {
final TrainData trainData;
DisplayTrainStations({required this.trainData});

7
pubspec.lock

@ -382,6 +382,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
sprintf:
dependency: "direct main"
description:
name: sprintf
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0"
stack_trace:
dependency: transitive
description:

3
pubspec.yaml

@ -11,7 +11,7 @@ description: O aplicație de vizualizare a datelor puse la dispoziție de Inform
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 2.5.0
version: 2.6.0
environment:
sdk: ">=2.12.0 <3.0.0"
@ -27,6 +27,7 @@ dependencies:
http: ^0.13.0
cupertino_icons: ^0.1.2
tuple: ^2.0.0
sprintf: ^6.0.0
flutter_redux: ^0.8.2
dev_dependencies:

Loading…
Cancel
Save