Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import io.homeassistant.companion.android.BaseActivity
import io.homeassistant.companion.android.BuildConfig
import io.homeassistant.companion.android.R
import io.homeassistant.companion.android.common.data.servers.ServerManager
import io.homeassistant.companion.android.common.util.FailFast
import io.homeassistant.companion.android.launch.LaunchActivity
import io.homeassistant.companion.android.launcher.LauncherActivity
import io.homeassistant.companion.android.settings.server.ServerChooserFragment
import io.homeassistant.companion.android.util.compose.HomeAssistantAppTheme
import io.homeassistant.companion.android.webview.WebViewActivity
import javax.inject.Inject
import kotlinx.coroutines.launch

private val USE_NEW_LAUNCHER by lazy { BuildConfig.DEBUG }

@AndroidEntryPoint
class LinkActivity : BaseActivity() {

Expand Down Expand Up @@ -67,7 +71,16 @@ class LinkActivity : BaseActivity() {
when (val destination = linkHandler.handleLink(dataUri)) {
LinkDestination.NoDestination -> finish()
is LinkDestination.Onboarding -> {
startActivity(LaunchActivity.newInstance(this@LinkActivity, destination.serverUrl))
if (USE_NEW_LAUNCHER) {
startActivity(
LauncherActivity.newInstance(
this@LinkActivity,
LauncherActivity.DeepLink.Invite(destination.serverUrl),
),
)
} else {
startActivity(LaunchActivity.newInstance(this@LinkActivity, destination.serverUrl))
}
finish()
}

Expand All @@ -83,21 +96,42 @@ class LinkActivity : BaseActivity() {
if (serverManager.defaultServers.size > 1) {
openServerChooser(path)
} else {
startActivity(WebViewActivity.newInstance(context = this, path = path))
if (USE_NEW_LAUNCHER) {
startActivity(
LauncherActivity.newInstance(
this,
LauncherActivity.DeepLink.NavigateTo(path, ServerManager.SERVER_ID_ACTIVE),
),
)
} else {
startActivity(WebViewActivity.newInstance(context = this, path = path))
}
finish()
}
}

private fun openServerChooser(path: String) {
supportFragmentManager.setFragmentResultListener(ServerChooserFragment.RESULT_KEY, this) { _, bundle ->
if (bundle.containsKey(ServerChooserFragment.RESULT_SERVER)) {
startActivity(
WebViewActivity.newInstance(
context = this,
path = path,
serverId = bundle.getInt(ServerChooserFragment.RESULT_SERVER),
),
)
if (USE_NEW_LAUNCHER) {
startActivity(
LauncherActivity.newInstance(
this,
LauncherActivity.DeepLink.NavigateTo(
path,
bundle.getInt(ServerChooserFragment.RESULT_SERVER),
),
),
)
} else {
startActivity(
WebViewActivity.newInstance(
context = this,
path = path,
serverId = bundle.getInt(ServerChooserFragment.RESULT_SERVER),
),
)
}
finish()
}
supportFragmentManager.clearFragmentResultListener(ServerChooserFragment.RESULT_KEY)
Expand All @@ -118,7 +152,9 @@ fun LinkActivityScreen() {
Image(
imageVector = ImageVector.vectorResource(R.drawable.app_icon_launch),
contentDescription = null,
modifier = Modifier.size(112.dp).align(Alignment.Center),
modifier = Modifier
.size(112.dp)
.align(Alignment.Center),
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion onboarding/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.homeassistant.android.common)
alias(libs.plugins.homeassistant.android.compose)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.parcelize)
}

android {
Expand Down
12 changes: 7 additions & 5 deletions onboarding/gradle.lockfile
Original file line number Diff line number Diff line change
Expand Up @@ -430,21 +430,23 @@ org.jetbrains.kotlin:abi-tools:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-build-tools-api:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-build-tools-impl:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.0=ktlint,ktlintBaselineReporter,ktlintRuleset
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-compiler-runner:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.2.0=kotlinCompilerPluginClasspathDebugScreenshotTest,kotlinCompilerPluginClasspathReleaseScreenshotTest
org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.2.20=kotlin-extension,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest
org.jetbrains.kotlin:kotlin-daemon-client:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.0=ktlint,ktlintBaselineReporter,ktlintRuleset
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.2.20=kotlinKlibCommonizerClasspath
org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.21=_agp_internal_javaPreCompileDebugAndroidTest_kspClasspath,_agp_internal_javaPreCompileDebugUnitTest_kspClasspath,_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileReleaseUnitTest_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorReleaseUnitTest,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath
org.jetbrains.kotlin:kotlin-metadata-jvm:2.2.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-reflect:1.6.10=_agp_internal_javaPreCompileDebugAndroidTest_kspClasspath,_agp_internal_javaPreCompileDebugUnitTest_kspClasspath,_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileReleaseUnitTest_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,hiltAnnotationProcessorReleaseUnitTest,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-parcelize-compiler:2.2.20=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest
org.jetbrains.kotlin:kotlin-parcelize-runtime:2.2.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-reflect:1.6.10=_agp_internal_javaPreCompileDebugAndroidTest_kspClasspath,_agp_internal_javaPreCompileDebugUnitTest_kspClasspath,_agp_internal_javaPreCompileDebug_kspClasspath,_agp_internal_javaPreCompileReleaseUnitTest_kspClasspath,_agp_internal_javaPreCompileRelease_kspClasspath,hiltAnnotationProcessorDebug,hiltAnnotationProcessorDebugAndroidTest,hiltAnnotationProcessorDebugUnitTest,hiltAnnotationProcessorRelease,hiltAnnotationProcessorReleaseUnitTest,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,kspDebugAndroidTestKotlinProcessorClasspath,kspDebugKotlinProcessorClasspath,kspDebugScreenshotTestKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,kspReleaseScreenshotTestKotlinProcessorClasspath,kspReleaseUnitTestKotlinProcessorClasspath,ktlint,ktlintBaselineReporter,ktlintRuleset,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-reflect:1.8.21=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-driver-instrumentation,_internal-unified-test-platform-android-test-plugin,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-result-listener-gradle,_internal-unified-test-platform-core,_internal-unified-test-platform-launcher
org.jetbrains.kotlin:kotlin-reflect:2.2.20=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlin:kotlin-script-runtime:2.1.0=ktlint,ktlintBaselineReporter,ktlintRuleset
org.jetbrains.kotlin:kotlin-script-runtime:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-script-runtime:2.2.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlin:kotlin-scripting-common:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.2.20=kotlinBuildToolsApiClasspath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.2.20=kotlinBuildToolsApiClasspath
Expand Down Expand Up @@ -486,7 +488,7 @@ org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=androidTestImplementationDepe
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=ktlint,ktlintBaselineReporter,ktlintRuleset
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-driver-instrumentation,_internal-unified-test-platform-android-test-plugin,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-result-listener-gradle,_internal-unified-test-platform-core,_internal-unified-test-platform-launcher
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=androidTestImplementationDependenciesMetadata
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugScreenshotTestCompileClasspath,debugScreenshotTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseScreenshotTestCompileClasspath,releaseScreenshotTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3=_internal-unified-test-platform-android-device-provider-ddmlib,_internal-unified-test-platform-android-device-provider-gradle,_internal-unified-test-platform-android-test-plugin-host-additional-test-output,_internal-unified-test-platform-android-test-plugin-host-apk-installer,_internal-unified-test-platform-android-test-plugin-host-coverage,_internal-unified-test-platform-android-test-plugin-host-device-info,_internal-unified-test-platform-android-test-plugin-host-emulator-control,_internal-unified-test-platform-android-test-plugin-host-logcat,_internal-unified-test-platform-android-test-plugin-result-listener-gradle,_internal-unified-test-platform-core,_internal-unified-test-platform-launcher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.homeassistant.companion.android.frontend.navigation.navigateToFrontend
import io.homeassistant.companion.android.loading.LoadingScreen
import io.homeassistant.companion.android.loading.navigation.LoadingRoute
import io.homeassistant.companion.android.loading.navigation.loadingScreen
import io.homeassistant.companion.android.onboarding.OnboardingRoute
import io.homeassistant.companion.android.onboarding.onboarding

/**
Expand Down Expand Up @@ -49,6 +50,7 @@ internal fun HANavHost(
// TODO remove this finish when the frontend is not an activity anymore
activity?.finish()
},
serverToOnboard = (startDestination as? OnboardingRoute)?.serverToOnboard,
)
frontendScreen(navController)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,62 @@
package io.homeassistant.companion.android.frontend.navigation

import android.content.ComponentName
import androidx.activity.compose.LocalActivity
import androidx.navigation.ActivityNavigator
import androidx.navigation.ActivityNavigatorDestinationBuilder
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import androidx.navigation.get
import androidx.navigation.toRoute
import io.homeassistant.companion.android.HAStartDestinationRoute
import io.homeassistant.companion.android.common.data.servers.ServerManager.Companion.SERVER_ID_ACTIVE
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
internal data class FrontendRoute(
internal data class FrontendActivityRoute(
val path: String? = null,
// Override the serial name to match the name in WebViewActivity
@SerialName("server") val serverId: Int = SERVER_ID_ACTIVE,
) : HAStartDestinationRoute
)

@Serializable
internal class FrontendRoute(val path: String? = null, val serverId: Int = SERVER_ID_ACTIVE) : HAStartDestinationRoute

internal fun NavController.navigateToFrontend(
path: String? = null,
serverId: Int = SERVER_ID_ACTIVE,
navOptions: NavOptions? = null,
) {
navigate(FrontendRoute(path, serverId), navOptions)
navigate(FrontendActivityRoute(path, serverId), navOptions)
}

/**
* Destination to the WebviewActivity with the [FrontendRoute.path] and [FrontendRoute.serverId] parameters.
* Registers the frontend/webview destination for the Home Assistant app.
*
* The actual navigation to the frontend is done by navigating to [FrontendActivityRoute] with the
* `path` and `serverId` parameters. This will launch the `WebViewActivity` (which is in `:app`).
*
* To ensure that the activity that starts the `WebViewActivity` is finished, users should navigate
* to [FrontendRoute]. This route will then navigate to [FrontendActivityRoute] and finish the
* current activity. This behavior is necessary until `WebViewActivity` is replaced with a
* composable NavGraph entry, allowing for more direct navigation.
*/
internal fun NavGraphBuilder.frontendScreen(navController: NavHostController) {
internal fun NavGraphBuilder.frontendScreen(navController: NavController) {
composable<FrontendRoute> {
val dummy = it.toRoute<FrontendRoute>()
navController.navigateToFrontend(dummy.path, dummy.serverId)
val activity = LocalActivity.current
activity?.finish()
}

// TODO replace with strong types when WebViewActivity is available to onboarding module
// Inspired from activity<T> { } to be able to give a ComponentName instead of a class since :onboarding doesn't know :app
val destination = ActivityNavigatorDestinationBuilder(
provider[ActivityNavigator::class],
FrontendRoute::class,
FrontendActivityRoute::class,
emptyMap(),
).build().setComponentName(
ComponentName(
Expand Down
Loading
Loading