First chat message list :)
This commit is contained in:
parent
2750764de9
commit
ca7abb2a2f
6 changed files with 218 additions and 28 deletions
|
@ -31,10 +31,19 @@ function getSimpleMessageText(message) {
|
|||
return qsTr("Sticker: %1").arg(message.content.sticker.emoji);
|
||||
}
|
||||
if (message.content['@type'] === 'messagePhoto') {
|
||||
return (typeof message.content.caption) ? qsTr("Picture: %1").arg(message.content.caption.text) : qsTr("Picture");
|
||||
return (message.content.caption.text !== "") ? qsTr("Picture: %1").arg(message.content.caption.text) : qsTr("shared a picture");
|
||||
}
|
||||
if (message.content['@type'] === 'messageVideo') {
|
||||
return (typeof message.content.caption) ? qsTr("Video: %1").arg(message.content.caption.text) : qsTr("Video");
|
||||
return (message.content.caption.text !== "") ? qsTr("Video: %1").arg(message.content.caption.text) : qsTr("shared a video");
|
||||
}
|
||||
if (message.content['@type'] === 'messageAudio') {
|
||||
return (message.content.caption.text !== "") ? qsTr("Audio: %1").arg(message.content.caption.text) : qsTr("shared an audio");
|
||||
}
|
||||
if (message.content['@type'] === 'messageVoiceNote') {
|
||||
return (message.content.caption.text !== "") ? qsTr("Voice Note: %1").arg(message.content.caption.text) : qsTr("shared a voice note");
|
||||
}
|
||||
if (message.content['@type'] === 'messageLocation') {
|
||||
return qsTr("shared their location");
|
||||
}
|
||||
if (message.content['@type'] === 'messageContactRegistered') {
|
||||
return qsTr("has registered with Telegram");
|
||||
|
|
|
@ -30,6 +30,7 @@ Page {
|
|||
allowedOrientations: Orientation.All
|
||||
|
||||
property bool loading: true;
|
||||
property int myUserId: tdLibWrapper.getUserInformation().id;
|
||||
property variant chatInformation;
|
||||
property bool isPrivateChat: false;
|
||||
property bool isBasicGroup: false;
|
||||
|
@ -84,6 +85,7 @@ Page {
|
|||
|
||||
function initializePage() {
|
||||
tdLibWrapper.openChat(chatInformation.id);
|
||||
chatModel.initialize(chatInformation.id);
|
||||
var chatType = chatInformation.type['@type'];
|
||||
isPrivateChat = ( chatType === "chatTypePrivate" );
|
||||
isBasicGroup = ( chatType === "chatTypeBasicGroup" );
|
||||
|
@ -144,6 +146,13 @@ Page {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: chatModel
|
||||
onMessagesReceived: {
|
||||
chatView.positionViewAtEnd();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: chatContactTimeUpdater
|
||||
interval: 60000
|
||||
|
@ -170,7 +179,7 @@ Page {
|
|||
Row {
|
||||
id: headerRow
|
||||
width: parent.width - (3 * Theme.horizontalPageMargin)
|
||||
height: chatOverviewColumn.height + Theme.horizontalPageMargin
|
||||
height: chatOverviewColumn.height + ( 2 * Theme.horizontalPageMargin )
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: Theme.paddingMedium
|
||||
|
||||
|
@ -180,13 +189,13 @@ Page {
|
|||
replacementStringHint: chatNameText.text
|
||||
width: chatOverviewColumn.height
|
||||
height: chatOverviewColumn.height
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
id: chatOverviewColumn
|
||||
width: parent.width - chatPictureThumbnail.width - Theme.paddingMedium
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Text {
|
||||
id: chatNameText
|
||||
text: chatInformation.title !== "" ? Emoji.emojify(chatInformation.title, font.pixelSize) : qsTr("Unknown")
|
||||
|
@ -228,16 +237,72 @@ Page {
|
|||
height: parent.height - ( 2 * Theme.paddingMedium ) - headerRow.height - newMessageRow.height
|
||||
|
||||
clip: true
|
||||
// visible: count > 0
|
||||
visible: count > 0
|
||||
|
||||
// model: chatListModel
|
||||
model: chatModel
|
||||
delegate: ListItem {
|
||||
|
||||
id: chatItem
|
||||
|
||||
//contentHeight: chatListRow.height + chatListSeparator.height + 2 * Theme.paddingMedium
|
||||
id: messageListItem
|
||||
contentHeight: messageTextItem.height + Theme.paddingMedium
|
||||
contentWidth: parent.width
|
||||
|
||||
Column {
|
||||
id: messageTextItem
|
||||
|
||||
spacing: Theme.paddingSmall
|
||||
|
||||
width: parent.width
|
||||
height: messageText.height + messageDateText.height + Theme.paddingMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Text {
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: (chatPage.myUserId === display.sender_user_id) ? 4 * Theme.horizontalPageMargin : Theme.horizontalPageMargin
|
||||
right: parent.right
|
||||
rightMargin: (chatPage.myUserId === display.sender_user_id) ? Theme.horizontalPageMargin : 4 * Theme.horizontalPageMargin
|
||||
}
|
||||
|
||||
id: messageText
|
||||
text: Emoji.emojify(Functions.getSimpleMessageText(display), font.pixelSize)
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: chatPage.myUserId === display.sender_user_id ? Theme.highlightColor : Theme.primaryColor
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: Text.StyledText
|
||||
onLinkActivated: {
|
||||
// Functions.handleLink(link);
|
||||
}
|
||||
horizontalAlignment: (chatPage.myUserId === display.sender_user_id) ? Text.AlignRight : Text.AlignLeft
|
||||
linkColor: Theme.highlightColor
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: messageDateUpdater
|
||||
interval: 60000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
messageDateText.text = Functions.getDateTimeElapsed(display.date);
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: (chatPage.myUserId === display.sender_user_id) ? 4 * Theme.horizontalPageMargin : Theme.horizontalPageMargin
|
||||
right: parent.right
|
||||
rightMargin: (chatPage.myUserId === display.sender_user_id) ? Theme.horizontalPageMargin : 4 * Theme.horizontalPageMargin
|
||||
}
|
||||
|
||||
id: messageDateText
|
||||
text: Functions.getDateTimeElapsed(display.date)
|
||||
font.pixelSize: Theme.fontSizeTiny
|
||||
color: chatPage.myUserId === display.sender_user_id ? Theme.highlightColor : Theme.primaryColor
|
||||
horizontalAlignment: (chatPage.myUserId === display.sender_user_id) ? Text.AlignRight : Text.AlignLeft
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VerticalScrollDecorator {}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#include "chatmodel.h"
|
||||
|
||||
#include <QListIterator>
|
||||
|
||||
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper)
|
||||
{
|
||||
this->tdLibWrapper = tdLibWrapper;
|
||||
this->inReload = false;
|
||||
connect(this->tdLibWrapper, SIGNAL(messagesReceived(QVariantList)), this, SLOT(handleMessagesReceived(QVariantList)));
|
||||
}
|
||||
|
||||
ChatModel::~ChatModel()
|
||||
|
@ -27,7 +31,9 @@ bool ChatModel::insertRows(int row, int count, const QModelIndex &parent)
|
|||
{
|
||||
qDebug() << "[ChatModel] Inserting at " << row << ", row count: " << count;
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
this->messages.insert(row, this->messagesToBeAdded);
|
||||
for (int i = 0; i < count; i++) {
|
||||
this->messages.insert(row + i, this->messagesToBeAdded.at(i));
|
||||
}
|
||||
this->messageIndexMap.clear();
|
||||
for (int i = 0; i < this->messages.size(); i++) {
|
||||
this->messageIndexMap.insert(this->messages.at(i).toMap().value("id").toString(), i);
|
||||
|
@ -35,3 +41,63 @@ bool ChatModel::insertRows(int row, int count, const QModelIndex &parent)
|
|||
endInsertRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChatModel::initialize(const QString &chatId)
|
||||
{
|
||||
this->chatId = chatId;
|
||||
this->messages.clear();
|
||||
this->messageIndexMap.clear();
|
||||
this->messagesToBeAdded.clear();
|
||||
}
|
||||
|
||||
bool compareMessages(const QVariant &message1, const QVariant &message2)
|
||||
{
|
||||
QVariantMap messageMap1 = message1.toMap();
|
||||
QVariantMap messageMap2 = message2.toMap();
|
||||
if (messageMap1.value("id").toLongLong() < messageMap2.value("id").toLongLong()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ChatModel::handleMessagesReceived(const QVariantList &messages)
|
||||
{
|
||||
qDebug() << "[ChatModel] Receiving new messages :)";
|
||||
this->messagesMutex.lock();
|
||||
this->messagesToBeAdded.clear();
|
||||
QListIterator<QVariant> messagesIterator(messages);
|
||||
while (messagesIterator.hasNext()) {
|
||||
QVariantMap currentMessage = messagesIterator.next().toMap();
|
||||
if (currentMessage.value("chat_id").toString() == this->chatId) {
|
||||
this->messagesToBeAdded.append(currentMessage);
|
||||
}
|
||||
}
|
||||
std::sort(this->messagesToBeAdded.begin(), this->messagesToBeAdded.end(), compareMessages);
|
||||
if (this->messages.isEmpty()) {
|
||||
beginResetModel();
|
||||
this->messages.append(this->messagesToBeAdded);
|
||||
endResetModel();
|
||||
} else {
|
||||
// There is only an append or a prepend, tertium non datur! (probably ;))
|
||||
if (this->messages.last().toMap().value("id").toLongLong() < this->messagesToBeAdded.first().toMap().value("id").toLongLong()) {
|
||||
// Append
|
||||
this->insertRows(rowCount(QModelIndex()), this->messagesToBeAdded.size());
|
||||
} else {
|
||||
// Prepend
|
||||
this->insertRows(0, this->messagesToBeAdded.size());
|
||||
}
|
||||
}
|
||||
this->messagesMutex.unlock();
|
||||
|
||||
// First call only returns one message, we need to get a little more than that...
|
||||
if (this->messagesToBeAdded.size() == 1 && !this->inReload) {
|
||||
qDebug() << "[ChatModel] Only one message received in first call, loading more...";
|
||||
this->inReload = true;
|
||||
this->tdLibWrapper->getChatHistory(this->chatId, this->messagesToBeAdded.first().toMap().value("id").toLongLong());
|
||||
} else {
|
||||
qDebug() << "[ChatModel] Messages loaded, notifying chat UI...";
|
||||
this->inReload = false;
|
||||
emit messagesReceived();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,23 @@ public:
|
|||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
Q_INVOKABLE void initialize(const QString &chatId);
|
||||
|
||||
signals:
|
||||
void messagesReceived();
|
||||
|
||||
public slots:
|
||||
void handleMessagesReceived(const QVariantList &messages);
|
||||
|
||||
private:
|
||||
|
||||
TDLibWrapper *tdLibWrapper;
|
||||
QVariantList messages;
|
||||
QVariantList messagesToBeAdded;
|
||||
QVariantMap messageIndexMap;
|
||||
QMutex chatListMutex;
|
||||
QMutex messagesMutex;
|
||||
QString chatId;
|
||||
bool inReload;
|
||||
};
|
||||
|
||||
#endif // CHATMODEL_H
|
||||
|
|
|
@ -258,10 +258,6 @@
|
|||
<source>Video: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>has registered with Telegram</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -270,10 +266,6 @@
|
|||
<source>Picture: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Picture</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sticker: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -290,5 +282,33 @@
|
|||
<source>left this chat.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Audio: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Voice Note: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared a picture</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared a video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared an audio</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared a voice note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared their location</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -258,10 +258,6 @@
|
|||
<source>Video: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>has registered with Telegram</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -270,10 +266,6 @@
|
|||
<source>Picture: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Picture</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sticker: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -290,5 +282,33 @@
|
|||
<source>left this chat.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Audio: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Voice Note: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared a picture</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared a video</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared an audio</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared a voice note</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shared their location</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
Loading…
Reference in a new issue