From bf654ea8373db7d03d026f5401c8228b5990468a Mon Sep 17 00:00:00 2001 From: Dan Cojocaru Date: Thu, 4 Aug 2022 03:45:32 +0300 Subject: [PATCH] Add about page, in-app changelog, Android download --- .vscode/launch.json | 6 +- CHANGELOG.TXT => CHANGELOG.txt | 5 +- lib/api/releases.dart | 16 +++ lib/main.dart | 26 +++- lib/models/changelog_entry.dart | 75 +++++++++++ lib/pages/about/about_page.dart | 75 +++++++++++ lib/pages/about/about_page_cupertino.dart | 127 ++++++++++++++++++ lib/pages/about/about_page_material.dart | 112 ++++++++++++++++ lib/pages/main/main_page.dart | 25 +++- lib/pages/main/main_page_cupertino.dart | 26 ++++ lib/pages/main/main_page_material.dart | 13 ++ lib/utils/iterable_extensions.dart | 6 + linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + pubspec.lock | 129 ++++++++++++++++++- pubspec.yaml | 11 +- 16 files changed, 636 insertions(+), 21 deletions(-) rename CHANGELOG.TXT => CHANGELOG.txt (95%) create mode 100644 lib/api/releases.dart create mode 100644 lib/models/changelog_entry.dart create mode 100644 lib/pages/about/about_page.dart create mode 100644 lib/pages/about/about_page_cupertino.dart create mode 100644 lib/pages/about/about_page_material.dart create mode 100644 lib/utils/iterable_extensions.dart diff --git a/.vscode/launch.json b/.vscode/launch.json index b0bdb95..f2c038f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,11 @@ { "name": "Current Device", "request": "launch", - "type": "dart" + "type": "dart", + "args": [ + "--dart-define", + "DOWNLOAD=apk" + ] }, { "name": "info_tren (profile mode)", diff --git a/CHANGELOG.TXT b/CHANGELOG.txt similarity index 95% rename from CHANGELOG.TXT rename to CHANGELOG.txt index d36e82d..9653a13 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.txt @@ -1,3 +1,7 @@ +v2.7.5 +Added about page and in-app changelog. +On Android, added download buttons. + v2.7.4 Addressed Android 12 component exporting rule. See: https://developer.android.com/about/versions/12/behavior-changes-12#exported @@ -51,7 +55,6 @@ Tweaks v2.0.6 Brought feature parity with iOS _(except for v2.0.2, which is iOS specific)_. - v2.0.5 - increased font weight on iOS - added support for system bolt font request on iOS diff --git a/lib/api/releases.dart b/lib/api/releases.dart new file mode 100644 index 0000000..34192b0 --- /dev/null +++ b/lib/api/releases.dart @@ -0,0 +1,16 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:info_tren/models/changelog_entry.dart'; +import 'package:info_tren/utils/iterable_extensions.dart'; + +Future> getRemoteReleases() async { + final Uri uri = Uri.parse('https://gitea.dcdev.ro/api/v1/repos/kbruen/info_tren/releases'); + final response = await http.get(uri); + final json = jsonDecode(response.body) as List; + return json.map((e) => ChangelogEntry( + version: ChangelogVersion.parse(e['tag_name']), + description: e['body'], + apkLink: (e['assets'] as List).where((e) => (e['name'] as String).contains('.apk')).map((e) => Uri.parse(e['browser_download_url'] as String)).firstOrNull, + )).toList(); +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index c916652..fcd0b0a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; // import 'package:flutter_redux/flutter_redux.dart'; import 'package:info_tren/models/ui_design.dart'; +import 'package:info_tren/pages/about/about_page.dart'; import 'package:info_tren/pages/main/main_page.dart'; import 'package:info_tren/pages/station_arrdep_page/select_station/select_station.dart'; import 'package:info_tren/pages/station_arrdep_page/view_station/view_station.dart'; @@ -28,10 +29,19 @@ void main() { Map routesByUiDesign(UiDesign uiDesign) => { Navigator.defaultRouteName: (context) { - return MainPage(uiDesign: uiDesign,); + return MainPage( + uiDesign: uiDesign, + ); + }, + AboutPage.routeName: (context) { + return AboutPage( + uiDesign: uiDesign, + ); }, SelectTrainPage.routeName: (context) { - return SelectTrainPage(uiDesign: uiDesign); + return SelectTrainPage( + uiDesign: uiDesign, + ); }, TrainInfo.routeName: (context) { return TrainInfo( @@ -40,7 +50,9 @@ Map routesByUiDesign(UiDesign uiDesign) => { ); }, SelectStationPage.routeName: (context) { - return SelectStationPage(uiDesign: uiDesign,); + return SelectStationPage( + uiDesign: uiDesign, + ); }, ViewStationPage.routeName: (context) { return ViewStationPage( @@ -80,9 +92,11 @@ class StartPoint extends StatelessWidget { title: appTitle, theme: ThemeData( primarySwatch: Colors.blue, - brightness: Brightness.dark, - primaryColor: Colors.blue.shade600, - accentColor: Colors.blue.shade700, + colorScheme: ColorScheme.fromSwatch( + brightness: Brightness.dark, + primarySwatch: Colors.blue, + accentColor: Colors.blue.shade700, + ), // fontFamily: 'Atkinson Hyperlegible', ), routes: routesByUiDesign(UiDesign.MATERIAL), diff --git a/lib/models/changelog_entry.dart b/lib/models/changelog_entry.dart new file mode 100644 index 0000000..b807878 --- /dev/null +++ b/lib/models/changelog_entry.dart @@ -0,0 +1,75 @@ +import 'package:quiver/core.dart'; + +class ChangelogEntry { + final ChangelogVersion version; + final String description; + final Uri? apkLink; + + ChangelogEntry({required this.version, required this.description, this.apkLink}); + + factory ChangelogEntry.fromTextBlock(String text) { + final lines = text.split(RegExp(r'(\r?\n)+')); + return ChangelogEntry( + version: ChangelogVersion.parse(lines.first), + description: lines.skip(1).join('\n'), + ); + } + + static List fromTextFile(String text) { + final blocks = text.split(RegExp(r'(\r?\n){2}')); + return blocks.map(ChangelogEntry.fromTextBlock).toList(); + } +} + +class ChangelogVersion implements Comparable { + final int major; + final int minor; + final int patch; + final String? prerelease; + + ChangelogVersion(this.major, this.minor, this.patch, [this.prerelease]); + + factory ChangelogVersion.parse(String version) { + if (version.startsWith('v')) { + version = version.substring(1); + } + String? prerelease; + if (version.contains('-')) { + final index = version.indexOf('-'); + prerelease = version.substring(index + 1); + version = version.substring(0, index); + } + final splitted = version.split('.').map(int.parse).toList(); + return ChangelogVersion(splitted[0], splitted[1], splitted[2], prerelease); + } + + @override + String toString() { + final vString = 'v$major.$minor.$patch'; + return prerelease == null ? vString : '$vString-$prerelease'; + } + + @override + bool operator==(dynamic other) { + if (other is! ChangelogVersion) { + return false; + } + return major == other.major && minor == other.minor && patch == other.patch && prerelease == other.prerelease; + } + + @override + int get hashCode { + return hash3(major.hashCode, minor.hashCode, patch.hashCode); + } + + @override + int compareTo(ChangelogVersion other) { + if (major != other.major) { + return major.compareTo(other.major); + } + if (minor != other.minor) { + return minor.compareTo(other.minor); + } + return patch.compareTo(other.patch); + } +} diff --git a/lib/pages/about/about_page.dart b/lib/pages/about/about_page.dart new file mode 100644 index 0000000..8743cb2 --- /dev/null +++ b/lib/pages/about/about_page.dart @@ -0,0 +1,75 @@ +import 'package:flutter/widgets.dart'; +import 'package:info_tren/api/releases.dart'; +import 'package:info_tren/models/changelog_entry.dart'; +import 'package:info_tren/models/ui_design.dart'; +import 'package:info_tren/pages/about/about_page_cupertino.dart'; +import 'package:info_tren/pages/about/about_page_material.dart'; +import 'package:info_tren/utils/default_ui_design.dart'; +import 'package:package_info_plus/package_info_plus.dart'; + +class AboutPage extends StatefulWidget { + final UiDesign? uiDesign; + + const AboutPage({Key? key, this.uiDesign}) : super(key: key); + + static String routeName = '/about'; + + @override + State createState() { + final uiDesign = this.uiDesign ?? defaultUiDesign; + + switch (uiDesign) { + case UiDesign.MATERIAL: + return AboutPageStateMaterial(); + case UiDesign.CUPERTINO: + return AboutPageStateCupertino(); + default: + throw UnmatchedUiDesignException(uiDesign); + } + } +} + +abstract class AboutPageState extends State { + static const String DOWNLOAD = String.fromEnvironment('DOWNLOAD'); + + final String pageTitle = 'Despre aplicație'; + final String versionTitleText = 'Versiunea aplicației'; + final String latestVersionText = 'Cea mai recentă versiune'; + final String currentVersionText = 'Versiunea curentă'; + + List localChangelog = []; + List remoteChangelog = []; + List get mergedChangelogs { + final logs = remoteChangelog.toList(); + final versions = logs.map((log) => log.version).toSet(); + for (final log in localChangelog) { + if (!versions.contains(log.version)) { + logs.add(log); + versions.add(log.version); + } + } + logs.sort((l1, l2) => l2.version.compareTo(l1.version)); + return logs; + } + + PackageInfo? packageInfo; + + @override + void didChangeDependencies() { + PackageInfo.fromPlatform().then((value) => setState(() { + packageInfo = value; + })); + + DefaultAssetBundle.of(context).loadString('CHANGELOG.txt').then((value) { + setState(() { + localChangelog = ChangelogEntry.fromTextFile(value); + }); + }); + + getRemoteReleases().then((value) => setState(() { + remoteChangelog = value; + })); + + super.didChangeDependencies(); + } +} diff --git a/lib/pages/about/about_page_cupertino.dart b/lib/pages/about/about_page_cupertino.dart new file mode 100644 index 0000000..72306a1 --- /dev/null +++ b/lib/pages/about/about_page_cupertino.dart @@ -0,0 +1,127 @@ +import 'package:flutter/cupertino.dart'; +import 'package:info_tren/components/cupertino_divider.dart'; +import 'package:info_tren/pages/about/about_page.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AboutPageStateCupertino extends AboutPageState { + @override + Widget build(BuildContext context) { + return CupertinoPageScaffold( + navigationBar: CupertinoNavigationBar( + middle: Text(pageTitle), + ), + child: Builder( + builder: (context) { + final topPadding = MediaQuery.of(context).padding.top; + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + SizedBox( + height: topPadding, + ), + Center( + child: Text( + 'Info Tren', + style: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle, + ), + ), + if (packageInfo != null) + Center( + child: Text( + packageInfo!.packageName, + style: TextStyle( + inherit: true, + fontSize: 14, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: CupertinoDivider(), + ), + for (final log in mergedChangelogs) ...[ + Padding( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Text( + log.version.toString(), + style: TextStyle( + inherit: true, + fontSize: 24, + ), + ), + ), + if (localChangelog.isNotEmpty && log.version == localChangelog.first.version) + Container( + decoration: BoxDecoration( + border: Border.all( + color: CupertinoTheme.of(context).textTheme.textStyle.color ?? CupertinoColors.inactiveGray, + width: 1, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text( + currentVersionText, + style: TextStyle( + inherit: true, + ), + ), + ), + ), + if (remoteChangelog.isNotEmpty && log.version == remoteChangelog.first.version && (localChangelog.isEmpty || localChangelog.first.version != log.version)) + Container( + decoration: BoxDecoration( + border: Border.all( + color: CupertinoColors.activeGreen, + width: 1, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text( + latestVersionText, + style: TextStyle( + inherit: true, + color: CupertinoColors.activeGreen, + ), + ), + ), + ), + if (AboutPageState.DOWNLOAD == 'apk' && log.apkLink != null) + CupertinoButton( + padding: EdgeInsets.all(4), + minSize: 0, + onPressed: () { + launchUrl(log.apkLink!); + }, + child: Icon(CupertinoIcons.arrow_down_circle), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: log.description, + ), + ), + ), + CupertinoDivider(), + ], + ], + ), + ); + } + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/about/about_page_material.dart b/lib/pages/about/about_page_material.dart new file mode 100644 index 0000000..aff2a66 --- /dev/null +++ b/lib/pages/about/about_page_material.dart @@ -0,0 +1,112 @@ +import 'package:flutter/material.dart'; +import 'package:info_tren/pages/about/about_page.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AboutPageStateMaterial extends AboutPageState { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(pageTitle), + centerTitle: true, + ), + body: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: Text( + 'Info Tren', + style: Theme.of(context).textTheme.displayMedium, + ), + ), + if (packageInfo != null) + Center( + child: Text( + packageInfo!.packageName, + style: Theme.of(context).textTheme.caption, + ), + ), + // ListTile( + // title: Text(versionTitleText), + // subtitle: localChangelog.isEmpty ? null : Text(localChangelog.first.title), + // ), + Divider(), + for (final log in mergedChangelogs) ...[ + Padding( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Text( + log.version.toString(), + style: Theme.of(context).textTheme.headline4, + ), + ), + if (localChangelog.isNotEmpty && log.version == localChangelog.first.version) + Container( + decoration: BoxDecoration( + border: Border.all( + color: Theme.of(context).colorScheme.onBackground, + width: 1, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text( + currentVersionText, + style: TextStyle( + inherit: true, + ), + ), + ), + ), + if (remoteChangelog.isNotEmpty && log.version == remoteChangelog.first.version && (localChangelog.isEmpty || localChangelog.first.version != log.version)) + Container( + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + width: 1, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Text( + latestVersionText, + style: TextStyle( + inherit: true, + color: Colors.green, + ), + ), + ), + ), + if (AboutPageState.DOWNLOAD == 'apk' && log.apkLink != null) + IconButton( + onPressed: () { + launchUrl(log.apkLink!); + }, + icon: Icon(Icons.download), + tooltip: 'Download APK', + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: RichText( + text: TextSpan( + text: log.description, + ), + ), + ), + ], + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/main/main_page.dart b/lib/pages/main/main_page.dart index 6911b3e..e285d6b 100644 --- a/lib/pages/main/main_page.dart +++ b/lib/pages/main/main_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/widgets.dart'; import 'package:info_tren/models/ui_design.dart'; +import 'package:info_tren/pages/about/about_page.dart'; import 'package:info_tren/pages/main/main_page_cupertino.dart'; import 'package:info_tren/pages/main/main_page_material.dart'; import 'package:info_tren/pages/station_arrdep_page/select_station/select_station.dart'; @@ -28,21 +29,31 @@ class MainPage extends StatelessWidget { abstract class MainPageShared extends StatelessWidget { final String pageTitle = 'Info Tren'; + final String moreOptionsText = 'Mai multe opțiuni'; - List get options => [ - MainPageOption( + List get popupMenu => [ + MainPageAction( + name: 'Despre aplicație', + action: (context) { + Navigator.of(context).pushNamed(AboutPage.routeName); + }, + ), + ]; + + List get options => [ + MainPageAction( name: 'Informații despre tren', - action: (BuildContext context) { + action: (context) { onTrainInfoPageInvoke(context); }, ), - MainPageOption( + MainPageAction( name: 'Tabelă plecari/sosiri', action: (context) { onStationBoardPageInvoke(context); }, ), - MainPageOption( + MainPageAction( name: 'Planificare rută', // TODO: Implement route planning action: null, @@ -62,9 +73,9 @@ abstract class MainPageShared extends StatelessWidget { } } -class MainPageOption { +class MainPageAction { final String name; final void Function(BuildContext context)? action; - MainPageOption({required this.name, this.action}); + MainPageAction({required this.name, this.action}); } diff --git a/lib/pages/main/main_page_cupertino.dart b/lib/pages/main/main_page_cupertino.dart index 4e0d2df..968b4c6 100644 --- a/lib/pages/main/main_page_cupertino.dart +++ b/lib/pages/main/main_page_cupertino.dart @@ -7,6 +7,32 @@ class MainPageCupertino extends MainPageShared { return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( middle: Text(pageTitle), + trailing: CupertinoButton( + child: Icon(CupertinoIcons.ellipsis_circle), + padding: EdgeInsets.zero, + onPressed: () { + showCupertinoModalPopup( + context: context, + builder: (context) { + return CupertinoActionSheet( + actions: popupMenu.map((m) => CupertinoActionSheetAction( + onPressed: () { + Navigator.of(context).pop(); + m.action?.call(context); + }, + child: Text(m.name), + )).toList(), + cancelButton: CupertinoActionSheetAction( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Anulare'), + ), + ); + }, + ); + }, + ), ), child: SafeArea( child: Center( diff --git a/lib/pages/main/main_page_material.dart b/lib/pages/main/main_page_material.dart index 1a78d76..e4e43c1 100644 --- a/lib/pages/main/main_page_material.dart +++ b/lib/pages/main/main_page_material.dart @@ -8,6 +8,19 @@ class MainPageMaterial extends MainPageShared { appBar: AppBar( title: Text(pageTitle), centerTitle: true, + actions: [ + PopupMenuButton( + icon: Icon(Icons.more_vert), + tooltip: moreOptionsText, + itemBuilder: (_) => popupMenu.asMap().entries.map((e) => PopupMenuItem( + child: Text(e.value.name), + value: e.key, + )).toList(), + onSelected: (index) { + popupMenu[index].action?.call(context); + }, + ), + ], ), body: SafeArea( child: Center( diff --git a/lib/utils/iterable_extensions.dart b/lib/utils/iterable_extensions.dart new file mode 100644 index 0000000..180d2de --- /dev/null +++ b/lib/utils/iterable_extensions.dart @@ -0,0 +1,6 @@ +extension ITerableExtensions on Iterable { + T? get firstOrNull { + final lst = take(1).toList(); + return lst.isEmpty ? null : lst.first; + } +} \ No newline at end of file diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index e71a16d..f6f23bf 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 2e1de87..f16b4c3 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/pubspec.lock b/pubspec.lock index 4a2aa36..28597d4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -140,7 +140,7 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "1.0.5" dart_style: dependency: transitive description: @@ -148,6 +148,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" file: dependency: transitive description: @@ -174,6 +181,11 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.8.2" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" frontend_server_client: dependency: transitive description: @@ -286,6 +298,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.3" + package_info_plus_linux: + dependency: transitive + description: + name: package_info_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + package_info_plus_macos: + dependency: transitive + description: + name: package_info_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + package_info_plus_web: + dependency: transitive + description: + name: package_info_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + package_info_plus_windows: + dependency: transitive + description: + name: package_info_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" path: dependency: transitive description: @@ -293,6 +347,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" pool: dependency: transitive description: @@ -315,7 +376,7 @@ packages: source: hosted version: "1.1.0" quiver: - dependency: transitive + dependency: "direct main" description: name: quiver url: "https://pub.dartlang.org" @@ -438,6 +499,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.5" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.17" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.17" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.12" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" vector_math: dependency: transitive description: @@ -459,6 +576,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.7.0" yaml: dependency: transitive description: @@ -468,3 +592,4 @@ packages: version: "3.1.1" sdks: dart: ">=2.17.0 <3.0.0" + flutter: ">=2.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index c32c7f0..fd87bc8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ description: O aplicație de vizualizare a datelor puse la dispoziție de Inform version: 2.7.4 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.15.0 <3.0.0" dependencies: flutter: @@ -22,13 +22,15 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. -# cupertino_icons: ^0.1.2 + cupertino_icons: ^1.0.5 rxdart: ^0.22.0 http: ^0.13.0 - cupertino_icons: ^0.1.2 tuple: ^2.0.0 sprintf: ^6.0.0 flutter_redux: ^0.8.2 + package_info_plus: ^1.4.3 + quiver: ^3.1.0 + url_launcher: ^6.1.5 dev_dependencies: # flutter_test: @@ -49,7 +51,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: + assets: + - CHANGELOG.txt # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg