swiss WIP

swiss
Thibault Duplessis 2020-04-29 15:46:31 -06:00
parent b866d04417
commit 7ebf6234a1
11 changed files with 147 additions and 54 deletions

View File

@ -14,59 +14,50 @@ import controllers.routes
object show {
def apply(
swiss: Swiss,
s: Swiss,
data: play.api.libs.json.JsObject,
chatOption: Option[lila.chat.UserChat.Mine]
)(implicit ctx: Context): Frag = ???
// views.html.base.layout(
// title = s"${tour.name()} #${tour.id}",
// moreJs = frag(
// jsAt(s"compiled/lichess.tournament${isProd ?? (".min")}.js"),
// embedJsUnsafe(s"""lichess=lichess||{};lichess.tournament=${safeJsonValue(
// Json.obj(
// "data" -> data,
// "i18n" -> bits.jsI18n,
// "userId" -> ctx.userId,
// "chat" -> chatOption.map { c =>
// chat.json(
// c.chat,
// name = trans.chatRoom.txt(),
// timeout = c.timeout,
// public = true,
// resourceId = lila.chat.Chat.ResourceId(s"tournament/${c.chat.id}")
// )
// }
// )
// )}""")
// ),
// moreCss = cssTag {
// if (tour.isTeamBattle) "tournament.show.team-battle"
// else "tournament.show"
// },
// chessground = false,
// openGraph = lila.app.ui
// .OpenGraph(
// title = s"${tour.name()}: ${tour.variant.name} ${tour.clock.show} ${tour.mode.name} #${tour.id}",
// url = s"$netBaseUrl${routes.Tournament.show(tour.id).url}",
// description = s"${tour.nbPlayers} players compete in the ${showEnglishDate(tour.startsAt)} ${tour.name()}. " +
// s"${tour.clock.show} ${tour.mode.name} games are played during ${tour.minutes} minutes. " +
// tour.winnerId.fold("Winner is not yet decided.") { winnerId =>
// s"${usernameOrId(winnerId)} takes the prize home!"
// }
// )
// .some
// )(
// main(cls := s"tour${tour.schedule
// .?? { sched =>
// s" tour-sched tour-sched-${sched.freq.name} tour-speed-${sched.speed.name} tour-variant-${sched.variant.key} tour-id-${tour.id}"
// }}")(
// st.aside(cls := "tour__side")(
// tournament.side(tour, verdicts, streamers, shieldOwner, chatOption.isDefined)
// ),
// div(cls := "tour__main")(div(cls := "box")),
// tour.isCreated option div(cls := "tour__faq")(
// faq(tour.mode.rated.some, tour.isPrivate.option(tour.id))
// )
// )
// )
)(implicit ctx: Context): Frag =
views.html.base.layout(
title = s"${s.name} #${s.id}",
moreJs = frag(
jsAt(s"compiled/lichess.swiss${isProd ?? (".min")}.js"),
embedJsUnsafe(s"""LichessSwiss.boot(${safeJsonValue(
Json.obj(
"data" -> data,
"i18n" -> bits.jsI18n,
"userId" -> ctx.userId,
"chat" -> chatOption.map { c =>
chat.json(
c.chat,
name = trans.chatRoom.txt(),
timeout = c.timeout,
public = true,
resourceId = lila.chat.Chat.ResourceId(s"swiss/${c.chat.id}")
)
}
)
)})""")
),
moreCss = cssTag("swiss.show"),
chessground = false,
openGraph = lila.app.ui
.OpenGraph(
title = s"${s.name}: ${s.variant.name} ${s.clock.show} #${s.id}",
url = s"$netBaseUrl${routes.Swiss.show(s.id.value).url}",
description = s"${s.nbPlayers} players compete in the ${showEnglishDate(s.startsAt)} ${s.name} swiss tournament " +
s"organized by ${teamIdToName(s.teamId)}. " +
s.winnerId.fold("Winner is not yet decided.") { winnerId =>
s"${usernameOrId(winnerId)} takes the prize home!"
}
)
.some
)(
main(cls := "swiss")(
st.aside(cls := "swiss__side")(
swiss.side(s, chatOption.isDefined)
),
div(cls := "swiss__main")(div(cls := "box"))
)
)
}

View File

@ -0,0 +1,50 @@
package views
package html.swiss
import lila.api.Context
import lila.app.templating.Environment._
import lila.app.ui.ScalatagsTemplate._
import lila.common.String.html.richText
import lila.swiss.Swiss
import controllers.routes
object side {
private val separator = " • "
def apply(s: Swiss, chat: Boolean)(implicit ctx: Context) = frag(
div(cls := "swiss__meta")(
st.section(dataIcon := s.perfType.map(_.iconChar.toString))(
div(
p(
s.clock.show,
separator,
if (s.variant.exotic) {
views.html.game.bits.variantLink(
s.variant,
if (s.variant == chess.variant.KingOfTheHill) s.variant.shortName
else s.variant.name
)
} else s.perfType.map(_.trans),
separator,
s"${s.round}/${s.nbRounds} rounds"
),
if (s.rated) trans.ratedTournament() else trans.casualTournament(),
separator,
"Swiss",
(isGranted(_.ManageTournament) || (ctx.userId
.has(s.createdBy) && !s.isFinished)) option frag(
" ",
a(href := routes.Tournament.edit(s.id.value), title := "Edit tournament")(iconTag("%"))
)
)
),
s.description map { d =>
st.section(cls := "description")(richText(d))
},
!s.isStarted option absClientDateTime(s.startsAt)
),
chat option views.html.chat.frag
)
}

View File

@ -16,6 +16,7 @@ object BusChan {
case object Simul extends BusChan
case object Study extends BusChan
case object Team extends BusChan
case object Swiss extends BusChan
case object Global extends BusChan
type Select = BusChan.type => BusChan

View File

@ -74,6 +74,7 @@ package shutup {
case class Study(id: String) extends PublicSource("study")
case class Watcher(gameId: String) extends PublicSource("watcher")
case class Team(id: String) extends PublicSource("team")
case class Swiss(id: String) extends PublicSource("swiss")
}
}
@ -207,6 +208,7 @@ package team {
case class CreateTeam(id: String, name: String, userId: String)
case class JoinTeam(id: String, userId: String)
case class GetLeaderIds(id: String, promise: Promise[Set[String]])
case class IsLeader(id: String, userId: String, promise: Promise[Boolean])
}
package fishnet {

View File

@ -0,0 +1,33 @@
package lila.swiss
import lila.room.RoomSocket.{ Protocol => RP, _ }
import lila.socket.RemoteSocket.{ Protocol => P, _ }
import lila.hub.actorApi.team.IsLeader
final private class SwissSocket(
remoteSocketApi: lila.socket.RemoteSocket,
chat: lila.chat.ChatApi
)(implicit ec: scala.concurrent.ExecutionContext, system: akka.actor.ActorSystem, mode: play.api.Mode) {
lazy val rooms = makeRoomMap(send)
subscribeChat(rooms, _.Swiss)
private lazy val handler: Handler =
roomHandler(
rooms,
chat,
logger,
roomId => _.Swiss(roomId.value).some,
localTimeout = Some { (roomId, modId, suspectId) =>
lila.common.Bus.ask[Boolean]("teamIsLeader") { IsLeader(roomId.value, modId, _) }
},
chatBusChan = _.Swiss
)
private lazy val send: String => Unit = remoteSocketApi.makeSender("swiss-out").apply _
remoteSocketApi.subscribe("swiss-in", RP.In.reader)(
handler orElse remoteSocketApi.baseHandler
) >>- send(P.Out.boot)
}

View File

@ -50,8 +50,10 @@ final class Env(
lazy val getTeamName = new GetTeamName(cached.blockingTeamName)
lila.common.Bus.subscribeFun("shadowban", "teamGetLeaders") {
lila.common.Bus.subscribeFun("shadowban", "teamGetLeaders", "teamIsLeader") {
case lila.hub.actorApi.mod.Shadowban(userId, true) => api deleteRequestsByUserId userId
case lila.hub.actorApi.team.GetLeaderIds(id, promise) => promise completeWith teamRepo.leadersOf(id)
case lila.hub.actorApi.team.IsLeader(teamId, userId, promise) =>
promise completeWith teamRepo.isLeader(teamId, userId)
}
}

View File

@ -0,0 +1 @@
.swiss {}

View File

@ -0,0 +1,7 @@
@import '../../../common/css/plugin';
@import '../../../common/css/component/fbt';
@import '../../../common/css/component/bar-glider';
@import '../../../common/css/component/slist';
@import '../../../common/css/component/quote';
@import '../../../chat/css/chat';
@import '../show';

View File

@ -0,0 +1,2 @@
@import '../../../common/css/theme/dark';
@import 'swiss.show';

View File

@ -0,0 +1,2 @@
@import '../../../common/css/theme/light';
@import 'swiss.show';

View File

@ -0,0 +1,2 @@
@import '../../../common/css/theme/transp';
@import 'swiss.show';