Display the list of conversations.

This commit is contained in:
Pierre HUBERT 2018-12-07 11:31:42 +01:00
parent 3d9748ad62
commit 1df359735d
24 changed files with 484 additions and 11 deletions

View File

@ -22,7 +22,10 @@ SOURCES += \
widgets/conversationitemwidget.cpp \ widgets/conversationitemwidget.cpp \
data/user.cpp \ data/user.cpp \
helpers/usershelper.cpp \ helpers/usershelper.cpp \
data/conversationslist.cpp data/conversationslist.cpp \
utils/uiutils.cpp \
data/userslist.cpp \
utils/timeutils.cpp
HEADERS += \ HEADERS += \
helpers/accounthelper.h \ helpers/accounthelper.h \
@ -46,10 +49,16 @@ HEADERS += \
widgets/conversationitemwidget.h \ widgets/conversationitemwidget.h \
data/user.h \ data/user.h \
helpers/usershelper.h \ helpers/usershelper.h \
data/conversationslist.h data/conversationslist.h \
utils/uiutils.h \
data/userslist.h \
utils/timeutils.h
FORMS += \ FORMS += \
widgets/loginwidget.ui \ widgets/loginwidget.ui \
widgets/mainwindow.ui \ widgets/mainwindow.ui \
widgets/aboutthisappdialog.ui \ widgets/aboutthisappdialog.ui \
widgets/conversationitemwidget.ui widgets/conversationitemwidget.ui
RESOURCES += \
res/ressources.qrc

View File

@ -1,4 +1,5 @@
#include "conversation.h" #include "conversation.h"
#include "userslist.h"
Conversation::Conversation() Conversation::Conversation()
{ {

View File

@ -15,3 +15,13 @@ QList<int> ConversationsList::getAllMembersId() const
} }
return members; return members;
} }
UsersList ConversationsList::getMembersInformation() const
{
return mMembersInformation;
}
void ConversationsList::setMembersInformation(const UsersList &membersInformation)
{
mMembersInformation = membersInformation;
}

View File

@ -10,6 +10,8 @@
#include <QList> #include <QList>
#include "conversation.h" #include "conversation.h"
#include "user.h"
#include "userslist.h"
class ConversationsList : public QList<Conversation> class ConversationsList : public QList<Conversation>
{ {
@ -23,6 +25,14 @@ public:
* @return The IDs of the conversations * @return The IDs of the conversations
*/ */
QList<int> getAllMembersId() const; QList<int> getAllMembersId() const;
UsersList getMembersInformation() const;
void setMembersInformation(const UsersList &membersInformation);
private:
//Private fields
UsersList mMembersInformation;
}; };
#endif // CONVERSATIONSLIST_H #endif // CONVERSATIONSLIST_H

View File

@ -35,6 +35,11 @@ void User::setLastName(const QString &lastName)
mLastName = lastName; mLastName = lastName;
} }
QString User::displayName() const
{
return firstName() + " " + lastName();
}
QString User::accountImage() const QString User::accountImage() const
{ {
return mAccountImage; return mAccountImage;

View File

@ -23,6 +23,11 @@ public:
QString lastName() const; QString lastName() const;
void setLastName(const QString &lastName); void setLastName(const QString &lastName);
/**
* Get and return display name of the user
*/
QString displayName() const;
QString accountImage() const; QString accountImage() const;
void setAccountImage(const QString &accountImage); void setAccountImage(const QString &accountImage);

16
data/userslist.cpp Normal file
View File

@ -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();
}

31
data/userslist.h Normal file
View File

@ -0,0 +1,31 @@
/**
* A list of users
*
* Provides methods to fetch users
*
* @author Pierre HUBERT
*/
#ifndef USERSLISTS_H
#define USERSLISTS_H
#include <QList>
#include "user.h"
class UsersList : public QList<User>
{
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

View File

@ -3,6 +3,7 @@
#include "conversationslisthelper.h" #include "conversationslisthelper.h"
#include "apihelper.h" #include "apihelper.h"
#include "accounthelper.h"
#include "../data/apirequest.h" #include "../data/apirequest.h"
#include "../data/conversationslist.h" #include "../data/conversationslist.h"
@ -20,6 +21,31 @@ void ConversationsListHelper::getList()
mAPIHelper->execute(request); 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) void ConversationsListHelper::getConvListCallback(int code, const QJsonDocument &document)
{ {
//Delete the request //Delete the request
@ -49,8 +75,8 @@ Conversation ConversationsListHelper::GetConversationFromJson(const QJsonObject
conv.setIDowner(obj.value("ID_owner").toInt()); conv.setIDowner(obj.value("ID_owner").toInt());
conv.setLastActive(obj.value("last_active").toInt()); conv.setLastActive(obj.value("last_active").toInt());
conv.setName(obj.value("name").toString()); conv.setName(obj.value("name").toString());
conv.setFollowing(obj.value("following").toBool()); conv.setFollowing(obj.value("following").toInt() == 1);
conv.setSawLastMessage(obj.value("saw_last_message").toBool()); conv.setSawLastMessage(obj.value("saw_last_message").toInt() == 1);
//Process the list of members of the conversation //Process the list of members of the conversation
QJsonArray members_arr = obj.value("members").toArray(); QJsonArray members_arr = obj.value("members").toArray();

View File

@ -12,6 +12,7 @@
#include <QObject> #include <QObject>
#include "../data/conversation.h" #include "../data/conversation.h"
#include "../data/userslist.h"
class QJsonObject; class QJsonObject;
@ -29,6 +30,15 @@ public:
*/ */
void getList(); 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: signals:
/** /**

View File

@ -31,12 +31,12 @@ void UsersHelper::getUsersInformationFinished(int code, const QJsonDocument &doc
//Check for error //Check for error
if(code != 200){ if(code != 200){
emit onGotUsersInfo(false, QList<User>()); emit onGotUsersInfo(false, UsersList());
return; return;
} }
//Parse the list of object //Parse the list of object
QList<User> list; UsersList list;
QJsonObject obj = document.object(); QJsonObject obj = document.object();
for(QString id : obj.keys()) for(QString id : obj.keys())
list.append(ParseJSONToUser(obj.value(id).toObject())); list.append(ParseJSONToUser(obj.value(id).toObject()));

View File

@ -12,6 +12,7 @@
#include <QObject> #include <QObject>
#include "../data/user.h" #include "../data/user.h"
#include "../data/userslist.h"
class QJsonObject; class QJsonObject;
@ -38,7 +39,7 @@ signals:
* @param success TRUE for a success / FALSE else * @param success TRUE for a success / FALSE else
* @param list Information about the users * @param list Information about the users
*/ */
void onGotUsersInfo(bool success, const QList<User> &list); void onGotUsersInfo(bool success, const UsersList &list);
public slots: public slots:

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

6
res/ressources.qrc Normal file
View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>baseline_people_black_48dp.png</file>
<file>baseline_access_time_black_48dp.png</file>
</qresource>
</RCC>

46
utils/timeutils.cpp Normal file
View File

@ -0,0 +1,46 @@
#include <QDateTime>
#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);
}

27
utils/timeutils.h Normal file
View File

@ -0,0 +1,27 @@
/**
* Time utilities
*
* @author Pierre HUBERT
*/
#ifndef TIMEUTILS_H
#define TIMEUTILS_H
#include <QObject>
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

24
utils/uiutils.cpp Normal file
View File

@ -0,0 +1,24 @@
#include <QLayout>
#include <QWidget>
#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);
}
}

25
utils/uiutils.h Normal file
View File

@ -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

View File

@ -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()));
}

View File

@ -0,0 +1,41 @@
/**
* Conversation item widget
*
* Contains information about a single conversation
*
* @author Pierre HUBERT
*/
#ifndef CONVERSATIONITEMWIDGET_H
#define CONVERSATIONITEMWIDGET_H
#include <QWidget>
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

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConversationItemWidget</class>
<widget class="QWidget" name="ConversationItemWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>138</width>
<height>91</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="nameLabel">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>8</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>15</width>
<height>15</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../res/ressources.qrc">:/baseline_people_black_48dp.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="numberMembersLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="maximumSize">
<size>
<width>15</width>
<height>15</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../res/ressources.qrc">:/baseline_access_time_black_48dp.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lastActivityLabel">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../res/ressources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,9 +1,12 @@
#include <QMessageBox> #include <QMessageBox>
#include <QVBoxLayout>
#include "conversationslistwidget.h" #include "conversationslistwidget.h"
#include "conversationitemwidget.h"
#include "../helpers/conversationslisthelper.h" #include "../helpers/conversationslisthelper.h"
#include "../helpers/usershelper.h" #include "../helpers/usershelper.h"
#include "../data/conversationslist.h" #include "../data/conversationslist.h"
#include "../utils/uiutils.h"
ConversationsListWidget::ConversationsListWidget(QWidget *parent) : ConversationsListWidget::ConversationsListWidget(QWidget *parent) :
QWidget(parent) QWidget(parent)
@ -15,6 +18,9 @@ ConversationsListWidget::ConversationsListWidget(QWidget *parent) :
//Create users helper //Create users helper
mUsersHelper = new UsersHelper(this); mUsersHelper = new UsersHelper(this);
connect(mUsersHelper, &UsersHelper::onGotUsersInfo, this, &ConversationsListWidget::onGotUsersInfo); connect(mUsersHelper, &UsersHelper::onGotUsersInfo, this, &ConversationsListWidget::onGotUsersInfo);
//Set conversations list layout
new QVBoxLayout(this);
} }
ConversationsListWidget::~ConversationsListWidget() ConversationsListWidget::~ConversationsListWidget()
@ -38,15 +44,28 @@ void ConversationsListWidget::onGotConversationsList(bool success, const Convers
//Get the list of users //Get the list of users
mUsersHelper->getList(list.getAllMembersId()); mUsersHelper->getList(list.getAllMembersId());
//Save the list of conversations
mCurrList = list;
} }
void ConversationsListWidget::onGotUsersInfo(bool success, const QList<User> &users) void ConversationsListWidget::onGotUsersInfo(bool success, const UsersList &users)
{ {
if(!success){ if(!success){
QMessageBox::warning(this, tr("Error"), tr("Could not get information about the members of the conversations!")); QMessageBox::warning(this, tr("Error"), tr("Could not get information about the members of the conversations!"));
return; return;
} }
qDebug("Got the list of members of the conversations."); //Save members information
//TODO : use ConversationItemWidget 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);
}
} }

View File

@ -4,6 +4,7 @@
#include <QWidget> #include <QWidget>
#include "../data/conversationslist.h" #include "../data/conversationslist.h"
#include "../data/userslist.h"
#include "../data/user.h" #include "../data/user.h"
class ConversationsListHelper; class ConversationsListHelper;
@ -38,7 +39,7 @@ private slots:
* @param success TRUE in case of success / FALSE else * @param success TRUE in case of success / FALSE else
* @param users The list of suers (empty list in case of failure) * @param users The list of suers (empty list in case of failure)
*/ */
void onGotUsersInfo(bool success, const QList<User> &users); void onGotUsersInfo(bool success, const UsersList &users);
private: private:
ConversationsListHelper *mConversationsList; ConversationsListHelper *mConversationsList;