mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 10:29:58 +02:00
feat(send): multi-file shares and receivers polish
Allow selecting multiple files on Android, desktop, and iOS and share them as one transfer through the core multi-source path. Update the composer UI for multi-file review, hide unfinished iOS receive methods, and surface refusal reasons on the receivers list.
This commit is contained in:
@@ -15,13 +15,14 @@ import javax.swing.filechooser.FileSystemView
|
||||
|
||||
@Composable
|
||||
actual fun rememberShareFilePicker(
|
||||
onFilePicked: (PickedShareFile) -> Unit,
|
||||
onFilesPicked: (List<PickedShareFile>) -> Unit,
|
||||
onError: (String) -> Unit,
|
||||
): ShareFilePicker = remember(onFilePicked, onError) {
|
||||
): ShareFilePicker = remember(onFilesPicked, onError) {
|
||||
object : ShareFilePicker {
|
||||
override fun pickFile() {
|
||||
override fun pickFiles() {
|
||||
openPicker(onError) {
|
||||
pickShareFile()?.let(onFilePicked)
|
||||
val selected = pickShareFiles()
|
||||
if (selected.isNotEmpty()) onFilesPicked(selected)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,22 +72,24 @@ private fun activeFrame(): Frame? {
|
||||
?: Frame.getFrames().firstOrNull { it.isVisible }
|
||||
}
|
||||
|
||||
private fun pickShareFile(): PickedShareFile? {
|
||||
val dialog = nativeFileDialog("Select file to share")
|
||||
private fun pickShareFiles(): List<PickedShareFile> {
|
||||
val dialog = nativeFileDialog("Select files to share").apply {
|
||||
isMultipleMode = true
|
||||
}
|
||||
return try {
|
||||
dialog.isVisible = true
|
||||
val directory = dialog.directory
|
||||
val file = dialog.file
|
||||
if (directory != null && file != null) {
|
||||
val selected = File(directory, file)
|
||||
val directory = dialog.directory ?: return emptyList()
|
||||
val names = dialog.files?.map { it.name }.orEmpty().ifEmpty {
|
||||
dialog.file?.let { listOf(it) }.orEmpty()
|
||||
}
|
||||
names.map { name ->
|
||||
val selected = File(directory, name)
|
||||
PickedShareFile(
|
||||
selected.absolutePath,
|
||||
selected.name,
|
||||
selected.length().takeIf { it >= 0L }?.toULong(),
|
||||
selected.systemIconPng(),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} finally {
|
||||
dialog.dispose()
|
||||
|
||||
@@ -28,11 +28,22 @@ private class JvmFileSystemService : FileSystemService {
|
||||
|
||||
override fun createReceiveOutputSink(folder: ReceiveFolder): ReceiveOutputSink? = null
|
||||
|
||||
override suspend fun sharePickedFile(
|
||||
override suspend fun sharePickedFiles(
|
||||
repository: CoreGateway,
|
||||
file: PickedShareFile,
|
||||
files: List<PickedShareFile>,
|
||||
transferName: String,
|
||||
senderName: String,
|
||||
accessPolicy: ShareAccessPolicy,
|
||||
): Result<Share> = repository.sharePath(file.value, transferName, senderName, accessPolicy)
|
||||
): Result<Share> {
|
||||
require(files.isNotEmpty()) { "Select at least one file to share" }
|
||||
val sources = files.map { file ->
|
||||
uniffi.vnidrop.ShareSource(
|
||||
kind = uniffi.vnidrop.SourceKind.PATH,
|
||||
value = file.value,
|
||||
displayName = file.displayName,
|
||||
isDirectory = false,
|
||||
)
|
||||
}
|
||||
return repository.shareSources(sources, transferName, senderName, accessPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user