Make it work
This commit is contained in:
parent
e599438696
commit
81712ce31b
132
app/css/app.css
132
app/css/app.css
@ -1915,53 +1915,7 @@ img.img_fullsize {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Emoji area */
|
/* Message composer */
|
||||||
.emoji-wysiwyg-editor:empty:before {
|
|
||||||
content: attr(placeholder);
|
|
||||||
color: #9aa2ab;
|
|
||||||
}
|
|
||||||
.emoji-wysiwyg-editor:active:before,
|
|
||||||
.emoji-wysiwyg-editor:focus:before {
|
|
||||||
content: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-wysiwyg-editor {
|
|
||||||
box-sizing: content-box;
|
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
font-size: 12px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 6px;
|
|
||||||
min-height: 38px;
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
|
||||||
max-height: 284px;
|
|
||||||
overflow: auto;
|
|
||||||
line-height: 17px;
|
|
||||||
|
|
||||||
border: 1px solid #d2dbe3;
|
|
||||||
border-radius: 2px;
|
|
||||||
-webkit-box-shadow: none;
|
|
||||||
box-shadow: none;
|
|
||||||
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
|
||||||
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
|
||||||
|
|
||||||
-webkit-user-select: text;
|
|
||||||
word-wrap: break-word;
|
|
||||||
|
|
||||||
-webkit-user-select: text;
|
|
||||||
-moz-user-select: text;
|
|
||||||
-ms-user-select: text;
|
|
||||||
user-select: text;
|
|
||||||
}
|
|
||||||
.emoji-wysiwyg-editor img {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: -3px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.composer_emoji_insert_btn {
|
.composer_emoji_insert_btn {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -2001,6 +1955,18 @@ img.img_fullsize {
|
|||||||
background: #FFF;
|
background: #FFF;
|
||||||
padding: 5px 2px 5px 5px;
|
padding: 5px 2px 5px 5px;
|
||||||
}
|
}
|
||||||
|
.composer_emoji_tooltip_shown {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.composer_emoji_tooltip_tail {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -14px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -13px;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 26px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
.icon-tooltip-tail {
|
.icon-tooltip-tail {
|
||||||
background: #FFF;
|
background: #FFF;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
@ -2019,10 +1985,10 @@ img.img_fullsize {
|
|||||||
-webkit-border-radius: 2px;
|
-webkit-border-radius: 2px;
|
||||||
-moz-border-radius: 2px;
|
-moz-border-radius: 2px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
position: absolute;
|
position: relative;
|
||||||
bottom: -10px;
|
top: -8px;
|
||||||
left: 50%;
|
left: 4px;
|
||||||
margin-left: -9px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.composer_emoji_tooltip_tabs {
|
.composer_emoji_tooltip_tabs {
|
||||||
@ -2089,8 +2055,6 @@ a.composer_emoji_btn:hover {
|
|||||||
background-color: #edf2f5;
|
background-color: #edf2f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.emoji {
|
.emoji {
|
||||||
display: -moz-inline-box;
|
display: -moz-inline-box;
|
||||||
-moz-box-orient: vertical;
|
-moz-box-orient: vertical;
|
||||||
@ -2128,7 +2092,6 @@ a.composer_emoji_btn:hover {
|
|||||||
background-image: url('../img/emojisprite_4.png');
|
background-image: url('../img/emojisprite_4.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.emoji-w20 {
|
.emoji-w20 {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
@ -2141,6 +2104,18 @@ a.composer_emoji_btn:hover {
|
|||||||
.emoji-w20.emoji-spritesheet-3 {background-size: 680px 60px;}
|
.emoji-w20.emoji-spritesheet-3 {background-size: 680px 60px;}
|
||||||
.emoji-w20.emoji-spritesheet-4 {background-size: 680px 140px;}
|
.emoji-w20.emoji-spritesheet-4 {background-size: 680px 140px;}
|
||||||
|
|
||||||
|
.emoji-w26 {
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.emoji-w26.emoji-spritesheet-0 {background-size: 702px 182px;}
|
||||||
|
.emoji-w26.emoji-spritesheet-1 {background-size: 754px 104px;}
|
||||||
|
.emoji-w26.emoji-spritesheet-2 {background-size: 858px 182px;}
|
||||||
|
.emoji-w26.emoji-spritesheet-3 {background-size: 884px 78px;}
|
||||||
|
.emoji-w26.emoji-spritesheet-4 {background-size: 884px 182px;}
|
||||||
|
|
||||||
.composer_dropdown {
|
.composer_dropdown {
|
||||||
display: none;
|
display: none;
|
||||||
/*max-width: 100%;*/
|
/*max-width: 100%;*/
|
||||||
@ -2186,6 +2161,55 @@ a.composer_emoji_btn:hover {
|
|||||||
max-height: 64px;
|
max-height: 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.composer_rich_textarea {
|
||||||
|
box-sizing: content-box;
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 6px;
|
||||||
|
min-height: 38px;
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
max-height: 284px;
|
||||||
|
overflow: auto;
|
||||||
|
line-height: 17px;
|
||||||
|
|
||||||
|
border: 1px solid #d2dbe3;
|
||||||
|
border-radius: 2px;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||||
|
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||||
|
|
||||||
|
-webkit-user-select: text;
|
||||||
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
-ms-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.composer_rich_textarea:empty:before {
|
||||||
|
content: attr(placeholder);
|
||||||
|
color: #9aa2ab;
|
||||||
|
}
|
||||||
|
.composer_rich_textarea:active:before,
|
||||||
|
.composer_rich_textarea:focus:before {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
.composer_rich_textarea:empty:active:before,
|
||||||
|
.composer_rich_textarea:empty:focus:before {
|
||||||
|
content: attr(placeholder);
|
||||||
|
color: #9aa2ab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.composer_rich_textarea img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: -3px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.error_modal_window .modal-dialog {
|
.error_modal_window .modal-dialog {
|
||||||
|
@ -963,7 +963,7 @@ a.im_panel_peer_photo .peer_initials {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.composer_emoji_insert_btn:active .icon-emoji,
|
.composer_emoji_insert_btn:active .icon-emoji,
|
||||||
.composer_emoji_insert_btn.on .icon-emoji {
|
.composer_emoji_insert_btn.composer_emoji_insert_btn_on .icon-emoji {
|
||||||
background-position: -9px -367px;
|
background-position: -9px -367px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
@ -986,8 +986,8 @@ a.im_panel_peer_photo .peer_initials {
|
|||||||
.im_send_field_wrap {
|
.im_send_field_wrap {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
.emoji-wysiwyg-editor,
|
.composer_rich_textarea,
|
||||||
.form-control.im_message_field {
|
.composer_textarea {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
@ -999,8 +999,8 @@ a.im_panel_peer_photo .peer_initials {
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.emoji-wysiwyg-editor:focus,
|
.composer_rich_textarea:focus,
|
||||||
.form-control.im_message_field:focus {
|
.composer_textarea:focus {
|
||||||
border: 0;
|
border: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
@ -1105,7 +1105,7 @@ a.mobile_modal_action .tg_checkbox_label {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.im_emoji_btn {
|
.composer_emoji_insert_btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -1127,10 +1127,10 @@ a.mobile_modal_action .tg_checkbox_label {
|
|||||||
.is_1x .icon-emoji {
|
.is_1x .icon-emoji {
|
||||||
background-image: url(../img/icons/IconsetW_1x.png);
|
background-image: url(../img/icons/IconsetW_1x.png);
|
||||||
}
|
}
|
||||||
.im_emoji_btn:active .icon-emoji,
|
.composer_emoji_insert_btn:active .icon-emoji,
|
||||||
.is_1x .im_emoji_btn:active .icon-emoji,
|
.is_1x .composer_emoji_insert_btn:active .icon-emoji,
|
||||||
.im_emoji_btn.on .icon-emoji,
|
.composer_emoji_insert_btn.on .icon-emoji,
|
||||||
.is_1x .im_emoji_btn.on .icon-emoji {
|
.is_1x .composer_emoji_insert_btn.on .icon-emoji {
|
||||||
background-position: -10px -803px;
|
background-position: -10px -803px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1141,21 +1141,21 @@ a.mobile_modal_action .tg_checkbox_label {
|
|||||||
.im_send_field_wrap .form-control {
|
.im_send_field_wrap .form-control {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
.emoji-wysiwyg-editor {
|
.composer_rich_textarea {
|
||||||
min-height: 18px;
|
min-height: 18px;
|
||||||
max-height: 136px;
|
max-height: 136px;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
.emoji-wysiwyg-editor:empty {
|
.composer_rich_textarea:empty {
|
||||||
background: #f1f1f1;
|
background: #f1f1f1;
|
||||||
border-color: #f1f1f1;
|
border-color: #f1f1f1;
|
||||||
}
|
}
|
||||||
.emoji-wysiwyg-editor:empty:before {
|
.composer_rich_textarea:empty:before {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
.emoji-wysiwyg-editor:active,
|
.composer_rich_textarea:active,
|
||||||
.emoji-wysiwyg-editor:focus {
|
.composer_rich_textarea:focus {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
background: #FFF;
|
background: #FFF;
|
||||||
@ -1164,17 +1164,33 @@ a.mobile_modal_action .tg_checkbox_label {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.emoji-menu {
|
.composer_emoji_tooltip {
|
||||||
margin-left: -20px;
|
margin-left: 10px;
|
||||||
margin-top: -202px;
|
margin-top: -175px;
|
||||||
width: 262px;
|
width: 262px;
|
||||||
}
|
}
|
||||||
.emoji-menu .emoji-items-wrap {
|
.composer_emoji_tooltip .composer_emoji_tooltip_content {
|
||||||
height: 106px;
|
height: 106px;
|
||||||
}
|
}
|
||||||
.emoji-menu .emoji-items a {
|
.composer_emoji_tooltip .composer_emoji_tooltip_content .composer_emoji_btn {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
.icon-tooltip-tail {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.composer_emoji_tooltip_tab {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.composer_sticker_btn {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
.composer_sticker_image {
|
||||||
|
max-width: 64px;
|
||||||
|
max-height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.contacts_modal_search {
|
.contacts_modal_search {
|
||||||
|
@ -48,7 +48,6 @@
|
|||||||
<script type="text/javascript" src="js/lib/config.js"></script>
|
<script type="text/javascript" src="js/lib/config.js"></script>
|
||||||
<script type="text/javascript" src="js/init.js"></script>
|
<script type="text/javascript" src="js/init.js"></script>
|
||||||
<script type="text/javascript" src="vendor/jquery.nanoscroller/nanoscroller.js"></script>
|
<script type="text/javascript" src="vendor/jquery.nanoscroller/nanoscroller.js"></script>
|
||||||
<script type="text/javascript" src="vendor/jquery.emojiarea/jquery.emojiarea.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="vendor/angular/angular.js"></script>
|
<script type="text/javascript" src="vendor/angular/angular.js"></script>
|
||||||
<script type="text/javascript" src="vendor/angular/angular-route.js"></script>
|
<script type="text/javascript" src="vendor/angular/angular-route.js"></script>
|
||||||
@ -83,8 +82,8 @@
|
|||||||
<script type="text/javascript" src="js/templates.js"></script>
|
<script type="text/javascript" src="js/templates.js"></script>
|
||||||
PRODUCTION_ONLY_END-->
|
PRODUCTION_ONLY_END-->
|
||||||
|
|
||||||
<script type="text/javascript" src="js/directives.js"></script>
|
|
||||||
<script type="text/javascript" src="js/message_composer.js"></script>
|
<script type="text/javascript" src="js/message_composer.js"></script>
|
||||||
|
<script type="text/javascript" src="js/directives.js"></script>
|
||||||
<script type="text/javascript" src="js/directives_mobile.js"></script>
|
<script type="text/javascript" src="js/directives_mobile.js"></script>
|
||||||
<!-- endbuild -->
|
<!-- endbuild -->
|
||||||
|
|
||||||
|
@ -1448,10 +1448,10 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
var text = $scope.draftMessage.text;
|
var text = $scope.draftMessage.text;
|
||||||
|
|
||||||
if (angular.isString(text) && text.length > 0) {
|
if (angular.isString(text) && text.length > 0) {
|
||||||
text = text.replace(/:([a-z0-9\-\+\*_]+?):/gi, function (all, name) {
|
text = text.replace(/:([a-z0-9\-\+\*_]+?):/gi, function (all, shortcut) {
|
||||||
var utfChar = $.emojiarea.reverseIcons[name];
|
var emojiCode = EmojiHelper.shortcuts[shortcut];
|
||||||
if (utfChar !== undefined) {
|
if (emojiCode !== undefined) {
|
||||||
return utfChar;
|
return EmojiHelper.emojis[emojiCode][0];
|
||||||
}
|
}
|
||||||
return all;
|
return all;
|
||||||
});
|
});
|
||||||
@ -1506,10 +1506,10 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
var backupDraftObj = {};
|
var backupDraftObj = {};
|
||||||
backupDraftObj['draft' + $scope.curDialog.peerID] = newVal;
|
backupDraftObj['draft' + $scope.curDialog.peerID] = newVal;
|
||||||
Storage.set(backupDraftObj);
|
Storage.set(backupDraftObj);
|
||||||
// console.log('draft save', backupDraftObj);
|
// console.log(dT(), 'draft save', backupDraftObj);
|
||||||
} else {
|
} else {
|
||||||
Storage.remove('draft' + $scope.curDialog.peerID);
|
Storage.remove('draft' + $scope.curDialog.peerID);
|
||||||
// console.log('draft delete', 'draft' + $scope.curDialog.peerID);
|
// console.log(dT(), 'draft delete', 'draft' + $scope.curDialog.peerID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1072,7 +1072,15 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
|
|
||||||
function link ($scope, element, attrs) {
|
function link ($scope, element, attrs) {
|
||||||
|
|
||||||
|
var messageField = $('textarea', element)[0];
|
||||||
var emojiButton = $('.composer_emoji_insert_btn', element)[0];
|
var emojiButton = $('.composer_emoji_insert_btn', element)[0];
|
||||||
|
var emojiPanel = $('.composer_emoji_panel', element)[0];
|
||||||
|
var fileSelects = $('input', element);
|
||||||
|
var dropbox = $('.im_send_dropbox_wrap', element)[0];
|
||||||
|
var messageFieldWrap = $('.im_send_field_wrap', element)[0];
|
||||||
|
var dragStarted, dragTimeout;
|
||||||
|
var submitBtn = $('.im_submit', element)[0];
|
||||||
|
|
||||||
new EmojiTooltip(emojiButton, {
|
new EmojiTooltip(emojiButton, {
|
||||||
getStickers: function (callback) {
|
getStickers: function (callback) {
|
||||||
AppStickersManager.getStickers().then(function () {
|
AppStickersManager.getStickers().then(function () {
|
||||||
@ -1093,153 +1101,77 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var emojiPanel = $('.composer_emoji_panel', element)[0];
|
var composerEmojiPanel;
|
||||||
new EmojiPanel(emojiPanel, {
|
if (emojiPanel) {
|
||||||
onEmojiSelected: function (code) {
|
composerEmojiPanel = new EmojiPanel(emojiPanel, {
|
||||||
composer.onEmojiSelected(code);
|
onEmojiSelected: function (code) {
|
||||||
}
|
composer.onEmojiSelected(code);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var messageField = $('textarea', element)[0];
|
|
||||||
var composer = new MessageComposer(messageField, {});
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
var messageField = $('textarea', element)[0],
|
|
||||||
fileSelects = $('input', element),
|
|
||||||
dropbox = $('.im_send_dropbox_wrap', element)[0],
|
|
||||||
emojiButton = $('.im_emoji_btn', element)[0],
|
|
||||||
emojiQuickSelect = !Config.Mobile ? $('.im_emoji_quick_select_area', element)[0] : false,
|
|
||||||
editorElement = messageField,
|
|
||||||
dragStarted, dragTimeout,
|
|
||||||
emojiArea = $(messageField).emojiarea({button: emojiButton, norealTime: true, quickSelect: emojiQuickSelect}),
|
|
||||||
emojiMenu = $('.emoji-menu', element)[0],
|
|
||||||
submitBtn = $('.im_submit', element)[0],
|
|
||||||
richTextarea = $('.emoji-wysiwyg-editor', element)[0];
|
|
||||||
|
|
||||||
if (richTextarea) {
|
|
||||||
editorElement = richTextarea;
|
|
||||||
$(richTextarea).addClass('form-control');
|
|
||||||
$(richTextarea).attr('placeholder', $interpolate($(messageField).attr('placeholder'))($scope));
|
|
||||||
|
|
||||||
var updatePromise;
|
|
||||||
$(richTextarea)
|
|
||||||
.on('DOMNodeInserted', onPastedImageEvent)
|
|
||||||
.on('keyup', function (e) {
|
|
||||||
updateHeight();
|
|
||||||
|
|
||||||
if (!sendAwaiting) {
|
|
||||||
$scope.$apply(function () {
|
|
||||||
$scope.draftMessage.text = richTextarea.textContent;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$timeout.cancel(updatePromise);
|
|
||||||
updatePromise = $timeout(updateValue, 1000);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head is sometimes slower
|
var composer = new MessageComposer(messageField, {
|
||||||
$timeout(function () {
|
onTyping: function () {
|
||||||
fileSelects
|
$scope.$emit('ui_typing');
|
||||||
.on('change', function () {
|
},
|
||||||
var self = this;
|
getSendOnEnter: function () {
|
||||||
$scope.$apply(function () {
|
return sendOnEnter;
|
||||||
$scope.draftMessage.files = Array.prototype.slice.call(self.files);
|
},
|
||||||
$scope.draftMessage.isMedia = $(self).hasClass('im_media_attach_input') || Config.Mobile;
|
onMessageSubmit: onMessageSubmit,
|
||||||
setTimeout(function () {
|
onFilesPaste: onFilesPaste
|
||||||
try {
|
});
|
||||||
self.value = '';
|
|
||||||
} catch (e) {};
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
var sendOnEnter = true,
|
var richTextarea = composer.richTextareaEl[0];
|
||||||
updateSendSettings = function () {
|
if (richTextarea) {
|
||||||
Storage.get('send_ctrlenter').then(function (sendOnCtrl) {
|
$(richTextarea)
|
||||||
sendOnEnter = !sendOnCtrl;
|
.attr('placeholder', $interpolate($(messageField).attr('placeholder'))($scope))
|
||||||
});
|
.on('keydown keyup', updateHeight);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
fileSelects.on('change', function () {
|
||||||
|
var self = this;
|
||||||
|
$scope.$apply(function () {
|
||||||
|
$scope.draftMessage.files = Array.prototype.slice.call(self.files);
|
||||||
|
$scope.draftMessage.isMedia = $(self).hasClass('im_media_attach_input') || Config.Mobile;
|
||||||
|
setTimeout(function () {
|
||||||
|
try {
|
||||||
|
self.value = '';
|
||||||
|
} catch (e) {};
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var sendOnEnter = true;
|
||||||
|
function updateSendSettings () {
|
||||||
|
Storage.get('send_ctrlenter').then(function (sendOnCtrl) {
|
||||||
|
sendOnEnter = !sendOnCtrl;
|
||||||
|
});
|
||||||
|
};
|
||||||
$scope.$on('settings_changed', updateSendSettings);
|
$scope.$on('settings_changed', updateSendSettings);
|
||||||
updateSendSettings();
|
updateSendSettings();
|
||||||
|
|
||||||
$(editorElement).on('keydown', function (e) {
|
$(submitBtn).on('mousedown touchstart', onMessageSubmit);
|
||||||
if (richTextarea) {
|
|
||||||
updateHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.keyCode == 13) {
|
function onMessageSubmit (e) {
|
||||||
var submit = false;
|
$scope.$apply(function () {
|
||||||
if (sendOnEnter && !e.shiftKey) {
|
updateValue();
|
||||||
submit = true;
|
$scope.draftMessage.send();
|
||||||
} else if (!sendOnEnter && (e.ctrlKey || e.metaKey)) {
|
composer.resetTyping();
|
||||||
submit = true;
|
if (composerEmojiPanel) {
|
||||||
|
composerEmojiPanel.update();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
if (submit) {
|
|
||||||
$timeout.cancel(updatePromise);
|
|
||||||
updateValue();
|
|
||||||
$scope.draftMessage.send();
|
|
||||||
$(element).trigger('message_send');
|
|
||||||
resetTyping();
|
|
||||||
return cancelEvent(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$(submitBtn).on('mousedown touchstart', function (e) {
|
|
||||||
$timeout.cancel(updatePromise);
|
|
||||||
updateValue();
|
|
||||||
$scope.draftMessage.send();
|
|
||||||
$(element).trigger('message_send');
|
|
||||||
resetTyping();
|
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
});
|
|
||||||
|
|
||||||
var lastTyping = 0,
|
|
||||||
lastLength;
|
|
||||||
$(editorElement).on('keyup', function (e) {
|
|
||||||
var now = tsNow(),
|
|
||||||
length = (editorElement[richTextarea ? 'textContent' : 'value']).length;
|
|
||||||
|
|
||||||
|
|
||||||
if (now - lastTyping > 5000 && length != lastLength) {
|
|
||||||
lastTyping = now;
|
|
||||||
lastLength = length;
|
|
||||||
$scope.$emit('ui_typing');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function resetTyping () {
|
|
||||||
lastTyping = 0;
|
|
||||||
lastLength = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
function updateRichTextarea () {
|
|
||||||
if (richTextarea) {
|
|
||||||
$timeout.cancel(updatePromise);
|
|
||||||
var html = $('<div>').text($scope.draftMessage.text || '').html();
|
|
||||||
html = html.replace(/\n/g, '<br/>');
|
|
||||||
$(richTextarea).html(html);
|
|
||||||
lastLength = html.length;
|
|
||||||
updateHeight();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateValue () {
|
function updateValue () {
|
||||||
if (richTextarea) {
|
if (richTextarea) {
|
||||||
$(richTextarea).trigger('change');
|
composer.onChange();
|
||||||
updateHeight();
|
updateHeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var height = richTextarea.offsetHeight;
|
var height = richTextarea && richTextarea.offsetHeight;
|
||||||
function updateHeight () {
|
function updateHeight () {
|
||||||
var newHeight = richTextarea.offsetHeight;
|
var newHeight = richTextarea.offsetHeight;
|
||||||
if (height != newHeight) {
|
if (height != newHeight) {
|
||||||
@ -1250,7 +1182,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
|
|
||||||
function onKeyDown(e) {
|
function onKeyDown(e) {
|
||||||
if (e.keyCode == 9 && !e.shiftKey && !e.ctrlKey && !e.metaKey && !$modalStack.getTop()) { // TAB
|
if (e.keyCode == 9 && !e.shiftKey && !e.ctrlKey && !e.metaKey && !$modalStack.getTop()) { // TAB
|
||||||
editorElement.focus();
|
composer.focus();
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1265,13 +1197,18 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
$scope.$on('ui_history_change', focusField);
|
$scope.$on('ui_history_change', focusField);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$on('ui_peer_change', resetTyping);
|
$scope.$on('ui_peer_change', composer.resetTyping.bind(composer));
|
||||||
$scope.$on('ui_peer_draft', updateRichTextarea);
|
$scope.$on('ui_peer_draft', function () {
|
||||||
|
if (richTextarea) {
|
||||||
|
composer.setValue($scope.draftMessage.text || '');
|
||||||
|
updateHeight();
|
||||||
|
}
|
||||||
|
composer.focus();
|
||||||
|
});
|
||||||
|
|
||||||
var sendAwaiting = false;
|
var sendAwaiting = false;
|
||||||
$scope.$on('ui_message_before_send', function () {
|
$scope.$on('ui_message_before_send', function () {
|
||||||
sendAwaiting = true;
|
sendAwaiting = true;
|
||||||
$timeout.cancel(updatePromise);
|
|
||||||
updateValue();
|
updateValue();
|
||||||
});
|
});
|
||||||
$scope.$on('ui_message_send', function () {
|
$scope.$on('ui_message_send', function () {
|
||||||
@ -1279,35 +1216,17 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
focusField();
|
focusField();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function focusField () {
|
function focusField () {
|
||||||
onContentLoaded(function () {
|
onContentLoaded(function () {
|
||||||
editorElement.focus();
|
composer.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPastedImageEvent (e) {
|
function onFilesPaste (blobs) {
|
||||||
var element = (e.originalEvent || e).target,
|
ErrorService.confirm({type: 'FILE_CLIPBOARD_PASTE'}).then(function () {
|
||||||
src = (element || {}).src || '',
|
$scope.draftMessage.files = blobs;
|
||||||
remove = false;
|
$scope.draftMessage.isMedia = true;
|
||||||
|
});
|
||||||
if (src.substr(0, 5) == 'data:') {
|
|
||||||
remove = true;
|
|
||||||
var blob = dataUrlToBlob(src);
|
|
||||||
ErrorService.confirm({type: 'FILE_CLIPBOARD_PASTE'}).then(function () {
|
|
||||||
$scope.draftMessage.files = [blob];
|
|
||||||
$scope.draftMessage.isMedia = true;
|
|
||||||
});
|
|
||||||
setZeroTimeout(function () {
|
|
||||||
element.parentNode.removeChild(element);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if (src && !src.match(/img\/blank\.gif/)) {
|
|
||||||
var replacementNode = document.createTextNode(' ' + src + ' ');
|
|
||||||
setTimeout(function () {
|
|
||||||
element.parentNode.replaceChild(replacementNode, element);
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function onPasteEvent (e) {
|
function onPasteEvent (e) {
|
||||||
@ -1348,7 +1267,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
if (e.type == 'dragenter' || e.type == 'dragover') {
|
if (e.type == 'dragenter' || e.type == 'dragover') {
|
||||||
if (dragStateChanged) {
|
if (dragStateChanged) {
|
||||||
$(dropbox)
|
$(dropbox)
|
||||||
.css({height: editorElement.offsetHeight + 2, width: editorElement.offsetWidth})
|
.css({height: messageFieldWrap.offsetHeight + 2, width: messageFieldWrap.offsetWidth})
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1371,15 +1290,11 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
|
|
||||||
|
|
||||||
$scope.$on('$destroy', function cleanup() {
|
$scope.$on('$destroy', function cleanup() {
|
||||||
$('body').off('dragenter dragleave dragover drop', onDragDropEvent);
|
|
||||||
$(document).off('paste', onPasteEvent);
|
$(document).off('paste', onPasteEvent);
|
||||||
$(document).off('keydown', onKeyDown);
|
$(document).off('keydown', onKeyDown);
|
||||||
$(submitBtn).off('mousedown')
|
$('body').off('dragenter dragleave dragover drop', onDragDropEvent);
|
||||||
|
$(submitBtn).off('mousedown touchstart');
|
||||||
fileSelects.off('change');
|
fileSelects.off('change');
|
||||||
if (richTextarea) {
|
|
||||||
$(richTextarea).off('DOMNodeInserted keyup', onPastedImageEvent);
|
|
||||||
}
|
|
||||||
$(editorElement).off('keydown');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!Config.Navigator.touch) {
|
if (!Config.Navigator.touch) {
|
||||||
|
@ -112,25 +112,63 @@ function getFieldSelection (field) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFieldValue(field) {
|
function getRichValue(field) {
|
||||||
if (!field) {
|
if (!field) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (field.tagName == 'INPUT' || field.tagName == 'TEXTAREA') {
|
|
||||||
return field.value;
|
|
||||||
}
|
|
||||||
var lines = [];
|
var lines = [];
|
||||||
var line = [];
|
var line = [];
|
||||||
getFieldElementValue(field, lines, line);
|
|
||||||
|
getRichElementValue(field, lines, line);
|
||||||
if (line.length) {
|
if (line.length) {
|
||||||
lines.push(line.join(''));
|
lines.push(line.join(''));
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines.join('\n');
|
return lines.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFieldElementValue(node, lines, line) {
|
function getRichValueWithCaret(field) {
|
||||||
|
if (!field) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var lines = [];
|
||||||
|
var line = [];
|
||||||
|
|
||||||
|
var sel = window.getSelection ? window.getSelection() : false;
|
||||||
|
var selNode, selOffset;
|
||||||
|
if (sel && sel.rangeCount) {
|
||||||
|
var range = sel.getRangeAt(0);
|
||||||
|
if (range.startContainer &&
|
||||||
|
range.startContainer == range.endContainer &&
|
||||||
|
range.startOffset == range.endOffset) {
|
||||||
|
selNode = range.startContainer;
|
||||||
|
selOffset = range.startOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getRichElementValue(field, lines, line, selNode, selOffset);
|
||||||
|
|
||||||
|
if (line.length) {
|
||||||
|
lines.push(line.join(''));
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = lines.join('\n');
|
||||||
|
var caretPos = value.indexOf('\001');
|
||||||
|
if (caretPos != -1) {
|
||||||
|
value = value.substr(0, caretPos) + value.substr(caretPos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [value, caretPos];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRichElementValue(node, lines, line, selNode, selOffset) {
|
||||||
if (node.nodeType == 3) { // TEXT
|
if (node.nodeType == 3) { // TEXT
|
||||||
line.push(node.nodeValue);
|
if (selNode === node) {
|
||||||
|
var value = node.nodeValue;
|
||||||
|
line.push(value.substr(0, selOffset) + '\001' + value.substr(selOffset));
|
||||||
|
} else {
|
||||||
|
line.push(node.nodeValue);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node.nodeType != 1) { // NON-ELEMENT
|
if (node.nodeType != 1) { // NON-ELEMENT
|
||||||
@ -147,9 +185,12 @@ function getFieldElementValue(node, lines, line) {
|
|||||||
line.push(node.alt);
|
line.push(node.alt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (selNode === node) {
|
||||||
|
line.push('\001');
|
||||||
|
}
|
||||||
var curChild = node.firstChild;
|
var curChild = node.firstChild;
|
||||||
while (curChild) {
|
while (curChild) {
|
||||||
getFieldElementValue(curChild, lines, line);
|
getRichElementValue(curChild, lines, line, selNode, selOffset);
|
||||||
curChild = curChild.nextSibling;
|
curChild = curChild.nextSibling;
|
||||||
}
|
}
|
||||||
if (isBlock && line.length) {
|
if (isBlock && line.length) {
|
||||||
@ -158,8 +199,31 @@ function getFieldElementValue(node, lines, line) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setRichFocus(field, selectNode) {
|
||||||
|
field.focus();
|
||||||
|
if (window.getSelection && document.createRange) {
|
||||||
|
var range = document.createRange();
|
||||||
|
if (selectNode) {
|
||||||
|
range.selectNode(selectNode);
|
||||||
|
} else {
|
||||||
|
range.selectNodeContents(field);
|
||||||
|
}
|
||||||
|
range.collapse(false);
|
||||||
|
|
||||||
|
var sel = window.getSelection();
|
||||||
|
sel.removeAllRanges();
|
||||||
|
sel.addRange(range);
|
||||||
|
}
|
||||||
|
else if (document.body.createTextRange !== undefined) {
|
||||||
|
var textRange = document.body.createTextRange();
|
||||||
|
textRange.moveToElementText(selectNode || field);
|
||||||
|
textRange.collapse(false);
|
||||||
|
textRange.select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onContentLoaded (cb) {
|
function onContentLoaded (cb) {
|
||||||
setTimeout(cb, 0);
|
setZeroTimeout(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tsNow (seconds) {
|
function tsNow (seconds) {
|
||||||
|
@ -147,6 +147,17 @@ function EmojiTooltip (btnEl, options) {
|
|||||||
self.onMouseLeave(true);
|
self.onMouseLeave(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$(this.btnEl).on('mousedown', function (e) {
|
||||||
|
if (!self.shown) {
|
||||||
|
clearTimeout(self.showTimeout);
|
||||||
|
delete self.showTimeout;
|
||||||
|
self.show();
|
||||||
|
} else {
|
||||||
|
clearTimeout(self.hideTimeout);
|
||||||
|
delete self.hideTimeout;
|
||||||
|
self.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiTooltip.prototype.onMouseEnter = function (triggerShow) {
|
EmojiTooltip.prototype.onMouseEnter = function (triggerShow) {
|
||||||
@ -180,7 +191,7 @@ EmojiTooltip.prototype.createTooltip = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.tooltipEl = $('<div class="composer_emoji_tooltip noselect"><div class="composer_emoji_tooltip_tabs"></div><div class="composer_emoji_tooltip_content clearfix"></div><div class="composer_emoji_tooltip_footer"><a class="composer_emoji_tooltip_settings"></a></div><i class="icon icon-tooltip-tail"></i></div>').appendTo(document.body);
|
this.tooltipEl = $('<div class="composer_emoji_tooltip noselect"><div class="composer_emoji_tooltip_tabs"></div><div class="composer_emoji_tooltip_content clearfix"></div><div class="composer_emoji_tooltip_footer"><a class="composer_emoji_tooltip_settings"></a></div><div class="composer_emoji_tooltip_tail"><i class="icon icon-tooltip-tail"></i></div></div>').appendTo(document.body);
|
||||||
|
|
||||||
this.tabsEl = $('.composer_emoji_tooltip_tabs', this.tooltip);
|
this.tabsEl = $('.composer_emoji_tooltip_tabs', this.tooltip);
|
||||||
this.contentEl = $('.composer_emoji_tooltip_content', this.tooltip);
|
this.contentEl = $('.composer_emoji_tooltip_content', this.tooltip);
|
||||||
@ -278,7 +289,7 @@ EmojiTooltip.prototype.updateTabContents = function (tab) {
|
|||||||
emoticonData = Config.Emoji[emoticonCode];
|
emoticonData = Config.Emoji[emoticonCode];
|
||||||
x = iconSize * (i % totalColumns);
|
x = iconSize * (i % totalColumns);
|
||||||
y = iconSize * Math.floor(i / totalColumns);
|
y = iconSize * Math.floor(i / totalColumns);
|
||||||
html.push('<a class="composer_emoji_btn" title=":' + encodeEntities(emoticonData[1][0]) + ':" data-code="' + encodeEntities(emoticonCode) + '"><i class="emoji emoji-w20 emoji-spritesheet-' + categoryIndex + '" style="background-position: -' + x + 'px -' + y + 'px;"></i></a>');
|
html.push('<a class="composer_emoji_btn" title=":' + encodeEntities(emoticonData[1][0]) + ':" data-code="' + encodeEntities(emoticonCode) + '"><i class="emoji emoji-w' + iconSize + ' emoji-spritesheet-' + categoryIndex + '" style="background-position: -' + x + 'px -' + y + 'px;"></i></a>');
|
||||||
}
|
}
|
||||||
this.contentEl.html(html.join(''));
|
this.contentEl.html(html.join(''));
|
||||||
}
|
}
|
||||||
@ -296,7 +307,7 @@ EmojiTooltip.prototype.updateTabContents = function (tab) {
|
|||||||
pos = spritesheet[1];
|
pos = spritesheet[1];
|
||||||
x = iconSize * spritesheet[3];
|
x = iconSize * spritesheet[3];
|
||||||
y = iconSize * spritesheet[2];
|
y = iconSize * spritesheet[2];
|
||||||
html.push('<a class="composer_emoji_btn" title=":' + encodeEntities(emoticonData[1][0]) + ':" data-code="' + encodeEntities(emoticonCode) + '"><i class="emoji emoji-w20 emoji-spritesheet-' + categoryIndex + '" style="background-position: -' + x + 'px -' + y + 'px;"></i></a>');
|
html.push('<a class="composer_emoji_btn" title=":' + encodeEntities(emoticonData[1][0]) + ':" data-code="' + encodeEntities(emoticonCode) + '"><i class="emoji emoji-w' + iconSize + ' emoji-spritesheet-' + categoryIndex + '" style="background-position: -' + x + 'px -' + y + 'px;"></i></a>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.contentEl.html(html.join(''));
|
self.contentEl.html(html.join(''));
|
||||||
@ -311,13 +322,17 @@ EmojiTooltip.prototype.updatePosition = function () {
|
|||||||
|
|
||||||
EmojiTooltip.prototype.show = function () {
|
EmojiTooltip.prototype.show = function () {
|
||||||
this.updatePosition();
|
this.updatePosition();
|
||||||
this.tooltipEl.show();
|
this.tooltipEl.addClass('composer_emoji_tooltip_shown');
|
||||||
|
this.btnEl.addClass('composer_emoji_insert_btn_on');
|
||||||
delete this.showTimeout;
|
delete this.showTimeout;
|
||||||
|
this.shown = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
EmojiTooltip.prototype.hide = function () {
|
EmojiTooltip.prototype.hide = function () {
|
||||||
this.tooltipEl.hide();
|
this.tooltipEl.removeClass('composer_emoji_tooltip_shown');
|
||||||
|
this.btnEl.removeClass('composer_emoji_insert_btn_on');
|
||||||
delete this.hideTimeout;
|
delete this.hideTimeout;
|
||||||
|
delete this.shown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -381,8 +396,6 @@ function MessageComposer (textarea, options) {
|
|||||||
this.textareaEl = $(textarea);
|
this.textareaEl = $(textarea);
|
||||||
|
|
||||||
this.setUpInput();
|
this.setUpInput();
|
||||||
// this.textareaEl.on('keyup keydown', this.onKeyEvent.bind(this));
|
|
||||||
// this.textareaEl.on('focus blur', this.onFocusBlur.bind(this));
|
|
||||||
|
|
||||||
this.autoCompleteEl = $('<ul class="composer_dropdown dropdown-menu"></ul>').appendTo(document.body);
|
this.autoCompleteEl = $('<ul class="composer_dropdown dropdown-menu"></ul>').appendTo(document.body);
|
||||||
|
|
||||||
@ -395,7 +408,7 @@ function MessageComposer (textarea, options) {
|
|||||||
}
|
}
|
||||||
if (code = target.attr('data-code')) {
|
if (code = target.attr('data-code')) {
|
||||||
if (self.onEmojiSelected) {
|
if (self.onEmojiSelected) {
|
||||||
self.onEmojiSelected(code);
|
self.onEmojiSelected(code, true);
|
||||||
}
|
}
|
||||||
EmojiHelper.pushPopularEmoji(code);
|
EmojiHelper.pushPopularEmoji(code);
|
||||||
}
|
}
|
||||||
@ -403,24 +416,32 @@ function MessageComposer (textarea, options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.isActive = false;
|
this.isActive = false;
|
||||||
|
|
||||||
|
this.onTyping = options.onTyping;
|
||||||
|
this.onMessageSubmit = options.onMessageSubmit;
|
||||||
|
this.getSendOnEnter = options.getSendOnEnter;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.setUpInput = function () {
|
MessageComposer.prototype.setUpInput = function () {
|
||||||
if ('contentEditable' in document.body) {
|
if ('contentEditable' in document.body) {
|
||||||
this.setUpContenteditable();
|
this.setUpRich();
|
||||||
} else {
|
} else {
|
||||||
this.setUpPlaintext();
|
this.setUpPlaintext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.setUpContenteditable = function () {
|
MessageComposer.prototype.setUpRich = function () {
|
||||||
this.textareaEl.hide();
|
this.textareaEl.hide();
|
||||||
this.contentEditableEl = $('<div class="composer_rich_textarea" contenteditable="true"></div>');
|
this.richTextareaEl = $('<div class="composer_rich_textarea" contenteditable="true"></div>');
|
||||||
|
|
||||||
this.textareaEl[0].parentNode.insertBefore(this.contentEditableEl[0], this.textareaEl[0]);
|
this.textareaEl[0].parentNode.insertBefore(this.richTextareaEl[0], this.textareaEl[0]);
|
||||||
|
|
||||||
this.contentEditableEl.on('keyup keydown', this.onKeyEvent.bind(this));
|
this.richTextareaEl.on('keyup keydown', this.onKeyEvent.bind(this));
|
||||||
this.contentEditableEl.on('focus blur', this.onFocusBlur.bind(this));
|
this.richTextareaEl.on('focus blur', this.onFocusBlur.bind(this));
|
||||||
|
this.richTextareaEl.on('paste', this.onRichPaste.bind(this));
|
||||||
|
this.richTextareaEl.on('DOMNodeInserted', this.onRichPasteNode.bind(this));
|
||||||
|
|
||||||
|
$(document.body).on('keydown', this.backupSelection.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.setUpPlaintext = function () {
|
MessageComposer.prototype.setUpPlaintext = function () {
|
||||||
@ -432,51 +453,145 @@ MessageComposer.prototype.onKeyEvent = function (e) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
if (e.type == 'keyup') {
|
if (e.type == 'keyup') {
|
||||||
this.checkAutocomplete();
|
this.checkAutocomplete();
|
||||||
}
|
|
||||||
if (e.type == 'keydown' && this.autocompleteShown) {
|
|
||||||
if (e.keyCode == 38 || e.keyCode == 40) { // UP / DOWN
|
|
||||||
var next = e.keyCode == 40;
|
|
||||||
var currentSelected = $(this.autoCompleteEl).find('.composer_emoji_option_active');
|
|
||||||
|
|
||||||
if (currentSelected.length) {
|
if (this.onTyping) {
|
||||||
var currentSelectedWrap = currentSelected[0].parentNode;
|
var now = tsNow();
|
||||||
var nextWrap = currentSelectedWrap[next ? 'nextSibling' : 'previousSibling'];
|
if (now - this.lastTyping > 5000) {
|
||||||
currentSelected.removeClass('composer_emoji_option_active');
|
var length = (this.richTextareaEl ? this.richTextareaEl[0].textContent : this.textareaEl[0].value).length;
|
||||||
if (nextWrap) {
|
|
||||||
$(nextWrap).find('a').addClass('composer_emoji_option_active');
|
if (length != this.lastLength) {
|
||||||
return cancelEvent(e);
|
this.lastTyping = now;
|
||||||
|
this.lastLength = length;
|
||||||
|
this.onTyping();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var childNodes = this.autoCompleteEl[0].childNodes;
|
|
||||||
var nextWrap = childNodes[next ? 0 : childNodes.length - 1];
|
|
||||||
$(nextWrap).find('a').addClass('composer_emoji_option_active');
|
|
||||||
|
|
||||||
return cancelEvent(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode == 13) { // ENTER
|
if (this.richTextareaEl) {
|
||||||
var currentSelected = $(this.autoCompleteEl).find('.composer_emoji_option_active') ||
|
clearTimeout(this.updateValueTO);
|
||||||
$(this.autoCompleteEl).childNodes[0].find('a');
|
var now = tsNow();
|
||||||
var code = currentSelected.attr('data-code');
|
if (this.keyupStarted === undefined) {
|
||||||
if (code) {
|
this.keyupStarted = now;
|
||||||
this.onEmojiSelected(code);
|
}
|
||||||
EmojiHelper.pushPopularEmoji(code);
|
if (now - this.keyupStarted > 10000) {
|
||||||
|
this.onChange();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.updateValueTO = setTimeout(this.onChange.bind(this), 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (e.type == 'keydown') {
|
||||||
|
if (this.autocompleteShown) {
|
||||||
|
if (e.keyCode == 38 || e.keyCode == 40) { // UP / DOWN
|
||||||
|
var next = e.keyCode == 40;
|
||||||
|
var currentSelected = $(this.autoCompleteEl).find('.composer_emoji_option_active');
|
||||||
|
|
||||||
|
if (currentSelected.length) {
|
||||||
|
var currentSelectedWrap = currentSelected[0].parentNode;
|
||||||
|
var nextWrap = currentSelectedWrap[next ? 'nextSibling' : 'previousSibling'];
|
||||||
|
currentSelected.removeClass('composer_emoji_option_active');
|
||||||
|
if (nextWrap) {
|
||||||
|
$(nextWrap).find('a').addClass('composer_emoji_option_active');
|
||||||
|
return cancelEvent(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var childNodes = this.autoCompleteEl[0].childNodes;
|
||||||
|
var nextWrap = childNodes[next ? 0 : childNodes.length - 1];
|
||||||
|
$(nextWrap).find('a').addClass('composer_emoji_option_active');
|
||||||
|
|
||||||
|
return cancelEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.keyCode == 13) { // ENTER
|
||||||
|
var currentSelected = $(this.autoCompleteEl).find('.composer_emoji_option_active') ||
|
||||||
|
$(this.autoCompleteEl).childNodes[0].find('a');
|
||||||
|
var code = currentSelected.attr('data-code');
|
||||||
|
if (code) {
|
||||||
|
this.onEmojiSelected(code, true);
|
||||||
|
EmojiHelper.pushPopularEmoji(code);
|
||||||
|
}
|
||||||
|
return cancelEvent(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (e.keyCode == 13) {
|
||||||
|
var submit = false;
|
||||||
|
var sendOnEnter = true;
|
||||||
|
if (this.getSendOnEnter && !this.getSendOnEnter()) {
|
||||||
|
sendOnEnter = false;
|
||||||
|
}
|
||||||
|
if (sendOnEnter && !e.shiftKey) {
|
||||||
|
submit = true;
|
||||||
|
} else if (!sendOnEnter && (e.ctrlKey || e.metaKey)) {
|
||||||
|
submit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submit) {
|
||||||
|
this.onMessageSubmit(e);
|
||||||
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
return cancelEvent(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.checkAutocomplete = function () {
|
MessageComposer.prototype.backupSelection = function () {
|
||||||
var textarea = this.contentEditableEl ? this.contentEditableEl[0] : this.textareaEl;
|
delete this.selection;
|
||||||
var pos = getFieldSelection(textarea);
|
|
||||||
var value = getFieldValue(textarea).substr(0, pos);
|
|
||||||
|
|
||||||
console.log(pos, value);
|
if (!this.isActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (window.getSelection) {
|
||||||
|
var sel = window.getSelection();
|
||||||
|
if (sel.getRangeAt && sel.rangeCount) {
|
||||||
|
this.selection = sel.getRangeAt(0);
|
||||||
|
}
|
||||||
|
} else if (document.selection && document.selection.createRange) {
|
||||||
|
this.selection = document.selection.createRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.restoreSelection = function () {
|
||||||
|
if (!this.selection) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var result = false;
|
||||||
|
if (window.getSelection) {
|
||||||
|
var sel = window.getSelection();
|
||||||
|
sel.removeAllRanges();
|
||||||
|
sel.addRange(this.selection);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else if (document.selection && this.selection.select) {
|
||||||
|
this.selection.select();
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
delete this.selection;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MessageComposer.prototype.checkAutocomplete = function () {
|
||||||
|
var pos, value;
|
||||||
|
if (this.richTextareaEl) {
|
||||||
|
var textarea = this.richTextareaEl[0];
|
||||||
|
var valueCaret = getRichValueWithCaret(textarea);
|
||||||
|
var value = valueCaret[0];
|
||||||
|
var pos = valueCaret[1] >= 0 ? valueCaret[1] : value.length;
|
||||||
|
} else {
|
||||||
|
var textarea = this.textareaEl[0];
|
||||||
|
var pos = getFieldSelection(textarea);
|
||||||
|
var value = textarea.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = value.substr(0, pos);
|
||||||
|
|
||||||
var matches = value.match(/:([A-Za-z_0-z\+-]*)$/);
|
var matches = value.match(/:([A-Za-z_0-z\+-]*)$/);
|
||||||
if (matches) {
|
if (matches/* && !this.richTextareaEl*/) {
|
||||||
if (this.previousQuery == matches[0]) {
|
if (this.previousQuery == matches[0]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -509,31 +624,157 @@ MessageComposer.prototype.onFocusBlur = function (e) {
|
|||||||
} else {
|
} else {
|
||||||
setTimeout(this.checkAutocomplete.bind(this), 100);
|
setTimeout(this.checkAutocomplete.bind(this), 100);
|
||||||
}
|
}
|
||||||
|
if (this.richTextareaEl) {
|
||||||
|
document.execCommand('enableObjectResizing', !this.isActive, !this.isActive);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.onEmojiSelected = function (code) {
|
MessageComposer.prototype.onRichPaste = function (e) {
|
||||||
console.log('emoji selected', code);
|
var cData = (e.originalEvent || e).clipboardData,
|
||||||
|
items = cData && cData.items || [],
|
||||||
var emoji = EmojiHelper.emojis[code];
|
i;
|
||||||
|
for (i = 0; i < items.length; i++) {
|
||||||
var textarea = this.textareaEl[0];
|
if (items[i].kind == 'file') {
|
||||||
var fullValue = textarea.value;
|
e.preventDefault();
|
||||||
var pos = this.isActive ? getFieldSelection(textarea) : fullValue.length;
|
return true;
|
||||||
var suffix = fullValue.substr(pos);
|
}
|
||||||
var prefix = fullValue.substr(0, pos);
|
}
|
||||||
var matches = prefix.match(/:([A-Za-z_0-z\+-]*)$/);
|
|
||||||
|
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
|
||||||
if (matches && matches[0]) {
|
setZeroTimeout(this.onChange.bind(this), 0);
|
||||||
var newValue = prefix.substr(0, matches.index) + ':' + emoji[1] + ': ' + suffix;
|
if (text.length) {
|
||||||
var newPos = matches.index + emoji[1].length + 3;
|
document.execCommand('insertText', false, text);
|
||||||
} else {
|
return cancelEvent(e);
|
||||||
var newValue = prefix + ':' + emoji[1] + ': ' + suffix;
|
}
|
||||||
var newPos = prefix.length + emoji[1].length + 3;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.onRichPasteNode = function (e) {
|
||||||
|
var element = (e.originalEvent || e).target,
|
||||||
|
src = (element || {}).src || '',
|
||||||
|
remove = false;
|
||||||
|
|
||||||
|
if (src.substr(0, 5) == 'data:') {
|
||||||
|
remove = true;
|
||||||
|
var blob = dataUrlToBlob(src);
|
||||||
|
this.onFilePaste(blob);
|
||||||
|
setZeroTimeout(function () {
|
||||||
|
element.parentNode.removeChild(element);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (src && !src.match(/img\/blank\.gif/)) {
|
||||||
|
var replacementNode = document.createTextNode(' ' + src + ' ');
|
||||||
|
setTimeout(function () {
|
||||||
|
element.parentNode.replaceChild(replacementNode, element);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MessageComposer.prototype.onEmojiSelected = function (code, autocomplete) {
|
||||||
|
if (this.richTextareaEl) {
|
||||||
|
var textarea = this.richTextareaEl[0];
|
||||||
|
if (!this.isActive) {
|
||||||
|
if (!this.restoreSelection()) {
|
||||||
|
setRichFocus(textarea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (autocomplete) {
|
||||||
|
var valueCaret = getRichValueWithCaret(textarea);
|
||||||
|
var fullValue = valueCaret[0];
|
||||||
|
var pos = valueCaret[1] >= 0 ? valueCaret[1] : fullValue.length;
|
||||||
|
var suffix = fullValue.substr(pos);
|
||||||
|
var prefix = fullValue.substr(0, pos);
|
||||||
|
var matches = prefix.match(/:([A-Za-z0-9\-\+\*_]*)$/);
|
||||||
|
var emoji = EmojiHelper.emojis[code];
|
||||||
|
|
||||||
|
var newValuePrefix;
|
||||||
|
if (matches && matches[0]) {
|
||||||
|
newValuePrefix = prefix.substr(0, matches.index) + ':' + emoji[1] + ':';
|
||||||
|
} else {
|
||||||
|
newValuePrefix = prefix + ':' + emoji[1] + ':';
|
||||||
|
}
|
||||||
|
textarea.value = newValue;
|
||||||
|
|
||||||
|
this.selId = (this.selId || 0) + 1;
|
||||||
|
var html = this.getRichHtml(newValuePrefix) + ' <span id="composer_sel' + this.selId + '"></span>' + this.getRichHtml(suffix);
|
||||||
|
|
||||||
|
this.richTextareaEl.html(html);
|
||||||
|
setRichFocus(textarea, $('#composer_sel' + this.selId)[0]);
|
||||||
|
} else {
|
||||||
|
document.execCommand('insertHTML', false, this.getEmojiHtml(code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var textarea = this.textareaEl[0];
|
||||||
|
var fullValue = textarea.value;
|
||||||
|
var pos = this.isActive ? getFieldSelection(textarea) : fullValue.length;
|
||||||
|
var suffix = fullValue.substr(pos);
|
||||||
|
var prefix = fullValue.substr(0, pos);
|
||||||
|
var matches = autocomplete && prefix.match(/:([A-Za-z0-9\-\+\*_]*)$/);
|
||||||
|
var emoji = EmojiHelper.emojis[code];
|
||||||
|
|
||||||
|
if (matches && matches[0]) {
|
||||||
|
var newValue = prefix.substr(0, matches.index) + ':' + emoji[1] + ': ' + suffix;
|
||||||
|
var newPos = matches.index + emoji[1].length + 3;
|
||||||
|
} else {
|
||||||
|
var newValue = prefix + ':' + emoji[1] + ': ' + suffix;
|
||||||
|
var newPos = prefix.length + emoji[1].length + 3;
|
||||||
|
}
|
||||||
|
textarea.value = newValue;
|
||||||
|
setFieldSelection(textarea, newPos);
|
||||||
}
|
}
|
||||||
textarea.value = newValue;
|
|
||||||
setFieldSelection(textarea, newPos);
|
|
||||||
|
|
||||||
this.hideSuggestions();
|
this.hideSuggestions();
|
||||||
|
this.onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.onChange = function (e) {
|
||||||
|
if (this.richTextareaEl) {
|
||||||
|
delete this.keyupStarted;
|
||||||
|
this.textareaEl.val(getRichValue(this.richTextareaEl[0])).trigger('change');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.getEmojiHtml = function (code, emoji) {
|
||||||
|
emoji = emoji || EmojiHelper.emojis[code];
|
||||||
|
var iconSize = 20;
|
||||||
|
var spritesheet = EmojiHelper.spritesheetPositions[code];
|
||||||
|
var categoryIndex = spritesheet[0];
|
||||||
|
var pos = spritesheet[1];
|
||||||
|
var x = iconSize * spritesheet[3];
|
||||||
|
var y = iconSize * spritesheet[2];
|
||||||
|
|
||||||
|
return '<img src="img/blank.gif" alt=":' + encodeEntities(emoji[1]) + ':" data-code="' + encodeEntities(code) + '" class="emoji emoji-w20 emoji-spritesheet-' + categoryIndex + '" style="background-position: -' + x + 'px -' + y + 'px;" onresizestart="return false" />';
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.setValue = function (text) {
|
||||||
|
if (this.richTextareaEl) {
|
||||||
|
this.richTextareaEl.html(this.getRichHtml(text));
|
||||||
|
this.lastLength = text.length;
|
||||||
|
} else {
|
||||||
|
this.textareaEl.val(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.getRichHtml = function (text) {
|
||||||
|
return $('<div>').text(text).html().replace(/:([A-Za-z0-9\-\+\*_]+?):/gi, (function (all, shortcut) {
|
||||||
|
var code = EmojiHelper.shortcuts[shortcut];
|
||||||
|
if (code !== undefined) {
|
||||||
|
return this.getEmojiHtml(code);
|
||||||
|
}
|
||||||
|
return all;
|
||||||
|
}).bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MessageComposer.prototype.focus = function () {
|
||||||
|
if (this.richTextareaEl) {
|
||||||
|
setRichFocus(this.richTextareaEl[0]);
|
||||||
|
} else {
|
||||||
|
setFieldSelection(this.textareaEl[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -567,7 +808,7 @@ MessageComposer.prototype.showEmojiSuggestions = function (codes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.updatePosition = function () {
|
MessageComposer.prototype.updatePosition = function () {
|
||||||
var offset = this.textareaEl.offset();
|
var offset = (this.richTextareaEl || this.textareaEl).offset();
|
||||||
var height = this.autoCompleteEl.outerHeight();
|
var height = this.autoCompleteEl.outerHeight();
|
||||||
this.autoCompleteEl.css({top: offset.top - height, left: offset.left});
|
this.autoCompleteEl.css({top: offset.top - height, left: offset.left});
|
||||||
}
|
}
|
||||||
@ -576,3 +817,9 @@ MessageComposer.prototype.hideSuggestions = function () {
|
|||||||
this.autoCompleteEl.hide();
|
this.autoCompleteEl.hide();
|
||||||
delete this.autocompleteShown;
|
delete this.autocompleteShown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.resetTyping = function () {
|
||||||
|
this.lastTyping = 0;
|
||||||
|
this.lastLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -171,13 +171,13 @@
|
|||||||
</a>
|
</a>
|
||||||
<a class="pull-left im_panel_own_photo" my-peer-photolink="ownID" img-class="im_panel_own_photo" watch="true" ng-click="openSettings()" no-open="true"></a>
|
<a class="pull-left im_panel_own_photo" my-peer-photolink="ownID" img-class="im_panel_own_photo" watch="true" ng-click="openSettings()" no-open="true"></a>
|
||||||
|
|
||||||
<form my-send-form draft-message="draftMessage" class="im_send_form" ng-class="{im_send_form_empty: !draftMessage.text.length}" message-composer>
|
<form my-send-form draft-message="draftMessage" class="im_send_form" ng-class="{im_send_form_empty: !draftMessage.text.length}">
|
||||||
|
|
||||||
<div class="im_send_field_wrap">
|
<div class="im_send_field_wrap">
|
||||||
<a class="composer_emoji_insert_btn"><i class="icon icon-emoji"></i></a>
|
<a class="composer_emoji_insert_btn"><i class="icon icon-emoji"></i></a>
|
||||||
|
|
||||||
<div class="im_send_dropbox_wrap" my-i18n="im_photos_drop_text"></div>
|
<div class="im_send_dropbox_wrap" my-i18n="im_photos_drop_text"></div>
|
||||||
<textarea ng-model="draftMessage.text" placeholder="{{'im_message_field_placeholder' | i18n}}" class="form-control im_message_field no_outline" message-composer-field></textarea>
|
<textarea ng-model="draftMessage.text" placeholder="{{'im_message_field_placeholder' | i18n}}" class="form-control im_message_field no_outline"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="clearfix">
|
<div class="clearfix">
|
||||||
@ -193,7 +193,7 @@
|
|||||||
<i class="icon icon-camera"></i>
|
<i class="icon icon-camera"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="composer_emoji_panel" message-composer-emoji-recents></div>
|
<div class="composer_emoji_panel"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -138,9 +138,7 @@
|
|||||||
<i class="icon icon-paperclip"></i>
|
<i class="icon icon-paperclip"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_emoji_btn pull-right" title="{{'im_emoji_btn_title' | i18n}}">
|
<a class="composer_emoji_insert_btn pull-right"><i class="icon icon-emoji"></i></a>
|
||||||
<i class="icon icon-emoji"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-success im_submit"></button>
|
<button type="submit" class="btn btn-success im_submit"></button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
CACHE MANIFEST
|
CACHE MANIFEST
|
||||||
|
|
||||||
# 57
|
# 59
|
||||||
|
|
||||||
NETWORK:
|
NETWORK:
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user