more streamer tweaks

This commit is contained in:
Thibault Duplessis 2018-01-05 14:25:25 -05:00
parent f4aa56f1f0
commit 6627b2d0c0
7 changed files with 133 additions and 147 deletions

View file

@ -45,19 +45,23 @@ object Streamer extends LilaController {
def edit = Auth { implicit ctx => me =>
AsStreamer { s =>
NoCache(Ok(html.streamer.edit(s, StreamerForm userForm s.streamer))).fuccess
Env.streamer.liveStreams of s flatMap { sws =>
NoCache(Ok(html.streamer.edit(sws, StreamerForm userForm sws.streamer))).fuccess
}
}
}
def editApply = AuthBody { implicit ctx => me =>
AsStreamer { s =>
implicit val req = ctx.body
StreamerForm.userForm(s.streamer).bindFromRequest.fold(
error => BadRequest(html.streamer.edit(s, error)).fuccess,
data => api.update(s.streamer, data, isGranted(_.Streamers)) inject Redirect {
s"${routes.Streamer.edit().url}${if (s.streamer is me) "" else "?u=" + s.user.id}"
}
)
Env.streamer.liveStreams of s flatMap { sws =>
implicit val req = ctx.body
StreamerForm.userForm(sws.streamer).bindFromRequest.fold(
error => BadRequest(html.streamer.edit(sws, error)).fuccess,
data => api.update(sws.streamer, data, isGranted(_.Streamers)) inject Redirect {
s"${routes.Streamer.edit().url}${if (sws.streamer is me) "" else "?u=" + sws.user.id}"
}
)
}
}
}

View file

@ -1,4 +1,4 @@
@(s: lila.streamer.Streamer.WithUser, form: Form[_])(implicit ctx: Context)
@(s: lila.streamer.Streamer.WithUserAndStream, form: Form[_])(implicit ctx: Context)
@import play.api.data.Field
@ -10,6 +10,7 @@
@moreCss = {
@cssTag("material.form.css")
@cssTag("streamer.show.css")
@cssTag("streamer.form.css")
}
@ -21,19 +22,16 @@
@base.layout(title = s"${s.user.titleUsername} streamer page",
moreCss = moreCss,
moreJs = moreJs,
menu = menu("edit", s.some).some) {
<div class="streamer_edit content_box no_padding">
menu = menu("edit", s.withoutStream.some).some) {
<div class="streamer edit content_box no_padding">
@if(ctx.is(s.user)) {
<div class="top">
<div class="picture_wrap">
@if(s.streamer.hasPicture) {
@if(ctx.is(s.user)) {
<a class="upload_picture" href="@routes.Streamer.picture" title="Change/delete your picture">
@pic(s.streamer, s.user, 250)
</a>
} else {
@pic(s.streamer, s.user, 250)
}
} else {
<div class="upload_picture">
@if(ctx.is(s.user)) {
<a class="button" href="@routes.Streamer.picture">Upload a picture</a>
@ -42,31 +40,14 @@ menu = menu("edit", s.some).some) {
}
</div>
<div class="overview">
<h1 @if(!ctx.is(s.user)){class="text" data-icon=""}>@s.streamer.name</h1>
<h1>@s.streamer.name</h1>
@rules()
</div>
</div>
@defining(s.streamer.approval.granted) { granted =>
@if(s.streamer.listed.value) {
<div class="status is@if(granted){-green}" data-icon="@if(granted){E}else{}">
@if(granted) {
Your stream is approved and listed on <a href="@routes.Streamer.index()">lichess streamers list</a>.
} else {
@if(s.streamer.approval.requested) {
Your stream is being reviewed by moderators, and will soon be listed on <a href="@routes.Streamer.index()">lichess streamers list</a>.
} else {
@if(s.streamer.completeEnough) {
When you are ready to be listed on <a href="@routes.Streamer.index()">lichess streamers list</a>,
<form method="post" action="@routes.Streamer.approvalRequest">
<button type="submmit" class="button" @if(!ctx.is(s.user)){disabled}>request a moderator review</button>
</form>
} else {
Please fill in your streamer information below.
}
}
}
</div>
} else {
@header(s)
}
@defining(s.streamer.approval.granted) { granted =>
<form class="content_box_content material form" action="@routes.Streamer.edit@if(!ctx.is(s.user)){?u=@s.user.id}" method="POST">
@errMsgMaterial(form.errors)
@if(isGranted(_.Streamers)) {
@ -92,6 +73,26 @@ menu = menu("edit", s.some).some) {
@base.form.submit()
</div>
}
@if(s.streamer.listed.value) {
<div class="status is@if(granted){-green}" data-icon="@if(granted){E}else{}">
@if(granted) {
Your stream is approved and listed on <a href="@routes.Streamer.index()">lichess streamers list</a>.
} else {
@if(s.streamer.approval.requested) {
Your stream is being reviewed by moderators, and will soon be listed on <a href="@routes.Streamer.index()">lichess streamers list</a>.
} else {
@if(s.streamer.completeEnough) {
When you are ready to be listed on <a href="@routes.Streamer.index()">lichess streamers list</a>,
<form method="post" action="@routes.Streamer.approvalRequest">
<button type="submmit" class="button" @if(!ctx.is(s.user)){disabled}>request a moderator review</button>
</form>
} else {
Please fill in your streamer information, and upload a picture.
}
}
}
</div>
}
<div>
@base.form.group(form("twitch"), Html("Your Twitch username or URL"), help = Html("Optional. Leave empty if none").some, half = true) {
@base.form.input(form("twitch"))

View file

@ -0,0 +1,35 @@
@(s: lila.streamer.Streamer.WithUserAndStream)(implicit ctx: Context)
<div class="top">
@pic(s.streamer, s.user, 250)
<div class="overview">
<h1>@titleTag(s.user.title)@s.streamer.name</h1>
@s.streamer.headline.map(_.value).map { d =>
<p class="headline @if(d.size < 60){small} else {@if(d.size < 120){medium}else{large}}">@d</p>
}
<div class="services">
@s.streamer.twitch.map { twitch =>
<a class="service twitch@if(s.stream.exists(_.twitch)){ live}" href="@twitch.fullUrl">
@StreamerSvg.twitch
@twitch.minUrl
</a>
}
@s.streamer.youTube.map { youTube =>
<a class="service youTube@if(s.stream.exists(_.youTube)){ live}" href="@youTube.fullUrl">
@StreamerSvg.youTube
@youTube.minUrl
</a>
}
</div>
@s.stream.map { s =>
<p class="at">
Currently streaming:
<strong>@s.status</strong>
</p>
}.getOrElse {
<p class="at">@trans.lastSeenActive(momentFromNow(s.streamer.seenAt))</p>
@s.streamer.liveAt.map { liveAt =>
<p class="at">Last stream @momentFromNow(liveAt)</p>
}
}
</div>
</div>

View file

@ -2,6 +2,47 @@
@title = @{ if (requests) "Streamer approval requests" else "Lichess streamers" }
@widget(s: lila.streamer.Streamer.WithUser, stream: Option[lila.streamer.Stream]) = {
<a class="overlay" href="@if(requests){@routes.Streamer.edit?u=@s.user.username}else{@routes.Streamer.show(s.user.username)}"></a>
@if(stream.isDefined) {
<span class="ribbon">
<span>LIVE!</span>
</span>
}
@pic(s.streamer, s.user, 250)
<div class="overview">
<h1>@titleTag(s.user.title)@s.streamer.name</h1>
@s.streamer.headline.map(_.value).map { d =>
<p class="headline @if(d.size < 60){small} else {@if(d.size < 120){medium}else{large}}">@d</p>
}
<div class="services">
@s.streamer.twitch.map { twitch =>
<div class="service twitch">
@StreamerSvg.twitch
@twitch.minUrl
</div>
}
@s.streamer.youTube.map { youTube =>
<div class="service youTube">
@StreamerSvg.youTube
@youTube.minUrl
</div>
}
</div>
@stream.map { s =>
<p class="at">
Currently streaming:
<strong>@s.status</strong>
</p>
}.getOrElse {
<p class="at">@trans.lastSeenActive(momentFromNow(s.streamer.seenAt))</p>
@s.streamer.liveAt.map { liveAt =>
<p class="at">Last stream @momentFromNow(liveAt)</p>
}
}
</div>
}
@base.layout(title = title,
moreCss = cssTag("streamer.list.css"),
moreJs = jsTag("vendor/jquery.infinitescroll.min.js"),
@ -10,16 +51,14 @@ menu = menu("index", none).some) {
<div class="top"><h1 data-icon="" class="text">@title</h1></div>
@if(!requests) {
<div class="list live">
@live.map { c =>
<div class="streamer">@widget(c.withoutStream, c.stream)</div>
@live.map { s =>
<div class="streamer">@widget(s.withoutStream, s.stream)</div>
}
</div>
}
<div class="list infinitescroll">
@pager.currentPageResults.map { c =>
<div class="streamer paginated_element" data-dedup="@c.streamer.id">
@widget(c, none, edit = requests)
</div>
@pager.currentPageResults.map { s =>
<div class="streamer paginated_element" data-dedup="@s.streamer.id">@widget(s, none)</div>
}
@pager.nextPage.map { np =>
<div class="pager none">

View file

@ -63,40 +63,7 @@ case _ => {
}
}
<div class="content_box no_padding streamer">
<div class="top">
@pic(s.streamer, s.user, 250)
<div class="overview">
<h1>@titleTag(s.user.title)@s.streamer.name</h1>
@s.streamer.headline.map(_.value).map { d =>
<p class="headline @if(d.size < 60){small} else {@if(d.size < 120){medium}else{large}}">@d</p>
}
<div class="services">
@s.streamer.twitch.map { twitch =>
<a class="service twitch@if(s.stream.exists(_.twitch)){ live}" href="@twitch.fullUrl">
@StreamerSvg.twitch
@twitch.minUrl
</a>
}
@s.streamer.youTube.map { youTube =>
<a class="service youTube@if(s.stream.exists(_.youTube)){ live}" href="@youTube.fullUrl">
@StreamerSvg.youTube
@youTube.minUrl
</a>
}
</div>
@s.stream.map { s =>
<p class="at">
Currently streaming:
<strong>@s.status</strong>
</p>
}.getOrElse {
<p class="at">@trans.lastSeenActive(momentFromNow(s.streamer.seenAt))</p>
@s.streamer.liveAt.map { liveAt =>
<p class="at">Last stream @momentFromNow(liveAt)</p>
}
}
</div>
</div>
@header(s)
<div class="description">@richText(s.streamer.description.fold("")(_.value))</div>
@views.html.activity.list(s.user, activities)
</div>

View file

@ -1,39 +0,0 @@
@(s: lila.streamer.Streamer.WithUser, stream: Option[lila.streamer.Stream], edit: Boolean = false)(implicit ctx: Context)
<a class="overlay" href="@if(edit){@routes.Streamer.edit?u=@s.user.username}else{@routes.Streamer.show(s.user.username)}"></a>
@if(stream.isDefined) {
<span class="ribbon">
<span>LIVE!</span>
</span>
}
@pic(s.streamer, s.user, 250)
<div class="overview">
<h1>@titleTag(s.user.title)@s.streamer.name</h1>
@s.streamer.headline.map(_.value).map { d =>
<p class="headline @if(d.size < 60){small} else {@if(d.size < 120){medium}else{large}}">@d</p>
}
<div class="services">
@s.streamer.twitch.map { twitch =>
<div class="service twitch">
@StreamerSvg.twitch
@twitch.minUrl
</div>
}
@s.streamer.youTube.map { youTube =>
<div class="service youTube">
@StreamerSvg.youTube
@youTube.minUrl
</div>
}
</div>
@stream.map { s =>
<p class="at">
Currently streaming:
<strong>@s.status</strong>
</p>
}.getOrElse {
<p class="at">@trans.lastSeenActive(momentFromNow(s.streamer.seenAt))</p>
@s.streamer.liveAt.map { liveAt =>
<p class="at">Last stream @momentFromNow(liveAt)</p>
}
}
</div>

View file

@ -1,18 +1,4 @@
.streamer_edit .top {
display: flex;
line-height: 2;
padding-right: 1em;
}
.streamer_edit .top h1 {
margin: 0;
padding: 0!important;
font-family: 'Roboto';
font-size: 32px;
text-transform: uppercase;
letter-spacing: 4px;
}
.streamer_edit .top .picture_wrap {
.streamer.edit .top .picture_wrap {
margin-right: 30px;
width: 250px;
height: 250px;
@ -21,17 +7,12 @@
text-align: center;
}
.streamer_edit .top .upload_picture {
.streamer.edit .top .upload_picture {
text-align: center;
margin-top: 80px;
}
.streamer_edit .top a,
body.dark .streamer_edit .top a {
color: #3893E8;
}
.streamer_edit #description {
.streamer.edit #description {
height: 10em;
}
@ -51,21 +32,19 @@ body.dark .streamer_edit .top a {
margin-top: 40px;
}
.streamer_edit .status {
margin: 30px 20px 20px 20px;
.streamer.edit .status {
margin: 0px 20px 60px 20px;
padding: 20px;
background: rgba(128,128,128,0.2);
}
.streamer_edit .mod {
border-bottom: 5px dotted rgba(128,128,128,0.15);
margin-bottom: 5em;
padding-bottom: 4em;
.streamer.edit .mod {
margin-bottom: 4em;
}
.streamer_edit .status::before {
.streamer.edit .status::before {
font-size: 2em;
margin-right: 0.5em;
}
.streamer_edit .status form {
.streamer.edit .status form {
display: inline;
}
@ -80,14 +59,14 @@ body.dark .streamer_edit .top a {
margin-bottom: 1em;
}
.streamer-new ul li,
.streamer_edit ul li {
.streamer.edit ul li {
font-size: 1.2em;
margin: 1em 0 1em 2.2em;
line-height: 1.6em;
text-indent: -2.2em;
}
.streamer-new ul li::before,
.streamer_edit ul li::before {
.streamer.edit ul li::before {
font-family: 'lichess';
content: 'E';
font-size: 1.5em;