diff --git a/ComunicMessages.pro b/ComunicMessages.pro index 96374cd..7fc6188 100644 --- a/ComunicMessages.pro +++ b/ComunicMessages.pro @@ -22,7 +22,10 @@ SOURCES += \ widgets/conversationitemwidget.cpp \ data/user.cpp \ helpers/usershelper.cpp \ - data/conversationslist.cpp + data/conversationslist.cpp \ + utils/uiutils.cpp \ + data/userslist.cpp \ + utils/timeutils.cpp HEADERS += \ helpers/accounthelper.h \ @@ -46,10 +49,16 @@ HEADERS += \ widgets/conversationitemwidget.h \ data/user.h \ helpers/usershelper.h \ - data/conversationslist.h + data/conversationslist.h \ + utils/uiutils.h \ + data/userslist.h \ + utils/timeutils.h FORMS += \ widgets/loginwidget.ui \ widgets/mainwindow.ui \ widgets/aboutthisappdialog.ui \ widgets/conversationitemwidget.ui + +RESOURCES += \ + res/ressources.qrc diff --git a/data/conversation.cpp b/data/conversation.cpp index f64d1e0..77843e1 100644 --- a/data/conversation.cpp +++ b/data/conversation.cpp @@ -1,4 +1,5 @@ #include "conversation.h" +#include "userslist.h" Conversation::Conversation() { diff --git a/data/conversationslist.cpp b/data/conversationslist.cpp index 31e8570..3e12ca0 100644 --- a/data/conversationslist.cpp +++ b/data/conversationslist.cpp @@ -15,3 +15,13 @@ QList ConversationsList::getAllMembersId() const } return members; } + +UsersList ConversationsList::getMembersInformation() const +{ + return mMembersInformation; +} + +void ConversationsList::setMembersInformation(const UsersList &membersInformation) +{ + mMembersInformation = membersInformation; +} diff --git a/data/conversationslist.h b/data/conversationslist.h index b07bef4..55e9976 100644 --- a/data/conversationslist.h +++ b/data/conversationslist.h @@ -10,6 +10,8 @@ #include #include "conversation.h" +#include "user.h" +#include "userslist.h" class ConversationsList : public QList { @@ -23,6 +25,14 @@ public: * @return The IDs of the conversations */ QList getAllMembersId() const; + + UsersList getMembersInformation() const; + void setMembersInformation(const UsersList &membersInformation); + +private: + + //Private fields + UsersList mMembersInformation; }; #endif // CONVERSATIONSLIST_H diff --git a/data/user.cpp b/data/user.cpp index f27310d..e49f181 100644 --- a/data/user.cpp +++ b/data/user.cpp @@ -35,6 +35,11 @@ void User::setLastName(const QString &lastName) mLastName = lastName; } +QString User::displayName() const +{ + return firstName() + " " + lastName(); +} + QString User::accountImage() const { return mAccountImage; diff --git a/data/user.h b/data/user.h index 1bb3db9..0ec602d 100644 --- a/data/user.h +++ b/data/user.h @@ -23,6 +23,11 @@ public: QString lastName() const; void setLastName(const QString &lastName); + /** + * Get and return display name of the user + */ + QString displayName() const; + QString accountImage() const; void setAccountImage(const QString &accountImage); diff --git a/data/userslist.cpp b/data/userslist.cpp new file mode 100644 index 0000000..97b3252 --- /dev/null +++ b/data/userslist.cpp @@ -0,0 +1,16 @@ +#include "userslist.h" + +UsersList::UsersList() : QList() +{ + +} + +User UsersList::get(int userID) const +{ + for(User user : *this) + if(user.iD() == userID) + return user; + + //User not found + return User(); +} diff --git a/data/userslist.h b/data/userslist.h new file mode 100644 index 0000000..842f699 --- /dev/null +++ b/data/userslist.h @@ -0,0 +1,31 @@ +/** + * A list of users + * + * Provides methods to fetch users + * + * @author Pierre HUBERT + */ + +#ifndef USERSLISTS_H +#define USERSLISTS_H + +#include + +#include "user.h" + +class UsersList : public QList +{ +public: + UsersList(); + + /** + * Find and return information about a user specified + * by its ID + * + * @param userID The ID of the target user + * @return Information about the user + */ + User get(int userID) const; +}; + +#endif // USERSLISTS_H diff --git a/helpers/conversationslisthelper.cpp b/helpers/conversationslisthelper.cpp index 963c265..e43f5b7 100644 --- a/helpers/conversationslisthelper.cpp +++ b/helpers/conversationslisthelper.cpp @@ -3,6 +3,7 @@ #include "conversationslisthelper.h" #include "apihelper.h" +#include "accounthelper.h" #include "../data/apirequest.h" #include "../data/conversationslist.h" @@ -20,6 +21,31 @@ void ConversationsListHelper::getList() mAPIHelper->execute(request); } +QString ConversationsListHelper::getConversationDisplayName(const Conversation &conv, const UsersList &usersInfo) +{ + //Check if the conversation has already a name + if(conv.name().length() > 0) + return conv.name(); + + QString name; + + int i = 0; + for(int j = 0; j < conv.members().length() && i < 3; j++){ + + //We bypass the current user name + if(conv.members().at(j) == AccountHelper::getUserID()) + continue; + + if(name.length() > 0) + name += ", "; + name += usersInfo.get(conv.members().at(j)).displayName(); + + i++; + } + + return name; +} + void ConversationsListHelper::getConvListCallback(int code, const QJsonDocument &document) { //Delete the request @@ -49,8 +75,8 @@ Conversation ConversationsListHelper::GetConversationFromJson(const QJsonObject conv.setIDowner(obj.value("ID_owner").toInt()); conv.setLastActive(obj.value("last_active").toInt()); conv.setName(obj.value("name").toString()); - conv.setFollowing(obj.value("following").toBool()); - conv.setSawLastMessage(obj.value("saw_last_message").toBool()); + conv.setFollowing(obj.value("following").toInt() == 1); + conv.setSawLastMessage(obj.value("saw_last_message").toInt() == 1); //Process the list of members of the conversation QJsonArray members_arr = obj.value("members").toArray(); diff --git a/helpers/conversationslisthelper.h b/helpers/conversationslisthelper.h index b28a52f..e81c177 100644 --- a/helpers/conversationslisthelper.h +++ b/helpers/conversationslisthelper.h @@ -12,6 +12,7 @@ #include #include "../data/conversation.h" +#include "../data/userslist.h" class QJsonObject; @@ -29,6 +30,15 @@ public: */ void getList(); + /** + * Get and return the display name of a conversation + * + * @param conv Information about the target conversation + * @param usersInfo Information about related users + * @return The name of the conversation + */ + static QString getConversationDisplayName(const Conversation &conv, const UsersList &usersInfo); + signals: /** diff --git a/helpers/usershelper.cpp b/helpers/usershelper.cpp index baf302a..5fc4840 100644 --- a/helpers/usershelper.cpp +++ b/helpers/usershelper.cpp @@ -31,12 +31,12 @@ void UsersHelper::getUsersInformationFinished(int code, const QJsonDocument &doc //Check for error if(code != 200){ - emit onGotUsersInfo(false, QList()); + emit onGotUsersInfo(false, UsersList()); return; } //Parse the list of object - QList list; + UsersList list; QJsonObject obj = document.object(); for(QString id : obj.keys()) list.append(ParseJSONToUser(obj.value(id).toObject())); diff --git a/helpers/usershelper.h b/helpers/usershelper.h index e6511b0..94c34e1 100644 --- a/helpers/usershelper.h +++ b/helpers/usershelper.h @@ -12,6 +12,7 @@ #include #include "../data/user.h" +#include "../data/userslist.h" class QJsonObject; @@ -38,7 +39,7 @@ signals: * @param success TRUE for a success / FALSE else * @param list Information about the users */ - void onGotUsersInfo(bool success, const QList &list); + void onGotUsersInfo(bool success, const UsersList &list); public slots: diff --git a/res/baseline_access_time_black_48dp.png b/res/baseline_access_time_black_48dp.png new file mode 100755 index 0000000..4399b1e Binary files /dev/null and b/res/baseline_access_time_black_48dp.png differ diff --git a/res/baseline_people_black_48dp.png b/res/baseline_people_black_48dp.png new file mode 100755 index 0000000..43ef39f Binary files /dev/null and b/res/baseline_people_black_48dp.png differ diff --git a/res/ressources.qrc b/res/ressources.qrc new file mode 100644 index 0000000..4e22012 --- /dev/null +++ b/res/ressources.qrc @@ -0,0 +1,6 @@ + + + baseline_people_black_48dp.png + baseline_access_time_black_48dp.png + + diff --git a/utils/timeutils.cpp b/utils/timeutils.cpp new file mode 100644 index 0000000..f4efff1 --- /dev/null +++ b/utils/timeutils.cpp @@ -0,0 +1,46 @@ +#include + +#include "timeutils.h" + +TimeUtils::TimeUtils() +{ + +} + +QString TimeUtils::TimeDiffToString(qint64 time) +{ + qint64 diffTime = QDateTime::currentSecsSinceEpoch() - time; + + if(diffTime < 60) + return QObject::tr("%1s ago").arg(diffTime); + + diffTime = diffTime/60; + if(diffTime < 60) + return QObject::tr("%1m ago").arg(diffTime); + + diffTime = diffTime/60; + if(diffTime < 24) + return QObject::tr("%1h ago").arg(diffTime); + + diffTime = diffTime/24; + if(diffTime < 30){ + if(diffTime == 1) + return QObject::tr("1 day ago"); + else + return QObject::tr("%1 days ago").arg(diffTime); + } + + diffTime = diffTime/30; + if(diffTime < 12){ + if(diffTime == 1) + return QObject::tr("1 month ago"); + else + return QObject::tr("%1 months ago").arg(diffTime); + } + + diffTime = diffTime/12; + if(diffTime == 1) + return QObject::tr("1 year ago"); + else + return QObject::tr("%1 years ago").arg(diffTime); +} diff --git a/utils/timeutils.h b/utils/timeutils.h new file mode 100644 index 0000000..7d3ed55 --- /dev/null +++ b/utils/timeutils.h @@ -0,0 +1,27 @@ +/** + * Time utilities + * + * @author Pierre HUBERT + */ + +#ifndef TIMEUTILS_H +#define TIMEUTILS_H + +#include + +class TimeUtils +{ +public: + TimeUtils(); + + /** + * Turn a timestamp into a diff string, in order to + * be shown to the user + * + * @param time The time to convert + * @return Generated string + */ + static QString TimeDiffToString(qint64 time); +}; + +#endif // TIMEUTILS_H diff --git a/utils/uiutils.cpp b/utils/uiutils.cpp new file mode 100644 index 0000000..24eb918 --- /dev/null +++ b/utils/uiutils.cpp @@ -0,0 +1,24 @@ +#include +#include + +#include "uiutils.h" + +UiUtils::UiUtils() +{ + +} + +void UiUtils::emptyLayout(QLayout *layout) +{ + while(layout->count() > 0){ + QLayoutItem *item = layout->itemAt(0); + + if(item->layout() != nullptr) + emptyLayout(item->layout()); + + if(item->widget() != nullptr) + item->widget()->deleteLater(); + + layout->removeItem(item); + } +} diff --git a/utils/uiutils.h b/utils/uiutils.h new file mode 100644 index 0000000..d87bcf8 --- /dev/null +++ b/utils/uiutils.h @@ -0,0 +1,25 @@ +/** + * UI utilities + * + * @author Pierre HUBERT + */ + +#ifndef UIUTILS_H +#define UIUTILS_H + +class QLayout; + +class UiUtils +{ +public: + UiUtils(); + + /** + * Remove all the items of a layout + * + * @param layout The layout to process + */ + static void emptyLayout(QLayout *layout); +}; + +#endif // UIUTILS_H diff --git a/widgets/conversationitemwidget.cpp b/widgets/conversationitemwidget.cpp new file mode 100644 index 0000000..ac6b943 --- /dev/null +++ b/widgets/conversationitemwidget.cpp @@ -0,0 +1,31 @@ +#include "conversationitemwidget.h" +#include "ui_conversationitemwidget.h" +#include "../helpers/conversationslisthelper.h" +#include "../utils/timeutils.h" + +ConversationItemWidget::ConversationItemWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::ConversationItemWidget) +{ + ui->setupUi(this); +} + +ConversationItemWidget::~ConversationItemWidget() +{ + delete ui; +} + +void ConversationItemWidget::setConversation(const Conversation &conv, const UsersList &list) +{ + ui->nameLabel->setText(ConversationsListHelper::getConversationDisplayName(conv, list)); + QFont font = ui->nameLabel->font(); + font.setBold(!conv.sawLastMessage()); + ui->nameLabel->setFont(font); + + if(conv.members().size() == 1) + ui->numberMembersLabel->setText(tr("1 member")); + else + ui->numberMembersLabel->setText(tr("%1 members").arg(conv.members().size())); + + ui->lastActivityLabel->setText(TimeUtils::TimeDiffToString(conv.lastActive())); +} diff --git a/widgets/conversationitemwidget.h b/widgets/conversationitemwidget.h new file mode 100644 index 0000000..cda8965 --- /dev/null +++ b/widgets/conversationitemwidget.h @@ -0,0 +1,41 @@ +/** + * Conversation item widget + * + * Contains information about a single conversation + * + * @author Pierre HUBERT + */ +#ifndef CONVERSATIONITEMWIDGET_H +#define CONVERSATIONITEMWIDGET_H + +#include + +namespace Ui { +class ConversationItemWidget; +} + +class Conversation; +class User; +class UsersList; + +class ConversationItemWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ConversationItemWidget(QWidget *parent = nullptr); + ~ConversationItemWidget(); + + /** + * Apply a conversation to the widget + * + * @param conv Information about the conversation to apply + * @param list Information about potential users of the conversation + */ + void setConversation(const Conversation &conv, const UsersList &list); + +private: + Ui::ConversationItemWidget *ui; +}; + +#endif // CONVERSATIONITEMWIDGET_H diff --git a/widgets/conversationitemwidget.ui b/widgets/conversationitemwidget.ui new file mode 100644 index 0000000..2f1830b --- /dev/null +++ b/widgets/conversationitemwidget.ui @@ -0,0 +1,129 @@ + + + ConversationItemWidget + + + + 0 + 0 + 138 + 91 + + + + Form + + + + 0 + + + + + + 14 + + + + TextLabel + + + + + + + 8 + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + + 15 + 15 + + + + + + + :/baseline_people_black_48dp.png + + + true + + + + + + + + 16777215 + 50 + + + + + 9 + + + + TextLabel + + + + + + + + + 8 + + + + + + 15 + 15 + + + + + + + :/baseline_access_time_black_48dp.png + + + true + + + + + + + + 9 + + + + TextLabel + + + + + + + + + + + + diff --git a/widgets/conversationslistwidget.cpp b/widgets/conversationslistwidget.cpp index 5c60490..8172e5c 100644 --- a/widgets/conversationslistwidget.cpp +++ b/widgets/conversationslistwidget.cpp @@ -1,9 +1,12 @@ #include +#include #include "conversationslistwidget.h" +#include "conversationitemwidget.h" #include "../helpers/conversationslisthelper.h" #include "../helpers/usershelper.h" #include "../data/conversationslist.h" +#include "../utils/uiutils.h" ConversationsListWidget::ConversationsListWidget(QWidget *parent) : QWidget(parent) @@ -15,6 +18,9 @@ ConversationsListWidget::ConversationsListWidget(QWidget *parent) : //Create users helper mUsersHelper = new UsersHelper(this); connect(mUsersHelper, &UsersHelper::onGotUsersInfo, this, &ConversationsListWidget::onGotUsersInfo); + + //Set conversations list layout + new QVBoxLayout(this); } ConversationsListWidget::~ConversationsListWidget() @@ -38,15 +44,28 @@ void ConversationsListWidget::onGotConversationsList(bool success, const Convers //Get the list of users mUsersHelper->getList(list.getAllMembersId()); + + //Save the list of conversations + mCurrList = list; } -void ConversationsListWidget::onGotUsersInfo(bool success, const QList &users) +void ConversationsListWidget::onGotUsersInfo(bool success, const UsersList &users) { if(!success){ QMessageBox::warning(this, tr("Error"), tr("Could not get information about the members of the conversations!")); return; } - qDebug("Got the list of members of the conversations."); - //TODO : use ConversationItemWidget + //Save members information + mCurrList.setMembersInformation(users); + + //First, remove any present convversation + UiUtils::emptyLayout(layout()); + + //Append the list of conversations + for(Conversation conv : mCurrList){ + ConversationItemWidget *item = new ConversationItemWidget; + item->setConversation(conv, users); + layout()->addWidget(item); + } } diff --git a/widgets/conversationslistwidget.h b/widgets/conversationslistwidget.h index 7f86f2c..14a43f9 100644 --- a/widgets/conversationslistwidget.h +++ b/widgets/conversationslistwidget.h @@ -4,6 +4,7 @@ #include #include "../data/conversationslist.h" +#include "../data/userslist.h" #include "../data/user.h" class ConversationsListHelper; @@ -38,7 +39,7 @@ private slots: * @param success TRUE in case of success / FALSE else * @param users The list of suers (empty list in case of failure) */ - void onGotUsersInfo(bool success, const QList &users); + void onGotUsersInfo(bool success, const UsersList &users); private: ConversationsListHelper *mConversationsList;