diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b102a6c..7940473 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -87,4 +87,6 @@ dependencies { implementation(project(":feature:detail")) implementation(project(":feature:recipe")) implementation(project(":feature:collection")) + + implementation("io.airbridge:sdk-android:4.1.0") } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 993a487..ac28e3a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,7 +38,17 @@ - + + + + + + + + + @@ -46,9 +56,17 @@ + + + + + + + + diff --git a/app/src/main/kotlin/xyz/duckee/android/DuckeeApplication.kt b/app/src/main/kotlin/xyz/duckee/android/DuckeeApplication.kt index 060026b..6b0e754 100644 --- a/app/src/main/kotlin/xyz/duckee/android/DuckeeApplication.kt +++ b/app/src/main/kotlin/xyz/duckee/android/DuckeeApplication.kt @@ -19,10 +19,24 @@ import android.app.Application import coil.ImageLoader import coil.ImageLoaderFactory import dagger.hilt.android.HiltAndroidApp +import co.ab180.airbridge.Airbridge +import co.ab180.airbridge.AirbridgeOption +import co.ab180.airbridge.AirbridgeOptionBuilder @HiltAndroidApp class DuckeeApplication : Application(), ImageLoaderFactory { + override fun onCreate() { + super.onCreate() + initializeAirbridge() + } + + private fun initializeAirbridge() { + val option = AirbridgeOptionBuilder("duckee", "fc57a50c7b39453fb2582e4991e326a7") + .build() + Airbridge.initializeSDK(this, option) + } + override fun newImageLoader(): ImageLoader = ImageLoader.Builder(this) .crossfade(true) diff --git a/app/src/main/kotlin/xyz/duckee/android/MainActivity.kt b/app/src/main/kotlin/xyz/duckee/android/MainActivity.kt index 1af694d..1e6211b 100644 --- a/app/src/main/kotlin/xyz/duckee/android/MainActivity.kt +++ b/app/src/main/kotlin/xyz/duckee/android/MainActivity.kt @@ -17,7 +17,6 @@ package xyz.duckee.android import android.net.Uri import android.os.Bundle -import android.util.Log import android.view.WindowManager import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -25,9 +24,6 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.core.view.WindowCompat import androidx.navigation.NavHostController -import com.google.firebase.dynamiclinks.PendingDynamicLinkData -import com.google.firebase.dynamiclinks.ktx.dynamicLinks -import com.google.firebase.ktx.Firebase import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheetResult import dagger.hilt.android.AndroidEntryPoint @@ -48,6 +44,7 @@ import xyz.duckee.android.core.navigation.navigateToDetailScreen import xyz.duckee.android.core.navigation.navigateToExploreTab import xyz.duckee.android.core.navigation.navigateToRecipeScreen import xyz.duckee.android.core.navigation.navigateToSignInScreen +import co.ab180.airbridge.Airbridge @AndroidEntryPoint class MainActivity : ComponentActivity() { @@ -118,51 +115,55 @@ class MainActivity : ComponentActivity() { override fun onResume() { super.onResume() + handleAirbridgeDeeplink() + } - Firebase.dynamicLinks - .getDynamicLink(intent) - .addOnSuccessListener(this) { pendingDynamicLinkData: PendingDynamicLinkData? -> - pendingDynamicLinkData?.link?.let { deepLink -> - val path = deepLink.path ?: return@let - when { - path.startsWith("/recipe/") -> { - val recipePattern = "/recipe/(\\d+)".toRegex() - val matchResult = recipePattern.find(path) - matchResult?.let { result -> - val recipeId = result.groupValues[1] - navigationController?.navigateToRecipeScreen(recipeId) - } - } - - path.startsWith("/detail/") -> { - val detailPattern = "/detail/([\\w-]+)".toRegex() - val matchResult = detailPattern.find(path) - matchResult?.let { result -> - val detailId = result.groupValues[1] - navigationController?.navigateToDetailScreen(detailId) - } - } - - path == "/explore" -> { - navigationController?.navigateToExploreTab() - } - - path == "/collection" -> { - navigationController?.navigateToCollectionTab() - } - - path == "/signin" -> { - navigationController?.navigateToSignInScreen() - } - - else -> { - Timber.tag("[DuckeeMainActivity]").w("Unhandled deep link path: $path") - } - } + private fun handleAirbridgeDeeplink() { + Airbridge.handleDeeplink(intent) { deeplink -> + handleDeeplink(deeplink) + } + + Airbridge.handleDeferredDeeplink { deeplink -> + deeplink?.let { handleDeeplink(it) } + } + } + + private fun handleDeeplink(deeplink: Uri) { + val path = deeplink.path ?: return + when { + path.startsWith("/recipe/") -> { + val recipePattern = "/recipe/(\\d+)".toRegex() + val matchResult = recipePattern.find(path) + matchResult?.let { result -> + val recipeId = result.groupValues[1] + navigationController?.navigateToRecipeScreen(recipeId) + } + } + + path.startsWith("/detail/") -> { + val detailPattern = "/detail/([\\w-]+)".toRegex() + val matchResult = detailPattern.find(path) + matchResult?.let { result -> + val detailId = result.groupValues[1] + navigationController?.navigateToDetailScreen(detailId) } } - .addOnFailureListener(this) { e -> - Timber.tag("[DuckeeMainActivity]").w(e, "getDynamicLink:onFailure") + + path == "/explore" -> { + navigationController?.navigateToExploreTab() } + + path == "/collection" -> { + navigationController?.navigateToCollectionTab() + } + + path == "/signin" -> { + navigationController?.navigateToSignInScreen() + } + + else -> { + Timber.tag("[DuckeeMainActivity]").w("Unhandled deep link path: $path") + } + } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidFirebaseConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFirebaseConventionPlugin.kt index 635dadb..88484be 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFirebaseConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFirebaseConventionPlugin.kt @@ -30,7 +30,8 @@ class AndroidFirebaseConventionPlugin : Plugin { "implementation"(platform(libs.findLibrary("firebase.bom").get())) "implementation"(libs.findLibrary("firebase.auth").get()) "implementation"(libs.findLibrary("firebase.authUI").get()) - "implementation"(libs.findLibrary("firebase.dynamicLink").get()) + // Remove the following line + // "implementation"(libs.findLibrary("firebase.dynamicLink").get()) } } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 2f3e6bb..c748253 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,6 +6,7 @@ pluginManagement { google() mavenCentral() gradlePluginPortal() + maven { url = uri("https://sdk-download.airbridge.io/maven") } } } dependencyResolutionManagement { @@ -15,6 +16,7 @@ dependencyResolutionManagement { google() mavenCentral() maven { url = uri("https://jitpack.io") } + maven { url = uri("https://sdk-download.airbridge.io/maven") } } }