Show option to download native app

This commit is contained in:
Hillel Coren 2021-09-20 12:03:43 +03:00
parent 61e9e3b1b5
commit 64ee9eaf95
6 changed files with 99 additions and 11 deletions

View File

@ -258,6 +258,12 @@ const kGatewayTypes = {
const String kNotificationChannelEmail = 'email';
const String kNotificationChannelSlack = 'slack';
const String kPlatformWindows = 'Windows';
const String kPlatformLinux = 'Linux';
const String kPlatformMacOS = 'macOS';
const String kPlatformAndroid = 'Android';
const String kPlatformiPhone = 'iPhone';
const String kNotificationsAll = 'all_notifications';
const String kNotificationsAllUser = 'all_user_notifications';
const String kNotificationsPaymentSuccess = 'payment_success';

View File

@ -50,30 +50,24 @@ import 'package:invoiceninja_flutter/ui/credit/edit/credit_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/design/edit/design_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/group/edit/group_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/product/edit/product_edit_vm.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/recurring_expense/recurring_expense_state.dart';
import 'package:invoiceninja_flutter/ui/recurring_expense/edit/recurring_expense_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/recurring_expense/recurring_expense_selectors.dart';
import 'package:invoiceninja_flutter/redux/subscription/subscription_state.dart';
import 'package:invoiceninja_flutter/ui/recurring_expense/recurring_expense_screen.dart';
import 'package:invoiceninja_flutter/ui/subscription/edit/subscription_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/subscription/subscription_selectors.dart';
import 'package:invoiceninja_flutter/redux/task_status/task_status_state.dart';
import 'package:invoiceninja_flutter/ui/recurring_invoice/recurring_invoice_screen.dart';
import 'package:invoiceninja_flutter/ui/task_status/edit/task_status_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/task_status/task_status_selectors.dart';
import 'package:invoiceninja_flutter/redux/expense_category/expense_category_state.dart';
import 'package:invoiceninja_flutter/ui/expense_category/edit/expense_category_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/expense_category/expense_category_selectors.dart';
import 'package:invoiceninja_flutter/redux/recurring_invoice/recurring_invoice_state.dart';
import 'package:invoiceninja_flutter/ui/recurring_invoice/edit/recurring_invoice_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/recurring_invoice/recurring_invoice_selectors.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_state.dart';
import 'package:invoiceninja_flutter/ui/webhook/edit/webhook_edit_vm.dart';
import 'package:invoiceninja_flutter/redux/webhook/webhook_selectors.dart';

View File

@ -269,6 +269,7 @@ class _LoginState extends State<LoginView> {
@override
Widget build(BuildContext context) {
final localization = AppLocalization.of(context);
final platform = getNativePlatform();
final viewModel = widget.viewModel;
final state = viewModel.state;
@ -676,9 +677,15 @@ class _LoginState extends State<LoginView> {
]),
),
),
if (!_recoverPassword && !_isSelfHosted)
if (!_recoverPassword && (!_isSelfHosted || kIsWeb))
InkWell(
onTap: () => launch(kStatusCheckUrl),
onTap: () {
if (platform.isNotEmpty) {
launch(getNativeAppUrl(platform));
} else {
launch(kStatusCheckUrl);
}
},
child: Padding(
padding: const EdgeInsets.only(
left: 25, top: 12, right: 20, bottom: 12),
@ -686,9 +693,15 @@ class _LoginState extends State<LoginView> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.security, size: 16),
Icon(
platform.isEmpty
? Icons.security
: getNativeAppIcon(platform),
size: 16),
SizedBox(width: 8),
Text(localization.checkStatus)
Text(platform.isEmpty
? localization.checkStatus
: '$platform ${localization.app}')
],
),
),

View File

@ -15,6 +15,8 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = {
'en': {
// STARTER: lang key - do not remove comment
'app': 'App',
'for_best_performance': 'For the best performance download the :app app',
'gross_line_total': 'Gross Line Total',
'bulk_email_invoice': 'Email Invoice',
'bulk_email_quote': 'Email Quote',
@ -62623,6 +62625,13 @@ mixin LocalizationsProvider on LocaleCodeAware {
_localizedValues[localeCode]['gross_line_total'] ??
_localizedValues['en']['gross_line_total'];
String get forBestPerformance =>
_localizedValues[localeCode]['for_best_performance'] ??
_localizedValues['en']['for_best_performance'];
String get app =>
_localizedValues[localeCode]['app'] ?? _localizedValues['en']['app'];
// STARTER: lang field - do not remove comment
String lookup(String key) {

View File

@ -7,6 +7,9 @@ import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:invoiceninja_flutter/utils/web_stub.dart'
if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart';
bool isDesktopOS() => isMacOS() || isWindows() || isLinux();
@ -78,6 +81,69 @@ String getPdfRequirements(BuildContext context) {
}
}
String getNativePlatform() {
String userAgent = WebUtils.getHtmlValue('user-agent') ?? '';
userAgent = userAgent.toLowerCase();
if (userAgent.contains('ipad') ||
userAgent.contains('ipod') ||
userAgent.contains('iphone')) {
return kPlatformiPhone;
} else if (userAgent.contains('android')) {
return kPlatformAndroid;
} else if (userAgent.contains('win')) {
return kPlatformWindows;
} else if (userAgent.contains('mac')) {
return kPlatformMacOS;
} else if (userAgent.contains('linux')) {
return kPlatformLinux;
} else {
return '';
}
}
String getNativeAppUrl(String platform) {
if (!kIsWeb) {
return '';
}
switch (platform) {
case kPlatformAndroid:
return kGoogleStoreUrl;
case kPlatformiPhone:
return kAppleStoreUrl;
case kPlatformWindows:
return kWindowsUrl;
case kPlatformMacOS:
return kMacOSUrl;
case kPlatformLinux:
return kLinuxUrl;
}
return '';
}
IconData getNativeAppIcon(String platform) {
if (!kIsWeb) {
return null;
}
switch (platform) {
case kPlatformAndroid:
return Icons.android;
case kPlatformiPhone:
return MdiIcons.apple;
case kPlatformWindows:
return MdiIcons.microsoft;
case kPlatformMacOS:
return MdiIcons.apple;
case kPlatformLinux:
return MdiIcons.linux;
}
return null;
}
String getPlatform(BuildContext context) =>
Theme.of(context).platform == TargetPlatform.iOS ? 'ios' : 'android';

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html data-report-errors="1" data-rc="" data-user-agent="">
<head>
<base href="/">