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 @@ -4,7 +4,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension

fun KotlinMultiplatformExtension.configureIosTargets(baseName: String? = null) {
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.uikit.LocalUIView
import androidx.compose.ui.uikit.LocalUIViewController
import platform.AVFoundation.AVErrorApplicationIsNotAuthorizedToUseDevice
import platform.UIKit.UIButton
Expand All @@ -19,7 +20,7 @@ actual fun rememberDocumentScanner(
options: DocumentScannerOptions
): DocumentScanner {

val localViewController = LocalUIViewController.current
val localUiView = LocalUIView.current

var delegate by remember() { mutableStateOf<DocumentScannerDelegate?>(null) }

Expand All @@ -37,7 +38,7 @@ actual fun rememberDocumentScanner(
onResult(Result.failure(exception))
},
onCancel = {
controller.dismissViewControllerAnimated(true) {}
controller.dismissModalViewControllerAnimated(false)
},
onResult = { result ->
controller.dismissViewControllerAnimated(true) {}
Expand All @@ -53,7 +54,8 @@ actual fun rememberDocumentScanner(
delegate = it // need to remember delegate else it is dereferenced
}
)
localViewController.presentViewController(controller, animated = true) {
val viewController = localUiView.window?.rootViewController
viewController?.presentViewController(controller, animated = true) {
if (options.ios.captureMode == DocumentCaptureMode.MANUAL) {
controller.setManualMode()
}
Expand Down
1 change: 0 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ kotlin.code.style=official
#MPP
kotlin.mpp.stability.nowarn=true
kotlin.mpp.enableCInteropCommonization=true
kotlin.mpp.androidSourceSetLayoutVersion=2

#Compose
org.jetbrains.compose.experimental.uikit.enabled=true
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ jvmTarget = "17"
agp = "9.0.1"

#https://github.com/JetBrains/compose-multiplatform
compose-multiplatform = "1.10.1"
compose-multiplatform = "1.11.1"
material3 = "1.10.0-alpha05"
#https://kotlinlang.org/docs/multiplatform-compatibility-guide.html
kotlin = "2.2.21"
kotlin = "2.4.0"
# https://github.com/google/ksp
ksp = "2.3.4"

Expand Down
1 change: 0 additions & 1 deletion sample-app/shared/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ android.useAndroidX=true
#MPP
kotlin.mpp.stability.nowarn=true
#kotlin.mpp.enableCInteropCommonization=true
kotlin.mpp.androidSourceSetLayoutVersion=2

#Compose
org.jetbrains.compose.experimental.uikit.enabled=true
113 changes: 70 additions & 43 deletions sample-app/shared/src/commonMain/kotlin/MainView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
Expand All @@ -29,64 +33,87 @@ import io.github.kalinjul.easydocumentscan.KmpImage
import io.github.kalinjul.easydocumentscan.rememberDocumentScanner
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainView() {
val snackbarHostState = remember() { SnackbarHostState() }

var showBottomSheet by remember { mutableStateOf(false) }
if (showBottomSheet) {

ModalBottomSheet(
onDismissRequest = { showBottomSheet = false }
) {
var images by remember { mutableStateOf<List<KmpImage>>(listOf()) }
var bitmapImages by remember { mutableStateOf<List<ImageBitmap>>(listOf()) }

LaunchedEffect(images) {
images.map { it.loadImage() }.also { bitmapImages = it }
}

Column(modifier = Modifier) {
Text("Scanner Bottom sheet")
val scope = rememberCoroutineScope()
val scanner = rememberDocumentScanner(
onResult = {
if (it.isSuccess) {
images = it.getOrThrow()
scope.launch {
snackbarHostState.showSnackbar(
"${images.size} documents scanned",
duration = SnackbarDuration.Short
)
}
} else {
println(it.exceptionOrNull())
}
},
options = DocumentScannerOptions(
DocumentScannerOptionsAndroid(
pageLimit = 3,
allowGalleryImport = true,
scannerMode = DocumentScannerModeAndroid.BASE
),
DocumentScannerOptionsIos(
captureMode = DocumentCaptureMode.MANUAL
)
)
)
Button(onClick = {
scanner.scan()
}) {
Text("Scan")
}

LazyColumn {
items(bitmapImages) {
Image(
bitmap = it,
contentDescription = null
)
}
}
}
}
}

Scaffold(
snackbarHost = {
SnackbarHost(
hostState = snackbarHostState
)
}
},
) {
var images by remember { mutableStateOf<List<KmpImage>>(listOf()) }
var bitmapImages by remember { mutableStateOf<List<ImageBitmap>>(listOf()) }

LaunchedEffect(images) {
images.map { it.loadImage() }.also { bitmapImages = it }
}

Column(modifier = Modifier.padding(it)) {
Text("Document Scanner demo")
val scope = rememberCoroutineScope()
val scanner = rememberDocumentScanner(
onResult = {
if (it.isSuccess) {
images = it.getOrThrow()
scope.launch {
snackbarHostState.showSnackbar(
"${images.size} documents scanned",
duration = SnackbarDuration.Short
)
}
} else {
println(it.exceptionOrNull())
}
},
options = DocumentScannerOptions(
DocumentScannerOptionsAndroid(
pageLimit = 3,
allowGalleryImport = true,
scannerMode = DocumentScannerModeAndroid.BASE
),
DocumentScannerOptionsIos(
captureMode = DocumentCaptureMode.MANUAL
)
)
)
Button(onClick = {
scanner.scan()
}) {
Text("Scan")
}
scope.launch {
showBottomSheet = !showBottomSheet

LazyColumn {
items(bitmapImages) {
Image(
bitmap = it,
contentDescription = null
)
}
}) {
Text("Show Bottom sheet")
}
}
}
Expand Down
Loading