mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-13 20:15:23 +02:00
notifications: add avatars to gnu/linux notifications
Gitlab: #320 Change-Id: Ib2121257af2704dd2a246b499961657b66ae944d
This commit is contained in:
parent
2cc82053c9
commit
7f28ac65df
7 changed files with 57 additions and 14 deletions
|
@ -140,6 +140,8 @@ pkg_check_modules(LIBNOTIFY libnotify>=0.7.6)
|
|||
if(LIBNOTIFY_FOUND)
|
||||
add_definitions(-DUSE_LIBNOTIFY)
|
||||
add_definitions(${LIBNOTIFY_CFLAGS})
|
||||
pkg_check_modules(LIBGDKPIXBUF gdk-pixbuf-2.0>=2.40.0)
|
||||
add_definitions(${LIBGDKPIXBUF_CFLAGS})
|
||||
endif()
|
||||
|
||||
if(QT5_VER AND QT5_PATH)
|
||||
|
@ -217,7 +219,8 @@ include_directories(${PROJECT_SOURCE_DIR}
|
|||
${SRC_DIR}
|
||||
${LRC_SRC_PATH}
|
||||
${LIBNM_INCLUDE_DIRS}
|
||||
${LIBNOTIFY_INCLUDE_DIRS})
|
||||
${LIBNOTIFY_INCLUDE_DIRS}
|
||||
${LIBGDKPIXBUF_INCLUDE_DIRS})
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
${SRC_DIR}/main.cpp
|
||||
|
@ -239,7 +242,8 @@ target_link_libraries(jami-qt
|
|||
${qrencode}
|
||||
${X11}
|
||||
${LIBNM_LIBRARIES}
|
||||
${LIBNOTIFY_LIBRARIES})
|
||||
${LIBNOTIFY_LIBRARIES}
|
||||
${LIBGDKPIXBUF_LIBRARIES})
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
message("Add Jami tests")
|
||||
|
|
|
@ -102,13 +102,19 @@ CallAdapter::onCallStatusChanged(const QString& accountId, const QString& callId
|
|||
if (systemTray_->hideNotification(QString("%1;%2").arg(accountId).arg(convInfo.uid))
|
||||
&& call.startTime.time_since_epoch().count() == 0) {
|
||||
// This was a missed call; show a missed call notification
|
||||
// TODO: swarmify(avoid using convInfo.participants[0])
|
||||
auto contactPhoto = Utils::contactPhoto(lrcInstance_,
|
||||
convInfo.participants[0],
|
||||
QSize(50, 50),
|
||||
accountId);
|
||||
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
||||
auto from = accInfo.contactModel->bestNameForContact(convInfo.participants[0]);
|
||||
auto notifId = QString("%1;%2").arg(accountId).arg(convInfo.uid);
|
||||
systemTray_->showNotification(notifId,
|
||||
tr("Missed call"),
|
||||
tr("Missed call from %1").arg(from),
|
||||
NotificationType::CHAT);
|
||||
NotificationType::CHAT,
|
||||
Utils::QImageToByteArray(contactPhoto));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -384,11 +390,16 @@ CallAdapter::showNotification(const QString& accountId, const QString& convUid)
|
|||
Q_EMIT lrcInstance_->updateSmartList();
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
auto contactPhoto = Utils::contactPhoto(lrcInstance_,
|
||||
convInfo.participants[0],
|
||||
QSize(50, 50),
|
||||
accountId);
|
||||
auto notifId = QString("%1;%2").arg(accountId).arg(convUid);
|
||||
systemTray_->showNotification(notifId,
|
||||
tr("Incoming call"),
|
||||
tr("%1 is calling you").arg(from),
|
||||
NotificationType::CALL);
|
||||
NotificationType::CALL,
|
||||
Utils::QImageToByteArray(contactPhoto));
|
||||
#else
|
||||
auto onClicked = [this, accountId, convUid = convInfo.uid]() {
|
||||
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
|
||||
|
|
|
@ -171,14 +171,19 @@ ConversationsAdapter::onNewUnreadInteraction(const QString& accountId,
|
|||
if (!interaction.authorUri.isEmpty()
|
||||
&& (!QApplication::focusWindow() || accountId != lrcInstance_->getCurrAccId()
|
||||
|| convUid != lrcInstance_->getCurrentConvUid())) {
|
||||
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
||||
auto from = accInfo.contactModel->bestNameForContact(interaction.authorUri);
|
||||
auto& accountInfo = lrcInstance_->getAccountInfo(accountId);
|
||||
auto from = accountInfo.contactModel->bestNameForContact(interaction.authorUri);
|
||||
#ifdef Q_OS_LINUX
|
||||
auto contactPhoto = Utils::contactPhoto(lrcInstance_,
|
||||
interaction.authorUri,
|
||||
QSize(50, 50),
|
||||
accountId);
|
||||
auto notifId = QString("%1;%2;%3").arg(accountId).arg(convUid).arg(interactionId);
|
||||
systemTray_->showNotification(notifId,
|
||||
tr("New message"),
|
||||
from + ": " + interaction.body,
|
||||
NotificationType::CHAT);
|
||||
NotificationType::CHAT,
|
||||
Utils::QImageToByteArray(contactPhoto));
|
||||
|
||||
#else
|
||||
Q_UNUSED(interactionId)
|
||||
|
@ -215,11 +220,13 @@ ConversationsAdapter::onNewTrustRequest(const QString& accountId, const QString&
|
|||
if (!QApplication::focusWindow() || accountId != lrcInstance_->getCurrAccId()) {
|
||||
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
||||
auto from = accInfo.contactModel->bestNameForContact(peerUri);
|
||||
auto contactPhoto = Utils::contactPhoto(lrcInstance_, peerUri, QSize(50, 50), accountId);
|
||||
auto notifId = QString("%1;%2").arg(accountId).arg(peerUri);
|
||||
systemTray_->showNotification(notifId,
|
||||
tr("Trust request"),
|
||||
"New request from " + from,
|
||||
NotificationType::REQUEST);
|
||||
NotificationType::REQUEST,
|
||||
Utils::QImageToByteArray(contactPhoto));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -167,7 +167,8 @@ void
|
|||
SystemTray::showNotification(const QString& id,
|
||||
const QString& title,
|
||||
const QString& body,
|
||||
NotificationType type)
|
||||
NotificationType type,
|
||||
const QByteArray& avatar)
|
||||
{
|
||||
if (!settingsManager_->getValue(Settings::Key::EnableNotifications).toBool())
|
||||
return;
|
||||
|
@ -184,7 +185,16 @@ SystemTray::showNotification(const QString& id,
|
|||
|
||||
pimpl_->notifications.emplace(id, n);
|
||||
|
||||
// TODO: notify_notification_set_image_from_pixbuf <- GdkPixbuf
|
||||
if (!avatar.isEmpty()) {
|
||||
GError* error = nullptr;
|
||||
GdkPixbuf* pixbuf = nullptr;
|
||||
GInputStream* stream = nullptr;
|
||||
stream = g_memory_input_stream_new_from_data(avatar.constData(), avatar.size(), NULL);
|
||||
pixbuf = gdk_pixbuf_new_from_stream(stream, nullptr, &error);
|
||||
g_input_stream_close(stream, nullptr, nullptr);
|
||||
g_object_unref(stream);
|
||||
notify_notification_set_image_from_pixbuf(notification.get(), pixbuf);
|
||||
}
|
||||
|
||||
if (type != NotificationType::CHAT) {
|
||||
notify_notification_set_urgency(notification.get(), NOTIFY_URGENCY_CRITICAL);
|
||||
|
|
|
@ -42,7 +42,8 @@ public:
|
|||
void showNotification(const QString& id,
|
||||
const QString& title,
|
||||
const QString& body,
|
||||
NotificationType type);
|
||||
NotificationType type,
|
||||
const QByteArray& avatar = {});
|
||||
|
||||
Q_SIGNALS:
|
||||
void openConversationActivated(const QString& accountId, const QString& convUid);
|
||||
|
|
|
@ -68,6 +68,7 @@ Utils::CreateStartupLink(const std::wstring& wstrAppName)
|
|||
|
||||
return Utils::CreateLink(programPath.c_str(), linkPath.c_str());
|
||||
#else
|
||||
Q_UNUSED(wstrAppName)
|
||||
QString desktopPath;
|
||||
/* cmake should set JAMI_INSTALL_PREFIX, otherwise it checks the following dirs
|
||||
* - /usr/<data dir>
|
||||
|
@ -179,6 +180,7 @@ Utils::DeleteStartupLink(const std::wstring& wstrAppName)
|
|||
DeleteFile(linkPath.c_str());
|
||||
|
||||
#else
|
||||
Q_UNUSED(wstrAppName)
|
||||
QString desktopFile = QStandardPaths::locate(QStandardPaths::ConfigLocation,
|
||||
"autostart/jami-qt.desktop");
|
||||
if (!desktopFile.isEmpty()) {
|
||||
|
@ -205,6 +207,7 @@ Utils::CheckStartupLink(const std::wstring& wstrAppName)
|
|||
linkPath += std::wstring(TEXT("\\") + wstrAppName + TEXT(".lnk"));
|
||||
return PathFileExists(linkPath.c_str());
|
||||
#else
|
||||
Q_UNUSED(wstrAppName)
|
||||
return (!QStandardPaths::locate(QStandardPaths::ConfigLocation, "autostart/jami-qt.desktop")
|
||||
.isEmpty());
|
||||
#endif
|
||||
|
@ -222,6 +225,7 @@ Utils::WinGetEnv(const char* name)
|
|||
return 0;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(name)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -321,7 +325,10 @@ Utils::GetISODate()
|
|||
}
|
||||
|
||||
QImage
|
||||
Utils::contactPhoto(LRCInstance* instance, const QString& contactUri, const QSize& size)
|
||||
Utils::contactPhoto(LRCInstance* instance,
|
||||
const QString& contactUri,
|
||||
const QSize& size,
|
||||
const QString& accountId)
|
||||
{
|
||||
QImage photo;
|
||||
|
||||
|
@ -329,7 +336,8 @@ Utils::contactPhoto(LRCInstance* instance, const QString& contactUri, const QSiz
|
|||
/*
|
||||
* Get first contact photo.
|
||||
*/
|
||||
auto& accountInfo = instance->accountModel().getAccountInfo(instance->getCurrAccId());
|
||||
auto& accountInfo = instance->accountModel().getAccountInfo(
|
||||
accountId.isEmpty() ? instance->getCurrAccId() : accountId);
|
||||
auto contactInfo = accountInfo.contactModel->getContact(contactUri);
|
||||
auto contactPhoto = contactInfo.profileInfo.avatar;
|
||||
auto bestName = accountInfo.contactModel->bestNameForContact(contactUri);
|
||||
|
@ -405,6 +413,7 @@ Utils::getRealSize(QScreen* screen)
|
|||
(DEVMODE*) &dmThisScreen);
|
||||
return QSize(dmThisScreen.dmPelsWidth, dmThisScreen.dmPelsHeight);
|
||||
#else
|
||||
Q_UNUSED(screen)
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -84,7 +84,8 @@ static const QSize defaultAvatarSize {128, 128};
|
|||
QImage contactPhotoFromBase64(const QByteArray& data, const QString& type);
|
||||
QImage contactPhoto(LRCInstance* instance,
|
||||
const QString& contactUri,
|
||||
const QSize& size = defaultAvatarSize);
|
||||
const QSize& size = defaultAvatarSize,
|
||||
const QString& accountId = {});
|
||||
QImage getCirclePhoto(const QImage original, int sizePhoto);
|
||||
QColor getAvatarColor(const QString& canonicalUri);
|
||||
QImage fallbackAvatar(const QString& canonicalUriStr,
|
||||
|
|
Loading…
Add table
Reference in a new issue