team chat WIP

team-chat
Thibault Duplessis 2020-04-25 18:52:13 -06:00
parent f3e01bca5a
commit 6db316fe0a
10 changed files with 95 additions and 10 deletions

View File

@ -49,8 +49,17 @@ final class Team(
for {
info <- env.teamInfo(team, ctx.me)
members <- paginator.teamMembers(team, page)
_ <- env.user.lightUserApi preloadMany info.userIds
} yield html.team.show(team, members, info)
chat <- canHaveChat(info) ?? env.chat.api.userChat.cached
.findMine(lila.chat.Chat.Id(team.id), ctx.me)
.map(some)
_ <- env.user.lightUserApi preloadMany {
info.userIds ::: chat.??(_.chat.userIds)
}
version <- info.mine ?? env.team.version(team.id).dmap(some)
} yield html.team.show(team, members, info, chat, version)
private def canHaveChat(info: lila.app.mashup.TeamInfo)(implicit ctx: Context): Boolean =
info.mine && !ctx.kid // no chats for kids
def legacyUsers(teamId: String) = Action {
MovedPermanently(routes.Team.users(teamId).url)

View File

@ -47,13 +47,17 @@ object bits {
)
)
private[team] def layout(title: String, openGraph: Option[lila.app.ui.OpenGraph] = None)(
private[team] def layout(
title: String,
openGraph: Option[lila.app.ui.OpenGraph] = None,
moreJs: Frag = emptyFrag
)(
body: Frag
)(implicit ctx: Context) =
views.html.base.layout(
title = title,
moreCss = cssTag("team"),
moreJs = infiniteScrollTag,
moreJs = frag(infiniteScrollTag, moreJs),
openGraph = openGraph
)(body)
}

View File

@ -1,10 +1,12 @@
package views.html.team
import play.api.libs.json.Json
import lila.api.Context
import lila.app.templating.Environment._
import lila.app.ui.ScalatagsTemplate._
import lila.common.paginator.Paginator
import lila.common.String.html.richText
import lila.common.String.html.{ richText, safeJsonValue }
import lila.team.Team
import controllers.routes
@ -13,7 +15,13 @@ object show {
import trans.team._
def apply(t: Team, members: Paginator[lila.team.MemberWithUser], info: lila.app.mashup.TeamInfo)(
def apply(
t: Team,
members: Paginator[lila.team.MemberWithUser],
info: lila.app.mashup.TeamInfo,
chatOption: Option[lila.chat.UserChat.Mine],
socketVersion: Option[lila.socket.Socket.SocketVersion]
)(
implicit ctx: Context
) =
bits.layout(
@ -24,11 +32,33 @@ object show {
url = s"$netBaseUrl${routes.Team.show(t.id).url}",
description = shorten(t.description, 152)
)
.some
.some,
moreJs =
for {
v <- socketVersion
chat <- chatOption
} yield frag(
jsAt(s"compiled/lichess.chat${isProd ?? (".min")}.js"),
embedJsUnsafe(s"""lichess.team=${safeJsonValue(
Json.obj(
"id" -> t.id,
"socketVersion" -> v.value,
"chat" -> views.html.chat.json(
chat.chat,
name = trans.chatRoom.txt(),
timeout = chat.timeout,
public = true,
resourceId = lila.chat.Chat.ResourceId(s"team/${chat.chat.id}")
)
)
)}""")
)
)(
main(cls := "page-menu")(
bits.menu(none),
div(cls := "team-show page-menu__content box team-show")(
div(cls := "team-show page-menu__content box team-show", socketVersion.map { v =>
data("socket-version") := v.value
})(
div(cls := "box__top")(
h1(cls := "text", dataIcon := "f")(t.name, " ", em(trans.team.team.txt().toUpperCase)),
div(
@ -143,7 +173,8 @@ object show {
},
a(cls := "more", href := teamForumUrl(t.id))(t.name, " ", trans.forum(), " »")
)
)
),
chatOption.isDefined option views.html.chat.frag
)
)
)

View File

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

View File

@ -73,6 +73,7 @@ package shutup {
case class Simul(id: String) extends PublicSource("simul")
case class Study(id: String) extends PublicSource("study")
case class Watcher(gameId: String) extends PublicSource("watcher")
case class Team(id: String) extends PublicSource("team")
}
}

View File

@ -26,6 +26,7 @@ object PublicLine {
case Array("s", id) => Success(Source.Simul(id))
case Array("w", gameId) => Success(Source.Watcher(gameId))
case Array("u", id) => Success(Source.Study(id))
case Array("e", id) => Success(Source.Team(id))
case _ => lila.db.BSON.handlerBadValue(s"Invalid PublicLine source $v")
}
},
@ -35,6 +36,7 @@ object PublicLine {
case Source.Simul(id) => s"s:$id"
case Source.Study(id) => s"u:$id"
case Source.Watcher(gameId) => s"w:$gameId"
case Source.Team(id) => s"e:$id"
})
)

View File

@ -6,6 +6,7 @@ import com.softwaremill.macwire._
import lila.common.config._
import lila.mod.ModlogApi
import lila.notify.NotifyApi
import lila.socket.Socket.{ GetVersion, SocketVersion }
@Module
final class Env(
@ -15,10 +16,12 @@ final class Env(
userRepo: lila.user.UserRepo,
modLog: ModlogApi,
notifyApi: NotifyApi,
remoteSocketApi: lila.socket.RemoteSocket,
chatApi: lila.chat.ChatApi,
cacheApi: lila.memo.CacheApi,
lightUserApi: lila.user.LightUserApi,
db: lila.db.Db
)(implicit ec: scala.concurrent.ExecutionContext, system: ActorSystem) {
)(implicit ec: scala.concurrent.ExecutionContext, system: ActorSystem, mode: play.api.Mode) {
lazy val teamRepo = new TeamRepo(db(CollName("team")))
lazy val memberRepo = new MemberRepo(db(CollName("team_member")))
@ -38,6 +41,11 @@ final class Env(
lazy val jsonView = wire[JsonView]
private val teamSocket = wire[TeamSocket]
def version(teamId: Team.ID) =
teamSocket.rooms.ask[SocketVersion](teamId)(GetVersion)
private lazy val notifier = wire[Notifier]
lazy val getTeamName = new GetTeamName(cached.blockingTeamName)

View File

@ -0,0 +1,23 @@
package lila.team
import lila.room.RoomSocket.{ Protocol => RP, _ }
import lila.socket.RemoteSocket.{ Protocol => P, _ }
final private class TeamSocket(
remoteSocketApi: lila.socket.RemoteSocket,
chat: lila.chat.ChatApi
)(implicit ec: scala.concurrent.ExecutionContext, mode: play.api.Mode) {
lazy val rooms = makeRoomMap(send)
subscribeChat(rooms, _.Team)
private lazy val handler: Handler =
roomHandler(rooms, chat, logger, roomId => _.Team(roomId.value).some, chatBusChan = _.Team)
private lazy val send: String => Unit = remoteSocketApi.makeSender("team-out").apply _
remoteSocketApi.subscribe("team-in", RP.In.reader)(
handler orElse remoteSocketApi.baseHandler
) >>- send(P.Out.boot)
}

View File

@ -2,5 +2,6 @@
@import '../../../common/css/component/slist';
@import '../../../common/css/form/form3';
@import '../../../common/css/form/captcha';
@import '../../../chat/css/chat';
@import '../team/team';

View File

@ -218,6 +218,7 @@
else if (lichess.puzzle) startPuzzle(lichess.puzzle);
else if (lichess.tournament) startTournament(lichess.tournament);
else if (lichess.simul) startSimul(lichess.simul);
else if (lichess.team) startTeam(lichess.team);
// delay so round starts first (just for perceived perf)
lichess.requestIdleCallback(function() {
@ -878,6 +879,10 @@
simul = LichessSimul(cfg);
}
function startTeam(cfg) {
lichess.socket = lichess.StrongSocket('/team/' + cfg.id + '/socket/v4', cfg.socketVersion);
}
////////////////
// user_analysis.js //
////////////////