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);
|
return qsTr("Sticker: %1").arg(message.content.sticker.emoji);
|
||||||
}
|
}
|
||||||
if (message.content['@type'] === 'messagePhoto') {
|
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') {
|
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') {
|
if (message.content['@type'] === 'messageContactRegistered') {
|
||||||
return qsTr("has registered with Telegram");
|
return qsTr("has registered with Telegram");
|
||||||
|
|
|
@ -30,6 +30,7 @@ Page {
|
||||||
allowedOrientations: Orientation.All
|
allowedOrientations: Orientation.All
|
||||||
|
|
||||||
property bool loading: true;
|
property bool loading: true;
|
||||||
|
property int myUserId: tdLibWrapper.getUserInformation().id;
|
||||||
property variant chatInformation;
|
property variant chatInformation;
|
||||||
property bool isPrivateChat: false;
|
property bool isPrivateChat: false;
|
||||||
property bool isBasicGroup: false;
|
property bool isBasicGroup: false;
|
||||||
|
@ -84,6 +85,7 @@ Page {
|
||||||
|
|
||||||
function initializePage() {
|
function initializePage() {
|
||||||
tdLibWrapper.openChat(chatInformation.id);
|
tdLibWrapper.openChat(chatInformation.id);
|
||||||
|
chatModel.initialize(chatInformation.id);
|
||||||
var chatType = chatInformation.type['@type'];
|
var chatType = chatInformation.type['@type'];
|
||||||
isPrivateChat = ( chatType === "chatTypePrivate" );
|
isPrivateChat = ( chatType === "chatTypePrivate" );
|
||||||
isBasicGroup = ( chatType === "chatTypeBasicGroup" );
|
isBasicGroup = ( chatType === "chatTypeBasicGroup" );
|
||||||
|
@ -144,6 +146,13 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: chatModel
|
||||||
|
onMessagesReceived: {
|
||||||
|
chatView.positionViewAtEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: chatContactTimeUpdater
|
id: chatContactTimeUpdater
|
||||||
interval: 60000
|
interval: 60000
|
||||||
|
@ -170,7 +179,7 @@ Page {
|
||||||
Row {
|
Row {
|
||||||
id: headerRow
|
id: headerRow
|
||||||
width: parent.width - (3 * Theme.horizontalPageMargin)
|
width: parent.width - (3 * Theme.horizontalPageMargin)
|
||||||
height: chatOverviewColumn.height + Theme.horizontalPageMargin
|
height: chatOverviewColumn.height + ( 2 * Theme.horizontalPageMargin )
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: Theme.paddingMedium
|
spacing: Theme.paddingMedium
|
||||||
|
|
||||||
|
@ -180,13 +189,13 @@ Page {
|
||||||
replacementStringHint: chatNameText.text
|
replacementStringHint: chatNameText.text
|
||||||
width: chatOverviewColumn.height
|
width: chatOverviewColumn.height
|
||||||
height: chatOverviewColumn.height
|
height: chatOverviewColumn.height
|
||||||
anchors.bottom: parent.bottom
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: chatOverviewColumn
|
id: chatOverviewColumn
|
||||||
width: parent.width - chatPictureThumbnail.width - Theme.paddingMedium
|
width: parent.width - chatPictureThumbnail.width - Theme.paddingMedium
|
||||||
anchors.bottom: parent.bottom
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
Text {
|
Text {
|
||||||
id: chatNameText
|
id: chatNameText
|
||||||
text: chatInformation.title !== "" ? Emoji.emojify(chatInformation.title, font.pixelSize) : qsTr("Unknown")
|
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
|
height: parent.height - ( 2 * Theme.paddingMedium ) - headerRow.height - newMessageRow.height
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
// visible: count > 0
|
visible: count > 0
|
||||||
|
|
||||||
// model: chatListModel
|
model: chatModel
|
||||||
delegate: ListItem {
|
delegate: ListItem {
|
||||||
|
|
||||||
id: chatItem
|
id: messageListItem
|
||||||
|
contentHeight: messageTextItem.height + Theme.paddingMedium
|
||||||
//contentHeight: chatListRow.height + chatListSeparator.height + 2 * Theme.paddingMedium
|
|
||||||
contentWidth: parent.width
|
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 {}
|
VerticalScrollDecorator {}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
#include "chatmodel.h"
|
#include "chatmodel.h"
|
||||||
|
|
||||||
|
#include <QListIterator>
|
||||||
|
|
||||||
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper)
|
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper)
|
||||||
{
|
{
|
||||||
this->tdLibWrapper = tdLibWrapper;
|
this->tdLibWrapper = tdLibWrapper;
|
||||||
|
this->inReload = false;
|
||||||
|
connect(this->tdLibWrapper, SIGNAL(messagesReceived(QVariantList)), this, SLOT(handleMessagesReceived(QVariantList)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatModel::~ChatModel()
|
ChatModel::~ChatModel()
|
||||||
|
@ -27,7 +31,9 @@ bool ChatModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||||
{
|
{
|
||||||
qDebug() << "[ChatModel] Inserting at " << row << ", row count: " << count;
|
qDebug() << "[ChatModel] Inserting at " << row << ", row count: " << count;
|
||||||
beginInsertRows(parent, row, row + count - 1);
|
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();
|
this->messageIndexMap.clear();
|
||||||
for (int i = 0; i < this->messages.size(); i++) {
|
for (int i = 0; i < this->messages.size(); i++) {
|
||||||
this->messageIndexMap.insert(this->messages.at(i).toMap().value("id").toString(), 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();
|
endInsertRows();
|
||||||
return true;
|
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 QVariant data(const QModelIndex &index, int role) const override;
|
||||||
virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) 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:
|
private:
|
||||||
|
|
||||||
TDLibWrapper *tdLibWrapper;
|
TDLibWrapper *tdLibWrapper;
|
||||||
QVariantList messages;
|
QVariantList messages;
|
||||||
QVariantList messagesToBeAdded;
|
QVariantList messagesToBeAdded;
|
||||||
QVariantMap messageIndexMap;
|
QVariantMap messageIndexMap;
|
||||||
QMutex chatListMutex;
|
QMutex messagesMutex;
|
||||||
|
QString chatId;
|
||||||
|
bool inReload;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHATMODEL_H
|
#endif // CHATMODEL_H
|
||||||
|
|
|
@ -258,10 +258,6 @@
|
||||||
<source>Video: %1</source>
|
<source>Video: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Video</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>has registered with Telegram</source>
|
<source>has registered with Telegram</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -270,10 +266,6 @@
|
||||||
<source>Picture: %1</source>
|
<source>Picture: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Picture</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Sticker: %1</source>
|
<source>Sticker: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -290,5 +282,33 @@
|
||||||
<source>left this chat.</source>
|
<source>left this chat.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</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>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -258,10 +258,6 @@
|
||||||
<source>Video: %1</source>
|
<source>Video: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Video</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>has registered with Telegram</source>
|
<source>has registered with Telegram</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -270,10 +266,6 @@
|
||||||
<source>Picture: %1</source>
|
<source>Picture: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Picture</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Sticker: %1</source>
|
<source>Sticker: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -290,5 +282,33 @@
|
||||||
<source>left this chat.</source>
|
<source>left this chat.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</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>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
Loading…
Reference in a new issue