lila/app/views/base/layout.scala.html

202 lines
9.0 KiB
HTML

@(
title: String,
fullTitle: Option[String] = None,
baseline: Option[Html] = None,
side: Option[Html] = None,
menu: Option[Html] = None,
chat: Option[Html] = None,
underchat: Option[Html] = None,
robots: Boolean = isGloballyCrawlable,
moreCss: Html = emptyHtml,
moreJs: Html = emptyHtml,
playing: Boolean = false,
openGraph: Option[lila.app.ui.OpenGraph] = None,
atom: Option[Html] = None,
chessground: Boolean = true,
zoomable: Boolean = false,
asyncJs: Boolean = false,
csp: Option[lila.common.ContentSecurityPolicy] = None)(body: Html)(implicit ctx: Context)
<!doctype html>
<html lang="@lang.language">
<!-- Lichess is open source! See https://github.com/ornicar/lila -->
<head>
<meta charset="utf-8">
@if(cspEnabled()) {
<!-- <meta http-equiv="Content-Security-Policy" content="@csp.getOrElse(defaultCsp)"> -->
}
@if(isProd) {
<title>@fullTitle.getOrElse{@title • lichess.org}</title>
<link href="https://fonts.googleapis.com/css?family=Noto+Sans:400,700|Roboto:300" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:500&text=0123456789:." rel="stylesheet">
} else {
<title>[dev] @fullTitle.getOrElse{@title • lichess.org}</title>
@cssAt("offline/font.noto.css")
@cssAt("offline/font.roboto.mono.css")
}
@ctx.currentBg match {
case "dark" => { @cssTag("dark.css") }
case "transp" => { @cssTag("dark.css")@cssTag("transp.css") }
case _ => {}
}
@cssTag("common.css")
@cssTag("board.css")
@if(zoomable) {
@ctx.zoom.map { z =>
@zoomStyle(z / 100f, ctx.pref.is3d) }
}
@if(ctx.pref.is3d) { @cssTag("board-3d.css") }
@if(ctx.pref.coords == 1) { @cssTag("board.coords.inner.css") }
@if(ctx.pageData.inquiry.isDefined) { @cssTag("inquiry.css") }
@if(ctx.userContext.impersonatedBy.isDefined) { @cssTag("impersonate.css") }
@if(isStage) { @cssTag("stage.css") }
@moreCss
<link id="piece-sprite" href="@assetUrl(s"stylesheets/piece/${ctx.currentPieceSet}.css")" type="text/css" rel="stylesheet"/>
<meta content="@openGraph.fold(trans.siteDescription.txt())(o => o.description)" name="description">
<link id="favicon" rel="shortcut icon" href="@staticUrl("images/favicon-32-white.png")" type="image/x-icon" />
<link rel="mask-icon" href="@staticUrl("favicon.svg")" color="black">
<link rel="icon" type="image/png" href="@staticUrl("favicon.256.png")" sizes="256x256"/><link rel="icon" type="image/png" href="@staticUrl("favicon.128.png")" sizes="128x128"/><link rel="icon" type="image/png" href="@staticUrl("favicon.64.png")" sizes="64x64"/>
@if(!robots) {<meta content="noindex, nofollow" name="robots">}
<meta name="google" content="notranslate" />
@openGraph.map(_.html)
@atom.getOrElse {
<link href="@routes.Blog.atom()" type="application/atom+xml" rel="alternate" title="@trans.blog()" />
}
@ctx.transpBgImg.map { img =>
<style type="text/css" id="bg-data">body.transp::before{background-image:url('@img');}</style>
}
<link rel="preload" href="@staticUrl("font81/fonts/lichess.woff")" as="font" type="font/woff" crossorigin/>
<link rel="manifest" href="/manifest.json" />
<meta name="twitter:site" content="@@lichess" />
</head>
<body class="preload base @List(
ctx.currentTheme.cssClass,
ctx.currentTheme3d.cssClass,
if (ctx.currentBg == "transp") "dark transp" else ctx.currentBg,
ctx.currentPieceSet3d,
ctx.pref.pieceNotationIsLetter ?? "piece_letter",
ctx.pref.isZen ?? "zen",
ctx.blindMode ?? "blind_mode",
ctx.kid ?? "kid",
ctx.isMobileBrowser ?? "mobile",
playing ?? "playing fixed-scroll").mkString(" ")"
@if(!isProd){data-dev="true"}
@ctx.userId.map {id => data-user="@id"}
data-sound-set="@ctx.currentSoundSet"
data-socket-domain="@socketDomain"
data-asset-url="@assetBaseUrl"
data-asset-version="@assetVersion"
@ctx.nonce.map { nonce => data-nonce="@nonce" }
@ctx.zoom.map { zoom => data-zoom="@zoom" }>
<form id="blind_mode" action="@routes.Main.toggleBlindMode" method="POST"><input type="hidden" name="enable" value="@if(ctx.blindMode){0}else{1}" /><input type="hidden" name="redirect" value="@ctx.req.path" /><button type="submit">Accessibility: @if(ctx.blindMode){Disable}else{Enable} blind mode</button></form>
<div id="site_description">@trans.siteDescription()</div>
@ctx.pageData.inquiry.map { inquiry =>
@mod.inquiry(inquiry)
}
@ctx.me.map { me =>
@if(ctx.userContext.impersonatedBy.isDefined) { @mod.impersonate(me) }
}
@if(isStage) {
<div id="stage">This is an empty lichess preview website for developers. <a href="https://lichess.org">Go to lichess.org instead</a></div>
}
@lila.security.EmailConfirm.cookie.get(ctx.req).map(auth.emailConfirmBanner(_))
@if(playing) { <a data-icon="E" id="zentog" class="text fbt active">ZEN MODE</a> }
<div id="top" class="@if(ctx.pref.is3d){is3d}else{is2d}">
@topmenu()
<div id="ham-plate" class="link hint--bottom" data-hint="@trans.menu()">
<div id="hamburger" data-icon="["></div>
</div>
@ctx.me.map { me =>
<div class="dasher">
<a id="user_tag" class="toggle link">@me.username</a>
<div id="dasher_app" class="dropdown"></div>
</div>
<div class="challenge_notifications">
<a id="challenge_notifications_tag" class="toggle link data-count" data-count="@ctx.nbChallenges">
<span class="hint--bottom-left" data-hint="@trans.challenges()">
<span data-icon="U"></span>
</span>
</a>
<div id="challenge_app" class="dropdown"></div>
</div>
<div class="site_notifications">
<a id="site_notifications_tag" class="toggle link data-count" data-count="@ctx.nbNotifications">
<span class="hint--bottom-left" data-hint="@trans.notifications()">
<span data-icon=""></span>
</span>
</a>
<div id="notify_app" class="dropdown"></div>
</div>
}.getOrElse {
@if(!ctx.pageData.error) {
<div class="dasher">
<a class="toggle anon">
<span class="hint--bottom-left" data-hint="@trans.preferences()">
<span data-icon="%"></span>
</span>
</a>
<div id="dasher_app" class="dropdown"@if(playing){ data-playing="true"}></div>
</div>
<a href="@routes.Auth.login?referrer=@currentPath" class="signin button text">@trans.signIn()</a>
}
}
@if(ctx.teamNbRequests > 0) {
<a class="link data-count" href="@routes.Team.requests()" data-count="@ctx.teamNbRequests">
<span class="hint--bottom-left" data-hint="@trans.teams()">
<span data-icon="f"></span>
</span>
</a>
}
@if(isGranted(_.SeeReport)) {
<a class="link text data-count" href="@routes.Report.list" data-count="@reportNbOpen" data-icon=""></a>
}
<div id="clinput"><a class="link"><span data-icon="y"></span></a><input spellcheck="false" placeholder="@trans.search()"/></div>
<a id="reconnecting" class="link text" data-icon="B">@trans.reconnecting()</a>
</div>
<div class="content @if(ctx.pref.is3d){is3d}else{is2d}">
<div id="site_header">
<div id="notifications"></div>
<div class="board_left">
<h1>
<a id="site_title" href="@routes.Lobby.home">@if(ctx.kid){<span title="@trans.kidMode()" class="kiddo">😊</span>}else{@if(ctx.isBot){<img src="@staticUrl("images/icons/bot.png")" title="Robot chess" style="display:inline;width:34px;height:34px;vertical-align:top;margin-right:5px;"/>}}lichess<span class="extension">@if(isProd){.org}else{ dev}</span></a>
</h1>
@baseline
@menu.map { sideMenu =>
<div class="side_menu">@sideMenu</div>
}
@side
@chat
</div>
@underchat.map { g =>
<div class="under_chat">@g</div>
}
</div>
<div id="lichess">
@body
</div>
</div>
@ctx.me.map { me =>
<div id="friend_box" data-preload="@ctx.onlineFriends.users.map(_.titleName).mkString(",")"
data-playing="@ctx.onlineFriends.playing.mkString(",")"
data-patrons="@ctx.onlineFriends.patrons.mkString(",")"
data-studying="@ctx.onlineFriends.studying.mkString(",")">
<div class="title"><strong class="online"> </strong> @trans.onlineFriends()</div>
<div class="content_wrap">
<div class="content list"></div>
<div class="nobody@if(ctx.onlineFriends.users.nonEmpty){ none}">
<span>@trans.noFriendsOnline()</span>
<a class="find button" href="@routes.User.opponents">
<span class="is3 text" data-icon="h">@trans.findFriends()</span>
</a>
</div>
</div>
</div>
}
@if(chessground) {@jsTag("vendor/chessground.min.js")}
@if(ctx.requiresFingerprint) { @fingerprintTag }
@jsAt(s"compiled/lichess.site${isProd??".min"}.js", async = asyncJs)
@moreJs
@embedJs {lichess.quantity=@i18nJsQuantityFunction;@timeagoLocaleScript;}
@if(ctx.pageData.inquiry.isDefined) { @jsTag("inquiry.js", async = asyncJs) }
</body>
</html>