Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
kaidan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Robert Maerkisch
kaidan
Commits
4da78fbc
Commit
4da78fbc
authored
Dec 30, 2018
by
Linus Jahn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement XEP-0308: Last Message Correction (back-end)
parent
dfe6860c
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
182 additions
and
12 deletions
+182
-12
i18n/base.ts
i18n/base.ts
+4
-0
i18n/de.ts
i18n/de.ts
+4
-0
i18n/de_AT.ts
i18n/de_AT.ts
+4
-0
i18n/es.ts
i18n/es.ts
+4
-0
i18n/eu.ts
i18n/eu.ts
+4
-0
i18n/fr.ts
i18n/fr.ts
+4
-0
i18n/it.ts
i18n/it.ts
+4
-0
i18n/ja.ts
i18n/ja.ts
+4
-0
i18n/ms.ts
i18n/ms.ts
+4
-0
i18n/nb.ts
i18n/nb.ts
+4
-0
i18n/nl.ts
i18n/nl.ts
+4
-0
i18n/pl.ts
i18n/pl.ts
+4
-0
i18n/pt.ts
i18n/pt.ts
+4
-0
i18n/ru.ts
i18n/ru.ts
+4
-0
src/Database.cpp
src/Database.cpp
+15
-4
src/Database.h
src/Database.h
+1
-0
src/Kaidan.h
src/Kaidan.h
+7
-0
src/MessageHandler.cpp
src/MessageHandler.cpp
+55
-2
src/MessageHandler.h
src/MessageHandler.h
+5
-0
src/MessageModel.cpp
src/MessageModel.cpp
+26
-4
src/MessageModel.h
src/MessageModel.h
+13
-0
src/UploadManager.cpp
src/UploadManager.cpp
+4
-2
No files found.
i18n/base.ts
View file @
4da78fbc
...
...
@@ -158,6 +158,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterManager
<
/name
>
...
...
i18n/de.ts
View file @
4da78fbc
...
...
@@ -295,6 +295,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
Konnte
Nachricht
nicht
versenden
,
da
Sie
nicht
verbunden
sind
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/de_AT.ts
View file @
4da78fbc
...
...
@@ -158,6 +158,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterManager
<
/name
>
...
...
i18n/es.ts
View file @
4da78fbc
...
...
@@ -267,6 +267,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
No
se
pudo
enviar
el
mensaje
porque
no
está
conectado
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/eu.ts
View file @
4da78fbc
...
...
@@ -224,6 +224,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
>
Ezin
izan
da
mezua
bidali
,
konektaturik
ez
zaudelako
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/fr.ts
View file @
4da78fbc
...
...
@@ -274,6 +274,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
>
Vous
n
&
apos
;
êtes
pas
connecté
.
Impossible
d
&
apos
;
envoyer
le
message
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/it.ts
View file @
4da78fbc
...
...
@@ -158,6 +158,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
Impossibile
inviare
messaggi
a
causa
della
mancata
connessione
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterManager
<
/name
>
...
...
i18n/ja.ts
View file @
4da78fbc
...
...
@@ -185,6 +185,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/ms.ts
View file @
4da78fbc
...
...
@@ -270,6 +270,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
Tidak
dapat
hantar
mesej
,
kerana
anda
tiada
sambungan
internet
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/nb.ts
View file @
4da78fbc
...
...
@@ -251,6 +251,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
>
Kunne
ikke
sende
melding
,
som
følge
av
manglende
tilkobling
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/nl.ts
View file @
4da78fbc
...
...
@@ -214,6 +214,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
Kan
geen
bericht
verzenden
,
omdat
er
geen
verbinding
is
gemaakt
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
i18n/pl.ts
View file @
4da78fbc
...
...
@@ -158,6 +158,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
Nie
można
było
wysłać
wiadomości
,
w
wyniku
braku
połączenia
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterManager
<
/name
>
...
...
i18n/pt.ts
View file @
4da78fbc
...
...
@@ -206,6 +206,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
Não
foi
possível
enviar
mensagem
,
como
resultado
de
não
estar
conectado
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterManager
<
/name
>
...
...
i18n/ru.ts
View file @
4da78fbc
...
...
@@ -248,6 +248,10 @@
<
source
>
Could
not
send
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
>
Не
смог
отправить
сообщение
,
в
результате
того
,
что
не
был
подключен
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Could
not
correct
message
,
as
a
result
of
not
being
connected
.
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
RosterAddContactSheet
<
/name
>
...
...
src/Database.cpp
View file @
4da78fbc
...
...
@@ -41,7 +41,7 @@
#include <QSqlQuery>
#include <QSqlRecord>
static
const
int
DATABASE_LATEST_VERSION
=
8
;
static
const
int
DATABASE_LATEST_VERSION
=
9
;
static
const
char
*
DATABASE_TABLE_INFO
=
"dbinfo"
;
static
const
char
*
DATABASE_TABLE_MESSAGES
=
"Messages"
;
static
const
char
*
DATABASE_TABLE_ROSTER
=
"Roster"
;
...
...
@@ -124,7 +124,7 @@ bool Database::needToConvert()
void
Database
::
convertDatabase
()
{
qDebug
()
<<
"[database] Converting database to latest version from verion"
<<
version
;
qDebug
()
<<
"[database] Converting database to latest version from ver
s
ion"
<<
version
;
while
(
version
<
DATABASE_LATEST_VERSION
)
{
switch
(
version
)
{
case
0
:
...
...
@@ -143,6 +143,8 @@ void Database::convertDatabase()
convertDatabaseToV7
();
version
=
7
;
break
;
case
7
:
convertDatabaseToV8
();
version
=
8
;
break
;
case
8
:
convertDatabaseToV9
();
version
=
9
;
break
;
default:
break
;
}
...
...
@@ -161,7 +163,7 @@ void Database::convertDatabase()
void
Database
::
createNewDatabase
()
{
QSqlQuery
query
(
database
);
//
// DB info
//
...
...
@@ -205,6 +207,7 @@ void Database::createNewDatabase()
"'mediaLocation' TEXT,"
"'mediaThumb' BLOB,"
"'mediaHashes' TEXT,"
"'edited' BOOL,"
// whether the message has been edited
"FOREIGN KEY('author') REFERENCES Roster ('jid'),"
"FOREIGN KEY('recipient') REFERENCES Roster ('jid')"
")"
...
...
@@ -219,7 +222,7 @@ void Database::createDbInfoTable()
QSqlQuery
query
(
database
);
query
.
prepare
(
"CREATE TABLE IF NOT EXISTS 'dbinfo' (version INTEGER NOT NULL)"
);
execQuery
(
query
);
query
.
prepare
(
QString
(
"INSERT INTO 'dbinfo' (version) VALUES (%1)"
)
.
arg
(
DATABASE_LATEST_VERSION
));
execQuery
(
query
);
...
...
@@ -328,6 +331,14 @@ void Database::convertDatabaseToV8()
execQuery
(
query
);
}
void
Database
::
convertDatabaseToV9
()
{
QSqlQuery
query
(
database
);
query
.
prepare
(
"ALTER TABLE 'Messages' ADD 'edited' BOOL"
);
execQuery
(
query
);
}
void
Database
::
execQuery
(
QSqlQuery
&
query
)
{
if
(
!
query
.
exec
())
{
...
...
src/Database.h
View file @
4da78fbc
...
...
@@ -60,6 +60,7 @@ private:
void
convertDatabaseToV6
();
void
convertDatabaseToV7
();
void
convertDatabaseToV8
();
void
convertDatabaseToV9
();
void
execQuery
(
QSqlQuery
&
query
);
QSqlDatabase
database
;
...
...
src/Kaidan.h
View file @
4da78fbc
...
...
@@ -359,6 +359,13 @@ signals:
*/
void
sendMessage
(
QString
jid
,
QString
message
);
/**
* Correct the last message
*
* To get/check the last message id, use `kaidan.messageModel.lastMessageId(jid)`
*/
void
correctMessage
(
QString
toJid
,
QString
msgId
,
QString
message
);
/**
* Upload and send file
*/
...
...
src/MessageHandler.cpp
View file @
4da78fbc
...
...
@@ -53,6 +53,7 @@ MessageHandler::MessageHandler(Kaidan *kaidan, QXmppClient *client, MessageModel
{
connect
(
client
,
&
QXmppClient
::
messageReceived
,
this
,
&
MessageHandler
::
handleMessage
);
connect
(
kaidan
,
&
Kaidan
::
sendMessage
,
this
,
&
MessageHandler
::
sendMessage
);
connect
(
kaidan
,
&
Kaidan
::
correctMessage
,
this
,
&
MessageHandler
::
correctMessage
);
client
->
addExtension
(
&
receiptManager
);
connect
(
&
receiptManager
,
&
QXmppMessageReceiptManager
::
messageDelivered
,
...
...
@@ -140,7 +141,18 @@ void MessageHandler::handleMessage(const QXmppMessage &msg)
entry
.
timestamp
=
stamp
.
toUTC
().
toString
(
Qt
::
ISODate
);
// save the message to the database
#if QXMPP_VERSION >= QT_VERSION_CHECK(1, 0, 0)
// in case of message correction, replace old message
if
(
msg
.
replaceId
().
isEmpty
())
{
emit
model
->
addMessageRequested
(
entry
);
}
else
{
entry
.
edited
=
true
;
emit
model
->
updateMessageRequested
(
msg
.
replaceId
(),
entry
);
}
#else
// no message correction with old QXmpp
emit
model
->
addMessageRequested
(
entry
);
#endif
// Send a message notification
//
...
...
@@ -184,8 +196,49 @@ void MessageHandler::sendMessage(QString toJid, QString body)
m
.
setId
(
msg
.
id
);
m
.
setReceiptRequested
(
true
);
// TODO: check return code
client
->
sendPacket
(
m
);
bool
success
=
client
->
sendPacket
(
m
);
if
(
success
)
emit
model
->
setMessageAsSentRequested
(
msg
.
id
);
// TODO: handle error
}
void
MessageHandler
::
correctMessage
(
QString
toJid
,
QString
msgId
,
QString
body
)
{
// TODO: load old message from model and put everything into the new message
// instead of only the new body
// TODO: Add offline message cache and send when connnected again
if
(
client
->
state
()
!=
QXmppClient
::
ConnectedState
)
{
emit
kaidan
->
passiveNotificationRequested
(
tr
(
"Could not correct message, as a result of not being connected."
)
);
qWarning
()
<<
"[client] [MessageHandler] Could not correct message, as a result of "
"not being connected."
;
return
;
}
MessageModel
::
Message
msg
;
msg
.
author
=
client
->
configuration
().
jidBare
();
msg
.
recipient
=
toJid
;
msg
.
id
=
QXmppUtils
::
generateStanzaHash
(
48
);
msg
.
sentByMe
=
true
;
msg
.
message
=
body
;
msg
.
type
=
MessageType
::
MessageText
;
// text message without media
msg
.
edited
=
true
;
emit
model
->
updateMessageRequested
(
msgId
,
msg
);
QXmppMessage
m
(
msg
.
author
,
msg
.
recipient
,
body
);
m
.
setId
(
msg
.
id
);
m
.
setReceiptRequested
(
true
);
#if QXMPP_VERSION >= QT_VERSION_CHECK(1, 0, 0)
m
.
setReplaceId
(
msgId
);
#endif
bool
success
=
client
->
sendPacket
(
m
);
if
(
success
)
emit
model
->
setMessageAsSentRequested
(
msg
.
id
);
// TODO: handle error
}
void
MessageHandler
::
handleDiscoInfo
(
const
QXmppDiscoveryIq
&
info
)
...
...
src/MessageHandler.h
View file @
4da78fbc
...
...
@@ -74,6 +74,11 @@ public slots:
*/
void
sendMessage
(
QString
toJid
,
QString
body
);
/**
* Sends the corrected version of a message
*/
void
correctMessage
(
QString
toJid
,
QString
msgId
,
QString
newBody
);
/**
* Handles service discovery info and enables carbons if feature was found
*/
...
...
src/MessageModel.cpp
View file @
4da78fbc
...
...
@@ -107,6 +107,11 @@ MessageType MessageModel::messageTypeFromMimeType(const QMimeType &type)
return
MessageType
::
MessageFile
;
}
QString
MessageModel
::
lastMessageId
(
QString
jid
)
const
{
return
lastMsgIdCache
.
value
(
jid
,
""
);
}
void
MessageModel
::
setMessageAsSent
(
const
QString
msgId
)
{
for
(
int
i
=
0
;
i
<
rowCount
();
++
i
)
{
...
...
@@ -150,12 +155,15 @@ void MessageModel::updateMessage(const QString id, Message msg)
if
(
!
found
)
return
;
QString
newId
=
msg
.
id
.
isEmpty
()
?
id
:
msg
.
id
;
rec
.
setValue
(
"id"
,
newId
);
rec
.
setValue
(
"edited"
,
msg
.
edited
);
rec
.
setValue
(
"isSent"
,
msg
.
isSent
);
rec
.
setValue
(
"isDelivered"
,
msg
.
isDelivered
);
if
(
!
msg
.
timestamp
.
isEmpty
())
rec
.
setValue
(
"timestamp"
,
msg
.
timestamp
);
if
(
!
msg
.
message
.
isEmpty
())
rec
.
setValue
(
"message"
,
msg
.
message
);
if
(
!
msg
.
id
.
isEmpty
())
rec
.
setValue
(
"id"
,
msg
.
id
);
if
(
!
msg
.
mediaUrl
.
isEmpty
())
rec
.
setValue
(
"mediaUrl"
,
msg
.
mediaUrl
);
if
(
msg
.
mediaSize
)
...
...
@@ -173,6 +181,12 @@ void MessageModel::updateMessage(const QString id, Message msg)
setRecord
(
recId
,
rec
);
submitAll
();
// check if we're author/recipient
QVariant
jid
=
rec
.
value
(
"author"
).
toString
()
==
ownJid
?
rec
.
value
(
"recipient"
)
:
rec
.
value
(
"author"
);
// update last message id
lastMsgIdCache
[
jid
.
toString
()]
=
newId
;
}
void
MessageModel
::
addMessage
(
Message
msg
)
...
...
@@ -187,9 +201,10 @@ void MessageModel::addMessage(Message msg)
record
.
setValue
(
"timestamp"
,
msg
.
timestamp
);
record
.
setValue
(
"message"
,
msg
.
message
);
record
.
setValue
(
"id"
,
msg
.
id
);
record
.
setValue
(
"isSent"
,
!
msg
.
sentByMe
);
record
.
setValue
(
"isDelivered"
,
!
msg
.
sentByMe
);
record
.
setValue
(
"isSent"
,
msg
.
isSent
);
record
.
setValue
(
"isDelivered"
,
msg
.
isDelivered
);
record
.
setValue
(
"type"
,
(
quint8
)
msg
.
type
);
record
.
setValue
(
"edited"
,
msg
.
edited
);
record
.
setValue
(
"mediaUrl"
,
msg
.
mediaUrl
);
if
(
msg
.
mediaSize
)
record
.
setValue
(
"mediaSize"
,
msg
.
mediaSize
);
...
...
@@ -206,4 +221,11 @@ void MessageModel::addMessage(Message msg)
}
submitAll
();
// update last message id
if
(
!
msg
.
id
.
isEmpty
())
{
// check if we're author/recipient
QString
jid
=
msg
.
author
==
ownJid
?
msg
.
recipient
:
msg
.
author
;
lastMsgIdCache
[
jid
]
=
msg
.
id
;
}
}
src/MessageModel.h
View file @
4da78fbc
...
...
@@ -63,6 +63,9 @@ public:
QString
id
;
bool
sentByMe
;
MessageType
type
;
bool
edited
=
false
;
bool
isSent
=
false
;
bool
isDelivered
=
false
;
QString
mediaUrl
;
quint64
mediaSize
;
QString
mediaContentType
;
...
...
@@ -74,6 +77,14 @@ public:
static
MessageType
messageTypeFromMimeType
(
const
QMimeType
&
);
/**
* Returns the last message id of a contact
*
* The result can be empty, if the last message was sent in a previous session. This
* is, because we currently can't be sure if there were other messages since then.
*/
Q_INVOKABLE
QString
lastMessageId
(
QString
jid
)
const
;
signals:
/**
* Emitted when the user opens another chat to apply a filter to the db
...
...
@@ -103,6 +114,8 @@ private:
QSqlDatabase
*
database
;
QString
ownJid
;
QHash
<
QString
,
QString
>
lastMsgIdCache
;
};
#endif // MESSAGEMODEL_H
src/UploadManager.cpp
View file @
4da78fbc
...
...
@@ -129,8 +129,10 @@ void UploadManager::handleUploadSucceeded(const QXmppHttpUpload *upload)
m
.
setOutOfBandUrl
(
upload
->
slot
().
getUrl
().
toEncoded
());
#endif
// TODO: check return code
client
->
sendPacket
(
m
);
bool
success
=
client
->
sendPacket
(
m
);
if
(
success
)
emit
msgModel
->
setMessageAsSentRequested
(
originalMsg
->
id
);
// TODO: handle error
messages
.
remove
(
upload
->
id
());
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment