persistent challenges WIP
parent
31b7123a5a
commit
f87da2f442
|
@ -106,7 +106,9 @@ withLangAnnotations: Boolean = true)(body: Html)(implicit ctx: Context)
|
|||
<span data-icon="U"></span>
|
||||
</span>
|
||||
</a>
|
||||
<div id="challenge_notifications" class="links dropdown"></div>
|
||||
<div id="challenge_notifications" class="links dropdown">
|
||||
<div class="square-wrap"><div class="square-spin"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
}.getOrElse {
|
||||
<a href="@routes.Auth.login" class="signin button fright text">@trans.signIn()</a>
|
||||
|
|
|
@ -46,8 +46,14 @@ private object BSONHandlers {
|
|||
def read(b: BSONBoolean) = Mode(b.value)
|
||||
def write(m: Mode) = BSONBoolean(m.rated)
|
||||
}
|
||||
implicit val RatingBSONHandler = new BSON[Rating] {
|
||||
def reads(r: Reader) = Rating(r.int("i"), r.boolD("p"))
|
||||
def writes(w: Writer, r: Rating) = BSONDocument(
|
||||
"i" -> r.int,
|
||||
"b" -> w.boolO(r.provisional))
|
||||
}
|
||||
implicit val EitherChallengerBSONHandler = new BSON[EitherChallenger] {
|
||||
def reads(r: Reader) = (r.strO("id") |@| r.intO("rating")) {
|
||||
def reads(r: Reader) = (r.strO("id") |@| r.getO[Rating]("rating")) {
|
||||
case (id, rating) => Right(Registered(id, rating))
|
||||
} orElse r.strO("secret").map { secret =>
|
||||
Left(Anonymous(secret))
|
||||
|
|
|
@ -25,7 +25,12 @@ case class Challenge(
|
|||
|
||||
object Challenge {
|
||||
|
||||
case class Registered(id: String, rating: Int)
|
||||
case class Rating(int: Int, provisional: Boolean)
|
||||
object Rating {
|
||||
def apply(p: lila.rating.Perf): Rating = Rating(p.intRating, p.provisional)
|
||||
}
|
||||
|
||||
case class Registered(id: String, rating: Rating)
|
||||
case class Anonymous(secret: String)
|
||||
|
||||
sealed trait TimeControl
|
||||
|
@ -78,7 +83,7 @@ object Challenge {
|
|||
case _ => ColorChoice.Random
|
||||
},
|
||||
challenger = challenger.fold[EitherChallenger](Left(Anonymous(randomId))) { u =>
|
||||
Right(Registered(u.id, u.perfs(perfType(variant, timeControl)).intRating))
|
||||
Right(Registered(u.id, Rating(u.perfs(perfType(variant, timeControl)))))
|
||||
},
|
||||
destUserId = destUserId,
|
||||
createdAt = DateTime.now,
|
||||
|
|
|
@ -2,6 +2,8 @@ package lila.challenge
|
|||
|
||||
import play.api.libs.json._
|
||||
|
||||
import lila.common.PimpedJson._
|
||||
|
||||
final class JsonView(getLightUser: String => Option[lila.common.LightUser]) {
|
||||
|
||||
import Challenge._
|
||||
|
@ -18,8 +20,9 @@ final class JsonView(getLightUser: String => Option[lila.common.LightUser]) {
|
|||
"id" -> u.id,
|
||||
"name" -> light.fold(u.id)(_.name),
|
||||
"title" -> light.map(_.title),
|
||||
"rating" -> u.rating
|
||||
)
|
||||
"rating" -> u.rating.int,
|
||||
"provisional" -> u.rating.provisional
|
||||
).noNull
|
||||
},
|
||||
"destUserId" -> c.destUserId,
|
||||
"variant" -> Json.obj(
|
||||
|
@ -28,12 +31,13 @@ final class JsonView(getLightUser: String => Option[lila.common.LightUser]) {
|
|||
"name" -> c.variant.name),
|
||||
"rated" -> c.mode.rated,
|
||||
"timeControl" -> (c.timeControl match {
|
||||
case TimeControl.Clock(l, i) => Json.obj(
|
||||
case c@TimeControl.Clock(l, i) => Json.obj(
|
||||
"type" -> "clock",
|
||||
"limit" -> l,
|
||||
"increment" -> i)
|
||||
"increment" -> i,
|
||||
"show" -> c.show)
|
||||
case TimeControl.Correspondence(d) => Json.obj(
|
||||
"type" -> "clock",
|
||||
"type" -> "correspondence",
|
||||
"daysPerTurn" -> d)
|
||||
case TimeControl.Unlimited => Json.obj("type" -> "unlimited")
|
||||
}),
|
||||
|
|
|
@ -346,10 +346,9 @@ lichess.challengeBox = (function() {
|
|||
var baseUrl = $('body').data('asset-url');
|
||||
var isDev = $('body').data('dev');
|
||||
$('head').append($('<link rel="stylesheet" type="text/css" />')
|
||||
.attr('href', baseUrl + '/assets/stylesheet/challenge.css'));
|
||||
$.getScript(baseUrl + "/assets/compiled/challenge" + (isDev ? '.min' : '') + '.js').done(function() {
|
||||
instance = LichessChallenge({
|
||||
element: document.getElementById('#challenge_notifications'),
|
||||
.attr('href', baseUrl + '/assets/stylesheet/challengeBox.css'));
|
||||
$.getScript(baseUrl + "/assets/compiled/lichess.challenge" + (isDev ? '' : '.min') + '.js').done(function() {
|
||||
instance = LichessChallenge(document.getElementById('challenge_notifications'), {
|
||||
setCount: function(nb) {
|
||||
$('#challenge_notifications_tag').attr('data-count', nb).toggleClass('none', !nb);
|
||||
}
|
||||
|
@ -1114,9 +1113,9 @@ lichess.unique = function(xs) {
|
|||
}
|
||||
});
|
||||
});
|
||||
$('#challenge_notifications').one('mouseover', function() {
|
||||
$('#challenge_notifications_tag').one('mouseover click', function() {
|
||||
lichess.challengeBox.load();
|
||||
});
|
||||
}).trigger('click');
|
||||
|
||||
$('#translation_call .close').click(function() {
|
||||
$.post($(this).data("href"));
|
||||
|
|
|
@ -6,12 +6,20 @@ module.exports = function(env) {
|
|||
|
||||
this.data = env.data;
|
||||
|
||||
this.userId = env.userId;
|
||||
|
||||
this.socket = new socket(env.socketSend, this);
|
||||
|
||||
this.vm = {
|
||||
initiating: true,
|
||||
reloading: false
|
||||
};
|
||||
|
||||
this.update = function(data) {
|
||||
this.data = data;
|
||||
this.vm.initiating = false;
|
||||
this.vm.reloading = false;
|
||||
}.bind(this);
|
||||
|
||||
xhr.load();
|
||||
|
||||
this.trans = lichess.trans(env.i18n);
|
||||
};
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
var m = require('mithril');
|
||||
var ctrl = require('./ctrl');
|
||||
|
||||
module.exports = function(element, opts) {
|
||||
|
||||
var controller = new ctrl(opts);
|
||||
|
||||
m.module(element, {
|
||||
controller: function() {
|
||||
return {
|
||||
data: opts.data
|
||||
};
|
||||
return controller;
|
||||
},
|
||||
view: require('./view')
|
||||
});
|
||||
|
|
|
@ -1,6 +1,55 @@
|
|||
var m = require('mithril');
|
||||
|
||||
function user(u) {
|
||||
var rating = u.rating + (u.provisional ? '?' : '');
|
||||
var fullName = (u.title ? u.title + ' ' : '') + u.name;
|
||||
return {
|
||||
tag: 'a',
|
||||
attrs: {
|
||||
class: 'ulpt user_link',
|
||||
'data-href': '/@/' + u.name
|
||||
},
|
||||
children: [
|
||||
fullName,
|
||||
m('span.progress', [rating, ratingDiff])
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
function timeControl(c) {
|
||||
switch (c.type) {
|
||||
case 'unlimited':
|
||||
return 'Unlimited';
|
||||
case 'correspondence':
|
||||
return c.daysPerTurn + ' days';
|
||||
case 'clock':
|
||||
return c.show;
|
||||
}
|
||||
}
|
||||
|
||||
function challenge(c) {
|
||||
return m('div.challenge', [
|
||||
m('i', {
|
||||
'data-icon': c.perf.icon
|
||||
}),
|
||||
m('div.content', [
|
||||
m('span.title', user(c.challenger)),
|
||||
m('span.desc', [
|
||||
c.rated ? 'Rated' : 'Casual',
|
||||
timeControl(c.timeControl),
|
||||
c.variant.name
|
||||
].join(' '))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = function(ctrl) {
|
||||
if (ctrl.vm.initiating) return m('div.square-wrap', m('div.square-spin'));
|
||||
var d = ctrl.data;
|
||||
return m('div.challenges', 'hehe');
|
||||
return m('div', {
|
||||
class: 'challenges ' + (ctrl.vm.reloading ? ' reloading' : '')
|
||||
}, [
|
||||
d.in.map(challenge),
|
||||
d.out.map(challenge),
|
||||
])
|
||||
};
|
||||
|
|
|
@ -10,4 +10,11 @@ function uncache(url) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
load: function() {
|
||||
return m.request({
|
||||
method: 'GET',
|
||||
url: uncache('/challenge'),
|
||||
config: xhrConfig,
|
||||
}).then(ctrl.update);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue