Browse Source

Brought project up to date with modern Flutter

pull/1/head
Dan Cojocaru 3 years ago
parent
commit
7111f2865e
Signed by: kbruen
GPG Key ID: 818A889458EDC937
  1. 1
      .gitignore
  2. 37
      .vscode/launch.json
  3. 12
      android/app/src/main/AndroidManifest.xml
  4. 9
      android/app/src/main/kotlin/ml/dandevelop/info_tren/MainActivity.kt
  5. 18
      ios/Flutter/Flutter.podspec
  6. 15
      ios/Flutter/flutter_export_environment.sh
  7. 67
      ios/Podfile
  8. 10
      ios/Podfile.lock
  9. 24
      ios/Runner.xcodeproj/project.pbxproj
  10. 2
      ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  11. 38
      lib/main.dart
  12. 7
      lib/models/train_data.dart
  13. 8
      lib/stations_list.dart
  14. 20
      lib/train_info_display.dart
  15. 56
      lib/train_info_page/train_info_material.dart
  16. 34
      lib/train_info_page/train_info_material_DisplayTrainStation.dart
  17. 8
      lib/train_info_page/train_info_prompt.dart
  18. 2
      lib/utils/stream_list.dart
  19. 55
      pubspec.lock

1
.gitignore vendored

@ -24,6 +24,7 @@
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/

37
.vscode/launch.json vendored

@ -0,0 +1,37 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Current Device",
"request": "launch",
"type": "dart"
},
{
"name": "info_tren (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "Android Emulator",
"request": "launch",
"type": "dart",
"deviceId": "sdk gphone"
},
{
"name": "iPhone",
"request": "launch",
"type": "dart",
"deviceId": "iphone"
}
],
"compounds": [
{
"name": "All Devices",
"configurations": ["Android Emulator", "iPhone"]
}
]
}

12
android/app/src/main/AndroidManifest.xml

@ -9,7 +9,6 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="Info Tren"
android:icon="@mipmap/ic_launcher">
<activity
@ -20,17 +19,22 @@
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:screenOrientation="portrait">
<!-- Specify that the launch screen should continue being displayed -->
<!-- until Flutter renders its first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

9
android/app/src/main/kotlin/ml/dandevelop/info_tren/MainActivity.kt

@ -1,13 +1,6 @@
package ml.dandevelop.info_tren
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
}
}

18
ios/Flutter/Flutter.podspec

@ -0,0 +1,18 @@
#
# NOTE: This podspec is NOT to be published. It is only used as a local source!
# This is a generated file; do not edit or check into version control.
#
Pod::Spec.new do |s|
s.name = 'Flutter'
s.version = '1.0.0'
s.summary = 'High-performance, high-fidelity mobile apps.'
s.homepage = 'https://flutter.io'
s.license = { :type => 'MIT' }
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
# Framework linking is handled by Flutter tooling, not CocoaPods.
# Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs.
s.vendored_frameworks = 'path/to/nothing'
end

15
ios/Flutter/flutter_export_environment.sh

@ -0,0 +1,15 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/usr/local/Caskroom/flutter/2.2.3/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/dan.cojocaru/info_tren"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=/Users/dan.cojocaru/info_tren/lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
export "FLUTTER_BUILD_NAME=2.0.6"
export "FLUTTER_BUILD_NUMBER=2.0.6"
export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=/Users/dan.cojocaru/info_tren/.dart_tool/package_config.json"

67
ios/Podfile

@ -10,65 +10,32 @@ project 'Runner', {
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
pods_ary = []
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
target 'Runner' do
use_frameworks!
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
flutter_ios_podfile_setup
# Flutter Pods
generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
if generated_xcode_build_settings.empty?
puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
end
generated_xcode_build_settings.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join('.symlinks', 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
end
}
target 'Runner' do
use_frameworks!
use_modular_headers!
# Plugin Pods
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join('.symlinks', 'plugins', p[:name])
File.symlink(p[:path], symlink)
pod p[:name], :path => File.join(symlink, 'ios')
}
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
flutter_additional_ios_build_settings(target)
end
end

10
ios/Podfile.lock

@ -4,19 +4,19 @@ PODS:
- Flutter
DEPENDENCIES:
- Flutter (from `.symlinks/flutter/ios-release`)
- Flutter (from `Flutter`)
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
EXTERNAL SOURCES:
Flutter:
:path: ".symlinks/flutter/ios-release"
:path: Flutter
webview_flutter:
:path: ".symlinks/plugins/webview_flutter/ios"
SPEC CHECKSUMS:
Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
webview_flutter: 1aa7604e6cdb451a9b7ed2c37d5454c0b440246b
PODFILE CHECKSUM: b6a0a141693093b304368d08511b46cf3d1d0ac5
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
COCOAPODS: 1.6.1
COCOAPODS: 1.10.1

24
ios/Runner.xcodeproj/project.pbxproj

@ -9,12 +9,8 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
722F441253D3B79676E4DE80 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F72320B12B1F4015789BBC8E /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
@ -28,8 +24,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -41,7 +35,6 @@
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
313F1E773DA06364A0C4F20A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
636963D381657D3BAEDC0A47 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -49,7 +42,6 @@
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@ -63,8 +55,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
722F441253D3B79676E4DE80 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -83,9 +73,7 @@
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
@ -248,14 +236,13 @@
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/webview_flutter/webview_flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/webview_flutter.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@ -274,7 +261,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
@ -326,7 +313,6 @@
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -406,7 +392,6 @@
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -462,7 +447,6 @@
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;

2
ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata generated

@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>

38
lib/main.dart

@ -102,7 +102,7 @@ class MainPageMaterial extends StatelessWidget with MainPageAction {
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RaisedButton(
ElevatedButton(
child: Text(
"Informații despre tren",
style: Theme.of(context).textTheme.button.copyWith(fontSize: 18),
@ -111,23 +111,27 @@ class MainPageMaterial extends StatelessWidget with MainPageAction {
onTrainInfoPageInvoke(context);
},
),
RaisedButton(
ElevatedButton(
child: Text(
"Tabelă plecari/sosiri",
style: Theme.of(context).textTheme.button.copyWith(fontSize: 18),
),
onPressed: () {
onStationBoardPageInvoke(context);
},
// TODO: Implement departure/arrival
onPressed: null,
// onPressed: () {
// onStationBoardPageInvoke(context);
// },
),
RaisedButton(
ElevatedButton(
child: Text(
"Planificare rută",
style: Theme.of(context).textTheme.button.copyWith(fontSize: 18),
),
onPressed: () {
onRoutePlanPageInvoke(context);
},
// TODO: Implement route planning
onPressed: null,
// onPressed: () {
// onRoutePlanPageInvoke(context);
// },
)
].map((w) => Padding(
padding: const EdgeInsets.fromLTRB(4, 2, 4, 2),
@ -163,15 +167,19 @@ class MainPageCupertino extends StatelessWidget with MainPageAction {
),
CupertinoButton.filled(
child: Text("Tabelă plecari/sosiri"),
onPressed: () {
onStationBoardPageInvoke(context);
},
// TODO: Implement departure/arrival
onPressed: null,
// onPressed: () {
// onStationBoardPageInvoke(context);
// },
),
CupertinoButton.filled(
child: Text("Planificare rută"),
onPressed: () {
onRoutePlanPageInvoke(context);
},
// TODO: Implement route planning
onPressed: null,
// onPressed: () {
// onRoutePlanPageInvoke(context);
// },
),
].map((w) => Padding(
padding: const EdgeInsets.fromLTRB(4, 2, 4, 2),

7
lib/models/train_data.dart

@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io' show Platform;
import 'package:flutter/widgets.dart';
import 'package:info_tren/hidden_webview.dart';
@ -479,7 +478,7 @@ class OnDemandNextStop extends OnDemand {
class OnDemandStations extends OnDemand {
final WebViewController _controller;
List<OnDemand> issuedOnDemands = List();
List<OnDemand> issuedOnDemands = [];
@override
void invalidate() {
@ -744,7 +743,7 @@ class TrainDataWebViewAdapter extends StatefulWidget {
}
static _TrainDataWebViewAdapterState of(BuildContext context) =>
(context.inheritFromWidgetOfExactType(_TrainDataWebViewAdapterInheritedWidget) as _TrainDataWebViewAdapterInheritedWidget)
(context.findAncestorWidgetOfExactType<_TrainDataWebViewAdapterInheritedWidget>())
.state;
}
@ -841,7 +840,7 @@ class _TrainDataWebViewAdapterState extends State<TrainDataWebViewAdapter> {
return TrainLookupResult.OTHER;
}
List<OnDemand> currentDatas = List();
List<OnDemand> currentDatas = [];
Future<OnDemandTrainData> trainData({Function onInvalidation}) async {
final controller = await webViewController;

8
lib/stations_list.dart

@ -168,14 +168,14 @@ class StopOnLineDetails extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 1.0),
child: Text(
station.name,
style: Theme.of(context).textTheme.headline,
style: Theme.of(context).textTheme.headline5,
textAlign: TextAlign.center,
),
),
if (station.observations == "ONI")
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.5),
child: Text("oprire ne-itinerarică", style: Theme.of(context).textTheme.body1.copyWith(color: Colors.red.shade700),),
child: Text("oprire ne-itinerarică", style: Theme.of(context).textTheme.bodyText2.copyWith(color: Colors.red.shade700),),
),
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0.5, 8.0, 8.0),
@ -293,14 +293,14 @@ class StopOnLineDelayDetails extends StatelessWidget {
else if (station.delay < 0) {
return Text(
"${-(station.delay)} minute mai devreme",
style: Theme.of(context).textTheme.body1.copyWith(color: Colors.green.shade700),
style: Theme.of(context).textTheme.bodyText2.copyWith(color: Colors.green.shade700),
textAlign: TextAlign.center,
);
}
else {
return Text(
"${station.delay} minute întârziere",
style: Theme.of(context).textTheme.body1.copyWith(color: Colors.red.shade700),
style: Theme.of(context).textTheme.bodyText2.copyWith(color: Colors.red.shade700),
textAlign: TextAlign.center,
);
}

20
lib/train_info_display.dart

@ -82,7 +82,7 @@ class TrainName extends StatelessWidget {
Widget build(BuildContext context) {
return Text(
"${trainData.rang} ${trainData.trainNumber}",
style: Theme.of(context).textTheme.display2,
style: Theme.of(context).textTheme.headline3,
);
}
}
@ -99,19 +99,19 @@ class TrainRoute extends StatelessWidget {
Expanded(
child: Text(
"${trainData.route.split("-")[0]}",
style: Theme.of(context).textTheme.body2.copyWith(fontStyle: FontStyle.italic),
style: Theme.of(context).textTheme.bodyText1.copyWith(fontStyle: FontStyle.italic),
textAlign: TextAlign.left,
),
),
Text(
"-",
style: Theme.of(context).textTheme.body2.copyWith(fontStyle: FontStyle.italic),
style: Theme.of(context).textTheme.bodyText1.copyWith(fontStyle: FontStyle.italic),
textAlign: TextAlign.center,
),
Expanded(
child: Text(
"${trainData.route.split("-")[1]}",
style: Theme.of(context).textTheme.body2.copyWith(fontStyle: FontStyle.italic),
style: Theme.of(context).textTheme.bodyText1.copyWith(fontStyle: FontStyle.italic),
textAlign: TextAlign.right,
),
),
@ -128,7 +128,7 @@ class TrainOperator extends StatelessWidget {
Widget build(BuildContext context) {
return Text(
"Operat de ${trainData.operator}",
style: Theme.of(context).textTheme.body1,
style: Theme.of(context).textTheme.bodyText2,
textAlign: TextAlign.center,
);
}
@ -143,7 +143,7 @@ class TrainStatus extends StatelessWidget {
return Text(
trainData.state,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline,
style: Theme.of(context).textTheme.headline5,
);
}
}
@ -182,7 +182,7 @@ class LastUpdate extends StatelessWidget {
children: <Widget>[
Padding(
padding: const EdgeInsets.all(2.0),
child: Text("Ultima informație", style: Theme.of(context).textTheme.headline,),
child: Text("Ultima informație", style: Theme.of(context).textTheme.headline5,),
),
Row(
children: <Widget>[
@ -202,8 +202,8 @@ class LastUpdate extends StatelessWidget {
child: trainData.lastInfo.delay == 0
? Text("Fără întârziere", style: Theme.of(context).textTheme.caption,)
: trainData.lastInfo.delay > 0
? Text("${trainData.lastInfo.delay} minute întârziere", style: Theme.of(context).textTheme.body1.copyWith(color: Colors.red.shade700),)
: Text("${-(trainData.lastInfo.delay)} minute mai devreme", style: Theme.of(context).textTheme.body1.copyWith(color: Colors.green.shade700),)
? Text("${trainData.lastInfo.delay} minute întârziere", style: Theme.of(context).textTheme.bodyText2.copyWith(color: Colors.red.shade700),)
: Text("${-(trainData.lastInfo.delay)} minute mai devreme", style: Theme.of(context).textTheme.bodyText2.copyWith(color: Colors.green.shade700),)
),
Padding(
padding: const EdgeInsets.all(2.0),
@ -225,7 +225,7 @@ class NextStop extends StatelessWidget {
children: <Widget>[
Padding(
padding: const EdgeInsets.all(2.0),
child: Text("Următoarea oprire", style: Theme.of(context).textTheme.headline,),
child: Text("Următoarea oprire", style: Theme.of(context).textTheme.headline5,),
),
Row(
children: <Widget>[

56
lib/train_info_page/train_info_material.dart

@ -104,7 +104,7 @@ class _TrainInfoMaterialBeforeState extends State<_TrainInfoMaterialBefore> {
CircularProgressIndicator(),
Text(
"Conectare...",
style: Theme.of(context).textTheme.title,
style: Theme.of(context).textTheme.headline6,
),
],
),
@ -172,7 +172,7 @@ class _TrainInfoMaterialBeforeState extends State<_TrainInfoMaterialBefore> {
: widget.lookupResult == TrainLookupResult.NOT_FOUND
? "Trenul nu a fost găsit"
: "A apărut o eroare în căutarea trenului",
style: Theme.of(context).textTheme.title,
style: Theme.of(context).textTheme.headline6,
),
),
Expanded(child: Container(),),
@ -352,9 +352,9 @@ class DisplayTrainID extends StatelessWidget {
return Text(
"${list[0]} ${list[1]}",
style: (isSmallScreen(context)
? Theme.of(context).textTheme.display1
: Theme.of(context).textTheme.display2).copyWith(
color: Theme.of(context).textTheme.body1.color,
? Theme.of(context).textTheme.headline4
: Theme.of(context).textTheme.headline3).copyWith(
color: Theme.of(context).textTheme.bodyText2.color,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
@ -376,7 +376,7 @@ class DisplayTrainOperator extends StatelessWidget {
builder: (context, op) {
return Text(
op,
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontStyle: FontStyle.italic,
fontSize: isSmallScreen(context) ? 12 : 14,
),
@ -404,7 +404,7 @@ class DisplayTrainRoute extends StatelessWidget {
padding: const EdgeInsets.all(4),
child: Text(
routePieces[0],
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: 16,
),
),
@ -418,7 +418,7 @@ class DisplayTrainRoute extends StatelessWidget {
padding: const EdgeInsets.all(4),
child: Text(
routePieces[1],
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: 16,
),
textAlign: TextAlign.right,
@ -446,7 +446,7 @@ class DisplayTrainDeparture extends StatelessWidget {
builder: (context, dataPlecare) {
return Text(
"Plecare în ${dataPlecare.day.toString().padLeft(2, '0')}.${dataPlecare.month.toString().padLeft(2, '0')}.${dataPlecare.year.toString().padLeft(4, '0')}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w200,
fontSize: isSmallScreen(context) ? 12 : 14,
@ -477,7 +477,7 @@ class DisplayTrainLastInfo extends StatelessWidget {
padding: const EdgeInsets.all(2),
child: Text(
"Ultima informație",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 18 : 20,
fontWeight: FontWeight.bold,
),
@ -493,7 +493,7 @@ class DisplayTrainLastInfo extends StatelessWidget {
builder: (context, station) {
return Text(
station,
style: Theme.of(context).textTheme.body1,
style: Theme.of(context).textTheme.bodyText2,
textAlign: TextAlign.left,
);
},
@ -507,7 +507,7 @@ class DisplayTrainLastInfo extends StatelessWidget {
builder: (context, event) {
return Text(
event,
style: Theme.of(context).textTheme.body1,
style: Theme.of(context).textTheme.bodyText2,
textAlign: TextAlign.right,
);
},
@ -540,7 +540,7 @@ class DisplayTrainLastInfo extends StatelessWidget {
if (snapshot.data > 0) {
return Text(
"${snapshot.data} minute întârziere",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: 14,
color: Color.fromRGBO(200, 30, 15, 1),
),
@ -549,7 +549,7 @@ class DisplayTrainLastInfo extends StatelessWidget {
else {
return Text(
"${-snapshot.data} minute mai devreme",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: 12,
color: Color.fromRGBO(15, 200, 15, 1),
),
@ -590,7 +590,7 @@ class DisplayTrainNextStop extends StatelessWidget {
padding: const EdgeInsets.all(4),
child: Text(
"Următoarea oprire",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 18 : 20,
fontWeight: FontWeight.bold,
),
@ -604,7 +604,7 @@ class DisplayTrainNextStop extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(4, 0, 4, 0),
child: Text(
station,
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 16 : 18,
fontWeight: FontWeight.w500,
),
@ -623,14 +623,14 @@ class DisplayTrainNextStop extends StatelessWidget {
children: <Widget>[
Text(
"în ${arrival.day} ${months[arrival.month - 1]} ${arrival.year}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 12 : 14,
),
textAlign: TextAlign.center,
),
Text(
"la ${arrival.hour.toString().padLeft(2, '0')}:${arrival.minute.toString().padLeft(2, '0')}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 12 : 14,
),
textAlign: TextAlign.center,
@ -672,7 +672,7 @@ class DisplayTrainDestination extends StatelessWidget {
padding: const EdgeInsets.all(4),
child: Text(
"Destinația",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 18 : 20,
fontWeight: FontWeight.bold,
),
@ -686,7 +686,7 @@ class DisplayTrainDestination extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(4, 0, 4, 0),
child: Text(
station,
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 16 : 18,
fontWeight: FontWeight.w500,
),
@ -705,14 +705,14 @@ class DisplayTrainDestination extends StatelessWidget {
children: <Widget>[
Text(
"în ${arrival.day} ${months[arrival.month - 1]} ${arrival.year}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 12 : 14,
),
textAlign: TextAlign.center,
),
Text(
"la ${arrival.hour.toString().padLeft(2, '0')}:${arrival.minute.toString().padLeft(2, '0')}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 12 : 14,
),
textAlign: TextAlign.center,
@ -747,7 +747,7 @@ class DisplayTrainRouteDistance extends StatelessWidget {
children: <Widget>[
Text(
"Distanța rutei",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 16 : 18,
fontWeight: FontWeight.bold,
),
@ -758,7 +758,7 @@ class DisplayTrainRouteDistance extends StatelessWidget {
builder: (context, distance) {
return Text(
"$distance km",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 14 : 16,
),
textAlign: TextAlign.center,
@ -789,7 +789,7 @@ class DisplayTrainRouteDuration extends StatelessWidget {
children: <Widget>[
Text(
"Durata rutei",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 16 : 18,
fontWeight: FontWeight.bold,
),
@ -831,7 +831,7 @@ class DisplayTrainRouteDuration extends StatelessWidget {
return Text(
durationString.toString(),
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 14 : 16,
),
textAlign: TextAlign.center,
@ -925,8 +925,8 @@ class SlimAppBar extends StatelessWidget {
title,
textAlign: TextAlign.center,
style:
Theme.of(context).appBarTheme.textTheme?.caption?.copyWith(color: Theme.of(context).appBarTheme.textTheme?.body1?.color) ??
Theme.of(context).textTheme.caption.copyWith(color: Theme.of(context).textTheme.body1.color),
Theme.of(context).appBarTheme.textTheme?.caption?.copyWith(color: Theme.of(context).appBarTheme.textTheme?.bodyText2?.color) ??
Theme.of(context).textTheme.caption.copyWith(color: Theme.of(context).textTheme.bodyText2.color),
),
),
),

34
lib/train_info_page/train_info_material_DisplayTrainStation.dart

@ -113,7 +113,7 @@ class KmBadge extends StatelessWidget {
builder: (context, value) {
return Text(
value.toString(),
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 14 : 18,
fontWeight: MediaQuery.of(context).boldText ? FontWeight.w400 : FontWeight.w200,
color: MediaQuery.of(context).boldText ? Colors.white70 : foregroundColor,
@ -126,7 +126,7 @@ class KmBadge extends StatelessWidget {
),
Text(
"km",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: 10,
color: MediaQuery.of(context).boldText ? Colors.white70 : foregroundColor,
),
@ -155,7 +155,7 @@ class Title extends StatelessWidget {
builder: (context, items) {
return Text(
items[0],
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 18 : 22,
fontWeight: MediaQuery.of(context).boldText ? FontWeight.w400 : FontWeight.w200,
fontStyle: items[1] == "ONI" ? FontStyle.italic : FontStyle.normal,
@ -204,7 +204,7 @@ class Time extends StatelessWidget {
children: <Widget>[
Text(
"",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 18 : 22,
),
),
@ -217,7 +217,7 @@ class Time extends StatelessWidget {
Container(width: 2,),
Text(
"",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 18 : 22,
),
),
@ -251,7 +251,7 @@ class ArrivalTime extends StatelessWidget {
children: <Widget>[
Text(
"",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: isSmallScreen(context) ? 18 : 22,
),
),
@ -278,13 +278,13 @@ class ArrivalTime extends StatelessWidget {
children: <Widget>[
Text(
"${oldDate.hour.toString().padLeft(2, '0')}:${oldDate.minute.toString().padLeft(2, '0')}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
decoration: TextDecoration.lineThrough,
),
),
Text(
"${data[0]}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: Colors.red.shade300,
),
),
@ -303,13 +303,13 @@ class ArrivalTime extends StatelessWidget {
children: <Widget>[
Text(
"${oldDate.hour.toString().padLeft(2, '0')}:${oldDate.minute.toString().padLeft(2, '0')}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
decoration: TextDecoration.lineThrough,
),
),
Text(
"${data[0]}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: Colors.green.shade300,
),
),
@ -398,7 +398,7 @@ class DepartureTime extends StatelessWidget {
Container(width: 2,),
Text(
"",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
fontSize: 22,
),
),
@ -421,13 +421,13 @@ class DepartureTime extends StatelessWidget {
children: <Widget>[
Text(
"${oldDate.hour.toString().padLeft(2, '0')}:${oldDate.minute.toString().padLeft(2, '0')}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
decoration: TextDecoration.lineThrough,
),
),
Text(
"${data[0]}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: Colors.red.shade300,
),
),
@ -446,13 +446,13 @@ class DepartureTime extends StatelessWidget {
children: <Widget>[
Text(
"${oldDate.hour.toString().padLeft(2, '0')}:${oldDate.minute.toString().padLeft(2, '0')}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
decoration: TextDecoration.lineThrough,
),
),
Text(
"${data[0]}",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: Colors.green.shade300,
),
),
@ -483,7 +483,7 @@ class Delay extends StatelessWidget {
else if (delay > 0) {
return Text(
"$delay minute întârziere",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: Colors.red.shade300,
fontSize: 12,
fontStyle: FontStyle.italic,
@ -494,7 +494,7 @@ class Delay extends StatelessWidget {
else if (delay < 0) {
return Text(
"${-delay} minute mai devreme",
style: Theme.of(context).textTheme.body1.copyWith(
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: Colors.green.shade300,
fontSize: 12,
fontStyle: FontStyle.italic,

8
lib/train_info_page/train_info_prompt.dart

@ -21,10 +21,10 @@ mixin TrainInfoPromptCommon {
}
mixin TrainInfoPromptListHandling {
List<TrainOperatorLines> operators = List();
List<TrainOperatorLines> operators = [];
Future loadOperators(BuildContext context) async {
operators = List();
operators = [];
final operatorsString = await DefaultAssetBundle.of(context).loadString("assets/lines/files.txt");
final operatorsFilesList = operatorsString.split("\n");
@ -265,7 +265,7 @@ class _TrainInfoPromptMaterialState extends State<TrainInfoPromptMaterial> with
labelText: "Numărul trenului",
),
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly,
FilteringTextInputFormatter.digitsOnly,
],
textInputAction: TextInputAction.search,
keyboardType: TextInputType.number,
@ -326,7 +326,7 @@ class _TrainInfoPromptCupertinoState extends State<TrainInfoPromptCupertino> wit
setState(() {});
},
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly,
FilteringTextInputFormatter.digitsOnly,
],
),
),

2
lib/utils/stream_list.dart

@ -1,7 +1,7 @@
import 'dart:async';
Stream<List<T>> listifyStream<T>(Stream<T> stream) async* {
List<T> list = List();
List<T> list = [];
await for (T item in stream) {
list.add(item);

55
pubspec.lock

@ -21,14 +21,14 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
version: "2.6.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
version: "2.1.0"
build:
dependency: transitive
description:
@ -85,13 +85,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.7.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
version: "1.2.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
code_builder:
dependency: transitive
description:
@ -105,7 +119,7 @@ packages:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
version: "1.15.0"
convert:
dependency: transitive
description:
@ -141,6 +155,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.9"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
fixnum:
dependency: transitive
description:
@ -255,14 +276,14 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.5"
version: "0.12.10"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
version: "1.3.0"
mime:
dependency: transitive
description:
@ -290,7 +311,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.2"
version: "1.8.0"
pedantic:
dependency: transitive
description:
@ -365,21 +386,21 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.5"
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0"
stream_transform:
dependency: transitive
description:
@ -393,21 +414,21 @@ packages:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.5"
version: "0.3.0"
timing:
dependency: transitive
description:
@ -428,14 +449,14 @@ packages:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
version: "2.1.0"
watcher:
dependency: transitive
description:
@ -465,5 +486,5 @@ packages:
source: hosted
version: "2.1.16"
sdks:
dart: ">=2.3.0 <3.0.0"
flutter: ">=1.5.0 <2.0.0"
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.5.0"

Loading…
Cancel
Save