Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
33600eee
Commit
33600eee
authored
Mar 07, 2019
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
No need for a separate `archive_id` value.
With MAM2 we can just use stanza-id
parent
be6a5d9c
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
363 additions
and
312 deletions
+363
-312
dist/converse.js
dist/converse.js
+108
-106
spec/mam.js
spec/mam.js
+141
-90
spec/messages.js
spec/messages.js
+15
-9
src/headless/converse-chatboxes.js
src/headless/converse-chatboxes.js
+32
-35
src/headless/converse-mam.js
src/headless/converse-mam.js
+40
-42
src/headless/converse-muc.js
src/headless/converse-muc.js
+27
-30
No files found.
dist/converse.js
View file @
33600eee
This diff is collapsed.
Click to expand it.
spec/mam.js
View file @
33600eee
This diff is collapsed.
Click to expand it.
spec/messages.js
View file @
33600eee
...
...
@@ -2223,7 +2223,7 @@
await
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
room
'
,
'
muc.example.com
'
,
'
dummy
'
);
const
view
=
_converse
.
chatboxviews
.
get
(
'
room@muc.example.com
'
);
spyOn
(
view
.
model
,
'
hasDuplicate
StanzaID
'
).
and
.
callThrough
();
spyOn
(
view
.
model
,
'
findDuplicateFrom
StanzaID
'
).
and
.
callThrough
();
let
stanza
=
u
.
toStanza
(
`
<message xmlns="jabber:client"
from="room@muc.example.com/some1"
...
...
@@ -2238,9 +2238,9 @@
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
await
test_utils
.
waitUntil
(()
=>
_converse
.
api
.
chats
.
get
().
length
);
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
messages
.
length
===
1
);
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
hasDuplicate
StanzaID
.
calls
.
count
()
===
1
);
let
result
=
await
view
.
model
.
hasDuplicate
StanzaID
.
calls
.
all
()[
0
].
returnValue
;
expect
(
result
).
toBe
(
false
);
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
findDuplicateFrom
StanzaID
.
calls
.
count
()
===
1
);
let
result
=
await
view
.
model
.
findDuplicateFrom
StanzaID
.
calls
.
all
()[
0
].
returnValue
;
expect
(
result
).
toBe
(
undefined
);
stanza
=
u
.
toStanza
(
`
<message xmlns="jabber:client"
...
...
@@ -2254,9 +2254,9 @@
<origin-id xmlns="urn:xmpp:sid:0" id="de305d54-75b4-431b-adb2-eb6b9e546013"/>
</message>`
);
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
hasDuplicate
StanzaID
.
calls
.
count
()
===
2
);
result
=
await
view
.
model
.
hasDuplicate
StanzaID
.
calls
.
all
()[
1
].
returnValue
;
expect
(
result
).
toBe
(
true
);
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
findDuplicateFrom
StanzaID
.
calls
.
count
()
===
2
);
result
=
await
view
.
model
.
findDuplicateFrom
StanzaID
.
calls
.
all
()[
1
].
returnValue
;
expect
(
result
instanceof
_converse
.
Message
).
toBe
(
true
);
expect
(
view
.
model
.
messages
.
length
).
toBe
(
1
);
done
();
}));
...
...
@@ -2477,7 +2477,13 @@
<origin-id xmlns="urn:xmpp:sid:0" id="
${
msg_obj
.
get
(
'
origin_id
'
)}
"/>
</message>`
);
await
view
.
model
.
onMessage
(
stanza
);
await
test_utils
.
waitUntil
(()
=>
view
.
el
.
querySelectorAll
(
'
.chat-msg__receipt
'
).
length
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__receipt
'
).
length
).
toBe
(
1
);
expect
(
view
.
model
.
messages
.
length
).
toBe
(
1
);
const
message
=
view
.
model
.
messages
.
at
(
0
);
expect
(
message
.
get
(
'
stanza_id lounge@localhost
'
)).
toBe
(
'
5f3dbc5e-e1d3-4077-a492-693f3769c7ad
'
);
expect
(
message
.
get
(
'
origin_id
'
)).
toBe
(
msg_obj
.
get
(
'
origin_id
'
));
done
();
}));
...
...
@@ -2518,9 +2524,9 @@
by="room@muc.example.com"/>
<origin-id xmlns="urn:xmpp:sid:0" id="
${
attrs
.
origin_id
}
"/>
</message>`
);
spyOn
(
view
.
model
,
'
handleReflection
'
).
and
.
callThrough
();
spyOn
(
view
.
model
,
'
updateMessage
'
).
and
.
callThrough
();
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
handleReflection
.
calls
.
count
()
===
1
);
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
updateMessage
.
calls
.
count
()
===
1
);
expect
(
view
.
model
.
messages
.
length
).
toBe
(
1
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
stanza_id room@muc.example.com
'
)).
toBe
(
"
5f3dbc5e-e1d3-4077-a492-693f3769c7ad
"
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
origin_id
'
)).
toBe
(
attrs
.
origin_id
);
...
...
src/headless/converse-chatboxes.js
View file @
33600eee
...
...
@@ -290,6 +290,10 @@ converse.plugins.add('converse-chatboxes', {
return
this
.
vcard
.
get
(
'
fullname
'
)
||
this
.
get
(
'
jid
'
);
},
updateMessage
(
message
,
stanza
)
{
// Overridden in converse-muc and converse-mam
},
handleMessageCorrection
(
stanza
)
{
const
replace
=
sizzle
(
`replace[xmlns="
${
Strophe
.
NS
.
MESSAGE_CORRECT
}
"]`
,
stanza
).
pop
();
if
(
replace
)
{
...
...
@@ -316,10 +320,14 @@ converse.plugins.add('converse-chatboxes', {
return
false
;
},
getDuplicateMessage
(
stanza
)
{
return
this
.
findDuplicateFromOriginID
(
stanza
)
||
this
.
findDuplicateFromStanzaID
(
stanza
);
},
findDuplicateFromOriginID
(
stanza
)
{
const
origin_id
=
sizzle
(
`origin-id[xmlns="
${
Strophe
.
NS
.
SID
}
"]`
,
stanza
).
pop
();
if
(
!
origin_id
)
{
return
false
;
return
null
;
}
return
this
.
messages
.
findWhere
({
'
origin_id
'
:
origin_id
.
getAttribute
(
'
id
'
),
...
...
@@ -327,23 +335,7 @@ converse.plugins.add('converse-chatboxes', {
});
},
async
hasDuplicateArchiveID
(
stanza
)
{
const
result
=
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
stanza
).
pop
();
if
(
!
result
)
{
return
false
;
}
const
by_jid
=
stanza
.
getAttribute
(
'
from
'
)
||
this
.
get
(
'
jid
'
);
const
supported
=
await
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
MAM
,
by_jid
);
if
(
!
supported
.
length
)
{
return
false
;
}
const
query
=
{};
query
[
`stanza_id
${
by_jid
}
`
]
=
result
.
getAttribute
(
'
id
'
);
const
msg
=
this
.
messages
.
findWhere
(
query
);
return
!
_
.
isNil
(
msg
);
},
async
hasDuplicateStanzaID
(
stanza
)
{
async
findDuplicateFromStanzaID
(
stanza
)
{
const
stanza_id
=
sizzle
(
`stanza-id[xmlns="
${
Strophe
.
NS
.
SID
}
"]`
,
stanza
).
pop
();
if
(
!
stanza_id
)
{
return
false
;
...
...
@@ -355,8 +347,7 @@ converse.plugins.add('converse-chatboxes', {
}
const
query
=
{};
query
[
`stanza_id
${
by_jid
}
`
]
=
stanza_id
.
getAttribute
(
'
id
'
);
const
msg
=
this
.
messages
.
findWhere
(
query
);
return
!
_
.
isNil
(
msg
);
return
this
.
messages
.
findWhere
(
query
);
},
...
...
@@ -654,6 +645,10 @@ converse.plugins.add('converse-chatboxes', {
return
attrs
;
},
isArchived
(
original_stanza
)
{
return
!
_
.
isNil
(
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
original_stanza
).
pop
());
},
getMessageAttributesFromStanza
(
stanza
,
original_stanza
)
{
/* Parses a passed in message stanza and returns an object
* of attributes.
...
...
@@ -666,8 +661,7 @@ converse.plugins.add('converse-chatboxes', {
* that contains the message stanza, if it was
* contained, otherwise it's the message stanza itself.
*/
const
archive
=
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
original_stanza
).
pop
(),
spoiler
=
sizzle
(
`spoiler[xmlns="
${
Strophe
.
NS
.
SPOILER
}
"]`
,
original_stanza
).
pop
(),
const
spoiler
=
sizzle
(
`spoiler[xmlns="
${
Strophe
.
NS
.
SPOILER
}
"]`
,
original_stanza
).
pop
(),
delay
=
sizzle
(
`delay[xmlns="
${
Strophe
.
NS
.
DELAY
}
"]`
,
original_stanza
).
pop
(),
text
=
_converse
.
chatboxes
.
getMessageBody
(
stanza
)
||
undefined
,
chat_state
=
stanza
.
getElementsByTagName
(
_converse
.
COMPOSING
).
length
&&
_converse
.
COMPOSING
||
...
...
@@ -678,7 +672,7 @@ converse.plugins.add('converse-chatboxes', {
const
attrs
=
_
.
extend
({
'
chat_state
'
:
chat_state
,
'
is_archived
'
:
!
_
.
isNil
(
archive
),
'
is_archived
'
:
this
.
isArchived
(
original_stanza
),
'
is_delayed
'
:
!
_
.
isNil
(
delay
),
'
is_spoiler
'
:
!
_
.
isNil
(
spoiler
),
'
is_single_emoji
'
:
text
?
u
.
isSingleEmoji
(
text
)
:
false
,
...
...
@@ -926,18 +920,21 @@ converse.plugins.add('converse-chatboxes', {
roster_nick
=
_
.
get
(
_converse
.
api
.
contacts
.
get
(
contact_jid
),
'
attributes.nickname
'
),
chatbox
=
this
.
getChatBox
(
contact_jid
,
{
'
nickname
'
:
roster_nick
},
has_body
);
if
(
chatbox
&&
!
chatbox
.
findDuplicateFromOriginID
(
stanza
)
&&
!
await
chatbox
.
hasDuplicateArchiveID
(
original_stanza
)
&&
!
await
chatbox
.
hasDuplicateStanzaID
(
stanza
)
&&
!
chatbox
.
handleMessageCorrection
(
stanza
)
&&
!
chatbox
.
handleReceipt
(
stanza
,
from_jid
,
is_carbon
,
is_me
)
&&
!
chatbox
.
handleChatMarker
(
stanza
,
from_jid
,
is_carbon
,
is_roster_contact
))
{
const
attrs
=
await
chatbox
.
getMessageAttributesFromStanza
(
stanza
,
original_stanza
);
if
(
attrs
[
'
chat_state
'
]
||
!
u
.
isEmptyMessage
(
attrs
))
{
const
msg
=
chatbox
.
messages
.
create
(
attrs
);
chatbox
.
incrementUnreadMsgCounter
(
msg
);
if
(
chatbox
)
{
const
message
=
await
chatbox
.
getDuplicateMessage
(
stanza
);
if
(
message
)
{
chatbox
.
updateMessage
(
message
,
original_stanza
);
}
if
(
!
message
&&
!
chatbox
.
handleMessageCorrection
(
stanza
)
&&
!
chatbox
.
handleReceipt
(
stanza
,
from_jid
,
is_carbon
,
is_me
)
&&
!
chatbox
.
handleChatMarker
(
stanza
,
from_jid
,
is_carbon
,
is_roster_contact
))
{
const
attrs
=
await
chatbox
.
getMessageAttributesFromStanza
(
stanza
,
original_stanza
);
if
(
attrs
[
'
chat_state
'
]
||
!
u
.
isEmptyMessage
(
attrs
))
{
const
msg
=
chatbox
.
messages
.
create
(
attrs
);
chatbox
.
incrementUnreadMsgCounter
(
msg
);
}
}
}
_converse
.
emit
(
'
message
'
,
{
'
stanza
'
:
original_stanza
,
'
chatbox
'
:
chatbox
});
...
...
src/headless/converse-mam.js
View file @
33600eee
...
...
@@ -23,17 +23,6 @@ const RSM_ATTRIBUTES = ['max', 'first', 'last', 'after', 'before', 'index', 'cou
const
MAM_ATTRIBUTES
=
[
'
with
'
,
'
start
'
,
'
end
'
];
function
getMessageArchiveID
(
stanza
)
{
// See https://xmpp.org/extensions/xep-0313.html#results
//
// The result messages MUST contain a <result/> element with an 'id'
// attribute that gives the current message's archive UID
const
result
=
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
stanza
).
pop
();
if
(
!
_
.
isUndefined
(
result
))
{
return
result
.
getAttribute
(
'
id
'
);
}
}
function
queryForArchivedMessages
(
_converse
,
options
,
callback
,
errback
)
{
/* Internal function, called by the "archive.query" API method.
*/
...
...
@@ -128,10 +117,38 @@ converse.plugins.add('converse-mam', {
// New functions which don't exist yet can also be added.
ChatBox
:
{
async
getMessageAttributesFromStanza
(
message
,
original_stanza
)
{
const
attrs
=
await
this
.
__super__
.
getMessageAttributesFromStanza
.
apply
(
this
,
arguments
);
attrs
.
archive_id
=
getMessageArchiveID
(
original_stanza
);
return
attrs
;
async
findDuplicateFromArchiveID
(
stanza
)
{
const
{
_converse
}
=
this
.
__super__
;
const
result
=
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
stanza
).
pop
();
if
(
!
result
)
{
return
null
;
}
const
by_jid
=
stanza
.
getAttribute
(
'
from
'
)
||
this
.
get
(
'
jid
'
);
const
supported
=
await
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
MAM
,
by_jid
);
if
(
!
supported
.
length
)
{
return
null
;
}
const
query
=
{};
query
[
`stanza_id
${
by_jid
}
`
]
=
result
.
getAttribute
(
'
id
'
);
return
this
.
messages
.
findWhere
(
query
);
},
async
getDuplicateMessage
(
stanza
)
{
const
message
=
await
this
.
__super__
.
getDuplicateMessage
.
apply
(
this
,
arguments
);
if
(
!
message
)
{
return
this
.
findDuplicateFromArchiveID
(
stanza
);
}
return
message
;
},
updateMessage
(
message
,
stanza
)
{
this
.
__super__
.
updateMessage
.
apply
(
this
,
arguments
);
if
(
message
&&
!
message
.
get
(
'
is_archived
'
))
{
message
.
save
(
_
.
extend
({
'
is_archived
'
:
this
.
isArchived
(
stanza
)
},
this
.
getStanzaIDs
(
stanza
)));
}
}
},
...
...
@@ -155,15 +172,11 @@ converse.plugins.add('converse-mam', {
if
(
_
.
isNil
(
most_recent_msg
))
{
this
.
fetchArchivedMessages
();
}
else
{
const
archive_id
=
most_recent_msg
.
get
(
'
archive_id
'
);
if
(
archive_id
)
{
this
.
fetchArchivedMessages
({
'
after
'
:
most_recent_msg
.
get
(
'
archive_id
'
)
});
const
stanza_id
=
most_recent_msg
.
get
(
`stanza_id
${
this
.
model
.
get
(
'
jid
'
)}
`
);
if
(
stanza_id
)
{
this
.
fetchArchivedMessages
({
'
after
'
:
stanza_id
});
}
else
{
this
.
fetchArchivedMessages
({
'
start
'
:
most_recent_msg
.
get
(
'
time
'
)
});
this
.
fetchArchivedMessages
({
'
start
'
:
most_recent_msg
.
get
(
'
time
'
)});
}
}
},
...
...
@@ -250,11 +263,10 @@ converse.plugins.add('converse-mam', {
const
{
_converse
}
=
this
.
__super__
;
if
(
this
.
content
.
scrollTop
===
0
&&
this
.
model
.
messages
.
length
)
{
const
oldest_message
=
this
.
model
.
messages
.
at
(
0
);
const
archive_id
=
oldest_message
.
get
(
'
archive_id
'
);
if
(
archive_id
)
{
this
.
fetchArchivedMessages
({
'
before
'
:
archive_id
});
const
by_jid
=
this
.
model
.
get
(
'
jid
'
);
const
stanza_id
=
oldest_message
.
get
(
`stanza_id
${
by_jid
}
`
);
if
(
stanza_id
)
{
this
.
fetchArchivedMessages
({
'
before
'
:
stanza_id
});
}
else
{
this
.
fetchArchivedMessages
({
'
end
'
:
oldest_message
.
get
(
'
time
'
)
...
...
@@ -264,20 +276,6 @@ converse.plugins.add('converse-mam', {
},
},
ChatRoom
:
{
isDuplicate
(
message
,
original_stanza
)
{
const
result
=
this
.
__super__
.
isDuplicate
.
apply
(
this
,
arguments
);
if
(
result
)
{
return
result
;
}
const
archive_id
=
getMessageArchiveID
(
original_stanza
);
if
(
archive_id
)
{
return
this
.
messages
.
filter
({
'
archive_id
'
:
archive_id
}).
length
>
0
;
}
}
},
ChatRoomView
:
{
initialize
()
{
...
...
src/headless/converse-muc.js
View file @
33600eee
...
...
@@ -972,33 +972,6 @@ converse.plugins.add('converse-muc', {
acknowledged[xmlns="
${
Strophe
.
NS
.
MARKERS
}
"]`
,
stanza
).
length
>
0
;
},
handleReflection
(
stanza
)
{
/* Handle a MUC reflected message and return true if so.
*
* Parameters:
* (XMLElement) stanza: The message stanza
*/
const
from
=
stanza
.
getAttribute
(
'
from
'
);
const
own_message
=
Strophe
.
getResourceFromJid
(
from
)
==
this
.
get
(
'
nick
'
);
if
(
own_message
)
{
const
msg
=
this
.
findDuplicateFromOriginID
(
stanza
);
if
(
msg
)
{
const
attrs
=
{};
const
stanza_id
=
sizzle
(
`stanza-id[xmlns="
${
Strophe
.
NS
.
SID
}
"]`
,
stanza
).
pop
();
const
by_jid
=
stanza_id
?
stanza_id
.
getAttribute
(
'
by
'
)
:
undefined
;
if
(
by_jid
)
{
const
key
=
`stanza_id
${
by_jid
}
`
;
attrs
[
key
]
=
stanza_id
.
getAttribute
(
'
id
'
);
}
if
(
!
msg
.
get
(
'
received
'
))
{
attrs
.
received
=
moment
().
format
();
}
msg
.
save
(
attrs
);
}
return
msg
?
true
:
false
;
}
},
subjectChangeHandled
(
attrs
)
{
/* Handle a subject change and return `true` if so.
*
...
...
@@ -1029,6 +1002,28 @@ converse.plugins.add('converse-muc', {
return
is_csn
&&
(
attrs
.
is_delayed
||
own_message
);
},
updateMessage
(
message
,
stanza
)
{
/* Make sure that the already cached message is updated with
* the stanza ID.
*/
_converse
.
ChatBox
.
prototype
.
updateMessage
.
call
(
this
,
message
,
stanza
);
const
from
=
stanza
.
getAttribute
(
'
from
'
);
const
own_message
=
Strophe
.
getResourceFromJid
(
from
)
==
this
.
get
(
'
nick
'
);
if
(
own_message
)
{
const
attrs
=
{};
const
stanza_id
=
sizzle
(
`stanza-id[xmlns="
${
Strophe
.
NS
.
SID
}
"]`
,
stanza
).
pop
();
const
by_jid
=
stanza_id
?
stanza_id
.
getAttribute
(
'
by
'
)
:
undefined
;
if
(
by_jid
)
{
const
key
=
`stanza_id
${
by_jid
}
`
;
attrs
[
key
]
=
stanza_id
.
getAttribute
(
'
id
'
);
}
if
(
!
message
.
get
(
'
received
'
))
{
attrs
.
received
=
moment
().
format
();
}
message
.
save
(
attrs
);
}
},
async
onMessage
(
stanza
)
{
/* Handler for all MUC messages sent to this groupchat.
*
...
...
@@ -1042,9 +1037,11 @@ converse.plugins.add('converse-muc', {
if
(
forwarded
)
{
stanza
=
forwarded
.
querySelector
(
'
message
'
);
}
if
(
this
.
handleReflection
(
stanza
)
||
await
this
.
hasDuplicateArchiveID
(
original_stanza
)
||
await
this
.
hasDuplicateStanzaID
(
stanza
)
||
const
message
=
await
this
.
getDuplicateMessage
(
original_stanza
);
if
(
message
)
{
this
.
updateMessage
(
message
,
original_stanza
);
}
if
(
message
||
this
.
handleMessageCorrection
(
stanza
)
||
this
.
isReceipt
(
stanza
)
||
this
.
isChatMarker
(
stanza
))
{
...
...
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