diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro
index 4c1e850..5823b5a 100644
--- a/harbour-fernschreiber.pro
+++ b/harbour-fernschreiber.pro
@@ -16,7 +16,7 @@ CONFIG += sailfishapp sailfishapp_i18n
PKGCONFIG += nemonotifications-qt5 zlib
-QT += core dbus sql
+QT += core dbus sql multimedia
DEFINES += QT_STATICPLUGIN
diff --git a/qml/components/VoiceNoteOverlay.qml b/qml/components/VoiceNoteOverlay.qml
index fb2b92a..66dcb4f 100644
--- a/qml/components/VoiceNoteOverlay.qml
+++ b/qml/components/VoiceNoteOverlay.qml
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2020 Sebastian J. Wolf and other contributors
+ Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber.
@@ -18,13 +18,74 @@
*/
import QtQuick 2.6
import Sailfish.Silica 1.0
+import WerkWolf.Fernschreiber 1.0
import "../components"
import "../js/twemoji.js" as Emoji
+import "../js/debug.js" as Debug
Item {
id: voiceNoteOverlayItem
anchors.fill: parent
+ property int recordingState: fernschreiberUtils.getVoiceNoteRecordingState();
+ property int recordingDuration: 0;
+
+ function handleRecordingState() {
+ switch (recordingState) {
+ case FernschreiberUtilities.Unavailable:
+ recordingStateLabel.text = qsTr("Unavailable");
+ break;
+ case FernschreiberUtilities.Stopped:
+ recordingStateLabel.text = qsTr("Stopped");
+ break;
+ case FernschreiberUtilities.Starting:
+ recordingStateLabel.text = qsTr("Starting");
+ break;
+ case FernschreiberUtilities.Recording:
+ recordingStateLabel.text = qsTr("Recording");
+ break;
+ case FernschreiberUtilities.Stopping:
+ recordingStateLabel.text = qsTr("Stopping");
+ break;
+ }
+ }
+
+ function getTwoDigitString(numberToBeConverted) {
+ var numberString = "00";
+ if (numberToBeConverted > 0 && numberToBeConverted < 10) {
+ numberString = "0" + String(numberToBeConverted);
+ }
+ if (numberToBeConverted >= 10) {
+ numberString = String(numberToBeConverted);
+ }
+ return numberString;
+ }
+
+ function handleRecordingDuration() {
+ var minutes = Math.floor(recordingDuration / 60);
+ var seconds = recordingDuration % 60;
+ recordingDurationLabel.text = getTwoDigitString(minutes) + ":" + getTwoDigitString(seconds);
+ }
+
+ Component.onCompleted: {
+ handleRecordingState();
+ handleRecordingDuration();
+ }
+
+ Connections {
+ target: fernschreiberUtils
+ onVoiceNoteDurationChanged: {
+ Debug.log("New duration received: " + duration);
+ recordingDuration = Math.round(duration / 1000);
+ handleRecordingDuration();
+ }
+ onVoiceNoteRecordingStateChanged: {
+ Debug.log("New state received: " + state);
+ recordingState = state;
+ handleRecordingState();
+ }
+ }
+
Rectangle {
id: stickerPickerOverlayBackground
anchors.fill: parent
@@ -52,17 +113,85 @@ Item {
text: qsTr("Record a Voice Note")
}
- Image {
- id: recorderImage
- source: "image://theme/icon-l-recorder"
+ Label {
+ wrapMode: Text.Wrap
+ width: parent.width - ( 2 * Theme.horizontalPageMargin )
+ horizontalAlignment: Text.AlignHCenter
+ text: qsTr("Press the button to start recording")
+ font.pixelSize: Theme.fontSizeMedium
anchors {
horizontalCenter: parent.horizontalCenter
}
+ }
- fillMode: Image.PreserveAspectFit
- asynchronous: true
- width: Theme.itemSizeLarge
- height: Theme.itemSizeLarge
+ Item {
+ width: Theme.iconSizeExtraLarge
+ height: Theme.iconSizeExtraLarge
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ Rectangle {
+ color: Theme.primaryColor
+ opacity: Theme.opacityOverlay
+ width: Theme.iconSizeExtraLarge
+ height: Theme.iconSizeExtraLarge
+ anchors.centerIn: parent
+ radius: width / 2
+ }
+
+ Rectangle {
+ id: recordButton
+ color: "red"
+ width: Theme.iconSizeExtraLarge * 0.6
+ height: Theme.iconSizeExtraLarge * 0.6
+ anchors.centerIn: parent
+ radius: width / 2
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ recordButton.visible = false;
+ fernschreiberUtils.startRecordingVoiceNote();
+ }
+ }
+ }
+
+ Rectangle {
+ id: stopButton
+ visible: !recordButton.visible
+ color: Theme.overlayBackgroundColor
+ width: Theme.iconSizeExtraLarge * 0.4
+ height: Theme.iconSizeExtraLarge * 0.4
+ anchors.centerIn: parent
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ recordButton.visible = true;
+ fernschreiberUtils.stopRecordingVoiceNote();
+ }
+ }
+ }
+ }
+
+ Label {
+ id: recordingStateLabel
+ wrapMode: Text.Wrap
+ width: parent.width - ( 2 * Theme.horizontalPageMargin )
+ horizontalAlignment: Text.AlignHCenter
+ font.pixelSize: Theme.fontSizeMedium
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ Label {
+ id: recordingDurationLabel
+ wrapMode: Text.Wrap
+ width: parent.width - ( 2 * Theme.horizontalPageMargin )
+ horizontalAlignment: Text.AlignHCenter
+ font.pixelSize: Theme.fontSizeMedium
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
}
}
diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml
index f5f0aeb..0cdbb6f 100644
--- a/qml/pages/ChatPage.qml
+++ b/qml/pages/ChatPage.qml
@@ -1145,6 +1145,11 @@ Page {
width: parent.width
height: active ? parent.height : 0
source: "../components/VoiceNoteOverlay.qml"
+ onActiveChanged: {
+ if (!active) {
+ fernschreiberUtils.stopRecordingVoiceNote();
+ }
+ }
}
}
diff --git a/src/fernschreiberutils.cpp b/src/fernschreiberutils.cpp
index b75734a..d079d59 100644
--- a/src/fernschreiberutils.cpp
+++ b/src/fernschreiberutils.cpp
@@ -1,10 +1,57 @@
-#include "fernschreiberutils.h"
+/*
+ Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+#include "fernschreiberutils.h"
#include
#include
+#include
+#include
+#include
+#include
+#include
+
+#define DEBUG_MODULE FernschreiberUtils
+#include "debuglog.h"
FernschreiberUtils::FernschreiberUtils(QObject *parent) : QObject(parent)
{
+ LOG("Initializing audio recorder...");
+
+ QString temporaryDirectoryPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + + "/harbour-fernschreiber";
+ QDir temporaryDirectory(temporaryDirectoryPath);
+ if (!temporaryDirectory.exists()) {
+ temporaryDirectory.mkpath(temporaryDirectoryPath);
+ }
+
+ QAudioEncoderSettings encoderSettings;
+ encoderSettings.setCodec("audio/vorbis");
+ encoderSettings.setChannelCount(1);
+ encoderSettings.setQuality(QMultimedia::LowQuality);
+ this->audioRecorder.setEncodingSettings(encoderSettings);
+ this->audioRecorder.setContainerFormat("ogg");
+ this->audioRecorder.setOutputLocation(QUrl::fromLocalFile(temporaryDirectoryPath + "/voicenote.ogg"));
+
+ QMediaRecorder::Status audioRecorderStatus = this->audioRecorder.status();
+ this->handleAudioRecorderStatusChanged(audioRecorderStatus);
+
+ connect(&audioRecorder, SIGNAL(durationChanged(qlonglong)), this, SIGNAL(voiceNoteDurationChanged(qlonglong)));
+ connect(&audioRecorder, SIGNAL(statusChanged(QMediaRecorder::Status)), this, SLOT(handleAudioRecorderStatusChanged(QMediaRecorder::Status)));
}
@@ -128,3 +175,58 @@ QString FernschreiberUtils::getUserName(const QVariantMap &userInformation)
const QString lastName = userInformation.value("last_name").toString();
return QString(firstName + " " + lastName).trimmed();
}
+
+void FernschreiberUtils::startRecordingVoiceNote()
+{
+ LOG("Start recording voice note...");
+ QString voiceNotePath = this->voiceNotePath();
+ LOG("Using temporary file at " << voiceNotePath);
+ if (QFile::exists(voiceNotePath)) {
+ LOG("Removing old temporary file...");
+ QFile::remove(voiceNotePath);
+ }
+ this->audioRecorder.setVolume(1);
+ this->audioRecorder.record();
+}
+
+void FernschreiberUtils::stopRecordingVoiceNote()
+{
+ LOG("Stop recording voice note...");
+ this->audioRecorder.stop();
+}
+
+QString FernschreiberUtils::voiceNotePath()
+{
+ return this->audioRecorder.outputLocation().toLocalFile();
+}
+
+FernschreiberUtils::VoiceNoteRecordingState FernschreiberUtils::getVoiceNoteRecordingState()
+{
+ return this->voiceNoteRecordingState;
+}
+
+void FernschreiberUtils::handleAudioRecorderStatusChanged(QMediaRecorder::Status status)
+{
+ LOG("Audio recorder status changed:" << status);
+ switch (status) {
+ case QMediaRecorder::UnavailableStatus:
+ case QMediaRecorder::UnloadedStatus:
+ case QMediaRecorder::LoadingStatus:
+ this->voiceNoteRecordingState = VoiceNoteRecordingState::Unavailable;
+ break;
+ case QMediaRecorder::LoadedStatus:
+ case QMediaRecorder::PausedStatus:
+ this->voiceNoteRecordingState = VoiceNoteRecordingState::Stopped;
+ break;
+ case QMediaRecorder::StartingStatus:
+ this->voiceNoteRecordingState = VoiceNoteRecordingState::Starting;
+ break;
+ case QMediaRecorder::FinalizingStatus:
+ this->voiceNoteRecordingState = VoiceNoteRecordingState::Stopping;
+ break;
+ case QMediaRecorder::RecordingStatus:
+ this->voiceNoteRecordingState = VoiceNoteRecordingState::Recording;
+ break;
+ }
+ emit voiceNoteRecordingStateChanged(this->voiceNoteRecordingState);
+}
diff --git a/src/fernschreiberutils.h b/src/fernschreiberutils.h
index 35fc8a0..16e80c3 100644
--- a/src/fernschreiberutils.h
+++ b/src/fernschreiberutils.h
@@ -1,7 +1,27 @@
+/*
+ Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
#ifndef FERNSCHREIBERUTILS_H
#define FERNSCHREIBERUTILS_H
#include
+#include
#include "tdlibwrapper.h"
class FernschreiberUtils : public QObject
@@ -10,12 +30,34 @@ class FernschreiberUtils : public QObject
public:
explicit FernschreiberUtils(QObject *parent = nullptr);
+ enum VoiceNoteRecordingState {
+ Unavailable,
+ Stopped,
+ Starting,
+ Recording,
+ Stopping
+ };
+ Q_ENUM(VoiceNoteRecordingState)
+
static QString getMessageShortText(TDLibWrapper *tdLibWrapper, const QVariantMap &messageContent, const bool isChannel, const qlonglong currentUserId, const QVariantMap &messageSender);
static QString getUserName(const QVariantMap &userInformation);
-signals:
+ Q_INVOKABLE void startRecordingVoiceNote();
+ Q_INVOKABLE void stopRecordingVoiceNote();
+ Q_INVOKABLE QString voiceNotePath();
+ Q_INVOKABLE VoiceNoteRecordingState getVoiceNoteRecordingState();
+
+signals:
+ void voiceNoteDurationChanged(qlonglong duration);
+ void voiceNoteRecordingStateChanged(VoiceNoteRecordingState state);
+
+private slots:
+ void handleAudioRecorderStatusChanged(QMediaRecorder::Status status);
+
+private:
+ QAudioRecorder audioRecorder;
+ VoiceNoteRecordingState voiceNoteRecordingState;
-public slots:
};
#endif // FERNSCHREIBERUTILS_H
diff --git a/src/harbour-fernschreiber.cpp b/src/harbour-fernschreiber.cpp
index 6efdf5d..0852fea 100644
--- a/src/harbour-fernschreiber.cpp
+++ b/src/harbour-fernschreiber.cpp
@@ -82,6 +82,7 @@ int main(int argc, char *argv[])
FernschreiberUtils *fernschreiberUtils = new FernschreiberUtils(view.data());
context->setContextProperty("fernschreiberUtils", fernschreiberUtils);
+ qmlRegisterUncreatableType(uri, 1, 0, "FernschreiberUtilities", QString());
DBusAdaptor *dBusAdaptor = tdLibWrapper->getDBusAdaptor();
context->setContextProperty("dBusAdaptor", dBusAdaptor);
diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts
index 10db4a5..6894a9e 100644
--- a/translations/harbour-fernschreiber-de.ts
+++ b/translations/harbour-fernschreiber-de.ts
@@ -1438,6 +1438,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-en.ts b/translations/harbour-fernschreiber-en.ts
index ffaad43..e474f3f 100644
--- a/translations/harbour-fernschreiber-en.ts
+++ b/translations/harbour-fernschreiber-en.ts
@@ -1438,6 +1438,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts
index 57c7541..5f812e5 100644
--- a/translations/harbour-fernschreiber-es.ts
+++ b/translations/harbour-fernschreiber-es.ts
@@ -1417,6 +1417,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts
index 2739023..cb1004c 100644
--- a/translations/harbour-fernschreiber-fi.ts
+++ b/translations/harbour-fernschreiber-fi.ts
@@ -1439,6 +1439,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-hu.ts b/translations/harbour-fernschreiber-hu.ts
index 630f4ae..a160d2d 100644
--- a/translations/harbour-fernschreiber-hu.ts
+++ b/translations/harbour-fernschreiber-hu.ts
@@ -1417,6 +1417,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts
index 5c18e4c..d0319bc 100644
--- a/translations/harbour-fernschreiber-it.ts
+++ b/translations/harbour-fernschreiber-it.ts
@@ -1438,6 +1438,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts
index dd55b46..fc7f215 100644
--- a/translations/harbour-fernschreiber-pl.ts
+++ b/translations/harbour-fernschreiber-pl.ts
@@ -1459,6 +1459,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts
index 0edb938..d3b4699 100644
--- a/translations/harbour-fernschreiber-ru.ts
+++ b/translations/harbour-fernschreiber-ru.ts
@@ -1459,6 +1459,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-sv.ts b/translations/harbour-fernschreiber-sv.ts
index 2a159af..0bbb2e4 100644
--- a/translations/harbour-fernschreiber-sv.ts
+++ b/translations/harbour-fernschreiber-sv.ts
@@ -1438,6 +1438,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber-zh_CN.ts b/translations/harbour-fernschreiber-zh_CN.ts
index 44d8a9e..437b5d8 100644
--- a/translations/harbour-fernschreiber-zh_CN.ts
+++ b/translations/harbour-fernschreiber-zh_CN.ts
@@ -1417,6 +1417,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview
diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts
index f0b5aa4..5664771 100644
--- a/translations/harbour-fernschreiber.ts
+++ b/translations/harbour-fernschreiber.ts
@@ -1438,6 +1438,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WebPagePreview