diff --git a/Intents.md b/Intents.md
new file mode 100644
index 00000000..a083ae7a
--- /dev/null
+++ b/Intents.md
@@ -0,0 +1,151 @@
+# Intents
+
+> [!WARNING]
+> This feature is only available in the develop builds until the next release!
+
+> [!IMPORTANT]
+> This feature is experimental and the exact behaviors and/or parameters may change at any time
+
+Wholphin accepts [intents](https://developer.android.com/guide/components/intents-filters) to load or play specified media.
+
+Parameters can be specified as "extras" (eg `--es query value`) or as query parameters to the data URI (eg `-d wholphin://search?query=value`).
+
+UUID parameters can be specified with or without hyphens.
+
+If using data URI query parameters on the command line, you need to escape ampersands: `itemId=...\&userId=...`
+
+## Server/user switching
+
+You can choose a server and user to switch to with the `serverId` and `userId` UUID parameters. If the profile is not protected, the app will switch to it.
+
+If not specified, the app will use the current user if auto sign in is enabled.
+
+## Search
+
+Action: `android.intent.action.SEARCH`
+
+Shorthand action: `search`
+
+Parameters:
+- `query` - Optional, prepopulate the search field
+
+
+### Examples
+
+Full format
+```bash
+adb shell am start \
+ -a android.intent.action.SEARCH \
+ -n 'com.github.damontecres.wholphin/.MainActivity' \
+ --es query "Avengers"
+```
+
+URI based
+```bash
+adb shell am start -d 'wholphin://search?query=Avengers'
+```
+
+Multi-word query:
+```bash
+# Whole shell command is wrapped in double quotes
+adb shell "am start \
+ -a android.intent.action.SEARCH \
+ -n 'com.github.damontecres.wholphin/.MainActivity' \
+ --es query 'Avengers Endgame'"
+
+adb shell am start -d 'wholphin://search?query=Avengers+Endgame'
+adb shell am start -d 'wholphin://search?query=Avengers%20Endgame'
+```
+
+## View
+
+This opens the app to the specified item such as an episode or movie
+
+Action: `android.intent.action.VIEW`
+
+Shorthand action: `view`
+
+Parameters:
+- `itemId` - Required, the UUID of the media item
+
+
+### Examples
+
+Full format
+```bash
+adb shell am start \
+ -a android.intent.action.VIEW \
+ -n 'com.github.damontecres.wholphin/.MainActivity' \
+ --es itemId "5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d"
+```
+
+URI based
+```bash
+adb shell am start -d 'wholphin://view?itemId=5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d'
+```
+
+## Playback
+
+Action: `com.github.damontecres.wholphin.PLAYBACK`
+
+Shorthand action: `play`
+
+Parameters:
+- `itemId` - Required, the UUID of the media item
+- `position` - Optional, the start position for playback in milliseconds
+
+### Examples
+
+Full format
+```bash
+adb shell am start \
+ -a com.github.damontecres.wholphin.PLAYBACK \
+ -n 'com.github.damontecres.wholphin/.MainActivity' \
+ --es itemId "5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d"
+```
+
+URI based
+```bash
+adb shell am start -d 'wholphin://play?itemId=5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d'
+```
+
+Start at 4m30s:
+```bash
+adb shell am start \
+ -a com.github.damontecres.wholphin.PLAYBACK \
+ -n 'com.github.damontecres.wholphin/.MainActivity' \
+ --es itemId "5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d" \
+ --el position 270000
+
+adb shell am start -d 'wholphin://play?itemId=5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d\&position=270000'
+```
+
+## More examples
+
+### Switch user
+
+Full format
+```bash
+adb shell am start \
+ -a android.intent.action.VIEW \
+ -n 'com.github.damontecres.wholphin/.MainActivity' \
+ --es itemId "5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d" \
+ --es serverId "341880f9-ca88-4038-8718-f6b2407950b1" \
+ --es userId "5c8575e0-468d-44fb-8c70-00aa79160587"
+```
+
+URI based
+```bash
+adb shell am start -d 'wholphin://view?itemId=66c80aaac9c17d3761782d2205520229\&serverId=341880f9-ca88-4038-8718-f6b2407950b1\&userId=5c8575e0-468d-44fb-8c70-00aa79160587'
+```
+
+### Debug build
+
+Debug builds have a different package, so you must specify the component by its full name:
+
+```bash
+adb shell am start \
+ -a android.intent.action.VIEW \
+ -n 'com.github.damontecres.wholphin.debug/com.github.damontecres.wholphin.MainActivity' \
+ --es itemId "5cf8f8e7-2a5f-4aa9-8c12-ddf63d42ee6d"
+```
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 64e7493c..42404590 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -58,6 +58,13 @@
+
+
+
+
+
+
+
= 0 && seasonNumber >= 0) {
- Destination.SeriesOverview(
- itemId = seriesId,
- type = BaseItemKind.SERIES,
- seasonEpisode =
- SeasonEpisodeIds(
- seasonId = seasonId,
- seasonNumber = seasonNumber,
- episodeId = itemId,
- episodeNumber = episodeNumber,
- ),
- )
- } else {
- Destination.MediaItem(itemId, type)
- }
- } else {
- null
- }
- }
-
fun changeDisplayMode(modeId: Int) {
lifecycleScope.launch(WholphinDispatchers.Main + ExceptionHandler(autoToast = true)) {
val attrs = window.attributes
@@ -431,13 +400,6 @@ class MainActivity : AppCompatActivity() {
}
companion object {
- const val INTENT_ITEM_ID = "itemId"
- const val INTENT_ITEM_TYPE = "itemType"
- const val INTENT_SERIES_ID = "seriesId"
- const val INTENT_EPISODE_NUMBER = "epNum"
- const val INTENT_SEASON_NUMBER = "seaNum"
- const val INTENT_SEASON_ID = "seaId"
-
private const val KEY_BACK_STACK = "backStack"
private const val KEY_EXTERNAL_PLAYER = "extPlayer"
@@ -453,16 +415,55 @@ class MainActivityViewModel
@param:ApplicationContext private val context: Context,
private val preferences: DataStore,
val serverRepository: ServerRepository,
- private val navigationManager: SetupNavigationManager,
+ private val setupNavigationManager: SetupNavigationManager,
+ private val navigationManager: NavigationManager,
private val deviceProfileService: DeviceProfileService,
private val backdropService: BackdropService,
private val appUpgradeHandler: AppUpgradeHandler,
+ private val intentService: IntentService,
) : ViewModel() {
private val mutex = Mutex()
- fun appStart() {
+ fun appStart(intent: Intent?) {
viewModelScope.launchDefault {
mutex.withLock {
+ try {
+ val result = intent?.let { intentService.parseIntent(intent) }
+ when (result) {
+ is IntentResult.Error -> {
+ setupNavigationManager.navigateTo(SetupDestination.ServerList)
+ Timber.e("Error parsing intent: %s", result.message)
+ showToast(context, "Invalid intent: ${result.message}")
+ return@withLock
+ }
+
+ is IntentResult.Target -> {
+ val current = serverRepository.current.value
+ if (current != null) {
+ Timber.i("Received valid intent, switching to AppContent")
+ navigationManager.replace(result.destination)
+ setupNavigationManager.navigateTo(
+ SetupDestination.AppContent(current),
+ )
+ } else {
+ // This should never happen, but just reset app state if it does
+ setupNavigationManager.navigateTo(SetupDestination.ServerList)
+ Timber.e("Error parsing intent, no user is active")
+ showToast(context, "An error occurred parsing the intent")
+ }
+ return@withLock
+ }
+
+ IntentResult.NoOp,
+ null,
+ -> {
+ // No-op, proceed below
+ }
+ }
+ } catch (ex: Exception) {
+ Timber.e(ex, "Error parsing intent")
+ }
+
try {
val needUpgrade = appUpgradeHandler.needUpgrade()
if (needUpgrade) {
@@ -479,9 +480,9 @@ class MainActivityViewModel
val prefs =
preferences.data.firstOrNull() ?: AppPreferences.getDefaultInstance()
val profileProtected =
- serverRepository.current.value?.user?.let {
- it.hasPin || it.requireLogin
- } == true
+ serverRepository.current.value
+ ?.user
+ ?.isProtected == true
if (prefs.signInAutomatically && !profileProtected) {
val current =
serverRepository.restoreSession(
@@ -490,38 +491,46 @@ class MainActivityViewModel
)
if (current != null) {
if (current.user.hasPin || current.user.requireLogin) {
- navigationManager.navigateTo(SetupDestination.UserList(current.server))
+ setupNavigationManager.navigateTo(
+ SetupDestination.UserList(
+ current.server,
+ ),
+ )
} else {
// Restored
- navigationManager.navigateTo(SetupDestination.AppContent(current))
+ setupNavigationManager.navigateTo(
+ SetupDestination.AppContent(
+ current,
+ ),
+ )
}
} else {
// Did not restore
- navigationManager.navigateTo(SetupDestination.ServerList)
+ setupNavigationManager.navigateTo(SetupDestination.ServerList)
}
} else {
- navigationManager.navigateTo(SetupDestination.Loading)
+ setupNavigationManager.navigateTo(SetupDestination.Loading)
backdropService.clearBackdrop()
val currentServerId = prefs.currentServerId?.toUUIDOrNull()
if (currentServerId != null) {
val currentServer =
serverRepository.serverDao.getServer(currentServerId)?.server
if (currentServer != null) {
- navigationManager.navigateTo(
+ setupNavigationManager.navigateTo(
SetupDestination.UserList(
currentServer,
),
)
} else {
- navigationManager.navigateTo(SetupDestination.ServerList)
+ setupNavigationManager.navigateTo(SetupDestination.ServerList)
}
} else {
- navigationManager.navigateTo(SetupDestination.ServerList)
+ setupNavigationManager.navigateTo(SetupDestination.ServerList)
}
}
} catch (ex: Exception) {
Timber.e(ex, "Error during appStart")
- navigationManager.navigateTo(SetupDestination.ServerList)
+ setupNavigationManager.navigateTo(SetupDestination.ServerList)
}
}
}
diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/model/JellyfinServer.kt b/app/src/main/java/com/github/damontecres/wholphin/data/model/JellyfinServer.kt
index 44c19b4a..4c54311c 100644
--- a/app/src/main/java/com/github/damontecres/wholphin/data/model/JellyfinServer.kt
+++ b/app/src/main/java/com/github/damontecres/wholphin/data/model/JellyfinServer.kt
@@ -71,6 +71,8 @@ data class JellyfinUser(
) {
val hasPin: Boolean get() = pin.isNotNullOrBlank()
+ val isProtected: Boolean get() = hasPin || requireLogin
+
override fun toString(): String =
"JellyfinUser(rowId=$rowId, id=$id, name=$name, serverId=$serverId, lastUsed=$lastUsed, " +
"accessToken?=${accessToken.isNotNullOrBlank()}, pin?=${pin.isNotNullOrBlank()}), " +
diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/IntentService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/IntentService.kt
new file mode 100644
index 00000000..0a043506
--- /dev/null
+++ b/app/src/main/java/com/github/damontecres/wholphin/services/IntentService.kt
@@ -0,0 +1,164 @@
+package com.github.damontecres.wholphin.services
+
+import android.app.SearchManager
+import android.content.Intent
+import com.github.damontecres.wholphin.data.ServerRepository
+import com.github.damontecres.wholphin.data.model.BaseItem
+import com.github.damontecres.wholphin.ui.detail.series.SeasonEpisodeIds
+import com.github.damontecres.wholphin.ui.nav.Destination
+import kotlinx.coroutines.flow.first
+import org.jellyfin.sdk.api.client.ApiClient
+import org.jellyfin.sdk.api.client.extensions.userLibraryApi
+import org.jellyfin.sdk.model.api.BaseItemKind
+import org.jellyfin.sdk.model.serializer.toUUIDOrNull
+import timber.log.Timber
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class IntentService
+ @Inject
+ constructor(
+ private val api: ApiClient,
+ private val serverRepository: ServerRepository,
+ private val userPreferencesService: UserPreferencesService,
+ ) {
+ suspend fun parseIntent(intent: Intent): IntentResult {
+ Timber.v("Parsing intent %s", intent)
+ Timber.v("Intent extras: %s", intent.extras)
+ Timber.v("Intent data: %s", intent.data)
+ if (intent.getStringParam("type") != null) {
+ return getDestinationFromChannel(intent)?.let { IntentResult.Target(it) }
+ ?: IntentResult.Error("Invalid parameters")
+ }
+ val action = intent.action ?: intent.data?.host
+ if (action == Intent.ACTION_MAIN || action.isNullOrBlank()) {
+ return IntentResult.NoOp
+ }
+
+ val userId = intent.getStringParam("userId")?.toUUIDOrNull()
+ val serverId = intent.getStringParam("serverId")?.toUUIDOrNull()
+ if (userId != null && serverId != null) {
+ Timber.v("Intent switches user")
+ val user =
+ serverRepository.serverDao.getUser(serverId, userId)
+ ?: return IntentResult.Error("User not found")
+ if (!user.isProtected) {
+ serverRepository.restoreSession(serverId, userId)
+ } else {
+ return IntentResult.Error("Cannot switch to specified user")
+ }
+ } else if (serverRepository.currentUser == null) {
+ Timber.v("No current user, so restoring last")
+ val appPrefs = userPreferencesService.flow.first().appPreferences
+ if (appPrefs.signInAutomatically) {
+ val userId = appPrefs.currentUserId.toUUIDOrNull()
+ val serverId = appPrefs.currentServerId.toUUIDOrNull()
+ if (userId != null && serverId != null) {
+ serverRepository.restoreSession(serverId, userId)
+ ?: return IntentResult.Error("Error restoring user")
+ } else {
+ return IntentResult.Error("Could not auto sign-in, specify a server & user")
+ }
+ } else {
+ return IntentResult.Error("Auto sign-in not enabled, specify a server & user")
+ }
+ }
+
+ if (action == Intent.ACTION_SEARCH || action == "search") {
+ val query = intent.getStringParam(SearchManager.QUERY)
+ return IntentResult.Target(Destination.Search(query ?: ""))
+ }
+ val itemId =
+ intent.getStringParam("itemId")?.toUUIDOrNull()
+ ?: return IntentResult.Error("No item id provided")
+
+ val item =
+ try {
+ api.userLibraryApi
+ .getItem(itemId)
+ .content
+ .let { BaseItem(it) }
+ } catch (ex: Exception) {
+ Timber.w(ex, "Error fetching item %s", itemId)
+ return IntentResult.Error("Could not fetch item $itemId")
+ }
+
+ val destination =
+ when (action) {
+ Intent.ACTION_VIEW, "view" -> {
+ item.destination()
+ }
+
+ "com.github.damontecres.wholphin.PLAYBACK", "play" -> {
+ val position = intent.getLongParam("position")?.coerceAtLeast(0)
+ Destination.Playback(
+ itemId = itemId,
+ positionMs = position ?: 0L,
+ )
+ }
+
+ else -> {
+ return IntentResult.Error("Invalid action: ${intent.action}")
+ }
+ }
+ return IntentResult.Target(destination)
+ }
+
+ private fun Intent.getStringParam(key: String) = getStringExtra(key) ?: data?.getQueryParameter(key)
+
+ private fun Intent.getLongParam(key: String) =
+ getLongExtra(key, -1).takeIf { it >= 0 } ?: data?.getQueryParameter(key)?.toLongOrNull()
+
+ private fun getDestinationFromChannel(intent: Intent): Destination? =
+ intent.let {
+ val itemId =
+ it.getStringExtra(INTENT_ITEM_ID)?.toUUIDOrNull()
+ val type =
+ it.getStringExtra(INTENT_ITEM_TYPE)?.let(BaseItemKind::fromNameOrNull)
+ if (itemId != null && type != null) {
+ val seriesId = it.getStringExtra(INTENT_SERIES_ID)?.toUUIDOrNull()
+ val seasonId = it.getStringExtra(INTENT_SEASON_ID)?.toUUIDOrNull()
+ val episodeNumber = it.getIntExtra(INTENT_EPISODE_NUMBER, -1)
+ val seasonNumber = it.getIntExtra(INTENT_SEASON_NUMBER, -1)
+ if (seriesId != null && seasonId != null && episodeNumber >= 0 && seasonNumber >= 0) {
+ Destination.SeriesOverview(
+ itemId = seriesId,
+ type = BaseItemKind.SERIES,
+ seasonEpisode =
+ SeasonEpisodeIds(
+ seasonId = seasonId,
+ seasonNumber = seasonNumber,
+ episodeId = itemId,
+ episodeNumber = episodeNumber,
+ ),
+ )
+ } else {
+ Destination.MediaItem(itemId, type)
+ }
+ } else {
+ null
+ }
+ }
+
+ companion object {
+ const val INTENT_ITEM_ID = "itemId"
+ const val INTENT_ITEM_TYPE = "itemType"
+ const val INTENT_SERIES_ID = "seriesId"
+ const val INTENT_EPISODE_NUMBER = "epNum"
+ const val INTENT_SEASON_NUMBER = "seaNum"
+ const val INTENT_SEASON_ID = "seaId"
+ }
+ }
+
+sealed interface IntentResult {
+ data class Error(
+ val message: String,
+ ) : IntentResult
+
+ data object NoOp : IntentResult
+
+ data class Target(
+ val destination: Destination,
+ ) : IntentResult
+}
diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/tvprovider/TvProviderWorker.kt b/app/src/main/java/com/github/damontecres/wholphin/services/tvprovider/TvProviderWorker.kt
index 0df2193b..d3dbf4c7 100644
--- a/app/src/main/java/com/github/damontecres/wholphin/services/tvprovider/TvProviderWorker.kt
+++ b/app/src/main/java/com/github/damontecres/wholphin/services/tvprovider/TvProviderWorker.kt
@@ -24,6 +24,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.preferences.AppPreference
import com.github.damontecres.wholphin.preferences.AppPreferences
import com.github.damontecres.wholphin.services.ImageUrlService
+import com.github.damontecres.wholphin.services.IntentService
import com.github.damontecres.wholphin.services.LatestNextUpService
import com.github.damontecres.wholphin.ui.SlimItemFields
import dagger.assisted.Assisted
@@ -226,27 +227,27 @@ class TvProviderWorker
setIntent(
Intent(context, MainActivity::class.java)
- .putExtra(MainActivity.INTENT_ITEM_ID, item.id.toString())
- .putExtra(MainActivity.INTENT_ITEM_TYPE, item.type.serialName)
+ .putExtra(IntentService.INTENT_ITEM_ID, item.id.toString())
+ .putExtra(IntentService.INTENT_ITEM_TYPE, item.type.serialName)
.apply {
if (item.type == BaseItemKind.EPISODE) {
putExtra(
- MainActivity.INTENT_SERIES_ID,
+ IntentService.INTENT_SERIES_ID,
dto.seriesId?.toString(),
)
putExtra(
- MainActivity.INTENT_SEASON_ID,
+ IntentService.INTENT_SEASON_ID,
dto.seasonId?.toString(),
)
dto.parentIndexNumber?.let {
putExtra(
- MainActivity.INTENT_SEASON_NUMBER,
+ IntentService.INTENT_SEASON_NUMBER,
it,
)
}
dto.indexNumber?.let {
putExtra(
- MainActivity.INTENT_EPISODE_NUMBER,
+ IntentService.INTENT_EPISODE_NUMBER,
it,
)
}
@@ -363,27 +364,27 @@ class TvProviderWorker
setIntent(
Intent(context, MainActivity::class.java)
- .putExtra(MainActivity.INTENT_ITEM_ID, item.id.toString())
- .putExtra(MainActivity.INTENT_ITEM_TYPE, item.type.serialName)
+ .putExtra(IntentService.INTENT_ITEM_ID, item.id.toString())
+ .putExtra(IntentService.INTENT_ITEM_TYPE, item.type.serialName)
.apply {
if (item.type == BaseItemKind.EPISODE) {
putExtra(
- MainActivity.INTENT_SERIES_ID,
+ IntentService.INTENT_SERIES_ID,
dto.seriesId?.toString(),
)
putExtra(
- MainActivity.INTENT_SEASON_ID,
+ IntentService.INTENT_SEASON_ID,
dto.seasonId?.toString(),
)
dto.parentIndexNumber?.let {
putExtra(
- MainActivity.INTENT_SEASON_NUMBER,
+ IntentService.INTENT_SEASON_NUMBER,
it,
)
}
dto.indexNumber?.let {
putExtra(
- MainActivity.INTENT_EPISODE_NUMBER,
+ IntentService.INTENT_EPISODE_NUMBER,
it,
)
}
diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt
index 50c2cc6a..2b54f693 100644
--- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt
+++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt
@@ -496,6 +496,7 @@ private const val COMBINED_ROW = TAB_ROW + 1
@Composable
fun SearchPage(
+ initialQuery: String,
userPreferences: UserPreferences,
modifier: Modifier = Modifier,
viewModel: SearchViewModel = hiltViewModel(),
@@ -513,7 +514,7 @@ fun SearchPage(
val voiceSearchButtonVisible = prefs.showVoiceSearchButton
// val query = rememberTextFieldState()
- var query by rememberSaveable { mutableStateOf("") }
+ var query by rememberSaveable { mutableStateOf(initialQuery) }
val focusRequesters = remember { List(SEERR_ROW + 1) { FocusRequester() } }
val seerrActive by viewModel.seerrActive.collectAsState(initial = false)
diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/Destination.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/Destination.kt
index accfd693..2468cd78 100644
--- a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/Destination.kt
+++ b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/Destination.kt
@@ -54,10 +54,11 @@ sealed class Destination(
) : Destination(true)
@Serializable
- data object UserAppPreferences : Destination(true)
+ data class Search(
+ val query: String = "",
+ ) : Destination()
- @Serializable
- data object Search : Destination()
+ data object UserAppPreferences : Destination(true)
@Serializable
data class SeriesOverview(
diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/DestinationContent.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/DestinationContent.kt
index e0f89304..d7756161 100644
--- a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/DestinationContent.kt
+++ b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/DestinationContent.kt
@@ -351,9 +351,10 @@ fun DestinationContent(
LicenseInfo(modifier)
}
- Destination.Search -> {
+ is Destination.Search -> {
LaunchedEffect(Unit) { onClearBackdrop.invoke() }
SearchPage(
+ initialQuery = destination.query,
userPreferences = preferences,
modifier = modifier,
)
diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt
index 67fb849d..19f027a8 100644
--- a/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt
+++ b/app/src/main/java/com/github/damontecres/wholphin/ui/nav/NavDrawer.kt
@@ -409,7 +409,7 @@ fun NavDrawer(
interactionSource = interactionSource,
onClick = {
viewModel.setIndex(SEARCH_INDEX)
- viewModel.navigationManager.navigateToFromDrawer(Destination.Search)
+ viewModel.navigationManager.navigateToFromDrawer(Destination.Search())
},
modifier =
Modifier