Smooth reload animation

This commit is contained in:
RainLoop Team 2015-03-31 04:12:05 +04:00
parent de06ab1a41
commit 18931eaca0
6 changed files with 97 additions and 16 deletions

50
dev/External/ko.js vendored
View file

@ -938,23 +938,59 @@
ko.extenders.falseTimeout = function (oTarget, iOption)
{
var Utils = require('Common/Utils');
oTarget.iTimeout = 0;
oTarget.iFalseTimeoutTimeout = 0;
oTarget.subscribe(function (bValue) {
if (bValue)
{
window.clearTimeout(oTarget.iTimeout);
oTarget.iTimeout = window.setTimeout(function () {
window.clearTimeout(oTarget.iFalseTimeoutTimeout);
oTarget.iFalseTimeoutTimeout = window.setTimeout(function () {
oTarget(false);
oTarget.iTimeout = 0;
}, Utils.pInt(iOption));
oTarget.iFalseTimeoutTimeout = 0;
}, require('Common/Utils').pInt(iOption));
}
});
return oTarget;
};
ko.extenders.specialThrottle = function (oTarget, iOption)
{
oTarget.iSpecialThrottleTimeoutValue = require('Common/Utils').pInt(iOption);
if (0 < oTarget.iSpecialThrottleTimeoutValue)
{
oTarget.iSpecialThrottleTimeout = 0;
oTarget.valueForRead = ko.observable(!!oTarget()).extend({'throttle': 10});
return ko.computed({
'read': oTarget.valueForRead,
'write': function (bValue) {
if (bValue)
{
oTarget.valueForRead(bValue);
}
else
{
if (oTarget.valueForRead())
{
window.clearTimeout(oTarget.iSpecialThrottleTimeout);
oTarget.iSpecialThrottleTimeout = window.setTimeout(function () {
oTarget.valueForRead(false);
oTarget.iSpecialThrottleTimeout = 0;
}, oTarget.iSpecialThrottleTimeoutValue);
}
else
{
oTarget.valueForRead(bValue);
}
}
}
});
}
return oTarget;
};
// functions
ko.observable.fn.validateNone = function ()

View file

@ -662,9 +662,10 @@
/**
* @param {Object} oExcludeEmails
* @param {boolean=} bLast = false
* @return {Array}
*/
MessageModel.prototype.replyEmails = function (oExcludeEmails)
MessageModel.prototype.replyEmails = function (oExcludeEmails, bLast)
{
var
aResult = [],
@ -677,16 +678,23 @@
MessageHelper.replyHelper(this.from, oUnic, aResult);
}
if (0 === aResult.length && !bLast)
{
return this.replyEmails({}, true);
}
return aResult;
};
/**
* @param {Object} oExcludeEmails
* @param {boolean=} bLast = false
* @return {Array.<Array>}
*/
MessageModel.prototype.replyAllEmails = function (oExcludeEmails)
MessageModel.prototype.replyAllEmails = function (oExcludeEmails, bLast)
{
var
aData = [],
aToResult = [],
aCcResult = [],
oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails
@ -701,6 +709,12 @@
MessageHelper.replyHelper(this.to, oUnic, aToResult);
MessageHelper.replyHelper(this.cc, oUnic, aCcResult);
if (0 === aToResult.length && !bLast)
{
aData = this.replyAllEmails({}, true);
return [aData[0], aCcResult];
}
return [aToResult, aCcResult];
};

View file

@ -51,6 +51,7 @@
this.messageListLoading = ko.observable(false);
this.messageListIsNotCompleted = ko.observable(false);
this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
this.messageListCompleteLoadingThrottleForAnimation = ko.observable(false).extend({'specialThrottle': 700});
this.messageListDisableAutoSelect = ko.observable(false).extend({'falseTimeout': 500});
@ -164,7 +165,9 @@
MessageUserStore.prototype.subscribers = function ()
{
this.messageListCompleteLoading.subscribe(function (bValue) {
bValue = !!bValue;
this.messageListCompleteLoadingThrottle(bValue);
this.messageListCompleteLoadingThrottleForAnimation(bValue);
}, this);
this.messageList.subscribe(_.debounce(function (aList) {

View file

@ -9,6 +9,10 @@
0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); }
}
@keyframes bounce-me {
0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); }
}
@keyframes textLoadingAnimationKeyFrame {
0% { opacity: 1; } 33% { opacity: 0; } 100% { opacity: 1; }
}
@ -56,6 +60,10 @@ html.csstransitions.rl-started-trigger.no-mobile .b-login-content .loginFormWrap
.transition(opacity 0.3s ease-out);
}*/
&.csstransitions.no-mobile .btn-group.dropdown.colored-toggle.open .animate-this-icon-on-open {
animation: bounce-me .5s linear;
}
&.csstransitions.no-mobile .b-login-content .loginFormWrapper {
.transition(all 0.3s ease-out);
}

View file

@ -70,6 +70,7 @@
this.messageListCheckedOrSelected = MessageStore.messageListCheckedOrSelected;
this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails;
this.messageListCompleteLoadingThrottle = MessageStore.messageListCompleteLoadingThrottle;
this.messageListCompleteLoadingThrottleForAnimation = MessageStore.messageListCompleteLoadingThrottleForAnimation;
Translator.initOnStartOrLangChange(function () {
this.emptySubjectValue = Translator.i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT');
@ -174,6 +175,18 @@
return Consts.Values.UnuseOptionValue === FolderStore.archiveFolder();
}, this);
this.isArchiveVisible = ko.computed(function () {
return !this.isArchiveFolder() && !this.isArchiveDisabled() && !this.isDraftFolder();
}, this);
this.isSpamVisible = ko.computed(function () {
return !this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder();
}, this);
this.isUnSpamVisible = ko.computed(function () {
return this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder();
}, this);
this.canBeMoved = this.hasCheckedOrSelectedLines;
this.clearCommand = Utils.createCommand(this, function () {
@ -218,7 +231,7 @@
this.moveCommand = Utils.createCommand(this, Utils.emptyFunction, this.canBeMoved);
this.reloadCommand = Utils.createCommand(this, function () {
if (!MessageStore.messageListCompleteLoadingThrottle())
if (!MessageStore.messageListCompleteLoadingThrottleForAnimation())
{
require('App/User').reloadMessageList(false, true);
}

View file

@ -5,7 +5,7 @@
<div class="btn-toolbar">
<div class="btn-group">
<a class="btn single btn-dark-disabled-border buttonReload" data-tooltip-placement="bottom" data-bind="command: reloadCommand, tooltip: 'MESSAGE_LIST/BUTTON_RELOAD'">
<i class="icon-spinner" data-bind="css: {'animated': messageListCompleteLoadingThrottle}"></i>
<i class="icon-spinner" data-bind="css: {'animated': messageListCompleteLoadingThrottleForAnimation}"></i>
</a>
</div>
<div class="btn-group">&nbsp;</div>
@ -29,16 +29,23 @@
</div>
<div class="btn-group">&nbsp;</div>
<div class="btn-group">
<a class="btn first btn-dark-disabled-border button-archive" data-tooltip-placement="bottom" data-bind="visible: !isArchiveFolder() && !isArchiveDisabled() && !isDraftFolder(), command: archiveCommand, tooltip: 'MESSAGE_LIST/BUTTON_ARCHIVE'">
<a class="btn first btn-dark-disabled-border button-archive" data-tooltip-placement="bottom"
data-bind="visible: isArchiveVisible, command: archiveCommand, tooltip: 'MESSAGE_LIST/BUTTON_ARCHIVE'">
<i class="icon-archive"></i>
</a>
<a class="btn btn-dark-disabled-border button-spam" data-tooltip-placement="bottom" data-bind="visible: !isSpamFolder() && !isSpamDisabled() && !isDraftFolder() && !isSentFolder(), command: spamCommand, tooltip: 'MESSAGE_LIST/BUTTON_SPAM'">
<a class="btn btn-dark-disabled-border button-spam" data-tooltip-placement="bottom"
data-bind="visible: isSpamVisible, command: spamCommand, tooltip: 'MESSAGE_LIST/BUTTON_SPAM',
css: {'first': !isArchiveVisible()}">
<i class="icon-angry-smiley"></i>
</a>
<a class="btn btn-dark-disabled-border button-not-spam" data-tooltip-placement="bottom" data-bind="visible: isSpamFolder() && !isSpamDisabled() && !isDraftFolder() && !isSentFolder(), command: notSpamCommand, tooltip: 'MESSAGE_LIST/BUTTON_NOT_SPAM'">
<a class="btn btn-dark-disabled-border button-not-spam" data-tooltip-placement="bottom"
data-bind="visible: isUnSpamVisible, command: notSpamCommand, tooltip: 'MESSAGE_LIST/BUTTON_NOT_SPAM',
css: {'first': !isArchiveVisible()}">
<i class="icon-happy-smiley"></i>
</a>
<a class="btn last btn-dark-disabled-border button-delete" data-tooltip-placement="bottom" data-bind="command: deleteCommand, tooltip: 'MESSAGE_LIST/BUTTON_DELETE'">
<a class="btn last btn-dark-disabled-border button-delete" data-tooltip-placement="bottom"
data-bind="command: deleteCommand, tooltip: 'MESSAGE_LIST/BUTTON_DELETE',
css: {'first': !isArchiveVisible() && !isSpamVisible() && !isUnSpamVisible()}">
<i class="icon-trash"></i>
<!--<span data-bind="text: printableMessageCountForDeletion()"></span>-->
</a>
@ -46,7 +53,7 @@
<div class="btn-group">&nbsp;</div>
<div class="btn-group dropdown colored-toggle" data-bind="registrateBootstrapDropdown: true, openDropdownTrigger: moreDropdownTrigger">
<a id="more-list-dropdown-id" class="btn single btn-dark-disabled-border dropdown-toggle buttonMore" href="#" tabindex="-1" data-toggle="dropdown" data-tooltip-placement="bottom" data-bind="tooltip: 'MESSAGE_LIST/BUTTON_MORE'">
<i class="icon-list"></i>
<i class="icon-list animate-this-icon-on-open"></i>
</a>
<ul class="dropdown-menu g-ui-menu" role="menu" aria-labelledby="more-list-dropdown-id">
<li class="e-item" role="presentation" data-bind="click: listUnsetSeen, css: {'disabled': !hasCheckedOrSelectedLines()}">