Commit cc4e824b authored by Sébastien Blin's avatar Sébastien Blin Committed by Andreas Traczyk

ringnotify: rewrite notification system

Ring will now use three types of notifications:

1. Call notifications: opened when an incoming call is here
and closed at the end of the call.
2. Request notifications: opened when a new trust request
arrives and closed when the user accepts/refuse/block or
just open the conversation.
3. Chat notifications: arrives with new interactions and if
the current conversation is different or the client not focused. Closed
by Gnome or when the conversation is opened.

Change-Id: I5e5abf20507bac8bb37c429bc929c671fe66bd6b
Gitlab: #868Reviewed-by: Andreas Traczyk's avatarAndreas Traczyk <andreas.traczyk@savoirfairelinux.com>
parent 5912ad07
......@@ -34,6 +34,10 @@
<default>true</default>
<summary>Enable notifications for incoming calls.</summary>
</key>
<key name="enable-pending-notifications" type="b">
<default>true</default>
<summary>Enable notifications for pending requests.</summary>
</key>
<key name="enable-chat-notifications" type="b">
<default>true</default>
<summary>Enable notifications for new chat messages.</summary>
......
......@@ -59,6 +59,7 @@ struct _GeneralSettingsViewPrivate
GtkWidget *checkbutton_showstatusicon;
GtkWidget *checkbutton_bringtofront;
GtkWidget *checkbutton_callnotifications;
GtkWidget *checkbutton_pendingnotifications;
GtkWidget *checkbutton_chatnotifications;
GtkWidget *checkbutton_chatdisplaylinks;
GtkWidget *checkbutton_searchentryplacescall;
......@@ -223,6 +224,9 @@ general_settings_view_init(GeneralSettingsView *self)
g_settings_bind(priv->settings, "enable-display-links",
priv->checkbutton_chatdisplaylinks, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind(priv->settings, "enable-pending-notifications",
priv->checkbutton_pendingnotifications, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind(priv->settings, "enable-chat-notifications",
priv->checkbutton_chatnotifications, "active",
G_SETTINGS_BIND_DEFAULT);
......@@ -316,6 +320,7 @@ general_settings_view_class_init(GeneralSettingsViewClass *klass)
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_bringtofront);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_callnotifications);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_chatdisplaylinks);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_pendingnotifications);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_chatnotifications);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_searchentryplacescall);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, radiobutton_chatright);
......
......@@ -119,9 +119,6 @@ struct _RingClientPrivate {
NMClient *nm_client;
NMActiveConnection *primary_connection;
#endif
/* notifications */
QMetaObject::Connection call_notification;
};
/* this union is used to pass ints as pointers and vice versa for GAction parameters*/
......@@ -457,22 +454,6 @@ nm_client_cb(G_GNUC_UNUSED GObject *source_object, GAsyncResult *result, RingCli
#endif /* USE_LIBNM */
static void
call_notifications_toggled(RingClient *self)
{
auto priv = RING_CLIENT_GET_PRIVATE(self);
if (g_settings_get_boolean(priv->settings, "enable-call-notifications")) {
priv->call_notification = QObject::connect(
&CallModel::instance(),
&CallModel::incomingCall,
[] (Call *call) { ring_notify_incoming_call(call); }
);
} else {
QObject::disconnect(priv->call_notification);
}
}
static void
ring_client_startup(GApplication *app)
{
......@@ -590,12 +571,6 @@ ring_client_startup(GApplication *app)
ring_window_show(client);
}
);
/* enable notifications based on settings */
ring_notify_init();
call_notifications_toggled(client);
g_signal_connect_swapped(priv->settings, "changed::enable-call-notifications", G_CALLBACK(call_notifications_toggled), client);
#if USE_LIBNM
/* monitor the network using libnm to notify the daemon about connectivity chagnes */
nm_client_new_async(priv->cancellable, (GAsyncReadyCallback)nm_client_cb, client);
......@@ -617,7 +592,6 @@ ring_client_shutdown(GApplication *app)
g_object_unref(priv->cancellable);
QObject::disconnect(priv->uam_updated);
QObject::disconnect(priv->call_notification);
/* free the QCoreApplication, which will destroy all libRingClient models
* and thus send the Unregister signal over dbus to dring */
......@@ -631,8 +605,6 @@ ring_client_shutdown(GApplication *app)
g_clear_object(&priv->settings);
ring_notify_uninit();
#if USE_LIBNM
/* clear NetworkManager client if it was used */
g_clear_object(&priv->nm_client);
......
......@@ -23,7 +23,8 @@
// GTK+ related
#include <glib/gi18n.h>
#include <iostream>
// std
#include <algorithm>
// LRC
#include <accountmodel.h> // Old lrc but still used
......@@ -62,6 +63,7 @@
#include "ringnotify.h"
#include "accountinfopointer.h"
#include "native/pixbufmanipulator.h"
#include "ringnotify.h"
//==============================================================================
......@@ -111,11 +113,18 @@ struct RingMainWindowPrivate
GtkWidget *scrolled_window_contact_requests;
GtkWidget *webkit_chat_container; ///< The webkit_chat_container is created once, then reused for all chat views
GtkWidget *notifier;
GSettings *settings;
details::CppImpl* cpp; ///< Non-UI and C++ only code
gulong update_download_folder;
gulong notif_chat_view;
gulong notif_accept_pending;
gulong notif_refuse_pending;
gulong notif_accept_call;
gulong notif_decline_call;
};
G_DEFINE_TYPE_WITH_PRIVATE(RingMainWindow, ring_main_window, GTK_TYPE_APPLICATION_WINDOW);
......@@ -304,17 +313,22 @@ public:
QMetaObject::Connection showChatViewConnection_;
QMetaObject::Connection showCallViewConnection_;
QMetaObject::Connection showIncomingViewConnection_;
QMetaObject::Connection newTrustRequestNotification_;
QMetaObject::Connection closeTrustRequestNotification_;
QMetaObject::Connection slotNewInteraction_;
QMetaObject::Connection slotReadInteraction_;
QMetaObject::Connection changeAccountConnection_;
QMetaObject::Connection newAccountConnection_;
QMetaObject::Connection rmAccountConnection_;
QMetaObject::Connection invalidAccountConnection_;
QMetaObject::Connection historyClearedConnection_;
QMetaObject::Connection modelSortedConnection_;
QMetaObject::Connection callChangedConnection_;
QMetaObject::Connection newIncomingCallConnection_;
QMetaObject::Connection filterChangedConnection_;
QMetaObject::Connection newConversationConnection_;
QMetaObject::Connection conversationRemovedConnection_;
QMetaObject::Connection accountStatusChangedConnection_;
QMetaObject::Connection chatNotification_;
private:
CppImpl() = delete;
......@@ -325,7 +339,6 @@ private:
GtkWidget* displayIncomingView(lrc::api::conversation::Info);
GtkWidget* displayCurrentCallView(lrc::api::conversation::Info);
GtkWidget* displayChatView(lrc::api::conversation::Info);
void chatNotifications();
// Callbacks used as LRC Qt slot
void slotAccountAddedFromLrc(const std::string& id);
......@@ -334,12 +347,19 @@ private:
void slotAccountStatusChanged(const std::string& id);
void slotConversationCleared(const std::string& uid);
void slotModelSorted();
void slotNewIncomingCall(const std::string& callId);
void slotCallStatusChanged(const std::string& callId);
void slotFilterChanged();
void slotNewConversation(const std::string& uid);
void slotConversationRemoved(const std::string& uid);
void slotShowChatView(const std::string& id, lrc::api::conversation::Info origin);
void slotShowCallView(const std::string& id, lrc::api::conversation::Info origin);
void slotShowIncomingCallView(const std::string& id, lrc::api::conversation::Info origin);
void slotNewTrustRequest(const std::string& id, const std::string& contactUri);
void slotCloseTrustRequest(const std::string& id, const std::string& contactUri);
void slotNewInteraction(const std::string& accountId, const std::string& conversation,
uint64_t, const lrc::api::interaction::Info& interaction);
void slotCloseInteraction(const std::string& accountId, const std::string& conversation, uint64_t);
};
inline namespace gtk_callbacks
......@@ -646,7 +666,6 @@ on_handle_account_migrations(RingMainWindow* self)
for (const auto& accountId : accounts) {
priv->cpp->accountInfoForMigration_ = &priv->cpp->lrc_->getAccountModel().getAccountInfo(accountId);
if (priv->cpp->accountInfoForMigration_->status == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
std::cout << "DO MIGRATION" << std::endl;
priv->account_migration_view = account_migration_view_new(priv->cpp->accountInfoForMigration_);
g_signal_connect_swapped(priv->account_migration_view, "account-migration-completed",
G_CALLBACK(on_handle_account_migrations), self);
......@@ -678,6 +697,155 @@ on_handle_account_migrations(RingMainWindow* self)
priv->cpp->showAccountSelectorWidget();
}
enum class Action {
SELECT,
ACCEPT,
REFUSE
};
static void
action_notification(gchar* title, RingMainWindow* self, Action action)
{
g_return_if_fail(IS_RING_MAIN_WINDOW(self) && title);
auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
if (!priv->cpp->accountInfo_) {
g_warning("Notification clicked but accountInfo_ currently empty");
return;
}
std::string titleStr = title;
auto firstMarker = titleStr.find(":");
if (firstMarker == std::string::npos) return;
auto secondMarker = titleStr.find(":", firstMarker + 1);
if (secondMarker == std::string::npos) return;
auto id = titleStr.substr(0, firstMarker);
auto type = titleStr.substr(firstMarker + 1, secondMarker - firstMarker - 1);
auto information = titleStr.substr(secondMarker + 1);
if (action == Action::SELECT) {
// Select conversation
if (priv->cpp->show_settings) {
priv->cpp->leaveSettingsView();
}
if (priv->cpp->accountInfo_->id != id) {
priv->cpp->updateLrc(id);
}
if (type == "interaction") {
priv->cpp->accountInfo_->conversationModel->selectConversation(information);
conversations_view_select_conversation(CONVERSATIONS_VIEW(priv->treeview_conversations), information);
} else if (type == "request") {
for (const auto& conversation : priv->cpp->accountInfo_->conversationModel->getFilteredConversations(lrc::api::profile::Type::PENDING)) {
auto current_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(priv->notebook_contacts));
auto contactRequestsPageNum = gtk_notebook_page_num(GTK_NOTEBOOK(priv->notebook_contacts),
priv->scrolled_window_contact_requests);
gtk_notebook_set_current_page(GTK_NOTEBOOK(priv->notebook_contacts), contactRequestsPageNum);
if (!conversation.participants.empty() && conversation.participants.front() == information) {
priv->cpp->accountInfo_->conversationModel->selectConversation(conversation.uid);
}
conversations_view_select_conversation(CONVERSATIONS_VIEW(priv->treeview_conversations), conversation.uid);
}
}
} else {
// accept or refuse notifiation
try {
auto& accountInfo = priv->cpp->lrc_->getAccountModel().getAccountInfo(id);
for (const auto& conversation : accountInfo.conversationModel->getFilteredConversations(lrc::api::profile::Type::PENDING)) {
if (!conversation.participants.empty() && conversation.participants.front() == information) {
if (action == Action::ACCEPT) {
accountInfo.conversationModel->makePermanent(conversation.uid);
} else {
accountInfo.conversationModel->removeConversation(conversation.uid);
}
}
}
} catch (const std::out_of_range& e) {
g_warning("Can't get account %i: %s", id.c_str(), e.what());
}
}
}
static void
on_notification_chat_clicked(GtkWidget* notifier, gchar *title, RingMainWindow* self)
{
action_notification(title, self, Action::SELECT);
}
static void
on_notification_accept_pending(GtkWidget*, gchar *title, RingMainWindow* self)
{
action_notification(title, self, Action::ACCEPT);
}
static void
on_notification_refuse_pending(GtkWidget*, gchar *title, RingMainWindow* self)
{
action_notification(title, self, Action::REFUSE);
}
static void
on_notification_accept_call(GtkWidget* notifier, gchar *title, RingMainWindow* self)
{
g_return_if_fail(IS_RING_MAIN_WINDOW(self) && title);
auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
if (!priv->cpp->accountInfo_) {
g_warning("Notification clicked but accountInfo_ currently empty");
return;
}
std::string titleStr = title;
auto firstMarker = titleStr.find(":");
if (firstMarker == std::string::npos) return;
auto secondMarker = titleStr.find(":", firstMarker + 1);
if (secondMarker == std::string::npos) return;
auto id = titleStr.substr(0, firstMarker);
auto type = titleStr.substr(firstMarker + 1, secondMarker - firstMarker - 1);
auto information = titleStr.substr(secondMarker + 1);
if (priv->cpp->show_settings) {
priv->cpp->leaveSettingsView();
}
try {
auto& accountInfo = priv->cpp->lrc_->getAccountModel().getAccountInfo(id);
accountInfo.callModel->accept(information);
} catch (const std::out_of_range& e) {
g_warning("Can't get account %i: %s", id.c_str(), e.what());
}
}
static void
on_notification_decline_call(GtkWidget* notifier, gchar *title, RingMainWindow* self)
{
g_return_if_fail(IS_RING_MAIN_WINDOW(self) && title);
auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
if (!priv->cpp->accountInfo_) {
g_warning("Notification clicked but accountInfo_ currently empty");
return;
}
std::string titleStr = title;
auto firstMarker = titleStr.find(":");
if (firstMarker == std::string::npos) return;
auto secondMarker = titleStr.find(":", firstMarker + 1);
if (secondMarker == std::string::npos) return;
auto id = titleStr.substr(0, firstMarker);
auto type = titleStr.substr(firstMarker + 1, secondMarker - firstMarker - 1);
auto information = titleStr.substr(secondMarker + 1);
try {
auto& accountInfo = priv->cpp->lrc_->getAccountModel().getAccountInfo(id);
accountInfo.callModel->hangUp(information);
} catch (const std::out_of_range& e) {
g_warning("Can't get account %i: %s", id.c_str(), e.what());
}
}
} // namespace gtk_callbacks
CppImpl::CppImpl(RingMainWindow& widget)
......@@ -686,23 +854,6 @@ CppImpl::CppImpl(RingMainWindow& widget)
, lrc_ {std::make_unique<lrc::api::Lrc>()}
{}
void
CppImpl::chatNotifications()
{
chatNotification_ = QObject::connect(
&Media::RecordingModel::instance(),
&Media::RecordingModel::newTextMessage,
[this] (Media::TextRecording* t, ContactMethod* cm) {
if ((chatViewConversation_
&& chatViewConversation_->participants[0] == cm->uri().toStdString())
|| not g_settings_get_boolean(widgets->settings, "enable-chat-notifications"))
return;
ring_notify_message(cm, t);
}
);
}
static gboolean
on_clear_all_history_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer self)
{
......@@ -957,10 +1108,6 @@ CppImpl::init()
}
}
}
// setup chat notification
chatNotifications();
// delete obsolete history
if (not accountIds.empty()) {
auto days = g_settings_get_int(widgets->settings, "history-limit");
......@@ -975,6 +1122,17 @@ CppImpl::init()
if (accounts.empty()) {
enterAccountCreationWizard();
}
widgets->notif_chat_view = g_signal_connect(widgets->notifier, "showChatView",
G_CALLBACK(on_notification_chat_clicked), self);
widgets->notif_accept_pending = g_signal_connect(widgets->notifier, "acceptPending",
G_CALLBACK(on_notification_accept_pending), self);
widgets->notif_refuse_pending = g_signal_connect(widgets->notifier, "refusePending",
G_CALLBACK(on_notification_refuse_pending), self);
widgets->notif_accept_call = g_signal_connect(widgets->notifier, "acceptCall",
G_CALLBACK(on_notification_accept_call), self);
widgets->notif_decline_call = g_signal_connect(widgets->notifier, "declineCall",
G_CALLBACK(on_notification_decline_call), self);
}
CppImpl::~CppImpl()
......@@ -983,6 +1141,8 @@ CppImpl::~CppImpl()
QObject::disconnect(showIncomingViewConnection_);
QObject::disconnect(historyClearedConnection_);
QObject::disconnect(modelSortedConnection_);
QObject::disconnect(callChangedConnection_);
QObject::disconnect(newIncomingCallConnection_);
QObject::disconnect(filterChangedConnection_);
QObject::disconnect(newConversationConnection_);
QObject::disconnect(conversationRemovedConnection_);
......@@ -991,9 +1151,11 @@ CppImpl::~CppImpl()
QObject::disconnect(rmAccountConnection_);
QObject::disconnect(invalidAccountConnection_);
QObject::disconnect(showCallViewConnection_);
QObject::disconnect(modelSortedConnection_);
QObject::disconnect(newTrustRequestNotification_);
QObject::disconnect(closeTrustRequestNotification_);
QObject::disconnect(slotNewInteraction_);
QObject::disconnect(slotReadInteraction_);
QObject::disconnect(accountStatusChangedConnection_);
QObject::disconnect(chatNotification_);
g_clear_object(&widgets->welcome_view);
g_clear_object(&widgets->webkit_chat_container);
......@@ -1070,6 +1232,16 @@ CppImpl::displayChatView(lrc::api::conversation::Info conversation)
chatViewConversation_.reset(new lrc::api::conversation::Info(conversation));
auto* new_view = chat_view_new(webkitChatContainer(), accountInfo_, chatViewConversation_.get());
g_signal_connect_swapped(new_view, "hide-view-clicked", G_CALLBACK(on_hide_view_clicked), self);
try {
auto contactUri = chatViewConversation_->participants.front();
auto contactInfo = accountInfo_->contactModel->getContact(contactUri);
auto isPending = contactInfo.profileInfo.type == lrc::api::profile::Type::PENDING;
if (isPending) {
auto notifId = accountInfo_->id + ":request:" + contactUri;
ring_hide_notification(RING_NOTIFIER(widgets->notifier), notifId);
}
} catch(...) { }
return new_view;
}
......@@ -1369,7 +1541,13 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
QObject::disconnect(showIncomingViewConnection_);
QObject::disconnect(changeAccountConnection_);
QObject::disconnect(showCallViewConnection_);
QObject::disconnect(newTrustRequestNotification_);
QObject::disconnect(closeTrustRequestNotification_);
QObject::disconnect(slotNewInteraction_);
QObject::disconnect(slotReadInteraction_);
QObject::disconnect(modelSortedConnection_);
QObject::disconnect(callChangedConnection_);
QObject::disconnect(newIncomingCallConnection_);
QObject::disconnect(historyClearedConnection_);
QObject::disconnect(filterChangedConnection_);
QObject::disconnect(newConversationConnection_);
......@@ -1421,6 +1599,14 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
&lrc::api::ConversationModel::modelSorted,
[this] { slotModelSorted(); });
callChangedConnection_ = QObject::connect(&*accountInfo_->callModel,
&lrc::api::NewCallModel::callStatusChanged,
[this] (const std::string& callId) { slotCallStatusChanged(callId); });
newIncomingCallConnection_ = QObject::connect(&*accountInfo_->callModel,
&lrc::api::NewCallModel::newIncomingCall,
[this] (const std::string&, const std::string& callId) { slotNewIncomingCall(callId); });
filterChangedConnection_ = QObject::connect(&*accountInfo_->conversationModel,
&lrc::api::ConversationModel::filterChanged,
[this] { slotFilterChanged(); });
......@@ -1441,9 +1627,29 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
&lrc::api::BehaviorController::showCallView,
[this] (const std::string& id, lrc::api::conversation::Info origin) { slotShowCallView(id, origin); });
newTrustRequestNotification_ = QObject::connect(&lrc_->getBehaviorController(),
&lrc::api::BehaviorController::newTrustRequest,
[this] (const std::string& id, const std::string& contactUri) { slotNewTrustRequest(id, contactUri); });
closeTrustRequestNotification_ = QObject::connect(&lrc_->getBehaviorController(),
&lrc::api::BehaviorController::trustRequestTreated,
[this] (const std::string& id, const std::string& contactUri) { slotCloseTrustRequest(id, contactUri); });
showIncomingViewConnection_ = QObject::connect(&lrc_->getBehaviorController(),
&lrc::api::BehaviorController::showIncomingCallView,
[this] (const std::string& id, lrc::api::conversation::Info origin) { slotShowIncomingCallView(id, origin); });
[this] (const std::string& id, lrc::api::conversation::Info origin)
{ slotShowIncomingCallView(id, origin); });
slotNewInteraction_ = QObject::connect(&lrc_->getBehaviorController(),
&lrc::api::BehaviorController::newUnreadInteraction,
[this] (const std::string& accountId, const std::string& conversation,
uint64_t interactionId, const lrc::api::interaction::Info& interaction)
{ slotNewInteraction(accountId, conversation, interactionId, interaction); });
slotReadInteraction_ = QObject::connect(&lrc_->getBehaviorController(),
&lrc::api::BehaviorController::newReadInteraction,
[this] (const std::string& accountId, const std::string& conversation, uint64_t interactionId)
{ slotCloseInteraction(accountId, conversation, interactionId); });
const gchar *text = gtk_entry_get_text(GTK_ENTRY(widgets->search_entry));
currentTypeFilter_ = accountInfo_->profileInfo.type;
......@@ -1561,6 +1767,78 @@ CppImpl::slotModelSorted()
refreshPendingContactRequestTab();
}
void
CppImpl::slotCallStatusChanged(const std::string& callId)
{
if (!accountInfo_) {
return;
}
try {
auto call = accountInfo_->callModel->getCall(callId);
auto peer = call.peer;
if (accountInfo_->profileInfo.type == lrc::api::profile::Type::RING && peer.find("ring:") == 0) {
peer = peer.substr(5);
}
auto& contactModel = accountInfo_->contactModel;
std::string notifId = "";
try {
notifId = accountInfo_->id + ":call:" + callId;
} catch (...) {
g_warning("Can't get contact for account %s. Don't show notification", accountInfo_->id.c_str());
return;
}
if (call.status == lrc::api::call::Status::IN_PROGRESS
|| call.status == lrc::api::call::Status::ENDED) {
// Call ended, close the notification
ring_hide_notification(RING_NOTIFIER(widgets->notifier), notifId);
}
} catch (const std::exception& e) {
g_warning("Can't get call %lu for this account.", callId);
}
}
void
CppImpl::slotNewIncomingCall(const std::string& callId)
{
if (!accountInfo_) {
return;
}
try {
auto call = accountInfo_->callModel->getCall(callId);
auto peer = call.peer;
if (accountInfo_->profileInfo.type == lrc::api::profile::Type::RING && peer.find("ring:") == 0) {
peer = peer.substr(5);
}
auto& contactModel = accountInfo_->contactModel;
std::string avatar = "", name = "", notifId = "", uri = "";
try {
auto contactInfo = contactModel->getContact(peer);
uri = contactInfo.profileInfo.uri;
avatar = contactInfo.profileInfo.avatar;
name = contactInfo.profileInfo.alias;
if (name.empty()) {
name = contactInfo.registeredName;
if (name.empty()) {
name = contactInfo.profileInfo.uri;
}
}
notifId = accountInfo_->id + ":call:" + callId;
} catch (...) {
g_warning("Can't get contact for account %s. Don't show notification", accountInfo_->id.c_str());
return;
}
if (g_settings_get_boolean(widgets->settings, "enable-call-notifications")) {
name.erase(std::remove(name.begin(), name.end(), '\r'), name.end());
auto body = name + _(" is calling you!");
ring_show_notification(RING_NOTIFIER(widgets->notifier), avatar, uri, name, notifId, _("Incoming call"), body, NotificationType::CALL);
}
} catch (const std::exception& e) {
g_warning("Can't get call %lu for this account.", callId);
}
}
void
CppImpl::slotFilterChanged()
{
......@@ -1674,10 +1952,119 @@ CppImpl::slotShowCallView(const std::string& id, lrc::api::conversation::Info or
changeView(CURRENT_CALL_VIEW_TYPE, origin);
}
void
CppImpl::slotNewTrustRequest(const std::string& id, const std::string& contactUri)
{
try {
auto& accountInfo = lrc_->getAccountModel().getAccountInfo(id);
auto notifId = accountInfo.id + ":request:" + contactUri;
std::string avatar = "", name = "", uri = "";
auto& contactModel = accountInfo.contactModel;
try {
auto contactInfo = contactModel->getContact(contactUri);
uri = contactInfo.profileInfo.uri;
avatar = contactInfo.profileInfo.avatar;
name = contactInfo.profileInfo.alias;
if (name.empty()) {
name = contactInfo.registeredName;
if (name.empty()) {
name = contactInfo.profileInfo.uri;
}
}
} catch (...) {
g_warning("Can't get contact for account %s. Don't show notification", accountInfo.id.c_str());
return;
}
if (g_settings_get_boolean(widgets->settings, "enable-pending-notifications")) {