diff --git a/app/js/controllers.js b/app/js/controllers.js index ff175065..8431400b 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -518,6 +518,8 @@ angular.module('myApp.controllers', ['myApp.i18n']) skipped: false } + $scope.voiceRecorder = { time : '', recording : null, processing : false }; + $scope.openSettings = function () { $modal.open({ templateUrl: templateUrl('settings_modal'), diff --git a/app/js/directives.js b/app/js/directives.js index 87b5718c..69369de6 100755 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -1567,10 +1567,15 @@ angular.module('myApp.directives', ['myApp.filters']) var dragStarted var dragTimeout var submitBtn = $('.im_submit', element)[0] + var voiceRecord = $('.im_record', element); var stickerImageCompiled = $compile('') var cachedStickerImages = {} + var audioRecorder = null; + var audioPromise = null; + var audioStream = null; + var emojiTooltip = new EmojiTooltip(emojiButton, { getStickers: function (callback) { AppStickersManager.getStickers().then(callback) @@ -1683,7 +1688,82 @@ angular.module('myApp.directives', ['myApp.filters']) }) }) - var sendOnEnter = true + navigator.getUserMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); + + voiceRecord.on('touchstart', function(e) { + if ($scope.$parent.$parent.voiceRecorder.processing) { return; } + + navigator.getUserMedia({audio : true}, function(stream){ + var start = Date.now(); + var touch = null; + + audioPromise = null; + audioStream = stream; + audioRecorder = new MediaRecorder(stream); + + var interval = setInterval(function(){ + var time = (new Date()); + + time.setTime(Date.now() - start); + + $scope.$apply(function(){ + $scope.$parent.$parent.voiceRecorder.time = (time.getMinutes() < 10 ? '0' : '') + time.getMinutes() + ':' + (time.getSeconds() < 10 ? '0' : '') + time.getSeconds(); + }); + }, 1000); + + $scope.$apply(function(){ + $scope.$parent.$parent.voiceRecorder.time = '00:00'; + $scope.$parent.$parent.voiceRecorder.recording = interval; + }); + + audioRecorder.start(); + + console.log('recording now!'); + + }, function(e){ + console.error(e); + }); + }); + + voiceRecord.on('click', function(){ + if (audioPromise) { + $scope.$parent.$parent.voiceRecorder.processing = true; + + audioPromise.then(function(e) { + var blob = e.data; + + console.log(blob); + $scope.draftMessage.files = [blob]; + $scope.draftMessage.isMedia = true; + + $scope.$parent.$parent.voiceRecorder.processing = false; + + audioPromise = null; + }); + } + }); + + $($window).on('touchend', function(){ + if (audioStream && audioRecorder) { + audioPromise = new Promise(function(resolve) { + audioRecorder.ondataavailable = resolve; + }); + + audioRecorder.stop(); + audioStream.stop(); + + audioRecorder = null; + audioStream = null; + + clearInterval($scope.$parent.$parent.voiceRecorder.recording); + + $scope.$apply(function(){ + $scope.$parent.$parent.voiceRecorder.recording = null; + }); + } + }); + + var sendOnEnter = true; function updateSendSettings () { Storage.get('send_ctrlenter').then(function (sendOnCtrl) { sendOnEnter = !sendOnCtrl @@ -3900,4 +3980,4 @@ angular.module('myApp.directives', ['myApp.filters']) return { link: link } - }) + }) \ No newline at end of file diff --git a/app/js/locales/en-us.json b/app/js/locales/en-us.json index 900ad180..bbb2ea28 100644 --- a/app/js/locales/en-us.json +++ b/app/js/locales/en-us.json @@ -528,7 +528,7 @@ "im_submit_message": "Send", "im_submit_edit_message": "Save", "im_edit_message_title": "Edit message", - + "im_voice_recorder_label": "Swipe left to abort", "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 ad6f6d23..eace37c3 100644 --- a/app/less/mobile.less +++ b/app/less/mobile.less @@ -1416,7 +1416,7 @@ a.im_message_fwd_author { } } -.icon-paperclip { +.icon-paperclip, .icon-mic { display: inline-block; width: 19px; height: 23px; @@ -1427,12 +1427,16 @@ a.im_message_fwd_author { background-position: -12px -68px; } -.im_attach { +.icon-mic { + background-position: -12px -285px; +} + +.im_attach, .im_record { cursor: pointer; display: none; overflow: hidden; position: absolute; - right: 0; + right: 34px; top: 0; margin: 0; width: 50px; @@ -1447,6 +1451,32 @@ a.im_message_fwd_author { } } +.non_ffos { + .im_attach { + right: 0; + } +} + +.im_record { + right: 0; + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; +} + +.ffos { + .im_send_form_empty { + .im_send_field_wrap { + margin-right: 85px; + } + + .im_record { + display: block; + } + } +} + .im_send_form_empty { .im_submit { display: none; @@ -1457,6 +1487,38 @@ a.im_message_fwd_author { } } +.im_voice_recording, .im_processing_recording { + background-color: rgb(23, 23, 23); + color: white; + + .im_voice_recorder_wrap { + display: block; + } + + .im_send_field_wrap { + display: none; + } + + .im_attach { + display: none; + } + + .composer_emoji_insert_btn { + display: none; + } + +} + +.im_processing_recording { + .im_recorder_indicator i { + background-color: green; + } + + .im_record { + display: none; + } +} + .icon-emoji { display: inline-block; width: 22px; @@ -1497,6 +1559,45 @@ a.im_message_fwd_author { } } +.im_voice_recorder_wrap { + margin-left: 0px; + padding-left: 10px; + height: 38px; + display: none; + line-height: 38px; + color: white; +} + +.im_recorder_indicator, .im_recorder_time { + float: left; + vertical-align: middle; +} + +.im_recorder_indicator i { + background-color: #F00; + height: 10px; + width: 10px; + border-radius: 50%; + margin-right: 5px; + vertical-align: middle; + display: inline-block; +} + +.im_recorder_label { + overflow: auto; + font-size: 17px; + text-align: center; + margin-right: 50px; + + i, span { + vertical-align: middle; + } + + i { + margin-right: 5px; + } +} + .composer_rich_textarea { min-height: 18px; max-height: 136px; @@ -1876,8 +1977,7 @@ a.media_modal_date:hover { .im_send_keyboard_wrap { padding: 0 5px; } - .composer_progress_icon_wrap { right: 6px; top: 4px; -} \ No newline at end of file +} diff --git a/app/manifest.webapp b/app/manifest.webapp index 88416791..4d6825da 100644 --- a/app/manifest.webapp +++ b/app/manifest.webapp @@ -44,6 +44,9 @@ "device-storage:videos": { "description": "Required for videos download", "access": "createonly" + }, + "audio-capture" : { + "description" : "Required to record voice messages" } }, "activities": { diff --git a/app/partials/mobile/im.html b/app/partials/mobile/im.html index 32e043e9..778a2eb1 100644 --- a/app/partials/mobile/im.html +++ b/app/partials/mobile/im.html @@ -131,7 +131,7 @@ -
+
@@ -161,11 +161,24 @@
+
+
+
{{voiceRecorder.time}}
+
+ + +
+
+
+
+ +
+ @@ -194,4 +207,4 @@
- \ No newline at end of file +