Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Device Settings, Intercom Integration and Improvements #902

Merged
merged 14 commits into from
Sep 24, 2024
Merged
5 changes: 4 additions & 1 deletion app/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ if (keystorePropertiesFile.exists()) {

android {

namespace "com.friend.ios"


Comment on lines +40 to +42

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

The namespace "com.friend.ios" seems to be added in the Android build.gradle file. This could potentially cause confusion as it's an iOS namespace being used in an Android context. If this is intentional and required for some reason, consider adding a comment explaining why this is necessary.

-    namespace "com.friend.ios"
+    // Using iOS namespace due to XYZ reason
+    namespace "com.friend.ios"

// ----- BEGIN flavorDimensions (autogenerated by flutter_flavorizr) -----
flavorDimensions += "flavor-type"

Expand Down Expand Up @@ -105,6 +108,7 @@ android {
shrinkResources true
}
debug{
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

You've added ProGuard rules file to the debug build type. While this is not an issue per se, it's unusual to use ProGuard in debug builds as it obfuscates the code, making debugging more difficult. If you have a specific reason for doing this, it's fine. Otherwise, consider removing it from the debug build type.

+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

minifyEnabled true
}
}
Expand All @@ -117,7 +121,6 @@ flutter {
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10"
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.multidex:multidex:2.0.1'
Comment on lines 129 to 132

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

The Kotlin dependency has been removed from the dependencies block. If Kotlin is no longer being used in the project, this is fine. However, if there are still parts of the project written in Kotlin, this will cause compilation errors. Please ensure that all Kotlin code has been properly migrated to Java or another language before removing this dependency.

Expand Down
23 changes: 23 additions & 0 deletions app/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# This is generated automatically by the Android Gradle plugin.
-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication
-dontwarn com.google.android.play.core.splitinstall.SplitInstallException
-dontwarn com.google.android.play.core.splitinstall.SplitInstallManager
-dontwarn com.google.android.play.core.splitinstall.SplitInstallManagerFactory
-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest$Builder
-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest
-dontwarn com.google.android.play.core.splitinstall.SplitInstallSessionState
-dontwarn com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener
-dontwarn com.google.android.play.core.tasks.OnFailureListener
-dontwarn com.google.android.play.core.tasks.OnSuccessListener
-dontwarn com.google.android.play.core.tasks.Task

# XML parser stuff
-dontwarn org.xmlpull.v1.**
-dontwarn org.kxml2.io.**
-dontwarn android.content.res.**
-dontwarn org.slf4j.impl.StaticLoggerBinder


-keep class org.xmlpull.** { *; }
-keepclassmembers class org.xmlpull.** { *; }

#Flutter Wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
Expand Down
12 changes: 12 additions & 0 deletions app/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ allprojects {
google()
mavenCentral()
}
subprojects {
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android {
if (namespace == null) {
namespace project.group
}
}
}
}
}
}

rootProject.buildDir = '../build'
Expand All @@ -13,6 +24,7 @@ subprojects {
project.evaluationDependsOn(':app')
}


tasks.register("clean", Delete) {
delete rootProject.buildDir
}
4 changes: 2 additions & 2 deletions app/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
#Sun Sep 22 21:12:01 IST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
4 changes: 2 additions & 2 deletions app/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ pluginManagement {

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.2" apply false
id "com.android.application" version "8.1.4" apply false
// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
// END: FlutterFire Configuration
id "org.jetbrains.kotlin.android" version "1.8.21" apply false
id "org.jetbrains.kotlin.android" version "1.9.21" apply false


}
Expand Down
2 changes: 1 addition & 1 deletion app/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '14.0'
platform :ios, '15.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
18 changes: 9 additions & 9 deletions app/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerDebug-prod.entitlements";
DEVELOPMENT_TEAM = 9536L8KLMP;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

The iOS deployment target has been updated from 14.0 to 15.0. This change will require all users to have at least iOS 15.0 installed on their devices to use the app. If there are still a significant number of users on iOS 14, this could potentially exclude them from being able to update or install the app. Please ensure that this change aligns with your user base and support strategy.

- 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
+ 				IPHONEOS_DEPLOYMENT_TARGET = 15.0;

PRODUCT_BUNDLE_IDENTIFIER = "com.friend-app-with-wearable.ios12";
PRODUCT_NAME = Runner;
TARGETED_DEVICE_FAMILY = 1;
Expand All @@ -461,7 +461,7 @@
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerProfile-prod.entitlements";
DEVELOPMENT_TEAM = 9536L8KLMP;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.friend-app-with-wearable.ios12";
PRODUCT_NAME = Runner;
TARGETED_DEVICE_FAMILY = 1;
Expand All @@ -477,7 +477,7 @@
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-prod.entitlements";
DEVELOPMENT_TEAM = 9536L8KLMP;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.friend-app-with-wearable.ios12";
PRODUCT_NAME = Runner;
TARGETED_DEVICE_FAMILY = 1;
Expand All @@ -493,7 +493,7 @@
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerDebug-dev.entitlements";
DEVELOPMENT_TEAM = 9536L8KLMP;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.friend-app-with-wearable.ios12.development";
PRODUCT_NAME = Runner;
TARGETED_DEVICE_FAMILY = 1;
Expand All @@ -509,7 +509,7 @@
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerProfile-dev.entitlements";
DEVELOPMENT_TEAM = 9536L8KLMP;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.friend-app-with-wearable.ios12.development";
PRODUCT_NAME = Runner;
TARGETED_DEVICE_FAMILY = 1;
Expand All @@ -525,7 +525,7 @@
CODE_SIGN_ENTITLEMENTS = "Runner/RunnerRelease-dev.entitlements";
DEVELOPMENT_TEAM = 9536L8KLMP;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.friend-app-with-wearable.ios12.development";
PRODUCT_NAME = Runner;
TARGETED_DEVICE_FAMILY = 1;
Expand Down Expand Up @@ -604,7 +604,7 @@
);
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -904,7 +904,7 @@
);
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -949,7 +949,7 @@
);
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Omi;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
2 changes: 2 additions & 0 deletions app/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
<string>We need access to your photo library to allow you to upload and share photos through Instabug.</string>
<key>PermissionGroupNotification</key>
<string>You need to enable notifications to receive your pro-active feedback.</string>
<key>NSCameraUsageDescription</key>
<string>Camera access is required to report issues</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
Expand Down
12 changes: 12 additions & 0 deletions app/lib/env/dev_env.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,16 @@ final class DevEnv implements EnvFields {
@override
@EnviedField(varName: 'GLEAP_API_KEY', obfuscate: true)
final String? gleapApiKey = _DevEnv.gleapApiKey;

@override
@EnviedField(varName: 'INTERCOM_APP_ID', obfuscate: true)
final String? intercomAppId = _DevEnv.intercomAppId;

@override
@EnviedField(varName: 'INTERCOM_IOS_API_KEY', obfuscate: true)
final String? intercomIOSApiKey = _DevEnv.intercomIOSApiKey;

@override
@EnviedField(varName: 'INTERCOM_ANDROID_API_KEY', obfuscate: true)
final String? intercomAndroidApiKey = _DevEnv.intercomAndroidApiKey;
}
12 changes: 12 additions & 0 deletions app/lib/env/env.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ abstract class Env {
static String? get googleMapsApiKey => _instance.googleMapsApiKey;

static String? get gleapApiKey => _instance.gleapApiKey;

static String? get intercomAppId => _instance.intercomAppId;

static String? get intercomIOSApiKey => _instance.intercomIOSApiKey;

static String? get intercomAndroidApiKey => _instance.intercomAndroidApiKey;
}

abstract class EnvFields {
Expand All @@ -40,4 +46,10 @@ abstract class EnvFields {
String? get googleMapsApiKey;

String? get gleapApiKey;

String? get intercomAppId;

String? get intercomIOSApiKey;

String? get intercomAndroidApiKey;
}
12 changes: 12 additions & 0 deletions app/lib/env/prod_env.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,16 @@ final class ProdEnv implements EnvFields {
@override
@EnviedField(varName: 'GLEAP_API_KEY', obfuscate: true)
final String? gleapApiKey = _ProdEnv.gleapApiKey;

@override
@EnviedField(varName: 'INTERCOM_APP_ID', obfuscate: true)
final String? intercomAppId = _ProdEnv.intercomAppId;

@override
@EnviedField(varName: 'INTERCOM_IOS_API_KEY', obfuscate: true)
final String? intercomIOSApiKey = _ProdEnv.intercomIOSApiKey;

@override
@EnviedField(varName: 'INTERCOM_ANDROID_API_KEY', obfuscate: true)
final String? intercomAndroidApiKey = _ProdEnv.intercomAndroidApiKey;
}
17 changes: 15 additions & 2 deletions app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import 'package:friend_private/providers/message_provider.dart';
import 'package:friend_private/providers/onboarding_provider.dart';
import 'package:friend_private/providers/plugin_provider.dart';
import 'package:friend_private/providers/speech_profile_provider.dart';
import 'package:friend_private/providers/websocket_provider.dart';
import 'package:friend_private/services/notification_service.dart';
import 'package:friend_private/services/services.dart';
import 'package:friend_private/utils/analytics/gleap.dart';
Expand All @@ -39,6 +38,7 @@ import 'package:friend_private/utils/features/calendar.dart';
import 'package:friend_private/utils/logger.dart';
import 'package:gleap_sdk/gleap_sdk.dart';
import 'package:instabug_flutter/instabug_flutter.dart';
import 'package:intercom_flutter/intercom_flutter.dart';
import 'package:opus_dart/opus_dart.dart';
import 'package:opus_flutter/opus_flutter.dart' as opus_flutter;
import 'package:provider/provider.dart';
Expand All @@ -58,6 +58,13 @@ Future<bool> _init() async {
await Firebase.initializeApp(options: dev.DefaultFirebaseOptions.currentPlatform, name: 'dev');
}

if (Env.intercomAppId != null) {
await Intercom.instance.initialize(
Env.intercomAppId!,
iosApiKey: Env.intercomIOSApiKey,
androidApiKey: Env.intercomAndroidApiKey,
);
}
Comment on lines +61 to +67

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

This code initializes Intercom with the provided API keys. However, it's important to handle potential exceptions that might occur during initialization. For instance, if the API keys are incorrect or if there's a network issue, this could throw an error and crash the app. Consider wrapping this block in a try-catch statement to handle any exceptions gracefully.

+  try {
      if (Env.intercomAppId != null) {
        await Intercom.instance.initialize(
          Env.intercomAppId!,
          iosApiKey: Env.intercomIOSApiKey,
          androidApiKey: Env.intercomAndroidApiKey,
        );
      }
+  } catch (e) {
+    // Log the exception or handle it appropriately
+  }

await NotificationService.instance.initialize();
await SharedPreferencesUtil.init();
await MixpanelManager.init();
Expand Down Expand Up @@ -270,14 +277,20 @@ class DeciderWidget extends StatefulWidget {
class _DeciderWidgetState extends State<DeciderWidget> {
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (context.read<ConnectivityProvider>().isConnected) {
NotificationService.instance.saveNotificationToken();
}

if (context.read<AuthenticationProvider>().user != null) {
context.read<HomeProvider>().setupHasSpeakerProfile();
await Intercom.instance.loginIdentifiedUser(
userId: FirebaseAuth.instance.currentUser!.uid,
);
context.read<MessageProvider>().setMessagesFromCache();
context.read<MessageProvider>().refreshMessages();
} else {
await Intercom.instance.loginUnidentifiedUser();
Comment on lines +280 to +293

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

The Intercom.instance.loginIdentifiedUser and Intercom.instance.loginUnidentifiedUser methods are used here without any error handling. These methods can throw exceptions if there's a problem with the user ID or if there's a network issue. It's recommended to wrap these calls in a try-catch block to prevent the app from crashing due to unhandled exceptions.

     WidgetsBinding.instance.addPostFrameCallback((_) async {
       if (context.read<ConnectivityProvider>().isConnected) {
         NotificationService.instance.saveNotificationToken();
       }

       if (context.read<AuthenticationProvider>().user != null) {
         context.read<HomeProvider>().setupHasSpeakerProfile();
+        try {
           await Intercom.instance.loginIdentifiedUser(
             userId: FirebaseAuth.instance.currentUser!.uid,
           );
+        } catch (e) {
+          // Log the exception or handle it appropriately
+        }
         context.read<MessageProvider>().setMessagesFromCache();
         context.read<MessageProvider>().refreshMessages();
       } else {
+        try {
           await Intercom.instance.loginUnidentifiedUser();
+        } catch (e) {
+          // Log the exception or handle it appropriately
+        }
       }
     });

}
});
super.initState();
Expand Down
6 changes: 2 additions & 4 deletions app/lib/pages/capture/connect.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:friend_private/pages/home/device_settings.dart';
import 'package:friend_private/pages/settings/device_settings.dart';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

The import path for DeviceSettings has been updated. Ensure that the new path 'package:friend_private/pages/settings/device_settings.dart' is correct and the file exists at this location.

- import 'package:friend_private/pages/home/device_settings.dart';
+ import 'package:friend_private/pages/settings/device_settings.dart';

import 'package:friend_private/pages/home/page.dart';
import 'package:friend_private/pages/onboarding/find_device/page.dart';
import 'package:friend_private/utils/other/temp.dart';
Expand All @@ -24,9 +24,7 @@ class _ConnectDevicePageState extends State<ConnectDevicePage> {
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const DeviceSettings(
isDeviceConnected: false,
),
builder: (context) => const DeviceSettings(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description Entelligence.AI

The instantiation of DeviceSettings no longer includes the isDeviceConnected parameter. If this parameter was used to control any logic within DeviceSettings, ensure that its removal doesn't cause any unintended behavior.

- builder: (context) => const DeviceSettings(isDeviceConnected: false),
+ builder: (context) => const DeviceSettings(),

),
);
},
Expand Down
Loading
Loading