From fa47720d22cddb772baf9a21aa5ecb882a7eb9a4 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 10 Aug 2017 23:05:04 +0200 Subject: [PATCH] Working on mobile Broken desktop --- app/js/controllers.js | 5 +- app/js/directives.js | 81 ++++++++++++------ app/js/locales/en-us.json | 3 +- app/less/mobile.less | 125 +++++++++++++++++----------- app/partials/desktop/im.html | 50 +---------- app/partials/desktop/send_form.html | 50 +++++++++++ app/partials/mobile/im.html | 57 +------------ app/partials/mobile/send_form.html | 55 ++++++++++++ app/vendor/recorderjs/recorder.js | 3 + 9 files changed, 245 insertions(+), 184 deletions(-) create mode 100644 app/partials/desktop/send_form.html create mode 100644 app/partials/mobile/send_form.html diff --git a/app/js/controllers.js b/app/js/controllers.js index ff175065..342d4ca6 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -2321,6 +2321,8 @@ angular.module('myApp.controllers', ['myApp.i18n']) send: submitMessage, replyClear: replyClear, fwdsClear: fwdsClear, + toggleSlash: toggleSlash, + replyKeyboardToggle: replyKeyboardToggle, type: 'new' } $scope.mentions = {} @@ -2347,9 +2349,6 @@ angular.module('myApp.controllers', ['myApp.i18n']) $scope.$on('last_message_edit', setEditLastMessage) - $scope.replyKeyboardToggle = replyKeyboardToggle - $scope.toggleSlash = toggleSlash - $rootScope.$watch('idle.isIDLE', function (newVal) { if ($rootScope.idle.initial) { return diff --git a/app/js/directives.js b/app/js/directives.js index c5c4a11e..84f6bd9b 100755 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -1548,8 +1548,11 @@ angular.module('myApp.directives', ['myApp.filters']) }) .directive('mySendForm', function (_, $q, $timeout, $interval, $window, $compile, $modalStack, $http, $interpolate, Storage, AppStickersManager, AppDocsManager, ErrorService, AppInlineBotsManager, FileManager, shouldFocusOnInteraction) { + return { link: link, + templateUrl: templateUrl('send_form'), + replace: true, scope: { draftMessage: '=', mentions: '=', @@ -1574,7 +1577,6 @@ angular.module('myApp.directives', ['myApp.filters']) var cachedStickerImages = {} var voiceRecorder = null - var voiceRecordSuccess = false var voiceRecordSupported = Recorder.isRecordingSupported() var voiceRecordDurationInterval = null var voiceRecorderPromise = null @@ -1698,7 +1700,7 @@ angular.module('myApp.directives', ['myApp.filters']) $(voiceRecordBtn).on('contextmenu', cancelEvent) - $(voiceRecordBtn).on('touchstart', function(e) { + $(voiceRecordBtn).on('touchstart', function(event) { if ($scope.voiceRecorder.processing) { return } @@ -1716,8 +1718,6 @@ angular.module('myApp.directives', ['myApp.filters']) voiceRecorder.addEventListener('start', function(e) { var startTime = tsNow(true) - voiceRecordSuccess = false - voiceRecordDurationInterval = $interval(function() { $scope.voiceRecorder.duration = tsNow(true) - startTime }, 1000) @@ -1735,40 +1735,67 @@ angular.module('myApp.directives', ['myApp.filters']) voiceRecorder.initStream() - $($window).one('touchend', function() { - var deferred = $q.defer() - voiceRecorder.addEventListener('dataAvailable', function(e) { - var blob = blobConstruct([e.detail], 'audio/ogg') - deferred.resolve(blob) - }) - voiceRecorderPromise = deferred.promise - voiceRecorder.stop() + var curHover = false + var curBoundaries = {} - $interval.cancel(voiceRecordDurationInterval) + var updateVoiceHoverBoundaries = function () { + var offset = element.offset() + curBoundaries = { + top: offset.top, + left: offset.left, + width: element.outerWidth(), + height: element.outerHeight(), + } + } - $scope.$apply(function() { - $scope.voiceRecorder.recording = false - }) - }) - }) + var updateVoiceHoveredClass = function (event, returnHover) { + var originalEvent = event.originalEvent || event + var touch = originalEvent.changedTouches && originalEvent.changedTouches[0] + var isHover = touch && + touch.pageX >= curBoundaries.left && + touch.pageX <= curBoundaries.left + curBoundaries.width && + touch.pageY >= curBoundaries.top && + touch.pageY <= curBoundaries.top + curBoundaries.height - $(voiceRecordBtn).on('touchend', function(e) { - voiceRecordSuccess = true - $timeout(function () { - if (voiceRecorderPromise) { - $scope.voiceRecorder.processing = true + if (curHover != isHover) { + element.toggleClass('im_send_form_hover', isHover) + curHover = isHover + } + return returnHover && isHover + } - voiceRecorderPromise.then(function(blob) { + updateVoiceHoverBoundaries() + updateVoiceHoveredClass(event) + + $($window).on('touchmove', updateVoiceHoveredClass) + + $($window).one('touchend', function(event) { + $($window).off('touchmove', updateVoiceHoveredClass) + + var isHover = updateVoiceHoveredClass(event, true) + + if ($scope.voiceRecorder.duration > 0 && isHover) { + $scope.voiceRecorder.processing = true + voiceRecorder.addEventListener('dataAvailable', function(e) { + var blob = blobConstruct([e.detail], 'audio/ogg') console.warn(dT(), 'got audio', blob) + $scope.draftMessage.files = [blob] $scope.draftMessage.isMedia = true $scope.voiceRecorder.processing = false - - voiceRecorderPromise = null }) } - }, 100) + voiceRecorder.stop() + console.warn(dT(), 'stop audio') + + $interval.cancel(voiceRecordDurationInterval) + + $scope.$apply(function() { + $scope.voiceRecorder.recording = false + $scope.voiceRecorder.duration = 0 + }) + }) }) var sendOnEnter = true diff --git a/app/js/locales/en-us.json b/app/js/locales/en-us.json index 847b82ff..db8760dc 100644 --- a/app/js/locales/en-us.json +++ b/app/js/locales/en-us.json @@ -530,7 +530,8 @@ "im_submit_message": "Send", "im_submit_edit_message": "Save", "im_edit_message_title": "Edit message", - "im_voice_recorder_label": "Swipe left to abort", + "im_voice_recording_label": "Release outside this field 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.", "login_incorrect_number": "Incorrect phone number", diff --git a/app/less/mobile.less b/app/less/mobile.less index 4586fdd8..7f8494ee 100644 --- a/app/less/mobile.less +++ b/app/less/mobile.less @@ -577,6 +577,13 @@ html { .audio_player_volume_slider .tg_slider_wrap { display: none; } +.audio_player_seek_slider { + width: 100%; +} + +.audio_player_seek_slider .tg_slider_track { + background: rgba(200, 200, 200, 0.6); +} .im_message_body_media { .im_message_document, @@ -1426,7 +1433,7 @@ a.im_message_fwd_author { .icon-paperclip, .icon-mic { display: inline-block; - width: 19px; + width: 18px; height: 23px; vertical-align: text-top; opacity: 0.8; @@ -1438,19 +1445,22 @@ a.im_message_fwd_author { .icon-mic { background-position: -12px -285px; } +.im_voice_recording .icon-mic { + background-position: -12px -705px; +} .im_attach { cursor: pointer; - display: none; + display: block; overflow: hidden; position: absolute; - right: 34px; + left: 0; top: 0; margin: 0; width: 50px; height: 32px; padding: 3px 13px 4px 16px; - right: 0; + right: auto; &:active { .icon-paperclip { @@ -1461,47 +1471,51 @@ a.im_message_fwd_author { } .im_record { + display: none; right: 0; + top: -9px; + width: 50px; + height: 50px; + position: absolute; user-select: none; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; + padding: 13px 16px 13px 16px; - .im_record_supported .im_send_form_empty & { + border-radius: 50px; + overflow: hidden; + background: #fff; + transition: background-color linear 0.2s; + + .im_send_form_empty .im_record_supported & { display: block; } } +.im_send_form_hover .im_voice_recording .im_record { + background: #bfd9ed; +} -.im_send_form_empty { - .im_submit { - display: none; - } - - .im_attach { - display: block; - } +.im_send_form_empty .im_submit { + opacity: 0.4; +} +.im_send_form_empty .im_record_supported .im_submit { + display: none; } -.im_voice_recording, .im_processing_recording { - background-color: rgb(23, 23, 23); - color: white; - .im_voice_recorder_wrap { - display: block; - } +.im_voice_recording, +.im_processing_recording { + color: #AAA; - .im_send_field_wrap { - display: none; + .im_voice_recorder_wrap { + display: block; } - + .im_send_field_wrap, + .im_submit, .im_attach { display: none; } - - .composer_emoji_insert_btn { - display: none; - } - } .im_processing_recording { @@ -1527,17 +1541,12 @@ a.im_message_fwd_author { } .composer_emoji_insert_btn { - position: absolute; - left: 0; - top: 0; - margin: 0; - padding: 3px 13px 4px 13px; - width: 48px; - height: 32px; + top: 3px; + right: 5px; - &.on, + &.composer_emoji_insert_btn_on, &:active, - .is_1x &.on, + .is_1x &.composer_emoji_insert_btn_on, .is_1x &:active { .icon-emoji { background-position: -10px -803px; @@ -1555,34 +1564,46 @@ a.im_message_fwd_author { } .im_voice_recorder_wrap { - margin-left: 0px; - padding-left: 10px; - height: 38px; + height: 32px; display: none; - line-height: 38px; - color: white; + 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: #F00; + background-color: #ff1010; height: 10px; width: 10px; border-radius: 50%; margin-right: 5px; - vertical-align: middle; + 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: 17px; + font-size: 12px; text-align: center; - margin-right: 50px; + vertical-align: middle; + padding-right: 48px; + color: #3a6d99; + + transition: color linear 0.2s; i, span { vertical-align: middle; @@ -1591,6 +1612,10 @@ a.im_message_fwd_author { i { margin-right: 5px; } + + .im_send_form_hover & { + color: #CCC; + } } .composer_rich_textarea { @@ -1620,8 +1645,8 @@ a.im_message_fwd_author { } .composer_emoji_tooltip { - margin-left: 6px; - margin-top: -176px; + margin-left: -246px; + margin-top: -181px; z-index: 10000; } .composer_emoji_tooltip_tab { @@ -1940,6 +1965,8 @@ a.media_modal_date:hover { } .composer_rich_textarea, .composer_textarea { + padding-right: 28px; + .im_send_field_wrap_2ndbtn & { padding-right: 35px; } @@ -1962,11 +1989,11 @@ a.media_modal_date:hover { position: relative; } .composer_command_btn { - right: 10px; + right: 35px; top: 6px; } .composer_keyboard_btn { - right: 10px; + right: 35px; top: 6px; } .im_send_keyboard_wrap { diff --git a/app/partials/desktop/im.html b/app/partials/desktop/im.html index 6a87c3c7..1c403323 100644 --- a/app/partials/desktop/im.html +++ b/app/partials/desktop/im.html @@ -211,56 +211,8 @@ -
+
-
- -
- - -
- -
- -
-
- -
- -
-
-
- - - -
- -
- -
- - -
- - -
- -
- - -
- -
-
- -
-
-
- -
diff --git a/app/partials/desktop/send_form.html b/app/partials/desktop/send_form.html new file mode 100644 index 00000000..0f0b244d --- /dev/null +++ b/app/partials/desktop/send_form.html @@ -0,0 +1,50 @@ +
+ +
+ +
+ + +
+ +
+ +
+
+ +
+ +
+
+
+ + + +
+ +
+ +
+ + +
+ + +
+ +
+ + +
+ +
+
+ +
+
+
+ +
\ No newline at end of file diff --git a/app/partials/mobile/im.html b/app/partials/mobile/im.html index e84c656e..917ead92 100644 --- a/app/partials/mobile/im.html +++ b/app/partials/mobile/im.html @@ -131,65 +131,12 @@ -
+
-
- -
- - -
- -
- -
-
- -
-
- - - -
-
-
- -
- -
- -
-
-
-
- - -
-
- -
- - -
- -
- -
- - - - -
- - -
-
-
- -
+
diff --git a/app/partials/mobile/send_form.html b/app/partials/mobile/send_form.html new file mode 100644 index 00000000..09ce8f27 --- /dev/null +++ b/app/partials/mobile/send_form.html @@ -0,0 +1,55 @@ +
+ +
+ + +
+ +
+ +
+
+ +
+ +
+
+
+
+ + + +
+
+ +
+ + + + +
+
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + +
+ + +
+
+
+ +
\ No newline at end of file diff --git a/app/vendor/recorderjs/recorder.js b/app/vendor/recorderjs/recorder.js index 787ef9ca..188540c4 100755 --- a/app/vendor/recorderjs/recorder.js +++ b/app/vendor/recorderjs/recorder.js @@ -185,6 +185,9 @@ var root = (typeof self === 'object' && self.self === self && self) || (typeof g this.clearStream(); } + this.audioContext.close(); + this.audioContext = null; + this.encoder.postMessage({ command: "done" }); } };