Compare commits

...

4 commits

Author SHA1 Message Date
a2ebb3def5
Choose ideal group until selection is implemented 2023-07-24 07:04:51 +02:00
cc7caffffa
Boilerplate fixes 2023-07-24 06:55:45 +02:00
17d8fac893
Move to API v3 2023-07-24 06:55:16 +02:00
1f48e868b0
Upgrade to Flutter 3 2023-07-24 06:47:03 +02:00
51 changed files with 4575 additions and 930 deletions

View file

@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) {
} }
android { android {
compileSdkVersion 31 compileSdkVersion 33
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -51,7 +51,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "ro.dcdev.infotren" applicationId "ro.dcdev.infotren"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 31 targetSdkVersion 33
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }

View file

@ -6,7 +6,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.0' classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
@ -24,6 +24,6 @@ subprojects {
project.evaluationDependsOn(':app') project.evaluationDependsOn(':app')
} }
task clean(type: Delete) { tasks.register("clean", Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

View file

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-all.zip

View file

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>9.0</string> <string>11.0</string>
</dict> </dict>
</plist> </plist>

View file

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
# platform :ios, '9.0' # platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

34
ios/Podfile.lock Normal file
View file

@ -0,0 +1,34 @@
PODS:
- Flutter (1.0.0)
- package_info_plus (0.4.5):
- Flutter
- shared_preferences_ios (0.0.1):
- Flutter
- url_launcher_ios (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
shared_preferences_ios:
:path: ".symlinks/plugins/shared_preferences_ios/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
COCOAPODS: 1.11.3

View file

@ -13,6 +13,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
AF5528149967EA996B5AA109 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E6EB5FA5AA2228D5622CD62 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -31,7 +32,11 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2088AE25E07C211FFB9CE536 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
2F80AD107B0E1CC9E1C01A5A /* 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>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
5DA42B3CD8940DB121C028E8 /* 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>"; };
6E6EB5FA5AA2228D5622CD62 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; 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>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@ -49,6 +54,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
AF5528149967EA996B5AA109 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -72,6 +78,8 @@
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
B55F9B76DFEAB456725329A0 /* Pods */,
E56598AA51C5533E6B51BD5A /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -98,6 +106,25 @@
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
B55F9B76DFEAB456725329A0 /* Pods */ = {
isa = PBXGroup;
children = (
2F80AD107B0E1CC9E1C01A5A /* Pods-Runner.debug.xcconfig */,
2088AE25E07C211FFB9CE536 /* Pods-Runner.release.xcconfig */,
5DA42B3CD8940DB121C028E8 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
E56598AA51C5533E6B51BD5A /* Frameworks */ = {
isa = PBXGroup;
children = (
6E6EB5FA5AA2228D5622CD62 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -105,12 +132,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
2B2F3198BD0D2214C77EC99E /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
D71FC49A789443CEBF7C5C70 /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -127,7 +156,7 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1020; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
@ -169,6 +198,28 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
2B2F3198BD0D2214C77EC99E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -197,6 +248,23 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
D71FC49A789443CEBF7C5C70 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@ -272,7 +340,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -351,7 +419,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -400,7 +468,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1020" LastUpgradeVersion = "1300"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View file

@ -4,4 +4,7 @@
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "group:Runner.xcodeproj">
</FileRef> </FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace> </Workspace>

View file

@ -43,5 +43,7 @@
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict> </dict>
</plist> </plist>

View file

@ -4,7 +4,11 @@ import 'package:http/http.dart' as http;
import 'package:info_tren/api/common.dart'; import 'package:info_tren/api/common.dart';
import 'package:info_tren/models.dart'; import 'package:info_tren/models.dart';
Future<StationData> getStationData(String stationName) async { Future<StationData> getStationData(String stationName, [DateTime? date]) async {
final response = await http.get(Uri.https(authority, 'v3/stations/$stationName')); final uri = Uri.https(authority, 'v3/stations/$stationName');
if (date != null) {
uri.queryParameters['date'] = date.toIso8601String();
}
final response = await http.get(uri);
return StationData.fromJson(jsonDecode(response.body)); return StationData.fromJson(jsonDecode(response.body));
} }

View file

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

View file

@ -1,4 +1,3 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.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';
@ -6,7 +5,6 @@ import 'package:info_tren/components/select_train_suggestions/select_train_sugge
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.dart'; import 'package:info_tren/models.dart';
import 'package:info_tren/providers.dart'; import 'package:info_tren/providers.dart';
import 'package:info_tren/utils/default_ui_design.dart';
class SelectTrainSuggestions extends ConsumerWidget { class SelectTrainSuggestions extends ConsumerWidget {
final List<TrainsResult> choices; final List<TrainsResult> choices;

View file

@ -44,7 +44,7 @@ class SlimAppBar extends StatelessWidget {
title, title,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: style:
Theme.of(context).appBarTheme.textTheme?.bodySmall?.copyWith(color: Theme.of(context).appBarTheme.textTheme?.bodyMedium?.color) ?? Theme.of(context).textTheme.titleSmall?.copyWith(color: Theme.of(context).textTheme.titleLarge?.color) ??
Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).textTheme.bodyMedium?.color), Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).textTheme.bodyMedium?.color),
), ),
), ),

View file

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:fluent_ui/fluent_ui.dart' as f; import 'package:fluent_ui/fluent_ui.dart' as f;
import 'package:flutter/cupertino.dart' as c; import 'package:flutter/cupertino.dart' as c;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
@ -20,6 +21,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:timezone/data/latest.dart'; import 'package:timezone/data/latest.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized();
initializeTimeZones(); initializeTimeZones();
final sharedPreferences = await SharedPreferences.getInstance(); final sharedPreferences = await SharedPreferences.getInstance();
runApp( runApp(
@ -107,6 +109,8 @@ class StartPoint extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final uiDesign = ref.watch(uiDesignProvider); final uiDesign = ref.watch(uiDesignProvider);
if (uiDesign == UiDesign.CUPERTINO) { if (uiDesign == UiDesign.CUPERTINO) {
return DynamicColorBuilder(
builder: (lightScheme, darkScheme) {
return AnnotatedRegion( return AnnotatedRegion(
value: const SystemUiOverlayStyle( value: const SystemUiOverlayStyle(
statusBarBrightness: c.Brightness.dark, statusBarBrightness: c.Brightness.dark,
@ -114,7 +118,7 @@ class StartPoint extends ConsumerWidget {
child: c.CupertinoApp( child: c.CupertinoApp(
title: appTitle, title: appTitle,
theme: c.CupertinoThemeData( theme: c.CupertinoThemeData(
primaryColor: m.Colors.blue.shade600, primaryColor: darkScheme?.primary ?? m.Colors.blue.shade600,
brightness: c.Brightness.dark, brightness: c.Brightness.dark,
// textTheme: CupertinoTextThemeData( // textTheme: CupertinoTextThemeData(
// textStyle: TextStyle( // textStyle: TextStyle(
@ -127,27 +131,53 @@ class StartPoint extends ConsumerWidget {
), ),
); );
} }
);
}
else if (uiDesign == UiDesign.FLUENT) { else if (uiDesign == UiDesign.FLUENT) {
return DynamicColorBuilder(
builder: (lightScheme, darkScheme) {
return f.FluentApp( return f.FluentApp(
title: appTitle, title: appTitle,
theme: f.ThemeData( theme: f.FluentThemeData(
brightness: f.Brightness.light,
accentColor: lightScheme != null ? f.AccentColor.swatch({
'normal': lightScheme.primary,
}) : f.Colors.blue,
),
darkTheme: f.FluentThemeData(
brightness: f.Brightness.dark, brightness: f.Brightness.dark,
accentColor: f.Colors.blue, accentColor: darkScheme != null ? f.AccentColor.swatch({
'normal': darkScheme.primary,
}) : f.Colors.blue,
), ),
routes: routes, routes: routes,
scrollBehavior: Platform.isLinux ? const DragFluentScrollBevahior() : const f.FluentScrollBehavior(), scrollBehavior: Platform.isLinux ? const DragFluentScrollBevahior() : const f.FluentScrollBehavior(),
); );
} }
);
}
else { else {
return DynamicColorBuilder(
builder: (lightScheme, darkScheme) {
lightScheme ??= m.ColorScheme.fromSwatch(
brightness: m.Brightness.light,
primarySwatch: m.Colors.blue,
);
darkScheme ??= m.ColorScheme.fromSwatch(
brightness: m.Brightness.dark,
primarySwatch: m.Colors.blue,
);
return m.MaterialApp( return m.MaterialApp(
title: appTitle, title: appTitle,
theme: m.ThemeData( theme: m.ThemeData(
primarySwatch: m.Colors.blue, colorScheme: lightScheme,
colorScheme: m.ColorScheme.fromSwatch( useMaterial3: true,
brightness: m.Brightness.dark, // fontFamily: 'Atkinson Hyperlegible',
primarySwatch: m.Colors.blue,
accentColor: m.Colors.blue.shade700,
), ),
darkTheme: m.ThemeData(
colorScheme: darkScheme,
useMaterial3: true, useMaterial3: true,
// fontFamily: 'Atkinson Hyperlegible', // fontFamily: 'Atkinson Hyperlegible',
), ),
@ -155,5 +185,7 @@ class StartPoint extends ConsumerWidget {
routes: routes, routes: routes,
); );
} }
);
}
} }
} }

View file

@ -4,11 +4,11 @@ export 'package:info_tren/models/station_data.dart';
export 'package:info_tren/models/station_status.dart'; export 'package:info_tren/models/station_status.dart';
export 'package:info_tren/models/station_train.dart'; export 'package:info_tren/models/station_train.dart';
export 'package:info_tren/models/stations_result.dart'; export 'package:info_tren/models/stations_result.dart';
export 'package:info_tren/models/train_data.dart' hide State; export 'package:info_tren/models/train_data.dart';
export 'package:info_tren/models/trains_result.dart'; export 'package:info_tren/models/trains_result.dart';
export 'package:info_tren/models/ui_design.dart'; export 'package:info_tren/models/ui_design.dart';
export 'package:info_tren/models/ui_timezone.dart'; export 'package:info_tren/models/ui_timezone.dart';
import 'package:info_tren/models/train_data.dart' show State; import 'package:info_tren/models/train_data.dart' show TrainDataStatusState;
typedef TrainDataState = State; typedef TrainDataState = TrainDataStatusState;

View file

@ -1,7 +1,7 @@
// coverage:ignore-file // coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'station_arrdep.dart'; part of 'station_arrdep.dart';

View file

@ -1,7 +1,7 @@
// coverage:ignore-file // coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'station_data.dart'; part of 'station_data.dart';
@ -158,6 +158,7 @@ class _$_StationData implements _StationData {
List<StationArrDep>? get arrivals { List<StationArrDep>? get arrivals {
final value = _arrivals; final value = _arrivals;
if (value == null) return null; if (value == null) return null;
if (_arrivals is EqualUnmodifiableListView) return _arrivals;
// ignore: implicit_dynamic_type // ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value); return EqualUnmodifiableListView(value);
} }
@ -167,6 +168,7 @@ class _$_StationData implements _StationData {
List<StationArrDep>? get departures { List<StationArrDep>? get departures {
final value = _departures; final value = _departures;
if (value == null) return null; if (value == null) return null;
if (_departures is EqualUnmodifiableListView) return _departures;
// ignore: implicit_dynamic_type // ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value); return EqualUnmodifiableListView(value);
} }

View file

@ -1,7 +1,7 @@
// coverage:ignore-file // coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'station_status.dart'; part of 'station_status.dart';

View file

@ -1,7 +1,7 @@
// coverage:ignore-file // coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'station_train.dart'; part of 'station_train.dart';
@ -189,6 +189,7 @@ class _$_StationTrain implements _StationTrain {
List<String>? get route { List<String>? get route {
final value = _route; final value = _route;
if (value == null) return null; if (value == null) return null;
if (_route is EqualUnmodifiableListView) return _route;
// ignore: implicit_dynamic_type // ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value); return EqualUnmodifiableListView(value);
} }

View file

@ -1,7 +1,7 @@
// coverage:ignore-file // coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'stations_result.dart'; part of 'stations_result.dart';
@ -121,6 +121,7 @@ class _$_StationsResult implements _StationsResult {
List<String>? get stoppedAtBy { List<String>? get stoppedAtBy {
final value = _stoppedAtBy; final value = _stoppedAtBy;
if (value == null) return null; if (value == null) return null;
if (_stoppedAtBy is EqualUnmodifiableListView) return _stoppedAtBy;
// ignore: implicit_dynamic_type // ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value); return EqualUnmodifiableListView(value);
} }

View file

@ -4,181 +4,118 @@
import 'dart:convert'; import 'dart:convert';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'train_data.freezed.dart';
part 'train_data.g.dart';
TrainData trainDataFromJson(String str) => TrainData.fromJson(json.decode(str)); TrainData trainDataFromJson(String str) => TrainData.fromJson(json.decode(str));
String trainDataToJson(TrainData data) => json.encode(data.toJson()); String trainDataToJson(TrainData data) => json.encode(data.toJson());
/// Results of scrapping InfoFer website for train info /// Results of scrapping InfoFer website for train info
class TrainData { @freezed
TrainData({ class TrainData with _$TrainData {
required this.date, const TrainData._();
required this.number,
required this.operator,
required this.rank,
required this.route,
required this.stations,
this.status,
});
final String date; const factory TrainData({
final String number; required String rank,
final String operator; required String number,
final String rank; required String date,
final Route route; required String operator,
final List<Station> stations; required List<TrainDataGroup> groups,
final TrainDataStatus? status; }) = _TrainData;
factory TrainData.fromJson(Map<String, dynamic> json) => TrainData( factory TrainData.fromJson(Map<String, dynamic> json) => _$TrainDataFromJson(json);
date: json["date"],
number: json["number"],
operator: json["operator"],
rank: json["rank"],
route: Route.fromJson(json["route"]),
stations: List<Station>.from(
json["stations"].map((x) => Station.fromJson(x))),
status: json["status"] == null
? null
: TrainDataStatus.fromJson(json["status"]),
);
Map<String, dynamic> toJson() => { TrainDataGroup get idealGroup {
"date": date, var result = groups.first;
"number": number,
"operator": operator, for (final group in groups) {
"rank": rank, if (result.stations.map((s) => s.linkName).toSet().difference(group.stations.map((s) => s.linkName).toSet()).isEmpty) {
"route": route.toJson(), result = group;
"stations": List<dynamic>.from(stations.map((x) => x.toJson())), }
"status": status?.toJson(), }
};
return result;
}
List<TrainDataStation> get stations => idealGroup.stations;
TrainDataRoute get route => idealGroup.route;
TrainDataStatus? get status => idealGroup.status;
}
@freezed
class TrainDataGroup with _$TrainDataGroup {
const factory TrainDataGroup({
required TrainDataRoute route,
required List<TrainDataStation> stations,
TrainDataStatus? status,
}) = _TrainDataGroup;
factory TrainDataGroup.fromJson(Map<String, dynamic> json) => _$TrainDataGroupFromJson(json);
} }
/// Route of the train /// Route of the train
class Route { @freezed
Route({ class TrainDataRoute with _$TrainDataRoute {
required this.from, const factory TrainDataRoute({
required this.to, required String from,
}); required String to,
}) = _TrainDataRoute;
final String from; factory TrainDataRoute.fromJson(Map<String, dynamic> json) => _$TrainDataRouteFromJson(json);
final String to;
factory Route.fromJson(Map<String, dynamic> json) => Route(
from: json["from"],
to: json["to"],
);
Map<String, dynamic> toJson() => {
"from": from,
"to": to,
};
} }
class Station { @freezed
Station({ class TrainDataStation with _$TrainDataStation {
this.arrival, const factory TrainDataStation({
this.departure, required String name,
required this.km, required String linkName,
required this.name, required int km,
this.platform, int? stoppingTime,
this.stoppingTime, String? platform,
}); StationArrDepTime? arrival,
StationArrDepTime? departure,
@TrainDataNoteConverter()
required List<TrainDataNote> notes,
}) = _TrainDataStation;
final StationArrDepTime? arrival; factory TrainDataStation.fromJson(Map<String, dynamic> json) => _$TrainDataStationFromJson(json);
final StationArrDepTime? departure;
final int km;
final String name;
final String? platform;
final int? stoppingTime;
factory Station.fromJson(Map<String, dynamic> json) => Station(
arrival: json["arrival"] == null
? null
: StationArrDepTime.fromJson(json["arrival"]),
departure: json["departure"] == null
? null
: StationArrDepTime.fromJson(json["departure"]),
km: json["km"],
name: json["name"],
platform: json["platform"],
stoppingTime:
json["stoppingTime"],
);
Map<String, dynamic> toJson() => {
"arrival": arrival?.toJson(),
"departure": departure?.toJson(),
"km": km,
"name": name,
"platform": platform,
"stoppingTime": stoppingTime,
};
} }
class StationArrDepTime { @freezed
StationArrDepTime({ class StationArrDepTime with _$StationArrDepTime {
required this.scheduleTime, const factory StationArrDepTime({
this.status, required DateTime scheduleTime,
}); StationArrDepTimeStatus? status,
}) = _StationArrDepTime;
final DateTime scheduleTime; factory StationArrDepTime.fromJson(Map<String, dynamic> json) => _$StationArrDepTimeFromJson(json);
final StationArrDepTimeStatus? status;
factory StationArrDepTime.fromJson(Map<String, dynamic> json) =>
StationArrDepTime(
scheduleTime: DateTime.parse(json["scheduleTime"] as String),
status: json["status"] == null ? null : StationArrDepTimeStatus.fromJson(json["status"]),
);
Map<String, dynamic> toJson() => {
"scheduleTime": scheduleTime.toIso8601String(),
"status": status?.toJson(),
};
} }
class StationArrDepTimeStatus { @freezed
StationArrDepTimeStatus({ class StationArrDepTimeStatus with _$StationArrDepTimeStatus {
required this.delay, const factory StationArrDepTimeStatus({
required this.real, required int delay,
}); required bool real,
required bool cancelled,
}) = _StationArrDepTimeStatus;
final int delay; factory StationArrDepTimeStatus.fromJson(Map<String, dynamic> json) => _$StationArrDepTimeStatusFromJson(json);
final bool real;
factory StationArrDepTimeStatus.fromJson(Map<String, dynamic> json) =>
StationArrDepTimeStatus(
delay: json["delay"],
real: json["real"],
);
Map<String, dynamic> toJson() => {
"delay": delay,
"real": real,
};
} }
class TrainDataStatus { @freezed
TrainDataStatus({ class TrainDataStatus with _$TrainDataStatus {
required this.delay, const TrainDataStatus._();
required this.state,
required this.station,
});
final int delay; const factory TrainDataStatus({
final State state; required int delay,
final String station; required String station,
required TrainDataStatusState state,
}) = _TrainDataStatus;
factory TrainDataStatus.fromJson(Map<String, dynamic> json) => factory TrainDataStatus.fromJson(Map<String, dynamic> json) => _$TrainDataStatusFromJson(json);
TrainDataStatus(
delay: json["delay"],
state: stateValues.map[json["state"]]!,
station: json["station"],
);
Map<String, dynamic> toJson() => {
"delay": delay,
"state": stateValues.reverse[state],
"station": station,
};
@override @override
String toString() { String toString() {
@ -190,38 +127,118 @@ class TrainDataStatus {
result += '${delay.abs()} min'; result += '${delay.abs()} min';
} }
result += ' la '; result += ' la ';
switch (state) { result += switch (state) {
case State.PASSING: TrainDataStatusState.passing => 'trecerea fără oprire prin',
result += 'trecerea fără oprire prin'; TrainDataStatusState.arrival => 'sosirea în',
break; TrainDataStatusState.departure => 'plecarea din',
case State.ARRIVAL: };
result += 'sosirea în';
break;
case State.DEPARTURE:
result += 'plecarea din';
break;
}
result += station; result += station;
return result; return result;
} }
} }
enum State { PASSING, ARRIVAL, DEPARTURE } enum TrainDataStatusState { passing, arrival, departure }
final stateValues = EnumValues({ abstract class TrainDataNote {
"arrival": State.ARRIVAL, final String kind;
"departure": State.DEPARTURE,
"passing": State.PASSING
});
class EnumValues<T> { const TrainDataNote({required this.kind});
Map<String, T> map;
Map<T, String>? reverseMap;
EnumValues(this.map); Map<String, dynamic> toJson() => {
"kind": kind,
};
}
Map<T, String> get reverse { class TrainDataNoteConverter implements JsonConverter<TrainDataNote, Map<String, dynamic>> {
reverseMap ??= map.map((k, v) => MapEntry(v, k)); const TrainDataNoteConverter();
return reverseMap!;
@override
TrainDataNote fromJson(Map<String, dynamic> json) {
return switch(json['kind']) {
'trainNumberChange' => TrainDataNoteTrainNumberChange.fromJson(json),
'departsAs' => TrainDataNoteDepartsAs.fromJson(json),
'detachingWagons' => TrainDataNoteDetachingWagons.fromJson(json),
'receivingWagons' => TrainDataNoteReceivingWagons.fromJson(json),
_ => TrainDataNoteUnknown.fromJson(json),
};
}
@override
Map<String, dynamic> toJson(TrainDataNote object) {
return object.toJson();
} }
} }
@freezed
class TrainDataNoteTrainNumberChange with _$TrainDataNoteTrainNumberChange implements TrainDataNote {
@Implements<TrainDataNote>()
const factory TrainDataNoteTrainNumberChange({
// base
@Default("trainNumberChange")
String kind,
// impl
required String rank,
required String number,
}) = _TrainDataNoteTrainNumberChange;
factory TrainDataNoteTrainNumberChange.fromJson(Map<String, dynamic> json) => _$TrainDataNoteTrainNumberChangeFromJson(json);
}
@freezed
class TrainDataNoteDepartsAs with _$TrainDataNoteDepartsAs implements TrainDataNote {
@Implements<TrainDataNote>()
const factory TrainDataNoteDepartsAs({
// base
@Default("departsAs")
String kind,
// impl
required String rank,
required String number,
required DateTime departureDate,
}) = _TrainDataNoteDepartsAs;
factory TrainDataNoteDepartsAs.fromJson(Map<String, dynamic> json) => _$TrainDataNoteDepartsAsFromJson(json);
}
@freezed
class TrainDataNoteDetachingWagons with _$TrainDataNoteDetachingWagons implements TrainDataNote {
@Implements<TrainDataNote>()
const factory TrainDataNoteDetachingWagons({
// base
@Default("detachingWagons")
String kind,
// impl
required String station,
}) = _TrainDataNoteDetachingWagons;
factory TrainDataNoteDetachingWagons.fromJson(Map<String, dynamic> json) => _$TrainDataNoteDetachingWagonsFromJson(json);
}
@freezed
class TrainDataNoteReceivingWagons with _$TrainDataNoteReceivingWagons implements TrainDataNote {
@Implements<TrainDataNote>()
const factory TrainDataNoteReceivingWagons({
// base
@Default("receivingWagons")
String kind,
// impl
required String station,
}) = _TrainDataNoteReceivingWagons;
factory TrainDataNoteReceivingWagons.fromJson(Map<String, dynamic> json) => _$TrainDataNoteReceivingWagonsFromJson(json);
}
@freezed
class TrainDataNoteUnknown with _$TrainDataNoteUnknown implements TrainDataNote {
@Implements<TrainDataNote>()
const factory TrainDataNoteUnknown({
// base
required String kind,
// impl
required Map<String, dynamic> extra,
}) = _TrainDataNoteUnknown;
factory TrainDataNoteUnknown.fromJson(Map<String, dynamic> json) => TrainDataNoteUnknown(
kind: json['kind'],
extra: Map.from(json)..remove('kind'),
);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,217 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'train_data.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_TrainData _$$_TrainDataFromJson(Map<String, dynamic> json) => _$_TrainData(
rank: json['rank'] as String,
number: json['number'] as String,
date: json['date'] as String,
operator: json['operator'] as String,
groups: (json['groups'] as List<dynamic>)
.map((e) => TrainDataGroup.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$_TrainDataToJson(_$_TrainData instance) =>
<String, dynamic>{
'rank': instance.rank,
'number': instance.number,
'date': instance.date,
'operator': instance.operator,
'groups': instance.groups,
};
_$_TrainDataGroup _$$_TrainDataGroupFromJson(Map<String, dynamic> json) =>
_$_TrainDataGroup(
route: TrainDataRoute.fromJson(json['route'] as Map<String, dynamic>),
stations: (json['stations'] as List<dynamic>)
.map((e) => TrainDataStation.fromJson(e as Map<String, dynamic>))
.toList(),
status: json['status'] == null
? null
: TrainDataStatus.fromJson(json['status'] as Map<String, dynamic>),
);
Map<String, dynamic> _$$_TrainDataGroupToJson(_$_TrainDataGroup instance) =>
<String, dynamic>{
'route': instance.route,
'stations': instance.stations,
'status': instance.status,
};
_$_TrainDataRoute _$$_TrainDataRouteFromJson(Map<String, dynamic> json) =>
_$_TrainDataRoute(
from: json['from'] as String,
to: json['to'] as String,
);
Map<String, dynamic> _$$_TrainDataRouteToJson(_$_TrainDataRoute instance) =>
<String, dynamic>{
'from': instance.from,
'to': instance.to,
};
_$_TrainDataStation _$$_TrainDataStationFromJson(Map<String, dynamic> json) =>
_$_TrainDataStation(
name: json['name'] as String,
linkName: json['linkName'] as String,
km: json['km'] as int,
stoppingTime: json['stoppingTime'] as int?,
platform: json['platform'] as String?,
arrival: json['arrival'] == null
? null
: StationArrDepTime.fromJson(json['arrival'] as Map<String, dynamic>),
departure: json['departure'] == null
? null
: StationArrDepTime.fromJson(
json['departure'] as Map<String, dynamic>),
notes: (json['notes'] as List<dynamic>)
.map((e) => const TrainDataNoteConverter()
.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$_TrainDataStationToJson(_$_TrainDataStation instance) =>
<String, dynamic>{
'name': instance.name,
'linkName': instance.linkName,
'km': instance.km,
'stoppingTime': instance.stoppingTime,
'platform': instance.platform,
'arrival': instance.arrival,
'departure': instance.departure,
'notes':
instance.notes.map(const TrainDataNoteConverter().toJson).toList(),
};
_$_StationArrDepTime _$$_StationArrDepTimeFromJson(Map<String, dynamic> json) =>
_$_StationArrDepTime(
scheduleTime: DateTime.parse(json['scheduleTime'] as String),
status: json['status'] == null
? null
: StationArrDepTimeStatus.fromJson(
json['status'] as Map<String, dynamic>),
);
Map<String, dynamic> _$$_StationArrDepTimeToJson(
_$_StationArrDepTime instance) =>
<String, dynamic>{
'scheduleTime': instance.scheduleTime.toIso8601String(),
'status': instance.status,
};
_$_StationArrDepTimeStatus _$$_StationArrDepTimeStatusFromJson(
Map<String, dynamic> json) =>
_$_StationArrDepTimeStatus(
delay: json['delay'] as int,
real: json['real'] as bool,
cancelled: json['cancelled'] as bool,
);
Map<String, dynamic> _$$_StationArrDepTimeStatusToJson(
_$_StationArrDepTimeStatus instance) =>
<String, dynamic>{
'delay': instance.delay,
'real': instance.real,
'cancelled': instance.cancelled,
};
_$_TrainDataStatus _$$_TrainDataStatusFromJson(Map<String, dynamic> json) =>
_$_TrainDataStatus(
delay: json['delay'] as int,
station: json['station'] as String,
state: $enumDecode(_$TrainDataStatusStateEnumMap, json['state']),
);
Map<String, dynamic> _$$_TrainDataStatusToJson(_$_TrainDataStatus instance) =>
<String, dynamic>{
'delay': instance.delay,
'station': instance.station,
'state': _$TrainDataStatusStateEnumMap[instance.state]!,
};
const _$TrainDataStatusStateEnumMap = {
TrainDataStatusState.passing: 'passing',
TrainDataStatusState.arrival: 'arrival',
TrainDataStatusState.departure: 'departure',
};
_$_TrainDataNoteTrainNumberChange _$$_TrainDataNoteTrainNumberChangeFromJson(
Map<String, dynamic> json) =>
_$_TrainDataNoteTrainNumberChange(
kind: json['kind'] as String? ?? "trainNumberChange",
rank: json['rank'] as String,
number: json['number'] as String,
);
Map<String, dynamic> _$$_TrainDataNoteTrainNumberChangeToJson(
_$_TrainDataNoteTrainNumberChange instance) =>
<String, dynamic>{
'kind': instance.kind,
'rank': instance.rank,
'number': instance.number,
};
_$_TrainDataNoteDepartsAs _$$_TrainDataNoteDepartsAsFromJson(
Map<String, dynamic> json) =>
_$_TrainDataNoteDepartsAs(
kind: json['kind'] as String? ?? "departsAs",
rank: json['rank'] as String,
number: json['number'] as String,
departureDate: DateTime.parse(json['departureDate'] as String),
);
Map<String, dynamic> _$$_TrainDataNoteDepartsAsToJson(
_$_TrainDataNoteDepartsAs instance) =>
<String, dynamic>{
'kind': instance.kind,
'rank': instance.rank,
'number': instance.number,
'departureDate': instance.departureDate.toIso8601String(),
};
_$_TrainDataNoteDetachingWagons _$$_TrainDataNoteDetachingWagonsFromJson(
Map<String, dynamic> json) =>
_$_TrainDataNoteDetachingWagons(
kind: json['kind'] as String? ?? "detachingWagons",
station: json['station'] as String,
);
Map<String, dynamic> _$$_TrainDataNoteDetachingWagonsToJson(
_$_TrainDataNoteDetachingWagons instance) =>
<String, dynamic>{
'kind': instance.kind,
'station': instance.station,
};
_$_TrainDataNoteReceivingWagons _$$_TrainDataNoteReceivingWagonsFromJson(
Map<String, dynamic> json) =>
_$_TrainDataNoteReceivingWagons(
kind: json['kind'] as String? ?? "receivingWagons",
station: json['station'] as String,
);
Map<String, dynamic> _$$_TrainDataNoteReceivingWagonsToJson(
_$_TrainDataNoteReceivingWagons instance) =>
<String, dynamic>{
'kind': instance.kind,
'station': instance.station,
};
_$_TrainDataNoteUnknown _$$_TrainDataNoteUnknownFromJson(
Map<String, dynamic> json) =>
_$_TrainDataNoteUnknown(
kind: json['kind'] as String,
extra: json['extra'] as Map<String, dynamic>,
);
Map<String, dynamic> _$$_TrainDataNoteUnknownToJson(
_$_TrainDataNoteUnknown instance) =>
<String, dynamic>{
'kind': instance.kind,
'extra': instance.extra,
};

View file

@ -1,7 +1,7 @@
// coverage:ignore-file // coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'trains_result.dart'; part of 'trains_result.dart';

View file

@ -1,6 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:info_tren/components/cupertino_listtile.dart';
import 'package:info_tren/models.dart'; import 'package:info_tren/models.dart';
import 'package:info_tren/pages/settings/setings_page.dart'; import 'package:info_tren/pages/settings/setings_page.dart';
import 'package:info_tren/providers.dart'; import 'package:info_tren/providers.dart';

View file

@ -43,8 +43,9 @@ class ViewStationPage extends HookConsumerWidget {
class ViewStationArguments { class ViewStationArguments {
final String stationName; final String stationName;
final DateTime? date;
const ViewStationArguments({required this.stationName}); const ViewStationArguments({required this.stationName, this.date});
} }
abstract class ViewStationPageShared extends StatelessWidget { abstract class ViewStationPageShared extends StatelessWidget {

View file

@ -1,6 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart' hide Badge;
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:info_tren/components/badge/badge.dart'; import 'package:info_tren/components/badge/badge.dart';
import 'package:info_tren/components/loading/loading.dart'; import 'package:info_tren/components/loading/loading.dart';

View file

@ -1,4 +1,7 @@
import 'dart:async';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:info_tren/api/train_data.dart'; import 'package:info_tren/api/train_data.dart';
import 'package:info_tren/components/loading/loading.dart'; import 'package:info_tren/components/loading/loading.dart';
@ -9,59 +12,93 @@ import 'package:info_tren/pages/train_info_page/view_train/train_info_fluent.dar
import 'package:info_tren/pages/train_info_page/view_train/train_info_material.dart'; import 'package:info_tren/pages/train_info_page/view_train/train_info_material.dart';
import 'package:info_tren/providers.dart'; import 'package:info_tren/providers.dart';
class TrainInfo extends HookConsumerWidget {
class TrainInfo extends ConsumerWidget {
static String routeName = "/trainInfo/display"; static String routeName = "/trainInfo/display";
const TrainInfo({super.key,}); const TrainInfo({
super.key,
});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final uiDesign = ref.watch(uiDesignProvider); final uiDesign = ref.watch(uiDesignProvider);
final args = ref.watch(trainInfoArgumentsProvider); final args = ref.watch(trainInfoArgumentsProvider);
final trainNumber = args.trainNumber; final trainNumber = args.trainNumber;
final date = args.date; final viewYesterday = useState(false);
final date = args.date ??
DateTime.now().copyWith(
hour: 12,
minute: 0,
second: 0,
millisecond: 0,
microsecond: 0,
);
final requestDate =
viewYesterday.value ? date.subtract(const Duration(days: 1)) : date;
final trainDataAsync = ref
.watch(trainInfoProvider(trainNumber: trainNumber, date: requestDate));
Future refresh() async {
ref.invalidate(
trainInfoProvider(trainNumber: trainNumber, date: requestDate),
);
await Future.delayed(const Duration(seconds: 1));
}
return RefreshFutureBuilder<TrainData>(
futureCreator: () => getTrain(trainNumber, date: date),
builder: (context, refresh, replaceFutureBuilder, snapshot) {
void onViewYesterdayTrain() { void onViewYesterdayTrain() {
replaceFutureBuilder(() => getTrain(trainNumber, date: DateTime.now().subtract(const Duration(days: 1)))); viewYesterday.value = !viewYesterday.value;
} }
if ([RefreshFutureBuilderState.none, RefreshFutureBuilderState.waiting].contains(snapshot.state)) { useEffect(() {
return TrainInfoLoading(title: trainNumber.toString(), loadingText: "Se încarcă...",); final handle = Timer.periodic(const Duration(minutes: 1), (timer) {
} refresh();
else if (snapshot.state == RefreshFutureBuilderState.error) { });
return TrainInfoError(title: '$trainNumber - Error', error: snapshot.error!, refresh: refresh,); return () {
} handle.cancel();
};
});
return trainDataAsync.when(
data: (data) {
switch (uiDesign) { switch (uiDesign) {
case UiDesign.MATERIAL: case UiDesign.MATERIAL:
return TrainInfoMaterial( return TrainInfoMaterial(
trainData: snapshot.data!, trainData: data,
refresh: refresh, refresh: refresh,
isRefreshing: snapshot.state == RefreshFutureBuilderState.refreshing, isRefreshing: trainDataAsync.isRefreshing,
onViewYesterdayTrain: onViewYesterdayTrain, onViewYesterdayTrain: onViewYesterdayTrain,
); );
case UiDesign.CUPERTINO: case UiDesign.CUPERTINO:
return TrainInfoCupertino( return TrainInfoCupertino(
trainData: snapshot.data!, trainData: data,
refresh: refresh, refresh: refresh,
isRefreshing: snapshot.state == RefreshFutureBuilderState.refreshing, isRefreshing: trainDataAsync.isRefreshing,
onViewYesterdayTrain: onViewYesterdayTrain, onViewYesterdayTrain: onViewYesterdayTrain,
); );
case UiDesign.FLUENT: case UiDesign.FLUENT:
return TrainInfoFluent( return TrainInfoFluent(
trainData: snapshot.data!, trainData: data,
refresh: refresh, refresh: refresh,
isRefreshing: snapshot.state == RefreshFutureBuilderState.refreshing, isRefreshing: trainDataAsync.isRefreshing,
onViewYesterdayTrain: onViewYesterdayTrain, onViewYesterdayTrain: onViewYesterdayTrain,
); );
default: default:
throw UnmatchedUiDesignException(uiDesign); throw UnmatchedUiDesignException(uiDesign);
} }
}, },
error: (e, st) {
return TrainInfoError(
title: '$trainNumber - Error',
error: e,
refresh: refresh,
);
},
loading: () {
return TrainInfoLoading(
title: trainNumber.toString(),
loadingText: "Se încarcă...",
);
},
); );
} }
} }
@ -132,7 +169,9 @@ abstract class TrainInfoLoadingShared extends StatelessWidget {
required this.title, required this.title,
String? loadingText, String? loadingText,
super.key, super.key,
}) : loadingWidget = Loading(text: loadingText,); }) : loadingWidget = Loading(
text: loadingText,
);
} }
class TrainInfoError extends ConsumerWidget { class TrainInfoError extends ConsumerWidget {
@ -181,7 +220,12 @@ abstract class TrainInfoErrorShared extends StatelessWidget {
final Object error; final Object error;
final Future Function()? refresh; final Future Function()? refresh;
const TrainInfoErrorShared({required this.title, required this.error, this.refresh, super.key,}); const TrainInfoErrorShared({
required this.title,
required this.error,
this.refresh,
super.key,
});
} }
class TrainInfoBody extends ConsumerWidget { class TrainInfoBody extends ConsumerWidget {
@ -246,10 +290,15 @@ abstract class TrainInfoBodyShared extends StatelessWidget {
} }
abstract class DisplayTrainYesterdayWarningCommon extends StatelessWidget { abstract class DisplayTrainYesterdayWarningCommon extends StatelessWidget {
static const trainDidNotDepart = 'Acest tren nu a plecat încă din prima gară.'; static const trainDidNotDepart =
static const seeYesterdayTrain = 'Apasă aici pentru a vedea trenul care a plecat ieri.'; 'Acest tren nu a plecat încă din prima gară.';
static const seeYesterdayTrain =
'Apasă aici pentru a vedea trenul care a plecat ieri.';
final void Function() onViewYesterdayTrain; final void Function() onViewYesterdayTrain;
const DisplayTrainYesterdayWarningCommon(this.onViewYesterdayTrain, {super.key,}); const DisplayTrainYesterdayWarningCommon(
this.onViewYesterdayTrain, {
super.key,
});
} }

View file

@ -1051,8 +1051,8 @@ class DisplayTrainYesterdayWarningCupertino extends DisplayTrainYesterdayWarning
const TextSpan(text: '\n'), const TextSpan(text: '\n'),
TextSpan( TextSpan(
text: DisplayTrainYesterdayWarningCommon.seeYesterdayTrain, text: DisplayTrainYesterdayWarningCommon.seeYesterdayTrain,
style: const TextStyle( style: TextStyle(
color: CupertinoColors.link, color: CupertinoTheme.of(context).primaryColor,
), ),
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()
..onTap = onViewYesterdayTrain, ..onTap = onViewYesterdayTrain,

View file

@ -1,13 +1,18 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:info_tren/components/badge/badge.dart'; import 'package:info_tren/components/badge/badge.dart';
import 'package:info_tren/components/cupertino_divider.dart';
import 'package:info_tren/components/train_id_text_span.dart';
import 'package:info_tren/models.dart'; import 'package:info_tren/models.dart';
import 'package:info_tren/providers.dart'; import 'package:info_tren/providers.dart';
class DisplayTrainStation extends StatelessWidget { class DisplayTrainStation extends StatelessWidget {
final Station station; final TrainDataStation station;
const DisplayTrainStation({required this.station, super.key,}); const DisplayTrainStation({
required this.station,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -15,6 +20,26 @@ class DisplayTrainStation extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
if (station.notes.whereType<TrainDataNoteDepartsAs>().isNotEmpty) ...[
Builder(
builder: (context) {
final note =
station.notes.whereType<TrainDataNoteDepartsAs>().first;
return Padding(
padding: const EdgeInsets.all(2.0),
child: Text.rich(
TextSpan(
children: [
const TextSpan(text: 'Trenul pleacă cu numărul '),
trainIdSpan(rank: note.rank, number: note.number),
],
),
),
);
},
),
const CupertinoDivider(),
],
Row( Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
@ -22,8 +47,7 @@ class DisplayTrainStation extends StatelessWidget {
flex: 1, flex: 1,
child: Align( child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Builder( child: Builder(builder: (context) {
builder: (context) {
final departureStatus = station.departure?.status; final departureStatus = station.departure?.status;
final arrivalStatus = station.arrival?.status; final arrivalStatus = station.arrival?.status;
int delay; int delay;
@ -31,12 +55,10 @@ class DisplayTrainStation extends StatelessWidget {
if (departureStatus == null) { if (departureStatus == null) {
delay = arrivalStatus?.delay ?? 0; delay = arrivalStatus?.delay ?? 0;
real = arrivalStatus?.real ?? false; real = arrivalStatus?.real ?? false;
} } else if (arrivalStatus == null) {
else if (arrivalStatus == null) {
delay = departureStatus.delay; delay = departureStatus.delay;
real = departureStatus.real; real = departureStatus.real;
} } else {
else {
delay = departureStatus.delay; delay = departureStatus.delay;
real = departureStatus.real; real = departureStatus.real;
if (!real && arrivalStatus.real) { if (!real && arrivalStatus.real) {
@ -56,8 +78,7 @@ class DisplayTrainStation extends StatelessWidget {
isDelayed: isDelayed, isDelayed: isDelayed,
isOnTime: isOnTime, isOnTime: isOnTime,
); );
} }),
),
), ),
), ),
Title( Title(
@ -67,7 +88,9 @@ class DisplayTrainStation extends StatelessWidget {
flex: 1, flex: 1,
child: Align( child: Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: station.platform == null ? Container() : Badge(text: station.platform!, caption: 'linia'), child: station.platform == null
? Container()
: Badge(text: station.platform!, caption: 'linia'),
), ),
), ),
], ],
@ -75,16 +98,61 @@ class DisplayTrainStation extends StatelessWidget {
Time( Time(
station: station, station: station,
), ),
if (station.notes.whereType<TrainDataNoteDetachingWagons>().isNotEmpty)
Builder(
builder: (context) {
final note =
station.notes.whereType<TrainDataNoteDetachingWagons>().first;
return Text(
'Trenul detașează vagoane către ${note.station}',
textAlign: TextAlign.center,
);
},
),
if (station.notes.whereType<TrainDataNoteReceivingWagons>().isNotEmpty)
Builder(
builder: (context) {
final note =
station.notes.whereType<TrainDataNoteReceivingWagons>().first;
return Text(
'Trenul primește vagoane de la ${note.station}',
textAlign: TextAlign.center,
);
},
),
Delay( Delay(
station: station, station: station,
), ),
if (station.notes
.whereType<TrainDataNoteTrainNumberChange>()
.isNotEmpty) ...[
const CupertinoDivider(),
Builder(
builder: (context) {
final note = station.notes
.whereType<TrainDataNoteTrainNumberChange>()
.first;
return Padding(
padding: const EdgeInsets.all(2.0),
child: Text.rich(
TextSpan(
children: [
const TextSpan(text: 'Trenul își schimbă numărul în '),
trainIdSpan(rank: note.rank, number: note.number),
],
),
),
);
},
),
],
], ],
); );
} }
} }
class Title extends StatelessWidget { class Title extends StatelessWidget {
final Station station; final TrainDataStation station;
const Title({ const Title({
required this.station, required this.station,
@ -97,7 +165,9 @@ class Title extends StatelessWidget {
station.name, station.name,
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith( style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(
fontSize: 22, fontSize: 22,
fontWeight: MediaQuery.of(context).boldText ? FontWeight.w500 : FontWeight.w300, fontWeight: MediaQuery.of(context).boldText
? FontWeight.w500
: FontWeight.w300,
// fontStyle: items[1] == "ONI" ? FontStyle.italic : FontStyle.normal, // fontStyle: items[1] == "ONI" ? FontStyle.italic : FontStyle.normal,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -106,7 +176,7 @@ class Title extends StatelessWidget {
} }
class Time extends StatelessWidget { class Time extends StatelessWidget {
final Station station; final TrainDataStation station;
const Time({ const Time({
required this.station, required this.station,
@ -140,13 +210,27 @@ class Time extends StatelessWidget {
fontSize: 22, fontSize: 22,
), ),
), ),
Container(width: 2,), Container(
ArrivalTime(station: station,), width: 2,
Expanded(child: Container(),), ),
StopTime(station: station,), ArrivalTime(
Expanded(child: Container(),), station: station,
DepartureTime(station: station,), ),
Container(width: 2,), Expanded(
child: Container(),
),
StopTime(
station: station,
),
Expanded(
child: Container(),
),
DepartureTime(
station: station,
),
Container(
width: 2,
),
Text( Text(
"", "",
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith( style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(
@ -159,7 +243,7 @@ class Time extends StatelessWidget {
} }
class ArrivalTime extends ConsumerWidget { class ArrivalTime extends ConsumerWidget {
final Station station; final TrainDataStation station;
final bool finalStation; final bool finalStation;
const ArrivalTime({ const ArrivalTime({
@ -182,21 +266,26 @@ class ArrivalTime extends ConsumerWidget {
fontSize: 22, fontSize: 22,
), ),
), ),
Container(width: 2,), Container(
width: 2,
),
const Text("sosire la "), const Text("sosire la "),
ArrivalTime(station: station,), ArrivalTime(
Expanded(child: Container(),), station: station,
),
Expanded(
child: Container(),
),
], ],
); );
} } else {
else {
final delay = station.arrival!.status?.delay ?? 0; final delay = station.arrival!.status?.delay ?? 0;
final time = tz.convertDateTime(station.arrival!.scheduleTime); final time = tz.convertDateTime(station.arrival!.scheduleTime);
if (delay == 0) { if (delay == 0) {
return Text("${time.hour.toString().padLeft(2, "0")}:${time.minute.toString().padLeft(2, "0")}"); return Text(
} "${time.hour.toString().padLeft(2, "0")}:${time.minute.toString().padLeft(2, "0")}");
else if (delay > 0) { } else if (delay > 0) {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -217,8 +306,7 @@ class ArrivalTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -245,7 +333,7 @@ class ArrivalTime extends ConsumerWidget {
} }
class StopTime extends StatelessWidget { class StopTime extends StatelessWidget {
final Station station; final TrainDataStation station;
const StopTime({ const StopTime({
required this.station, required this.station,
@ -275,14 +363,12 @@ class StopTime extends StatelessWidget {
minutes ? '1 minut' : '1 secundă', minutes ? '1 minut' : '1 secundă',
textAlign: TextAlign.center, textAlign: TextAlign.center,
); );
} } else if (stopsForInt < 20) {
else if (stopsForInt < 20) {
return Text( return Text(
'$stopsForInt ${minutes ? 'minute' : 'seconde'}', '$stopsForInt ${minutes ? 'minute' : 'seconde'}',
textAlign: TextAlign.center, textAlign: TextAlign.center,
); );
} } else {
else {
return Text( return Text(
'$stopsForInt de ${minutes ? 'minute' : 'secunde'}', '$stopsForInt de ${minutes ? 'minute' : 'secunde'}',
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -296,7 +382,7 @@ class StopTime extends StatelessWidget {
} }
class DepartureTime extends ConsumerWidget { class DepartureTime extends ConsumerWidget {
final Station station; final TrainDataStation station;
final bool firstStation; final bool firstStation;
const DepartureTime({ const DepartureTime({
@ -312,10 +398,16 @@ class DepartureTime extends ConsumerWidget {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Expanded(child: Container(),), Expanded(
child: Container(),
),
const Text("plecare la "), const Text("plecare la "),
DepartureTime(station: station,), DepartureTime(
Container(width: 2,), station: station,
),
Container(
width: 2,
),
Text( Text(
"", "",
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith( style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(
@ -324,15 +416,14 @@ class DepartureTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final delay = station.departure!.status?.delay ?? 0; final delay = station.departure!.status?.delay ?? 0;
final time = tz.convertDateTime(station.departure!.scheduleTime); final time = tz.convertDateTime(station.departure!.scheduleTime);
if (delay == 0) { if (delay == 0) {
return Text("${time.hour.toString().padLeft(2, "0")}:${time.minute.toString().padLeft(2, "0")}"); return Text(
} "${time.hour.toString().padLeft(2, "0")}:${time.minute.toString().padLeft(2, "0")}");
else if (delay > 0) { } else if (delay > 0) {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -353,8 +444,7 @@ class DepartureTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -381,7 +471,7 @@ class DepartureTime extends ConsumerWidget {
} }
class Delay extends StatelessWidget { class Delay extends StatelessWidget {
final Station station; final TrainDataStation station;
const Delay({ const Delay({
required this.station, required this.station,
@ -409,8 +499,7 @@ class Delay extends StatelessWidget {
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
), ),
); );
} } else if (delay < 0) {
else if (delay < 0) {
return Text( return Text(
"${-delay} ${delay == -1 ? 'minut' : 'minute'} mai devreme", "${-delay} ${delay == -1 ? 'minut' : 'minute'} mai devreme",
style: CupertinoTheme.of(context).textTheme.textStyle.copyWith( style: CupertinoTheme.of(context).textTheme.textStyle.copyWith(

View file

@ -748,7 +748,7 @@ class DisplayTrainYesterdayWarningFluent
TextSpan( TextSpan(
text: DisplayTrainYesterdayWarningCommon.seeYesterdayTrain, text: DisplayTrainYesterdayWarningCommon.seeYesterdayTrain,
style: TextStyle( style: TextStyle(
color: Colors.blue, color: FluentTheme.of(context).accentColor,// Colors.blue,
), ),
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()
..onTap = onViewYesterdayTrain, ..onTap = onViewYesterdayTrain,

View file

@ -1,18 +1,44 @@
import 'package:fluent_ui/fluent_ui.dart'; import 'package:fluent_ui/fluent_ui.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:info_tren/components/badge/badge.dart'; import 'package:info_tren/components/badge/badge.dart';
import 'package:info_tren/components/train_id_text_span.dart';
import 'package:info_tren/models.dart'; import 'package:info_tren/models.dart';
import 'package:info_tren/providers.dart'; import 'package:info_tren/providers.dart';
class DisplayTrainStation extends StatelessWidget { class DisplayTrainStation extends StatelessWidget {
final Station station; final TrainDataStation station;
final void Function()? onTap; final void Function()? onTap;
const DisplayTrainStation({required this.station, this.onTap, super.key,}); const DisplayTrainStation({
required this.station,
this.onTap,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
if (station.notes.whereType<TrainDataNoteDepartsAs>().isNotEmpty)
Builder(
builder: (context) {
final note =
station.notes.whereType<TrainDataNoteDepartsAs>().first;
return Padding( return Padding(
padding: const EdgeInsets.all(2.0),
child: Text.rich(
TextSpan(
children: [
const TextSpan(text: 'Trenul pleacă cu numărul '),
trainIdSpan(rank: note.rank, number: note.number),
],
),
),
);
},
),
Padding(
padding: const EdgeInsets.all(2), padding: const EdgeInsets.all(2),
child: HoverButton( child: HoverButton(
onPressed: onTap, onPressed: onTap,
@ -30,8 +56,7 @@ class DisplayTrainStation extends StatelessWidget {
flex: 1, flex: 1,
child: Align( child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Builder( child: Builder(builder: (context) {
builder: (context) {
final departureStatus = station.departure?.status; final departureStatus = station.departure?.status;
final arrivalStatus = station.arrival?.status; final arrivalStatus = station.arrival?.status;
int delay; int delay;
@ -39,12 +64,10 @@ class DisplayTrainStation extends StatelessWidget {
if (departureStatus == null) { if (departureStatus == null) {
delay = arrivalStatus?.delay ?? 0; delay = arrivalStatus?.delay ?? 0;
real = arrivalStatus?.real ?? false; real = arrivalStatus?.real ?? false;
} } else if (arrivalStatus == null) {
else if (arrivalStatus == null) {
delay = departureStatus.delay; delay = departureStatus.delay;
real = departureStatus.real; real = departureStatus.real;
} } else {
else {
delay = departureStatus.delay; delay = departureStatus.delay;
real = departureStatus.real; real = departureStatus.real;
if (!real && arrivalStatus.real) { if (!real && arrivalStatus.real) {
@ -64,8 +87,7 @@ class DisplayTrainStation extends StatelessWidget {
isDelayed: isDelayed, isDelayed: isDelayed,
isOnTime: isOnTime, isOnTime: isOnTime,
); );
} }),
),
), ),
), ),
Title( Title(
@ -77,7 +99,10 @@ class DisplayTrainStation extends StatelessWidget {
? Container() ? Container()
: Align( : Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Badge(text: station.platform!, caption: 'linia',), child: Badge(
text: station.platform!,
caption: 'linia',
),
), ),
), ),
], ],
@ -85,6 +110,34 @@ class DisplayTrainStation extends StatelessWidget {
Time( Time(
station: station, station: station,
), ),
if (station.notes
.whereType<TrainDataNoteDetachingWagons>()
.isNotEmpty)
Builder(
builder: (context) {
final note = station.notes
.whereType<TrainDataNoteDetachingWagons>()
.first;
return Text(
'Trenul detașează vagoane către ${note.station}',
textAlign: TextAlign.center,
);
},
),
if (station.notes
.whereType<TrainDataNoteReceivingWagons>()
.isNotEmpty)
Builder(
builder: (context) {
final note = station.notes
.whereType<TrainDataNoteReceivingWagons>()
.first;
return Text(
'Trenul primește vagoane de la ${note.station}',
textAlign: TextAlign.center,
);
},
),
Delay( Delay(
station: station, station: station,
), ),
@ -93,12 +146,35 @@ class DisplayTrainStation extends StatelessWidget {
); );
}, },
), ),
),
if (station.notes
.whereType<TrainDataNoteTrainNumberChange>()
.isNotEmpty)
Builder(
builder: (context) {
final note = station.notes
.whereType<TrainDataNoteTrainNumberChange>()
.first;
return Padding(
padding: const EdgeInsets.all(2.0),
child: Text.rich(
TextSpan(
children: [
const TextSpan(text: 'Trenul își schimbă numărul în '),
trainIdSpan(rank: note.rank, number: note.number),
],
),
),
);
},
),
],
); );
} }
} }
class Title extends StatelessWidget { class Title extends StatelessWidget {
final Station station; final TrainDataStation station;
const Title({ const Title({
required this.station, required this.station,
@ -111,7 +187,9 @@ class Title extends StatelessWidget {
station.name, station.name,
style: FluentTheme.of(context).typography.body?.copyWith( style: FluentTheme.of(context).typography.body?.copyWith(
fontSize: 22, fontSize: 22,
fontWeight: MediaQuery.of(context).boldText ? FontWeight.w500 : FontWeight.w300, fontWeight: MediaQuery.of(context).boldText
? FontWeight.w500
: FontWeight.w300,
// fontStyle: items[1] == "ONI" ? FontStyle.italic : FontStyle.normal, // fontStyle: items[1] == "ONI" ? FontStyle.italic : FontStyle.normal,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -120,7 +198,7 @@ class Title extends StatelessWidget {
} }
class Time extends StatelessWidget { class Time extends StatelessWidget {
final Station station; final TrainDataStation station;
const Time({ const Time({
required this.station, required this.station,
@ -154,13 +232,27 @@ class Time extends StatelessWidget {
fontSize: 22, fontSize: 22,
), ),
), ),
Container(width: 2,), Container(
ArrivalTime(station: station,), width: 2,
Expanded(child: Container(),), ),
StopTime(station: station,), ArrivalTime(
Expanded(child: Container(),), station: station,
DepartureTime(station: station,), ),
Container(width: 2,), Expanded(
child: Container(),
),
StopTime(
station: station,
),
Expanded(
child: Container(),
),
DepartureTime(
station: station,
),
Container(
width: 2,
),
Text( Text(
"", "",
style: FluentTheme.of(context).typography.body?.copyWith( style: FluentTheme.of(context).typography.body?.copyWith(
@ -173,7 +265,7 @@ class Time extends StatelessWidget {
} }
class ArrivalTime extends ConsumerWidget { class ArrivalTime extends ConsumerWidget {
final Station station; final TrainDataStation station;
final bool finalStation; final bool finalStation;
const ArrivalTime({ const ArrivalTime({
@ -198,21 +290,26 @@ class ArrivalTime extends ConsumerWidget {
fontSize: 22, fontSize: 22,
), ),
), ),
Container(width: 2,), Container(
width: 2,
),
const Text("sosire la "), const Text("sosire la "),
ArrivalTime(station: station,), ArrivalTime(
Expanded(child: Container(),), station: station,
),
Expanded(
child: Container(),
),
], ],
); );
} } else {
else {
final delay = station.arrival!.status?.delay ?? 0; final delay = station.arrival!.status?.delay ?? 0;
final time = tz.convertDateTime(station.arrival!.scheduleTime); final time = tz.convertDateTime(station.arrival!.scheduleTime);
if (delay == 0) { if (delay == 0) {
return Text("${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}"); return Text(
} "${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}");
else if (delay > 0) { } else if (delay > 0) {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -234,8 +331,7 @@ class ArrivalTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -263,7 +359,7 @@ class ArrivalTime extends ConsumerWidget {
} }
class StopTime extends StatelessWidget { class StopTime extends StatelessWidget {
final Station station; final TrainDataStation station;
const StopTime({ const StopTime({
required this.station, required this.station,
@ -292,14 +388,12 @@ class StopTime extends StatelessWidget {
"1 ${minutes ? 'minut' : 'secundă'}", "1 ${minutes ? 'minut' : 'secundă'}",
textAlign: TextAlign.center, textAlign: TextAlign.center,
); );
} } else if (stopsForInt < 20) {
else if (stopsForInt < 20) {
return Text( return Text(
"$stopsForInt ${minutes ? 'minute' : 'secunde'}", "$stopsForInt ${minutes ? 'minute' : 'secunde'}",
textAlign: TextAlign.center, textAlign: TextAlign.center,
); );
} } else {
else {
return Text( return Text(
"$stopsForInt de ${minutes ? 'minute' : 'secunde'}", "$stopsForInt de ${minutes ? 'minute' : 'secunde'}",
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -313,7 +407,7 @@ class StopTime extends StatelessWidget {
} }
class DepartureTime extends ConsumerWidget { class DepartureTime extends ConsumerWidget {
final Station station; final TrainDataStation station;
final bool firstStation; final bool firstStation;
const DepartureTime({ const DepartureTime({
@ -332,10 +426,16 @@ class DepartureTime extends ConsumerWidget {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Expanded(child: Container(),), Expanded(
child: Container(),
),
const Text("plecare la "), const Text("plecare la "),
DepartureTime(station: station,), DepartureTime(
Container(width: 2,), station: station,
),
Container(
width: 2,
),
Text( Text(
"", "",
style: FluentTheme.of(context).typography.body?.copyWith( style: FluentTheme.of(context).typography.body?.copyWith(
@ -344,15 +444,14 @@ class DepartureTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final delay = station.departure!.status?.delay ?? 0; final delay = station.departure!.status?.delay ?? 0;
final time = tz.convertDateTime(station.departure!.scheduleTime); final time = tz.convertDateTime(station.departure!.scheduleTime);
if (delay == 0) { if (delay == 0) {
return Text("${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}"); return Text(
} "${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}");
else if (delay > 0) { } else if (delay > 0) {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -374,8 +473,7 @@ class DepartureTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -402,9 +500,8 @@ class DepartureTime extends ConsumerWidget {
} }
} }
class Delay extends StatelessWidget { class Delay extends StatelessWidget {
final Station station; final TrainDataStation station;
const Delay({ const Delay({
required this.station, required this.station,
@ -433,8 +530,7 @@ class Delay extends StatelessWidget {
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
), ),
); );
} } else if (delay < 0) {
else if (delay < 0) {
return Text( return Text(
"${-delay} ${delay == -1 ? 'minut' : 'minute'} mai devreme", "${-delay} ${delay == -1 ? 'minut' : 'minute'} mai devreme",
style: FluentTheme.of(context).typography.body?.copyWith( style: FluentTheme.of(context).typography.body?.copyWith(

View file

@ -9,7 +9,11 @@ import 'package:info_tren/pages/train_info_page/view_train/train_info_material_D
import 'package:info_tren/utils/state_to_string.dart'; import 'package:info_tren/utils/state_to_string.dart';
class TrainInfoLoadingMaterial extends TrainInfoLoadingShared { class TrainInfoLoadingMaterial extends TrainInfoLoadingShared {
TrainInfoLoadingMaterial({required super.title, super.loadingText, super.key,}); TrainInfoLoadingMaterial({
required super.title,
super.loadingText,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -81,8 +85,29 @@ class TrainInfoMaterial extends TrainInfoShared {
: AppBar( : AppBar(
centerTitle: true, centerTitle: true,
title: Text( title: Text(
"Informații despre ${trainData.rank} ${trainData.number}", 'Informații despre ${trainData.rank} ${trainData.number}',
), ),
actions: [
IconButton(
tooltip: 'Reîncarcă',
icon: (isRefreshing ?? false)
? const Center(
child: SizedBox(
height: 16,
width: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
),
),
)
: const Icon(Icons.refresh),
onPressed: (isRefreshing ?? false)
? null
: () {
refresh?.call();
},
),
],
), ),
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
@ -172,8 +197,7 @@ class TrainInfoBodyMaterial extends TrainInfoBodyShared {
if (onViewYesterdayTrain != null && if (onViewYesterdayTrain != null &&
trainData.stations.first.departure!.scheduleTime trainData.stations.first.departure!.scheduleTime
.compareTo(DateTime.now()) > .compareTo(DateTime.now()) >
0) 0) ...[
...[
DisplayTrainYesterdayWarningMaterial( DisplayTrainYesterdayWarningMaterial(
onViewYesterdayTrain!, onViewYesterdayTrain!,
), ),
@ -193,10 +217,7 @@ class TrainInfoBodyMaterial extends TrainInfoBodyShared {
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Container( child: Container(
height: MediaQuery height: MediaQuery.of(context).viewPadding.bottom,
.of(context)
.viewPadding
.bottom,
), ),
), ),
], ],
@ -204,8 +225,7 @@ class TrainInfoBodyMaterial extends TrainInfoBodyShared {
), ),
], ],
); );
} } else {
else {
return CustomScrollView( return CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
SliverToBoxAdapter( SliverToBoxAdapter(
@ -284,8 +304,8 @@ class TrainInfoBodyMaterial extends TrainInfoBodyShared {
.compareTo(DateTime.now()) > .compareTo(DateTime.now()) >
0) ...[ 0) ...[
SliverToBoxAdapter( SliverToBoxAdapter(
child: DisplayTrainYesterdayWarningMaterial( child:
onViewYesterdayTrain!), DisplayTrainYesterdayWarningMaterial(onViewYesterdayTrain!),
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Divider( child: Divider(
@ -299,10 +319,7 @@ class TrainInfoBodyMaterial extends TrainInfoBodyShared {
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Container( child: Container(
height: MediaQuery height: MediaQuery.of(context).viewPadding.bottom,
.of(context)
.viewPadding
.bottom,
), ),
), ),
], ],
@ -314,7 +331,10 @@ class TrainInfoBodyMaterial extends TrainInfoBodyShared {
class DisplayTrainID extends StatelessWidget { class DisplayTrainID extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainID({required this.trainData, super.key,}); const DisplayTrainID({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -335,7 +355,10 @@ class DisplayTrainID extends StatelessWidget {
class DisplayTrainOperator extends StatelessWidget { class DisplayTrainOperator extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainOperator({required this.trainData, super.key,}); const DisplayTrainOperator({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -353,7 +376,10 @@ class DisplayTrainOperator extends StatelessWidget {
class DisplayTrainRoute extends StatelessWidget { class DisplayTrainRoute extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainRoute({required this.trainData, super.key,}); const DisplayTrainRoute({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -418,7 +444,10 @@ class DisplayTrainDeparture extends StatelessWidget {
class DisplayTrainLastInfo extends StatelessWidget { class DisplayTrainLastInfo extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainLastInfo({required this.trainData, super.key,}); const DisplayTrainLastInfo({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -610,7 +639,10 @@ class DisplayTrainLastInfo extends StatelessWidget {
class DisplayTrainDestination extends StatelessWidget { class DisplayTrainDestination extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainDestination({required this.trainData, super.key,}); const DisplayTrainDestination({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -714,7 +746,10 @@ class DisplayTrainDestination extends StatelessWidget {
class DisplayTrainRouteDistance extends StatelessWidget { class DisplayTrainRouteDistance extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainRouteDistance({required this.trainData, super.key,}); const DisplayTrainRouteDistance({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -751,7 +786,10 @@ class DisplayTrainRouteDistance extends StatelessWidget {
class DisplayTrainRouteDuration extends StatelessWidget { class DisplayTrainRouteDuration extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainRouteDuration({required this.trainData, super.key,}); const DisplayTrainRouteDuration({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -834,7 +872,10 @@ class DisplayTrainRouteDuration extends StatelessWidget {
class DisplayTrainYesterdayWarningMaterial class DisplayTrainYesterdayWarningMaterial
extends DisplayTrainYesterdayWarningCommon { extends DisplayTrainYesterdayWarningCommon {
const DisplayTrainYesterdayWarningMaterial(super.onViewYesterdayTrain, {super.key,}); const DisplayTrainYesterdayWarningMaterial(
super.onViewYesterdayTrain, {
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -870,7 +911,10 @@ class DisplayTrainYesterdayWarningMaterial
class DisplayTrainStations extends StatelessWidget { class DisplayTrainStations extends StatelessWidget {
final TrainData trainData; final TrainData trainData;
const DisplayTrainStations({required this.trainData, super.key,}); const DisplayTrainStations({
required this.trainData,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -884,7 +928,8 @@ class DisplayTrainStations extends StatelessWidget {
onTap: () { onTap: () {
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
ViewStationPage.routeName, ViewStationPage.routeName,
arguments: ViewStationArguments(stationName: trainData.stations[index].name), arguments: ViewStationArguments(
stationName: trainData.stations[index].name),
); );
}, },
), ),

View file

@ -1,19 +1,45 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart' hide Badge;
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:info_tren/components/train_id_text_span.dart';
import 'package:info_tren/models.dart'; import 'package:info_tren/models.dart';
import 'package:info_tren/components/badge/badge.dart'; import 'package:info_tren/components/badge/badge.dart';
import 'package:info_tren/pages/train_info_page/view_train/train_info_material.dart'; import 'package:info_tren/pages/train_info_page/view_train/train_info_material.dart';
import 'package:info_tren/providers.dart'; import 'package:info_tren/providers.dart';
class DisplayTrainStation extends StatelessWidget { class DisplayTrainStation extends StatelessWidget {
final Station station; final TrainDataStation station;
final void Function()? onTap; final void Function()? onTap;
const DisplayTrainStation({required this.station, this.onTap, super.key,}); const DisplayTrainStation({
required this.station,
this.onTap,
super.key,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( return Column(
mainAxisSize: MainAxisSize.min,
children: [
if (station.notes.whereType<TrainDataNoteDepartsAs>().isNotEmpty)
Builder(
builder: (context) {
final note =
station.notes.whereType<TrainDataNoteDepartsAs>().first;
return Padding(
padding: const EdgeInsets.all(2.0),
child: Text.rich(
TextSpan(
children: [
const TextSpan(text: 'Trenul pleacă cu numărul '),
trainIdSpan(rank: note.rank, number: note.number),
],
),
),
);
},
),
Card(
child: InkWell( child: InkWell(
onTap: onTap, onTap: onTap,
child: Padding( child: Padding(
@ -29,8 +55,7 @@ class DisplayTrainStation extends StatelessWidget {
flex: 1, flex: 1,
child: Align( child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Builder( child: Builder(builder: (context) {
builder: (context) {
final departureStatus = station.departure?.status; final departureStatus = station.departure?.status;
final arrivalStatus = station.arrival?.status; final arrivalStatus = station.arrival?.status;
int delay; int delay;
@ -38,12 +63,10 @@ class DisplayTrainStation extends StatelessWidget {
if (departureStatus == null) { if (departureStatus == null) {
delay = arrivalStatus?.delay ?? 0; delay = arrivalStatus?.delay ?? 0;
real = arrivalStatus?.real ?? false; real = arrivalStatus?.real ?? false;
} } else if (arrivalStatus == null) {
else if (arrivalStatus == null) {
delay = departureStatus.delay; delay = departureStatus.delay;
real = departureStatus.real; real = departureStatus.real;
} } else {
else {
delay = departureStatus.delay; delay = departureStatus.delay;
real = departureStatus.real; real = departureStatus.real;
if (!real && arrivalStatus.real) { if (!real && arrivalStatus.real) {
@ -63,8 +86,7 @@ class DisplayTrainStation extends StatelessWidget {
isDelayed: isDelayed, isDelayed: isDelayed,
isOnTime: isOnTime, isOnTime: isOnTime,
); );
} }),
),
), ),
), ),
Title( Title(
@ -76,7 +98,10 @@ class DisplayTrainStation extends StatelessWidget {
? Container() ? Container()
: Align( : Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: Badge(text: station.platform!, caption: 'linia',), child: Badge(
text: station.platform!,
caption: 'linia',
),
), ),
), ),
], ],
@ -84,6 +109,34 @@ class DisplayTrainStation extends StatelessWidget {
Time( Time(
station: station, station: station,
), ),
if (station.notes
.whereType<TrainDataNoteDetachingWagons>()
.isNotEmpty)
Builder(
builder: (context) {
final note = station.notes
.whereType<TrainDataNoteDetachingWagons>()
.first;
return Text(
'Trenul detașează vagoane către ${note.station}',
textAlign: TextAlign.center,
);
},
),
if (station.notes
.whereType<TrainDataNoteReceivingWagons>()
.isNotEmpty)
Builder(
builder: (context) {
final note = station.notes
.whereType<TrainDataNoteReceivingWagons>()
.first;
return Text(
'Trenul primește vagoane de la ${note.station}',
textAlign: TextAlign.center,
);
},
),
Delay( Delay(
station: station, station: station,
), ),
@ -91,12 +144,35 @@ class DisplayTrainStation extends StatelessWidget {
), ),
), ),
), ),
),
if (station.notes
.whereType<TrainDataNoteTrainNumberChange>()
.isNotEmpty)
Builder(
builder: (context) {
final note = station.notes
.whereType<TrainDataNoteTrainNumberChange>()
.first;
return Padding(
padding: const EdgeInsets.all(2.0),
child: Text.rich(
TextSpan(
children: [
const TextSpan(text: 'Trenul își schimbă numărul în '),
trainIdSpan(rank: note.rank, number: note.number),
],
),
),
);
},
),
],
); );
} }
} }
class Title extends StatelessWidget { class Title extends StatelessWidget {
final Station station; final TrainDataStation station;
const Title({ const Title({
required this.station, required this.station,
@ -109,7 +185,9 @@ class Title extends StatelessWidget {
station.name, station.name,
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: isSmallScreen(context) ? 18 : 22, fontSize: isSmallScreen(context) ? 18 : 22,
fontWeight: MediaQuery.of(context).boldText ? FontWeight.w500 : FontWeight.w300, fontWeight: MediaQuery.of(context).boldText
? FontWeight.w500
: FontWeight.w300,
// fontStyle: items[1] == "ONI" ? FontStyle.italic : FontStyle.normal, // fontStyle: items[1] == "ONI" ? FontStyle.italic : FontStyle.normal,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -118,7 +196,7 @@ class Title extends StatelessWidget {
} }
class Time extends StatelessWidget { class Time extends StatelessWidget {
final Station station; final TrainDataStation station;
const Time({ const Time({
required this.station, required this.station,
@ -152,13 +230,27 @@ class Time extends StatelessWidget {
fontSize: isSmallScreen(context) ? 18 : 22, fontSize: isSmallScreen(context) ? 18 : 22,
), ),
), ),
Container(width: 2,), Container(
ArrivalTime(station: station,), width: 2,
Expanded(child: Container(),), ),
StopTime(station: station,), ArrivalTime(
Expanded(child: Container(),), station: station,
DepartureTime(station: station,), ),
Container(width: 2,), Expanded(
child: Container(),
),
StopTime(
station: station,
),
Expanded(
child: Container(),
),
DepartureTime(
station: station,
),
Container(
width: 2,
),
Text( Text(
"", "",
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
@ -171,7 +263,7 @@ class Time extends StatelessWidget {
} }
class ArrivalTime extends ConsumerWidget { class ArrivalTime extends ConsumerWidget {
final Station station; final TrainDataStation station;
final bool finalStation; final bool finalStation;
const ArrivalTime({ const ArrivalTime({
@ -196,21 +288,26 @@ class ArrivalTime extends ConsumerWidget {
fontSize: isSmallScreen(context) ? 18 : 22, fontSize: isSmallScreen(context) ? 18 : 22,
), ),
), ),
Container(width: 2,), Container(
width: 2,
),
const Text("sosire la "), const Text("sosire la "),
ArrivalTime(station: station,), ArrivalTime(
Expanded(child: Container(),), station: station,
),
Expanded(
child: Container(),
),
], ],
); );
} } else {
else {
final delay = station.arrival!.status?.delay ?? 0; final delay = station.arrival!.status?.delay ?? 0;
final time = tz.convertDateTime(station.arrival!.scheduleTime); final time = tz.convertDateTime(station.arrival!.scheduleTime);
if (delay == 0) { if (delay == 0) {
return Text("${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}"); return Text(
} "${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}");
else if (delay > 0) { } else if (delay > 0) {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -231,8 +328,7 @@ class ArrivalTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -259,7 +355,7 @@ class ArrivalTime extends ConsumerWidget {
} }
class StopTime extends StatelessWidget { class StopTime extends StatelessWidget {
final Station station; final TrainDataStation station;
const StopTime({ const StopTime({
required this.station, required this.station,
@ -288,14 +384,12 @@ class StopTime extends StatelessWidget {
"1 ${minutes ? 'minut' : 'secundă'}", "1 ${minutes ? 'minut' : 'secundă'}",
textAlign: TextAlign.center, textAlign: TextAlign.center,
); );
} } else if (stopsForInt < 20) {
else if (stopsForInt < 20) {
return Text( return Text(
"$stopsForInt ${minutes ? 'minute' : 'secunde'}", "$stopsForInt ${minutes ? 'minute' : 'secunde'}",
textAlign: TextAlign.center, textAlign: TextAlign.center,
); );
} } else {
else {
return Text( return Text(
"$stopsForInt de ${minutes ? 'minute' : 'secunde'}", "$stopsForInt de ${minutes ? 'minute' : 'secunde'}",
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -309,7 +403,7 @@ class StopTime extends StatelessWidget {
} }
class DepartureTime extends ConsumerWidget { class DepartureTime extends ConsumerWidget {
final Station station; final TrainDataStation station;
final bool firstStation; final bool firstStation;
const DepartureTime({ const DepartureTime({
@ -328,10 +422,16 @@ class DepartureTime extends ConsumerWidget {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Expanded(child: Container(),), Expanded(
child: Container(),
),
const Text("plecare la "), const Text("plecare la "),
DepartureTime(station: station,), DepartureTime(
Container(width: 2,), station: station,
),
Container(
width: 2,
),
Text( Text(
"", "",
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
@ -340,15 +440,14 @@ class DepartureTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final delay = station.departure!.status?.delay ?? 0; final delay = station.departure!.status?.delay ?? 0;
final time = tz.convertDateTime(station.departure!.scheduleTime); final time = tz.convertDateTime(station.departure!.scheduleTime);
if (delay == 0) { if (delay == 0) {
return Text("${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}"); return Text(
} "${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}");
else if (delay > 0) { } else if (delay > 0) {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -369,8 +468,7 @@ class DepartureTime extends ConsumerWidget {
), ),
], ],
); );
} } else {
else {
final oldDate = time; final oldDate = time;
final newDate = oldDate.add(Duration(minutes: delay)); final newDate = oldDate.add(Duration(minutes: delay));
@ -396,9 +494,8 @@ class DepartureTime extends ConsumerWidget {
} }
} }
class Delay extends StatelessWidget { class Delay extends StatelessWidget {
final Station station; final TrainDataStation station;
const Delay({ const Delay({
required this.station, required this.station,
@ -426,8 +523,7 @@ class Delay extends StatelessWidget {
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
), ),
); );
} } else if (delay < 0) {
else if (delay < 0) {
return Text( return Text(
"${-delay} ${delay == -1 ? 'minut' : 'minute'} mai devreme", "${-delay} ${delay == -1 ? 'minut' : 'minute'} mai devreme",
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(

View file

@ -3,13 +3,17 @@ import 'dart:developer';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:info_tren/api/station_data.dart'; import 'package:info_tren/api/station_data.dart';
import 'package:info_tren/api/train_data.dart';
import 'package:info_tren/models.dart'; import 'package:info_tren/models.dart';
import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.dart'; import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.dart';
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/utils/iterable_extensions.dart'; import 'package:info_tren/utils/iterable_extensions.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
part 'providers.g.dart';
final sharedPreferencesProvider = Provider<SharedPreferences>( final sharedPreferencesProvider = Provider<SharedPreferences>(
(_) => throw UnimplementedError('Please override in ProviderScope'), (_) => throw UnimplementedError('Please override in ProviderScope'),
); );
@ -76,8 +80,8 @@ final trainInfoArgumentsProvider = Provider<TrainInfoArguments>(
(_) => throw UnimplementedError('Please override in ProviderScope'), (_) => throw UnimplementedError('Please override in ProviderScope'),
); );
final stationDataProvider = FutureProvider.family((ref, String stationName) async { final stationDataProvider = FutureProvider.family((ref, ViewStationArguments args) async {
final data = await getStationData(stationName); final data = await getStationData(args.stationName, args.date);
final timer = Timer(const Duration(minutes: 2), () { final timer = Timer(const Duration(minutes: 2), () {
ref.invalidateSelf(); ref.invalidateSelf();
@ -93,6 +97,9 @@ final viewStationArgumentsProvider = Provider<ViewStationArguments>(
); );
final viewStationDataProvider = Provider((ref) { final viewStationDataProvider = Provider((ref) {
final args = ref.watch(viewStationArgumentsProvider); final args = ref.watch(viewStationArgumentsProvider);
final data = ref.watch(stationDataProvider(args.stationName)); final data = ref.watch(stationDataProvider(args));
return data; return data;
}, dependencies: [viewStationArgumentsProvider, stationDataProvider]); }, dependencies: [viewStationArgumentsProvider, stationDataProvider]);
@Riverpod(keepAlive: true)
Future<TrainData> trainInfo(TrainInfoRef ref, {required String trainNumber, DateTime? date}) => getTrain(trainNumber, date: date);

120
lib/providers.g.dart Normal file
View file

@ -0,0 +1,120 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'providers.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$trainInfoHash() => r'd25aabc3ba656acf6497ec6831e11892178b22c9';
/// Copied from Dart SDK
class _SystemHash {
_SystemHash._();
static int combine(int hash, int value) {
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + value);
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
return hash ^ (hash >> 6);
}
static int finish(int hash) {
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
// ignore: parameter_assignments
hash = hash ^ (hash >> 11);
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
}
}
typedef TrainInfoRef = FutureProviderRef<TrainData>;
/// See also [trainInfo].
@ProviderFor(trainInfo)
const trainInfoProvider = TrainInfoFamily();
/// See also [trainInfo].
class TrainInfoFamily extends Family<AsyncValue<TrainData>> {
/// See also [trainInfo].
const TrainInfoFamily();
/// See also [trainInfo].
TrainInfoProvider call({
required String trainNumber,
DateTime? date,
}) {
return TrainInfoProvider(
trainNumber: trainNumber,
date: date,
);
}
@override
TrainInfoProvider getProviderOverride(
covariant TrainInfoProvider provider,
) {
return call(
trainNumber: provider.trainNumber,
date: provider.date,
);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'trainInfoProvider';
}
/// See also [trainInfo].
class TrainInfoProvider extends FutureProvider<TrainData> {
/// See also [trainInfo].
TrainInfoProvider({
required this.trainNumber,
this.date,
}) : super.internal(
(ref) => trainInfo(
ref,
trainNumber: trainNumber,
date: date,
),
from: trainInfoProvider,
name: r'trainInfoProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$trainInfoHash,
dependencies: TrainInfoFamily._dependencies,
allTransitiveDependencies: TrainInfoFamily._allTransitiveDependencies,
);
final String trainNumber;
final DateTime? date;
@override
bool operator ==(Object other) {
return other is TrainInfoProvider &&
other.trainNumber == trainNumber &&
other.date == date;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, trainNumber.hashCode);
hash = _SystemHash.combine(hash, date.hashCode);
return _SystemHash.finish(hash);
}
}
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions

View file

@ -1,12 +1,7 @@
import 'package:info_tren/models.dart'; import 'package:info_tren/models.dart';
String stateToString(TrainDataState state) { String stateToString(TrainDataState state) => switch (state) {
switch(state) { TrainDataState.passing => 'trecere fără oprire',
case TrainDataState.PASSING: TrainDataState.arrival => 'sosire',
return 'trecere fără oprire'; TrainDataState.departure => 'plecare',
case TrainDataState.ARRIVAL: };
return 'sosire';
case TrainDataState.DEPARTURE:
return 'plecare';
}
}

View file

@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View file

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
url_launcher_linux url_launcher_linux
) )

View file

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig"

View file

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig"

40
macos/Podfile Normal file
View file

@ -0,0 +1,40 @@
platform :osx, '10.14'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', '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
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 Flutter-Generated.xcconfig, then run \"flutter pub get\""
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_macos_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
end
end

41
macos/Podfile.lock Normal file
View file

@ -0,0 +1,41 @@
PODS:
- dynamic_color (0.0.2):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- package_info_plus (0.0.1):
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- url_launcher_macos (0.0.1):
- FlutterMacOS
DEPENDENCIES:
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
EXTERNAL SOURCES:
dynamic_color:
:path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos
FlutterMacOS:
:path: Flutter/ephemeral
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
SPEC CHECKSUMS:
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
COCOAPODS: 1.12.1

View file

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 51; objectVersion = 54;
objects = { objects = {
/* Begin PBXAggregateTarget section */ /* Begin PBXAggregateTarget section */
@ -26,6 +26,7 @@
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
520B64251BD594DD8421C698 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE5B44A3963C12914D375BF2 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -52,6 +53,7 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0796070C1CDACAE0CA888A94 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* Info Tren.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Info Tren.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10ED2044A3C60003C045 /* Info Tren.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Info Tren.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@ -68,6 +70,9 @@
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
982BB43264C0B37351AE0773 /* 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>"; };
BE5B44A3963C12914D375BF2 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
FCA310A2438DD41F2A155FE5 /* 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>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -75,6 +80,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
520B64251BD594DD8421C698 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -99,6 +105,7 @@
33CEB47122A05771004F2AC0 /* Flutter */, 33CEB47122A05771004F2AC0 /* Flutter */,
33CC10EE2044A3C60003C045 /* Products */, 33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */, D73912EC22F37F3D000D13A0 /* Frameworks */,
EB1CD289E0F53193A2CB7A73 /* Pods */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -148,10 +155,22 @@
D73912EC22F37F3D000D13A0 /* Frameworks */ = { D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
BE5B44A3963C12914D375BF2 /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
EB1CD289E0F53193A2CB7A73 /* Pods */ = {
isa = PBXGroup;
children = (
FCA310A2438DD41F2A155FE5 /* Pods-Runner.debug.xcconfig */,
0796070C1CDACAE0CA888A94 /* Pods-Runner.release.xcconfig */,
982BB43264C0B37351AE0773 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -159,11 +178,13 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
85962951F5B916ED962A8FBD /* [CP] Check Pods Manifest.lock */,
33CC10E92044A3C60003C045 /* Sources */, 33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */, 33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */, 33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */, 3399D490228B24CF009A79C7 /* ShellScript */,
907AE34F1B4BFF5379ADD9D0 /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -182,7 +203,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0920; LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0930; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
33CC10EC2044A3C60003C045 = { 33CC10EC2044A3C60003C045 = {
@ -235,6 +256,7 @@
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
3399D490228B24CF009A79C7 /* ShellScript */ = { 3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -270,6 +292,45 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
}; };
85962951F5B916ED962A8FBD /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
907AE34F1B4BFF5379ADD9D0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@ -344,7 +405,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
@ -423,7 +484,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
@ -470,7 +531,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1000" LastUpgradeVersion = "1300"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View file

@ -4,4 +4,7 @@
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "group:Runner.xcodeproj">
</FileRef> </FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace> </Workspace>

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@ description: O aplicație de vizualizare a datelor puse la dispoziție de Inform
version: 2.7.10 version: 2.7.10
environment: environment:
sdk: ">=2.17.0 <3.0.0" sdk: ">=3.0.0 <4.0.0"
dependencies: dependencies:
flutter: flutter:
@ -30,19 +30,23 @@ dependencies:
url_launcher: ^6.1.5 url_launcher: ^6.1.5
flutter_hooks: ^0.18.5+1 flutter_hooks: ^0.18.5+1
hooks_riverpod: ^2.0.2 hooks_riverpod: ^2.0.2
freezed_annotation: ^2.2.0 freezed_annotation: ^2.4.1
json_annotation: ^4.7.0 json_annotation: ^4.8.1
shared_preferences: ^2.0.15 shared_preferences: ^2.0.15
fluent_ui: ^4.0.3+1 fluent_ui: ^4.0.3+1
timezone: ^0.9.0 timezone: ^0.9.0
dynamic_color: ^1.6.6
riverpod_annotation: ^2.1.1
dev_dependencies: dev_dependencies:
# flutter_test: # flutter_test:
# sdk: flutter # sdk: flutter
build_runner: ^2.1.0 build_runner: ^2.1.0
json_serializable: ^6.5.4 json_serializable: ^6.5.4
freezed: 2.2.0 freezed: ^2.4.1
flutter_lints: ^2.0.1 flutter_lints: ^2.0.1
riverpod_lint: ^1.3.2
riverpod_generator: ^2.2.3
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the

View file

@ -6,9 +6,12 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
DynamicColorPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows")); registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View file

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
url_launcher_windows url_launcher_windows
) )