diff --git a/composeApp/src/androidMain/kotlin/ui/download/PlatformDownloadImage.android.kt b/composeApp/src/androidMain/kotlin/ui/download/PlatformDownloadImage.android.kt index d215f4c..dddf46b 100644 --- a/composeApp/src/androidMain/kotlin/ui/download/PlatformDownloadImage.android.kt +++ b/composeApp/src/androidMain/kotlin/ui/download/PlatformDownloadImage.android.kt @@ -26,7 +26,7 @@ actual class PlatformDownloadImage(private val context: Context) { (context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager).enqueue(request) - ImageDownloadState.Successful + ImageDownloadState.Success } catch (e: Exception) { ImageDownloadState.Failure(e) } diff --git a/composeApp/src/commonMain/kotlin/App.kt b/composeApp/src/commonMain/kotlin/App.kt index 28310ce..d4fac15 100644 --- a/composeApp/src/commonMain/kotlin/App.kt +++ b/composeApp/src/commonMain/kotlin/App.kt @@ -4,7 +4,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable -import androidx.navigation.compose.rememberNavController import androidx.navigation.toRoute import data.repository.SharedRepository import org.jetbrains.compose.ui.tooling.preview.Preview @@ -12,6 +11,7 @@ import org.koin.compose.koinInject import ui.navigation.PhotoScreen import ui.screen.HomeScreenEntryPoint import ui.screen.PhotoDetailScreenEntryPoint +import ui.theme.LocalNavController import ui.theme.UnsplashKMPTheme @OptIn(ExperimentalFoundationApi::class) @@ -28,7 +28,7 @@ fun App() { UnsplashKMPTheme(darkTheme = sharedRepository.isDarkThemeEnabled) { - val navController = rememberNavController() + val navController = LocalNavController.current NavHost(navController = navController, startDestination = PhotoScreen.HomeScreen) { diff --git a/composeApp/src/commonMain/kotlin/ui/navigation/Util.kt b/composeApp/src/commonMain/kotlin/ui/navigation/Util.kt new file mode 100644 index 0000000..330796c --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ui/navigation/Util.kt @@ -0,0 +1,22 @@ +package ui.navigation + +import com.mohamedrejeb.calf.permissions.ExperimentalPermissionsApi +import com.mohamedrejeb.calf.permissions.PermissionState +import com.mohamedrejeb.calf.permissions.PermissionStatus + +@OptIn(ExperimentalPermissionsApi::class, ExperimentalPermissionsApi::class) +fun runWithPermission(permissionState: PermissionState, ifGranted: () -> Unit) { + when (val status = permissionState.status) { + is PermissionStatus.Denied -> { + if (status.shouldShowRationale) { + permissionState.launchPermissionRequest() + } else { + permissionState.openAppSettings() + } + } + + is PermissionStatus.Granted -> { + ifGranted() + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ui/screen/PhotoDetailScreenEntryPoint.kt b/composeApp/src/commonMain/kotlin/ui/screen/PhotoDetailScreenEntryPoint.kt index 76af813..9fbf011 100644 --- a/composeApp/src/commonMain/kotlin/ui/screen/PhotoDetailScreenEntryPoint.kt +++ b/composeApp/src/commonMain/kotlin/ui/screen/PhotoDetailScreenEntryPoint.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.CircularProgressIndicator import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -18,11 +19,11 @@ import androidx.compose.ui.window.DialogProperties import androidx.navigation.NavController import com.mohamedrejeb.calf.permissions.ExperimentalPermissionsApi import com.mohamedrejeb.calf.permissions.Permission -import com.mohamedrejeb.calf.permissions.PermissionStatus import com.mohamedrejeb.calf.permissions.rememberPermissionState import getPlatform import org.koin.compose.viewmodel.koinViewModel import org.koin.core.annotation.KoinExperimentalAPI +import ui.navigation.runWithPermission import ui.theme.appDark import ui.viewmodel.PhotoDetailViewModel @@ -45,6 +46,8 @@ fun PhotoDetailScreenEntryPoint( Permission.Gallery ) + val currentPlatform = remember { getPlatform() } + var showDialog = viewModel.isDownloading PhotoDetail( @@ -52,40 +55,19 @@ fun PhotoDetailScreenEntryPoint( state = viewModel.uiState, onBackPressed = { navController.popBackStack() } ) { - when (getPlatform()) { + when (currentPlatform) { Platform.Android -> { - - when (val status = writeStorage.status) { - is PermissionStatus.Denied -> { - if (status.shouldShowRationale) { - writeStorage.launchPermissionRequest() - } else { - writeStorage.openAppSettings() - } - } - - is PermissionStatus.Granted -> { - if (it != null) { - viewModel.startDownload(it) - } + runWithPermission(writeStorage) { + if (it != null) { + viewModel.startDownload(it) } } } Platform.Apple -> { - when (val status = gallery.status) { - is PermissionStatus.Denied -> { - if (status.shouldShowRationale) { - gallery.launchPermissionRequest() - } else { - gallery.openAppSettings() - } - } - - is PermissionStatus.Granted -> { - if (it != null) { - viewModel.startDownload(it) - } + runWithPermission(gallery) { + if (it != null) { + viewModel.startDownload(it) } } } @@ -104,7 +86,7 @@ fun PhotoDetailScreenEntryPoint( properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false) ) { Column( - modifier = Modifier.size(100.dp).background(appDark, RoundedCornerShape(8.dp)), + modifier = Modifier.size(100.dp).background(appDark, RoundedCornerShape(10.dp)), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { diff --git a/composeApp/src/commonMain/kotlin/ui/state/ImageDownloadState.kt b/composeApp/src/commonMain/kotlin/ui/state/ImageDownloadState.kt index 7e71fce..018ec92 100644 --- a/composeApp/src/commonMain/kotlin/ui/state/ImageDownloadState.kt +++ b/composeApp/src/commonMain/kotlin/ui/state/ImageDownloadState.kt @@ -3,6 +3,6 @@ package ui.state sealed class ImageDownloadState { data object Idle : ImageDownloadState() data object Loading : ImageDownloadState() - data object Successful : ImageDownloadState() + data object Success : ImageDownloadState() data class Failure(val exception: Throwable) : ImageDownloadState() } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ui/theme/Theme.kt b/composeApp/src/commonMain/kotlin/ui/theme/Theme.kt index 3cc935c..bbae313 100644 --- a/composeApp/src/commonMain/kotlin/ui/theme/Theme.kt +++ b/composeApp/src/commonMain/kotlin/ui/theme/Theme.kt @@ -6,7 +6,11 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.darkColors import androidx.compose.material.lightColors import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.graphics.Color +import androidx.navigation.NavHostController +import androidx.navigation.compose.rememberNavController import ng.devtamuno.unsplash.compose.ui.theme.Shapes private val DarkColorPalette = darkColors( @@ -27,6 +31,10 @@ private val LightColorPalette = lightColors( secondaryVariant = Color(0xFFD4D8EB) ) +val LocalNavController = compositionLocalOf { + error("NavController not provided") +} + @ExperimentalFoundationApi @Composable fun UnsplashKMPTheme( @@ -42,7 +50,8 @@ fun UnsplashKMPTheme( MaterialTheme( colors = colors, typography = getTypography(), - shapes = Shapes, - content = content - ) + shapes = Shapes + ) { + CompositionLocalProvider(LocalNavController provides rememberNavController(), content = content) + } } \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/ui/download/PlatformDownloadImage.desktop.kt b/composeApp/src/desktopMain/kotlin/ui/download/PlatformDownloadImage.desktop.kt index 35876e7..9ea6fc5 100644 --- a/composeApp/src/desktopMain/kotlin/ui/download/PlatformDownloadImage.desktop.kt +++ b/composeApp/src/desktopMain/kotlin/ui/download/PlatformDownloadImage.desktop.kt @@ -26,7 +26,7 @@ actual class PlatformDownloadImage(private val client: HttpClient) { val body = response.bodyAsChannel() val result = body.toByteArray() saveImageToFile(result, fileName) - ImageDownloadState.Successful + ImageDownloadState.Success } catch (e: Exception) { ImageDownloadState.Failure(e) } diff --git a/composeApp/src/nativeMain/kotlin/ui/download/PlatformDownloadImage.native.kt b/composeApp/src/nativeMain/kotlin/ui/download/PlatformDownloadImage.native.kt index da71253..1962560 100644 --- a/composeApp/src/nativeMain/kotlin/ui/download/PlatformDownloadImage.native.kt +++ b/composeApp/src/nativeMain/kotlin/ui/download/PlatformDownloadImage.native.kt @@ -39,7 +39,7 @@ actual class PlatformDownloadImage { saveImageToPhotos(image) println("Image saved successfully") - ImageDownloadState.Successful + ImageDownloadState.Success } catch (e: Exception) { ImageDownloadState.Failure(e) }