diff --git a/src/dialogs/AcceptCall.cpp b/src/dialogs/AcceptCall.cpp
new file mode 100644
index 00000000..be1eb0c9
--- /dev/null
+++ b/src/dialogs/AcceptCall.cpp
@@ -0,0 +1,135 @@
+#include <QComboBox>
+#include <QLabel>
+#include <QPushButton>
+#include <QString>
+#include <QVBoxLayout>
+
+#include "ChatPage.h"
+#include "Config.h"
+#include "UserSettingsPage.h"
+#include "Utils.h"
+#include "WebRTCSession.h"
+#include "dialogs/AcceptCall.h"
+#include "ui/Avatar.h"
+
+namespace dialogs {
+
+AcceptCall::AcceptCall(const QString &caller,
+ const QString &displayName,
+ const QString &roomName,
+ const QString &avatarUrl,
+ QSharedPointer<UserSettings> settings,
+ QWidget *parent)
+ : QWidget(parent)
+{
+ std::string errorMessage;
+ if (!WebRTCSession::instance().init(&errorMessage)) {
+ emit ChatPage::instance()->showNotification(QString::fromStdString(errorMessage));
+ emit close();
+ return;
+ }
+ audioDevices_ = WebRTCSession::instance().getAudioSourceNames(
+ settings->defaultAudioSource().toStdString());
+ if (audioDevices_.empty()) {
+ emit ChatPage::instance()->showNotification(
+ "Incoming call: No audio sources found.");
+ emit close();
+ return;
+ }
+
+ setAutoFillBackground(true);
+ setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
+ setWindowModality(Qt::WindowModal);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ setMinimumWidth(conf::modals::MIN_WIDGET_WIDTH);
+ setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+
+ auto layout = new QVBoxLayout(this);
+ layout->setSpacing(conf::modals::WIDGET_SPACING);
+ layout->setMargin(conf::modals::WIDGET_MARGIN);
+
+ QFont f;
+ f.setPointSizeF(f.pointSizeF());
+
+ QFont labelFont;
+ labelFont.setWeight(QFont::Medium);
+
+ QLabel *displayNameLabel = nullptr;
+ if (!displayName.isEmpty() && displayName != caller) {
+ displayNameLabel = new QLabel(displayName, this);
+ labelFont.setPointSizeF(f.pointSizeF() * 2);
+ displayNameLabel->setFont(labelFont);
+ displayNameLabel->setAlignment(Qt::AlignCenter);
+ }
+
+ QLabel *callerLabel = new QLabel(caller, this);
+ labelFont.setPointSizeF(f.pointSizeF() * 1.2);
+ callerLabel->setFont(labelFont);
+ callerLabel->setAlignment(Qt::AlignCenter);
+
+ auto avatar = new Avatar(this, QFontMetrics(f).height() * 6);
+ if (!avatarUrl.isEmpty())
+ avatar->setImage(avatarUrl);
+ else
+ avatar->setLetter(utils::firstChar(roomName));
+
+ const int iconSize = 22;
+ QLabel *callTypeIndicator = new QLabel(this);
+ callTypeIndicator->setPixmap(
+ QIcon(":/icons/icons/ui/place-call.png").pixmap(QSize(iconSize * 2, iconSize * 2)));
+
+ QLabel *callTypeLabel = new QLabel("Voice Call", this);
+ labelFont.setPointSizeF(f.pointSizeF() * 1.1);
+ callTypeLabel->setFont(labelFont);
+ callTypeLabel->setAlignment(Qt::AlignCenter);
+
+ auto buttonLayout = new QHBoxLayout;
+ buttonLayout->setSpacing(18);
+ acceptBtn_ = new QPushButton(tr("Accept"), this);
+ acceptBtn_->setDefault(true);
+ acceptBtn_->setIcon(QIcon(":/icons/icons/ui/place-call.png"));
+ acceptBtn_->setIconSize(QSize(iconSize, iconSize));
+
+ rejectBtn_ = new QPushButton(tr("Reject"), this);
+ rejectBtn_->setIcon(QIcon(":/icons/icons/ui/end-call.png"));
+ rejectBtn_->setIconSize(QSize(iconSize, iconSize));
+ buttonLayout->addWidget(acceptBtn_);
+ buttonLayout->addWidget(rejectBtn_);
+
+ auto deviceLayout = new QHBoxLayout;
+ auto audioLabel = new QLabel(this);
+ audioLabel->setPixmap(
+ QIcon(":/icons/icons/ui/microphone-unmute.png").pixmap(QSize(iconSize, iconSize)));
+
+ auto deviceList = new QComboBox(this);
+ for (const auto &d : audioDevices_)
+ deviceList->addItem(QString::fromStdString(d));
+
+ deviceLayout->addStretch();
+ deviceLayout->addWidget(audioLabel);
+ deviceLayout->addWidget(deviceList);
+
+ if (displayNameLabel)
+ layout->addWidget(displayNameLabel, 0, Qt::AlignCenter);
+ layout->addWidget(callerLabel, 0, Qt::AlignCenter);
+ layout->addWidget(avatar, 0, Qt::AlignCenter);
+ layout->addWidget(callTypeIndicator, 0, Qt::AlignCenter);
+ layout->addWidget(callTypeLabel, 0, Qt::AlignCenter);
+ layout->addLayout(buttonLayout);
+ layout->addLayout(deviceLayout);
+
+ connect(acceptBtn_, &QPushButton::clicked, this, [this, deviceList, settings]() {
+ WebRTCSession::instance().setAudioSource(deviceList->currentIndex());
+ settings->setDefaultAudioSource(
+ QString::fromStdString(audioDevices_[deviceList->currentIndex()]));
+ emit accept();
+ emit close();
+ });
+ connect(rejectBtn_, &QPushButton::clicked, this, [this]() {
+ emit reject();
+ emit close();
+ });
+}
+
+}
diff --git a/src/dialogs/AcceptCall.h b/src/dialogs/AcceptCall.h
new file mode 100644
index 00000000..909605d0
--- /dev/null
+++ b/src/dialogs/AcceptCall.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <QSharedPointer>
+#include <QWidget>
+
+class QPushButton;
+class QString;
+class UserSettings;
+
+namespace dialogs {
+
+class AcceptCall : public QWidget
+{
+ Q_OBJECT
+
+public:
+ AcceptCall(const QString &caller,
+ const QString &displayName,
+ const QString &roomName,
+ const QString &avatarUrl,
+ QSharedPointer<UserSettings> settings,
+ QWidget *parent = nullptr);
+
+signals:
+ void accept();
+ void reject();
+
+private:
+ QPushButton *acceptBtn_;
+ QPushButton *rejectBtn_;
+ std::vector<std::string> audioDevices_;
+};
+
+}
diff --git a/src/dialogs/PlaceCall.cpp b/src/dialogs/PlaceCall.cpp
new file mode 100644
index 00000000..4e70370a
--- /dev/null
+++ b/src/dialogs/PlaceCall.cpp
@@ -0,0 +1,104 @@
+#include <QComboBox>
+#include <QLabel>
+#include <QPushButton>
+#include <QString>
+#include <QVBoxLayout>
+
+#include "ChatPage.h"
+#include "Config.h"
+#include "UserSettingsPage.h"
+#include "Utils.h"
+#include "WebRTCSession.h"
+#include "dialogs/PlaceCall.h"
+#include "ui/Avatar.h"
+
+namespace dialogs {
+
+PlaceCall::PlaceCall(const QString &callee,
+ const QString &displayName,
+ const QString &roomName,
+ const QString &avatarUrl,
+ QSharedPointer<UserSettings> settings,
+ QWidget *parent)
+ : QWidget(parent)
+{
+ std::string errorMessage;
+ if (!WebRTCSession::instance().init(&errorMessage)) {
+ emit ChatPage::instance()->showNotification(QString::fromStdString(errorMessage));
+ emit close();
+ return;
+ }
+ audioDevices_ = WebRTCSession::instance().getAudioSourceNames(
+ settings->defaultAudioSource().toStdString());
+ if (audioDevices_.empty()) {
+ emit ChatPage::instance()->showNotification("No audio sources found.");
+ emit close();
+ return;
+ }
+
+ setAutoFillBackground(true);
+ setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
+ setWindowModality(Qt::WindowModal);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ auto layout = new QVBoxLayout(this);
+ layout->setSpacing(conf::modals::WIDGET_SPACING);
+ layout->setMargin(conf::modals::WIDGET_MARGIN);
+
+ auto buttonLayout = new QHBoxLayout;
+ buttonLayout->setSpacing(15);
+ buttonLayout->setMargin(0);
+
+ QFont f;
+ f.setPointSizeF(f.pointSizeF());
+ auto avatar = new Avatar(this, QFontMetrics(f).height() * 3);
+ if (!avatarUrl.isEmpty())
+ avatar->setImage(avatarUrl);
+ else
+ avatar->setLetter(utils::firstChar(roomName));
+ const int iconSize = 18;
+ voiceBtn_ = new QPushButton(tr("Voice"), this);
+ voiceBtn_->setIcon(QIcon(":/icons/icons/ui/place-call.png"));
+ voiceBtn_->setIconSize(QSize(iconSize, iconSize));
+ voiceBtn_->setDefault(true);
+ cancelBtn_ = new QPushButton(tr("Cancel"), this);
+
+ buttonLayout->addWidget(avatar);
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(voiceBtn_);
+ buttonLayout->addWidget(cancelBtn_);
+
+ QString name = displayName.isEmpty() ? callee : displayName;
+ QLabel *label = new QLabel("Place a call to " + name + "?", this);
+
+ auto deviceLayout = new QHBoxLayout;
+ auto audioLabel = new QLabel(this);
+ audioLabel->setPixmap(QIcon(":/icons/icons/ui/microphone-unmute.png")
+ .pixmap(QSize(iconSize * 1.2, iconSize * 1.2)));
+
+ auto deviceList = new QComboBox(this);
+ for (const auto &d : audioDevices_)
+ deviceList->addItem(QString::fromStdString(d));
+
+ deviceLayout->addStretch();
+ deviceLayout->addWidget(audioLabel);
+ deviceLayout->addWidget(deviceList);
+
+ layout->addWidget(label);
+ layout->addLayout(buttonLayout);
+ layout->addLayout(deviceLayout);
+
+ connect(voiceBtn_, &QPushButton::clicked, this, [this, deviceList, settings]() {
+ WebRTCSession::instance().setAudioSource(deviceList->currentIndex());
+ settings->setDefaultAudioSource(
+ QString::fromStdString(audioDevices_[deviceList->currentIndex()]));
+ emit voice();
+ emit close();
+ });
+ connect(cancelBtn_, &QPushButton::clicked, this, [this]() {
+ emit cancel();
+ emit close();
+ });
+}
+
+}
diff --git a/src/dialogs/PlaceCall.h b/src/dialogs/PlaceCall.h
new file mode 100644
index 00000000..5a1e982c
--- /dev/null
+++ b/src/dialogs/PlaceCall.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <QSharedPointer>
+#include <QWidget>
+
+class QPushButton;
+class QString;
+class UserSettings;
+
+namespace dialogs {
+
+class PlaceCall : public QWidget
+{
+ Q_OBJECT
+
+public:
+ PlaceCall(const QString &callee,
+ const QString &displayName,
+ const QString &roomName,
+ const QString &avatarUrl,
+ QSharedPointer<UserSettings> settings,
+ QWidget *parent = nullptr);
+
+signals:
+ void voice();
+ void cancel();
+
+private:
+ QPushButton *voiceBtn_;
+ QPushButton *cancelBtn_;
+ std::vector<std::string> audioDevices_;
+};
+
+}
diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp
index 3415b127..086dbb40 100644
--- a/src/dialogs/UserProfile.cpp
+++ b/src/dialogs/UserProfile.cpp
@@ -1,6 +1,7 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QListWidget>
+#include <QMessageBox>
#include <QShortcut>
#include <QVBoxLayout>
@@ -97,6 +98,14 @@ UserProfile::UserProfile(QWidget *parent)
if (utils::localUser() != user_id)
req.invite = {user_id.toStdString()};
+ if (QMessageBox::question(
+ this,
+ tr("Confirm DM"),
+ tr("Do you really want to invite %1 (%2) to a direct chat?")
+ .arg(cache::displayName(roomId_, user_id))
+ .arg(user_id)) != QMessageBox::Yes)
+ return;
+
emit ChatPage::instance()->createRoom(req);
});
@@ -199,6 +208,8 @@ UserProfile::init(const QString &userId, const QString &roomId)
{
resetToDefaults();
+ this->roomId_ = roomId;
+
auto displayName = cache::displayName(roomId, userId);
userIdLabel_->setText(userId);
diff --git a/src/dialogs/UserProfile.h b/src/dialogs/UserProfile.h
index 81276d2a..8129fdcf 100644
--- a/src/dialogs/UserProfile.h
+++ b/src/dialogs/UserProfile.h
@@ -53,6 +53,7 @@ private:
void resetToDefaults();
Avatar *avatar_;
+ QString roomId_;
QLabel *userIdLabel_;
QLabel *displayNameLabel_;
|