diff options
author | joffrey-bion <joffrey.bion@gmail.com> | 2020-11-29 15:40:24 +0100 |
---|---|---|
committer | joffrey-bion <joffrey.bion@gmail.com> | 2020-11-29 15:40:24 +0100 |
commit | 79e831435e47b15f418f12f6a4ed899d7d1e3e04 (patch) | |
tree | f69a97bbe1ac351350d258957d333c930d8f5de7 /sw-ui | |
parent | Add support for Icon intent in bpDialog (diff) | |
download | seven-wonders-79e831435e47b15f418f12f6a4ed899d7d1e3e04.tar.gz seven-wonders-79e831435e47b15f418f12f6a4ed899d7d1e3e04.tar.bz2 seven-wonders-79e831435e47b15f418f12f6a4ed899d7d1e3e04.zip |
Add fatal error dialog support
Diffstat (limited to 'sw-ui')
4 files changed, 85 insertions, 0 deletions
diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/Application.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/Application.kt index b1244b5c..a4cdba78 100644 --- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/Application.kt +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/Application.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.ui.components +import org.luxons.sevenwonders.ui.components.errors.errorDialog import org.luxons.sevenwonders.ui.components.game.gameScene import org.luxons.sevenwonders.ui.components.gameBrowser.gameBrowser import org.luxons.sevenwonders.ui.components.home.home @@ -12,6 +13,7 @@ import react.router.dom.route import react.router.dom.switch fun RBuilder.application() = hashRouter { + errorDialog() switch { route(Route.GAME_BROWSER.path) { gameBrowser() } route(Route.GAME.path) { gameScene() } diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/errors/ErrorDialog.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/errors/ErrorDialog.kt new file mode 100644 index 00000000..cb35ef54 --- /dev/null +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/errors/ErrorDialog.kt @@ -0,0 +1,74 @@ +package org.luxons.sevenwonders.ui.components.errors + +import com.palantir.blueprintjs.Classes +import com.palantir.blueprintjs.Intent +import com.palantir.blueprintjs.bpButton +import com.palantir.blueprintjs.bpDialog +import kotlinx.browser.window +import org.luxons.sevenwonders.ui.redux.* +import org.luxons.sevenwonders.ui.router.Navigate +import org.luxons.sevenwonders.ui.router.Route +import react.RBuilder +import react.RComponent +import react.RProps +import react.RState +import react.dom.p +import styled.css +import styled.styledDiv + +interface ErrorDialogStateProps : RProps { + var errorMessage: String? +} + +interface ErrorDialogDispatchProps : RProps { + var goHome: () -> Unit +} + +interface ErrorDialogProps : ErrorDialogDispatchProps, ErrorDialogStateProps + +class ErrorDialogPresenter(props: ErrorDialogProps) : RComponent<ErrorDialogProps, RState>(props) { + override fun RBuilder.render() { + val errorMessage = props.errorMessage + bpDialog( + isOpen = errorMessage != null, + title = "Oops!", + icon = "error", + iconIntent = Intent.DANGER, + onClose = { goHomeAndRefresh() } + ) { + styledDiv { + css { + classes.add(Classes.DIALOG_BODY) + } + p { + +(errorMessage ?: "fatal error") + } + } + styledDiv { + css { + classes.add(Classes.DIALOG_FOOTER) + } + bpButton(icon = "log-out", onClick = { goHomeAndRefresh() }) { + +"HOME" + } + } + } + } +} + +private fun goHomeAndRefresh() { + // we don't use a redux action here because we actually want to redirect and refresh the page + window.location.href = Route.HOME.path +} + +fun RBuilder.errorDialog() = errorDialog {} + +private val errorDialog = connectStateAndDispatch<ErrorDialogStateProps, ErrorDialogDispatchProps, ErrorDialogProps>( + clazz = ErrorDialogPresenter::class, + mapStateToProps = { state, _ -> + errorMessage = state.fatalError + }, + mapDispatchToProps = { dispatch, _ -> + goHome = { dispatch(Navigate(Route.HOME)) } + }, +) diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Actions.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Actions.kt index 951f4f2a..cd9443df 100644 --- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Actions.kt +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Actions.kt @@ -7,6 +7,8 @@ import org.luxons.sevenwonders.model.api.LobbyDTO import org.luxons.sevenwonders.model.cards.PreparedCard import redux.RAction +data class FatalError(val message: String) : RAction + data class SetCurrentPlayerAction(val player: ConnectedPlayer) : RAction data class UpdateGameListAction(val games: List<LobbyDTO>) : RAction diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt index 3de763b4..7789cabb 100644 --- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt @@ -18,6 +18,7 @@ data class SwState( val gamesById: Map<Long, LobbyDTO> = emptyMap(), val currentLobby: LobbyDTO? = null, val gameState: GameState? = null, + val fatalError: String? = null, ) { val currentPlayer: PlayerDTO? = (gameState?.players ?: currentLobby?.players)?.first { it.username == connectedPlayer?.username @@ -48,6 +49,7 @@ fun rootReducer(state: SwState, action: RAction): SwState = state.copy( connectedPlayer = currentPlayerReducer(state.connectedPlayer, action), currentLobby = currentLobbyReducer(state.currentLobby, action), gameState = gameStateReducer(state.gameState, action), + fatalError = connectionLostReducer(action), ) private fun gamesReducer(games: Map<Long, LobbyDTO>, action: RAction): Map<Long, LobbyDTO> = when (action) { @@ -95,3 +97,8 @@ private fun gameStateReducer(gameState: GameState?, action: RAction): GameState? is RequestPrepareMove -> gameState?.copy(transactionSelector = null) else -> gameState } + +private fun connectionLostReducer(action: RAction): String? = when (action) { + is FatalError -> action.message + else -> null +} |