6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 4b941663
Changed files
.../android/app/src/main/AndroidManifest.xml | 1 + comwell_key_app/ios/Runner/Info.plist | 2 ++ comwell_key_app/lib/comwell_app.dart | 3 +- .../pregistration/cubit/preregistration_cubit.dart | 8 ++--- .../lib/presentation/app/bloc/app_cubit.dart | 34 ++++++++++++++++++++-- .../bloc/booking_details_cubit.dart | 3 +- comwell_key_app/lib/routing/app_router.dart | 3 +- comwell_key_app/lib/services/http_client.dart | 8 ++--- .../interceptors/response_handle_interceptor.dart | 9 ++++-- comwell_key_app/lib/utils/cubit_utils.dart | 7 +++++ comwell_key_app/lib/utils/firebase.dart | 5 ++++ comwell_key_app/lib/utils/secure_storage.dart | 7 +++++ 12 files changed, 75 insertions(+), 15 deletions(-)
Diff
diff --git a/comwell_key_app/android/app/src/main/AndroidManifest.xml b/comwell_key_app/android/app/src/main/AndroidManifest.xml
index 39c38040..c78454ee 100644
--- a/comwell_key_app/android/app/src/main/AndroidManifest.xml
+++ b/comwell_key_app/android/app/src/main/AndroidManifest.xml
@@ -93,5 +93,6 @@
<meta-data android:name="google_analytics_default_allow_ad_storage" android:value="false" />
<meta-data android:name="google_analytics_default_allow_ad_user_data" android:value="false" />
<meta-data android:name="google_analytics_default_allow_ad_personalization_signals" android:value="false" />
+ <meta-data android:name="google_analytics_automatic_screen_reporting_enabled" android:value="false" />
</application>
</manifest>
diff --git a/comwell_key_app/ios/Runner/Info.plist b/comwell_key_app/ios/Runner/Info.plist
index 6bb4ee28..af498d91 100644
--- a/comwell_key_app/ios/Runner/Info.plist
+++ b/comwell_key_app/ios/Runner/Info.plist
@@ -76,6 +76,8 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FIREBASE_ANALYTICS_COLLECTION_ENABLED</key>
<false/>
+ <key>FirebaseAutomaticScreenReportingEnabled</key>
+ <false/>
<key>FlutterDeepLinkingEnabled</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
diff --git a/comwell_key_app/lib/comwell_app.dart b/comwell_key_app/lib/comwell_app.dart
index 3ac66650..49da3601 100644
--- a/comwell_key_app/lib/comwell_app.dart
+++ b/comwell_key_app/lib/comwell_app.dart
@@ -41,7 +41,7 @@ class ComwellApp extends StatelessWidget {
child: MultiBlocProvider(
providers: [
BlocProvider(
- create: (context) => AppCubit(),
+ create: (context) => AppCubit(locator.get()),
),
BlocProvider(
create: (context) => ConnectionStateCubit(
@@ -83,6 +83,7 @@ class ComwellApp extends StatelessWidget {
title: 'Comwell Key App',
routerConfig: router,
supportedLocales: AppLocalizations.supportedLocales,
+
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
diff --git a/comwell_key_app/lib/pregistration/cubit/preregistration_cubit.dart b/comwell_key_app/lib/pregistration/cubit/preregistration_cubit.dart
index 4c727af7..d103095f 100644
--- a/comwell_key_app/lib/pregistration/cubit/preregistration_cubit.dart
+++ b/comwell_key_app/lib/pregistration/cubit/preregistration_cubit.dart
@@ -82,14 +82,14 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
selectedCountry: '',
),
) {
- _tracking.trackScreenView(
- "Pre-registration - Betalingskort",
- "/pre-registration/betalingskort",
- );
init();
}
void init() async {
+ _tracking.trackScreenView(
+ "Pre-registration - Betalingskort",
+ "/pre-registration/betalingskort",
+ );
setupListeners();
emit(state.copyWith(isLoading: true));
try {
diff --git a/comwell_key_app/lib/presentation/app/bloc/app_cubit.dart b/comwell_key_app/lib/presentation/app/bloc/app_cubit.dart
index 6074bae9..7883145f 100644
--- a/comwell_key_app/lib/presentation/app/bloc/app_cubit.dart
+++ b/comwell_key_app/lib/presentation/app/bloc/app_cubit.dart
@@ -1,16 +1,22 @@
import 'dart:async';
+import 'dart:io';
import 'package:app_links/app_links.dart';
import 'package:comwell_key_app/base/base_cubit.dart';
import 'package:comwell_key_app/presentation/app/app_events.dart';
+import 'package:comwell_key_app/utils/secure_storage.dart';
import 'package:comwell_key_app/utils/uri_utils.dart';
import 'package:comwell_key_app/domain/models/app_error.dart';
+import 'package:device_info_plus/device_info_plus.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
+import 'package:package_info_plus/package_info_plus.dart';
part '../../../.generated/presentation/app/bloc/app_cubit.freezed.dart';
class AppCubit extends BaseCubit<AppState> {
- AppCubit() : super(const AppState()) {
+ final ComwellPreferences _comwellPreferences;
+
+ AppCubit(this._comwellPreferences) : super(const AppState()) {
_init();
}
@@ -22,12 +28,36 @@ class AppCubit extends BaseCubit<AppState> {
navigate(uri);
}
});
+ cacheUserAgent();
}
void navigate(Uri uri) {
safeEmit(state.copyWith(event: Navigate(uri)));
}
+ Future<void> cacheUserAgent() async {
+ try {
+ final packageInfo = await PackageInfo.fromPlatform();
+ final String osVersion;
+ if (Platform.isAndroid) {
+ final deviceInfo = await DeviceInfoPlugin().androidInfo;
+ osVersion = deviceInfo.version.sdkInt.toString();
+ } else {
+ final deviceInfo = await DeviceInfoPlugin().iosInfo;
+ osVersion = deviceInfo.systemVersion;
+ }
+
+ final platform = Platform.isAndroid ? 'android' : 'ios';
+ final versionCode = packageInfo.buildNumber;
+ final versionName = packageInfo.version;
+ await _comwellPreferences.setUserAgent(
+ "ComwellKeyApp/$versionName ($platform; OS $osVersion; Build $versionCode)",
+ );
+ } catch (e, st) {
+ logError(e, st);
+ }
+ }
+
@override
Future<void> close() async {
await _appLinksSubscription.cancel();
@@ -42,4 +72,4 @@ abstract class AppState with _$AppState {
@Default(AppError.none) AppError error,
@Default(null) AppEvent? event,
}) = _AppState;
-}
\ No newline at end of file
+}
diff --git a/comwell_key_app/lib/presentation/screens/booking_details/bloc/booking_details_cubit.dart b/comwell_key_app/lib/presentation/screens/booking_details/bloc/booking_details_cubit.dart
index 85e952c9..cbabc1b2 100644
--- a/comwell_key_app/lib/presentation/screens/booking_details/bloc/booking_details_cubit.dart
+++ b/comwell_key_app/lib/presentation/screens/booking_details/bloc/booking_details_cubit.dart
@@ -268,8 +268,9 @@ class BookingDetailsCubit extends BaseCubit<BookingDetailsState> {
bool get canOrderHousekeeping {
final now = DateTime.now();
final tomorrow = DateTime(now.year, now.month, now.day + 1);
+ final today = DateTime(now.year, now.month, now.day);
final checkoutDay = DateTime(booking.endDate.year, booking.endDate.month, booking.endDate.day);
- if (checkoutDay == tomorrow) return false;
+ if (checkoutDay == tomorrow || checkoutDay == today) return false;
return booking.endDate.difference(booking.startDate).inDays >= 2;
}
diff --git a/comwell_key_app/lib/routing/app_router.dart b/comwell_key_app/lib/routing/app_router.dart
index dc658ebb..81b40a49 100644
--- a/comwell_key_app/lib/routing/app_router.dart
+++ b/comwell_key_app/lib/routing/app_router.dart
@@ -27,6 +27,7 @@ import 'package:comwell_key_app/routing/go_router_observer.dart';
import 'package:comwell_key_app/share/share_booking_route.dart';
import 'package:comwell_key_app/up_sales/up_sales_route.dart';
import 'package:comwell_key_app/utils/context_utils.dart';
+import 'package:comwell_key_app/utils/firebase.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
@@ -45,7 +46,7 @@ final router = GoRouter(
initialLocation: AppRoutes.overview,
navigatorKey: _rootNavigatorKey,
debugLogDiagnostics: true,
- observers: [GoRouterObserver()],
+ observers: [GoRouterObserver(), firebaseAnalyticsObserver],
redirect: (context, state) {
final authRepo = locator<AuthenticationRepository>();
final isLoggedIn = authRepo.isLoggedIn;
diff --git a/comwell_key_app/lib/services/http_client.dart b/comwell_key_app/lib/services/http_client.dart
index d67b6fbc..3b0fcf9e 100644
--- a/comwell_key_app/lib/services/http_client.dart
+++ b/comwell_key_app/lib/services/http_client.dart
@@ -16,13 +16,13 @@ class ComwellHttpClient {
final dio = Dio(
BaseOptions(
baseUrl: dotenv.SERVICE_URL,
- receiveTimeout: const Duration(milliseconds: 15000),
- connectTimeout: const Duration(milliseconds: 15000),
- sendTimeout: const Duration(milliseconds: 15000),
+ receiveTimeout: const Duration(seconds: 15),
+ connectTimeout: const Duration(seconds: 15),
+ sendTimeout: const Duration(seconds: 15),
),
);
dio.interceptors.add(
- ResponseHandleInterceptor(locator.get()),
+ ResponseHandleInterceptor(locator.get(), locator.get()),
);
if (kDebugMode) dio.interceptors.add(PrettyDioLogger(requestHeader: true));
return dio;
diff --git a/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart b/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart
index d37f86fd..121a0727 100644
--- a/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart
+++ b/comwell_key_app/lib/services/interceptors/response_handle_interceptor.dart
@@ -4,15 +4,16 @@ import 'package:comwell_key_app/routing/app_routes.dart';
import 'package:comwell_key_app/services/exceptions.dart';
import 'package:comwell_key_app/utils/env_utils.dart';
import 'package:comwell_key_app/utils/locator.dart';
+import 'package:comwell_key_app/utils/secure_storage.dart';
import 'package:dio/dio.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
-import 'package:go_router/go_router.dart';
import 'package:flutter/material.dart';
class ResponseHandleInterceptor extends Interceptor {
+ final ComwellPreferences _comwellPreferences;
final MSALService _msalService;
- ResponseHandleInterceptor(this._msalService);
+ ResponseHandleInterceptor(this._msalService, this._comwellPreferences);
BuildContext? get context {
final navigatorKey = locator<GlobalKey<NavigatorState>>();
@@ -28,6 +29,9 @@ class ResponseHandleInterceptor extends Interceptor {
throw UnauthorizedException();
}
}
+ void addUserAgentHeader(RequestOptions requestOptions) {
+ requestOptions.headers['User-Agent'] = _comwellPreferences.userAgent;
+ }
@override
Future<dynamic> onRequest(
@@ -37,6 +41,7 @@ class ResponseHandleInterceptor extends Interceptor {
try {
await checkAuth(options);
options.headers['Ocp-Apim-Subscription-Key'] = dotenv.OCP_APIM_SUBSCRIPTION_KEY;
+ addUserAgentHeader(options);
return handler.next(options);
} on UnauthorizedException catch (e, st) {
final exc = DioException(requestOptions: options, error: e, stackTrace: st);
diff --git a/comwell_key_app/lib/utils/cubit_utils.dart b/comwell_key_app/lib/utils/cubit_utils.dart
new file mode 100644
index 00000000..db6b2de2
--- /dev/null
+++ b/comwell_key_app/lib/utils/cubit_utils.dart
@@ -0,0 +1,7 @@
+import 'package:comwell_key_app/tracking/comwell_tracking.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+extension CubitUtils on BuildContext {
+ ComwellTracking get tracker => read<ComwellTracking>();
+}
diff --git a/comwell_key_app/lib/utils/firebase.dart b/comwell_key_app/lib/utils/firebase.dart
index a6a6ce50..863a1bc0 100644
--- a/comwell_key_app/lib/utils/firebase.dart
+++ b/comwell_key_app/lib/utils/firebase.dart
@@ -13,6 +13,11 @@ Future<void> _backgroundHandler(RemoteMessage message) async {
debugPrint('Background message: ${message.data}');
}
+final FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.instance;
+final firebaseAnalyticsObserver = FirebaseAnalyticsObserver(
+ analytics: firebaseAnalytics,
+);
+
Future<void> configureFirebase() async {
final firebaseOptions = switch (appFlavor?.toLowerCase()) {
'prod' => prod.DefaultFirebaseOptions.currentPlatform,
diff --git a/comwell_key_app/lib/utils/secure_storage.dart b/comwell_key_app/lib/utils/secure_storage.dart
index 3d1d8677..9c0d7019 100644
--- a/comwell_key_app/lib/utils/secure_storage.dart
+++ b/comwell_key_app/lib/utils/secure_storage.dart
@@ -80,6 +80,13 @@ class ComwellPreferences {
await _sharedPreferences.clear();
}
+ Future<void> setUserAgent(String userAgent) async {
+ await _sharedPreferences.setString(_keyUserAgent, userAgent);
+ }
+
+ String get userAgent => _sharedPreferences.getString(_keyUserAgent) ?? '';
+
+ static const _keyUserAgent = "user_agent";
static const _keyOnboardingHasSeenBluetooth = "_keyOnboardingHasSeenBluetooth";
static const _keyOnboardingHasSeenNotification = "_keyOnboardingHasSeenNotification";
static const _keyOnboardingHasSeenUsageTracking = "_keyOnboardingHasSeenUsageTracking";