Performance improvements
This commit is contained in:
parent
3273329a3d
commit
ef3fc51e53
@ -1413,6 +1413,10 @@ span.emoji {
|
||||
font-size: 1.5em;
|
||||
padding: 0 50px;
|
||||
}
|
||||
.im_history_to_bottom .im_history_not_selected,
|
||||
.im_history_to_bottom .im_history_empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.im_send_panel_wrap {
|
||||
max-width: 526px;
|
||||
|
@ -36,6 +36,7 @@
|
||||
<script type="text/javascript" src="vendor/angular/angular-animate.js"></script>
|
||||
<script type="text/javascript" src="vendor/angular/angular-sanitize.js"></script>
|
||||
<script type="text/javascript" src="vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.10.0.js"></script>
|
||||
<script type="text/javascript" src="vendor/bindonce/bindonce.js"></script>
|
||||
|
||||
<script type="text/javascript" src="vendor/jsbn/jsbn_combined.js"></script>
|
||||
<script type="text/javascript" src="vendor/cryptoJS/crypto.js"></script>
|
||||
|
@ -30,6 +30,7 @@ angular.module('myApp', [
|
||||
'ngAnimate',
|
||||
'ngSanitize',
|
||||
'ui.bootstrap',
|
||||
'pasvaz.bindonce',
|
||||
'mtproto.services',
|
||||
'myApp.filters',
|
||||
'myApp.services',
|
||||
|
@ -318,6 +318,9 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
});
|
||||
|
||||
function updateSizes (heightOnly) {
|
||||
if (!element.is(':visible') || !$(element[0].parentNode).is(':visible')) {
|
||||
return;
|
||||
}
|
||||
if ($(sendFormWrap).is(':visible')) {
|
||||
$(sendFormWrap).css({
|
||||
height: $(sendForm).height()
|
||||
@ -851,7 +854,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
})
|
||||
|
||||
|
||||
.directive('myTypingDots', function($interval) {
|
||||
.directive('myLoadingDots', function($interval) {
|
||||
|
||||
return {
|
||||
link: link,
|
||||
|
@ -671,7 +671,7 @@ angular.module('myApp.services', [])
|
||||
}
|
||||
})
|
||||
|
||||
.service('AppMessagesManager', function ($q, $rootScope, $location, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, SearchIndexManager) {
|
||||
.service('AppMessagesManager', function ($q, $rootScope, $location, $filter, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, SearchIndexManager) {
|
||||
|
||||
var messagesStorage = {};
|
||||
var messagesForHistory = {};
|
||||
@ -1482,6 +1482,8 @@ angular.module('myApp.services', [])
|
||||
message.richMessage = RichTextProcessor.wrapRichText(message.message.substr(0, 64), {noLinks: true, noLinebreaks: true});
|
||||
}
|
||||
|
||||
message.dateText = $filter('dateOrTime')(message.date);
|
||||
|
||||
|
||||
return messagesForDialogs[msgID] = message;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
thumb="chatFull.thumb"
|
||||
/>
|
||||
<div class="chat_modal_photo_change_wrap" ng-if="chatFull.chat._ != 'chatForbidden' && !chatFull.chat.left">
|
||||
<div ng-if="photo.updating" class="chat_modal_photo_loading">Updating<span my-typing-dots></span></div>
|
||||
<div ng-if="photo.updating" class="chat_modal_photo_loading">Updating<span my-loading-dots></span></div>
|
||||
<div ng-if="!photo.updating">
|
||||
<div class="chat_modal_photo_update_link">
|
||||
<input my-file-upload type="file" multiple="false" class="im_attach_input" size="120" multiple="false" accept="image/x-png, image/png, image/gif, image/jpeg" />
|
||||
|
@ -1,9 +1,7 @@
|
||||
<a class="im_dialog" ng-click="dialogSelect(dialogMessage.peerString)">
|
||||
|
||||
<div class="im_dialog_meta pull-right text-right">
|
||||
<div class="im_dialog_date">
|
||||
{{dialogMessage.date | dateOrTime}}
|
||||
</div>
|
||||
<div class="im_dialog_date" ng-bind="dialogMessage.dateText"></div>
|
||||
<span
|
||||
class="im_dialog_badge badge"
|
||||
ng-show="dialogMessage.unreadCount > 0 && !dialogMessage.out"
|
||||
@ -25,11 +23,11 @@
|
||||
|
||||
<div class="im_dialog_message_wrap">
|
||||
|
||||
<div class="im_dialog_peer">
|
||||
<span class="im_dialog_chat" ng-if="dialogMessage.chatID">
|
||||
<i class="icon icon-group"></i> <span ng-bind-html="dialogMessage.peerData.rTitle"></span>
|
||||
<div class="im_dialog_peer" ng-switch="dialogMessage.peerID > 0">
|
||||
<span class="im_dialog_user" ng-switch-when="true" ng-bind-html="dialogMessage.peerData.rFullName"></span>
|
||||
<span class="im_dialog_chat" ng-switch-default>
|
||||
<span ng-bind-html="dialogMessage.peerData.rTitle"></span>
|
||||
</span>
|
||||
<span class="im_dialog_user" ng-if="dialogMessage.peerID > 0" ng-bind-html="dialogMessage.peerData.rFullName"></span>
|
||||
</div>
|
||||
|
||||
<div class="im_dialog_message">
|
||||
@ -59,22 +57,22 @@
|
||||
<span ng-switch-when="messageActionChatEditPhoto">changed group photo</span>
|
||||
<span ng-switch-when="messageActionChatDeletePhoto">removed group photo</span>
|
||||
|
||||
<span ng-switch-when="messageActionChatAddUser">
|
||||
<span ng-if="dialogMessage.from_id != dialogMessage.action.user_id">
|
||||
invited <span ng-bind-html="dialogMessage.action.user.rFullName"></span>
|
||||
</span>
|
||||
<span ng-if="dialogMessage.from_id == dialogMessage.action.user_id">
|
||||
<span ng-switch-when="messageActionChatAddUser" ng-switch="dialogMessage.from_id == dialogMessage.action.user_id">
|
||||
<span ng-switch-when="true">
|
||||
returned to group
|
||||
</span>
|
||||
<span ng-switch-default>
|
||||
invited <span ng-bind-html="dialogMessage.action.user.rFullName"></span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span ng-switch-when="messageActionChatDeleteUser">
|
||||
<span ng-if="dialogMessage.from_id != dialogMessage.action.user_id">
|
||||
kicked <span ng-bind-html="dialogMessage.action.user.rFullName"></span>
|
||||
</span>
|
||||
<span ng-if="dialogMessage.from_id == dialogMessage.action.user_id">
|
||||
<span ng-switch-when="messageActionChatDeleteUser" ng-switch="dialogMessage.from_id == dialogMessage.action.user_id">
|
||||
<span ng-switch-when="true">
|
||||
left group
|
||||
</span>
|
||||
<span ng-switch-default>
|
||||
kicked <span ng-bind-html="dialogMessage.action.user.rFullName"></span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
|
@ -22,9 +22,9 @@
|
||||
<div class="navbar-collapse" collapse="navbarCollapsed">
|
||||
|
||||
<ul ng-if="offline" class="nav navbar-nav navbar-offline">
|
||||
<li ng-show="!offlineConnecting"><span class="navbar-offline-text">Waiting for network<span my-typing-dots></span></span></li>
|
||||
<li ng-show="!offlineConnecting"><span class="navbar-offline-text">Waiting for network<span my-loading-dots></span></span></li>
|
||||
<li ng-show="!offlineConnecting"><a href="" ng-click="retryOnline()">Retry</a></li>
|
||||
<li ng-show="offlineConnecting"><span class="navbar-offline-text">Connecting<span my-typing-dots></span></span></li>
|
||||
<li ng-show="offlineConnecting"><span class="navbar-offline-text">Connecting<span my-loading-dots></span></span></li>
|
||||
</ul>
|
||||
|
||||
<ul ng-if="!offline" class="nav navbar-nav navbar-right">
|
||||
|
@ -63,7 +63,7 @@
|
||||
Please select a chat to start messaging
|
||||
</div>
|
||||
<div ng-show="!state.notSelected && !state.loaded" class="im_history_not_selected" my-vertical-position="0.3">
|
||||
Loading history <span my-typing-dots></span>
|
||||
Loading history<span my-loading-dots></span>
|
||||
</div>
|
||||
|
||||
<div ng-show="state.loaded">
|
||||
@ -90,25 +90,26 @@
|
||||
<strong class="im_history_panel_return_count" ng-show="missedCount > 0">+{{missedCount}}</strong>
|
||||
</a>
|
||||
|
||||
<h4 ng-show="mediaType !== false" ng-switch="mediaType">
|
||||
<span ng-switch-when="photos">Photos</span>
|
||||
<span ng-switch-when="video">Videos</span>
|
||||
<span ng-switch-when="documents">Documents</span>
|
||||
</h4>
|
||||
<div ng-switch="mediaType">
|
||||
<h4 ng-switch-when="photos">Photos</h4>
|
||||
<h4 ng-switch-when="video">Videos</h4>
|
||||
<h4 ng-switch-when="documents">Documents</h4>
|
||||
|
||||
<h4 ng-show="mediaType === false && historyPeer.id < 0" ng-click="showPeerInfo()">
|
||||
<span ng-bind-html="historyPeer.data.rTitle"></span>
|
||||
<small class="im_chat_users">
|
||||
<ng-pluralize count="historyPeer.data.participants_count"
|
||||
when="{'0': 'No members', 'one': '1 member', 'other': '{} members'}">
|
||||
</ng-pluralize>
|
||||
</small>
|
||||
</h4>
|
||||
|
||||
<h4 ng-show="mediaType === false && historyPeer.id > 0" ng-click="showPeerInfo()">
|
||||
<span ng-bind-html="historyPeer.data.rFullName"></span>
|
||||
<small class="im_peer_online">{{historyPeer.data | userStatus}}</small>
|
||||
</h4>
|
||||
<h4 ng-switch-default ng-switch="historyPeer.id > 0">
|
||||
<div ng-switch-when="true">
|
||||
<span ng-bind-html="historyPeer.data.rFullName"></span>
|
||||
<small class="im_peer_online">{{historyPeer.data | userStatus}}</small>
|
||||
</div>
|
||||
<div ng-switch-default>
|
||||
<span ng-bind-html="historyPeer.data.rTitle"></span>
|
||||
<small class="im_chat_users">
|
||||
<ng-pluralize count="historyPeer.data.participants_count"
|
||||
when="{'0': 'No members', 'one': '1 member', 'other': '{} members'}">
|
||||
</ng-pluralize>
|
||||
</small>
|
||||
</div>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -127,13 +128,13 @@
|
||||
No messages here yet...
|
||||
</div>
|
||||
<div class="im_history_messages">
|
||||
<div class="im_history_message_wrap" my-message ng-repeat="historyMessage in history"></div>
|
||||
<div class="im_history_message_wrap" my-message bindonce ng-repeat="historyMessage in history"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="im_history_typing_wrap">
|
||||
<div class="im_history_typing" ng-show="typing.user && !mediaType">
|
||||
<strong class="im_history_typing_author" ng-bind-html="typing.user.rFullName"></strong> is typing<span my-typing-dots></span>
|
||||
<strong class="im_history_typing_author" ng-bind-html="typing.user.rFullName"></strong> is typing<span my-loading-dots></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -145,17 +146,13 @@
|
||||
|
||||
<div class="im_bottom_panel_wrap">
|
||||
|
||||
<div class="im_edit_panel_wrap clearfix" ng-show="selectActions" ng-class="{im_edit_panel_wrap_loaded: true}">
|
||||
<div class="im_edit_panel_wrap clearfix" ng-show="selectActions">
|
||||
<div class="im_edit_panel_border"></div>
|
||||
<a class="im_edit_flush_link" ng-click="selectedFlush()" ng-show="historyPeer.id < 0">
|
||||
Clear History
|
||||
</a>
|
||||
<a class="im_edit_flush_link" ng-click="selectedFlush()" ng-show="historyPeer.id > 0">
|
||||
Delete Chat
|
||||
</a>
|
||||
<a class="im_edit_cancel_link" ng-click="selectedCancel()">
|
||||
Cancel
|
||||
<a class="im_edit_flush_link" ng-click="selectedFlush()" ng-switch="historyPeer.id > 0">
|
||||
<span ng-switch-when="true">Delete Chat</span>
|
||||
<span ng-switch-default>Clear History</span>
|
||||
</a>
|
||||
<a class="im_edit_cancel_link" ng-click="selectedCancel()">Cancel</a>
|
||||
<div class="im_edit_selected_actions">
|
||||
<a class="btn btn-primary im_edit_forward_btn" ng-click="selectedForward()">
|
||||
Forward <strong class="im_selected_count" ng-show="selectedCount > 0" ng-bind="selectedCount"></strong>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="im_message_unread_split" ng-if="historyUnread && historyUnread.beforeID == historyMessage.id">
|
||||
<div class="im_message_unread_split" bo-if="historyUnread.beforeID == historyMessage.id" ng-show="historyUnread.beforeID == historyMessage.id">
|
||||
<ng-pluralize count="historyUnread.count"
|
||||
when="{'one': '1 unread message', 'other': '{} unread messages'}">
|
||||
</ng-pluralize>
|
||||
@ -7,51 +7,51 @@
|
||||
<div class="im_message_outer_wrap" ng-class="{im_message_selected: selectedMsgs[historyMessage.id]}" ng-click="toggleMessage(historyMessage.id, $event.target)">
|
||||
|
||||
|
||||
<div class="im_message_wrap clearfix">
|
||||
<div class="im_message_wrap clearfix" bindonce>
|
||||
|
||||
<div class="im_service_message_wrap" ng-if="historyMessage._ == 'messageService'">
|
||||
<div class="im_service_message_wrap" bo-if="historyMessage._ == 'messageService'">
|
||||
<div class="im_service_message">
|
||||
|
||||
<a ng-click="openUser(historyMessage.from_id)" class="im_message_author" ng-bind-html="historyMessage.fromUser.rFullName"></a>
|
||||
|
||||
<span class="im_message_service" ng-switch="historyMessage.action['_']">
|
||||
<span ng-switch-when="messageActionChatCreate">
|
||||
<span class="im_message_service" bo-switch="historyMessage.action['_']">
|
||||
<span bo-switch-when="messageActionChatCreate">
|
||||
created the group «<strong>{{historyMessage.action.title}}</strong>»
|
||||
</span>
|
||||
<span ng-switch-when="messageActionChatEditTitle">
|
||||
<span bo-switch-when="messageActionChatEditTitle">
|
||||
changed group name to «<strong ng-bind-html="historyMessage.action.rTitle"></strong>»
|
||||
</span>
|
||||
<span ng-switch-when="messageActionChatEditPhoto">
|
||||
<span bo-switch-when="messageActionChatEditPhoto">
|
||||
changed group photo
|
||||
</span>
|
||||
<span ng-switch-when="messageActionChatDeletePhoto">
|
||||
<span bo-switch-when="messageActionChatDeletePhoto">
|
||||
removed group photo
|
||||
</span>
|
||||
<span ng-switch-when="messageActionChatAddUser">
|
||||
<span ng-if="historyMessage.from_id != historyMessage.action.user_id">
|
||||
<span bo-switch-when="messageActionChatAddUser">
|
||||
<span bo-if="historyMessage.from_id != historyMessage.action.user_id">
|
||||
invited <a ng-click="openUser(historyMessage.action.user_id)" ng-bind-html="historyMessage.action.user.rFullName"></a>
|
||||
</span>
|
||||
<span ng-if="historyMessage.from_id == historyMessage.action.user_id">
|
||||
<span bo-if="historyMessage.from_id == historyMessage.action.user_id">
|
||||
returned to group
|
||||
</span>
|
||||
</span>
|
||||
<span ng-switch-when="messageActionChatDeleteUser">
|
||||
<span ng-if="historyMessage.from_id != historyMessage.action.user_id">
|
||||
<span bo-switch-when="messageActionChatDeleteUser">
|
||||
<span bo-if="historyMessage.from_id != historyMessage.action.user_id">
|
||||
kicked <a ng-click="openUser(historyMessage.action.user_id)" ng-bind-html="historyMessage.action.user.rFullName"></a>
|
||||
</span>
|
||||
<span ng-if="historyMessage.from_id == historyMessage.action.user_id">
|
||||
<span bo-if="historyMessage.from_id == historyMessage.action.user_id">
|
||||
left group
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span ng-switch-default>
|
||||
<span bo-switch-default>
|
||||
unsupported action {{historyMessage.action}}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<a ng-if="historyMessage.action._ == 'messageActionChatEditPhoto'" class="im_service_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.action.photo.id)">
|
||||
<a bo-if="historyMessage.action._ == 'messageActionChatEditPhoto'" class="im_service_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.action.photo.id)">
|
||||
<img
|
||||
class="im_service_message_photo_thumb"
|
||||
my-load-thumb
|
||||
@ -63,15 +63,16 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="im_content_message_wrap" ng-if="historyMessage._ != 'messageService'">
|
||||
<div bindonce bo-if="historyMessage._ != 'messageService'" class="im_content_message_wrap">
|
||||
<div class="im_content_message_select_area">
|
||||
<i class="icon icon-select-tick"></i>
|
||||
</div>
|
||||
|
||||
<a ng-click="historyMessage.send()" ng-if="historyMessage.error">
|
||||
<a bo-if="historyMessage.pending || historyMessage.error" ng-click="historyMessage.send()" ng-show="historyMessage.error">
|
||||
<i class="icon-message-status icon-message-status-error" tooltip="Try again"></i>
|
||||
</a>
|
||||
<i class="icon-message-status" ng-class="{'icon-message-status-unread': historyMessage.unread, 'icon-message-status-pending': historyMessage.pending}" ng-if="!historyMessage.error"></i>
|
||||
|
||||
<i bo-if="historyMessage.unread || historyMessage.pending" class="icon-message-status" ng-class="{'icon-message-status-unread': historyMessage.unread, 'icon-message-status-pending': historyMessage.pending}" ng-show="!historyMessage.error"></i>
|
||||
|
||||
<a ng-click="openUser(historyMessage.from_id)" class="im_message_from_photo pull-left">
|
||||
<img
|
||||
@ -81,20 +82,19 @@
|
||||
/>
|
||||
</a>
|
||||
<div class="im_message_meta pull-right text-right">
|
||||
<span class="im_message_date">{{historyMessage.date | dateOrTime}}</span>
|
||||
<span class="im_message_date" bo-bind="historyMessage.date | dateOrTime"></span>
|
||||
</div>
|
||||
|
||||
<div class="im_message_body">
|
||||
|
||||
<a class="im_message_author user_color_{{historyMessage.fromPhoto.num}}" ng-click="openUser(historyMessage.from_id)" ng-bind-html="historyMessage.fromUser.rFullName" ng-if="historyMessage.to_id.chat_id > 0"></a>
|
||||
<a class="im_message_author" ng-click="openUser(historyMessage.from_id)" ng-bind-html="historyMessage.fromUser.rFirstName" ng-if="!historyMessage.to_id.chat_id"></a>
|
||||
<a bo-if="historyMessage.to_id.chat_id > 0" class="im_message_author user_color_{{historyMessage.fromPhoto.num}}" ng-click="openUser(historyMessage.from_id)" ng-bind-html="historyMessage.fromUser.rFullName"></a>
|
||||
<a bo-if="!historyMessage.to_id.chat_id" class="im_message_author" ng-click="openUser(historyMessage.from_id)" ng-bind-html="historyMessage.fromUser.rFirstName" ></a>
|
||||
|
||||
|
||||
<div class="im_message_fwd_header" ng-if="historyMessage._ == 'messageForwarded'">
|
||||
<div bo-if="historyMessage._ == 'messageForwarded'" class="im_message_fwd_header">
|
||||
Forwarded message from <a class="im_message_fwd_author" ng-click="openUser(historyMessage.fwd_from_id)" ng-bind-html="historyMessage.fwdUser.rFirstName"></a>, <span class="im_message_fwd_date">{{historyMessage.fwd_date | dateOrTime}}</span>
|
||||
</div>
|
||||
|
||||
<div class="im_message_media" ng-if="historyMessage.media && historyMessage.media._ != 'messageMediaEmpty'" ng-switch="historyMessage.media._">
|
||||
<div bo-if="historyMessage.media && historyMessage.media._ != 'messageMediaEmpty'" class="im_message_media" ng-switch="historyMessage.media._">
|
||||
|
||||
<a ng-switch-when="messageMediaPhoto" class="im_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.media.photo.id)" style="width: {{historyMessage.media.photo.thumb.width}}px;">
|
||||
<img
|
||||
@ -147,8 +147,8 @@
|
||||
|
||||
<div ng-switch-when="messageMediaDocument" class="im_message_document" ng-class="{im_message_document_thumbed: !!historyMessage.media.document.thumb}">
|
||||
<a href="" ng-click="downloadDoc(historyMessage.media.document.id, false, historyMessage.media.document.withPreview)" ng-class="{im_message_document_link_disabled: historyMessage.media.document.progress.enabled}">
|
||||
<i class="icon icon-document" ng-if="!historyMessage.media.document.thumb"></i>
|
||||
<div class="im_message_document_thumb_wrap" ng-if="historyMessage.media.document.thumb">
|
||||
<i class="icon icon-document" bo-if="!historyMessage.media.document.thumb"></i>
|
||||
<div class="im_message_document_thumb_wrap" bo-if="historyMessage.media.document.thumb">
|
||||
<img
|
||||
class="im_message_document_thumb"
|
||||
my-load-thumb
|
||||
@ -173,7 +173,7 @@
|
||||
</div>
|
||||
<div class="im_message_document_actions" ng-if="!historyMessage.media.document.progress.enabled">
|
||||
<a href="" ng-click="downloadDoc(historyMessage.media.document.id)">Download</a>
|
||||
<a href="" ng-click="downloadDoc(historyMessage.media.document.id, false, true)" ng-if="historyMessage.media.document.withPreview">Open</a>
|
||||
<a href="" ng-click="downloadDoc(historyMessage.media.document.id, false, true)" bo-if="historyMessage.media.document.withPreview">Open</a>
|
||||
</div>
|
||||
<div class="im_message_download_progress_wrap" ng-if="historyMessage.media.document.progress.enabled">
|
||||
<div class="progress tg_down_progress">
|
||||
@ -220,7 +220,7 @@
|
||||
</div>
|
||||
<div class="im_message_audio_player_wrap" ng-if="historyMessage.media.audio.url">
|
||||
<audio my-audio-autoplay audio="historyMessage.media.audio" controls="controls">
|
||||
<source ng-src="{{historyMessage.media.audio.url}}" type="audio/mpeg" />
|
||||
<source bo-src="{{historyMessage.media.audio.url}}" type="audio/mpeg" />
|
||||
<embed hidden="true" autostart="true" loop="false" src="{{historyMessage.media.audio.url}}" />
|
||||
</audio>
|
||||
</div>
|
||||
@ -232,7 +232,7 @@
|
||||
</a>
|
||||
|
||||
<div ng-switch-when="messageMediaContact">
|
||||
<a ng-click="openUser(historyMessage.media.user.id)" class="im_message_contact_photo pull-left" ng-if="historyMessage.media.user">
|
||||
<a bo-if="historyMessage.media.user" ng-click="openUser(historyMessage.media.user.id)" class="im_message_contact_photo pull-left">
|
||||
<img
|
||||
class="im_message_contact_photo"
|
||||
my-load-thumb
|
||||
@ -273,7 +273,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="im_message_text" ng-if="historyMessage.message.length" ng-bind-html="historyMessage.richMessage"></div>
|
||||
<div class="im_message_text" bo-if="historyMessage.message.length" ng-bind-html="historyMessage.richMessage"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@
|
||||
thumb="profile.photo"
|
||||
/>
|
||||
<div class="settings_profile_photo_change_wrap">
|
||||
<div ng-if="photo.updating" class="settings_profile_photo_loading">Updating<span my-typing-dots></span></div>
|
||||
<div ng-if="photo.updating" class="settings_profile_photo_loading">Updating<span my-loading-dots></span></div>
|
||||
<div ng-if="!photo.updating">
|
||||
<div class="settings_profile_photo_update_link">
|
||||
<input my-file-upload type="file" multiple="false" class="im_attach_input" size="120" multiple="false" accept="image/x-png, image/png, image/gif, image/jpeg" />
|
||||
|
321
app/vendor/bindonce/bindonce.js
vendored
Normal file
321
app/vendor/bindonce/bindonce.js
vendored
Normal file
@ -0,0 +1,321 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
/**
|
||||
* Bindonce - Zero watches binding for AngularJs
|
||||
* @version v0.3.1
|
||||
* @link https://github.com/Pasvaz/bindonce
|
||||
* @author Pasquale Vazzana <pasqualevazzana@gmail.com>
|
||||
* @license MIT License, http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
var bindonceModule = angular.module('pasvaz.bindonce', []);
|
||||
|
||||
bindonceModule.directive('bindonce', function ()
|
||||
{
|
||||
var toBoolean = function (value)
|
||||
{
|
||||
if (value && value.length !== 0)
|
||||
{
|
||||
var v = angular.lowercase("" + value);
|
||||
value = !(v === 'f' || v === '0' || v === 'false' || v === 'no' || v === 'n' || v === '[]');
|
||||
}
|
||||
else
|
||||
{
|
||||
value = false;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
var msie = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
|
||||
if (isNaN(msie))
|
||||
{
|
||||
msie = parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
|
||||
}
|
||||
|
||||
var bindonceDirective =
|
||||
{
|
||||
restrict: "AM",
|
||||
controller: ['$scope', '$element', '$attrs', '$interpolate', function ($scope, $element, $attrs, $interpolate)
|
||||
{
|
||||
var showHideBinder = function (elm, attr, value)
|
||||
{
|
||||
var show = (attr === 'show') ? '' : 'none';
|
||||
var hide = (attr === 'hide') ? '' : 'none';
|
||||
elm.css('display', toBoolean(value) ? show : hide);
|
||||
};
|
||||
var classBinder = function (elm, value)
|
||||
{
|
||||
if (angular.isObject(value) && !angular.isArray(value))
|
||||
{
|
||||
var results = [];
|
||||
angular.forEach(value, function (value, index)
|
||||
{
|
||||
if (value) results.push(index);
|
||||
});
|
||||
value = results;
|
||||
}
|
||||
if (value)
|
||||
{
|
||||
elm.addClass(angular.isArray(value) ? value.join(' ') : value);
|
||||
}
|
||||
};
|
||||
var transclude = function (transcluder, scope)
|
||||
{
|
||||
transcluder.transclude(scope, function (clone)
|
||||
{
|
||||
var parent = transcluder.element.parent();
|
||||
var afterNode = transcluder.element && transcluder.element[transcluder.element.length - 1];
|
||||
var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
|
||||
var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
|
||||
angular.forEach(clone, function (node)
|
||||
{
|
||||
parentNode.insertBefore(node, afterNextSibling);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var ctrl =
|
||||
{
|
||||
watcherRemover: undefined,
|
||||
binders: [],
|
||||
group: $attrs.boName,
|
||||
element: $element,
|
||||
ran: false,
|
||||
|
||||
addBinder: function (binder)
|
||||
{
|
||||
this.binders.push(binder);
|
||||
|
||||
// In case of late binding (when using the directive bo-name/bo-parent)
|
||||
// it happens only when you use nested bindonce, if the bo-children
|
||||
// are not dom children the linking can follow another order
|
||||
if (this.ran)
|
||||
{
|
||||
this.runBinders();
|
||||
}
|
||||
},
|
||||
|
||||
setupWatcher: function (bindonceValue)
|
||||
{
|
||||
var that = this;
|
||||
this.watcherRemover = $scope.$watch(bindonceValue, function (newValue)
|
||||
{
|
||||
if (newValue === undefined) return;
|
||||
that.removeWatcher();
|
||||
that.checkBindonce(newValue);
|
||||
}, true);
|
||||
},
|
||||
|
||||
checkBindonce: function (value)
|
||||
{
|
||||
var that = this, promise = (value.$promise) ? value.$promise.then : value.then;
|
||||
// since Angular 1.2 promises are no longer
|
||||
// undefined until they don't get resolved
|
||||
if (typeof promise === 'function')
|
||||
{
|
||||
promise(function ()
|
||||
{
|
||||
that.runBinders();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
that.runBinders();
|
||||
}
|
||||
},
|
||||
|
||||
removeWatcher: function ()
|
||||
{
|
||||
if (this.watcherRemover !== undefined)
|
||||
{
|
||||
this.watcherRemover();
|
||||
this.watcherRemover = undefined;
|
||||
}
|
||||
},
|
||||
|
||||
runBinders: function ()
|
||||
{
|
||||
while (this.binders.length > 0)
|
||||
{
|
||||
var binder = this.binders.shift();
|
||||
if (this.group && this.group != binder.group) continue;
|
||||
var value = binder.scope.$eval((binder.interpolate) ? $interpolate(binder.value) : binder.value);
|
||||
switch (binder.attr)
|
||||
{
|
||||
case 'boIf':
|
||||
if (toBoolean(value))
|
||||
{
|
||||
transclude(binder, binder.scope.$new());
|
||||
}
|
||||
break;
|
||||
case 'boSwitch':
|
||||
var selectedTranscludes, switchCtrl = binder.controller[0];
|
||||
if ((selectedTranscludes = switchCtrl.cases['!' + value] || switchCtrl.cases['?']))
|
||||
{
|
||||
binder.scope.$eval(binder.attrs.change);
|
||||
angular.forEach(selectedTranscludes, function (selectedTransclude)
|
||||
{
|
||||
transclude(selectedTransclude, binder.scope.$new());
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'boSwitchWhen':
|
||||
var ctrl = binder.controller[0];
|
||||
ctrl.cases['!' + binder.attrs.boSwitchWhen] = (ctrl.cases['!' + binder.attrs.boSwitchWhen] || []);
|
||||
ctrl.cases['!' + binder.attrs.boSwitchWhen].push({ transclude: binder.transclude, element: binder.element });
|
||||
break;
|
||||
case 'boSwitchDefault':
|
||||
var ctrl = binder.controller[0];
|
||||
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
||||
ctrl.cases['?'].push({ transclude: binder.transclude, element: binder.element });
|
||||
break;
|
||||
case 'hide':
|
||||
case 'show':
|
||||
showHideBinder(binder.element, binder.attr, value);
|
||||
break;
|
||||
case 'class':
|
||||
classBinder(binder.element, value);
|
||||
break;
|
||||
case 'text':
|
||||
binder.element.text(value);
|
||||
break;
|
||||
case 'html':
|
||||
binder.element.html(value);
|
||||
break;
|
||||
case 'style':
|
||||
binder.element.css(value);
|
||||
break;
|
||||
case 'src':
|
||||
binder.element.attr(binder.attr, value);
|
||||
if (msie) binder.element.prop('src', value);
|
||||
break;
|
||||
case 'attr':
|
||||
angular.forEach(binder.attrs, function (attrValue, attrKey)
|
||||
{
|
||||
var newAttr, newValue;
|
||||
if (attrKey.match(/^boAttr./) && binder.attrs[attrKey])
|
||||
{
|
||||
newAttr = attrKey.replace(/^boAttr/, '').replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
newValue = binder.scope.$eval(binder.attrs[attrKey]);
|
||||
binder.element.attr(newAttr, newValue);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'href':
|
||||
case 'alt':
|
||||
case 'title':
|
||||
case 'id':
|
||||
case 'value':
|
||||
binder.element.attr(binder.attr, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.ran = true;
|
||||
}
|
||||
};
|
||||
|
||||
return ctrl;
|
||||
}],
|
||||
|
||||
link: function (scope, elm, attrs, bindonceController)
|
||||
{
|
||||
var value = attrs.bindonce && scope.$eval(attrs.bindonce);
|
||||
if (value !== undefined)
|
||||
{
|
||||
bindonceController.checkBindonce(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
bindonceController.setupWatcher(attrs.bindonce);
|
||||
elm.bind("$destroy", bindonceController.removeWatcher);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return bindonceDirective;
|
||||
});
|
||||
|
||||
angular.forEach(
|
||||
[
|
||||
{ directiveName: 'boShow', attribute: 'show' },
|
||||
{ directiveName: 'boHide', attribute: 'hide' },
|
||||
{ directiveName: 'boClass', attribute: 'class' },
|
||||
{ directiveName: 'boText', attribute: 'text' },
|
||||
{ directiveName: 'boBind', attribute: 'text' },
|
||||
{ directiveName: 'boHtml', attribute: 'html' },
|
||||
{ directiveName: 'boSrcI', attribute: 'src', interpolate: true },
|
||||
{ directiveName: 'boSrc', attribute: 'src' },
|
||||
{ directiveName: 'boHrefI', attribute: 'href', interpolate: true },
|
||||
{ directiveName: 'boHref', attribute: 'href' },
|
||||
{ directiveName: 'boAlt', attribute: 'alt' },
|
||||
{ directiveName: 'boTitle', attribute: 'title' },
|
||||
{ directiveName: 'boId', attribute: 'id' },
|
||||
{ directiveName: 'boStyle', attribute: 'style' },
|
||||
{ directiveName: 'boValue', attribute: 'value' },
|
||||
{ directiveName: 'boAttr', attribute: 'attr' },
|
||||
|
||||
{ directiveName: 'boIf', transclude: 'element', terminal: true, priority: 1000 },
|
||||
{ directiveName: 'boSwitch', require: 'boSwitch', controller: function () { this.cases = {}; } },
|
||||
{ directiveName: 'boSwitchWhen', transclude: 'element', priority: 800, require: '^boSwitch' },
|
||||
{ directiveName: 'boSwitchDefault', transclude: 'element', priority: 800, require: '^boSwitch' }
|
||||
],
|
||||
function (boDirective)
|
||||
{
|
||||
var childPriority = 200;
|
||||
return bindonceModule.directive(boDirective.directiveName, function ()
|
||||
{
|
||||
var bindonceDirective =
|
||||
{
|
||||
priority: boDirective.priority || childPriority,
|
||||
transclude: boDirective.transclude || false,
|
||||
terminal: boDirective.terminal || false,
|
||||
require: ['^bindonce'].concat(boDirective.require || []),
|
||||
controller: boDirective.controller,
|
||||
compile: function (tElement, tAttrs, transclude)
|
||||
{
|
||||
return function (scope, elm, attrs, controllers)
|
||||
{
|
||||
var bindonceController = controllers[0];
|
||||
var name = attrs.boParent;
|
||||
if (name && bindonceController.group !== name)
|
||||
{
|
||||
var element = bindonceController.element.parent();
|
||||
bindonceController = undefined;
|
||||
var parentValue;
|
||||
|
||||
while (element[0].nodeType !== 9 && element.length)
|
||||
{
|
||||
if ((parentValue = element.data('$bindonceController'))
|
||||
&& parentValue.group === name)
|
||||
{
|
||||
bindonceController = parentValue;
|
||||
break;
|
||||
}
|
||||
element = element.parent();
|
||||
}
|
||||
if (!bindonceController)
|
||||
{
|
||||
throw new Error("No bindonce controller: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
bindonceController.addBinder(
|
||||
{
|
||||
element: elm,
|
||||
attr: boDirective.attribute || boDirective.directiveName,
|
||||
attrs: attrs,
|
||||
value: attrs[boDirective.directiveName],
|
||||
interpolate: boDirective.interpolate,
|
||||
group: name,
|
||||
transclude: transclude,
|
||||
controller: controllers.slice(1),
|
||||
scope: scope
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return bindonceDirective;
|
||||
});
|
||||
})
|
||||
})();
|
Loading…
x
Reference in New Issue
Block a user