202 lines
9.0 KiB
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>
|