diff --git a/src/conversationsview.cpp b/src/conversationsview.cpp index 54504ca3684260bf28f0dc087525b8cb32047290..0733fefe9699004b6962d303e77de974b09906a1 100644 --- a/src/conversationsview.cpp +++ b/src/conversationsview.cpp @@ -87,14 +87,14 @@ render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column, { // Draw first contact. // NOTE: We just draw the first contact, must change this for conferences when they will have their own object - auto conversation = priv->accountContainer_->info.conversationModel->filteredConversation(row); - auto contact = priv->accountContainer_->info.contactModel->getContact(conversation.participants.front()); + auto conversationInfo = priv->accountContainer_->info.conversationModel->filteredConversation(row); + auto contactInfo = priv->accountContainer_->info.contactModel->getContact(conversationInfo.participants.front()); std::shared_ptr<GdkPixbuf> image; auto var_photo = GlobalInstances::pixmapManipulator().conversationPhoto( - conversation, + conversationInfo, priv->accountContainer_->info, QSize(50, 50), - contact.isPresent + contactInfo.isPresent ); image = var_photo.value<std::shared_ptr<GdkPixbuf>>(); diff --git a/src/native/pixbufmanipulator.cpp b/src/native/pixbufmanipulator.cpp index a57d64628c4bcc8f8235ba5460a74fee7bac2438..04c392ebddfff52f5a90b63119bec0d30dad989c 100644 --- a/src/native/pixbufmanipulator.cpp +++ b/src/native/pixbufmanipulator.cpp @@ -122,7 +122,11 @@ PixbufManipulator::generateAvatar(const std::string& alias, const std::string& u } std::shared_ptr<GdkPixbuf> -PixbufManipulator::scaleAndFrame(const GdkPixbuf *photo, const QSize& size, bool display_presence, bool is_present) +PixbufManipulator::scaleAndFrame(const GdkPixbuf *photo, + const QSize& size, + bool display_presence, + bool is_present, + uint unreadMessages) { /** * for now, respect the height requested @@ -158,6 +162,10 @@ PixbufManipulator::scaleAndFrame(const GdkPixbuf *photo, const QSize& size, bool if (display_presence) result.reset(ring_draw_presence(result.get(), is_present), g_object_unref); + /* draw visual notification for unread messages */ + if (unreadMessages) + result.reset(ring_draw_unread_messages(result.get(), unreadMessages), g_object_unref); + return result; } @@ -255,12 +263,12 @@ QVariant PixbufManipulator::personPhoto(const QByteArray& data, const QString& t } QVariant -PixbufManipulator::conversationPhoto(const lrc::api::conversation::Info& conversation, +PixbufManipulator::conversationPhoto(const lrc::api::conversation::Info& conversationInfo, const lrc::api::account::Info& accountInfo, const QSize& size, bool displayPresence) { - auto contacts = conversation.participants; + auto contacts = conversationInfo.participants; if (!contacts.empty()) { // Get first contact photo @@ -268,16 +276,17 @@ PixbufManipulator::conversationPhoto(const lrc::api::conversation::Info& convers auto contactInfo = accountInfo.contactModel->getContact(contactUri); auto contactPhoto = contactInfo.profileInfo.avatar; auto bestName = contactInfo.profileInfo.alias.empty()? contactInfo.registeredName : contactInfo.profileInfo.alias; + auto unreadMessages = conversationInfo.unreadMessages; if (contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY && contactInfo.profileInfo.uri.empty()) { - return QVariant::fromValue(scaleAndFrame(temporaryItemAvatar().get(), size, false, false)); + return QVariant::fromValue(scaleAndFrame(temporaryItemAvatar().get(), size, false, false, unreadMessages)); } else if (contactInfo.profileInfo.type == lrc::api::profile::Type::SIP) { return QVariant::fromValue(scaleAndFrame(generateAvatar(bestName, "").get(), size, displayPresence, contactInfo.isPresent)); } else if (!contactPhoto.empty()) { QByteArray byteArray(contactPhoto.c_str(), contactPhoto.length()); QVariant photo = personPhoto(byteArray); - return QVariant::fromValue(scaleAndFrame(photo.value<std::shared_ptr<GdkPixbuf>>().get(), size, displayPresence, contactInfo.isPresent)); + return QVariant::fromValue(scaleAndFrame(photo.value<std::shared_ptr<GdkPixbuf>>().get(), size, displayPresence, contactInfo.isPresent, unreadMessages)); } else { - return QVariant::fromValue(scaleAndFrame(generateAvatar(bestName, contactInfo.profileInfo.uri).get(), size, displayPresence, contactInfo.isPresent)); + return QVariant::fromValue(scaleAndFrame(generateAvatar(bestName, contactInfo.profileInfo.uri).get(), size, displayPresence, contactInfo.isPresent, unreadMessages)); } } // should not diff --git a/src/native/pixbufmanipulator.h b/src/native/pixbufmanipulator.h index 3aa6a65c892d7cda7015f382ad58edb9deeb9879..0760e024e13243d1bc0676460466a1b8e91b15ba 100644 --- a/src/native/pixbufmanipulator.h +++ b/src/native/pixbufmanipulator.h @@ -68,7 +68,7 @@ private: std::shared_ptr<GdkPixbuf> generateAvatar(const ContactMethod* cm) const; std::shared_ptr<GdkPixbuf> generateAvatar(const std::string& alias, const std::string& uri) const; - std::shared_ptr<GdkPixbuf> scaleAndFrame(const GdkPixbuf *photo, const QSize& size, bool display_presence = false, bool is_present = false); + std::shared_ptr<GdkPixbuf> scaleAndFrame(const GdkPixbuf *photo, const QSize& size, bool display_presence = false, bool is_present = false, uint unreadMessages = 0); std::shared_ptr<GdkPixbuf> conferenceAvatar_; }; diff --git a/src/utils/drawing.cpp b/src/utils/drawing.cpp index f4bd4f8809360d3aaab7ddaac47c9a31013e0941..99e653be348001f646d8eaeb802abee9328da3f1 100644 --- a/src/utils/drawing.cpp +++ b/src/utils/drawing.cpp @@ -26,7 +26,7 @@ static constexpr const char* MSG_COUNT_FONT = "Sans"; static constexpr int MSG_COUNT_FONT_SIZE = 12; static constexpr GdkRGBA MSG_COUNT_FONT_COLOUR = {1.0, 1.0, 1.0, 1.0}; // white -static constexpr GdkRGBA MSG_COUNT_BACKGROUND = {0.984, 0.282, 0.278, 0.9}; // red 251, 72, 71, 0.9 +static constexpr GdkRGBA MSG_COUNT_BACKGROUND = {0.984, 0.282, 0.278, 1.0}; // red 251, 72, 71, 1.0 static constexpr GdkRGBA PRESENCE_PRESENT_BACKGROUND = {0, 0.4156827, 0.8, 1.0}; // green 112, 217, 6, 0.9 static constexpr GdkRGBA PRESENCE_ABSENT_BACKGROUND = {0.984, 0.282, 0.278, 1.0}; // red 251, 72, 71, 0.9 // This is the color palette for default avatars @@ -263,7 +263,7 @@ ring_draw_unread_messages(const GdkPixbuf *avatar, int unread_count) { cairo_paint(cr); /* make text */ - char *text = g_strdup_printf("%d", unread_count); + char *text = g_strdup_printf("%s", unread_count > 9 ? "9+" : std::to_string(unread_count).c_str()); cairo_text_extents_t extents; cairo_select_font_face (cr, MSG_COUNT_FONT, @@ -277,16 +277,18 @@ ring_draw_unread_messages(const GdkPixbuf *avatar, int unread_count) { * ie: 6 pixels higher, 6 pixels wider */ int border_width = 3; double rec_x = w - extents.width - border_width * 2; - double rec_y = h - extents.height - border_width * 2; + double rec_y = 0; double rec_w = extents.width + border_width * 2; double rec_h = extents.height + border_width * 2; double corner_radius = rec_h/2.5; create_rounded_rectangle_path(cr, corner_radius, rec_x, rec_y, rec_w, rec_h); - cairo_set_source_rgba(cr, MSG_COUNT_BACKGROUND.red, MSG_COUNT_BACKGROUND.blue, MSG_COUNT_BACKGROUND.green, MSG_COUNT_BACKGROUND.alpha); + cairo_set_source_rgba(cr, + MSG_COUNT_BACKGROUND.red, + MSG_COUNT_BACKGROUND.blue, MSG_COUNT_BACKGROUND.green, MSG_COUNT_BACKGROUND.alpha); cairo_fill(cr); /* draw text */ - cairo_move_to (cr, w-extents.width-border_width, h-border_width); + cairo_move_to (cr, w - extents.width-border_width, extents.height + border_width ); cairo_set_source_rgb(cr, MSG_COUNT_FONT_COLOUR.red, MSG_COUNT_FONT_COLOUR.blue, MSG_COUNT_FONT_COLOUR.green); cairo_show_text (cr, text);