working on web interface
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
build/*
|
||||
**/build/*
|
||||
|
||||
+1
-5
@@ -1,11 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform") version "2.4.10" apply false
|
||||
alias(libs.plugins.kotlin.multiplatform) apply false
|
||||
alias(libs.plugins.compose) apply false
|
||||
alias(libs.plugins.kotlin.compose) apply false
|
||||
alias(libs.plugins.ktor) apply false
|
||||
alias(libs.plugins.kotlin.serialization) apply false
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KotlinProject</title>
|
||||
<link type="text/css" rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body style="text-align: center; align-content: center">
|
||||
<h1>Web Client HTML</h1>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 50 50" role="presentation">
|
||||
<circle cx="25" cy="25" r="20" stroke="#ccc" stroke-width="4" fill="none"/>
|
||||
<circle cx="25" cy="25" r="20" stroke="#333" stroke-width="4" fill="none" stroke-linecap="round"
|
||||
stroke-dasharray="90 125">
|
||||
<animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s"
|
||||
repeatCount="indefinite"/>
|
||||
</circle>
|
||||
</svg>
|
||||
<script type="application/javascript" src="web.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
// alias(libs.plugins.kotlin.jvm)
|
||||
alias(libs.plugins.compose)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
@@ -7,23 +8,18 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":shared"))
|
||||
implementation("com.composables:icons-material-icons-filled-cmp:2.2.1")
|
||||
implementation(project(":shared_ui"))
|
||||
// implementation(libs.compose.icons.material)
|
||||
// implementation("com.composables:icons-material-icons-filled-cmp:2.2.1")
|
||||
implementation(libs.kotlinx.serialization)
|
||||
implementation(project(":shared"))
|
||||
implementation(libs.ktor.serialization.kotlinx.json)
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.cio)
|
||||
implementation(libs.ktor.client.content.negotiation)
|
||||
implementation("com.composables:icons-material-icons-filled-cmp:2.2.1")
|
||||
implementation("org.jetbrains.compose.material3:material3:1.9.0")
|
||||
implementation(libs.compose.material3)
|
||||
implementation(compose.desktop.currentOs)
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "dev.geekback.dopewars.desktop.Main3Kt"
|
||||
|
||||
@@ -3,11 +3,8 @@ package dev.geekback.dopewars.desktop
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.desktop.ApiClient
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import dev.geekback.dopewars.shared.api.TravelRequest
|
||||
import dev.geekback.dopewars.shared.api.TravelResult
|
||||
import dev.geekback.dopewars.ui.PlayerUi
|
||||
|
||||
class ClientState(player: Player) {
|
||||
var player by mutableStateOf(player)
|
||||
|
||||
@@ -19,7 +19,6 @@ import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import dev.geekback.dopewars.shared.Drug
|
||||
import dev.geekback.dopewars.shared.DrugInfo
|
||||
import dev.geekback.dopewars.shared.Drugs
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
import dev.geekback.dopewars.shared.Locations
|
||||
import dev.geekback.dopewars.shared.Market
|
||||
|
||||
@@ -2,23 +2,15 @@ package dev.geekback.dopewars.desktop
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DrawerState
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import com.composables.icons.materialicons.MaterialIcons
|
||||
import com.composables.icons.materialicons.filled.Menu
|
||||
import dev.geekback.dopewars.shared.Drug
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import kotlinx.coroutines.launch
|
||||
import dev.geekback.dopewars.ui.AppTheme
|
||||
|
||||
|
||||
fun main() {
|
||||
|
||||
@@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ModalDrawerSheet
|
||||
import androidx.compose.material3.ModalNavigationDrawer
|
||||
import androidx.compose.material3.NavigationDrawerItem
|
||||
@@ -22,8 +21,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import com.composables.icons.materialicons.MaterialIcons
|
||||
import com.composables.icons.materialicons.filled.Login
|
||||
import dev.geekback.dopewars.ui.AppTheme
|
||||
import dev.geekback.dopewars.ui.PlayerUi
|
||||
import dev.geekback.dopewars.ui.TravelUi
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -58,11 +56,13 @@ fun App() {
|
||||
NavigationDrawerItem(
|
||||
label = {
|
||||
Row {
|
||||
/*
|
||||
Icon(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
imageVector = MaterialIcons.Filled.Login,
|
||||
imageVector = ,
|
||||
contentDescription = "Login Icon"
|
||||
)
|
||||
*/
|
||||
Text(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
text = "Login"
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.onClick
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
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 androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import com.composables.icons.materialicons.MaterialIcons
|
||||
import com.composables.icons.materialicons.filled.Menu
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
import dev.geekback.dopewars.shared.Locations
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import dev.geekback.dopewars.shared.api.TravelRequest
|
||||
|
||||
class TravelUi {
|
||||
/*
|
||||
Wizard
|
||||
|
||||
Holds the users hand through picking a new location
|
||||
*/
|
||||
@Composable
|
||||
fun wizard(current: Player, onTicketPunched: (TravelRequest) -> Unit) {
|
||||
var stage by remember { mutableStateOf(0) }
|
||||
var pickedLocation by remember { mutableStateOf(0) }
|
||||
val locations = Locations.all
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
Window(onCloseRequest = { onTicketPunched(TravelRequest(destination = current.location)) }, title = "Select New Location") {
|
||||
Card(modifier = Modifier.padding(16.dp).fillMaxSize()) {
|
||||
Column {
|
||||
Text("Wizard")
|
||||
var index = 0;
|
||||
when (stage) {
|
||||
0 -> {
|
||||
Text(text = locations[pickedLocation].name)
|
||||
IconButton(onClick = { expanded = !expanded }) {
|
||||
Icon(MaterialIcons.Filled.Menu, contentDescription = "More options")
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
locations.forEach {
|
||||
DropdownMenuItem(
|
||||
text = { Text("$it.name / $index")},
|
||||
onClick = {
|
||||
expanded = false
|
||||
pickedLocation = (index - 1)
|
||||
println("location index to $index")
|
||||
}
|
||||
)
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Button(onClick = {
|
||||
stage += 1
|
||||
}) {
|
||||
Text("Next Step")
|
||||
}
|
||||
}
|
||||
1 -> {
|
||||
Text("Stage 1")
|
||||
Button(onClick = {
|
||||
println("Selected Location - $pickedLocation")
|
||||
onTicketPunched(TravelRequest(locations[pickedLocation]))
|
||||
}) {
|
||||
Text("Finish")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.jvmargs=-Xmx12g
|
||||
@@ -2,15 +2,19 @@
|
||||
ktor = "3.5.1"
|
||||
kotlin = "2.4.0"
|
||||
compose = "1.11.1"
|
||||
compose-material3 = "1.11.0-alpha07"
|
||||
datetime = "0.8.0"
|
||||
logback = "1.5.38"
|
||||
logback = "1.6.3"
|
||||
serialization = "1.11.0"
|
||||
kotlin-wrappers = "2026.7.7"
|
||||
|
||||
[plugins]
|
||||
compose = { id = "org.jetbrains.compose", version.ref="compose" }
|
||||
ktor = { id = "io.ktor.plugin", version.ref="ktor" }
|
||||
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref="kotlin" }
|
||||
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref="kotlin" }
|
||||
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref="kotlin"}
|
||||
|
||||
[libraries]
|
||||
# KotlinX Modules
|
||||
@@ -34,3 +38,10 @@ ktor-server-logging = { group = "io.ktor", name="ktor-server-call-logging", vers
|
||||
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
|
||||
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref="ktor" }
|
||||
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref="ktor" }
|
||||
# Compose Extras
|
||||
compose-icons-material = { group = "com.composables", name="icons-material-icons-filled-cmp", version="2.2.1" }
|
||||
compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose" }
|
||||
wrappers-browser = { module = "org.jetbrains.kotlin-wrappers:kotlin-browser", version.ref = "kotlin-wrappers" }
|
||||
compose-material3 = { group = "org.jetbrains.compose.material3", name = "material3", version.ref = "compose-material3" }
|
||||
compose-runtime = { group = "org.jetbrains.compose.runtime", name="runtime", version.ref="compose" }
|
||||
compose-foundation = { group = "org.jetbrains.compose.foundation", name="foundation", version.ref="compose"}
|
||||
|
||||
+43
-18
@@ -4,9 +4,19 @@ plugins {
|
||||
application
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
/*
|
||||
* Files supplied by the web project.
|
||||
*
|
||||
* This configuration is resolvable by this project but isn't itself
|
||||
* published for other projects to consume.
|
||||
*/
|
||||
val webFiles = configurations.create("webFiles")
|
||||
/*
|
||||
{
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
}
|
||||
*/
|
||||
|
||||
dependencies {
|
||||
// Ktor
|
||||
@@ -22,7 +32,12 @@ dependencies {
|
||||
// Logging
|
||||
implementation(libs.ktor.server.logging)
|
||||
implementation(libs.logback)
|
||||
|
||||
// Swagger/OpenAPI
|
||||
implementation(libs.ktor.server.swagger)
|
||||
implementation(libs.ktor.server.openapi)
|
||||
implementation(libs.ktor.server.routing.openapi)
|
||||
implementation(libs.ktor.server.content.negotiation)
|
||||
|
||||
// Testing
|
||||
testImplementation(libs.ktor.server.test.host)
|
||||
@@ -31,29 +46,39 @@ dependencies {
|
||||
// Websockets
|
||||
implementation(libs.ktor.server.websockets)
|
||||
|
||||
// Swagger/OpenAPI
|
||||
implementation(libs.ktor.server.openapi)
|
||||
implementation(libs.ktor.server.routing.openapi)
|
||||
implementation(libs.ktor.server.content.negotiation)
|
||||
|
||||
// General Use
|
||||
implementation(libs.kotlinx.datetime)
|
||||
|
||||
// Shared application code
|
||||
implementation(project(":shared"))
|
||||
implementation("ch.qos.logback:logback-classic:1.6.3")
|
||||
|
||||
/*
|
||||
* Web application's generated files.
|
||||
*
|
||||
* This is a build-time dependency, not a runtime dependency.
|
||||
* The web project exposes the files through its webDistribution
|
||||
* outgoing configuration.
|
||||
*/
|
||||
webFiles(project(path = ":web", configuration = "webDistribution"))
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass = "dev.geekback.dopewars.server.ServerKt"
|
||||
}
|
||||
//
|
||||
//// Copy the JS+HTML from web to here
|
||||
//tasks.processResources {
|
||||
// dependsOn(":web:wasmJsBrowserProductionWebpack")
|
||||
//
|
||||
// from(project(":web")
|
||||
// .layout
|
||||
// .buildDirectory
|
||||
// .dir("dist/js/productionExecutable"))
|
||||
//}
|
||||
|
||||
/*
|
||||
* Copy the web distribution into the server's resources.
|
||||
*
|
||||
* The files will end up at:
|
||||
*
|
||||
* server/build/resources/main/web/
|
||||
*
|
||||
* and therefore inside the server JAR at:
|
||||
*
|
||||
* web/
|
||||
*/
|
||||
tasks.processResources {
|
||||
from(webFiles) {
|
||||
into("web")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Swagger Codegen Ignore
|
||||
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1 @@
|
||||
3.0.81
|
||||
File diff suppressed because one or more lines are too long
@@ -68,7 +68,7 @@ fun Application.module() {
|
||||
*/
|
||||
}
|
||||
|
||||
staticResources("/", "")
|
||||
staticResources("/", "web")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<html>
|
||||
<body><h1>This is the default page.</h1></body>
|
||||
</html>
|
||||
+5
-1
@@ -1,5 +1,7 @@
|
||||
import org.gradle.api.initialization.resolve.RepositoriesMode
|
||||
|
||||
rootProject.name = "dopewars"
|
||||
include(":shared", ":server", ":desktop")
|
||||
include(":shared", ":shared_ui", ":server", ":desktop", ":web")
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
@@ -10,6 +12,8 @@ pluginManagement {
|
||||
}
|
||||
|
||||
dependencyResolutionManagement {
|
||||
// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
|
||||
+14
-6
@@ -1,21 +1,29 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
plugins {
|
||||
// kotlin("multiplatform")
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
@OptIn(ExperimentalWasmDsl::class)
|
||||
wasmJs {
|
||||
browser()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(libs.kotlinx.serialization)
|
||||
implementation(libs.kotlinx.datetime)
|
||||
}
|
||||
|
||||
wasmJsMain.dependencies {
|
||||
implementation(libs.wrappers.browser)
|
||||
}
|
||||
|
||||
jvmMain.dependencies {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
@file:OptIn(ExperimentalWasmDsl::class)
|
||||
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
wasmJs {
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(project(":shared"))
|
||||
implementation(libs.compose.material3)
|
||||
implementation(libs.compose.runtime)
|
||||
implementation(libs.compose.foundation)
|
||||
implementation(libs.compose.ui)
|
||||
}
|
||||
|
||||
wasmJsMain.dependencies {
|
||||
implementation(libs.wrappers.browser)
|
||||
}
|
||||
|
||||
jvmMain.dependencies {}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package dev.geekback.dopewars.desktop
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.border
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.shared.DrugInfo
|
||||
import dev.geekback.dopewars.ui.api.ApiUi
|
||||
|
||||
interface DopeWarsModelUi<T> {
|
||||
@@ -0,0 +1,85 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
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 androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.geekback.dopewars.shared.Locations
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import dev.geekback.dopewars.shared.api.TravelRequest
|
||||
|
||||
class TravelUi {
|
||||
/*
|
||||
Wizard
|
||||
|
||||
Holds the users hand through picking a new location
|
||||
*/
|
||||
@Composable
|
||||
fun wizard(current: Player, onTicketPunched: (TravelRequest) -> Unit) {
|
||||
var stage by remember { mutableStateOf(0) }
|
||||
var pickedLocation by remember { mutableStateOf(0) }
|
||||
val locations = Locations.all
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
// Window(onCloseRequest = { onTicketPunched(TravelRequest(destination = current.location)) }, title = "Select New Location") {
|
||||
/*
|
||||
Card(modifier = Modifier.padding(16.dp).fillMaxSize()) {
|
||||
Column {
|
||||
Text("Wizard")
|
||||
var index = 0;
|
||||
when (stage) {
|
||||
0 -> {
|
||||
Text(text = locations[pickedLocation].name)
|
||||
IconButton(onClick = { expanded = !expanded }) {
|
||||
// Icon(MaterialIcons.Filled.Menu, contentDescription = "More options")
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
locations.forEach {
|
||||
DropdownMenuItem(
|
||||
text = { Text("$it.name / $index")},
|
||||
onClick = {
|
||||
expanded = false
|
||||
pickedLocation = (index - 1)
|
||||
println("location index to $index")
|
||||
}
|
||||
)
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Button(onClick = {
|
||||
stage += 1
|
||||
}) {
|
||||
Text("Next Step")
|
||||
}
|
||||
}
|
||||
1 -> {
|
||||
Text("Stage 1")
|
||||
Button(onClick = {
|
||||
println("Selected Location - $pickedLocation")
|
||||
onTicketPunched(TravelRequest(locations[pickedLocation]))
|
||||
}) {
|
||||
Text("Finish")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
// }
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -9,8 +9,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.api.MarketRequest
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.ui.LocationUi
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package dev.geekback.dopewars.ui.api
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.api.MarketResult
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.ui.MarketUi
|
||||
|
||||
+1
-1
@@ -3,9 +3,9 @@ package dev.geekback.dopewars.ui.api
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.shared.api.PlayerNameUpdateRequest
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
|
||||
class PlayerNameUpdateRequestUi(): DopeWarsModelUi<PlayerNameUpdateRequest> {
|
||||
@Composable
|
||||
+1
-1
@@ -1,10 +1,10 @@
|
||||
package dev.geekback.dopewars.ui.api
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.ui.PlayerUi
|
||||
import dev.geekback.dopewars.shared.api.PlayerNameUpdateResponse
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
|
||||
class PlayerNameUpdateResponseUi: DopeWarsModelUi<PlayerNameUpdateResponse> {
|
||||
@Composable
|
||||
+1
-1
@@ -8,8 +8,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.api.TradeRequest
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
|
||||
class TradeRequestUi: DopeWarsModelUi<TradeRequest> {
|
||||
+1
-1
@@ -2,9 +2,9 @@ package dev.geekback.dopewars.ui.api
|
||||
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.shared.api.TravelRequest
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
|
||||
class TravelRequestUi: DopeWarsModelUi<TravelRequest> {
|
||||
@Composable
|
||||
+12
-10
@@ -8,8 +8,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.api.TravelResult
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.ui.LocationUi
|
||||
import dev.geekback.dopewars.ui.MarketUi
|
||||
@@ -38,15 +38,17 @@ class TravelResponseUi: DopeWarsModelUi<TravelResult> {
|
||||
println("Update location to $it")
|
||||
}
|
||||
|
||||
Row {
|
||||
Button(onClick = {}) {
|
||||
Text("Apply")
|
||||
}
|
||||
|
||||
Button(onClick = {}) {
|
||||
Text("Cancel")
|
||||
}
|
||||
}
|
||||
//
|
||||
//
|
||||
// Row {
|
||||
// Button(onClick = {}) {
|
||||
// Text("Apply")
|
||||
// }
|
||||
//
|
||||
// Button(onClick = {}) {
|
||||
// Text("Cancel")
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
-2
@@ -3,7 +3,6 @@ package dev.geekback.dopewars.ui
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.RangeSlider
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
@@ -13,7 +12,6 @@ import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.DRUG_MAX_PRICE
|
||||
import dev.geekback.dopewars.shared.Drug
|
||||
import dev.geekback.dopewars.shared.DrugInfo
|
||||
-1
@@ -3,7 +3,6 @@ package dev.geekback.dopewars.ui
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.InventoryItem
|
||||
|
||||
class InventoryUi: DopeWarsModelUi<List<InventoryItem>> {
|
||||
-1
@@ -10,7 +10,6 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
|
||||
class LocationUi: DopeWarsModelUi<Location> {
|
||||
-1
@@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.Market
|
||||
|
||||
class MarketUi: DopeWarsModelUi<Market> {
|
||||
-3
@@ -4,9 +4,6 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.geekback.dopewars.desktop.BorderedCard
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
import dev.geekback.dopewars.shared.Market
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import kotlin.time.Instant
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
alias(libs.plugins.compose)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
@OptIn(ExperimentalWasmDsl::class)
|
||||
wasmJs {
|
||||
browser()
|
||||
binaries.executable()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(project(":shared"))
|
||||
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material3)
|
||||
implementation(compose.ui)
|
||||
}
|
||||
|
||||
wasmJsMain.dependencies {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The directory produced by wasmJsBrowserDistribution.
|
||||
*
|
||||
* This is deliberately kept here rather than being referenced by
|
||||
* the server project. The web project owns its build layout.
|
||||
*/
|
||||
val webDistributionDirectory =
|
||||
layout.buildDirectory.dir("dist/wasmJs/productionExecutable")
|
||||
|
||||
/*
|
||||
* Expose the web distribution as an outgoing artifact.
|
||||
*
|
||||
* Other projects can consume:
|
||||
*
|
||||
* project(path = ":web", configuration = "webDistribution")
|
||||
*
|
||||
* without knowing where the files actually live.
|
||||
*/
|
||||
val webDistributionTask =
|
||||
tasks.named("wasmJsBrowserDistribution")
|
||||
|
||||
configurations {
|
||||
create("webDistribution") {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add(
|
||||
"webDistribution",
|
||||
webDistributionDirectory
|
||||
) {
|
||||
builtBy(webDistributionTask)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KotlinProject</title>
|
||||
<link type="text/css" rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body style="text-align: center; align-content: center">
|
||||
<h1>Web Client HTML</h1>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 50 50" role="presentation">
|
||||
<circle cx="25" cy="25" r="20" stroke="#ccc" stroke-width="4" fill="none"/>
|
||||
<circle cx="25" cy="25" r="20" stroke="#333" stroke-width="4" fill="none" stroke-linecap="round"
|
||||
stroke-dasharray="90 125">
|
||||
<animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s"
|
||||
repeatCount="indefinite"/>
|
||||
</circle>
|
||||
</svg>
|
||||
<script type="application/javascript" src="web.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.geekback.dopewars.web
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.ComposeViewport
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun main() {
|
||||
ComposeViewport {
|
||||
App()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun App() {
|
||||
MaterialTheme {
|
||||
Text(modifier = Modifier.padding(16.dp), text = "Taxation is theft")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KotlinProject</title>
|
||||
<link type="text/css" rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body style="text-align: center; align-content: center">
|
||||
<h1>Web Client HTML</h1>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 50 50" role="presentation">
|
||||
<circle cx="25" cy="25" r="20" stroke="#ccc" stroke-width="4" fill="none"/>
|
||||
<circle cx="25" cy="25" r="20" stroke="#333" stroke-width="4" fill="none" stroke-linecap="round"
|
||||
stroke-dasharray="90 125">
|
||||
<animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s"
|
||||
repeatCount="indefinite"/>
|
||||
</circle>
|
||||
</svg>
|
||||
<script type="application/javascript" src="web.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
Reference in New Issue
Block a user