mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Smooth reload animation
This commit is contained in:
parent
de06ab1a41
commit
18931eaca0
6 changed files with 97 additions and 16 deletions
50
dev/External/ko.js
vendored
50
dev/External/ko.js
vendored
|
|
@ -938,23 +938,59 @@
|
||||||
|
|
||||||
ko.extenders.falseTimeout = function (oTarget, iOption)
|
ko.extenders.falseTimeout = function (oTarget, iOption)
|
||||||
{
|
{
|
||||||
var Utils = require('Common/Utils');
|
oTarget.iFalseTimeoutTimeout = 0;
|
||||||
|
|
||||||
oTarget.iTimeout = 0;
|
|
||||||
oTarget.subscribe(function (bValue) {
|
oTarget.subscribe(function (bValue) {
|
||||||
if (bValue)
|
if (bValue)
|
||||||
{
|
{
|
||||||
window.clearTimeout(oTarget.iTimeout);
|
window.clearTimeout(oTarget.iFalseTimeoutTimeout);
|
||||||
oTarget.iTimeout = window.setTimeout(function () {
|
oTarget.iFalseTimeoutTimeout = window.setTimeout(function () {
|
||||||
oTarget(false);
|
oTarget(false);
|
||||||
oTarget.iTimeout = 0;
|
oTarget.iFalseTimeoutTimeout = 0;
|
||||||
}, Utils.pInt(iOption));
|
}, require('Common/Utils').pInt(iOption));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return oTarget;
|
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
|
// functions
|
||||||
|
|
||||||
ko.observable.fn.validateNone = function ()
|
ko.observable.fn.validateNone = function ()
|
||||||
|
|
|
||||||
|
|
@ -662,9 +662,10 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} oExcludeEmails
|
* @param {Object} oExcludeEmails
|
||||||
|
* @param {boolean=} bLast = false
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
MessageModel.prototype.replyEmails = function (oExcludeEmails)
|
MessageModel.prototype.replyEmails = function (oExcludeEmails, bLast)
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
aResult = [],
|
aResult = [],
|
||||||
|
|
@ -677,16 +678,23 @@
|
||||||
MessageHelper.replyHelper(this.from, oUnic, aResult);
|
MessageHelper.replyHelper(this.from, oUnic, aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 === aResult.length && !bLast)
|
||||||
|
{
|
||||||
|
return this.replyEmails({}, true);
|
||||||
|
}
|
||||||
|
|
||||||
return aResult;
|
return aResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} oExcludeEmails
|
* @param {Object} oExcludeEmails
|
||||||
|
* @param {boolean=} bLast = false
|
||||||
* @return {Array.<Array>}
|
* @return {Array.<Array>}
|
||||||
*/
|
*/
|
||||||
MessageModel.prototype.replyAllEmails = function (oExcludeEmails)
|
MessageModel.prototype.replyAllEmails = function (oExcludeEmails, bLast)
|
||||||
{
|
{
|
||||||
var
|
var
|
||||||
|
aData = [],
|
||||||
aToResult = [],
|
aToResult = [],
|
||||||
aCcResult = [],
|
aCcResult = [],
|
||||||
oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails
|
oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails
|
||||||
|
|
@ -701,6 +709,12 @@
|
||||||
MessageHelper.replyHelper(this.to, oUnic, aToResult);
|
MessageHelper.replyHelper(this.to, oUnic, aToResult);
|
||||||
MessageHelper.replyHelper(this.cc, oUnic, aCcResult);
|
MessageHelper.replyHelper(this.cc, oUnic, aCcResult);
|
||||||
|
|
||||||
|
if (0 === aToResult.length && !bLast)
|
||||||
|
{
|
||||||
|
aData = this.replyAllEmails({}, true);
|
||||||
|
return [aData[0], aCcResult];
|
||||||
|
}
|
||||||
|
|
||||||
return [aToResult, aCcResult];
|
return [aToResult, aCcResult];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@
|
||||||
this.messageListLoading = ko.observable(false);
|
this.messageListLoading = ko.observable(false);
|
||||||
this.messageListIsNotCompleted = ko.observable(false);
|
this.messageListIsNotCompleted = ko.observable(false);
|
||||||
this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
|
this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
|
||||||
|
this.messageListCompleteLoadingThrottleForAnimation = ko.observable(false).extend({'specialThrottle': 700});
|
||||||
|
|
||||||
this.messageListDisableAutoSelect = ko.observable(false).extend({'falseTimeout': 500});
|
this.messageListDisableAutoSelect = ko.observable(false).extend({'falseTimeout': 500});
|
||||||
|
|
||||||
|
|
@ -164,7 +165,9 @@
|
||||||
MessageUserStore.prototype.subscribers = function ()
|
MessageUserStore.prototype.subscribers = function ()
|
||||||
{
|
{
|
||||||
this.messageListCompleteLoading.subscribe(function (bValue) {
|
this.messageListCompleteLoading.subscribe(function (bValue) {
|
||||||
|
bValue = !!bValue;
|
||||||
this.messageListCompleteLoadingThrottle(bValue);
|
this.messageListCompleteLoadingThrottle(bValue);
|
||||||
|
this.messageListCompleteLoadingThrottleForAnimation(bValue);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
this.messageList.subscribe(_.debounce(function (aList) {
|
this.messageList.subscribe(_.debounce(function (aList) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@
|
||||||
0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); }
|
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 {
|
@keyframes textLoadingAnimationKeyFrame {
|
||||||
0% { opacity: 1; } 33% { opacity: 0; } 100% { opacity: 1; }
|
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);
|
.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 {
|
&.csstransitions.no-mobile .b-login-content .loginFormWrapper {
|
||||||
.transition(all 0.3s ease-out);
|
.transition(all 0.3s ease-out);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@
|
||||||
this.messageListCheckedOrSelected = MessageStore.messageListCheckedOrSelected;
|
this.messageListCheckedOrSelected = MessageStore.messageListCheckedOrSelected;
|
||||||
this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails;
|
this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails;
|
||||||
this.messageListCompleteLoadingThrottle = MessageStore.messageListCompleteLoadingThrottle;
|
this.messageListCompleteLoadingThrottle = MessageStore.messageListCompleteLoadingThrottle;
|
||||||
|
this.messageListCompleteLoadingThrottleForAnimation = MessageStore.messageListCompleteLoadingThrottleForAnimation;
|
||||||
|
|
||||||
Translator.initOnStartOrLangChange(function () {
|
Translator.initOnStartOrLangChange(function () {
|
||||||
this.emptySubjectValue = Translator.i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT');
|
this.emptySubjectValue = Translator.i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT');
|
||||||
|
|
@ -174,6 +175,18 @@
|
||||||
return Consts.Values.UnuseOptionValue === FolderStore.archiveFolder();
|
return Consts.Values.UnuseOptionValue === FolderStore.archiveFolder();
|
||||||
}, this);
|
}, 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.canBeMoved = this.hasCheckedOrSelectedLines;
|
||||||
|
|
||||||
this.clearCommand = Utils.createCommand(this, function () {
|
this.clearCommand = Utils.createCommand(this, function () {
|
||||||
|
|
@ -218,7 +231,7 @@
|
||||||
this.moveCommand = Utils.createCommand(this, Utils.emptyFunction, this.canBeMoved);
|
this.moveCommand = Utils.createCommand(this, Utils.emptyFunction, this.canBeMoved);
|
||||||
|
|
||||||
this.reloadCommand = Utils.createCommand(this, function () {
|
this.reloadCommand = Utils.createCommand(this, function () {
|
||||||
if (!MessageStore.messageListCompleteLoadingThrottle())
|
if (!MessageStore.messageListCompleteLoadingThrottleForAnimation())
|
||||||
{
|
{
|
||||||
require('App/User').reloadMessageList(false, true);
|
require('App/User').reloadMessageList(false, true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="btn-toolbar">
|
<div class="btn-toolbar">
|
||||||
<div class="btn-group">
|
<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'">
|
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group"> </div>
|
<div class="btn-group"> </div>
|
||||||
|
|
@ -29,16 +29,23 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group"> </div>
|
<div class="btn-group"> </div>
|
||||||
<div class="btn-group">
|
<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>
|
<i class="icon-archive"></i>
|
||||||
</a>
|
</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>
|
<i class="icon-angry-smiley"></i>
|
||||||
</a>
|
</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>
|
<i class="icon-happy-smiley"></i>
|
||||||
</a>
|
</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>
|
<i class="icon-trash"></i>
|
||||||
<!--<span data-bind="text: printableMessageCountForDeletion()"></span>-->
|
<!--<span data-bind="text: printableMessageCountForDeletion()"></span>-->
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -46,7 +53,7 @@
|
||||||
<div class="btn-group"> </div>
|
<div class="btn-group"> </div>
|
||||||
<div class="btn-group dropdown colored-toggle" data-bind="registrateBootstrapDropdown: true, openDropdownTrigger: moreDropdownTrigger">
|
<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'">
|
<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>
|
</a>
|
||||||
<ul class="dropdown-menu g-ui-menu" role="menu" aria-labelledby="more-list-dropdown-id">
|
<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()}">
|
<li class="e-item" role="presentation" data-bind="click: listUnsetSeen, css: {'disabled': !hasCheckedOrSelectedLines()}">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue