Skip to content
Snippets Groups Projects
Commit db0d8c9e authored by Tóth Miklós Tibor's avatar Tóth Miklós Tibor :shrug:
Browse files

Improve UI

parent 2189bb26
No related branches found
No related tags found
No related merge requests found
import androidx.compose.runtime.*
import api.MachineKind
import app.softwork.bootstrapcompose.*
import app.softwork.bootstrapcompose.Color
import components.*
......@@ -12,6 +13,7 @@ import org.jetbrains.compose.web.renderComposable
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.get
import org.w3c.dom.set
import styles.FloorStyle
import styles.LocalStyle
import styles.Style
......@@ -47,7 +49,23 @@ fun main() {
DomSideEffect {
it.setImportantBg(mosogepStyle.colors.surface)
}
Div(
attrs = {
style {
display(DisplayStyle.Flex)
flexDirection(FlexDirection.Row)
gap(.5.em)
alignItems(AlignItems.Center)
}
}
) {
icon(
src = MachineKind.Washer.toIcon(),
color = mosogepStyle.colors.onSurface,
width = 1.5.em
)
Text("MosógépSCH")
}
switch(
label = "Sötét téma",
value = mosogepStyle.dark,
......
package components
import styles.LocalStyle
import androidx.compose.runtime.*
import api.Floor
import api.Machine
import api.MachineKind
import api.MachineStatus
import localization.LocalLang
import localization.machineKind
import localization.machineStatus
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.*
import styles.ColorPair
import styles.applyColorPair
object FloorStyle: StyleSheet() {
val container by style {
display(DisplayStyle.Flex)
flexDirection(FlexDirection.Column)
justifyContent(JustifyContent.SpaceAround)
alignItems(AlignItems.Center)
position(Position.Relative)
}
val card by style {
maxWidth(20.em)
width(20.em)
flexDirection(FlexDirection.Row)
justifyContent(JustifyContent.SpaceAround)
property("box-shadow", "0 0 .7em #00000033")
}
val floorNum by style {
minWidth(2.75.ch)
marginBottom(0.px)
textAlign("right")
}
val machine by style {
flexGrow(1)
cursor("pointer")
}
val absCnt by style {
position(Position.Absolute)
left(0.px)
bottom(4.em)
width(0.px)
height(0.px)
property("z-index", -1)
}
val relCnt by style {
position(Position.Relative)
width(0.px)
height(0.px)
}
val underflowCnt by style {
margin(0.px)
padding(1.em)
paddingTop(0.em)
width(22.em)
overflow("hidden")
property("transition", "${styles.Style.baseTransition}, max-height 0.75s")
}
val underflowCard by style {
justifyContent(JustifyContent.SpaceBetween)
flexDirection(FlexDirection.Row)
gap(1.5.em)
padding(1.5.em)
margin(0.px)
width(100.percent)
paddingTop(5.em)
property("transition", "${styles.Style.baseTransition}, box-shadow 0.5s")
property("box-shadow", "0 0 1em #00000044")
}
val infoDiv by style {
display(DisplayStyle.Flex)
flexDirection(FlexDirection.Column)
flexGrow(1)
}
}
import styles.FloorStyle
@Composable
fun floor(floor: Floor, selectedMachine: Machine?, setMachine: (Machine?)->Unit) {
val lang = LocalLang.current
val colors = LocalStyle.current.colors
fun MachineStatus.toColor(): ColorPair = when (this) {
MachineStatus.Available -> ColorPair(colors.primary, colors.onPrimary)
MachineStatus.NotAvailable -> ColorPair(colors.error, colors.onError)
}
fun MachineStatus.toUnderColor(): ColorPair = when (this) {
MachineStatus.Available -> ColorPair(colors.primaryContainer, colors.onPrimaryContainer)
MachineStatus.NotAvailable -> ColorPair(colors.errorContainer, colors.onErrorContainer)
}
fun MachineKind.toIcon(): String = when (this) {
MachineKind.Washer -> "washer.svg"
MachineKind.Dryer -> "fan.svg"
}
val zIndex = 200 - floor.id*2
Div(attrs = {
......@@ -107,43 +17,7 @@ fun floor(floor: Floor, selectedMachine: Machine?, setMachine: (Machine?)->Unit)
property("z-index", zIndex)
}
}) {
card(attrs = {
classes(FloorStyle.card)
style {
backgroundColor(colors.surfaceVariant)
color(colors.onSurfaceVariant)
}
}) {
H3(attrs = {
classes(FloorStyle.floorNum)
}) { Text("${floor.id}.") }
floor.machines.forEach { machine ->
card(attrs = {
classes(FloorStyle.machine)
style {
applyColorPair(machine.status.toColor())
}
onClick {
if (selectedMachine == machine) {
setMachine(null)
} else {
setMachine(machine)
}
}
}) {
Div(
attrs = {
style {
backgroundColor(machine.status.toColor().fg)
property("mask", "url(/${machine.kindOf.toIcon()}) no-repeat center / contain")
height(2.em)
width(2.em)
}
}
) {}
}
}
}
FloorCard(floor, selectedMachine, setMachine)
floor.machines.forEach { machine ->
Div(attrs = {
......@@ -156,39 +30,13 @@ fun floor(floor: Floor, selectedMachine: Machine?, setMachine: (Machine?)->Unit)
classes(FloorStyle.underflowCnt)
style {
if (selectedMachine == machine) {
maxHeight(20.em)
maxHeight(22.em)
} else {
maxHeight(0.px)
}
}
}) {
card(attrs = {
classes(FloorStyle.underflowCard)
style {
applyColorPair(machine.status.toUnderColor())
if (selectedMachine != machine) {
property("box-shadow", "none")
}
}
}) {
Div(
attrs = {
style {
backgroundColor(machine.status.toUnderColor().fg)
property("mask", "url(/${machine.kindOf.toIcon()}) no-repeat center / contain")
height(2.em)
width(2.em)
}
}
) {}
Div(attrs = {
classes(FloorStyle.infoDiv)
}) {
H5 { Text("${lang.machineKind(machine.kindOf)} ${lang.floorFormat(floor.id)}") }
P { Text("${lang.lastUpdated} ${lang.formatInstant(machine.lastQueryTime)}") }
P { Text(lang.machineStatus(machine.status)) }
}
}
underCard(floor, machine, selectedMachine)
}
}
}
......
package components
import androidx.compose.runtime.Composable
import api.Floor
import api.Machine
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.H3
import org.jetbrains.compose.web.dom.Text
import styles.FloorStyle
import styles.LocalStyle
import styles.applyColorPair
@Composable
fun FloorCard(floor: Floor, selectedMachine: Machine?, setMachine: (Machine?)->Unit) {
val colors = LocalStyle.current.colors
card(attrs = {
classes(FloorStyle.card)
style {
backgroundColor(colors.surfaceVariant)
color(colors.onSurfaceVariant)
}
}) {
H3(attrs = {
classes(FloorStyle.floorNum)
}) { Text("${floor.id}.") }
floor.machines.forEach { machine ->
val cardColor = machine.status.toColor()
card(attrs = {
classes(FloorStyle.machine)
style {
applyColorPair(cardColor)
}
onClick {
if (selectedMachine == machine) {
setMachine(null)
} else {
setMachine(machine)
}
}
}) {
icon(
src = machine.kindOf.toIcon(),
color = cardColor.fg,
width = 2.em
)
}
}
}
}
\ No newline at end of file
package components
import androidx.compose.runtime.Composable
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.Div
@Composable
fun icon(
src: String,
color: CSSColorValue,
width: CSSNumeric,
height: CSSNumeric = width,
) {
Div(
attrs = {
style {
backgroundColor(color)
property("mask", "url($src) no-repeat center / contain")
property("-webkit-mask", "url($src) no-repeat center / contain")
height(height)
width(width)
}
}
) {}
}
\ No newline at end of file
package components
import androidx.compose.runtime.*
import api.Floor
import api.Machine
import localization.LocalLang
import localization.machineKind
import localization.machineStatus
import org.jetbrains.compose.web.dom.H5
import org.jetbrains.compose.web.dom.P
import org.jetbrains.compose.web.dom.Text
import styles.ColorPair
import styles.FloorStyle
import styles.LocalStyle
import styles.applyColorPair
@Composable
fun underCard(floor: Floor, machine: Machine, selectedMachine: Machine?) {
val lang = LocalLang.current
val cardColor = machine.status.toUnderColor()
val subbedColor = subbedColor()
val unsubbedColor = unsubbedColor()
card(attrs = {
classes(FloorStyle.underflowCard)
style {
applyColorPair(cardColor)
if (selectedMachine != machine) {
property("box-shadow", "none")
}
}
}) {
H5 { Text("${lang.machineKind(machine.kindOf)} ${lang.floorFormat(floor.id)}") }
P { Text("${lang.lastUpdated} ${lang.formatInstant(machine.lastQueryTime)}") }
P { Text(lang.machineStatus(machine.status)) }
var subbed by remember { mutableStateOf(false) }
card(attrs = {
classes(FloorStyle.subBtn)
onClick { subbed = !subbed }
style {
applyColorPair(if (subbed) subbedColor else unsubbedColor)
}
}) {
// TODO place icon
Text(if (subbed) lang.unsub else lang.sub)
}
}
}
\ No newline at end of file
package components
import androidx.compose.runtime.Composable
import api.MachineKind
import api.MachineStatus
import styles.ColorPair
import styles.LocalStyle
@Composable
fun MachineStatus.toColor(): ColorPair {
val colors = LocalStyle.current.colors
return when (this) {
MachineStatus.Available -> ColorPair(colors.primary, colors.onPrimary)
MachineStatus.NotAvailable -> ColorPair(colors.error, colors.onError)
}
}
@Composable
fun MachineStatus.toUnderColor(): ColorPair {
val colors = LocalStyle.current.colors
return when (this) {
MachineStatus.Available -> ColorPair(colors.primaryContainer, colors.onPrimaryContainer)
MachineStatus.NotAvailable -> ColorPair(colors.errorContainer, colors.onErrorContainer)
}
}
fun MachineKind.toIcon(): String {
return when (this) {
MachineKind.Washer -> "washer.svg"
MachineKind.Dryer -> "fan.svg"
}
}
@Composable
fun subbedColor(): ColorPair {
val colors = LocalStyle.current.colors
return ColorPair(colors.error, colors.onError)
}
@Composable
fun unsubbedColor(): ColorPair {
val colors = LocalStyle.current.colors
return ColorPair(colors.primary, colors.onPrimary)
}
\ No newline at end of file
......@@ -17,6 +17,9 @@ abstract class Localization {
open val lastUpdated = "Last updated"
open val daysAgo = "days ago"
open val sub = "Subscribe"
open val unsub = "Unsubscribe"
protected open fun timeFormat(dateTime: LocalDateTime): String = "at ${dateTime.hour.padded()}:${dateTime.minute.padded()}"
open fun floorFormat(floor: Int) = "on floor $floor"
......@@ -26,7 +29,6 @@ abstract class Localization {
val dateTime = instant.toLocalDateTime(tz)
val now = Clock.System.now()
val diff = now - instant
println(diff.toString())
if (diff < Duration.Companion.days(1)) {
return timeFormat(dateTime)
}
......
......@@ -12,6 +12,9 @@ class Hungarian: Localization() {
override val lastUpdated = "Utoljára frissítve"
override val daysAgo = "napja"
override val sub = "Feliratkozás"
override val unsub = "Leiratkozás"
override fun timeFormat(dateTime: LocalDateTime): String = "${dateTime.hour.padded()}:${dateTime.minute.padded()}-kor"
override fun floorFormat(floor: Int): String {
val nevelo = when(floor) {
......
package styles
import org.jetbrains.compose.web.css.*
object FloorStyle: StyleSheet() {
val container by style {
display(DisplayStyle.Flex)
flexDirection(FlexDirection.Column)
justifyContent(JustifyContent.SpaceAround)
alignItems(AlignItems.Center)
position(Position.Relative)
}
val card by style {
maxWidth(20.em)
width(20.em)
flexDirection(FlexDirection.Row)
justifyContent(JustifyContent.SpaceAround)
property("box-shadow", "0 0 .7em #00000033")
}
val floorNum by style {
minWidth(2.75.ch)
marginBottom(0.px)
textAlign("right")
}
val machine by style {
flexGrow(1)
cursor("pointer")
}
val absCnt by style {
position(Position.Absolute)
left(0.px)
bottom(4.em)
width(0.px)
height(0.px)
property("z-index", -1)
}
val relCnt by style {
position(Position.Relative)
width(0.px)
height(0.px)
}
val underflowCnt by style {
margin(0.px)
padding(1.em)
paddingTop(0.em)
width(22.em)
overflow("hidden")
property("transition", "${Style.baseTransition}, max-height 0.75s")
}
val underflowCard by style {
flexDirection(FlexDirection.Column)
justifyContent(JustifyContent.FlexStart)
alignItems(AlignItems.Stretch)
padding(1.5.em)
margin(0.px)
width(100.percent)
paddingTop(5.em)
property("transition", "${Style.baseTransition}, box-shadow 0.5s")
property("box-shadow", "0 0 1em #00000044")
}
val subBtn by style {
cursor("pointer")
}
}
\ No newline at end of file
......@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8">
<title>MosógépSCH</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment