diff --git a/dev/Model/Attachment.js b/dev/Model/Attachment.js index 456c6ef29..9d4524f50 100644 --- a/dev/Model/Attachment.js +++ b/dev/Model/Attachment.js @@ -192,6 +192,37 @@ return Links.attachmentPreviewAsPlain(this.download); }; + /** + * @return {string} + */ + AttachmentModel.prototype.linkPreviewMain = function () + { + var sResult = ''; + switch (true) + { + case this.isImage(): + case this.isPdf(): + sResult = this.linkPreview(); + break; + case this.isText(): + sResult = this.linkPreviewAsPlain(); + break; + case this.isFramed(): + sResult = this.linkFramed(); + break; + } + + return sResult; + }; + + /** + * @return {boolean} + */ + AttachmentModel.prototype.hasPreview = function () + { + return this.isImage() || this.isPdf() || this.isText() || this.isFramed(); + }; + /** * @return {string} */ diff --git a/dev/Storage/User/Data.js b/dev/Storage/User/Data.js index e9bcaa729..485773641 100644 --- a/dev/Storage/User/Data.js +++ b/dev/Storage/User/Data.js @@ -437,6 +437,7 @@ }, this); // other + this.composeInEdit = ko.observable(false); this.capaOpenPGP = ko.observable(false); this.openpgpkeys = ko.observableArray([]); this.openpgp = null; diff --git a/dev/Styles/Compose.less b/dev/Styles/Compose.less index e2e1ae4eb..be59d8f7a 100644 --- a/dev/Styles/Compose.less +++ b/dev/Styles/Compose.less @@ -41,6 +41,10 @@ margin-left: 8px; } + .button-close, .button-skip { + margin-left: 8px; + } + .disabled.button-delete { margin-left: 0px; } diff --git a/dev/Styles/MessageView.less b/dev/Styles/MessageView.less index 159ca78fb..61f2d45b9 100644 --- a/dev/Styles/MessageView.less +++ b/dev/Styles/MessageView.less @@ -253,34 +253,52 @@ html.rl-no-preview-pane { border-radius: 2px; .attachmentIconParent { + + position: relative; + height: 56px; width: 60px; background: none; + + .iconPreview, .iconBG, .iconMain { + position: absolute; + top: 0; + left: 0; + + display: inline-block; + width: 100%; + height: 100%; + } + + .iconPreview { + display: none; + + background: #555; + background-image: none; + background: rgba(0, 0, 0, .5) !important; + + .attachmentIcon { + color: #fff; + text-shadow: 0 1px 0 #000; + } + } } .attachmentNameParent { + + position: relative; + margin-left: 60px; padding: 4px; padding-left: 6px; min-width: 90px; - color: #fff; - background: #eee; - color: #333; background: #fafafa; border-left: 1px solid #ddd; } - &.hasThumbnail .attachmentNameParent { - background: rgba(0, 0, 0, .6); - - color: #fff; - text-shadow: 0 1px 0 #000; - border-left: 0px; - } - .attachmentIcon { margin: 6px 0 0 13px; font-size: 36px; @@ -289,46 +307,27 @@ html.rl-no-preview-pane { color: #aaa; } - .attachmentIconParent.hasPreview { - .attachmentNonePreview { + .attachmentIconParent.hasPreview:hover { + .iconPreview { + display: inline-block; + } + .iconMain { display: none; } } - a.attachmentPreview { - display: inline-block; - height: 100%; - width: 100%; + .showPreview { + display: none; } - .attachmentIconParent.hasPreview:hover { - - background: #555 !important; - background-image: none !important; - background: rgba(0, 0, 0, .8) !important; - - color: #fff; - - .attachmentIcon { - color: #fff; - text-shadow: 0 1px 0 #000; + .attachmentIconParent.hasPreview { + .showPreview { + display: inline; } - } - .attachmentIconParent.hasPreview .show-hover { - display: none; - } - - .attachmentIconParent.hasPreview:hover .show-hover { - display: inline-block; - } - - .attachmentIconParent.hasPreview:hover .hide-hover { - display: none; - } - - &.hasThumbnail .attachmentMainIcon { - display: none; + .hidePreview { + display: none; + } } } } diff --git a/dev/View/Popup/Ask.js b/dev/View/Popup/Ask.js index 01466ce5b..c878ea791 100644 --- a/dev/View/Popup/Ask.js +++ b/dev/View/Popup/Ask.js @@ -33,6 +33,7 @@ this.fYesAction = null; this.fNoAction = null; + this.bFocusYesOnShow = true; this.bDisabeCloseOnEsc = true; this.sDefaultKeyScope = Enums.KeyState.PopupAsk; @@ -81,8 +82,9 @@ * @param {Function=} fNoFunc * @param {string=} sYesButton * @param {string=} sNoButton + * @param {boolean=} bFocusYesOnShow */ - AskPopupView.prototype.onShow = function (sAskDesc, fYesFunc, fNoFunc, sYesButton, sNoButton) + AskPopupView.prototype.onShow = function (sAskDesc, fYesFunc, fNoFunc, sYesButton, sNoButton, bFocusYesOnShow) { this.clearPopup(); @@ -99,11 +101,16 @@ { this.yesButton(sNoButton); } + + this.bFocusYesOnShow = Utils.isUnd(bFocusYesOnShow) ? true : !!bFocusYesOnShow; }; AskPopupView.prototype.onFocus = function () { - this.yesFocus(true); + if (this.bFocusYesOnShow) + { + this.yesFocus(true); + } }; AskPopupView.prototype.onBuild = function () diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index a0f2aa8c4..eb27036ba 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -43,7 +43,6 @@ this.aDraftInfo = null; this.sInReplyTo = ''; this.bFromDraft = false; - this.bSkipNext = false; this.sReferences = ''; this.bCapaAdditionalIdentities = Settings.capa(Enums.Capa.AdditionalIdentities); @@ -58,6 +57,9 @@ } ; + this.bSkipNextHide = false; + this.composeInEdit = Data.composeInEdit; + this.capaOpenPGP = Data.capaOpenPGP; this.resizer = ko.observable(false).extend({'throttle': 50}); @@ -313,7 +315,7 @@ this.savedError(false); this.saving(true); - this.bSkipNext = true; + this.autosaveStart(); Cache.setFolderHash(Data.draftFolder(), ''); @@ -338,11 +340,25 @@ }, this.canBeSendedOrSaved); - Events.sub('interval.1m', function () { - if (this.modalVisibility() && !Data.draftFolderNotEnabled() && !this.isEmptyForm(false) && - !this.bSkipNext && !this.saving() && !this.sending() && !this.savedError()) + this.skipCommand = Utils.createCommand(this, function () { + + this.bSkipNextHide = true; + + if (this.modalVisibility() && !this.saving() && !this.sending() && + !Data.draftFolderNotEnabled()) + { + this.saveCommand(); + } + + this.tryToClosePopup(); + + }, this.canBeSendedOrSaved); + + Events.sub('interval.2m', function () { + + if (this.modalVisibility() && !Data.draftFolderNotEnabled() && !this.isEmptyForm(false) && + !this.saving() && !this.sending() && !this.savedError()) { - this.bSkipNext = false; this.saveCommand(); } }, this); @@ -400,6 +416,9 @@ this.tryToClosePopup = _.debounce(_.bind(this.tryToClosePopup, this), 200); this.emailsSource = _.bind(this.emailsSource, this); + this.autosaveFunction = _.bind(this.autosaveFunction, this); + + this.iTimer = 0; kn.constructorEnd(this); } @@ -407,6 +426,28 @@ kn.extendAsViewModel(['View/Popup/Compose', 'PopupsComposeViewModel'], ComposePopupView); _.extend(ComposePopupView.prototype, AbstractView.prototype); + ComposePopupView.prototype.autosaveFunction = function () + { + if (this.modalVisibility() && !Data.draftFolderNotEnabled() && !this.isEmptyForm(false) && + !this.saving() && !this.sending() && !this.savedError()) + { + this.saveCommand(); + } + + this.autosaveStart(); + }; + + ComposePopupView.prototype.autosaveStart = function () + { + window.clearTimeout(this.iTimer); + this.iTimer = window.setTimeout(this.autosaveFunction, 1000 * 60 * 1); + }; + + ComposePopupView.prototype.autosaveStop = function () + { + window.clearTimeout(this.iTimer); + }; + ComposePopupView.prototype.emailsSource = function (oData, fResponse) { require('App/User').getAutocomplete(oData.term, function (aData) { @@ -594,6 +635,8 @@ { if (oData.Result.NewFolder && oData.Result.NewUid) { + bResult = true; + if (this.bFromDraft) { oMessage = Data.message(); @@ -606,27 +649,22 @@ this.draftFolder(oData.Result.NewFolder); this.draftUid(oData.Result.NewUid); - if (this.modalVisibility()) + this.savedTime(window.Math.round((new window.Date()).getTime() / 1000)); + + this.savedOrSendingText( + 0 < this.savedTime() ? Utils.i18n('COMPOSE/SAVED_TIME', { + 'TIME': moment.unix(this.savedTime() - 1).format('LT') + }) : '' + ); + + if (this.bFromDraft) { - this.savedTime(window.Math.round((new window.Date()).getTime() / 1000)); - - this.savedOrSendingText( - 0 < this.savedTime() ? Utils.i18n('COMPOSE/SAVED_TIME', { - 'TIME': moment.unix(this.savedTime() - 1).format('LT') - }) : '' - ); - - bResult = true; - - if (this.bFromDraft) - { - Cache.setFolderHash(this.draftFolder(), ''); - } + Cache.setFolderHash(this.draftFolder(), ''); } } } - if (!this.modalVisibility() && !bResult) + if (!bResult) { this.savedError(true); this.savedOrSendingText(Utils.getNotification(Enums.Notification.CantSaveMessage)); @@ -637,7 +675,16 @@ ComposePopupView.prototype.onHide = function () { - this.reset(); + this.autosaveStop(); + + if (!this.bSkipNextHide) + { + this.composeInEdit(false); + this.reset(); + } + + this.bSkipNextHide = false; + kn.routeOn(); }; @@ -736,6 +783,41 @@ { kn.routeOff(); + this.autosaveStart(); + + if (this.composeInEdit()) + { + sType = sType || Enums.ComposeType.Empty; + + var + self = this, + PopupsAskViewModel = require('View/Popup/Ask') + ; + + if (Enums.ComposeType.Empty !== sType) + { + kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('COMPOSE/DISCARD_UNSAVED_DATA'), function () { + self.initOnShow(sType, oMessageOrArray, aToEmails, sCustomSubject, sCustomPlainText); + }, null, null, null, false]); + } + } + else + { + this.initOnShow(sType, oMessageOrArray, aToEmails, sCustomSubject, sCustomPlainText); + } + }; + + /** + * @param {string=} sType = Enums.ComposeType.Empty + * @param {?MessageModel|Array=} oMessageOrArray = null + * @param {Array=} aToEmails = null + * @param {string=} sCustomSubject = null + * @param {string=} sCustomPlainText = null + */ + ComposePopupView.prototype.initOnShow = function (sType, oMessageOrArray, aToEmails, sCustomSubject, sCustomPlainText) + { + this.composeInEdit(true); + var self = this, sFrom = '', @@ -1033,14 +1115,21 @@ PopupsAskViewModel = require('View/Popup/Ask') ; - if (!kn.isPopupVisible(PopupsAskViewModel)) + if (!kn.isPopupVisible(PopupsAskViewModel) && this.modalVisibility()) { - kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW'), function () { - if (self.modalVisibility()) - { - Utils.delegateRun(self, 'closeCommand'); - } - }]); + if (this.bSkipNextHide || (this.isEmptyForm() && !this.draftUid())) + { + Utils.delegateRun(self, 'closeCommand'); + } + else + { + kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW'), function () { + if (self.modalVisibility()) + { + Utils.delegateRun(self, 'closeCommand'); + } + }]); + } } }; @@ -1716,14 +1805,14 @@ ComposePopupView.prototype.isEmptyForm = function (bIncludeAttachmentInProgress) { bIncludeAttachmentInProgress = Utils.isUnd(bIncludeAttachmentInProgress) ? true : !!bIncludeAttachmentInProgress; - var bAttach = bIncludeAttachmentInProgress ? + var bWithoutAttach = bIncludeAttachmentInProgress ? 0 === this.attachments().length : 0 === this.attachmentsInReady().length; return 0 === this.to().length && 0 === this.cc().length && 0 === this.bcc().length && 0 === this.subject().length && - bAttach && + bWithoutAttach && (!this.oEditor || '' === this.oEditor.getData()) ; }; diff --git a/dev/View/User/MailBox/FolderList.js b/dev/View/User/MailBox/FolderList.js index a7d7348ae..d3835d523 100644 --- a/dev/View/User/MailBox/FolderList.js +++ b/dev/View/User/MailBox/FolderList.js @@ -34,6 +34,8 @@ this.oContentVisible = null; this.oContentScrollable = null; + this.composeInEdit = Data.composeInEdit; + this.messageList = Data.messageList; this.folderList = Data.folderList; this.folderListSystem = Data.folderListSystem; diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js index 668f73367..9366ed5f6 100644 --- a/dev/View/User/MailBox/MessageView.js +++ b/dev/View/User/MailBox/MessageView.js @@ -367,7 +367,7 @@ if (this.pswpDom) { oDom - .on('click', 'a.attachmentImagePreview[data-index]:visible', function (oEvent) { + .on('click', '.attachmentImagePreview[data-index]', function (oEvent) { var oPs = null, @@ -375,7 +375,7 @@ aItems = [] ; - oDom.find('a.attachmentImagePreview:visible').each(function (index, oSubElement) { + oDom.find('.attachmentImagePreview[data-index]').each(function (index, oSubElement) { var $oItem = $(oSubElement); diff --git a/gulpfile.js b/gulpfile.js index bd8326852..67b9196ad 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -191,7 +191,8 @@ gulp.task('less:main', function() { })) .pipe(rename(cfg.paths.less.main.name)) .pipe(eol('\n', true)) - .pipe(gulp.dest(cfg.paths.staticCSS)); + .pipe(gulp.dest(cfg.paths.staticCSS)) + .on('error', gutil.log); }); gulp.task('css:main-begin', ['less:main'], function() { diff --git a/package.json b/package.json index 7a2e91279..7b98a87dc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "RainLoop", "title": "RainLoop Webmail", "version": "1.7.1", - "release": "215", + "release": "217", "description": "Simple, modern & fast web-based email client", "homepage": "http://rainloop.net", "main": "gulpfile.js", @@ -52,7 +52,7 @@ "gulp-uglify": "*", "gulp-rimraf": "*", "gulp-jshint": "*", - "gulp-less": "*", + "gulp-less": "1.3.6", "gulp-zip": "*", "gulp-rename": "*", "gulp-replace": "*", diff --git a/rainloop/v/0.0.0/app/libraries/Facebook/FacebookRedirectLoginHelper.php b/rainloop/v/0.0.0/app/libraries/Facebook/FacebookRedirectLoginHelper.php index 5511ea647..4897a7acd 100644 --- a/rainloop/v/0.0.0/app/libraries/Facebook/FacebookRedirectLoginHelper.php +++ b/rainloop/v/0.0.0/app/libraries/Facebook/FacebookRedirectLoginHelper.php @@ -241,7 +241,8 @@ class FacebookRedirectLoginHelper } $buf = ''; // http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ - if (is_readable('/dev/urandom')) { + if (false && is_readable('/dev/urandom')) { +// if (is_readable('/dev/urandom')) { $fp = fopen('/dev/urandom', 'rb'); if ($fp !== FALSE) { $buf = fread($fp, $bytes); diff --git a/rainloop/v/0.0.0/app/src/RainLoop/Actions.php b/rainloop/v/0.0.0/app/src/RainLoop/Actions.php index fee0b7b92..aa8d0fc58 100644 --- a/rainloop/v/0.0.0/app/src/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/src/RainLoop/Actions.php @@ -7081,7 +7081,7 @@ class Actions $oThumb =@ new \PHPThumb\GD($sFileName); if ($oThumb) { - $oThumb->adaptiveResize(220, 80)->show(); + $oThumb->adaptiveResize(60, 60)->show(); $bDone = true; } } diff --git a/rainloop/v/0.0.0/app/templates/Views/User/MailFolderList.html b/rainloop/v/0.0.0/app/templates/Views/User/MailFolderList.html index 061f4ca0f..1359619c3 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/MailFolderList.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/MailFolderList.html @@ -1,6 +1,7 @@