Browse Source

Switch train suggestions to online data

master v2.7.1
Kenneth Bruen 2 years ago
parent
commit
9436b7964a
Signed by: kbruen
GPG Key ID: C1980A470C3EE5B1
  1. 26
      .metadata
  2. 4
      CHANGELOG.TXT
  3. 1
      assets/lines/atc.json
  4. 1
      assets/lines/cfr.json
  5. 6
      assets/lines/files.txt
  6. 1
      assets/lines/interregional.json
  7. 1
      assets/lines/rc.json
  8. 1
      assets/lines/st.json
  9. 1
      assets/lines/tfc.json
  10. 11
      lib/api/trains.dart
  11. 1
      lib/components/loading/loading_cupertino.dart
  12. 112
      lib/components/select_train_suggestions/select_train_suggestions.dart
  13. 6
      lib/components/select_train_suggestions/select_train_suggestions_cupertino.dart
  14. 6
      lib/components/select_train_suggestions/select_train_suggestions_material.dart
  15. 2
      lib/models/stations_result.dart
  16. 42
      lib/models/train_operator_lines.dart
  17. 42
      lib/models/train_operator_lines.g.dart
  18. 19
      lib/models/trains_result.dart
  19. 20
      lib/models/trains_result.g.dart
  20. 7
      lib/pages/station_arrdep_page/select_station/select_station.dart
  21. 54
      lib/pages/train_info_page/select_train/select_train.dart
  22. 1
      linux/.gitignore
  23. 138
      linux/CMakeLists.txt
  24. 88
      linux/flutter/CMakeLists.txt
  25. 11
      linux/flutter/generated_plugin_registrant.cc
  26. 15
      linux/flutter/generated_plugin_registrant.h
  27. 23
      linux/flutter/generated_plugins.cmake
  28. 6
      linux/main.cc
  29. 104
      linux/my_application.cc
  30. 18
      linux/my_application.h
  31. 123
      pubspec.lock
  32. 4
      pubspec.yaml
  33. 30
      test/widget_test.dart

26
.metadata

@ -1,10 +1,30 @@
# This file tracks properties of this Flutter project. # This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc. # Used by Flutter tool to assess capabilities and perform upgrades etc.
# #
# This file should be version controlled and should not be manually edited. # This file should be version controlled.
version: version:
revision: b712a172f9694745f50505c93340883493b505e5 revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
channel: stable channel: beta
project_type: app project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
- platform: linux
create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

4
CHANGELOG.TXT

@ -1,3 +1,7 @@
v2.7.1
Switched train suggestions list from hardcoded data to server data.
Added Linux build files.
v2.7.0 v2.7.0
Changed domain name for server providing the data. Changed domain name for server providing the data.
Changed bundle name accordingly. Changed bundle name accordingly.

1
assets/lines/atc.json

@ -1 +0,0 @@
{"short_name":"ATC","operator":"Astra Trans Carpatic","data_export":"20171212","valabil":{"de_la":"20171210","pana_la":"20181208"},"versiune":"1","trenuri":[{"rang":"IR","numar":"15510","numar_intern":15510},{"rang":"IR","numar":"15511","numar_intern":15511},{"rang":"IR","numar":"15512","numar_intern":15512},{"rang":"IR","numar":"15513*","numar_intern":15513},{"rang":"IR","numar":"15513","numar_intern":15513},{"rang":"IR","numar":"15514","numar_intern":15514},{"rang":"IR","numar":"15514","numar_intern":15514},{"rang":"IR","numar":"15516","numar_intern":15516},{"rang":"IR","numar":"15520","numar_intern":15520},{"rang":"IR","numar":"15521*","numar_intern":15521},{"rang":"IR","numar":"15521","numar_intern":15521},{"rang":"IR","numar":"15522","numar_intern":15522},{"rang":"IR","numar":"15522","numar_intern":15522},{"rang":"IR","numar":"15523","numar_intern":15523},{"rang":"IR","numar":"15523","numar_intern":15523},{"rang":"IR","numar":"15527","numar_intern":15527},{"rang":"IR","numar":"15528","numar_intern":15528},{"rang":"IR","numar":"15529","numar_intern":15529},{"rang":"IR","numar":"15531","numar_intern":15531},{"rang":"IR","numar":"15532","numar_intern":15532},{"rang":"IR","numar":"15533","numar_intern":15533},{"rang":"IR","numar":"15533e","numar_intern":15533},{"rang":"IR","numar":"15534","numar_intern":15534},{"rang":"IR","numar":"15535","numar_intern":15535},{"rang":"IR","numar":"15536","numar_intern":15536},{"rang":"IR","numar":"15537-2","numar_intern":15537},{"rang":"IR","numar":"15538","numar_intern":15538},{"rang":"IR","numar":"15540","numar_intern":15540},{"rang":"IR","numar":"15541","numar_intern":15541},{"rang":"IR","numar":"15541","numar_intern":15541},{"rang":"IR","numar":"15542","numar_intern":15542},{"rang":"IR","numar":"15542","numar_intern":15542},{"rang":"IR","numar":"15543","numar_intern":15543},{"rang":"IR","numar":"15544","numar_intern":15544},{"rang":"IR","numar":"15545","numar_intern":15545},{"rang":"IR","numar":"15546*","numar_intern":15546},{"rang":"IR","numar":"15546","numar_intern":15546},{"rang":"IR","numar":"15547","numar_intern":15547},{"rang":"IR","numar":"15548","numar_intern":15548},{"rang":"IR","numar":"15549*","numar_intern":15549},{"rang":"IR","numar":"15549b","numar_intern":15549},{"rang":"IR","numar":"15551","numar_intern":15551},{"rang":"IR","numar":"15552","numar_intern":15552},{"rang":"IR","numar":"15553","numar_intern":15553},{"rang":"IR","numar":"15581","numar_intern":15581},{"rang":"IR","numar":"15582","numar_intern":15582},{"rang":"IR","numar":"15582***","numar_intern":15582},{"rang":"IR","numar":"15583","numar_intern":15583},{"rang":"IR","numar":"15590","numar_intern":15590},{"rang":"IR","numar":"15591","numar_intern":15591},{"rang":"IR","numar":"15592","numar_intern":15592},{"rang":"IR","numar":"15593","numar_intern":15593},{"rang":"R","numar":"*P18801","numar_intern":null},{"rang":"IR","numar":"*15546","numar_intern":null},{"rang":"R","numar":"**P18801","numar_intern":null},{"rang":"IR","numar":"*15591","numar_intern":null},{"rang":"R","numar":"**P18800","numar_intern":null},{"rang":"IR","numar":"15593","numar_intern":15593},{"rang":"IR","numar":"15594","numar_intern":15594},{"rang":"IR","numar":"15595-2","numar_intern":15595},{"rang":"R","numar":"18800","numar_intern":18800},{"rang":"R","numar":"18801","numar_intern":18801},{"rang":"IR","numar":"18826","numar_intern":18826},{"rang":"IR","numar":"18851","numar_intern":18851},{"rang":"IR","numar":"18852","numar_intern":18852}]}

1
assets/lines/cfr.json

File diff suppressed because one or more lines are too long

6
assets/lines/files.txt

@ -1,6 +0,0 @@
atc.json
cfr.json
interregional.json
rc.json
st.json
tfc.json

1
assets/lines/interregional.json

File diff suppressed because one or more lines are too long

1
assets/lines/rc.json

File diff suppressed because one or more lines are too long

1
assets/lines/st.json

@ -1 +0,0 @@
{"short_name":"Softrans","operator":"Softrans S.R.L.","data_export":"20181212","valabil":{"de_la":"20181209","pana_la":"20191214"},"versiune":"1","trenuri":[{"rang":"IR","numar":"15931-2","numar_intern":15931},{"rang":"IR","numar":"15932","numar_intern":15932},{"rang":"IR","numar":"15933-2","numar_intern":15933},{"rang":"IR","numar":"15934","numar_intern":15934},{"rang":"IR","numar":"15935-2","numar_intern":15935},{"rang":"IR","numar":"15936","numar_intern":15936},{"rang":"IR","numar":"15982","numar_intern":15982},{"rang":"IR","numar":"15984","numar_intern":15984}]}

1
assets/lines/tfc.json

File diff suppressed because one or more lines are too long

11
lib/api/trains.dart

@ -0,0 +1,11 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:info_tren/api/common.dart';
import 'package:info_tren/models/trains_result.dart';
Future<List<TrainsResult>> get trains async {
final result = await http.get(Uri.https(authority, 'v2/trains'));
final data = jsonDecode(result.body) as List<dynamic>;
return data.map((e) => TrainsResult.fromJson(e)).toList(growable: false,);
}

1
lib/components/loading/loading_cupertino.dart

@ -1,5 +1,4 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:info_tren/components/loading/loading.dart'; import 'package:info_tren/components/loading/loading.dart';
class LoadingCupertino extends LoadingCommon { class LoadingCupertino extends LoadingCommon {

112
lib/components/select_train_suggestions/select_train_suggestions.dart

@ -3,17 +3,18 @@ import 'dart:convert';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:info_tren/components/select_train_suggestions/select_train_suggestions_cupertino.dart'; import 'package:info_tren/components/select_train_suggestions/select_train_suggestions_cupertino.dart';
import 'package:info_tren/components/select_train_suggestions/select_train_suggestions_material.dart'; import 'package:info_tren/components/select_train_suggestions/select_train_suggestions_material.dart';
import 'package:info_tren/models/train_operator_lines.dart'; import 'package:info_tren/models/trains_result.dart';
import 'package:info_tren/models/ui_design.dart'; import 'package:info_tren/models/ui_design.dart';
import 'package:info_tren/utils/default_ui_design.dart'; import 'package:info_tren/utils/default_ui_design.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class SelectTrainSuggestions extends StatefulWidget { class SelectTrainSuggestions extends StatefulWidget {
final UiDesign? uiDesign; final UiDesign? uiDesign;
final String userInput; final List<TrainsResult> choices;
final String? currentInput;
final void Function(String trainNumber) onTrainSelected; final void Function(String trainNumber) onTrainSelected;
const SelectTrainSuggestions({ Key? key, required this.uiDesign, required this.userInput, required this.onTrainSelected }) : super(key: key); const SelectTrainSuggestions({Key? key, required this.uiDesign, required this.choices, this.currentInput, required this.onTrainSelected }) : super(key: key);
@override @override
SelectTrainSuggestionsState createState() { SelectTrainSuggestionsState createState() {
@ -30,76 +31,15 @@ class SelectTrainSuggestions extends StatefulWidget {
} }
abstract class SelectTrainSuggestionsState extends State<SelectTrainSuggestions> { abstract class SelectTrainSuggestionsState extends State<SelectTrainSuggestions> {
late String userInput; String getUseCurrentInputWidgetText(String currentInput) => 'Caută trenul cu numărul ${widget.currentInput}';
List<TrainOperatorLines> operators = [];
Future loadOperators(BuildContext context) async {
operators = [];
final operatorsString = await DefaultAssetBundle.of(context).loadString("assets/lines/files.txt");
final operatorsFilesList = operatorsString.split("\n");
final decoder = JsonDecoder();
for (final operatorFile in operatorsFilesList) {
final operatorString = await DefaultAssetBundle.of(context).loadString("assets/lines/$operatorFile");
final operatorData = decoder.convert(operatorString);
final _operator = TrainOperatorLines.fromJson(operatorData);
operators.add(_operator);
}
}
@override
void initState() {
super.initState();
userInput = widget.userInput;
loadOperators(context).then((_) {
setState(() {});
});
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (userInput != widget.userInput) {
setState(() {
userInput = widget.userInput;
});
}
}
String getUseCurrentInputWidgetText(String currentInput) => 'Caută trenul cu numărul $currentInput';
Widget getUseCurrentInputWidget(String currentInput, void Function(String) onTrainSelected); Widget getUseCurrentInputWidget(String currentInput, void Function(String) onTrainSelected);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var sliversTuple = operators.map( var slivers = widget.choices.map((c) => c.company).toSet().map((operator) => OperatorAutocompleteSliver(
(op) => Tuple2(
getFilteredLines(op, userInput),
op.operator,
)
).where((tuple) => tuple.item1.isNotEmpty).toList();
if (userInput.isNotEmpty) sliversTuple.sort((a, b) {
final aTrain = a.item1.first;
final bTrain = b.item1.first;
final inputAsRegExp = RegExp(userInput);
final matchOnA = inputAsRegExp.firstMatch(aTrain.number)!;
final matchOnB = inputAsRegExp.firstMatch(bTrain.number)!;
if (matchOnA.start != matchOnB.start) return matchOnA.start - matchOnB.start;
if (aTrain.number.length != bTrain.number.length) return aTrain.number.length - bTrain.number.length;
return aTrain.number.compareTo(bTrain.number);
});
var slivers = sliversTuple.map((tuple) => OperatorAutocompleteSliver(
uiDesign: widget.uiDesign, uiDesign: widget.uiDesign,
operatorName: tuple.item2, operatorName: operator,
trains: tuple.item1, trains: widget.choices.where((c) => c.company == operator).toList(),
onTrainSelected: widget.onTrainSelected, onTrainSelected: widget.onTrainSelected,
)).toList(); )).toList();
@ -107,7 +47,7 @@ abstract class SelectTrainSuggestionsState extends State<SelectTrainSuggestions>
slivers: <Widget>[ slivers: <Widget>[
...slivers, ...slivers,
SliverToBoxAdapter( SliverToBoxAdapter(
child: int.tryParse(userInput) != null ? getUseCurrentInputWidget(userInput, widget.onTrainSelected) : Container(), child: widget.currentInput != null && int.tryParse(widget.currentInput!) != null ? getUseCurrentInputWidget(widget.currentInput!, widget.onTrainSelected) : Container(),
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Container( child: Container(
@ -117,43 +57,17 @@ abstract class SelectTrainSuggestionsState extends State<SelectTrainSuggestions>
], ],
); );
} }
List<TrainOperatorTrainDescription> getFilteredLines(TrainOperatorLines _operator, String currentInput) {
if (currentInput.isNotEmpty) {
final filteredLines = _operator.trains
.where((elem) => elem.number.contains(currentInput))
.toList();
filteredLines.sort((a, b) {
final inputAsRegExp = RegExp(currentInput);
final matchOnA = inputAsRegExp.firstMatch(a.number)!;
final matchOnB = inputAsRegExp.firstMatch(b.number)!;
if (matchOnA.start != matchOnB.start) return matchOnA.start - matchOnB.start;
if (a.number.length != b.number.length) return a.number.length - b.number.length;
return a.number.compareTo(b.number);
});
return filteredLines;
}
else {
return _operator.trains;
}
}
} }
class OperatorAutocompleteSliver extends StatelessWidget { class OperatorAutocompleteSliver extends StatelessWidget {
final UiDesign? uiDesign; final UiDesign? uiDesign;
final String operatorName; final String operatorName;
final List<TrainOperatorTrainDescription> trains; final List<TrainsResult> trains;
final void Function(String) onTrainSelected; final void Function(String) onTrainSelected;
const OperatorAutocompleteSliver({ Key? key, required this.uiDesign, required this.operatorName, required this.trains, required this.onTrainSelected }) : super(key: key); const OperatorAutocompleteSliver({ Key? key, required this.uiDesign, required this.operatorName, required this.trains, required this.onTrainSelected }) : super(key: key);
Widget mapTrainToItem(TrainOperatorTrainDescription train) { Widget mapTrainToItem(TrainsResult train) {
final uiDesign = this.uiDesign ?? defaultUiDesign; final uiDesign = this.uiDesign ?? defaultUiDesign;
switch (uiDesign) { switch (uiDesign) {
case UiDesign.MATERIAL: case UiDesign.MATERIAL:
@ -182,7 +96,7 @@ class OperatorAutocompleteSliver extends StatelessWidget {
return SliverPrototypeExtentList( return SliverPrototypeExtentList(
prototypeItem: Column( prototypeItem: Column(
children: <Widget>[ children: <Widget>[
mapTrainToItem(TrainOperatorTrainDescription()), mapTrainToItem(TrainsResult(company: 'Company', number: '123', rank: 'R')),
], ],
), ),
delegate: SliverChildBuilderDelegate( delegate: SliverChildBuilderDelegate(
@ -202,7 +116,7 @@ class OperatorAutocompleteSliver extends StatelessWidget {
abstract class OperatorAutocompleteTile extends StatelessWidget { abstract class OperatorAutocompleteTile extends StatelessWidget {
final String operatorName; final String operatorName;
final TrainOperatorTrainDescription train; final TrainsResult train;
final void Function(String) onTrainSelected; final void Function(String) onTrainSelected;
const OperatorAutocompleteTile({ Key? key, required this.onTrainSelected, required this.operatorName, required this.train }) : super(key: key); const OperatorAutocompleteTile({ Key? key, required this.onTrainSelected, required this.operatorName, required this.train }) : super(key: key);

6
lib/components/select_train_suggestions/select_train_suggestions_cupertino.dart

@ -1,7 +1,7 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:info_tren/components/cupertino_divider.dart'; import 'package:info_tren/components/cupertino_divider.dart';
import 'package:info_tren/components/select_train_suggestions/select_train_suggestions.dart'; import 'package:info_tren/components/select_train_suggestions/select_train_suggestions.dart';
import 'package:info_tren/models/train_operator_lines.dart'; import 'package:info_tren/models/trains_result.dart';
class SelectTrainSuggestionsStateCupertino extends SelectTrainSuggestionsState { class SelectTrainSuggestionsStateCupertino extends SelectTrainSuggestionsState {
@override @override
@ -32,7 +32,7 @@ class OperatorAutocompleteTileCupertino extends OperatorAutocompleteTile {
Key? key, Key? key,
required String operatorName, required String operatorName,
required void Function(String) onTrainSelected, required void Function(String) onTrainSelected,
required TrainOperatorTrainDescription train required TrainsResult train
}): super( }): super(
onTrainSelected: onTrainSelected, onTrainSelected: onTrainSelected,
operatorName: operatorName, operatorName: operatorName,
@ -63,7 +63,7 @@ class OperatorAutocompleteTileCupertino extends OperatorAutocompleteTile {
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
Text( Text(
"${train.rang} ${train.number}", "${train.rank} ${train.number}",
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
], ],

6
lib/components/select_train_suggestions/select_train_suggestions_material.dart

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:info_tren/components/select_train_suggestions/select_train_suggestions.dart'; import 'package:info_tren/components/select_train_suggestions/select_train_suggestions.dart';
import 'package:info_tren/models/train_operator_lines.dart'; import 'package:info_tren/models/trains_result.dart';
class SelectTrainSuggestionsStateMaterial extends SelectTrainSuggestionsState { class SelectTrainSuggestionsStateMaterial extends SelectTrainSuggestionsState {
@override @override
@ -25,7 +25,7 @@ class OperatorAutocompleteTileMaterial extends OperatorAutocompleteTile {
Key? key, Key? key,
required String operatorName, required String operatorName,
required void Function(String) onTrainSelected, required void Function(String) onTrainSelected,
required TrainOperatorTrainDescription train required TrainsResult train
}): super( }): super(
onTrainSelected: onTrainSelected, onTrainSelected: onTrainSelected,
operatorName: operatorName, operatorName: operatorName,
@ -37,7 +37,7 @@ class OperatorAutocompleteTileMaterial extends OperatorAutocompleteTile {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListTile( return ListTile(
dense: true, dense: true,
title: Text("${train.rang} ${train.number}"), title: Text("${train.rank} ${train.number}"),
subtitle: Text(operatorName), subtitle: Text(operatorName),
onTap: () { onTap: () {
onTrainSelected(train.number); onTrainSelected(train.number);

2
lib/models/stations_result.dart

@ -11,4 +11,4 @@ class StationsResult {
factory StationsResult.fromJson(Map<String, dynamic> json) => _$StationsResultFromJson(json); factory StationsResult.fromJson(Map<String, dynamic> json) => _$StationsResultFromJson(json);
Map<String, dynamic> toJson() => _$StationsResultToJson(this); Map<String, dynamic> toJson() => _$StationsResultToJson(this);
} }

42
lib/models/train_operator_lines.dart

@ -1,42 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
part 'train_operator_lines.g.dart';
@JsonSerializable()
class TrainOperatorLines {
@JsonKey(name: "short_name")
final String shortName;
final String operator;
@JsonKey(name: "versiune")
final String version;
@JsonKey(name: "trenuri")
final List<TrainOperatorTrainDescription> trains;
TrainOperatorLines({
required this.operator,
this.shortName = "",
required this.version,
required this.trains,
});
factory TrainOperatorLines.fromJson(Map<String, dynamic> json) => _$TrainOperatorLinesFromJson(json);
Map<String, dynamic> toJson() => _$TrainOperatorLinesToJson(this);
}
@JsonSerializable()
class TrainOperatorTrainDescription {
final String rang;
@JsonKey(name: "numar")
final String number;
@JsonKey(name: "numar_intern")
final int internalNumber;
TrainOperatorTrainDescription({
this.number = '',
this.rang = '',
this.internalNumber = 0,
});
factory TrainOperatorTrainDescription.fromJson(Map<String, dynamic> json) => _$TrainOperatorTrainDescriptionFromJson(json);
Map<String, dynamic> toJson() => _$TrainOperatorTrainDescriptionToJson(this);
}

42
lib/models/train_operator_lines.g.dart

@ -1,42 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'train_operator_lines.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
TrainOperatorLines _$TrainOperatorLinesFromJson(Map<String, dynamic> json) =>
TrainOperatorLines(
operator: json['operator'] as String,
shortName: json['short_name'] as String? ?? "",
version: json['versiune'] as String,
trains: (json['trenuri'] as List<dynamic>)
.map((e) =>
TrainOperatorTrainDescription.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$TrainOperatorLinesToJson(TrainOperatorLines instance) =>
<String, dynamic>{
'short_name': instance.shortName,
'operator': instance.operator,
'versiune': instance.version,
'trenuri': instance.trains,
};
TrainOperatorTrainDescription _$TrainOperatorTrainDescriptionFromJson(
Map<String, dynamic> json) =>
TrainOperatorTrainDescription(
number: json['numar'] as String? ?? '',
rang: json['rang'] as String? ?? '',
internalNumber: json['numar_intern'] as int? ?? 0,
);
Map<String, dynamic> _$TrainOperatorTrainDescriptionToJson(
TrainOperatorTrainDescription instance) =>
<String, dynamic>{
'rang': instance.rang,
'numar': instance.number,
'numar_intern': instance.internalNumber,
};

19
lib/models/trains_result.dart

@ -0,0 +1,19 @@
import 'package:json_annotation/json_annotation.dart';
part 'trains_result.g.dart';
@JsonSerializable()
class TrainsResult {
final String rank;
final String number;
final String company;
const TrainsResult({
required this.rank,
required this.number,
required this.company,
});
factory TrainsResult.fromJson(Map<String, dynamic> json) => _$TrainsResultFromJson(json);
Map<String, dynamic> toJson() => _$TrainsResultToJson(this);
}

20
lib/models/trains_result.g.dart

@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'trains_result.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
TrainsResult _$TrainsResultFromJson(Map<String, dynamic> json) => TrainsResult(
rank: json['rank'] as String,
number: json['number'] as String,
company: json['company'] as String,
);
Map<String, dynamic> _$TrainsResultToJson(TrainsResult instance) =>
<String, dynamic>{
'rank': instance.rank,
'number': instance.number,
'company': instance.company,
};

7
lib/pages/station_arrdep_page/select_station/select_station.dart

@ -21,6 +21,8 @@ class SelectStationPage extends StatefulWidget {
return SelectStationPageStateMaterial(); return SelectStationPageStateMaterial();
case UiDesign.CUPERTINO: case UiDesign.CUPERTINO:
return SelectStationPageStateCupertino(); return SelectStationPageStateCupertino();
default:
throw UnmatchedUiDesignException(uiDesign);
} }
} }
} }
@ -35,6 +37,9 @@ abstract class SelectStationPageState extends State<SelectStationPage> {
'ș': 's', 'ș': 's',
'ț': 't', 'ț': 't',
}; };
final textEditingController = TextEditingController();
List<String> stations = []; List<String> stations = [];
List<String> get filteredStations { List<String> get filteredStations {
@ -75,6 +80,4 @@ abstract class SelectStationPageState extends State<SelectStationPage> {
Navigator.of(context).pushNamed(ViewStationPage.routeName, arguments: suggestion); Navigator.of(context).pushNamed(ViewStationPage.routeName, arguments: suggestion);
} }
final TextEditingController textEditingController = TextEditingController();
} }

54
lib/pages/train_info_page/select_train/select_train.dart

@ -3,11 +3,13 @@ import 'dart:io' show Platform;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:info_tren/components/select_train_suggestions/select_train_suggestions.dart'; import 'package:info_tren/components/select_train_suggestions/select_train_suggestions.dart';
import 'package:info_tren/models/trains_result.dart';
import 'package:info_tren/models/ui_design.dart'; import 'package:info_tren/models/ui_design.dart';
import 'package:info_tren/pages/train_info_page/select_train/select_train_cupertino.dart'; import 'package:info_tren/pages/train_info_page/select_train/select_train_cupertino.dart';
import 'package:info_tren/pages/train_info_page/select_train/select_train_material.dart'; import 'package:info_tren/pages/train_info_page/select_train/select_train_material.dart';
import 'package:info_tren/pages/train_info_page/view_train/train_info.dart'; import 'package:info_tren/pages/train_info_page/view_train/train_info.dart';
import 'package:info_tren/utils/default_ui_design.dart'; import 'package:info_tren/utils/default_ui_design.dart';
import 'package:info_tren/api/trains.dart' as apiTrains;
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
typedef TrainSelectedCallback(int trainNumber); typedef TrainSelectedCallback(int trainNumber);
@ -20,6 +22,7 @@ class SelectTrainPage extends StatefulWidget {
static String routeName = "/trainInfo/selectTrain"; static String routeName = "/trainInfo/selectTrain";
void onTrainSelected(BuildContext context, String selection) { void onTrainSelected(BuildContext context, String selection) {
selection = selection.characters.takeWhile((char) => List.generate(10, (i) => i.toString()).contains(char)).join();
Navigator.of(context).pushNamed(TrainInfo.routeName, arguments: selection); Navigator.of(context).pushNamed(TrainInfo.routeName, arguments: selection);
} }
@ -41,10 +44,56 @@ abstract class SelectTrainPageState extends State<SelectTrainPage> {
final String pageTitle = 'Informații despre tren'; final String pageTitle = 'Informații despre tren';
final String textFieldLabel = 'Numărul trenului'; final String textFieldLabel = 'Numărul trenului';
TextEditingController trainNoController = TextEditingController(); final trainNoController = TextEditingController();
List<TrainsResult> trains = [];
List<TrainsResult> get filteredTrains {
final filter = trainNoController.text
.trim()
.toLowerCase();
if (filter.isEmpty) {
return trains;
}
final filtered = trains.where((e) => e.number.contains(filter)).toList(growable: false);
filtered.sort((t1, t2) {
final posInNum1 = t1.number.indexOf(filter);
final posInNum2 = t2.number.indexOf(filter);
if (posInNum1 != posInNum2) {
return posInNum1.compareTo(posInNum2);
}
return t1.number.length.compareTo(t2.number.length);
});
return filtered;
}
@override @override
void initState() { void initState() {
apiTrains.trains.then((value) {
setState(() {
trains = value;
trains.sort((t1, t2) {
if (t1.company != t2.company) {
return t1.company.compareTo(t2.company);
}
if (t1.rank != t2.rank) {
return t1.rank.compareTo(t2.rank);
}
final t1Num = t1.number.padLeft(t2.number.length, '0');
final t2Num = t2.number.padLeft(t1.number.length, '0');
return t1Num.compareTo(t2Num);
});
});
});
super.initState(); super.initState();
} }
@ -54,8 +103,9 @@ abstract class SelectTrainPageState extends State<SelectTrainPage> {
Widget get suggestionsList => SelectTrainSuggestions( Widget get suggestionsList => SelectTrainSuggestions(
uiDesign: widget.uiDesign, uiDesign: widget.uiDesign,
userInput: trainNoController.text, choices: filteredTrains,
onTrainSelected: (trainNumber) => widget.onTrainSelected(context, trainNumber), onTrainSelected: (trainNumber) => widget.onTrainSelected(context, trainNumber),
currentInput: trainNoController.text,
key: ValueKey(trainNoController.text), key: ValueKey(trainNoController.text),
); );
} }

1
linux/.gitignore vendored

@ -0,0 +1 @@
flutter/ephemeral

138
linux/CMakeLists.txt

@ -0,0 +1,138 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "info_tren")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "ro.dcdev.info_tren")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0063 NEW)
# Load bundled libraries from the lib/ directory relative to the binary.
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Root filesystem for cross-building.
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
# Define build configuration options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
# Flutter library and tool build rules.
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endforeach(bundled_library)
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
# Install the AOT library on non-Debug builds only.
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()

88
linux/flutter/CMakeLists.txt

@ -0,0 +1,88 @@
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required(VERSION 3.10)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
# which isn't available in 3.10.
function(list_prepend LIST_NAME PREFIX)
set(NEW_LIST "")
foreach(element ${${LIST_NAME}})
list(APPEND NEW_LIST "${PREFIX}${element}")
endforeach(element)
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# === Flutter Library ===
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"fl_basic_message_channel.h"
"fl_binary_codec.h"
"fl_binary_messenger.h"
"fl_dart_project.h"
"fl_engine.h"
"fl_json_message_codec.h"
"fl_json_method_codec.h"
"fl_message_codec.h"
"fl_method_call.h"
"fl_method_channel.h"
"fl_method_codec.h"
"fl_method_response.h"
"fl_plugin_registrar.h"
"fl_plugin_registry.h"
"fl_standard_message_codec.h"
"fl_standard_method_codec.h"
"fl_string_codec.h"
"fl_value.h"
"fl_view.h"
"flutter_linux.h"
)
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
target_link_libraries(flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
)
add_dependencies(flutter flutter_assemble)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
)

11
linux/flutter/generated_plugin_registrant.cc

@ -0,0 +1,11 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}

15
linux/flutter/generated_plugin_registrant.h

@ -0,0 +1,15 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter_linux/flutter_linux.h>
// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_

23
linux/flutter/generated_plugins.cmake

@ -0,0 +1,23 @@
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)

6
linux/main.cc

@ -0,0 +1,6 @@
#include "my_application.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}

104
linux/my_application.cc

@ -0,0 +1,104 @@
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
// Use a header bar when running in GNOME as this is the common style used
// by applications and is the setup most users will be using (e.g. Ubuntu
// desktop).
// If running on X and not using GNOME then just use a traditional title bar
// in case the window manager does more exotic layout, e.g. tiling.
// If running on Wayland assume the header bar will work (may need changing
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen* screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "info_tren");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(window, "info_tren");
}
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
}
// Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
MyApplication* self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr;
if (!g_application_register(application, nullptr, &error)) {
g_warning("Failed to register: %s", error->message);
*exit_status = 1;
return TRUE;
}
g_application_activate(application);
*exit_status = 0;
return TRUE;
}
// Implements GObject::dispose.
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
}
static void my_application_init(MyApplication* self) {}
MyApplication* my_application_new() {
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID,
"flags", G_APPLICATION_NON_UNIQUE,
nullptr));
}

18
linux/my_application.h

@ -0,0 +1,18 @@
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
GtkApplication)
/**
* my_application_new:
*
* Creates a new Flutter-based application.
*
* Returns: a new #MyApplication.
*/
MyApplication* my_application_new();
#endif // FLUTTER_MY_APPLICATION_H_

123
pubspec.lock

@ -7,35 +7,35 @@ packages:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "24.0.0" version: "31.0.0"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.8.0"
args: args:
dependency: transitive dependency: transitive
description: description:
name: args name: args
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.0" version: "2.3.1"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.1" version: "2.9.0"
build: build:
dependency: transitive dependency: transitive
description: description:
name: build name: build
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.3.0"
build_config: build_config:
dependency: transitive dependency: transitive
description: description:
@ -49,56 +49,49 @@ packages:
name: build_daemon name: build_daemon
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.0" version: "3.1.0"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
name: build_resolvers name: build_resolvers
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.4" version: "2.0.6"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "2.1.11"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "7.1.0" version: "7.2.2"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
name: built_collection name: built_collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.1.0" version: "5.1.1"
built_value: built_value:
dependency: transitive dependency: transitive
description: description:
name: built_value name: built_value
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "8.1.2" version: "8.4.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@ -112,49 +105,49 @@ packages:
name: cli_util name: cli_util
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.3" version: "0.3.5"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
name: code_builder name: code_builder
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.0" version: "4.2.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0" version: "1.16.0"
convert: convert:
dependency: transitive dependency: transitive
description: description:
name: convert name: convert
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
name: cupertino_icons name: cupertino_icons
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2" version: "0.1.3"
dart_style: dart_style:
dependency: transitive dependency: transitive
description: description:
name: dart_style name: dart_style
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.2.1"
file: file:
dependency: transitive dependency: transitive
description: description:
@ -168,7 +161,7 @@ packages:
name: fixnum name: fixnum
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -187,42 +180,42 @@ packages:
name: frontend_server_client name: frontend_server_client
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.2" version: "2.1.3"
glob: glob:
dependency: transitive dependency: transitive
description: description:
name: glob name: glob
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.1" version: "2.1.0"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:
name: graphs name: graphs
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
name: http name: http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.13.3" version: "0.13.4"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
name: http_multi_server name: http_multi_server
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.2.1"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.0" version: "4.0.1"
io: io:
dependency: transitive dependency: transitive
description: description:
@ -236,7 +229,7 @@ packages:
name: js name: js
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.3" version: "0.6.4"
json_annotation: json_annotation:
dependency: transitive dependency: transitive
description: description:
@ -250,21 +243,28 @@ packages:
name: json_serializable name: json_serializable
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.0" version: "5.0.2"
logging: logging:
dependency: transitive dependency: transitive
description: description:
name: logging name: logging
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.2"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.10" version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -278,56 +278,49 @@ packages:
name: mime name: mime
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.2"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
name: package_config name: package_config
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0" version: "1.8.2"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.1"
pool: pool:
dependency: transitive dependency: transitive
description: description:
name: pool name: pool
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.0" version: "1.5.1"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
name: pub_semver name: pub_semver
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.1"
pubspec_parse: pubspec_parse:
dependency: transitive dependency: transitive
description: description:
name: pubspec_parse name: pubspec_parse
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.1.0"
quiver: quiver:
dependency: transitive dependency: transitive
description: description:
name: quiver name: quiver
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.1.0"
redux: redux:
dependency: transitive dependency: transitive
description: description:
@ -341,21 +334,21 @@ packages:
name: rxdart name: rxdart
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.22.0" version: "0.22.6"
shelf: shelf:
dependency: transitive dependency: transitive
description: description:
name: shelf name: shelf
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.3.2"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
name: shelf_web_socket name: shelf_web_socket
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.2"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -367,21 +360,21 @@ packages:
name: source_gen name: source_gen
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.2"
source_helper: source_helper:
dependency: transitive dependency: transitive
description: description:
name: source_helper name: source_helper
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.1" version: "1.3.2"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.1" version: "1.9.1"
sprintf: sprintf:
dependency: "direct main" dependency: "direct main"
description: description:
@ -416,14 +409,14 @@ packages:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
timing: timing:
dependency: transitive dependency: transitive
description: description:
@ -444,34 +437,34 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.2"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
name: watcher name: watcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.1"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
name: web_socket_channel name: web_socket_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.2.0"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:
name: yaml name: yaml
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.0" version: "3.1.1"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.17.0 <3.0.0"

4
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. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 2.7.0 version: 2.7.1
environment: environment:
sdk: ">=2.12.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
@ -88,5 +88,3 @@ flutter:
# #
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages # see https://flutter.dev/custom-fonts/#from-packages
assets:
- assets/lines/

30
test/widget_test.dart

@ -0,0 +1,30 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:info_tren/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
Loading…
Cancel
Save