Merge branch 'master' of github.com:ornicar/lila

* 'master' of github.com:ornicar/lila:
  Neaten messages power tip
  Ensure count never falls below zero
  Iron out more bugs
  Fix mistakes, neaten code
  Challenge notifications drop-down
  Sleeker challenge notification
  Add data-hint to bookmark button
  Lower sound play frequency
  If you can't fix it, make it look intentional
This commit is contained in:
Thibault Duplessis 2014-11-24 23:51:19 +01:00
commit 978821034e
8 changed files with 166 additions and 69 deletions

View file

@ -184,6 +184,15 @@ openGraph: Map[Symbol, String] = Map.empty)(body: Html)(implicit ctx: Context)
<span class="is2" data-icon="e"></span>
<span id="nb_messages" class="new_messages@if(ctx.nbMessages > 0) { unread}">@ctx.nbMessages</span>
</a>
<div class="challenge_notifications">
<a id="challenge_notifications_tag" class="toggle toggle_challenge_notifications">
<span data-icon="U"></span>
<span id="nb_challenges" class="new_challenges">0</span>
</a>
<div id="challenge_notifications" class="links dropdown">
<div class="title">Pending challenges</div>
</div>
</div>
}.getOrElse {
<a href="@routes.Auth.login" class="signin button" data-icon="F">&nbsp;@trans.signIn()</a>
}

View file

@ -1,7 +1,7 @@
@(g: Game)(implicit ctx: Context)
@ctx.me.map { m =>
<a class="bookmark@isBookmarked(g, m).fold(" bookmarked", "")" href="@routes.Bookmark.toggle(g.id)" title="@trans.bookmarkThisGame()">
<a class="bookmark@isBookmarked(g, m).fold(" bookmarked", "") hint--left" href="@routes.Bookmark.toggle(g.id)" data-hint="@trans.bookmarkThisGame()">
<span data-icon="t" class="on is3"> @g.showBookmarks</span>
<span data-icon="s" class="off is3"> @g.showBookmarks</span>
</a>

View file

@ -13,9 +13,9 @@
case _ => {8}
}">
@bookmark.toggle(game)
<div class="header">
<span class="setup">
@bookmark.toggle(game)
@game.clock.map(_.show).getOrElse {
<span data-hint="@trans.unlimited()" class="hint--top"></span>
} •

View file

@ -1,12 +1,33 @@
@(g: Game, user: User)
@notification.view("challenge_reminder_" + g.id, cssClass = "challenge_reminder foldable glowing", closable = false) {
@userLink(user)<br />
@trans.challengeToPlay.en()<br />
@clockNameNoCtx(g.clock)<br />
@game.variantLink(g.variant, variantNameNoCtx(g.variant), hintAsTitle = true), @modeNameNoCtx(g.mode)
<div class="actions">
<a class="action decline" href="@routes.Setup.decline(g.id)" data-icon="L">&nbsp;@trans.decline.en()</a>
<a class="action" href="@routes.Round.watcher(g.id, "white")" data-icon="v">&nbsp;View challenge</a>
</div>
}
<div id="challenge_reminder_@g.id" class="notification challenge_reminder">
<a class="notification_link" href="@routes.Round.watcher(g.id, "white")"></a>
<div class="inner">
<div class="actions">
<a class="action decline" href="@routes.Setup.decline(g.id)" data-icon="L">&nbsp;</a>
</div>
<div class="game_infos" data-icon="@g.perfType match {
case _ if g.fromPosition => {*}
case _ if g.hasAi => {:}
case _ if g.imported => {/}
case Some(p) => {@p.iconChar}
case _ => {8}
}">
<div class="header">
<b>@usernameOrId(user.id)</b><br />
<span class="setup">
@g.clock.map(_.show).getOrElse {∞} •
@if(g.variant.exotic) {
@((if (g.variant == chess.Variant.KingOfTheHill) g.variant.shortName else g.variant.name).toUpperCase)
} else {
@g.perfType.map { pt =>
@pt.name.toUpperCase
}
} • @g.rated.fold(trans.rated.en(), trans.casual.en()).toUpperCase
</span>
</div>
</div>
</div>
</div>

View file

@ -148,6 +148,16 @@ var storage = {
},
challengeReminder: function(data) {
if (!storage.get('challenge-refused-' + data.id)) {
var nbChallenges = function() {
var nb = parseInt($('#nb_challenges').text());
return nb ? ((nb > 0) ? nb : 0) : 0;
};
var nbChallengesAdd = function() {
$('#nb_challenges').text(nbChallenges() + 1).toggleClass("unread", true);
};
var nbChallengesMinus = function() {
$('#nb_challenges').text(nbChallenges() - 1).toggleClass("unread", nbChallenges() > 0);
};
var htmlId = 'challenge_reminder_' + data.id;
var $notif = $('#' + htmlId);
var declineListener = function($a, callback) {
@ -156,12 +166,14 @@ var storage = {
storage.set('challenge-refused-' + data.id, 1);
$('#' + htmlId).remove();
if ($.isFunction(callback)) callback();
nbChallengesMinus();
return false;
});
};
if ($notif.length) clearTimeout($notif.data('timeout'));
else {
$('#notifications').append(data.html);
nbChallengesAdd();
$('#challenge_notifications').append(data.html);
$notif = $('#' + htmlId).one('mouseover', function() {
$(this).removeClass('glowing glow');
});
@ -182,6 +194,7 @@ var storage = {
});
$notif.data('timeout', setTimeout(function() {
$notif.remove();
nbChallengesMinus();
}, 3000));
}
},

View file

@ -613,6 +613,7 @@ body.tight #site_baseline {
}
#footer_wrap {
border-top: 1px solid #c9c9c9;
border-bottom: 1px solid #c9c9c9;
background: #e4e4e4;
padding: 30px 0;
margin-top: 60px;
@ -803,13 +804,17 @@ div.side_box .top {
div.side_box .padded {
padding: 7px;
}
.notification .game_infos,
div.side_box .game_infos {
padding-left: 36px;
padding-bottom: 8px;
border-bottom: 1px solid #ccc;
margin-bottom: 6px;
position: relative;
}
div.side_box .game_infos {
border-bottom: 1px solid #ccc;
padding-bottom: 8px;
margin-bottom: 6px;
}
.notification .game_infos::before,
div.side_box .game_infos::before {
position: absolute;
top: 2px;
@ -926,7 +931,8 @@ body.offline #nb_connected_players {
color: #303030;
border-color: #d85000;
}
#top span.new_messages {
#top span.new_messages,
#top span.new_challenges {
display: none;
padding: 1px 5px 1px 4px;
background: #bbb;
@ -935,7 +941,8 @@ body.offline #nb_connected_players {
border-radius: 2px;
font-size: 0.9em;
}
#top span.new_messages.unread {
#top span.new_messages.unread,
#top span.new_challenges.unread {
display: inline;
}
#top .shown a.toggle {
@ -951,13 +958,16 @@ body.offline #nb_connected_players {
#user_tag {
font-weight: bold;
}
#top div.challenge_notifications,
#top div.auth {
float: right;
position: relative;
}
#top div.challenge_notifications.shown .links,
#top div.auth.shown .links {
display: block;
}
#top div.challenge_notifications .links > a,
#top div.auth .links > a {
display: block;
padding: 5px 10px;
@ -988,6 +998,84 @@ body.offline #nb_connected_players {
display: block;
padding: 5px 10px 10px 10px;
}
#top #challenge_notifications_tag span:before {
padding-left: 3px;
}
#top #challenge_notifications div.title {
padding: 5px 3% 5px 3%;
text-align: center;
}
.notification a.notification_link {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
text-decoration: none;
z-index: 3;
}
#challenge_notifications > div.notification {
border-top: 1px solid #c0c0c0;
padding: 6px 8px 7px 8px;
position: relative;
}
#challenge_notifications > div.notification:hover {
background-color: #f0f0f0;
}
#challenge_notifications,
#notifications {
position: absolute;
top: -20px;
left: -30px;
width: 228px;
z-index: 2;
}
#notifications > div {
border: 1px solid #c0c0c0;
padding: 6px 8px 7px 8px;
margin-bottom: 8px;
border-radius: 2px;
box-shadow: 0 0 3px 0px #d85000;
transition: box-shadow 1.5s;
}
#notifications > div.foldable {
line-height: 1.6em;
height: 1.5em;
overflow: hidden;
}
#notifications > div.foldable:hover {
line-height: inherit;
height: auto;
}
#challenge_notifications > div a.close,
#notifications > div a.close {
text-decoration: none;
float: right;
}
#challenge_notifications > div a.close:hover,
#notifications > div a.close:hover {
font-weight: bold;
}
#challenge_notifications .actions,
#notifications .actions {
position: relative;
float: right;
z-index: 4;
text-decoration: none;
}
#challenge_notifications a,
#notifications a {
font-weight: bold;
text-decoration: none;
}
#challenge_notifications .actions a,
#notifications .actions a {
margin-left: 10px;
}
#challenge_notifications .actions a:hover,
#notifications .actions a:hover {
color: #d85000;
}
form.wide input[type="text"],
form.wide textarea {
padding: 0.5em;
@ -1366,7 +1454,8 @@ a.button:active {
div.pagination span.current,
#top span.new_messages,
div.progressbar.flashy div,
#import_game .progression {
#import_game .progression,
#top span.new_challenges {
color: #fff !important;
text-shadow: 0px 1px 0px #000 !important;
background: #d85000 !important;
@ -1759,52 +1848,6 @@ div.progressbar.flashy.green div {
.glow {
box-shadow: 0 0 5px 2px #fff, 0 0 10px 3px #e89000, 0 0 20px 3px #d85000!important;
}
#notifications {
position: absolute;
top: -20px;
left: -30px;
width: 228px;
z-index: 2;
}
#notifications > div {
border: 1px solid #c0c0c0;
padding: 6px 8px 7px 8px;
margin-bottom: 8px;
border-radius: 2px;
box-shadow: 0 0 3px 0px #d85000;
transition: all 1.5s;
}
#notifications > div.foldable {
line-height: 1.6em;
height: 1.5em;
overflow: hidden;
}
#notifications > div.foldable:hover {
line-height: inherit;
height: auto;
}
#notifications > div a.close {
text-decoration: none;
float: right;
}
#notifications > div a.close:hover {
font-weight: bold;
}
#notifications .actions {
text-align: right;
width: 100%;
margin: 3px 0 3px 0;
}
#notifications a {
font-weight: bold;
text-decoration: none;
}
#notifications .actions a {
margin-left: 10px;
}
#notifications a:hover {
text-decoration: underline;
}
a.hover_text > .base,
a.hover_text:hover > .hover {
display: inline-block;
@ -1845,7 +1888,7 @@ input.copyable {
border: 1px solid #ccc;
}
#powerTip.messages {
width: 500px;
max-width: 500px;
padding: 1em;
min-height: 1em;
}

View file

@ -124,7 +124,8 @@ body.dark div.doc_box h2,
body.dark div.training div.box,
body.dark div.force_resign_zone,
body.dark div.negotiation,
body.dark div.side_box div.game_infos {
body.dark div.side_box div.game_infos,
body.dark #challenge_notifications > div.notification {
border-color: #3d3d3d;
}
body.dark .crosstable td.last {
@ -136,7 +137,8 @@ body.dark #hooks_wrap > div.tabs > a.active {
body.dark .ui-slider,
body.dark div.progressbar,
body.dark #translation_call div.progressbar,
body.dark #themepicker div.theme:hover {
body.dark #themepicker div.theme:hover,
body.dark #challenge_notifications > div.notification:hover {
background-color: #505050;
}
body.dark #hooks_wrap > div.tabs > a,

View file

@ -8,6 +8,11 @@ module.exports = function(data, onFlag, soundColor) {
delay: 5000
};
var soundPlayable = {
white: true,
black: true
}
this.data = data;
this.data.barTime = Math.max(this.data.initial, 2) + 5 * this.data.increment;
@ -31,11 +36,15 @@ module.exports = function(data, onFlag, soundColor) {
this.data[color] = Math.max(0, lastUpdate[color] - (new Date() - lastUpdate.at) / 1000);
if (this.data[color] === 0) onFlag();
m.endComputation();
if (soundColor == color && this.data[soundColor] < this.data.emerg) {
if (soundColor == color && this.data[soundColor] < this.data.emerg && soundPlayable[soundColor] == true) {
if (!emergSound.last || (data.increment && new Date() - emergSound.delay > emergSound.last)) {
emergSound.play();
emergSound.last = new Date();
soundPlayable[soundColor] = false;
}
}
if (soundColor == color && this.data[soundColor] > 2*this.data.emerg && soundPlayable[soundColor] == false) {
soundPlayable[soundColor] = true;
}
}.bind(this);
}