add start stop delete
This commit is contained in:
		
					parent
					
						
							
								6da971ef21
							
						
					
				
			
			
				commit
				
					
						784879393f
					
				
			
		
					 8 changed files with 183 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -49,7 +49,7 @@ fun InstancesScreen(dashboardViewModel: DashboardViewModel) {
 | 
			
		|||
 | 
			
		||||
    // TODO actually get instances
 | 
			
		||||
 | 
			
		||||
    if (rentedInstances.size > 0) {
 | 
			
		||||
    if (rentedInstances.isNotEmpty()) {
 | 
			
		||||
        ContextualFlowRow(
 | 
			
		||||
            modifier = Modifier
 | 
			
		||||
                .fillMaxWidth()
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +66,12 @@ fun InstancesScreen(dashboardViewModel: DashboardViewModel) {
 | 
			
		|||
                sshButtonClick = {
 | 
			
		||||
                    dashboardViewModel.sshButtonClick(activity, it)
 | 
			
		||||
                },
 | 
			
		||||
                actionButtonClick = {
 | 
			
		||||
                    dashboardViewModel.toggleInstance(it)
 | 
			
		||||
                },
 | 
			
		||||
                deleteButtonClick = {
 | 
			
		||||
                    dashboardViewModel.deleteInstance(it)
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -89,6 +95,8 @@ fun RentedInstanceCard(
 | 
			
		|||
    rentedInstance: RentedInstance,
 | 
			
		||||
    termuxAvailable: Int,
 | 
			
		||||
    sshButtonClick: (RentedInstance) -> Unit,
 | 
			
		||||
    actionButtonClick: (RentedInstance) -> Unit,
 | 
			
		||||
    deleteButtonClick: (RentedInstance) -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val instance by remember(rentedInstance) { derivedStateOf { rentedInstance.instance } }
 | 
			
		||||
    val label by remember(instance) { derivedStateOf {
 | 
			
		||||
| 
						 | 
				
			
			@ -103,27 +111,66 @@ fun RentedInstanceCard(
 | 
			
		|||
            Column(
 | 
			
		||||
                horizontalAlignment = Alignment.End
 | 
			
		||||
            ) {
 | 
			
		||||
                Button( // TODO consider other buttons
 | 
			
		||||
                    modifier = Modifier.height(24.dp),
 | 
			
		||||
                    contentPadding = PaddingValues(0.dp),
 | 
			
		||||
                    onClick = { sshButtonClick(rentedInstance) }
 | 
			
		||||
                ) {
 | 
			
		||||
                    if (termuxAvailable > -1) {
 | 
			
		||||
                Row {
 | 
			
		||||
                    Button(
 | 
			
		||||
                        modifier = Modifier.size(24.dp),
 | 
			
		||||
                        contentPadding = PaddingValues(0.dp),
 | 
			
		||||
                        onClick = { deleteButtonClick(rentedInstance) },
 | 
			
		||||
                    ) {
 | 
			
		||||
                        Icon(
 | 
			
		||||
                            painter = painterResource(id = R.drawable.termux_icon),
 | 
			
		||||
                            contentDescription = "Run in Termux"
 | 
			
		||||
                            modifier = Modifier.size(16.dp),
 | 
			
		||||
                            painter = painterResource(id = R.drawable.baseline_delete_24),
 | 
			
		||||
                            contentDescription = "Delete instance"
 | 
			
		||||
                        )
 | 
			
		||||
                        Text("ssh")
 | 
			
		||||
                        Spacer(modifier = Modifier.size(4.dp)) // necessary because TODO the termux icon has padding
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Spacer(modifier = Modifier.size(1.dp)) // TODO make this not needed?
 | 
			
		||||
                        Icon(
 | 
			
		||||
                            modifier = Modifier.size(12.dp),
 | 
			
		||||
                            painter = painterResource(id = R.drawable.copy_regular), // TODO copy icon here
 | 
			
		||||
                            contentDescription = "Copy command"
 | 
			
		||||
                        )
 | 
			
		||||
                        Spacer(modifier = Modifier.size(6.dp))
 | 
			
		||||
                        Text("ssh")
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Spacer(modifier = Modifier.width(4.dp))
 | 
			
		||||
 | 
			
		||||
                    Button(
 | 
			
		||||
                        modifier = Modifier.size(24.dp),
 | 
			
		||||
                        contentPadding = PaddingValues(0.dp),
 | 
			
		||||
                        onClick = { actionButtonClick(rentedInstance) },
 | 
			
		||||
                        enabled = rentedInstance.status == rentedInstance.targetStatus
 | 
			
		||||
                    ) {
 | 
			
		||||
                        if (rentedInstance.status == "running") {
 | 
			
		||||
                            Icon(
 | 
			
		||||
                                modifier = Modifier.size(16.dp),
 | 
			
		||||
                                painter = painterResource(id = R.drawable.baseline_stop_24),
 | 
			
		||||
                                contentDescription = "Stop instance"
 | 
			
		||||
                            )
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Icon(
 | 
			
		||||
                                modifier = Modifier.size(16.dp),
 | 
			
		||||
                                painter = painterResource(id = R.drawable.baseline_play_arrow_24),
 | 
			
		||||
                                contentDescription = "Start instance"
 | 
			
		||||
                            )
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Spacer(modifier = Modifier.width(4.dp))
 | 
			
		||||
 | 
			
		||||
                    Button(
 | 
			
		||||
                        modifier = Modifier.height(24.dp),
 | 
			
		||||
                        contentPadding = PaddingValues(0.dp),
 | 
			
		||||
                        onClick = { sshButtonClick(rentedInstance) }
 | 
			
		||||
                    ) {
 | 
			
		||||
                        if (termuxAvailable > -1) {
 | 
			
		||||
                            Icon(
 | 
			
		||||
                                painter = painterResource(id = R.drawable.termux_icon),
 | 
			
		||||
                                contentDescription = "Run in Termux"
 | 
			
		||||
                            )
 | 
			
		||||
                            Text("ssh")
 | 
			
		||||
                            Spacer(modifier = Modifier.size(4.dp)) // necessary because TODO the termux icon has padding
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Spacer(modifier = Modifier.size(1.dp)) // TODO make this not needed?
 | 
			
		||||
                            Icon(
 | 
			
		||||
                                modifier = Modifier.size(12.dp),
 | 
			
		||||
                                painter = painterResource(id = R.drawable.copy_regular), // TODO copy icon here
 | 
			
		||||
                                contentDescription = "Copy command"
 | 
			
		||||
                            )
 | 
			
		||||
                            Spacer(modifier = Modifier.size(6.dp))
 | 
			
		||||
                            Text("ssh")
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
package eu.m724.vastapp.vastai.api
 | 
			
		||||
 | 
			
		||||
import eu.m724.vastapp.vastai.ApiFailure
 | 
			
		||||
import org.json.JSONObject
 | 
			
		||||
 | 
			
		||||
class JsonUrlRequestCallback(
 | 
			
		||||
    onSuccess: (JSONObject) -> Unit,
 | 
			
		||||
    onFailure: (ApiFailure) -> Unit
 | 
			
		||||
) : StringUrlRequestCallback({ stringResponse ->
 | 
			
		||||
    try {
 | 
			
		||||
        val jsonResponse = JSONObject(stringResponse)
 | 
			
		||||
        onSuccess(jsonResponse)
 | 
			
		||||
    } catch (e: Exception) {
 | 
			
		||||
        onFailure(ApiFailure(e.message))
 | 
			
		||||
    }
 | 
			
		||||
}, onFailure)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
package eu.m724.vastapp.vastai.api
 | 
			
		||||
 | 
			
		||||
import eu.m724.vastapp.vastai.ApiFailure
 | 
			
		||||
import org.chromium.net.CronetException
 | 
			
		||||
import org.chromium.net.UrlRequest
 | 
			
		||||
import org.chromium.net.UrlResponseInfo
 | 
			
		||||
import java.nio.ByteBuffer
 | 
			
		||||
import java.nio.charset.CodingErrorAction
 | 
			
		||||
 | 
			
		||||
open class StringUrlRequestCallback(
 | 
			
		||||
    val onSuccess: (String) -> Unit,
 | 
			
		||||
    val onFailure: (ApiFailure) -> Unit
 | 
			
		||||
) : UrlRequest.Callback() {
 | 
			
		||||
    protected val stringResponse = StringBuilder()
 | 
			
		||||
 | 
			
		||||
    override fun onRedirectReceived(
 | 
			
		||||
        request: UrlRequest?,
 | 
			
		||||
        info: UrlResponseInfo?,
 | 
			
		||||
        newLocationUrl: String?
 | 
			
		||||
    ) {
 | 
			
		||||
        request?.followRedirect()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
 | 
			
		||||
        request?.read(ByteBuffer.allocateDirect(102400))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onReadCompleted(
 | 
			
		||||
        request: UrlRequest?,
 | 
			
		||||
        info: UrlResponseInfo?,
 | 
			
		||||
        byteBuffer: ByteBuffer?
 | 
			
		||||
    ) {
 | 
			
		||||
        byteBuffer?.clear()
 | 
			
		||||
        request?.read(byteBuffer)
 | 
			
		||||
 | 
			
		||||
        stringResponse.append(Charsets.UTF_8.newDecoder().onUnmappableCharacter(CodingErrorAction.IGNORE).decode(byteBuffer))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
 | 
			
		||||
        if (info?.httpStatusCode == 200) {
 | 
			
		||||
            onSuccess(stringResponse.toString())
 | 
			
		||||
        } else {
 | 
			
		||||
            onFailure(ApiFailure("${info?.httpStatusCode} ${info?.httpStatusText}"))
 | 
			
		||||
            println("API error: ${stringResponse.toString()}")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
 | 
			
		||||
        onFailure(ApiFailure("Network error: ${error?.message ?: "Unknown"}"))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
package eu.m724.vastapp.vastai.api.upload
 | 
			
		||||
 | 
			
		||||
import org.json.JSONObject
 | 
			
		||||
 | 
			
		||||
class JsonUploadDataProvider(
 | 
			
		||||
    jsonObject: JSONObject
 | 
			
		||||
) : StringUploadDataProvider(
 | 
			
		||||
    jsonObject.toString()
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
package eu.m724.vastapp.vastai.api.upload
 | 
			
		||||
 | 
			
		||||
import org.chromium.net.UploadDataProvider
 | 
			
		||||
import org.chromium.net.UploadDataSink
 | 
			
		||||
import java.nio.ByteBuffer
 | 
			
		||||
import java.nio.charset.StandardCharsets
 | 
			
		||||
 | 
			
		||||
open class StringUploadDataProvider(
 | 
			
		||||
    val data: String
 | 
			
		||||
) : UploadDataProvider() {
 | 
			
		||||
    override fun getLength(): Long {
 | 
			
		||||
        return data.length.toLong()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun read(uploadDataSink: UploadDataSink?, byteBuffer: ByteBuffer?) {
 | 
			
		||||
        byteBuffer!!.put(data.toByteArray(StandardCharsets.UTF_8))
 | 
			
		||||
        uploadDataSink!!.onReadSucceeded(false)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun rewind(uploadDataSink: UploadDataSink?) {
 | 
			
		||||
        // TODO look into it
 | 
			
		||||
        uploadDataSink!!.onRewindSucceeded()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/baseline_delete_24.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/baseline_delete_24.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
 | 
			
		||||
      
 | 
			
		||||
    <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
 | 
			
		||||
    
 | 
			
		||||
</vector>
 | 
			
		||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/baseline_play_arrow_24.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/baseline_play_arrow_24.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
 | 
			
		||||
      
 | 
			
		||||
    <path android:fillColor="@android:color/white" android:pathData="M8,5v14l11,-7z"/>
 | 
			
		||||
    
 | 
			
		||||
</vector>
 | 
			
		||||
							
								
								
									
										5
									
								
								app/src/main/res/drawable/baseline_stop_24.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/res/drawable/baseline_stop_24.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
 | 
			
		||||
      
 | 
			
		||||
    <path android:fillColor="@android:color/white" android:pathData="M6,6h12v12H6z"/>
 | 
			
		||||
    
 | 
			
		||||
</vector>
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue