Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'master' into 'master'
[commhistoryd] Improve notifications for IM. Contributes to MER#2067

See merge request mer-core/commhistory-daemon!31
  • Loading branch information
llewelld committed Sep 24, 2020
2 parents 3a97a31 + 1a0628e commit 3669b0f
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 53 deletions.
2 changes: 1 addition & 1 deletion rpm/commhistory-daemon.spec
Expand Up @@ -14,7 +14,7 @@ BuildRequires: pkgconfig(Qt5Test)
BuildRequires: pkgconfig(commhistory-qt5) >= 1.10.2
BuildRequires: pkgconfig(contactcache-qt5)
BuildRequires: pkgconfig(qtcontacts-sqlite-qt5-extensions)
BuildRequires: pkgconfig(TelepathyQt5)
BuildRequires: pkgconfig(TelepathyQt5) >= 0.9.8
BuildRequires: pkgconfig(mlite5)
BuildRequires: pkgconfig(mlocale5)
BuildRequires: pkgconfig(mce)
Expand Down
21 changes: 16 additions & 5 deletions src/textchannellistener.cpp
Expand Up @@ -635,6 +635,8 @@ void TextChannelListener::handleMessages()
// Normal sms
} else {
QString supersedes = supersedesToken(message.header());
bool silent = message.isSilent();

if (!supersedes.isEmpty()) {
CommHistory::Event originalEvent;
getEventForToken(supersedes, QString(), m_Group.id(), originalEvent);
Expand All @@ -645,7 +647,9 @@ void TextChannelListener::handleMessages()
event.setMessageToken(supersedes);
addEvents << event;
addMessages << message;
nManager->showNotification(event, targetId(), m_Group.chatType());
if (!silent) {
nManager->showNotification(event, targetId(), m_Group.chatType());
}
} else {
//update message
originalEvent.setFreeText(event.freeText());
Expand All @@ -657,10 +661,11 @@ void TextChannelListener::handleMessages()
modifyMessages[event.groupId()] << message;
modifyTokens[event.groupId()].insertMulti(originalEvent.id(),originalEvent.messageToken());

nManager->showNotification(originalEvent, targetId(), m_Group.chatType());
if (!silent) {
nManager->showNotification(originalEvent, targetId(), m_Group.chatType());
}
}
}
else {
} else {
if (message.isScrollback()) {
scrollbackEvents << event;
} else {
Expand All @@ -669,7 +674,9 @@ void TextChannelListener::handleMessages()
addMessages << message;

if (event.direction() != CommHistory::Event::Outbound) {
nManager->showNotification(event, targetId(), m_Group.chatType());
if (!silent) {
nManager->showNotification(event, targetId(), m_Group.chatType());
}
}
}
}
Expand Down Expand Up @@ -1205,6 +1212,10 @@ void TextChannelListener::handleReceivedMessage(const Tp::ReceivedMessage &messa
event.setDirection(CommHistory::Event::Inbound);
}

Tp::DeliveryStatus deliveryStatus = message.deliveryDetails().status();
if (deliveryStatus == Tp::DeliveryStatusRead)
event.setIsRead(true);

QDateTime receivedTime;
if (message.received().isValid())
receivedTime = message.received();
Expand Down
188 changes: 141 additions & 47 deletions tests/stubs/TelepathyQt/message.cpp
Expand Up @@ -29,69 +29,67 @@
namespace Tp
{

struct Message::Private : public QSharedData
{
Private(const MessagePartList &parts);
~Private();

MessagePartList parts;

ContactPtr sender;

inline QVariant value(uint index, const char *key) const;
inline uint getUIntOrZero(uint index, const char *key) const;
inline QString getStringOrEmpty(uint index, const char *key) const;
inline bool getBoolean(uint index, const char *key,
bool assumeIfAbsent) const;
inline uint senderHandle() const;
inline uint pendingId() const;
void clearSenderHandle();
};

Message::Private::Private(const MessagePartList &parts)
: parts(parts),
sender(0)
namespace
{
}

Message::Private::~Private()
QVariant valueFromPart(const MessagePartList &parts, uint index, const char *key)
{
return parts.at(index).value(QLatin1String(key)).variant();
}

inline QVariant Message::Private::value(uint index, const char *key) const
uint uintOrZeroFromPart(const MessagePartList &parts, uint index, const char *key)
{
return parts.at(index).value(QLatin1String(key)).variant();
return valueFromPart(parts, index, key).toUInt();
}

inline QString Message::Private::getStringOrEmpty(uint index, const char *key)
const
QString stringOrEmptyFromPart(const MessagePartList &parts, uint index, const char *key)
{
QString s = value(index, key).toString();
QString s = valueFromPart(parts, index, key).toString();
if (s.isNull()) {
s = QLatin1String("");
}
return s;
}

inline uint Message::Private::getUIntOrZero(uint index, const char *key)
const
{
return value(index, key).toUInt();
}

inline bool Message::Private::getBoolean(uint index, const char *key,
bool assumeIfAbsent) const
bool booleanFromPart(const MessagePartList &parts, uint index, const char *key,
bool assumeIfAbsent)
{
QVariant v = value(index, key);
QVariant v = valueFromPart(parts, index, key);
if (v.isValid() && v.type() == QVariant::Bool) {
return v.toBool();
}
return assumeIfAbsent;
}

}

struct Message::Private : public QSharedData
{
Private(const MessagePartList &parts);
~Private();

uint senderHandle() const;
uint pendingId() const;
void clearSenderHandle();

MessagePartList parts;

ContactPtr sender;
};

Message::Private::Private(const MessagePartList &parts)
: parts(parts),
sender(0)
{
}

Message::Private::~Private()
{
}

inline uint Message::Private::senderHandle() const
{
return getUIntOrZero(0, "message-sender");
return uintOrZeroFromPart(parts, 0, "message-sender");
}

/**
Expand Down Expand Up @@ -203,7 +201,7 @@ Message::~Message()
QDateTime Message::sent() const
{
// FIXME See http://bugs.freedesktop.org/show_bug.cgi?id=21690
uint stamp = mPriv->value(0, "message-sent").toUInt();
uint stamp = valueFromPart(mPriv->parts, 0, "message-sent").toUInt();
if (stamp != 0) {
return QDateTime::fromTime_t(stamp);
} else {
Expand All @@ -219,7 +217,7 @@ QDateTime Message::sent() const
*/
ChannelTextMessageType Message::messageType() const
{
uint raw = mPriv->value(0, "message-type").toUInt();
uint raw = valueFromPart(mPriv->parts, 0, "message-type").toUInt();

if (raw < static_cast<uint>(NUM_CHANNEL_TEXT_MESSAGE_TYPES)) {
return ChannelTextMessageType(raw);
Expand All @@ -236,7 +234,7 @@ ChannelTextMessageType Message::messageType() const
*/
QString Message::messageToken() const
{
return mPriv->getStringOrEmpty(0, "message-token");
return stringOrEmptyFromPart(mPriv->parts, 0, "message-token");
}

QString Message::text() const
Expand All @@ -246,8 +244,8 @@ QString Message::text() const
QString text;

for (int i = 1; i < size(); i++) {
QString altGroup = mPriv->getStringOrEmpty(i, "alternative");
QString contentType = mPriv->getStringOrEmpty(i, "content-type");
QString altGroup = stringOrEmptyFromPart(mPriv->parts, i, "alternative");
QString contentType = stringOrEmptyFromPart(mPriv->parts, i, "content-type");

if (contentType == QLatin1String("text/plain")) {
if (!altGroup.isEmpty()) {
Expand All @@ -258,7 +256,7 @@ QString Message::text() const
}
}

QVariant content = mPriv->value(i, "content");
QVariant content = valueFromPart(mPriv->parts, i, "content");
if (content.type() == QVariant::String) {
text += content.toString();
} else {
Expand Down Expand Up @@ -328,6 +326,79 @@ MessagePart& Message::ut_part(uint index)
* available on received messages.
*/

/**
* \class ReceivedMessage::DeliveryDetails
* \ingroup clientchannel
* \headerfile TelepathyQt/message.h <TelepathyQt/ReceivedMessage>
*
* \brief The ReceivedMessage::DeliveryDetails class represents the details of a delivery report.
*/

struct ReceivedMessage::DeliveryDetails::Private : public QSharedData
{
Private(const MessagePartList &parts)
: parts(parts)
{
}

MessagePartList parts;
};

/**
* Default constructor.
*/
ReceivedMessage::DeliveryDetails::DeliveryDetails()
{
}

/**
* Copy constructor.
*/
ReceivedMessage::DeliveryDetails::DeliveryDetails(const DeliveryDetails &other)
: mPriv(other.mPriv)
{
}

/**
* Construct a new ReceivedMessage::DeliveryDetails object.
*
* \param The message parts.
*/
ReceivedMessage::DeliveryDetails::DeliveryDetails(const MessagePartList &parts)
: mPriv(new Private(parts))
{
}

/**
* Class destructor.
*/
ReceivedMessage::DeliveryDetails::~DeliveryDetails()
{
}

/**
* Assignment operator.
*/
ReceivedMessage::DeliveryDetails &ReceivedMessage::DeliveryDetails::operator=(
const DeliveryDetails &other)
{
this->mPriv = other.mPriv;
return *this;
}

/**
* Return the delivery status of a message.
*
* \return The delivery status as #DeliveryStatus.
*/
DeliveryStatus ReceivedMessage::DeliveryDetails::status() const
{
if (!isValid()) {
return DeliveryStatusUnknown;
}
return static_cast<DeliveryStatus>(uintOrZeroFromPart(mPriv->parts, 0, "delivery-status"));
}

/**
* Default constructor, only used internally.
*/
Expand Down Expand Up @@ -386,7 +457,7 @@ ReceivedMessage::~ReceivedMessage()
QDateTime ReceivedMessage::received() const
{
// FIXME See http://bugs.freedesktop.org/show_bug.cgi?id=21690
uint stamp = mPriv->value(0, "message-received").toUInt();
uint stamp = valueFromPart(mPriv->parts, 0, "message-received").toUInt();
if (stamp != 0) {
return QDateTime::fromTime_t(stamp);
} else {
Expand Down Expand Up @@ -417,7 +488,30 @@ ContactPtr ReceivedMessage::sender() const
*/
bool ReceivedMessage::isScrollback() const
{
return mPriv->getBoolean(0, "scrollback", false);
return booleanFromPart(mPriv->parts, 0, "scrollback", false);
}

/**
* Return whether the incoming message should trigger a user notification.
*
* If \c true, UI should not notify the user about this message.
*
* \return \c true if the silent flag is set, \c false otherwise.
*/
bool ReceivedMessage::isSilent() const
{
return booleanFromPart(mPriv->parts, 0, "silent", false);
}

/**
* Return the details of a delivery report.
*
* \return The delivery report as a ReceivedMessage::DeliveryDetails object.
* \sa isDeliveryReport()
*/
ReceivedMessage::DeliveryDetails ReceivedMessage::deliveryDetails() const
{
return DeliveryDetails(parts());
}

void ReceivedMessage::ut_setSender(const ContactPtr& sender)
Expand Down
26 changes: 26 additions & 0 deletions tests/stubs/TelepathyQt/message.h
Expand Up @@ -86,6 +86,29 @@ class Message
class ReceivedMessage : public Message
{
public:
class DeliveryDetails
{
public:
DeliveryDetails();
DeliveryDetails(const DeliveryDetails &other);
~DeliveryDetails();

DeliveryDetails &operator=(const DeliveryDetails &other);

bool isValid() const { return mPriv.constData() != nullptr; }

DeliveryStatus status() const;

private:
friend class ReceivedMessage;

DeliveryDetails(const MessagePartList &parts);

struct Private;
friend struct Private;
QSharedDataPointer<Private> mPriv;
};

ReceivedMessage(const MessagePartList &parts);
ReceivedMessage();

Expand All @@ -96,6 +119,9 @@ class ReceivedMessage : public Message
QDateTime received() const;
ContactPtr sender() const;
bool isScrollback() const;
bool isSilent() const;

DeliveryDetails deliveryDetails() const;

public: //ut
void ut_setSender(const ContactPtr& sender);
Expand Down
4 changes: 4 additions & 0 deletions tests/stubs/TelepathyQt/referenced-handles.cpp
Expand Up @@ -182,7 +182,11 @@ bool ReferencedHandles::removeOne(uint handle)

void ReferencedHandles::swap(int i, int j)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
mPriv->handles.swapItemsAt(i, j);
#else
mPriv->handles.swap(i, j);
#endif
}

uint ReferencedHandles::takeAt(int i)
Expand Down

0 comments on commit 3669b0f

Please sign in to comment.