Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/main/kotlin/core/disc_storage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.util.*
// TODO tento file si zasluzi lasku

private val folder = "${System.getProperty("user.home")}${File.separatorChar}MockdogMocks".also { File(it).mkdirs() }
private val mockFiles = mutableStateOf(emptyList<String>())
val mockFiles = mutableStateOf(emptyList<String>())

fun saveFile(path: String, name: String, body: String) = try {
// TODO nefunguje ak name v sebe obsahuje '_'
Expand Down
23 changes: 14 additions & 9 deletions src/main/kotlin/core/server.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import ui.globalResponse
import java.net.Inet4Address
import java.net.InetAddress
import java.net.NetworkInterface
Expand Down Expand Up @@ -64,18 +65,22 @@ fun startServer(port: Int = 52242, inetAddress: InetAddress = getDefaultIpV4Addr

requests.add(request)

val response: SentResponse = if(mockingEnabled.value) {
responses[request.id] = Loading
responses[request.id] = EditResponse(sendRealRequest(request))
val value = queues.getOrPut(request.id) { ArrayBlockingQueue(1) }.take()
if(value is SentResponse) {
value
val response: SentResponse = if (globalResponse != null) {
SentResponse(status = globalResponse!!.code, body = globalResponse!!.body)
} else {
if(mockingEnabled.value) {
responses[request.id] = Loading
responses[request.id] = EditResponse(sendRealRequest(request))
val value = queues.getOrPut(request.id) { ArrayBlockingQueue(1) }.take()
if(value is SentResponse) {
value
} else {
responses[request.id] = value
sendRealRequest(request)
}
} else {
responses[request.id] = value
sendRealRequest(request)
}
} else {
sendRealRequest(request)
}

responses[request.id] = response
Expand Down
189 changes: 163 additions & 26 deletions src/main/kotlin/ui/app.kt
Original file line number Diff line number Diff line change
@@ -1,45 +1,182 @@
package ui

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.rememberDialogState
import core.mockFiles
import core.mutable
import core.readFile
import java.util.*

data class GlobalResponse(
val code: Int,
val name: String,
val body: String
)

var globalResponse by mutableStateOf<GlobalResponse?>(null)
var globalResponseDialog by mutableStateOf(false)

@Composable
fun App() {
MaterialTheme(
colors = Palette,
typography = Typography
) {
Surface(M.fillMaxWidth()) {
Row {
val leftPaneWidth = mutable(400.dp)
val selectedRequest = mutable<UUID?>(null)

// Left pane - history + settings
LeftPane(
paneWidth = leftPaneWidth.value,
selected = selectedRequest.value,
onSelect = { selectedRequest.value = it })

// Movable divider
DraggableDivider(
width = leftPaneWidth.value,
onWidthChange = { leftPaneWidth.value = it })

// Detail
Surface(
modifier = M.fillMaxHeight().weight(1f),
color = C.background
) {
selectedRequest.value?.let { Detail(id = it) }
Column {
// Global response status
globalResponse?.let { response ->
ContextMenuArea(items = { listOf(ContextMenuItem("Remove global response") { globalResponse = null }) }) {
Row(
modifier = M.fillMaxWidth().background(color = Orange),
horizontalArrangement = Arrangement.Center
) {
Text(
text = "☺ Warning ☻ global response is set to ► ${response.code} - ${response.name}",
fontWeight = FontWeight.Bold)
}
}
}

// App content
Row {
val leftPaneWidth = mutable(400.dp)
val selectedRequest = mutable<UUID?>(null)

// Left pane - history + settings
LeftPane(
paneWidth = leftPaneWidth.value,
selected = selectedRequest.value,
onSelect = { selectedRequest.value = it })

// Movable divider
DraggableDivider(
width = leftPaneWidth.value,
onWidthChange = { leftPaneWidth.value = it })

// Detail
Surface(
modifier = M.fillMaxHeight().weight(1f),
color = C.background
) {
selectedRequest.value?.let { Detail(id = it) }
}
}
}
}

if (globalResponseDialog)
GlobalResponseDialog()
}
}

@Composable
private fun GlobalResponseDialog() {
val (body, setBody) = mutable("")
val (mockDialog, setMockDialog) = mutable(false)
val lazyState = rememberLazyListState()

Dialog(
state = rememberDialogState(size = DpSize(600.dp, 900.dp)),
onCloseRequest = { globalResponseDialog = false },
title = "Global request response",
resizable = true,
content = {
Column (
modifier = M.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
Text(
modifier = M.align(Alignment.CenterHorizontally),
text = "Set global response for every request.",
style = T.h6)

// Insert own JSON
OutlinedTextField(
modifier = M.fillMaxWidth().padding(bottom = 16.dp).weight(1f),
label = { Text("JSON response body", style = T.caption) },
colors = TextFieldDefaults.outlinedTextFieldColors(backgroundColor = C.surface),
value = body,
onValueChange = setBody)

Button(onClick = { setMockDialog(true) }) {
Text(text = "Load saved mock")
}

Text(text = "Response codes:")

Box(modifier = M.fillMaxWidth().weight(1f)) {
LazyColumn(state = lazyState) {
allHttpCodes.forEach { entry ->
item {
Text(
text = "${entry.key} - ${entry.value}",
style = T.subtitle1,
modifier = M.fillMaxWidth().padding(vertical = 4.dp).clickable {
globalResponse = GlobalResponse(
code = entry.key,
name = entry.value,
body = body
)

globalResponseDialog = false
})
}
}
}

VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
adapter = rememberScrollbarAdapter(lazyState)
)
}
}
})

if (mockDialog)
Dialog(
state = rememberDialogState(size = DpSize(400.dp, 600.dp)),
onCloseRequest = { setMockDialog(false) },
title = "Load saved mock",
resizable = true,
content = {
Column (
modifier = M.fillMaxWidth().padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Text(
modifier = M.align(Alignment.CenterHorizontally),
text = "Load saved mock from file",
style = T.subtitle1)

Column(M.verticalScroll(rememberScrollState()).weight(1f)) {
mockFiles.value.filter {
it.contains('_')
}.forEach {
val requestPath = it.substringAfterLast('_')
Text(
modifier = M.fillMaxWidth().padding(vertical = 4.dp).clickable {
readFile(it)?.let(setBody)
setMockDialog(false)
},
text = requestPath
)
}
}
}
})
}
2 changes: 1 addition & 1 deletion src/main/kotlin/ui/detail.kt
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ private val httpCodes = mapOf(
200 to "Ok", 401 to "Unauthorised", 404 to "Not Found", 500 to "Internal Server Error"
)

private val allHttpCodes = mapOf(
val allHttpCodes = mapOf(
100 to "Continue", 101 to "Switching Protocols", 102 to "Processing", 103 to "Early Hints",
200 to "Ok", 201 to "Created", 202 to "Accepted", 203 to "Non-Authoritative Information", 204 to "No Content", 205 to "Reset Content", 206 to "Partial Content", 207 to "Multi Status", 208 to "Already Reported", 226 to "IM Used",
300 to "Multiple Choices", 301 to "Moved Permanently", 302 to "Found", 303 to "See Other", 304 to "Not Modified", 305 to "Use Proxy", 306 to "Unused", 307 to "Temporary Redirect", 308 to "Permanent Redirect",
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/ui/left_pane.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ fun LeftPane(
) {
Column(M.fillMaxHeight().width(paneWidth).background(C.surface)) {
Column(M.weight(1f)) {
Button(onClick = { globalResponseDialog = true }) {
Text("Set global response TODO(do setting)")
}
Row {
Text(
modifier = M.padding(16.dp).weight(1f),
Expand Down