diff --git a/app/img/icons/IconsetW.png b/app/img/icons/IconsetW.png index dfbe1362..9e8d7ede 100644 Binary files a/app/img/icons/IconsetW.png and b/app/img/icons/IconsetW.png differ diff --git a/app/img/icons/IconsetW_2x.png b/app/img/icons/IconsetW_2x.png index 19e6472b..d8519014 100644 Binary files a/app/img/icons/IconsetW_2x.png and b/app/img/icons/IconsetW_2x.png differ diff --git a/app/js/directives.js b/app/js/directives.js index 84f6bd9b..9759fe91 100755 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -1494,6 +1494,9 @@ angular.module('myApp.directives', ['myApp.filters']) return } if ($(sendFormWrap).is(':visible')) { + if (!sendForm || !sendForm.offsetHeight) { + sendForm = $('.im_send_form', element)[0] + } $(sendFormWrap).css({ height: $(sendForm).height() }) @@ -1552,7 +1555,6 @@ angular.module('myApp.directives', ['myApp.filters']) return { link: link, templateUrl: templateUrl('send_form'), - replace: true, scope: { draftMessage: '=', mentions: '=', @@ -1561,16 +1563,16 @@ angular.module('myApp.directives', ['myApp.filters']) } function link ($scope, element, attrs) { + var messageFieldWrap = $('.im_send_field_wrap', element)[0] var messageField = $('textarea', 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 sendFieldPanel = $('.im_send_field_panel', element)[0] var dragStarted var dragTimeout var submitBtn = $('.im_submit', element)[0] + var voiceRecorderWrap = $('.im_voice_recorder_wrap', element)[0] var voiceRecordBtn = $('.im_record', element)[0] var stickerImageCompiled = $compile('') @@ -1581,7 +1583,7 @@ angular.module('myApp.directives', ['myApp.filters']) var voiceRecordDurationInterval = null var voiceRecorderPromise = null if (voiceRecordSupported) { - $(sendFieldPanel).addClass('im_record_supported') + element.addClass('im_record_supported') } $scope.voiceRecorder = {duration: 0, recording: false, processing: false} @@ -1700,7 +1702,13 @@ angular.module('myApp.directives', ['myApp.filters']) $(voiceRecordBtn).on('contextmenu', cancelEvent) - $(voiceRecordBtn).on('touchstart', function(event) { + var voiceRecordTouch = Config.Navigator.touch ? true : false + var voiceRecordEvents = { + start: voiceRecordTouch ? 'touchstart' : 'mousedown', + move: voiceRecordTouch ? 'touchmove' : 'mousemove', + stop: voiceRecordTouch ? 'touchend' : 'mouseup' + } + $(voiceRecordBtn).on(voiceRecordEvents.start, function(event) { if ($scope.voiceRecorder.processing) { return } @@ -1739,18 +1747,23 @@ angular.module('myApp.directives', ['myApp.filters']) var curBoundaries = {} var updateVoiceHoverBoundaries = function () { - var offset = element.offset() + var boundElement = $('.im_bottom_panel_wrap') + // console.warn(dT(), 'bound', boundElement[0]) + var offset = boundElement.offset() curBoundaries = { top: offset.top, left: offset.left, - width: element.outerWidth(), - height: element.outerHeight(), + width: boundElement.outerWidth(), + height: boundElement.outerHeight(), } } var updateVoiceHoveredClass = function (event, returnHover) { var originalEvent = event.originalEvent || event - var touch = originalEvent.changedTouches && originalEvent.changedTouches[0] + var touch = voiceRecordTouch + ? originalEvent.changedTouches && originalEvent.changedTouches[0] + : originalEvent + // console.log('event', voiceRecordTouch, originalEvent) var isHover = touch && touch.pageX >= curBoundaries.left && touch.pageX <= curBoundaries.left + curBoundaries.width && @@ -1758,6 +1771,7 @@ angular.module('myApp.directives', ['myApp.filters']) touch.pageY <= curBoundaries.top + curBoundaries.height if (curHover != isHover) { + console.warn(dT(), 'change hover', isHover) element.toggleClass('im_send_form_hover', isHover) curHover = isHover } @@ -1767,10 +1781,18 @@ angular.module('myApp.directives', ['myApp.filters']) updateVoiceHoverBoundaries() updateVoiceHoveredClass(event) - $($window).on('touchmove', updateVoiceHoveredClass) + if (!Config.Mobile) { + $(voiceRecorderWrap).css({ + height: messageFieldWrap.offsetHeight, + width: messageFieldWrap.offsetWidth + }) + } - $($window).one('touchend', function(event) { - $($window).off('touchmove', updateVoiceHoveredClass) + $($window).on(voiceRecordEvents.move, updateVoiceHoveredClass) + + $($window).one(voiceRecordEvents.stop, function(event) { + console.warn(111) + $($window).off(voiceRecordEvents.move, updateVoiceHoveredClass) var isHover = updateVoiceHoveredClass(event, true) @@ -1982,14 +2004,14 @@ angular.module('myApp.directives', ['myApp.filters']) if (e.type == 'dragenter' || e.type == 'dragover') { if (dragStateChanged) { - if (!Config.Mobile) { - $(emojiButton).hide() - } - $(dropbox) - .css({height: messageFieldWrap.offsetHeight + 2, width: messageFieldWrap.offsetWidth}) - .show() + $(dropbox).css({ + height: messageFieldWrap.offsetHeight, + width: messageFieldWrap.offsetWidth + }) + element.addClass('im_send_form_dragging') } } else { + return cancelEvent(e) if (e.type == 'drop') { $scope.$apply(function () { $scope.draftMessage.files = Array.prototype.slice.call(e.originalEvent.dataTransfer.files) @@ -1997,10 +2019,7 @@ angular.module('myApp.directives', ['myApp.filters']) }) } dragTimeout = setTimeout(function () { - $(dropbox).hide() - if (!Config.Mobile) { - $(emojiButton).show() - } + element.removeClass('im_send_form_dragging') dragStarted = false dragTimeout = false }, 300) diff --git a/app/js/locales/en-us.json b/app/js/locales/en-us.json index db8760dc..516c076b 100644 --- a/app/js/locales/en-us.json +++ b/app/js/locales/en-us.json @@ -530,7 +530,7 @@ "im_submit_message": "Send", "im_submit_edit_message": "Save", "im_edit_message_title": "Edit message", - "im_voice_recording_label": "Release outside this field to cancel", + "im_voice_recording_label": "Release outside this form to cancel", "im_voice_processing_label": "Processing{dots}", "login_sign_in": "Sign in", "login_enter_number_description": "Please choose your country and enter your full phone number.", diff --git a/app/js/message_composer.js b/app/js/message_composer.js index fb0b805f..298a8a7e 100644 --- a/app/js/message_composer.js +++ b/app/js/message_composer.js @@ -1610,7 +1610,8 @@ MessageComposer.prototype.resetTyping = function () { } MessageComposer.prototype.setPlaceholder = function (newPlaceholder) { - (this.richTextareaEl || this.textareaEl).attr('placeholder', newPlaceholder) + console.warn(dT(), 'set placeholder', this.richTextareaEl) + ;(this.richTextareaEl || this.textareaEl).attr('placeholder', newPlaceholder) } function Scroller (content, options) { diff --git a/app/less/app.less b/app/less/app.less index 04187eaf..dfe7e53c 100644 --- a/app/less/app.less +++ b/app/less/app.less @@ -2551,6 +2551,21 @@ a.im_message_fwd_photo { color: #999; position: absolute; } +.im_send_form_dragging { + .im_send_dropbox_wrap { + display: block; + } + .composer_rich_textarea, + .im_message_field, + .composer_emoji_insert_btn, + .composer_progress_icon_wrap, + .composer_command_btn, + .composer_keyboard_btn, + .im_inline_placeholder_wrap { + visibility: hidden; + } +} + .im_send_field_wrap { position: relative; } @@ -3505,6 +3520,61 @@ li.inline_result_sticker.composer_autocomplete_option_active a { } +.im_voice_recorder_wrap { + display: none; + z-index: 100; +} + +.im_recorder_indicator, .im_recorder_time { + float: left; + vertical-align: middle; + color: #333; +} + +.im_recorder_indicator i { + background-color: #ff1010; + height: 10px; + width: 10px; + border-radius: 50%; + margin-right: 5px; + vertical-align: baseline; + display: inline-block; + animation: blinker 0.5s cubic-bezier(.5, 0, 1, 1) infinite alternate; +} + +@keyframes blinker { + from { opacity: 1; } + to { opacity: 0; } +} + +.im_recorder_label { + overflow: auto; + font-size: 12px; + text-align: center; + vertical-align: middle; + color: #3a6d99; + + transition: color linear 0.2s; + + i { + margin-right: 5px; + } + + .im_send_form_hover & { + color: #CCC; + } +} + +.im_voice_recording, +.im_processing_recording { + color: #AAA; + + .im_voice_recorder_wrap { + display: block; + } +} + + .error_modal_window { .modal-dialog { max-width: 350px; diff --git a/app/less/desktop.less b/app/less/desktop.less index f170b203..f4b8f1cd 100644 --- a/app/less/desktop.less +++ b/app/less/desktop.less @@ -1290,6 +1290,75 @@ a.im_panel_peer_photo .peer_initials { } } +.im_record { + display: none; + width: 50px; + height: 50px; + margin: -8px 0 0 -18px; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + padding: 13px 16px 13px 16px; + + border-radius: 50px; + overflow: hidden; + background: #fff; + transition: background-color linear 0.2s; + + .im_record_supported & { + display: block; + } +} +.im_send_form_hover .im_voice_recording .im_record { + background: #bfd9ed; +} + +.icon-mic { + display: inline-block; + width: 18px; + height: 22px; + vertical-align: text-top; + opacity: 0.8; + + .image-2x('../img/icons/IconsetW.png', 42px, 1171px); + background-position: -12px -285px; + background-color: transparent; + + .im_record:hover & { + opacity: 1; + } + .im_record:active &, + .im_voice_recording & { + background-position: -12px -705px; + } + +} + +.im_voice_recorder_wrap { + padding: 17px 10px 0; + display: none; + position: absolute; +} + +.im_voice_recording, +.im_processing_recording { + .im_voice_recorder_wrap { + display: block; + } + + .composer_rich_textarea, + .im_message_field, + .composer_emoji_insert_btn, + .composer_progress_icon_wrap, + .composer_command_btn, + .composer_keyboard_btn, + .im_inline_placeholder_wrap { + visibility: hidden; + } +} + + @media (max-height: 600px) { a { &.im_panel_peer_photo, @@ -1340,6 +1409,10 @@ a.im_panel_peer_photo .peer_initials { top: 0; left: 100%; margin: 0 0 0 15px; + + .im_record_supported .im_send_form_empty & { + display: none; + } } .im_media_attach { position: absolute; @@ -1412,6 +1485,22 @@ a.im_panel_peer_photo .peer_initials { padding-top: 5px; padding-bottom: 5px; } + + .im_record { + display: none; + position: absolute; + top: -4px; + right: -56px; + + .im_record_supported .im_send_form_empty & { + display: block; + } + } + + .im_voice_recorder_wrap { + padding-top: 4px; + } + } .im_edit_panel { diff --git a/app/less/mobile.less b/app/less/mobile.less index 7f8494ee..8393aa4f 100644 --- a/app/less/mobile.less +++ b/app/less/mobile.less @@ -1473,7 +1473,7 @@ a.im_message_fwd_author { .im_record { display: none; right: 0; - top: -9px; + top: -8px; width: 50px; height: 50px; position: absolute; @@ -1488,7 +1488,7 @@ a.im_message_fwd_author { background: #fff; transition: background-color linear 0.2s; - .im_send_form_empty .im_record_supported & { + .im_record_supported .im_send_form_empty & { display: block; } } @@ -1499,13 +1499,24 @@ a.im_message_fwd_author { .im_send_form_empty .im_submit { opacity: 0.4; } -.im_send_form_empty .im_record_supported .im_submit { +.im_record_supported .im_send_form_empty .im_submit { display: none; } +.im_voice_recorder_wrap { + height: 32px; + line-height: 32px; + right: 50px; + left: 0; + padding: 0 0 0 20px; +} +.im_recorder_label { + padding-right: 48px; +} + .im_voice_recording, -.im_processing_recordingĀ { +.im_processing_recording { color: #AAA; .im_voice_recorder_wrap { @@ -1515,11 +1526,12 @@ a.im_message_fwd_author { .im_submit, .im_attach { display: none; + // visibility: hidden; } } .im_processing_recording { - .im_recorder_indicator iĀ { + .im_recorder_indicator i { background-color: green; } @@ -1563,61 +1575,6 @@ a.im_message_fwd_author { } } -.im_voice_recorder_wrap { - height: 32px; - display: none; - line-height: 32px; - right: 50px; - left: 0; - z-index: 100; - padding: 0 0 0 20px; -} - -.im_recorder_indicator, .im_recorder_time { - float: left; - vertical-align: middle; - color: #333; -} - -.im_recorder_indicator i { - background-color: #ff1010; - height: 10px; - width: 10px; - border-radius: 50%; - margin-right: 5px; - vertical-align: baseline; - display: inline-block; - animation: blinker 0.5s cubic-bezier(.5, 0, 1, 1) infinite alternate; -} - -@keyframes blinker { - from { opacity: 1; } - to { opacity: 0; } -} - -.im_recorder_label { - overflow: auto; - font-size: 12px; - text-align: center; - vertical-align: middle; - padding-right: 48px; - color: #3a6d99; - - transition: color linear 0.2s; - - i, span { - vertical-align: middle; - } - - i { - margin-right: 5px; - } - - .im_send_form_hover & { - color: #CCC; - } -} - .composer_rich_textarea { min-height: 18px; max-height: 136px; diff --git a/app/partials/desktop/send_form.html b/app/partials/desktop/send_form.html index 0f0b244d..208e8bfa 100644 --- a/app/partials/desktop/send_form.html +++ b/app/partials/desktop/send_form.html @@ -1,4 +1,4 @@ -
+
@@ -21,6 +21,16 @@
+
+
+
+
+ + + +
+
+ @@ -40,6 +50,10 @@ + + + +
diff --git a/app/partials/mobile/send_form.html b/app/partials/mobile/send_form.html index 09ce8f27..1bbb6891 100644 --- a/app/partials/mobile/send_form.html +++ b/app/partials/mobile/send_form.html @@ -13,13 +13,13 @@
-
-
-
- - - -
+
+
+
+ + + +