App review
This commit is contained in:
parent
53f74c2d88
commit
b298b1179b
|
|
@ -25,16 +25,18 @@ const String kSourceCodeFrontend =
|
||||||
'https://github.com/invoiceninja/admin-portal';
|
'https://github.com/invoiceninja/admin-portal';
|
||||||
const String kSourceCodeFrontendSDK = 'https://pub.dev/packages/invoiceninja';
|
const String kSourceCodeFrontendSDK = 'https://pub.dev/packages/invoiceninja';
|
||||||
|
|
||||||
|
const String kAppStoreId = 'com.invoiceninja.app';
|
||||||
|
const String kMicrosoftAppStoreId = '9n3f2bbcfdr6';
|
||||||
const String kAppleStoreUrl =
|
const String kAppleStoreUrl =
|
||||||
'https://apps.apple.com/us/app/invoice-ninja-v5/id1503970375';
|
'https://apps.apple.com/us/app/invoice-ninja-v5/id1503970375';
|
||||||
const String kGoogleStoreUrl =
|
const String kGoogleStoreUrl =
|
||||||
'https://play.google.com/store/apps/details?id=com.invoiceninja.app';
|
'https://play.google.com/store/apps/details?id=$kAppStoreId';
|
||||||
const String kGoogleFDroidUrl =
|
const String kGoogleFDroidUrl =
|
||||||
'https://f-droid.org/packages/com.invoiceninja.app';
|
'https://f-droid.org/packages/com.invoiceninja.app';
|
||||||
const String kMacOSUrl = 'https://apps.apple.com/app/id1503970375';
|
const String kMacOSUrl = 'https://apps.apple.com/app/id1503970375';
|
||||||
const String kLinuxUrl = 'https://snapcraft.io/invoiceninja';
|
const String kLinuxUrl = 'https://snapcraft.io/invoiceninja';
|
||||||
const String kWindowsUrl =
|
const String kWindowsUrl =
|
||||||
'https://www.microsoft.com/en-us/p/invoice-ninja/9n3f2bbcfdr6';
|
'https://www.microsoft.com/en-us/p/invoice-ninja/$kMicrosoftAppStoreId';
|
||||||
|
|
||||||
const String kSlackUrl = 'http://slack.invoiceninja.com';
|
const String kSlackUrl = 'http://slack.invoiceninja.com';
|
||||||
const String kGitHubUrl = 'https://github.com/invoiceninja';
|
const String kGitHubUrl = 'https://github.com/invoiceninja';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'dart:convert';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:in_app_review/in_app_review.dart';
|
||||||
|
|
||||||
// Package imports:
|
// Package imports:
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
@ -1379,7 +1380,17 @@ void _showAbout(BuildContext context) async {
|
||||||
label: localization.reviewApp.toUpperCase(),
|
label: localization.reviewApp.toUpperCase(),
|
||||||
iconData: Icons.star,
|
iconData: Icons.star,
|
||||||
color: Colors.purple,
|
color: Colors.purple,
|
||||||
onPressed: () => launch(getRateAppURL(context)),
|
onPressed: () {
|
||||||
|
if (kIsWeb || isLinux()) {
|
||||||
|
launch(getRateAppURL(context));
|
||||||
|
} else {
|
||||||
|
final InAppReview inAppReview = InAppReview.instance;
|
||||||
|
inAppReview.openStoreListing(
|
||||||
|
appStoreId: kAppStoreId,
|
||||||
|
microsoftStoreId: kMicrosoftAppStoreId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
SizedBox(height: 22),
|
SizedBox(height: 22),
|
||||||
Wrap(
|
Wrap(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:invoiceninja_flutter/constants.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
||||||
|
|
@ -7,6 +9,7 @@ import 'package:invoiceninja_flutter/ui/app/menu_drawer.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'package:in_app_review/in_app_review.dart';
|
||||||
|
|
||||||
class ReviewApp extends StatefulWidget {
|
class ReviewApp extends StatefulWidget {
|
||||||
const ReviewApp({Key key}) : super(key: key);
|
const ReviewApp({Key key}) : super(key: key);
|
||||||
|
|
@ -18,6 +21,8 @@ class ReviewApp extends StatefulWidget {
|
||||||
class _ReviewAppState extends State<ReviewApp> {
|
class _ReviewAppState extends State<ReviewApp> {
|
||||||
bool _likesTheApp;
|
bool _likesTheApp;
|
||||||
|
|
||||||
|
final InAppReview inAppReview = InAppReview.instance;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
|
|
@ -33,7 +38,7 @@ class _ReviewAppState extends State<ReviewApp> {
|
||||||
_likesTheApp == null
|
_likesTheApp == null
|
||||||
? localization.areYouEnjoyingTheApp
|
? localization.areYouEnjoyingTheApp
|
||||||
: _likesTheApp == true
|
: _likesTheApp == true
|
||||||
? localization.wouldYouLeaveAReview
|
? localization.wouldYouRateIt
|
||||||
: localization.wouldYouTellUsMore,
|
: localization.wouldYouTellUsMore,
|
||||||
style: Theme.of(context).textTheme.subtitle1,
|
style: Theme.of(context).textTheme.subtitle1,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
|
|
@ -42,14 +47,23 @@ class _ReviewAppState extends State<ReviewApp> {
|
||||||
Wrap(
|
Wrap(
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
if (_likesTheApp == null) {
|
if (_likesTheApp == null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_likesTheApp = true;
|
_likesTheApp = true;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (_likesTheApp == true) {
|
if (_likesTheApp == true) {
|
||||||
launch(getRateAppURL(context));
|
if (await inAppReview.isAvailable()) {
|
||||||
|
inAppReview.requestReview();
|
||||||
|
} else if (kIsWeb || isLinux()) {
|
||||||
|
launch(getRateAppURL(context));
|
||||||
|
} else {
|
||||||
|
inAppReview.openStoreListing(
|
||||||
|
appStoreId: kAppStoreId,
|
||||||
|
microsoftStoreId: kMicrosoftAppStoreId,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showDialog<void>(
|
showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
'are_you_enjoying_the_app': 'Are you enjoying the app?',
|
'are_you_enjoying_the_app': 'Are you enjoying the app?',
|
||||||
'yes_its_great': 'Yes, it\'s great!',
|
'yes_its_great': 'Yes, it\'s great!',
|
||||||
'not_so_much': 'Not so much',
|
'not_so_much': 'Not so much',
|
||||||
'would_you_leave_a_review':
|
'would_you_rate_it': 'Great to hear! Would you like to rate it?',
|
||||||
'Great to hear! Would you like to leave a review?',
|
|
||||||
'would_you_tell_us_more':
|
'would_you_tell_us_more':
|
||||||
'Sorry to hear it! Would you like to tell us more?',
|
'Sorry to hear it! Would you like to tell us more?',
|
||||||
'sure_happy_to': 'Sure, happy to',
|
'sure_happy_to': 'Sure, happy to',
|
||||||
|
|
@ -70873,9 +70872,9 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
||||||
_localizedValues[localeCode]['are_you_enjoying_the_app'] ??
|
_localizedValues[localeCode]['are_you_enjoying_the_app'] ??
|
||||||
_localizedValues['en']['are_you_enjoying_the_app'];
|
_localizedValues['en']['are_you_enjoying_the_app'];
|
||||||
|
|
||||||
String get wouldYouLeaveAReview =>
|
String get wouldYouRateIt =>
|
||||||
_localizedValues[localeCode]['would_you_leave_a_review'] ??
|
_localizedValues[localeCode]['would_you_rate_it'] ??
|
||||||
_localizedValues['en']['would_you_leave_a_review'];
|
_localizedValues['en']['would_you_rate_it'];
|
||||||
|
|
||||||
String get wouldYouTellUsMore =>
|
String get wouldYouTellUsMore =>
|
||||||
_localizedValues[localeCode]['would_you_tell_us_more'] ??
|
_localizedValues[localeCode]['would_you_tell_us_more'] ??
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import in_app_review
|
||||||
import package_info
|
import package_info
|
||||||
import package_info_plus_macos
|
import package_info_plus_macos
|
||||||
import path_provider_macos
|
import path_provider_macos
|
||||||
|
|
@ -15,6 +16,7 @@ import sqflite
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
||||||
FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
|
FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
|
||||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ dependencies:
|
||||||
printing: ^5.8.0
|
printing: ^5.8.0
|
||||||
image_cropper: ^2.0.2
|
image_cropper: ^2.0.2
|
||||||
msal_js: ^2.14.0
|
msal_js: ^2.14.0
|
||||||
|
in_app_review: ^2.0.4
|
||||||
# bitsdojo_window: ^0.1.2
|
# bitsdojo_window: ^0.1.2
|
||||||
# quick_actions: ^0.2.1
|
# quick_actions: ^0.2.1
|
||||||
# idb_shim: ^1.11.1+1
|
# idb_shim: ^1.11.1+1
|
||||||
|
|
|
||||||
14
pubspec.lock
14
pubspec.lock
|
|
@ -570,6 +570,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.6.0"
|
version: "4.6.0"
|
||||||
|
in_app_review:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: in_app_review
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.4"
|
||||||
|
in_app_review_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: in_app_review_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.3"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ dependencies:
|
||||||
printing: ^5.8.0
|
printing: ^5.8.0
|
||||||
image_cropper: ^2.0.2
|
image_cropper: ^2.0.2
|
||||||
msal_js: ^2.14.0
|
msal_js: ^2.14.0
|
||||||
|
in_app_review: ^2.0.4
|
||||||
# bitsdojo_window: ^0.1.2
|
# bitsdojo_window: ^0.1.2
|
||||||
# quick_actions: ^0.2.1
|
# quick_actions: ^0.2.1
|
||||||
# idb_shim: ^1.11.1+1
|
# idb_shim: ^1.11.1+1
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ dependencies:
|
||||||
printing: ^5.8.0
|
printing: ^5.8.0
|
||||||
image_cropper: ^2.0.2
|
image_cropper: ^2.0.2
|
||||||
msal_js: ^2.14.0
|
msal_js: ^2.14.0
|
||||||
|
in_app_review: ^2.0.4
|
||||||
# bitsdojo_window: ^0.1.2
|
# bitsdojo_window: ^0.1.2
|
||||||
# quick_actions: ^0.2.1
|
# quick_actions: ^0.2.1
|
||||||
# idb_shim: ^1.11.1+1
|
# idb_shim: ^1.11.1+1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue