From d9447f62245b6686b94d18d93ae6075a7ae68886 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Wed, 29 Jan 2014 18:37:18 +0400 Subject: [PATCH] Lots of bug fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EmojiMenu click scroll fix EmojiMenu tail Emojiarea improve paste hadling Emoji, attach icons styles (opacity + color on active state) Message better placeholder styles Notifications click improve (now focus field) Send message from modal now closes all modals Send message now scrolls down Message drafts now support line breaks Correct display ‘f’, ’n’, ‘no’ messages Group info click causes double modal window fixed Document is now downloaded on icon click --- app/css/app.css | 40 ++++++++++--- app/index.html | 14 ++--- app/js/app.js | 2 +- app/js/controllers.js | 25 +++++--- app/js/directives.js | 28 +++++++-- app/js/services.js | 11 +--- app/partials/dialog.html | 2 +- app/partials/im.html | 2 +- app/partials/message.html | 8 ++- .../jquery.emojiarea/jquery.emojiarea.js | 58 +++++++++++++++---- .../ui-bootstrap/ui-bootstrap-custom-0.7.0.js | 18 +++--- .../ui-bootstrap-custom-tpls-0.7.0.js | 9 +++ 12 files changed, 157 insertions(+), 60 deletions(-) diff --git a/app/css/app.css b/app/css/app.css index 8c2c7204..779290de 100644 --- a/app/css/app.css +++ b/app/css/app.css @@ -580,7 +580,7 @@ a.im_dialog:hover .im_dialog_message_text { margin-left: 5px; } .im_history_panel_info_link { - /*color: #999;*/ + color: #999; font-size: 13px; font-weight: normal; padding-top: 5px; @@ -1000,9 +1000,14 @@ textarea.im_message_field { vertical-align: text-top; background: url(../img/icons/Attach_2x.png) 0 0 no-repeat; background-size: 19px 22px; + opacity: 0.6; } .im_attach:hover .icon-paperclip { + opacity: 1; +} +.im_attach:active .icon-paperclip { background-image: url(../img/icons/Attach_pressed_2x.png); + opacity: 1; } .im_emoji_btn { @@ -1021,9 +1026,15 @@ textarea.im_message_field { vertical-align: text-top; background: url(../img/icons/Smile_2x.png) 0 0 no-repeat; background-size: 22px 22px; + opacity: 0.6; } .im_emoji_btn:hover .icon-emoji { + opacity: 1; +} +.im_emoji_btn:active .icon-emoji, +.im_emoji_btn.on .icon-emoji { background-image: url(../img/icons/Smile_pressed_2x.png); + opacity: 1; } .im_attach_input { @@ -1184,10 +1195,14 @@ img.img_fullsize { /* Emoji area */ -.emoji-wysiwyg-editor:empty:before{ - content:attr(placeholder); +.emoji-wysiwyg-editor:empty:before { + content: attr(placeholder); color: #9aa2ab; } +.emoji-wysiwyg-editor:active:before, +.emoji-wysiwyg-editor:focus:before { + content: '' !important; +} .emoji-wysiwyg-editor { font-size: 12px; @@ -1215,15 +1230,16 @@ img.img_fullsize { position: absolute; z-index: 999; width: 180px; + margin-left: -90px; + margin-top: -232px; + overflow: hidden; +} +.emoji-items-wrap1 { + background: rgba(0,0,0, 0.65); padding: 5px 2px 5px 5px; - margin-left: -88px; - margin-top: -225px; - -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; - background: rgba(0,0,0, 0.7); - overflow: hidden; } .emoji-menu .emoji-items-wrap { position: relative; @@ -1259,6 +1275,14 @@ img.img_fullsize { display: none; } +.emoji-menu-tail { + background: url(../img/icons/Arrow_2x.png) 0 0 no-repeat; + background-size: 14px 7px; + width: 14px; + height: 7px; + margin: 0 83px; +} + .emoji-menu .nano > .pane { background : rgba(255,255,255,.0); diff --git a/app/index.html b/app/index.html index f0e25997..71fb1b76 100644 --- a/app/index.html +++ b/app/index.html @@ -7,7 +7,7 @@ - + @@ -34,13 +34,13 @@ - + - + @@ -51,11 +51,11 @@ - - - + + + - + diff --git a/app/js/app.js b/app/js/app.js index ce633664..11fb238c 100644 --- a/app/js/app.js +++ b/app/js/app.js @@ -50,7 +50,7 @@ config(['$locationProvider', '$routeProvider', '$compileProvider', function($loc // $locationProvider.html5Mode(true); $routeProvider.when('/', {templateUrl: 'partials/welcome.html?1', controller: 'AppWelcomeController'}); $routeProvider.when('/login', {templateUrl: 'partials/login.html?2', controller: 'AppLoginController'}); - $routeProvider.when('/im', {templateUrl: 'partials/im.html?3', controller: 'AppIMController', reloadOnSearch: false}); + $routeProvider.when('/im', {templateUrl: 'partials/im.html?4', controller: 'AppIMController', reloadOnSearch: false}); $routeProvider.otherwise({redirectTo: '/'}); }]); diff --git a/app/js/controllers.js b/app/js/controllers.js index bb677d8e..0b685d82 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -59,7 +59,6 @@ angular.module('myApp.controllers', []) $scope.error = {}; }, function (error) { - console.log(error); $scope.progress.enabled = false; console.log('sendCode error', error); switch (error.type) { @@ -125,6 +124,15 @@ angular.module('myApp.controllers', []) $scope.$on('$routeUpdate', updateCurDialog); + $scope.$on('history_focus', function (e, peerData) { + if (peerData.peerString == $scope.curDialog.peer) { + $scope.$broadcast('ui_history_focus'); + } else { + $location.url('/im?p=' + peerData.peerString); + } + }); + + $scope.isLoggedIn = true; $scope.logOut = function () { MtpApiManager.logOut().then(function () { @@ -354,7 +362,7 @@ angular.module('myApp.controllers', []) // console.trace(); $scope.history.push(AppMessagesManager.wrapForHistory(addedMessage.messageID)); $scope.typing = {}; - $scope.$broadcast('ui_history_append'); + $scope.$broadcast('ui_history_append', {my: addedMessage.my}); offset++; // console.log('append check', $rootScope.idle.isIDLE, addedMessage.peerID, $scope.curDialog.peerID); @@ -382,7 +390,7 @@ angular.module('myApp.controllers', []) break; case 'updateChatUserTyping': - if (-update.chat_id == $scope.curDialog.peerID) { + if (-update.chat_id == $scope.curDialog.peerID && AppUsersManager.hasUser(update.user_id)) { $scope.typing = {user: AppUsersManager.getUser(update.user_id)}; $timeout.cancel(typingTimeouts[update.user_id]); @@ -420,6 +428,8 @@ angular.module('myApp.controllers', []) var lastTyping = false; $scope.$watch('draftMessage.text', function (newVal) { + // console.log('ctrl text changed', newVal); + // console.trace('ctrl text changed', newVal); AppMessagesManager.readHistory($scope.curDialog.inputPeer); if (newVal.length) { @@ -457,7 +467,7 @@ angular.module('myApp.controllers', []) return false; } - text = text.replace(/:\s*(.+?)\s*:/g, function (all, name) { + text = text.replace(/:([a-z0-9\-_]+?):/gi, function (all, name) { var utfChar = $.emojiarea.reverseIcons[name]; if (utfChar !== undefined) { return utfChar; @@ -485,6 +495,7 @@ angular.module('myApp.controllers', []) } else { // console.log('Reset peer'); $scope.draftMessage.text = ''; + $scope.$broadcast('ui_peer_draft'); } } @@ -509,11 +520,11 @@ angular.module('myApp.controllers', []) $scope.video = AppVideoManager.wrapForFull($scope.videoID); }) - .controller('UserModalController', function ($scope, $location, AppUsersManager) { + .controller('UserModalController', function ($scope, $location, $rootScope, $modalStack, AppUsersManager) { $scope.user = AppUsersManager.wrapForFull($scope.userID); $scope.goToHistory = function () { - $scope.$close(); - $location.url('/im?p=' + $scope.user.peerString); + $modalStack.dismissAll(); + $rootScope.$broadcast('history_focus', {peerString: $scope.user.peerString}); }; }) diff --git a/app/js/directives.js b/app/js/directives.js index 16b8b19f..49bb55e6 100644 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -16,7 +16,7 @@ angular.module('myApp.directives', ['myApp.filters']) restrict: 'AE', scope: true, translude: false, - templateUrl: 'partials/dialog.html?3' + templateUrl: 'partials/dialog.html?4' }; }) @@ -25,7 +25,7 @@ angular.module('myApp.directives', ['myApp.filters']) restrict: 'AE', scope: true, translude: false, - templateUrl: 'partials/message.html?4' + templateUrl: 'partials/message.html?5' }; }) @@ -124,8 +124,8 @@ angular.module('myApp.directives', ['myApp.filters']) var animated = true, curAnimation = false; - scope.$on('ui_history_append', function () { - if (!atBottom) { + scope.$on('ui_history_append', function (e, options) { + if (!atBottom && !options.my) { return; } if (animated) { @@ -143,8 +143,8 @@ angular.module('myApp.directives', ['myApp.filters']) }, { duration: 200, always: function () { - curAnimation = false; updateScroller(); + curAnimation = false; } }); updateScroller(); @@ -171,6 +171,13 @@ angular.module('myApp.directives', ['myApp.filters']) }); }); + scope.$on('ui_history_focus', function () { + if (!atBottom) { + scrollableWrap.scrollTop = scrollableWrap.scrollHeight; + updateScroller(); + atBottom = true; + } + }); scope.$on('ui_history_prepend', function () { var sh = scrollableWrap.scrollHeight, @@ -264,6 +271,11 @@ angular.module('myApp.directives', ['myApp.filters']) $(fileSelect).on('change', function () { scope.$apply(function () { scope.draftMessage.files = Array.prototype.slice.call(fileSelect.files); + setTimeout(function () { + try { + fileSelect.value = ''; + } catch (e) {}; + }, 1000); }); }); @@ -287,6 +299,7 @@ angular.module('myApp.directives', ['myApp.filters']) if (richTextarea) { scope.$watch('draftMessage.text', function (newVal) { + // console.log('dir text change', newVal); if (!newVal.length && !messageField.value.length) { $timeout(function () { updateField(); @@ -296,12 +309,15 @@ angular.module('myApp.directives', ['myApp.filters']) } function updateField () { - $(richTextarea).text(scope.draftMessage.text || ''); + var html = $('
').text(scope.draftMessage.text || '').html(); + html = html.replace(/\n/g, '
'); + $(richTextarea).html(html) } $('body').on('dragenter dragleave dragover drop', onDragDropEvent); scope.$on('ui_peer_change', focusField); + scope.$on('ui_history_focus', focusField); scope.$on('ui_history_change', focusField); scope.$on('ui_message_send', focusField); scope.$on('ui_peer_draft', updateField); diff --git a/app/js/services.js b/app/js/services.js index 1fd6ca42..97f6cb5e 100644 --- a/app/js/services.js +++ b/app/js/services.js @@ -46,19 +46,14 @@ angular.module('myApp.services', []) var deferred = $q.defer(); - // console.log('get', keys); chrome.storage.local.get(keys, function (resultObj) { - // console.log('got', resultObj); result = []; angular.forEach(keys, function (key) { var value = resultObj[key]; - // console.log('p1', key, value); value = value === undefined || value === null ? false : JSON.parse(value); - // console.log('p2', value); result.push(cache[key] = value); }); - // console.log('got parsed', result); deferred.resolve(single ? result[0] : result); }); @@ -711,7 +706,7 @@ angular.module('myApp.services', []) saveMessages([message]); historyStorage.pending.unshift(messageID); - $rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID}); + $rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true}); // setTimeout(function () { message.send(); @@ -805,7 +800,7 @@ angular.module('myApp.services', []) saveMessages([message]); historyStorage.pending.unshift(messageID); - $rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID}); + $rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true}); // setTimeout(function () { message.send(); @@ -1013,7 +1008,7 @@ angular.module('myApp.services', []) } notification.onclick = function () { - $location.url('/im?p=' + peerString); + $rootScope.$broadcast('history_focus', {peerString: peerString}); }; notification.message = notificationMessage; diff --git a/app/partials/dialog.html b/app/partials/dialog.html index c2714b42..fb7006ba 100644 --- a/app/partials/dialog.html +++ b/app/partials/dialog.html @@ -91,7 +91,7 @@ - +
diff --git a/app/partials/im.html b/app/partials/im.html index c1d7be1b..9511e5fc 100644 --- a/app/partials/im.html +++ b/app/partials/im.html @@ -31,8 +31,8 @@
+ Info

- Info
- + + + + +
@@ -179,7 +183,7 @@
-
+
diff --git a/app/vendor/jquery.emojiarea/jquery.emojiarea.js b/app/vendor/jquery.emojiarea/jquery.emojiarea.js index 1d4edbff..5a176bbb 100644 --- a/app/vendor/jquery.emojiarea/jquery.emojiarea.js +++ b/app/vendor/jquery.emojiarea/jquery.emojiarea.js @@ -16,7 +16,7 @@ /** * This file also contains some modifications by Igor Zhukov in order to add custom scrollbars to EmojiMenu - * See keyword `MODIFICATION: ` in source code. + * See keyword `MODIFICATION` in source code. */ (function($, window, document) { @@ -254,7 +254,7 @@ this.$editor = $('
').addClass('emoji-wysiwyg-editor'); this.$editor.text($textarea.val()); this.$editor.attr({contenteditable: 'true'}); - this.$editor.on('blur keyup paste', function() { return self.onChange.apply(self, arguments); }); + this.$editor.on('blur keyup paste', function(e) { return self.onChange.apply(self, [e]); }); this.$editor.on('mousedown focus', function() { document.execCommand('enableObjectResizing', false, false); }); this.$editor.on('blur', function() { document.execCommand('enableObjectResizing', true, true); }); @@ -278,7 +278,19 @@ }); }; - EmojiArea_WYSIWYG.prototype.onChange = function() { + EmojiArea_WYSIWYG.prototype.onChange = function(e) { + if (e && e.type == 'paste') { + var text = (e.originalEvent || e).clipboardData.getData('text/plain'), + self = this; + setTimeout(function () { + self.onChange(); + }, 0); + if (text.length) { + document.execCommand('insertText', false, text); + return cancelEvent(); + } + return true; + } this.$textarea.val(this.val()).trigger('change'); }; @@ -363,13 +375,18 @@ this.$menu.addClass('emoji-menu'); this.$menu.hide(); - /* MODIFICATION: Following 2 lines are modified by Igor Zhukov, in order to add scrollbars to EmojiMenu */ - this.$itemsWrap = $('
').appendTo(this.$menu); + /*! MODIFICATION START + Following code was modified by Igor Zhukov, in order to add scrollbars and tail to EmojiMenu + */ + this.$itemsTailWrap = $('
').appendTo(this.$menu); + this.$itemsWrap = $('
').appendTo(this.$itemsTailWrap); this.$items = $('
').appendTo(this.$itemsWrap); + $('
').appendTo(this.$menu); + /*! MODIFICATION END */ $body.append(this.$menu); - /* MODIFICATION: Following line is added by Igor Zhukov, in order to add scrollbars to EmojiMenu */ + /*! MODIFICATION: Following line is added by Igor Zhukov, in order to add scrollbars to EmojiMenu */ this.$itemsWrap.nanoScroller({preventPageScrolling: true, tabIndex: -1}); $body.on('keydown', function(e) { @@ -378,7 +395,19 @@ } }); - $body.on('mouseup', function() { + $body.on('mouseup', function(e) { + /*! MODIFICATION START + Following code was added by Igor Zhukov, in order to prevent close on click on EmojiMenu scrollbar + */ + e = e.originalEvent || e; + var target = e.originalTarget || e.target || window; + while (target && target != window) { + target = target.parentNode; + if (target == self.$menu[0]) { + return; + } + } + /*! MODIFICATION END */ self.hide(); }); @@ -394,7 +423,14 @@ this.$menu.on('click', 'a', function(e) { var emoji = $('.label', $(this)).text(); window.setTimeout(function() { - self.onItemSelected.apply(self, [emoji]); + /*! MODIFICATION START + Following code was modified by Igor Zhukov, in order to prevent close on shift-, ctrl-, alt- emoji select + */ + self.onItemSelected(emoji); + if (!e.shiftKey && !e.ctrlKey && !e.metaKey) { + self.hide(); + } + /*! MODIFICATION END */ }, 0); e.stopPropagation(); return false; @@ -405,7 +441,6 @@ EmojiMenu.prototype.onItemSelected = function(emoji) { this.emojiarea.insert(emoji); - this.hide(); }; EmojiMenu.prototype.load = function() { @@ -425,7 +460,7 @@ this.$items.html(html.join('')); - /* MODIFICATION: Following 4 lines were added by Igor Zhukov, in order to add scrollbars to EmojiMenu */ + /*! MODIFICATION: Following 4 lines were added by Igor Zhukov, in order to add scrollbars to EmojiMenu */ var self = this; setTimeout(function () { self.$itemsWrap.nanoScroller(); @@ -450,12 +485,15 @@ this.emojiarea.$button.removeClass('on'); this.emojiarea = null; } + + this.visible = false; this.$menu.hide(); }; EmojiMenu.prototype.show = function(emojiarea) { if (this.emojiarea && this.emojiarea === emojiarea) return; + emojiarea.$button.addClass('on'); this.emojiarea = emojiarea; this.emojiarea.menu = this; diff --git a/app/vendor/ui-bootstrap/ui-bootstrap-custom-0.7.0.js b/app/vendor/ui-bootstrap/ui-bootstrap-custom-0.7.0.js index 797840d6..731c18e7 100644 --- a/app/vendor/ui-bootstrap/ui-bootstrap-custom-0.7.0.js +++ b/app/vendor/ui-bootstrap/ui-bootstrap-custom-0.7.0.js @@ -71,10 +71,8 @@ angular.module('ui.bootstrap.modal', []) }); scope.close = function (evt) { - console.log('close', evt); var modal = $modalStack.getTop(); if (modal && modal.value.backdrop && modal.value.backdrop != 'static') { - console.log('backdrop click'); evt.preventDefault(); evt.stopPropagation(); $modalStack.dismiss(modal.key, 'backdrop click'); @@ -94,7 +92,6 @@ angular.module('ui.bootstrap.modal', []) transclude: true, templateUrl: 'template/modal/window.html', link: function (scope, element, attrs) { - console.log('init window'); scope.windowClass = attrs.windowClass || ''; //trigger CSS transitions @@ -170,8 +167,6 @@ angular.module('ui.bootstrap.modal', []) }); $modalStack.open = function (modalInstance, modal) { - console.log('open', 11); - openedWindows.add(modalInstance, { deferred: modal.deferred, modalScope: modal.scope, @@ -196,8 +191,6 @@ angular.module('ui.bootstrap.modal', []) }; $modalStack.close = function (modalInstance, result) { - // console.log('close'); - console.trace(); var modal = openedWindows.get(modalInstance); if (modal) { modal.value.deferred.resolve(result); @@ -218,6 +211,15 @@ angular.module('ui.bootstrap.modal', []) return openedWindows.top(); }; + $modalStack.dismissAll = function () { + var modal; + while (modal = openedWindows.top()) { + $rootScope.$apply(function () { + $modalStack.dismiss(modal.key); + }); + } + } + return $modalStack; }]) @@ -260,14 +262,12 @@ angular.module('ui.bootstrap.modal', []) result: modalResultDeferred.promise, opened: modalOpenedDeferred.promise, close: function (result) { - console.log('close'); $modalStack.close(modalInstance, result); }, dismiss: function (reason) { $modalStack.dismiss(modalInstance, reason); } }; - console.log('modal', modalInstance); //merge and clean up options modalOptions = angular.extend({}, $modalProvider.options, modalOptions); diff --git a/app/vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.7.0.js b/app/vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.7.0.js index 1e837cf6..6cb3d2ae 100644 --- a/app/vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.7.0.js +++ b/app/vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.7.0.js @@ -210,6 +210,15 @@ angular.module('ui.bootstrap.modal', []) } }; + $modalStack.dismissAll = function () { + var modal; + while (openedWindows.length()) { + if (modal = openedWindows.top()) { + $modalStack.dismiss(modal.key); + } + } + } + $modalStack.getTop = function () { return openedWindows.top(); };