v1.1.26 android release

This commit is contained in:
bossanyit 2022-11-13 09:43:49 +01:00
parent 20c481298f
commit 6ef311286c
11 changed files with 107 additions and 83 deletions

View File

@ -6,7 +6,7 @@ buildscript {
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:4.0.2" classpath "com.android.tools.build:gradle:7.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.gms:google-services:4.3.4" classpath "com.google.gms:google-services:4.3.4"
} }

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.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip

View File

@ -372,7 +372,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2; CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -518,7 +518,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2; CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -556,7 +556,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2; CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (

View File

@ -15,7 +15,10 @@ import 'package:aitrainer_app/util/purchases.dart';
import 'package:aitrainer_app/util/track.dart'; import 'package:aitrainer_app/util/track.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/services.dart';
import 'package:purchases_flutter/errors.dart';
import 'package:purchases_flutter/models/offering_wrapper.dart'; import 'package:purchases_flutter/models/offering_wrapper.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
part 'sales_event.dart'; part 'sales_event.dart';
part 'sales_state.dart'; part 'sales_state.dart';
@ -50,25 +53,46 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
final int productId = event.productId; final int productId = event.productId;
log("Requesting purchase for: " + productId.toString()); log("Requesting purchase for: " + productId.toString());
Track().track(TrackingEvent.purchase_request); Track().track(TrackingEvent.purchase_request);
final Product? selectedProduct = this.getSelectedProduct(productId); try {
log("SelectedProduct for purchase $selectedProduct"); final Product? selectedProduct = this.getSelectedProduct(productId);
if (selectedProduct != null) {
await RevenueCatPurchases().makePurchase(selectedProduct); log("SelectedProduct for purchase $selectedProduct");
if (Cache().hasPurchased) { if (selectedProduct != null) {
Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId); await RevenueCatPurchases().makePurchase(selectedProduct);
purchase.dateAdd = DateTime.now(); if (Cache().hasPurchased) {
purchase.purchaseSum = 0; Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId);
purchase.currency = "EUR"; purchase.dateAdd = DateTime.now();
await PurchaseApi().savePurchase(purchase); purchase.purchaseSum = 0;
Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString()); purchase.currency = "EUR";
CustomerRepository customerRepository = CustomerRepository(); await PurchaseApi().savePurchase(purchase);
customerRepository.customer = Cache().userLoggedIn; Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString());
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository); CustomerRepository customerRepository = CustomerRepository();
await mauticRepository.sendMauticPurchase(); customerRepository.customer = Cache().userLoggedIn;
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticPurchase();
}
emit(SalesSuccessful());
} else {
emit(SalesError(message: "No selected product"));
} }
emit(SalesSuccessful()); } on PlatformException catch (e) {
} else { await Sentry.captureException(e);
emit(SalesError(message: "No selected product")); var errorCode = PurchasesErrorHelper.getErrorCode(e);
if (errorCode == PurchasesErrorCode.invalidReceiptError) {
log("iOS Sandbox invalid receipt");
Cache().hasPurchased = true;
log(" -- Purchased -- ");
return;
}
log(e.toString());
if (errorCode == PurchasesErrorCode.purchaseCancelledError) {
emit(SalesError(message: "Purchase was cancelled"));
} else {
emit(SalesError(message: "Purchase was not successful"));
}
} on Exception catch (e) {
log(e.toString());
emit(SalesError(message: "Purchase was not successful"));
} }
} }

View File

@ -25,18 +25,23 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
log(" -------- Session starting..."); log(" -------- Session starting...");
emit(SessionLoading()); emit(SessionLoading());
this.settingsBloc = event.settingsBloc; try {
await session.fetchSessionAndNavigate(); this.settingsBloc = event.settingsBloc;
FirebaseApi().setupRemoteConfig(); await session.fetchSessionAndNavigate();
String lang = AppLanguage().appLocal.languageCode; FirebaseApi().setupRemoteConfig();
log("Change lang to $lang"); String lang = AppLanguage().appLocal.languageCode;
settingsBloc!.add(SettingsChangeLanguage(language: lang)); log("Change lang to $lang");
final iTunes = ITunesSearchAPI(); settingsBloc!.add(SettingsChangeLanguage(language: lang));
final resultsFuture = iTunes.lookupByBundleId('com.aitrainer.app'); final iTunes = ITunesSearchAPI();
resultsFuture.then((results) { final resultsFuture = iTunes.lookupByBundleId('com.aitrainer.app');
print('iTunes results: $results'); resultsFuture.then((results) {
}); print('iTunes results: $results');
emit(SessionReady()); });
} on Exception catch (e) {
emit(SessionFailure(message: e.toString()));
} finally {
emit(SessionReady());
}
} }
@override @override

View File

@ -70,7 +70,6 @@ import 'view/training_evaluation_page.dart';
import 'package:syncfusion_localizations/syncfusion_localizations.dart'; import 'package:syncfusion_localizations/syncfusion_localizations.dart';
const dsn = 'https://2309523cf2374c089fa1143d19209bc1@glitch.workouttest.org/2'; const dsn = 'https://2309523cf2374c089fa1143d19209bc1@glitch.workouttest.org/2';
//const dsn = 'https://be8b4f90398a45e68b6798c32c4e6baf@app.glitchtip.com/1992';
/// Whether the VM is running in debug mode. /// Whether the VM is running in debug mode.
/// ///
@ -152,10 +151,7 @@ Future<Null> main() async {
await initThirdParty(); await initThirdParty();
final FirebaseAnalytics analytics = FirebaseAnalytics.instance; final FirebaseAnalytics analytics = FirebaseAnalytics.instance;
await SentryFlutter.init( await SentryFlutter.init((options) => options..dsn = dsn,
(options) => options
..dsn = dsn
..debug = true,
appRunner: () => runApp(MultiBlocProvider( appRunner: () => runApp(MultiBlocProvider(
providers: [ providers: [
BlocProvider<SessionBloc>( BlocProvider<SessionBloc>(

View File

@ -118,7 +118,7 @@ class Cache with Logging {
static final String myTrainingPlanKey = "myTrainingPlan"; static final String myTrainingPlanKey = "myTrainingPlan";
static String baseUrlLive = 'https://api.workouttest.org/api/'; static String baseUrlLive = 'https://api.workouttest.org/api/';
static String baseUrlTest = 'https://api-test.workouttest.org/api/'; static String baseUrlTest = 'https://apitest.workouttest.org/api/';
late String baseUrl; late String baseUrl;
static final String mediaUrl = 'https://admin.aitrainer.app/media/'; static final String mediaUrl = 'https://admin.aitrainer.app/media/';
static final String username = 'bosi'; static final String username = 'bosi';

View File

@ -52,7 +52,12 @@ class APIClient with Common, Logging {
return jsonDecode(await result.transform(utf8.decoder).join()); return jsonDecode(await result.transform(utf8.decoder).join());
} catch (exception) { } catch (exception) {
print(exception.toString()); print(exception.toString());
await Sentry.captureException(exception); try {
await Sentry.captureException(exception);
} on Exception catch (e) {
print(e);
}
throw Exception("Network error, try again later!"); throw Exception("Network error, try again later!");
} }
} }

View File

@ -75,49 +75,34 @@ class RevenueCatPurchases with Logging {
} }
Future<void> makePurchase(wtproduct.Product product) async { Future<void> makePurchase(wtproduct.Product product) async {
try { if (_offering == null) {
if (_offering == null) { _offering = await getOfferings();
_offering = await getOfferings(); }
} if (_offering != null) {
if (_offering != null) { String productId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!;
String productId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!; Package? selectedPackage;
Package? selectedPackage; log("Nr of packages: " + _offering!.availablePackages.length.toString() + " ProductId: " + productId);
log("Nr of packages: " + _offering!.availablePackages.length.toString() + " ProductId: " + productId); for (var package in _offering!.availablePackages) {
for (var package in _offering!.availablePackages) { log("package to check " + package.product.identifier.toString());
log("package to check " + package.product.identifier.toString()); if (package.product.identifier == productId) {
if (package.product.identifier == productId) { selectedPackage = package;
selectedPackage = package; log("**** Selected package to purchase" + package.product.identifier);
log("**** Selected package to purchase" + package.product.identifier); break;
break;
}
} }
if (selectedPackage != null) { }
PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage); if (selectedPackage != null) {
if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) { PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage);
Cache().hasPurchased = true; if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
log(" -- Purchased -- "); Cache().hasPurchased = true;
} log(" -- Purchased -- ");
} else {
log("!!!! No Selected package to purchase");
throw Exception("Purchase was not successful");
} }
} else { } else {
log("!!!! No active offering"); log("!!!! No Selected package to purchase");
} throw Exception("No Selected package to purchase");
} on PlatformException catch (e) {
var errorCode = PurchasesErrorHelper.getErrorCode(e);
if (errorCode == PurchasesErrorCode.invalidReceiptError) {
log("iOS Sandbox invalid receipt");
Cache().hasPurchased = true;
log(" -- Purchased -- ");
return;
}
log(e.toString());
if (errorCode == PurchasesErrorCode.purchaseCancelledError) {
throw Exception("Purchase was cancelled");
} else {
throw Exception("Purchase was not successful");
} }
} else {
log("!!!! No active offering");
throw Exception("No active offering");
} }
} }
} }

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:aitrainer_app/bloc/session/session_bloc.dart'; import 'package:aitrainer_app/bloc/session/session_bloc.dart';
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart'; import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
@ -72,11 +74,18 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans, Traceable
final appcastURL = "https://raw.githubusercontent.com/bossanyit/appcast/main/android_rss.xml"; final appcastURL = "https://raw.githubusercontent.com/bossanyit/appcast/main/android_rss.xml";
final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']); final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']);
print("Packageinfo ${Cache().packageInfo}"); print("Packageinfo ${Cache().packageInfo}");
String minVersion = "";
if (Platform.isAndroid) {
minVersion = "[Minimum supported app version: 1.1.26]";
} else {
minVersion = "[:mav: 1.1.26]";
}
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: UpgradeAlert( body: UpgradeAlert(
upgrader: Upgrader(appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)), upgrader: Upgrader(
countryCode: "hu", minAppVersion: minVersion, appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)),
child: BlocConsumer<SessionBloc, SessionState>(listener: (context, state) { child: BlocConsumer<SessionBloc, SessionState>(listener: (context, state) {
if (state is SessionFailure) { if (state is SessionFailure) {
showDialog( showDialog(

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.26+107 version: 1.1.26+108
environment: environment:
sdk: ">=2.12.0 <3.9.0" sdk: ">=2.12.0 <3.9.0"