lobby filter UI
This commit is contained in:
parent
7063449860
commit
9e80c71585
|
@ -41,7 +41,7 @@ object Lobby extends LilaController with Results {
|
|||
filter = env.setup.filter
|
||||
).map(_.fold(Redirect(_), {
|
||||
case (preload, posts, tours, featured) ⇒ status(html.lobby.home(
|
||||
toJson(preload).pp,
|
||||
toJson(preload),
|
||||
myHook,
|
||||
posts,
|
||||
tours,
|
||||
|
|
|
@ -52,12 +52,20 @@ object Setup extends LilaController with TheftPrevention with RoundEventPerforme
|
|||
}
|
||||
}
|
||||
|
||||
val filterForm = Open { implicit ctx ⇒
|
||||
IOk(forms.filterFilled map { html.setup.filter(_) })
|
||||
val filterForm = Auth { implicit ctx ⇒
|
||||
me ⇒
|
||||
IOk(forms.filterFilled map { html.setup.filter(_) })
|
||||
}
|
||||
|
||||
val filter = process(forms.filter) { config ⇒
|
||||
implicit ctx ⇒ processor filter config inject routes.Lobby.home()
|
||||
val filter = AuthBody { implicit ctx ⇒
|
||||
me ⇒
|
||||
implicit val req = ctx.body
|
||||
IOResult {
|
||||
forms.filter(ctx).bindFromRequest.fold(
|
||||
f ⇒ putStrLn(f.errors.toString) inject BadRequest(),
|
||||
config ⇒ processor filter config inject JsonOk(config.render)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def join(id: String) = Open { implicit ctx ⇒
|
||||
|
@ -108,7 +116,7 @@ object Setup extends LilaController with TheftPrevention with RoundEventPerforme
|
|||
OpenBody { ctx ⇒
|
||||
implicit val req = ctx.body
|
||||
IORedirect(form(ctx).bindFromRequest.fold(
|
||||
f ⇒ putStrLn(f.errors.toString) map { _ ⇒ routes.Lobby.home },
|
||||
f ⇒ putStrLn(f.errors.toString) inject routes.Lobby.home,
|
||||
config ⇒ op(config)(ctx)
|
||||
))
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import scalaz.effects._
|
|||
import org.joda.time.DateTime
|
||||
import org.scala_tools.time.Imports._
|
||||
|
||||
class HookRepo(collection: MongoCollection)
|
||||
final class HookRepo(collection: MongoCollection)
|
||||
extends SalatDAO[Hook, String](collection) {
|
||||
|
||||
def hook(hookId: String): IO[Option[Hook]] = io {
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.mongodb.casbah.MongoCollection
|
|||
import com.mongodb.casbah.query.Imports._
|
||||
import scalaz.effects._
|
||||
|
||||
final class MessageRepo(collection: MongoCollection, max: Int)
|
||||
private[lobby] final class MessageRepo(collection: MongoCollection, max: Int)
|
||||
extends CappedRepo[Message](collection, max) {
|
||||
|
||||
val all = io {
|
||||
|
|
|
@ -17,7 +17,7 @@ import akka.util.duration._
|
|||
import akka.util.Timeout
|
||||
import scalaz.effects._
|
||||
|
||||
final class Preload(
|
||||
private[lobby] final class Preload(
|
||||
fisherman: Fisherman,
|
||||
history: History,
|
||||
hookRepo: HookRepo,
|
||||
|
@ -54,10 +54,10 @@ final class Preload(
|
|||
ioToFuture(filter) map {
|
||||
case ((((((hooks, messages), entries), posts), tours), feat), filter) ⇒ (Right((Map(
|
||||
"version" -> history.version,
|
||||
"pool" -> renderHooks(hooks, myHook),
|
||||
"pool" -> renderHooks(hooks, myHook).pp,
|
||||
"chat" -> (messages.reverse map (_.render)),
|
||||
"timeline" -> (entries.reverse map (_.render)),
|
||||
"filter" -> filter.toMap
|
||||
"filter" -> filter.render
|
||||
), posts, tours, feat))): Response
|
||||
}
|
||||
)
|
||||
|
|
|
@ -12,7 +12,7 @@ case class FilterConfig(variant: Option[Variant]) {
|
|||
|
||||
def >> = Some((variant map (_.id)))
|
||||
|
||||
def toMap = Map("variant" -> variant.map(_.id))
|
||||
def render = Map("variant" -> variant.map(_.toString))
|
||||
}
|
||||
|
||||
object FilterConfig {
|
||||
|
|
|
@ -24,7 +24,8 @@ private[setup] final class UserConfigRepo(collection: MongoCollection)
|
|||
def filter(user: User): IO[FilterConfig] = io {
|
||||
for {
|
||||
obj ← collection.findOneByID(user.id, DBObject("filter" -> true))
|
||||
variant ← obj.getAs[Int]("v")
|
||||
filter ← obj.getAs[DBObject]("filter")
|
||||
variant ← filter.getAs[Int]("v")
|
||||
config ← RawFilterConfig(variant).decode
|
||||
} yield config
|
||||
} map (_ | FilterConfig.default)
|
||||
|
|
|
@ -7,7 +7,7 @@ import play.api.templates.Html
|
|||
|
||||
trait AssetHelper {
|
||||
|
||||
val assetVersion = 23
|
||||
val assetVersion = 24
|
||||
|
||||
def cssTag(name: String) = css("stylesheets/" + name)
|
||||
|
||||
|
|
|
@ -33,13 +33,5 @@ final class LobbyMenu(i18nKeys: I18nKeys) {
|
|||
i18nKeys.playWithTheMachine,
|
||||
i18nKeys.challengeTheArtificialIntelligence)
|
||||
|
||||
val filter = new Elem(
|
||||
"filter",
|
||||
routes.Setup.filterForm,
|
||||
i18nKeys.filterGames,
|
||||
i18nKeys.filterGames)
|
||||
|
||||
val allAnon = List(hook, friend, ai)
|
||||
|
||||
val allUser = allAnon :+ filter
|
||||
val all = List(hook, friend, ai)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div class="lichess_ground">
|
||||
<div class="lichess_table lichess_table_not_started" id="start_buttons">
|
||||
@ctx.isAuth.fold(lobbyMenu.allUser, lobbyMenu.allAnon).map { b =>
|
||||
@lobbyMenu.all.map { b =>
|
||||
<a class="lichess_button button config_@b.code" href="@b.route" title="@b.title()">@b.name()</a>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -51,6 +51,10 @@ underchat = underchat.some) {
|
|||
@board.white()
|
||||
@widget.connection()
|
||||
<div class="hooks_wrap">
|
||||
@if(ctx.isAuth) {
|
||||
<a class="filter" href="@routes.Setup.filterForm()"><span class="s16">@trans.filterGames()</span></a>
|
||||
<div class="filter"></div>
|
||||
}
|
||||
<div class="hooks"
|
||||
data-my-hook="@myHook.map(_.ownerId)"
|
||||
data-cancel-url="@routes.Lobby.cancel("000000000000")"
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
@(form: Form[_])(implicit ctx: Context)
|
||||
|
||||
<div class="lichess_overboard auto_center game_config game_config_filter">
|
||||
<h2>@trans.filterGames()</h2>
|
||||
<div class="game_config_form">
|
||||
@helper.form(action = routes.Setup.filter, 'novalidate -> "novalidate") {
|
||||
<div class="variants">
|
||||
@base.select(form("variant"), translatedVariantChoices, "Any variant".some)
|
||||
</div>
|
||||
<button type="submit" class="submit">Save filter</button>
|
||||
}
|
||||
</div>
|
||||
@helper.form(action = routes.Setup.filter(), 'novalidate -> "novalidate") {
|
||||
<div class="variants">
|
||||
@base.select(form("variant"), translatedVariantChoices, "Any variant".some)
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a class="reset">Reset</a>
|
||||
<button type="submit" class="submit">Done</button>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1520,6 +1520,36 @@ $(function() {
|
|||
var myElo = isRegistered ? parseInt($userTag.data('elo')) : null;
|
||||
var hookOwnerId = $hooks.data('my-hook');
|
||||
|
||||
$wrap.find('a.filter').click(function() {
|
||||
$(this).toggleClass('active');
|
||||
if($(this).hasClass('active')) {
|
||||
var $filter = $wrap.find('div.filter').fadeIn(200);
|
||||
$.ajax({
|
||||
url: $(this).attr('href'),
|
||||
success: function(html) {
|
||||
$filter.html(html).find('select').change(_.throttle(function() {
|
||||
var $form = $filter.find('form');
|
||||
$.ajax({
|
||||
url: $form.attr('action'),
|
||||
data: $form.serialize(),
|
||||
type: 'post',
|
||||
success: function(filter) {
|
||||
lichess_preload.filter = filter;
|
||||
updateHookTable();
|
||||
}
|
||||
});
|
||||
}, 500));
|
||||
$filter.find('a.reset').click(function() {
|
||||
$filter.find('select').val('').change();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var $filter = $wrap.find('div.filter').fadeOut(200);
|
||||
}
|
||||
return false;
|
||||
}).click();
|
||||
|
||||
if (chatExists) {
|
||||
var $form = $chat.find('form');
|
||||
$chat.find('.lichess_messages').scrollable();
|
||||
|
@ -1645,8 +1675,7 @@ $(function() {
|
|||
}
|
||||
function addHooks(hooks) {
|
||||
var html = "";
|
||||
for (i in hooks) html += renderHook(hooks[i]);
|
||||
$hooksTable.append(html);
|
||||
for (i in hooks) html += $hooksTable.append(renderHook(hooks[i]));
|
||||
updateHookTable();
|
||||
}
|
||||
function addHook(hook) {
|
||||
|
@ -1654,6 +1683,14 @@ $(function() {
|
|||
updateHookTable();
|
||||
}
|
||||
function updateHookTable() {
|
||||
var filter = lichess_preload.filter;
|
||||
$hooksTable.find('tr.hook').each(function() {
|
||||
var hook = $(this).data('hook');
|
||||
var hide = (filter.variant != null && filter.variant != hook.variant);
|
||||
hide = hide && (hook.action != 'cancel');
|
||||
if (hide) $(this).hide(); else $(this).show();
|
||||
});
|
||||
|
||||
if (0 == $hooksTable.find('tr.hook').length) {
|
||||
$hooksTable.addClass('empty_table').html('<tr class="create_game"><td colspan="5">'+$.trans("No game available right now, create one!")+'</td></tr>');
|
||||
} else {
|
||||
|
@ -1708,8 +1745,10 @@ $(function() {
|
|||
var cancelParam = hookOwnerId ? "?cancel=" + hookOwnerId : ""
|
||||
html += '<a href="'+actionUrls.join.replace(/\/0{8}/, '/'+hook.id)+cancelParam+'" class="join"></a>';
|
||||
}
|
||||
html += '</td>';
|
||||
}
|
||||
return html;
|
||||
html += '</tr>';
|
||||
return $(html).data('hook', hook);
|
||||
}
|
||||
|
||||
function resizeLobby() {
|
||||
|
|
28
public/javascripts/deps.min.js
vendored
28
public/javascripts/deps.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -77,7 +77,7 @@ div.hooks_wrap {
|
|||
top: 51px;
|
||||
left: 52px;
|
||||
padding: 12px;
|
||||
border-radius: 3px;
|
||||
border-radius: 3px 0 3px 3px;
|
||||
box-shadow: 0 0 20px #444;
|
||||
background: rgba(245,245,245,0.8);
|
||||
background: -moz-linear-gradient(top, rgba(212,212,212,0.9) 0%, rgba(240,240,240,0.5) 100%);
|
||||
|
@ -85,6 +85,7 @@ div.hooks_wrap {
|
|||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(212,212,212,0.9)), to(rgba(240,240,240,0.5)));
|
||||
background: -ms-linear-gradient(top, rgba(212,212,212,0.9) 0%,rgba(240,240,240,0.5) 100%);
|
||||
background: -o-linear-gradient(top, rgba(212,212,212,0.9) 0%,rgba(240,240,240,0.5) 100%);
|
||||
background: linear-gradient(top, rgba(212,212,212,0.9) 0%,rgba(240,240,240,0.5) 100%);
|
||||
}
|
||||
div.hooks_wrap.large {
|
||||
height: 512px;
|
||||
|
@ -94,6 +95,57 @@ div.hooks_wrap.large {
|
|||
div.hooks_wrap.hidden {
|
||||
display: none;
|
||||
}
|
||||
div.hooks_wrap a.filter {
|
||||
position: absolute;
|
||||
top: -21px;
|
||||
right: -1px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
padding: 0 2px 0 10px;
|
||||
background: rgba(212,212,212,0.9);
|
||||
background: -moz-linear-gradient(top,rgba(212,212,212,1) 0%, rgba(212,212,212,0.9) 100%);
|
||||
border: 1px solid #444;
|
||||
border-bottom: 0;
|
||||
display: block;
|
||||
border-radius: 3px 3px 0 0;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
div.hooks_wrap a.filter:hover,
|
||||
div.hooks_wrap a.filter.active {
|
||||
background: #fff;
|
||||
}
|
||||
div.hooks_wrap a.filter span {
|
||||
background-position: right -192px;
|
||||
padding-left: 0;
|
||||
padding-right: 20px;
|
||||
}
|
||||
div.hooks_wrap div.filter {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
min-height: 181px;
|
||||
width: 244px;
|
||||
padding: 12px;
|
||||
border: 1px solid #444;
|
||||
border-width: 0 0 1px 1px;
|
||||
background: #fff;
|
||||
}
|
||||
div.hooks_wrap div.filter select {
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
text-transform: capitalize;
|
||||
padding: 6px;
|
||||
}
|
||||
div.hooks_wrap div.filter .actions {
|
||||
text-align: right;
|
||||
}
|
||||
div.hooks_wrap div.filter .actions button {
|
||||
padding: 6px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
div.hooks {
|
||||
border: 1px solid #bababa;
|
||||
border-top: 0
|
||||
|
|
Loading…
Reference in a new issue