From 95f3362a8446c87cb1a4c06ca9cc7fb679038e8e Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 6 Jan 2023 20:47:22 -0500 Subject: [PATCH 1/4] Apps bottom bar tweaks (#216) --- lib/pages/apps.dart | 768 +++++++++++++++++++++++--------------------- 1 file changed, 404 insertions(+), 364 deletions(-) diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index b419eb4..1b422f8 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -348,8 +348,9 @@ class AppsPageState extends State { Row( children: [ selectedApps.isEmpty - ? IconButton( - visualDensity: VisualDensity.compact, + ? TextButton.icon( + style: + const ButtonStyle(visualDensity: VisualDensity.compact), onPressed: () { selectThese(sortedApps.map((e) => e.app).toList()); }, @@ -357,7 +358,7 @@ class AppsPageState extends State { Icons.select_all_outlined, color: Theme.of(context).colorScheme.primary, ), - tooltip: tr('selectAll')) + label: Text(sortedApps.length.toString())) : TextButton.icon( style: const ButtonStyle(visualDensity: VisualDensity.compact), @@ -375,376 +376,415 @@ class AppsPageState extends State { label: Text(selectedApps.length.toString())), const VerticalDivider(), Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - selectedApps.isEmpty - ? const SizedBox() - : IconButton( - visualDensity: VisualDensity.compact, - onPressed: () { - showDialog?>( - context: context, - builder: (BuildContext ctx) { - return GeneratedFormModal( - title: tr('removeSelectedAppsQuestion'), - items: const [], - initValid: true, - message: tr( - 'xWillBeRemovedButRemainInstalled', - args: [ - plural('apps', selectedApps.length) - ]), - ); - }).then((values) { - if (values != null) { - appsProvider.removeApps( - selectedApps.map((e) => e.id).toList()); - } - }); - }, - tooltip: tr('removeSelectedApps'), - icon: const Icon(Icons.delete_outline_outlined), - ), - IconButton( - visualDensity: VisualDensity.compact, - onPressed: appsProvider.areDownloadsRunning() || - (existingUpdateIdsAllOrSelected.isEmpty && - newInstallIdsAllOrSelected.isEmpty && - trackOnlyUpdateIdsAllOrSelected.isEmpty) - ? null - : () { - HapticFeedback.heavyImpact(); - List formItems = []; - if (existingUpdateIdsAllOrSelected.isNotEmpty) { - formItems.add(GeneratedFormSwitch('updates', - label: tr('updateX', args: [ - plural('apps', - existingUpdateIdsAllOrSelected.length) - ]), - defaultValue: true)); - } - if (newInstallIdsAllOrSelected.isNotEmpty) { - formItems.add(GeneratedFormSwitch('installs', - label: tr('installX', args: [ - plural('apps', - newInstallIdsAllOrSelected.length) - ]), - defaultValue: existingUpdateIdsAllOrSelected - .isNotEmpty)); - } - if (trackOnlyUpdateIdsAllOrSelected.isNotEmpty) { - formItems.add(GeneratedFormSwitch('trackonlies', - label: tr('markXTrackOnlyAsUpdated', args: [ - plural('apps', - trackOnlyUpdateIdsAllOrSelected.length) - ]), - defaultValue: existingUpdateIdsAllOrSelected - .isNotEmpty || - newInstallIdsAllOrSelected.isNotEmpty)); - } - showDialog?>( - context: context, - builder: (BuildContext ctx) { - var totalApps = existingUpdateIdsAllOrSelected - .length + - newInstallIdsAllOrSelected.length + - trackOnlyUpdateIdsAllOrSelected.length; - return GeneratedFormModal( - title: tr('changeX', - args: [plural('apps', totalApps)]), - items: formItems.map((e) => [e]).toList(), - initValid: true, - ); - }).then((values) { - if (values != null) { - if (values.isEmpty) { - values = getDefaultValuesFromFormItems( - [formItems]); - } - bool shouldInstallUpdates = - values['updates'] == true; - bool shouldInstallNew = - values['installs'] == true; - bool shouldMarkTrackOnlies = - values['trackonlies'] == true; - (() async { - if (shouldInstallNew || - shouldInstallUpdates) { - await settingsProvider - .getInstallPermission(); - } - })() - .then((_) { - List toInstall = []; - if (shouldInstallUpdates) { - toInstall - .addAll(existingUpdateIdsAllOrSelected); - } - if (shouldInstallNew) { - toInstall - .addAll(newInstallIdsAllOrSelected); - } - if (shouldMarkTrackOnlies) { - toInstall.addAll( - trackOnlyUpdateIdsAllOrSelected); - } - appsProvider - .downloadAndInstallLatestApps(toInstall, - globalNavigatorKey.currentContext) - .catchError((e) { - showError(e, context); - }); - }); - } - }); - }, - tooltip: selectedApps.isEmpty - ? tr('installUpdateApps') - : tr('installUpdateSelectedApps'), - icon: const Icon( - Icons.file_download_outlined, - )), - selectedApps.isEmpty - ? const SizedBox() - : IconButton( - visualDensity: VisualDensity.compact, - onPressed: () async { - try { - Set? preselected; - var showPrompt = false; - for (var element in selectedApps) { - var currentCats = element.categories.toSet(); - if (preselected == null) { - preselected = currentCats; - } else { - if (!settingsProvider.setEqual( - currentCats, preselected)) { - showPrompt = true; - break; - } - } - } - var cont = true; - if (showPrompt) { - cont = await showDialog?>( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + IconButton( + visualDensity: VisualDensity.compact, + onPressed: selectedApps.isEmpty + ? null + : () { + showDialog?>( context: context, builder: (BuildContext ctx) { return GeneratedFormModal( - title: tr('categorize'), + title: + tr('removeSelectedAppsQuestion'), items: const [], initValid: true, - message: - tr('selectedCategorizeWarning'), + message: tr( + 'xWillBeRemovedButRemainInstalled', + args: [ + plural( + 'apps', selectedApps.length) + ]), ); - }) != - null; - } - if (cont) { - await showDialog?>( - context: context, - builder: (BuildContext ctx) { - return GeneratedFormModal( - title: tr('categorize'), - items: const [], - initValid: true, - singleNullReturnButton: tr('continue'), - additionalWidgets: [ - CategoryEditorSelector( - preselected: !showPrompt - ? preselected ?? {} - : {}, - showLabelWhenNotEmpty: false, - onSelected: (categories) { - appsProvider - .saveApps(selectedApps.map((e) { - e.categories = categories; - return e; - }).toList()); - }, - ) - ], - ); + }).then((values) { + if (values != null) { + appsProvider.removeApps(selectedApps + .map((e) => e.id) + .toList()); + } }); - } - } catch (err) { - showError(err, context); - } - }, - tooltip: tr('categorize'), - icon: const Icon(Icons.category_outlined), - ), - selectedApps.isEmpty - ? const SizedBox() - : IconButton( - visualDensity: VisualDensity.compact, - onPressed: () { - showDialog( - context: context, - builder: (BuildContext ctx) { - return AlertDialog( - scrollable: true, - content: Padding( - padding: const EdgeInsets.only(top: 6), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - children: [ - IconButton( - onPressed: - appsProvider - .areDownloadsRunning() - ? null - : () { - showDialog( - context: context, - builder: - (BuildContext - ctx) { - return AlertDialog( - title: Text(tr( - 'markXSelectedAppsAsUpdated', - args: [ - selectedApps - .length - .toString() - ])), - content: Text( - tr('onlyWorksWithNonEVDApps'), - style: const TextStyle( - fontWeight: - FontWeight - .bold, - fontStyle: - FontStyle.italic), - ), - actions: [ - TextButton( - onPressed: - () { - Navigator.of(context) - .pop(); - }, - child: Text( - tr('no'))), - TextButton( - onPressed: - () { - HapticFeedback - .selectionClick(); - appsProvider - .saveApps(selectedApps.map((a) { - if (a.installedVersion != - null) { - a.installedVersion = a.latestVersion; - } - return a; - }).toList()); + }, + tooltip: tr('removeSelectedApps'), + icon: const Icon(Icons.delete_outline_outlined), + ), + IconButton( + visualDensity: VisualDensity.compact, + onPressed: appsProvider.areDownloadsRunning() || + (existingUpdateIdsAllOrSelected.isEmpty && + newInstallIdsAllOrSelected.isEmpty && + trackOnlyUpdateIdsAllOrSelected.isEmpty) + ? null + : () { + HapticFeedback.heavyImpact(); + List formItems = []; + if (existingUpdateIdsAllOrSelected + .isNotEmpty) { + formItems.add(GeneratedFormSwitch( + 'updates', + label: tr('updateX', args: [ + plural( + 'apps', + existingUpdateIdsAllOrSelected + .length) + ]), + defaultValue: true)); + } + if (newInstallIdsAllOrSelected.isNotEmpty) { + formItems.add(GeneratedFormSwitch( + 'installs', + label: tr('installX', args: [ + plural( + 'apps', + newInstallIdsAllOrSelected + .length) + ]), + defaultValue: + existingUpdateIdsAllOrSelected + .isNotEmpty)); + } + if (trackOnlyUpdateIdsAllOrSelected + .isNotEmpty) { + formItems.add(GeneratedFormSwitch( + 'trackonlies', + label: tr('markXTrackOnlyAsUpdated', + args: [ + plural( + 'apps', + trackOnlyUpdateIdsAllOrSelected + .length) + ]), + defaultValue: + existingUpdateIdsAllOrSelected + .isNotEmpty || + newInstallIdsAllOrSelected + .isNotEmpty)); + } + showDialog?>( + context: context, + builder: (BuildContext ctx) { + var totalApps = + existingUpdateIdsAllOrSelected.length + + newInstallIdsAllOrSelected + .length + + trackOnlyUpdateIdsAllOrSelected + .length; + return GeneratedFormModal( + title: tr('changeX', args: [ + plural('apps', totalApps) + ]), + items: formItems + .map((e) => [e]) + .toList(), + initValid: true, + ); + }).then((values) { + if (values != null) { + if (values.isEmpty) { + values = + getDefaultValuesFromFormItems( + [formItems]); + } + bool shouldInstallUpdates = + values['updates'] == true; + bool shouldInstallNew = + values['installs'] == true; + bool shouldMarkTrackOnlies = + values['trackonlies'] == true; + (() async { + if (shouldInstallNew || + shouldInstallUpdates) { + await settingsProvider + .getInstallPermission(); + } + })() + .then((_) { + List toInstall = []; + if (shouldInstallUpdates) { + toInstall.addAll( + existingUpdateIdsAllOrSelected); + } + if (shouldInstallNew) { + toInstall.addAll( + newInstallIdsAllOrSelected); + } + if (shouldMarkTrackOnlies) { + toInstall.addAll( + trackOnlyUpdateIdsAllOrSelected); + } + appsProvider + .downloadAndInstallLatestApps( + toInstall, + globalNavigatorKey + .currentContext) + .catchError((e) { + showError(e, context); + }); + }); + } + }); + }, + tooltip: selectedApps.isEmpty + ? tr('installUpdateApps') + : tr('installUpdateSelectedApps'), + icon: const Icon( + Icons.file_download_outlined, + )), + IconButton( + visualDensity: VisualDensity.compact, + onPressed: selectedApps.isEmpty + ? null + : () async { + try { + Set? preselected; + var showPrompt = false; + for (var element in selectedApps) { + var currentCats = + element.categories.toSet(); + if (preselected == null) { + preselected = currentCats; + } else { + if (!settingsProvider.setEqual( + currentCats, preselected)) { + showPrompt = true; + break; + } + } + } + var cont = true; + if (showPrompt) { + cont = await showDialog< + Map?>( + context: context, + builder: (BuildContext ctx) { + return GeneratedFormModal( + title: tr('categorize'), + items: const [], + initValid: true, + message: tr( + 'selectedCategorizeWarning'), + ); + }) != + null; + } + if (cont) { + await showDialog?>( + context: context, + builder: (BuildContext ctx) { + return GeneratedFormModal( + title: tr('categorize'), + items: const [], + initValid: true, + singleNullReturnButton: + tr('continue'), + additionalWidgets: [ + CategoryEditorSelector( + preselected: !showPrompt + ? preselected ?? {} + : {}, + showLabelWhenNotEmpty: false, + onSelected: (categories) { + appsProvider.saveApps( + selectedApps.map((e) { + e.categories = categories; + return e; + }).toList()); + }, + ) + ], + ); + }); + } + } catch (err) { + showError(err, context); + } + }, + tooltip: tr('categorize'), + icon: const Icon(Icons.category_outlined), + ), + IconButton( + visualDensity: VisualDensity.compact, + onPressed: selectedApps.isEmpty + ? null + : () { + showDialog( + context: context, + builder: (BuildContext ctx) { + return AlertDialog( + scrollable: true, + content: Padding( + padding: + const EdgeInsets.only(top: 6), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + children: [ + IconButton( + onPressed: appsProvider + .areDownloadsRunning() + ? null + : () { + showDialog( + context: + context, + builder: + (BuildContext + ctx) { + return AlertDialog( + title: Text(tr( + 'markXSelectedAppsAsUpdated', + args: [ + selectedApps.length.toString() + ])), + content: + Text( + tr('onlyWorksWithNonEVDApps'), + style: const TextStyle( + fontWeight: + FontWeight.bold, + fontStyle: FontStyle.italic), + ), + actions: [ + TextButton( + onPressed: + () { + Navigator.of(context).pop(); + }, + child: + Text(tr('no'))), + TextButton( + onPressed: + () { + HapticFeedback.selectionClick(); + appsProvider.saveApps(selectedApps.map((a) { + if (a.installedVersion != null) { + a.installedVersion = a.latestVersion; + } + return a; + }).toList()); - Navigator.of(context) - .pop(); - }, - child: Text( - tr('yes'))) - ], - ); - }).whenComplete(() { - Navigator.of( - context) - .pop(); - }); - }, - tooltip: - tr('markSelectedAppsUpdated'), - icon: const Icon(Icons.done)), - IconButton( - onPressed: () { - var pinStatus = selectedApps - .where((element) => - element.pinned) - .isEmpty; - appsProvider.saveApps( - selectedApps.map((e) { - e.pinned = pinStatus; - return e; - }).toList()); - Navigator.of(context).pop(); - }, - tooltip: selectedApps - .where((element) => - element.pinned) - .isEmpty - ? tr('pinToTop') - : tr('unpinFromTop'), - icon: Icon(selectedApps - .where((element) => - element.pinned) - .isEmpty - ? Icons.bookmark_outline_rounded - : Icons - .bookmark_remove_outlined), + Navigator.of(context).pop(); + }, + child: + Text(tr('yes'))) + ], + ); + }).whenComplete(() { + Navigator.of( + context) + .pop(); + }); + }, + tooltip: tr( + 'markSelectedAppsUpdated'), + icon: const Icon( + Icons.done)), + IconButton( + onPressed: () { + var pinStatus = + selectedApps + .where((element) => + element + .pinned) + .isEmpty; + appsProvider.saveApps( + selectedApps.map((e) { + e.pinned = pinStatus; + return e; + }).toList()); + Navigator.of(context) + .pop(); + }, + tooltip: selectedApps + .where((element) => + element.pinned) + .isEmpty + ? tr('pinToTop') + : tr('unpinFromTop'), + icon: Icon(selectedApps + .where((element) => + element.pinned) + .isEmpty + ? Icons + .bookmark_outline_rounded + : Icons + .bookmark_remove_outlined), + ), + IconButton( + onPressed: () { + String urls = ''; + for (var a + in selectedApps) { + urls += '${a.url}\n'; + } + urls = urls.substring( + 0, urls.length - 1); + Share.share(urls, + subject: tr( + 'selectedAppURLsFromObtainium')); + Navigator.of(context) + .pop(); + }, + tooltip: tr( + 'shareSelectedAppURLs'), + icon: + const Icon(Icons.share), + ), + IconButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext + ctx) { + return GeneratedFormModal( + title: tr( + 'resetInstallStatusForSelectedAppsQuestion'), + items: const [], + initValid: true, + message: tr( + 'installStatusOfXWillBeResetExplanation', + args: [ + plural( + 'app', + selectedApps + .length) + ]), + ); + }).then((values) { + if (values != null) { + appsProvider.saveApps( + selectedApps + .map((e) { + e.installedVersion = + null; + return e; + }).toList()); + } + }).whenComplete(() { + Navigator.of(context) + .pop(); + }); + }, + tooltip: tr( + 'resetInstallStatus'), + icon: const Icon(Icons + .restore_page_outlined), + ), + ]), ), - IconButton( - onPressed: () { - String urls = ''; - for (var a in selectedApps) { - urls += '${a.url}\n'; - } - urls = urls.substring( - 0, urls.length - 1); - Share.share(urls, - subject: tr( - 'selectedAppURLsFromObtainium')); - Navigator.of(context).pop(); - }, - tooltip: tr('shareSelectedAppURLs'), - icon: const Icon(Icons.share), - ), - IconButton( - onPressed: () { - showDialog( - context: context, - builder: (BuildContext ctx) { - return GeneratedFormModal( - title: tr( - 'resetInstallStatusForSelectedAppsQuestion'), - items: const [], - initValid: true, - message: tr( - 'installStatusOfXWillBeResetExplanation', - args: [ - plural( - 'app', - selectedApps - .length) - ]), - ); - }).then((values) { - if (values != null) { - appsProvider.saveApps( - selectedApps.map((e) { - e.installedVersion = null; - return e; - }).toList()); - } - }).whenComplete(() { - Navigator.of(context).pop(); - }); - }, - tooltip: tr('resetInstallStatus'), - icon: const Icon( - Icons.restore_page_outlined), - ), - ]), - ), - ); - }); - }, - tooltip: tr('more'), - icon: const Icon(Icons.more_horiz), - ), - ], - )), + ); + }); + }, + tooltip: tr('more'), + icon: const Icon(Icons.more_horiz), + ), + ], + ))), const VerticalDivider(), IconButton( visualDensity: VisualDensity.compact, From 02751fe8fa8b618887ebc84341e8c80c201b9ac0 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 6 Jan 2023 20:57:26 -0500 Subject: [PATCH 2/4] Made GitHub PATs hidden (password field) (#215) --- lib/app_sources/github.dart | 1 + lib/components/generated_form.dart | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/app_sources/github.dart b/lib/app_sources/github.dart index 82af377..910eb61 100644 --- a/lib/app_sources/github.dart +++ b/lib/app_sources/github.dart @@ -15,6 +15,7 @@ class GitHub extends AppSource { additionalSourceSpecificSettingFormItems = [ GeneratedFormTextField('github-creds', label: tr('githubPATLabel'), + password: true, required: false, additionalValidators: [ (value) { diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 7698dd0..6a74181 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -3,7 +3,6 @@ import 'dart:math'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:obtainium/components/generated_form_modal.dart'; -import 'package:obtainium/providers/settings_provider.dart'; abstract class GeneratedFormItem { late String key; @@ -24,6 +23,7 @@ class GeneratedFormTextField extends GeneratedFormItem { late bool required; late int max; late String? hint; + late bool password; GeneratedFormTextField(String key, {String label = 'Input', @@ -32,7 +32,8 @@ class GeneratedFormTextField extends GeneratedFormItem { List additionalValidators = const [], this.required = true, this.max = 1, - this.hint}) + this.hint, + this.password = false}) : super(key, label: label, belowWidgets: belowWidgets, @@ -188,6 +189,9 @@ class _GeneratedFormState extends State { if (formItem is GeneratedFormTextField) { final formFieldKey = GlobalKey(); return TextFormField( + obscureText: formItem.password, + autocorrect: !formItem.password, + enableSuggestions: !formItem.password, key: formFieldKey, initialValue: values[formItem.key], autovalidateMode: AutovalidateMode.onUserInteraction, From 081c2a07d2e0b9a1d1175e7a49161b03bd780de9 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 6 Jan 2023 21:10:04 -0500 Subject: [PATCH 3/4] Categories re-added on import (#213) --- lib/components/generated_form.dart | 30 +++++++++++++++--------------- lib/pages/import_export.dart | 17 +++++++++++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index 6a74181..1a7e45e 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -130,6 +130,21 @@ class GeneratedForm extends StatefulWidget { State createState() => _GeneratedFormState(); } +// Generates a random light color +// Courtesy of ChatGPT 😭 (with a bugfix 🥳) +Color generateRandomLightColor() { + // Create a random number generator + final Random random = Random(); + + // Generate random hue, saturation, and value values + final double hue = random.nextDouble() * 360; + final double saturation = 0.5 + random.nextDouble() * 0.5; + final double value = 0.9 + random.nextDouble() * 0.1; + + // Create a HSV color with the random values + return HSVColor.fromAHSV(1.0, hue, saturation, value).toColor(); +} + class _GeneratedFormState extends State { final _formKey = GlobalKey(); Map values = {}; @@ -154,21 +169,6 @@ class _GeneratedFormState extends State { widget.onValueChanges(returnValues, valid, isBuilding); } - // Generates a random light color - // Courtesy of ChatGPT 😭 (with a bugfix 🥳) - Color generateRandomLightColor() { - // Create a random number generator - final Random random = Random(); - - // Generate random hue, saturation, and value values - final double hue = random.nextDouble() * 360; - final double saturation = 0.5 + random.nextDouble() * 0.5; - final double value = 0.9 + random.nextDouble() * 0.1; - - // Create a HSV color with the random values - return HSVColor.fromAHSV(1.0, hue, saturation, value).toColor(); - } - @override void initState() { super.initState(); diff --git a/lib/pages/import_export.dart b/lib/pages/import_export.dart index 5d09d00..f6d1dcf 100644 --- a/lib/pages/import_export.dart +++ b/lib/pages/import_export.dart @@ -9,6 +9,7 @@ import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/components/generated_form_modal.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/providers/apps_provider.dart'; +import 'package:obtainium/providers/settings_provider.dart'; import 'package:obtainium/providers/source_provider.dart'; import 'package:provider/provider.dart'; import 'package:file_picker/file_picker.dart'; @@ -28,6 +29,7 @@ class _ImportExportPageState extends State { Widget build(BuildContext context) { SourceProvider sourceProvider = SourceProvider(); var appsProvider = context.read(); + var settingsProvider = context.read(); var outlineButtonStyle = ButtonStyle( shape: MaterialStateProperty.all( StadiumBorder( @@ -100,6 +102,21 @@ class _ImportExportPageState extends State { appsProvider .importApps(data) .then((value) { + var cats = + settingsProvider.categories; + appsProvider.apps + .forEach((key, value) { + for (var c + in value.app.categories) { + if (!cats.containsKey(c)) { + cats[c] = + generateRandomLightColor() + .value; + } + } + }); + settingsProvider.categories = + cats; showError( tr('importedX', args: [ plural('apps', value) From 1c8e759494d5c6b6efebb7add7335facded3e8ec Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 6 Jan 2023 21:11:13 -0500 Subject: [PATCH 4/4] Increment version + updated packages --- lib/main.dart | 2 +- pubspec.lock | 8 ++++---- pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 12f540e..e48163b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,7 +21,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; // ignore: implementation_imports import 'package:easy_localization/src/localization.dart'; -const String currentVersion = '0.9.13'; +const String currentVersion = '0.9.14'; const String currentReleaseTag = 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES diff --git a/pubspec.lock b/pubspec.lock index b1d938b..3289058 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -56,7 +56,7 @@ packages: name: checked_yaml url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.2" cli_util: dependency: transitive description: @@ -286,7 +286,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "3.2.2" + version: "3.3.0" install_plugin_v2: dependency: "direct main" description: @@ -559,7 +559,7 @@ packages: name: shared_preferences_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" shared_preferences_platform_interface: dependency: transitive description: @@ -655,7 +655,7 @@ packages: name: timezone url: "https://pub.dartlang.org" source: hosted - version: "0.9.0" + version: "0.9.1" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e605c47..96f8173 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 0.9.13+103 # When changing this, update the tag in main() accordingly +version: 0.9.14+104 # When changing this, update the tag in main() accordingly environment: sdk: '>=2.18.2 <3.0.0'