summaryrefslogtreecommitdiff
path: root/sw-ui
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@booking.com>2020-07-01 02:47:48 +0200
committerJoffrey Bion <joffrey.bion@booking.com>2020-07-01 02:47:48 +0200
commitb18eb71559a1fc2db628a96fee02ba1e81073559 (patch)
treec85c567771531c8fe34cadd6a0c2bb3e53786d81 /sw-ui
parentKeep wonders associated to the same player when reordering players (diff)
downloadseven-wonders-b18eb71559a1fc2db628a96fee02ba1e81073559.tar.gz
seven-wonders-b18eb71559a1fc2db628a96fee02ba1e81073559.tar.bz2
seven-wonders-b18eb71559a1fc2db628a96fee02ba1e81073559.zip
Use correct keys in player list to allow animations on reorder
Diffstat (limited to 'sw-ui')
-rw-r--r--sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialList.kt37
-rw-r--r--sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialPlayerList.kt50
2 files changed, 52 insertions, 35 deletions
diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialList.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialList.kt
index 10ddb2b1..e27e1cd8 100644
--- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialList.kt
+++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialList.kt
@@ -9,11 +9,11 @@ import react.ReactElement
import react.dom.*
import styled.*
-typealias ElementBuilder = RBuilder.() -> ReactElement
-
-fun RBuilder.radialList(
- itemBuilders: List<ElementBuilder>,
- centerElementBuilder: ElementBuilder,
+fun <T> RBuilder.radialList(
+ items: List<T>,
+ centerElement: ReactElement,
+ renderItem: (T) -> ReactElement,
+ getKey: (T) -> String,
itemWidth: Int,
itemHeight: Int,
options: RadialConfig = RadialConfig(),
@@ -30,13 +30,18 @@ fun RBuilder.radialList(
height = containerHeight.px
}
block()
- radialListItems(itemBuilders, options)
- radialListCenter(centerElementBuilder)
+ radialListItems(items, renderItem, getKey, options)
+ radialListCenter(centerElement)
}
}
-private fun RBuilder.radialListItems(itemBuilders: List<ElementBuilder>, radialConfig: RadialConfig): ReactElement {
- val offsets = offsetsFromCenter(itemBuilders.size, radialConfig)
+private fun <T> RBuilder.radialListItems(
+ items: List<T>,
+ renderItem: (T) -> ReactElement,
+ getKey: (T) -> String,
+ radialConfig: RadialConfig
+): ReactElement {
+ val offsets = offsetsFromCenter(items.size, radialConfig)
return styledUl {
css {
zeroMargins()
@@ -46,13 +51,13 @@ private fun RBuilder.radialListItems(itemBuilders: List<ElementBuilder>, radialC
height = radialConfig.diameter.px
absoluteCenter()
}
- itemBuilders.forEachIndexed { i, itemBuilder ->
- radialListItem(itemBuilder, i, offsets[i])
+ items.forEachIndexed { i, item ->
+ radialListItem(renderItem(item), getKey(item), offsets[i])
}
}
}
-private fun RBuilder.radialListItem(itemBuilder: ElementBuilder, i: Int, offset: CartesianCoords): ReactElement {
+private fun RBuilder.radialListItem(item: ReactElement, key: String, offset: CartesianCoords): ReactElement {
return styledLi {
css {
display = Display.block
@@ -69,13 +74,13 @@ private fun RBuilder.radialListItem(itemBuilder: ElementBuilder, i: Int, offset:
}
}
attrs {
- key = "$i"
+ this.key = key
}
- itemBuilder()
+ child(item)
}
}
-private fun RBuilder.radialListCenter(centerElement: ElementBuilder?): ReactElement? {
+private fun RBuilder.radialListCenter(centerElement: ReactElement?): ReactElement? {
if (centerElement == null) {
return null
}
@@ -84,7 +89,7 @@ private fun RBuilder.radialListCenter(centerElement: ElementBuilder?): ReactElem
zIndex = 0
absoluteCenter()
}
- centerElement()
+ child(centerElement)
}
}
diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialPlayerList.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialPlayerList.kt
index 78133f92..061d680f 100644
--- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialPlayerList.kt
+++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/lobby/RadialPlayerList.kt
@@ -5,24 +5,35 @@ import com.palantir.blueprintjs.bpIcon
import kotlinx.css.*
import org.luxons.sevenwonders.model.api.PlayerDTO
import org.luxons.sevenwonders.model.api.actions.Icon
-import react.RBuilder
-import react.ReactElement
+import react.*
import react.dom.*
import styled.css
import styled.styledDiv
import styled.styledH4
+private sealed class PlayerItem {
+ abstract val username: String
+
+ data class Player(val player: PlayerDTO) : PlayerItem() {
+ override val username = player.username
+ }
+ data class Placeholder(val index: Int) : PlayerItem() {
+ override val username = "player-placeholder-$index"
+ }
+}
+
fun RBuilder.radialPlayerList(players: List<PlayerDTO>, currentPlayer: PlayerDTO): ReactElement {
- val playerItemBuilders = players
- .growTo(targetSize = 3)
+ val playerItems = players
+ .growWithPlaceholders(targetSize = 3)
.withUserFirst(currentPlayer)
- .map { p -> p.elementBuilder(p?.username == currentPlayer.username) }
- val tableImgBuilder: ElementBuilder = { roundTableImg() }
+ val tableImg = buildElement { roundTableImg() }
return radialList(
- itemBuilders = playerItemBuilders,
- centerElementBuilder = tableImgBuilder,
+ items = playerItems,
+ centerElement = tableImg,
+ renderItem = { it.renderAsListItem(it.username == currentPlayer.username) },
+ getKey = { it.username },
itemWidth = 120,
itemHeight = 100,
options = RadialConfig(
@@ -40,25 +51,26 @@ private fun RBuilder.roundTableImg(): ReactElement = img(src = "images/round-tab
}
}
-private fun List<PlayerDTO?>.withUserFirst(me: PlayerDTO): List<PlayerDTO?> {
- val nonUsersBeginning = takeWhile { it?.username != me.username }
+private fun List<PlayerItem>.withUserFirst(me: PlayerDTO): List<PlayerItem> {
+ val nonUsersBeginning = takeWhile { (it as? PlayerItem.Player)?.player?.username != me.username }
val userToEnd = subList(nonUsersBeginning.size, size)
return userToEnd + nonUsersBeginning
}
-private fun <T> List<T>.growTo(targetSize: Int): List<T?> {
- if (size >= targetSize) return this
- return this + List(targetSize - size) { null }
-}
-
-private fun PlayerDTO?.elementBuilder(isMe: Boolean): ElementBuilder {
- if (this == null) {
- return { playerPlaceholder() }
+private fun List<PlayerDTO>.growWithPlaceholders(targetSize: Int): List<PlayerItem> {
+ val items = map { PlayerItem.Player(it) }
+ return if (size >= targetSize) {
+ items
} else {
- return { playerItem(this@elementBuilder, isMe) }
+ items + List(targetSize - size) { PlayerItem.Placeholder(size + it) }
}
}
+private fun PlayerItem.renderAsListItem(isMe: Boolean): ReactElement = when (this) {
+ is PlayerItem.Placeholder -> buildElement { playerPlaceholder() }
+ is PlayerItem.Player -> buildElement { playerItem(this@renderAsListItem.player, isMe) }
+}
+
private fun RBuilder.playerItem(player: PlayerDTO, isMe: Boolean): ReactElement = styledDiv {
css {
display = Display.flex
bgstack15