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") }
}
}