Commit b988457c by Aleksandr

Ability to get content from other apps

parent 3a4599a8
package com.isidroid.c23 package com.isidroid.c23
import android.app.Activity
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle import androidx.activity.SystemBarStyle
...@@ -16,13 +18,18 @@ import androidx.compose.runtime.getValue ...@@ -16,13 +18,18 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.isidroid.c23.ext.isEdgeToEdge import com.isidroid.c23.ext.isEdgeToEdge
import com.isidroid.c23.ui.navigation.AppNavHost import com.isidroid.c23.ui.navigation.AppNavHost
import com.isidroid.c23.ui.navigation.PrintJobs
import com.isidroid.c23.ui.navigation.routeHome
import com.isidroid.c23.ui.theme.AppTheme import com.isidroid.c23.ui.theme.AppTheme
import com.isidroid.core.ext.navigateSingleTopTo
import com.isidroid.core.ext.printCurrentDestination import com.isidroid.core.ext.printCurrentDestination
import com.isidroid.utils.extractUris
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint @AndroidEntryPoint
...@@ -35,6 +42,7 @@ class MainActivity : ComponentActivity() { ...@@ -35,6 +42,7 @@ class MainActivity : ComponentActivity() {
navigationBarStyle = SystemBarStyle.light(Color.Transparent.toArgb(), Color.Transparent.toArgb()), navigationBarStyle = SystemBarStyle.light(Color.Transparent.toArgb(), Color.Transparent.toArgb()),
) )
setContent { setContent {
ComposeApp() ComposeApp()
} }
...@@ -47,6 +55,14 @@ fun ComposeApp() { ...@@ -47,6 +55,14 @@ fun ComposeApp() {
val navController = rememberNavController() val navController = rememberNavController()
val currentBackStack by navController.currentBackStackEntryAsState() val currentBackStack by navController.currentBackStackEntryAsState()
val isEdgeToEdge = currentBackStack?.destination?.route.isEdgeToEdge val isEdgeToEdge = currentBackStack?.destination?.route.isEdgeToEdge
val activity = LocalContext.current as Activity
val intent = activity.intent
LaunchedEffect(intent) {
val uris = intent.extractUris()
if (uris != null)
navController.navigateSingleTopTo(routeHome(uris = uris.joinToString()))
}
LaunchedEffect(Unit) { navController.printCurrentDestination() } LaunchedEffect(Unit) { navController.printCurrentDestination() }
......
...@@ -21,7 +21,7 @@ class HomeUseCase @Inject constructor( ...@@ -21,7 +21,7 @@ class HomeUseCase @Inject constructor(
private val activeSpotRepository: ActiveSpotRepository, private val activeSpotRepository: ActiveSpotRepository,
private val appDataBase: AppDataBase private val appDataBase: AppDataBase
) { ) {
fun createSession() = flow { fun createSession(uris: String?) = flow {
emit(FlowResult.Loading) emit(FlowResult.Loading)
// if (isDebug()) { // if (isDebug()) {
...@@ -52,7 +52,7 @@ class HomeUseCase @Inject constructor( ...@@ -52,7 +52,7 @@ class HomeUseCase @Inject constructor(
lng = -121.9752617, lng = -121.9752617,
) )
uris != null -> HomeContract.Effect.Navigation.ToPreview(uris)
else -> HomeContract.Effect.Navigation.ToSelectContent else -> HomeContract.Effect.Navigation.ToSelectContent
} }
......
...@@ -21,16 +21,31 @@ fun AppNavHost( ...@@ -21,16 +21,31 @@ fun AppNavHost(
navController: NavHostController, navController: NavHostController,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val startDestination = if (isDebug()) Home.route else Home.route val startDestination = if (isDebug())
routeHome(uris = "{${Argument.URI}}")
else
routeHome(uris = "{${Argument.URI}}")
BasicNavHost( BasicNavHost(
navController = navController, navController = navController,
startDestination = startDestination, startDestination = startDestination,
modifier = modifier, modifier = modifier,
) { ) {
composable(route = Home.route) { HomeScreenDestination(navController) } composable(
composable(route = routeSelectContent()) { ContentScreenDestination(navController) } route = routeHome(uris = "{${Argument.URI}}"),
composable(route = routePrintJobs()) { PrintJobsScreenDestination(navController) } arguments = listOf(makeNavArgument(Argument.URI, NavType.StringType)),
content = { HomeScreenDestination(navController) }
)
composable(
route = routeSelectContent(),
content = { ContentScreenDestination(navController) }
)
composable(
route = routePrintJobs(),
content = { PrintJobsScreenDestination(navController) }
)
composable( composable(
route = routeRenderPreview(uris = "{${Argument.URI}}"), route = routeRenderPreview(uris = "{${Argument.URI}}"),
......
...@@ -6,6 +6,10 @@ import com.isidroid.c23.constant.Argument ...@@ -6,6 +6,10 @@ import com.isidroid.c23.constant.Argument
internal fun routeSelectContent() = Content.route.toUri().toString() internal fun routeSelectContent() = Content.route.toUri().toString()
internal fun routePrintJobs() = PrintJobs.route.toUri().toString() internal fun routePrintJobs() = PrintJobs.route.toUri().toString()
internal fun routeHome(uris: String? = null) = Home.route.toUri().buildUpon()
.appendQueryParameter(Argument.URI, uris)
.toString()
internal fun routeRenderPreview(uris: String = Argument.URI) = RenderPreview.route.toUri().buildUpon() internal fun routeRenderPreview(uris: String = Argument.URI) = RenderPreview.route.toUri().buildUpon()
.appendQueryParameter(Argument.URI, uris) .appendQueryParameter(Argument.URI, uris)
.toString() .toString()
......
...@@ -3,12 +3,15 @@ package com.isidroid.c23.ui.navigation.destinations ...@@ -3,12 +3,15 @@ package com.isidroid.c23.ui.navigation.destinations
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.isidroid.c23.ui.navigation.routeHome
import com.isidroid.c23.ui.navigation.routeMap import com.isidroid.c23.ui.navigation.routeMap
import com.isidroid.c23.ui.navigation.routeRenderPreview
import com.isidroid.c23.ui.navigation.routeSelectContent import com.isidroid.c23.ui.navigation.routeSelectContent
import com.isidroid.c23.ui.screen.home.HomeContract import com.isidroid.c23.ui.screen.home.HomeContract
import com.isidroid.c23.ui.screen.home.HomeScreen import com.isidroid.c23.ui.screen.home.HomeScreen
import com.isidroid.c23.ui.screen.home.HomeViewModel import com.isidroid.c23.ui.screen.home.HomeViewModel
import com.isidroid.core.ext.navigateSingleTopTo import com.isidroid.core.ext.navigateSingleTopTo
import timber.log.Timber
@Composable @Composable
fun HomeScreenDestination(navController: NavHostController) { fun HomeScreenDestination(navController: NavHostController) {
...@@ -22,9 +25,15 @@ fun HomeScreenDestination(navController: NavHostController) { ...@@ -22,9 +25,15 @@ fun HomeScreenDestination(navController: NavHostController) {
HomeContract.Effect.Navigation.ToLogin -> TODO("Session is not implemented") HomeContract.Effect.Navigation.ToLogin -> TODO("Session is not implemented")
HomeContract.Effect.Navigation.ToSelectContent -> routeSelectContent() HomeContract.Effect.Navigation.ToSelectContent -> routeSelectContent()
is HomeContract.Effect.Navigation.ToSelectSpot -> routeMap(lat = effect.lat?.toString(), lng = effect.lng?.toString(), spotCode = effect.spotCode) is HomeContract.Effect.Navigation.ToSelectSpot -> routeMap(lat = effect.lat?.toString(), lng = effect.lng?.toString(), spotCode = effect.spotCode)
is HomeContract.Effect.Navigation.ToPreview -> routeRenderPreview(uris = effect.uris)
} }
navController.navigateSingleTopTo(route, isLaunchSingleTop = true, isInclusive = true) navController.navigateSingleTopTo(
route = route,
isLaunchSingleTop = true,
isInclusive = true,
popupToRoute = routeHome()
)
} }
) )
} }
\ No newline at end of file
...@@ -16,8 +16,9 @@ class HomeContract { ...@@ -16,8 +16,9 @@ class HomeContract {
sealed interface Effect : ViewSideEffect { sealed interface Effect : ViewSideEffect {
sealed interface Navigation : Effect { sealed interface Navigation : Effect {
data object ToLogin : Navigation data object ToLogin : Navigation
data class ToSelectSpot(val lat: Double? = null, val lng: Double? = null, val spotCode: String? = null) : Navigation
data object ToSelectContent : Navigation data object ToSelectContent : Navigation
data class ToSelectSpot(val lat: Double? = null, val lng: Double? = null, val spotCode: String? = null) : Navigation
data class ToPreview(val uris: String) : Navigation
} }
} }
} }
......
package com.isidroid.c23.ui.screen.home package com.isidroid.c23.ui.screen.home
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.isidroid.c23.constant.Argument
import com.isidroid.c23.domain.use_case.HomeUseCase import com.isidroid.c23.domain.use_case.HomeUseCase
import com.isidroid.c23.ext.isDebug import com.isidroid.c23.ext.isDebug
import com.isidroid.core.FlowResult import com.isidroid.core.FlowResult
...@@ -14,10 +16,17 @@ import javax.inject.Inject ...@@ -14,10 +16,17 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class HomeViewModel @Inject constructor( class HomeViewModel @Inject constructor(
private val useCase: HomeUseCase private val useCase: HomeUseCase,
savedStateHandle: SavedStateHandle
) : BaseViewModel<HomeContract.Event, HomeContract.State, HomeContract.Effect>() { ) : BaseViewModel<HomeContract.Event, HomeContract.State, HomeContract.Effect>() {
init { init {
viewModelScope.launch { onCreate() } viewModelScope.launch {
savedStateHandle.getStateFlow<String?>(Argument.URI, null)
.collect { uris ->
onCreate(uris)
}
}
} }
...@@ -26,8 +35,8 @@ class HomeViewModel @Inject constructor( ...@@ -26,8 +35,8 @@ class HomeViewModel @Inject constructor(
override suspend fun handleEvents(event: HomeContract.Event) {} override suspend fun handleEvents(event: HomeContract.Event) {}
// handle events // handle events
private suspend fun onCreate() { private suspend fun onCreate(uris: String?) {
useCase.createSession() useCase.createSession(uris)
.flowOn(Dispatchers.IO) .flowOn(Dispatchers.IO)
.catchTimber { } .catchTimber { }
.collect { res -> .collect { res ->
......
package com.isidroid.utils
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Parcelable
inline fun <reified T : Parcelable> Intent?.getParcelableCompat(key: String): T? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
this?.getParcelableExtra(key, T::class.java)
else
this?.getParcelableExtra<T>(key)
}
inline fun <reified T : Parcelable> Intent?.getParcelableArrayListExtraCompat(key: String): List<T>? {
val list = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
this?.getParcelableArrayListExtra(key, T::class.java)
else
this?.getParcelableArrayListExtra(key)
return list?.filterNotNull()
}
fun Intent.extractUris(): Collection<Uri>? {
return when (action) {
Intent.ACTION_SEND -> return listOfNotNull(getParcelableCompat<Uri>(Intent.EXTRA_STREAM))
Intent.ACTION_SEND_MULTIPLE -> getParcelableArrayListExtraCompat<Uri>(Intent.EXTRA_STREAM)
else -> null
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment