diff --git a/app/controllers/Round.scala b/app/controllers/Round.scala index a7ef767327..954091fc14 100644 --- a/app/controllers/Round.scala +++ b/app/controllers/Round.scala @@ -70,6 +70,7 @@ object Round extends LilaController { def drawOffer(fullId: String) = performAndRedirect(fullId, hand.drawOffer) def drawCancel(fullId: String) = performAndRedirect(fullId, hand.drawCancel) def drawDecline(fullId: String) = performAndRedirect(fullId, hand.drawDecline) + def rematch(fullId: String) = Action { rematcher offerOrAccept fullId flatMap { validResult ⇒ validResult.fold( @@ -83,8 +84,9 @@ object Round extends LilaController { ) } unsafePerformIO } - def rematchCancel(fullId: String) = TODO - def rematchDecline(fullId: String) = TODO + def rematchCancel(fullId: String) = performAndRedirect(fullId, hand.rematchCancel) + def rematchDecline(fullId: String) = performAndRedirect(fullId, hand.rematchDecline) + def takebackAccept(fullId: String) = performAndRedirect(fullId, hand.takebackAccept) def takebackOffer(fullId: String) = performAndRedirect(fullId, hand.takebackOffer) def takebackCancel(fullId: String) = performAndRedirect(fullId, hand.takebackCancel) diff --git a/app/round/Hand.scala b/app/round/Hand.scala index b51e881130..6853eae19d 100644 --- a/app/round/Hand.scala +++ b/app/round/Hand.scala @@ -127,23 +127,33 @@ final class Hand( else !!("no draw offer to decline " + fullId) }) - def rematch(fullId: String): IO[Valid[(String, List[Event])]] = - attempt(fullId, { - case pov @ Pov(game, color) if game playerCanRematch color ⇒ - if (game.opponent(color).isOfferingRematch) success { - game.nextId.fold( - nextId ⇒ io(nextId -> Nil), - io(fullId -> Nil) // accept - ) - } - else success { - val progress = Progress(game, Event.ReloadTable(!color)) map { g ⇒ - g.updatePlayer(color, _.offerRematch) + def rematchCancel(fullId: String): IO[Valid[List[Event]]] = attempt(fullId, { + case pov @ Pov(g1, color) ⇒ + pov.player.isOfferingRematch.fold( + success(for { + p1 ← messenger.systemMessages(g1, "Rematch offer canceled") map { es ⇒ + Progress(g1, Event.ReloadTable(!color) :: es) } - gameRepo save progress map { _ ⇒ fullId -> progress.events } - } - case _ ⇒ !!("invalid rematch offer " + fullId) - }) + p2 = p1 map { g ⇒ g.updatePlayer(color, _.removeRematchOffer) } + _ ← gameRepo save p2 + } yield p2.events), + !!("no rematch offer to cancel " + fullId) + ) + }) + + def rematchDecline(fullId: String): IO[Valid[List[Event]]] = attempt(fullId, { + case pov @ Pov(g1, color) ⇒ + g1.player(!color).isOfferingRematch.fold( + success(for { + p1 ← messenger.systemMessages(g1, "Rematch offer declined") map { es ⇒ + Progress(g1, Event.ReloadTable(!color) :: es) + } + p2 = p1 map { g ⇒ g.updatePlayer(!color, _.removeRematchOffer) } + _ ← gameRepo save p2 + } yield p2.events), + !!("no rematch offer to decline " + fullId) + ) + }) def takebackAccept(fullId: String): IOValidEvents = fromPov(fullId) { pov ⇒ if (pov.opponent.isProposingTakeback) for { diff --git a/app/setup/Rematcher.scala b/app/setup/Rematcher.scala index db12634640..22b3e0ea4d 100644 --- a/app/setup/Rematcher.scala +++ b/app/setup/Rematcher.scala @@ -20,7 +20,7 @@ final class Rematcher( def offerOrAccept(fullId: String): IO[Valid[(String, List[Event])]] = attempt(fullId, { case pov @ Pov(game, color) if game playerCanRematch color ⇒ - if (game.opponent(color).isOfferingRematch) success { + success(game.opponent(color).isOfferingRematch.fold( game.nextId.fold( nextId ⇒ io(nextId -> Nil), for { @@ -39,13 +39,12 @@ final class Rematcher( Event.ReloadTable(White), Event.ReloadTable(Black)) ) - } - else success { + , { val progress = Progress(game, Event.ReloadTable(!color)) map { g ⇒ g.updatePlayer(color, _.offerRematch) } gameRepo save progress map { _ ⇒ fullId -> progress.events } - } + })) case _ ⇒ !!("invalid rematch offer " + fullId) })