study index UI

more-scalatags
Thibault Duplessis 2019-04-09 20:36:23 +07:00
parent 965a84088a
commit e336cf0d5e
12 changed files with 134 additions and 170 deletions

View File

@ -12,22 +12,25 @@ import controllers.routes
object bits {
def newButton()(implicit ctx: Context) = ctx.isAuth option
form(cls := "new_study", action := routes.Study.create, method := "post")(
button(`type` := "submit", cls := "button")("New study")
form(cls := "new-study", action := routes.Study.create, method := "post")(
button(tpe := "submit", cls := "button")("New study")
)
def newForm()(implicit ctx: Context) =
form(cls := "new_study", action := routes.Study.create, method := "post")(
button(`type` := "submit", cls := "button frameless", dataIcon := "O", title := "New study")
form(cls := "new-study", action := routes.Study.create, method := "post")(
button(tpe := "submit", cls := "button button-green", dataIcon := "O", title := "New study")
)
def authLinks(me: User, active: String, order: lila.study.Order)(implicit ctx: Context) = frag(
a(cls := "mine" == active option "mine", href := routes.Study.mine(order.key))("My studies"),
a(cls := "mineMember" == active option "mineMember", href := routes.Study.mineMember(order.key))("Studies I contribute to"),
a(cls := "minePublic" == active option "minePublic", href := routes.Study.minePublic(order.key))("My public studies"),
a(cls := "minePrivate" == active option "minePrivate", href := routes.Study.minePrivate(order.key))("My private studies"),
a(cls := "mineLikes" == active option "mineLikes", href := routes.Study.mineLikes(order.key))("Favourite studies")
)
def authLinks(me: User, active: String, order: lila.study.Order)(implicit ctx: Context) = {
def activeCls(c: String) = cls := (c == active).option("active")
frag(
a(activeCls("mine"), href := routes.Study.mine(order.key))("My studies"),
a(activeCls("mineMember"), href := routes.Study.mineMember(order.key))("Studies I contribute to"),
a(activeCls("minePublic"), href := routes.Study.minePublic(order.key))("My public studies"),
a(activeCls("minePrivate"), href := routes.Study.minePrivate(order.key))("My private studies"),
a(activeCls("mineLikes"), href := routes.Study.mineLikes(order.key))("Favourite studies")
)
}
def widget(s: lila.study.Study.WithChaptersAndLiked, tag: Tag = h2)(implicit ctx: Context) = frag(
a(cls := "overlay", href := routes.Study.show(s.study.id.value)),

View File

@ -89,29 +89,13 @@ object list {
iconTag("4"),
p("None yet.")
)
else div(cls := "list infinitescroll")(
else div(cls := "studies list infinitescroll")(
pager.currentPageResults.map { s =>
div(cls := "study paginated")(bits.widget(s))
},
pagerNext(pager, np => addQueryParameter(url.url, "page", np))
)
private def orderChoice(
url: lila.study.Order => Call,
order: lila.study.Order,
orders: List[lila.study.Order] = lila.study.Order.all
)(implicit ctx: Context) = div(cls := "orders mselect")(
div(cls := "button")(
order.name,
iconTag("u")
),
div(cls := "list")(
orders.map { o =>
a(href := url(o))(o.name)
}
)
)
private def layout(
title: String,
active: String,
@ -121,27 +105,33 @@ object list {
searchFilter: String
)(titleFrag: Frag)(implicit ctx: Context) = views.html.base.layout(
title = title,
// menu = Some(frag(
// a(
// cls := active.active("all"),
// href := routes.Study.all(order.key)
// )("All studies"),
// ctx.me.map { bits.authLinks(_, active, order) },
// a(cls := "text", dataIcon := "", href := "//lichess.org/blog/V0KrLSkAAMo3hsi4/study-chess-the-lichess-way")("What are studies?")
// )),
moreCss = cssTag("studyList.css"),
moreCss = responsiveCssTag("study.index"),
responsive = true,
moreJs = infiniteScrollTag
) {
div(cls := "content_box no_padding studies")(
div(cls := "top")(
form(cls := "search", action := routes.Study.search(), method := "get")(
input(name := "q", placeholder := title, value := s"$searchFilter${searchFilter.nonEmpty ?? " "}"),
button(`type` := "submit", cls := "submit button", dataIcon := "y")
),
orderChoice(o => url(o.key), order, if (active == "all") lila.study.Order.allButOldest else lila.study.Order.all),
bits.newForm()
main(cls := "page-menu")(
st.aside(cls := "page-menu__menu subnav")(
a(cls := active.active("all"), href := routes.Study.all(order.key))("All studies"),
ctx.me.map { bits.authLinks(_, active, order) },
a(cls := "text", dataIcon := "", href := "//lichess.org/blog/V0KrLSkAAMo3hsi4/study-chess-the-lichess-way")("What are studies?")
),
paginate(pag, url(order.key))
main(cls := "page-menu__content study-index box")(
div(cls := "box__top")(
form(cls := "search", action := routes.Study.search(), method := "get")(
input(name := "q", placeholder := title, value := s"$searchFilter${searchFilter.nonEmpty ?? " "}"),
button(`type` := "submit", cls := "submit button", dataIcon := "y")
),
views.html.base.bits.mselect(
"orders",
span(order.name),
(if (active == "all") lila.study.Order.allButOldest else lila.study.Order.all) map { o =>
a(href := url(o.key))(o.name)
}
),
bits.newForm()
),
paginate(pag, url(order.key))
)
)
}
}

View File

@ -1,107 +0,0 @@
.studies .top {
display: flex;
align-items: center;
}
.studies .top .search {
flex: 1 1 100%;
margin: 15px 20px;
display: flex;
}
.studies .top .search input {
flex: 1 1 100%;
padding: 0 10px;
font-size: 20px;
line-height: 40px;
border: 1px solid #ccc;
}
.studies .top .search .submit {
padding: 0 30px;
border-radius: 0 3px 3px 0;
border-left: 0;
font-size: 16px;
}
.studies .top .search .submit::before {
opacity: 0.7;
}
.studies .top .search .submit:hover::before {
opacity: 1;
}
.studies .top .new_study,
.studies .top .orders {
white-space: nowrap;
margin-right: 10px;
}
.studies .top .new_study .button i::before {
color: #759900;
font-size: 40px;
}
.studies .list {
display: flex;
flex-flow: row wrap;
border-top: 1px solid #ccc;
}
.studies .nostudies {
text-align: center;
margin: 40px 0 80px;
font-size: 2em;
}
.studies .nostudies p {
opacity: 0.6;
}
.studies .nostudies i {
display: block;
font-size: 180px;
opacity: 0.4;
}
.studies .nostudies form {
margin-top: 20px;
}
.mselect {
display:inline-block;
position: relative;
padding:0;
border:0;
}
.mselect .button {
padding: 0 10px 0 10px;
display: flex;
align-items: center;
line-height: 40px;
}
.mselect .button i {
margin-left: 5px;
font-size: 10px;
}
.mselect .list {
margin:0;
padding:0;
position:absolute;
z-index: 3;
top:0;
text-align: left;
list-style-type:none;
font-weight: normal;
background: #fff;
box-shadow: 0px 8px 17px 0px rgba(0, 0, 0, 0.2), 0px 6px 20px 0px rgba(0, 0, 0, 0.19);
border-radius: 3px;
display: none;
}
.mselect.shown .list {
display: block;
}
.mselect .list a {
display: block;
padding: 10px;
background:#fff;
transition: 0.13s;
outline:0;
text-decoration:none;
cursor:pointer;
}
.mselect .list a:hover{
background: #3893E8;
color: #fff;
}
.studies #infscr-loading {
width: 100%;
}

View File

@ -0,0 +1,3 @@
@import '../../../common/css/plugin';
@import '../../../common/css/component/mselect';
@import '../study/index';

View File

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

View File

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

View File

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

View File

@ -0,0 +1,64 @@
@import 'list-widget';
.study-index {
.box__top {
@extend %flex-center;
.search {
flex: 1 1 auto;
display: flex;
}
.search input {
flex: 1 1 100%;
font-size: 1.2em;
}
.search .submit {
padding: 0 30px;
border-radius: 0 3px 3px 0;
border-left: 0;
}
.search .submit::before {
opacity: 0.7;
}
.search .submit:hover::before {
opacity: 1;
}
.mselect {
margin: 0 1em;
font-size: 1.2em;
&__label::after {
margin-left: .6em;
}
}
.new_study,
.orders {
white-space: nowrap;
margin-right: 10px;
}
.new_study .button i::before {
color: #759900;
font-size: 40px;
}
}
.list {
border-top: $border;
}
.nostudies {
text-align: center;
margin: 40px 0 80px;
font-size: 2em;
p {
opacity: 0.6;
}
i {
display: block;
font-size: 180px;
opacity: 0.4;
}
form {
margin-top: 20px;
}
}
#infscr-loading {
width: 100%;
}
}

View File

@ -1,52 +1,52 @@
$c-study: $c-primary;
.studies {
@extend %flex-wrap;
border-top: $border;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
.study {
flex: 0 0 50%;
max-width: 50%;
border: $border;
border-width: 0 1px 1px 0;
padding: 1em .6em 1em 1.3em;
position: relative;
@include transition();
&:hover {
background: mix($c-accent, $c-bg-box, 12%);
background: mix($c-study, $c-bg-box, 10%);
}
.overlay {
@extend %link-overlay;
}
.body {
display: flex;
font-size: .9em;
}
ol.chapters {
.chapters {
flex: 0 0 58%;
max-width: 58%;
}
ol.members {
.members {
flex: 0 0 40%;
max-width: 40%;
margin-left: 2%;
}
ol li {
li {
@extend %nowrap-hidden;
color: $c-font-dim;
text-overflow: ellipsis;
}
ol li::before {
color: $c-font-dimmer;
&::before {
color: $c-font-dimmer;
}
}
.top {
@extend %roboto;
font-weight: normal;
display: block;
position: relative;
box-sizing: border-box;
height: 60px;
padding-left: 54px;
.study-name {
@extend %nowrap-hidden;
font-size: 1.5em;
font-weight: normal;
color: $c-brag;
color: $c-study;
display: block;
margin: 0;
text-overflow: ellipsis;
@ -62,10 +62,10 @@
left: 0;
}
.icon::before {
color: $c-brag;
color: $c-study;
font-size: 38px;
line-height: 45px;
opacity: 0.8;
opacity: .8;
}
}
}

View File

@ -2,13 +2,15 @@ $c-mselect: $c-primary;
.mselect {
position: relative;
white-space: nowrap;
&__toggle {
position: absolute;
top: -9999px;
left: -9999px;
}
&__label {
@extend %box-neat, %metal, %flex-center, %flex-between;
@extend %box-neat, %metal, %flex-between;
flex-flow: row nowrap;
padding: .3rem .3rem .3rem 1rem;
cursor: pointer;
&:hover {

View File

@ -52,6 +52,9 @@
}
&__studies {
margin-top: 20px;
.studies {
border-top: $border;
}
h2 {
padding: 1em 0 0 2em;
}

View File

@ -90,7 +90,7 @@
text-align: right;
padding-right: 5px;
}
span.icon {
.icon {
font-size: 1.3em;
margin: 2px 1px -1px 3px;
}