qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
notificationgenerator.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2020 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  qTox is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "notificationgenerator.h"
22 #include "util/display.h"
23 
24 #include <QCollator>
25 
26 namespace
27 {
28  size_t getNumMessages(
29  const QHash<const Friend*, size_t>& friendNotifications,
30  const QHash<const Group* , size_t>& groupNotifications)
31  {
32  auto numMessages = std::accumulate(friendNotifications.begin(), friendNotifications.end(), 0);
33  numMessages = std::accumulate(groupNotifications.begin(), groupNotifications.end(), numMessages);
34 
35  return numMessages;
36  }
37 
38  size_t getNumChats(
39  const QHash<const Friend*, size_t>& friendNotifications,
40  const QHash<const Group* , size_t>& groupNotifications)
41  {
42  return friendNotifications.size() + groupNotifications.size();
43  }
44 
45  QString generateMultiChatTitle(size_t numChats, size_t numMessages)
46  {
47  //: e.g. 3 messages from 2 chats
48  return QObject::tr("%1 message(s) from %2 chats")
49  .arg(numMessages)
50  .arg(numChats);
51  }
52 
53  template <typename T>
54  QString generateSingleChatTitle(
55  const QHash<T, size_t> numNotifications,
56  T contact)
57  {
58  if (numNotifications[contact] > 1)
59  {
60  //: e.g. 2 messages from Bob
61  return QObject::tr("%1 message(s) from %2")
62  .arg(numNotifications[contact])
63  .arg(contact->getDisplayedName());
64  }
65  else
66  {
67  return contact->getDisplayedName();
68  }
69  }
70 
71  QString generateTitle(
72  const QHash<const Friend*, size_t>& friendNotifications,
73  const QHash<const Group* , size_t>& groupNotifications,
74  const Friend* f)
75  {
76  auto numChats = getNumChats(friendNotifications, groupNotifications);
77  if (numChats > 1)
78  {
79  return generateMultiChatTitle(numChats, getNumMessages(friendNotifications, groupNotifications));
80  }
81  else
82  {
83  return generateSingleChatTitle(friendNotifications, f);
84  }
85  }
86 
87  QString generateTitle(
88  const QHash<const Friend*, size_t>& friendNotifications,
89  const QHash<const Group* , size_t>& groupNotifications,
90  const Group* g)
91  {
92  auto numChats = getNumChats(friendNotifications, groupNotifications);
93  if (numChats > 1)
94  {
95  return generateMultiChatTitle(numChats, getNumMessages(friendNotifications, groupNotifications));
96  }
97  else
98  {
99  return generateSingleChatTitle(groupNotifications, g);
100  }
101  }
102 
103  QString generateContent(
104  const QHash<const Friend*, size_t>& friendNotifications,
105  const QHash<const Group*, size_t>& groupNotifications,
106  QString lastMessage,
107  const ToxPk& sender)
108  {
109  assert(friendNotifications.size() > 0 || groupNotifications.size() > 0);
110 
111  auto numChats = getNumChats(friendNotifications, groupNotifications);
112  if (numChats > 1) {
113  // Copy all names into a vector to simplify formatting logic between
114  // multiple lists
115  std::vector<QString> displayNames;
116  displayNames.reserve(numChats);
117 
118  for (auto it = friendNotifications.begin(); it != friendNotifications.end(); ++it) {
119  displayNames.push_back(it.key()->getDisplayedName());
120  }
121 
122  for (auto it = groupNotifications.begin(); it != groupNotifications.end(); ++it) {
123  displayNames.push_back(it.key()->getDisplayedName());
124  }
125 
126  assert(displayNames.size() > 0);
127 
128  // Lexiographically sort all display names to ensure consistent formatting
129  QCollator collator;
130  std::sort(displayNames.begin(), displayNames.end(), [&] (const QString& a, const QString& b) {
131  return collator.compare(a, b) < 1;
132  });
133 
134  auto it = displayNames.begin();
135 
136  QString ret = *it;
137 
138  while (++it != displayNames.end()) {
139  ret += ", " + *it;
140  }
141 
142  return ret;
143  }
144  else {
145  if (groupNotifications.size() == 1) {
146  return groupNotifications.begin().key()->getPeerList()[sender] + ": " + lastMessage;
147  }
148 
149  return lastMessage;
150  }
151  }
152 
153  QPixmap getSenderAvatar(Profile* profile, const ToxPk& sender)
154  {
155  return profile ? profile->loadAvatar(sender) : QPixmap();
156  }
157 } // namespace
158 
160  INotificationSettings const& notificationSettings,
161  Profile* profile)
162  : notificationSettings(notificationSettings)
163  , profile(profile)
164 {}
165 
167 
169 {
170  friendNotifications[f]++;
171 
172  NotificationData ret;
173 
175  ret.title = tr("New message");
176  return ret;
177  }
178 
179  ret.title = generateTitle(friendNotifications, groupNotifications, f);
180  ret.message = generateContent(friendNotifications, groupNotifications, message, f->getPublicKey());
181  ret.pixmap = getSenderAvatar(profile, f->getPublicKey());
182 
183  return ret;
184 }
185 
186 NotificationData NotificationGenerator::groupMessageNotification(const Group* g, const ToxPk& sender, const QString& message)
187 {
188  groupNotifications[g]++;
189 
190  NotificationData ret;
191 
193  ret.title = tr("New group message");
194  return ret;
195  }
196 
197  ret.title = generateTitle(friendNotifications, groupNotifications, g);
198  ret.message = generateContent(friendNotifications, groupNotifications, message, sender);
199  ret.pixmap = getSenderAvatar(profile, sender);
200 
201  return ret;
202 }
203 
204 NotificationData NotificationGenerator::fileTransferNotification(const Friend* f, const QString& filename, size_t fileSize)
205 {
206  friendNotifications[f]++;
207 
208  NotificationData ret;
209 
211  ret.title = tr("Incoming file transfer");
212  return ret;
213  }
214 
215  auto numChats = getNumChats(friendNotifications, groupNotifications);
216  auto numMessages = getNumMessages(friendNotifications, groupNotifications);
217 
218  if (numChats > 1 || numMessages > 1)
219  {
220  ret.title = generateTitle(friendNotifications, groupNotifications, f);
221  ret.message = generateContent(friendNotifications, groupNotifications, tr("Incoming file transfer"), f->getPublicKey());
222  }
223  else
224  {
225  //: e.g. Bob - file transfer
226  ret.title = tr("%1 - file transfer").arg(f->getDisplayedName());
227  ret.message = filename + " (" + getHumanReadableSize(fileSize) + ")";
228  }
229 
230  ret.pixmap = getSenderAvatar(profile, f->getPublicKey());
231 
232  return ret;
233 }
234 
236 {
237  NotificationData ret;
238 
240  ret.title = tr("Group invite received");
241  return ret;
242  }
243 
244  ret.title = tr("%1 invites you to join a group.").arg(from->getDisplayedName());
245  ret.message = "";
246  ret.pixmap = getSenderAvatar(profile, from->getPublicKey());
247 
248  return ret;
249 }
250 
252 {
253  NotificationData ret;
254 
256  ret.title = tr("Friend request received");
257  return ret;
258  }
259 
260  ret.title = tr("Friend request received from %1").arg(sender.toString());
261  ret.message = message;
262 
263  return ret;
264 }
265 
267 {
268  friendNotifications = {};
269  groupNotifications = {};
270 }
NotificationData::pixmap
QPixmap pixmap
Definition: notificationdata.h:29
Profile
Handles all qTox internal paths.
Definition: profile.h:42
NotificationGenerator::onNotificationActivated
void onNotificationActivated()
Definition: notificationgenerator.cpp:266
notificationgenerator.h
Profile::loadAvatar
QPixmap loadAvatar()
Get our avatar from cache.
Definition: profile.cpp:556
NotificationGenerator::profile
Profile * profile
Definition: notificationgenerator.h:59
NotificationGenerator::groupInvitationNotification
NotificationData groupInvitationNotification(const Friend *from)
Definition: notificationgenerator.cpp:235
INotificationSettings::getNotifyHide
virtual bool getNotifyHide() const =0
NotificationData
Definition: notificationdata.h:25
NotificationGenerator::NotificationGenerator
NotificationGenerator(INotificationSettings const &notificationSettings, Profile *profile)
Definition: notificationgenerator.cpp:159
HistMessageContentType::message
@ message
filetransferwidget.h
ToxPk
This class represents a Tox Public Key, which is a part of Tox ID.
Definition: toxpk.h:26
Friend
Definition: friend.h:31
NotificationGenerator::friendNotifications
QHash< const Friend *, size_t > friendNotifications
Definition: notificationgenerator.h:60
QHash< const Friend *, size_t >
NotificationGenerator::friendMessageNotification
NotificationData friendMessageNotification(const Friend *f, const QString &message)
Definition: notificationgenerator.cpp:168
NotificationGenerator::notificationSettings
INotificationSettings const & notificationSettings
Definition: notificationgenerator.h:58
NotificationGenerator::friendRequestNotification
NotificationData friendRequestNotification(const ToxPk &sender, const QString &message)
Definition: notificationgenerator.cpp:251
Friend::getDisplayedName
QString getDisplayedName() const override
Friend::getDisplayedName Gets the name that should be displayed for a user.
Definition: friend.cpp:112
NotificationGenerator::~NotificationGenerator
virtual ~NotificationGenerator()
Group
Definition: group.h:34
NotificationData::message
QString message
Definition: notificationdata.h:28
NotificationData::title
QString title
Definition: notificationdata.h:27
FileTransferList::Column::contact
@ contact
Friend::getPublicKey
const ToxPk & getPublicKey() const
Definition: friend.cpp:131
NotificationGenerator::groupMessageNotification
NotificationData groupMessageNotification(const Group *g, const ToxPk &sender, const QString &message)
Definition: notificationgenerator.cpp:186
NotificationGenerator::fileTransferNotification
NotificationData fileTransferNotification(const Friend *f, const QString &filename, size_t fileSize)
Definition: notificationgenerator.cpp:204
NotificationGenerator::groupNotifications
QHash< const Group *, size_t > groupNotifications
Definition: notificationgenerator.h:61
ContactId::toString
QString toString() const
Converts the ContactId to a uppercase hex string.
Definition: contactid.cpp:78
INotificationSettings
Definition: inotificationsettings.h:24