Import menu composable for both kinds of imports
parent
a6105c9ced
commit
ef1353e82b
|
|
@ -0,0 +1,53 @@
|
||||||
|
package xyz.pixelatedw.recipe.ui.components
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Add
|
||||||
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import xyz.pixelatedw.recipe.MainActivity
|
||||||
|
import xyz.pixelatedw.recipe.utils.sync
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ImportDropdownMenu(ctx: MainActivity) {
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
Box(
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
onClick = { expanded = !expanded }
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Add,
|
||||||
|
contentDescription = "Import recipes"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = { expanded = false }
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text("Import") },
|
||||||
|
onClick = {
|
||||||
|
ctx.sourceChooser.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE))
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text("Sync") },
|
||||||
|
onClick = {
|
||||||
|
sync(ctx)
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
contentDescription = "Toggle tags filtering menu"
|
contentDescription = "Toggle tags filtering menu"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Load / Delete
|
// Import / Delete
|
||||||
if (selectedEntries.isNotEmpty()) {
|
if (selectedEntries.isNotEmpty()) {
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier.weight(0.15f),
|
modifier = Modifier.weight(0.15f),
|
||||||
|
|
@ -130,16 +130,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IconButton(
|
ImportDropdownMenu(ctx)
|
||||||
modifier = Modifier.weight(0.15f),
|
|
||||||
onClick = { sync(ctx) },
|
|
||||||
// onClick = { ctx.sourceChooser.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)) },
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Add,
|
|
||||||
contentDescription = "Load recipes from filesystem"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
package xyz.pixelatedw.recipe.utils
|
package xyz.pixelatedw.recipe.utils
|
||||||
|
|
||||||
import android.os.Build
|
import android.content.Context
|
||||||
import android.os.FileUtils
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import xyz.pixelatedw.recipe.MainActivity
|
import xyz.pixelatedw.recipe.MainActivity
|
||||||
import java.io.BufferedOutputStream
|
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
|
@ -16,14 +13,20 @@ import java.nio.ByteBuffer
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
const val DEFAULT_SYNC_SERVER_IP = "192.168.0.100"
|
||||||
|
const val DEFAULT_SYNC_SERVER_PORT = 9696
|
||||||
|
|
||||||
fun sync(ctx: MainActivity) {
|
fun sync(ctx: MainActivity) {
|
||||||
val executor = Executors.newSingleThreadExecutor()
|
val executor = Executors.newSingleThreadExecutor()
|
||||||
val handler = Handler(Looper.getMainLooper())
|
val handler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
executor.execute(Runnable() {
|
executor.execute {
|
||||||
try {
|
try {
|
||||||
val conn = Socket("192.168.0.100", 9696)
|
val prefs = ctx.getPreferences(Context.MODE_PRIVATE)
|
||||||
|
val syncServerIp = prefs.getString("syncServerIp", DEFAULT_SYNC_SERVER_IP)
|
||||||
|
val syncServerPort = prefs.getInt("syncServerPort", DEFAULT_SYNC_SERVER_PORT)
|
||||||
|
|
||||||
|
val conn = Socket(syncServerIp, syncServerPort)
|
||||||
val stream = conn.getInputStream()
|
val stream = conn.getInputStream()
|
||||||
|
|
||||||
val inputStream = DataInputStream(stream)
|
val inputStream = DataInputStream(stream)
|
||||||
|
|
@ -31,16 +34,16 @@ fun sync(ctx: MainActivity) {
|
||||||
var buffer = ByteArray(8)
|
var buffer = ByteArray(8)
|
||||||
inputStream.read(buffer)
|
inputStream.read(buffer)
|
||||||
val filesSent = ByteBuffer.wrap(buffer).getLong().toInt()
|
val filesSent = ByteBuffer.wrap(buffer).getLong().toInt()
|
||||||
// println("files sent: $filesSent")
|
|
||||||
|
|
||||||
for(f in 0..<filesSent) {
|
for (f in 0..<filesSent) {
|
||||||
buffer = ByteArray(8)
|
buffer = ByteArray(8)
|
||||||
inputStream.read(buffer)
|
inputStream.read(buffer)
|
||||||
val nameBufLen = ByteBuffer.wrap(buffer).getLong().toInt()
|
val nameBufLen = ByteBuffer.wrap(buffer).getLong().toInt()
|
||||||
|
|
||||||
buffer = ByteArray(nameBufLen)
|
buffer = ByteArray(nameBufLen)
|
||||||
inputStream.read(buffer)
|
inputStream.read(buffer)
|
||||||
val fileFullPath = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(buffer)).toString();
|
val fileFullPath =
|
||||||
|
StandardCharsets.UTF_8.decode(ByteBuffer.wrap(buffer)).toString();
|
||||||
val fileName = fileFullPath.split("/").last()
|
val fileName = fileFullPath.split("/").last()
|
||||||
val filePath = fileFullPath.replace(fileName, "")
|
val filePath = fileFullPath.replace(fileName, "")
|
||||||
|
|
||||||
|
|
@ -62,8 +65,7 @@ fun sync(ctx: MainActivity) {
|
||||||
while (usedBytes != contentBufLen) {
|
while (usedBytes != contentBufLen) {
|
||||||
if (usedBytes + blockSize > contentBufLen) {
|
if (usedBytes + blockSize > contentBufLen) {
|
||||||
blockSize = contentBufLen - usedBytes
|
blockSize = contentBufLen - usedBytes
|
||||||
}
|
} else if (blockSize > contentBufLen) {
|
||||||
else if (blockSize > contentBufLen) {
|
|
||||||
blockSize = contentBufLen
|
blockSize = contentBufLen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,10 +89,10 @@ fun sync(ctx: MainActivity) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.post(Runnable {
|
handler.post {
|
||||||
val recipes = ctx.db.recipeWithTagsDao().getAll()
|
val recipes = ctx.db.recipeWithTagsDao().getAll()
|
||||||
ctx.recipeView.setRecipes(recipes)
|
ctx.recipeView.setRecipes(recipes)
|
||||||
println("syncing complete")
|
// println("syncing complete")
|
||||||
})
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue