Giorgi
01/24/2023, 2:46 PMfun main() {
onWasmReady {
Window {
var selectedDestination by remember { mutableStateOf(Destinations.HISTORY) }
val destinations = Destinations.values()
Row {
NavigationRail {
FloatingActionButton(onClick = {
// TODO show file dialog here
}, shape = RoundedCornerShape(10.dp)) {
Icon(Icons.Filled.Add, contentDescription = "Add")
}
Spacer(Modifier.height(16.dp))
destinations.forEach { item ->
NavigationRailItem(
icon = { Icon(item.icon, contentDescription = item.title) },
label = { Text(item.title) },
selected = selectedDestination == item,
onClick = { selectedDestination = item }
)
}
}
when (selectedDestination) {
Destinations.HISTORY -> HistoryPage()
Destinations.STATS -> StatsPage()
Destinations.DOWNLOADS -> DownloadsPage()
Destinations.SETTINGS -> SettingsPage()
}
}
}
}
}
and when user clicks the FloatingActionButton
he should be able to select a file. I tried to do it like here https://stackoverflow.com/a/8385882/4885394 but im not able to translate Javascript to Kotlin. How can I create an Input element and then add a click listener? tried like document.createElement("input")
but then it has different type and I dont know to what I should cast it.
Before I had this
Input(InputType.File) {
onChange {
val file = it.target.files?.asList()?.first()
if (file != null) {
scope.launch {
output = try {
YoutubeHistory(file.text(), minVideoClicks).toString()
} catch (e: Exception) {
e.message ?: "Unknown Error"
}
}
}
}
}
and it worked. Thats what I want to achieve but in actual multiplatform compose. Or what do you guys call it? the version that uses skia on web with canvasDavid Herman
01/24/2023, 4:06 PMfun Document.downloadFileToDisk(
filename: String,
type: String,
content: String,
) {
val snapshotBlob = Blob(arrayOf(content), BlobPropertyBag(type))
val url = DomURL.createObjectURL(snapshotBlob)
val tempAnchor = (createElement("a") as HTMLAnchorElement).apply {
style.display = "none"
href = url
download = filename
}
document.body!!.append(tempAnchor)
tempAnchor.click()
DomURL.revokeObjectURL(url)
tempAnchor.remove()
}
fun Document.loadFileFromDisk(
accept: String,
onLoaded: (String) -> Unit,
) {
val tempInput = (createElement("input") as HTMLInputElement).apply {
type = "file"
style.display = "none"
this.accept = accept
multiple = false
}
tempInput.onchange = { changeEvt ->
val file = changeEvt.target.asDynamic().files[0] as File
val reader = FileReader()
reader.onload = { loadEvt ->
val content = loadEvt.target.asDynamic().result as String
onLoaded(content)
}
reader.readAsText(file, "UTF-8")
}
body!!.append(tempInput)
tempInput.click()
tempInput.remove()
}
which you'd call like so:
document.loadFileFromDisk(".sav") { saveFileContent -> ... }
Document
here because I try to avoid creating globally scoped methods when possible, but document
itself is a global so technically my save/load methods can be global too).
(Also, you didn't ask about downloading, but I included it in case it's helpful for anyone else who stumbles upon this later)FileDialog
class with a load
method in it, and then different constructors per platform to pass in anything you need to launch the dialog.Giorgi
01/24/2023, 5:31 PM