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
8d002946
Commit
8d002946
authored
Feb 14, 2019
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use `origin-id` to check for reflected messages.
Also, store the returned `stanza-id` on the message.
parent
6eb05be4
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
114 additions
and
51 deletions
+114
-51
CHANGES.md
CHANGES.md
+1
-0
dist/converse.js
dist/converse.js
+23
-13
spec/messages.js
spec/messages.js
+59
-22
spec/muc.js
spec/muc.js
+12
-7
src/headless/converse-muc.js
src/headless/converse-muc.js
+18
-9
tests/utils.js
tests/utils.js
+1
-0
No files found.
CHANGES.md
View file @
8d002946
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
-
Accessibility: Tag the chat-content as an ARIA live region, for screen readers
-
Accessibility: Tag the chat-content as an ARIA live region, for screen readers
-
Set releases URL to new Github repo
-
Set releases URL to new Github repo
-
Rudimentary support for XEP-0333 chat markers
-
Rudimentary support for XEP-0333 chat markers
-
Better support for XEP-0359
`stanza-id`
and
`origin-id`
elements.
-
#1369 Don't wrongly interpret message with
`subject`
as a topic change.
-
#1369 Don't wrongly interpret message with
`subject`
as a topic change.
-
#1405 Status of contacts list are not displayed properly
-
#1405 Status of contacts list are not displayed properly
-
#1408 New config option
`roomconfig_whitelist`
-
#1408 New config option
`roomconfig_whitelist`
...
...
dist/converse.js
View file @
8d002946
...
@@ -66942,7 +66942,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
...
@@ -66942,7 +66942,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
const stanza_id = sizzle(`stanza-id[xmlns="${Strophe.NS.SID}"]`, message).pop();
const stanza_id = sizzle(`stanza-id[xmlns="${Strophe.NS.SID}"]`, message).pop();
if (!stanza_id) {
if (!stanza_id) {
return;
return
false
;
}
}
const by_jid = stanza_id.getAttribute('by');
const by_jid = stanza_id.getAttribute('by');
...
@@ -66992,22 +66992,32 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
...
@@ -66992,22 +66992,32 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
const own_message = Strophe.getResourceFromJid(from) == this.get('nick');
const own_message = Strophe.getResourceFromJid(from) == this.get('nick');
if (own_message) {
if (own_message) {
const msgid = stanza.getAttribute('id'),
const origin_id = sizzle(`origin-id[xmlns="${Strophe.NS.SID}"]`, stanza).pop();
jid = stanza.getAttribute('from'); // TODO: use stanza-id?
if (!origin_id) {
return false;
}
if (msgid) {
const msg = this.messages.findWhere({
const msg = this.messages.findWhere({
'msgid': msgid
,
'origin_id': origin_id.getAttribute('id')
,
'from': jid
'sender': 'me'
});
});
if (msg && msg.get('sender') === 'me' && !msg.get('received')) {
if (msg) {
msg.save({
const stanza_id = sizzle(`stanza-id[xmlns="${Strophe.NS.SID}"]`, stanza).pop();
'received': moment().format()
const attrs = {
});
'stanza_id': stanza_id ? stanza_id.getAttribute('id') : undefined,
return true;
'stanza_id_by_jid': stanza_id ? stanza_id.getAttribute('by') : undefined
};
if (!msg.get('received')) {
attrs.received = moment().format();
}
}
msg.save(attrs);
}
}
return msg ? true : false;
}
}
},
},
spec/messages.js
View file @
8d002946
...
@@ -2208,18 +2208,7 @@
...
@@ -2208,18 +2208,7 @@
null
,
[
'
rosterGroupsFetched
'
],
{},
null
,
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
async
function
(
done
,
_converse
)
{
const
features
=
[
await
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
room
'
,
'
muc.example.com
'
,
'
dummy
'
);
'
http://jabber.org/protocol/muc
'
,
'
jabber:iq:register
'
,
'
muc_passwordprotected
'
,
'
muc_hidden
'
,
'
muc_temporary
'
,
'
muc_membersonly
'
,
'
muc_unmoderated
'
,
'
muc_nonanonymous
'
,
Strophe
.
NS
.
SID
,
];
await
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
room
'
,
'
muc.example.com
'
,
'
dummy
'
,
features
);
const
view
=
_converse
.
chatboxviews
.
get
(
'
room@muc.example.com
'
);
const
view
=
_converse
.
chatboxviews
.
get
(
'
room@muc.example.com
'
);
spyOn
(
view
.
model
,
'
isDuplicate
'
).
and
.
callThrough
();
spyOn
(
view
.
model
,
'
isDuplicate
'
).
and
.
callThrough
();
let
stanza
=
u
.
toStanza
(
`
let
stanza
=
u
.
toStanza
(
`
...
@@ -2464,20 +2453,68 @@
...
@@ -2464,20 +2453,68 @@
});
});
await
new
Promise
((
resolve
,
reject
)
=>
view
.
once
(
'
messageInserted
'
,
resolve
));
await
new
Promise
((
resolve
,
reject
)
=>
view
.
once
(
'
messageInserted
'
,
resolve
));
const
msg_obj
=
view
.
model
.
messages
.
at
(
0
);
const
msg_obj
=
view
.
model
.
messages
.
at
(
0
);
const
msg_id
=
msg_obj
.
get
(
'
msgid
'
);
const
stanza
=
u
.
toStanza
(
`
const
from
=
msg_obj
.
get
(
'
from
'
);
<message xmlns="jabber:client"
const
body
=
msg_obj
.
get
(
'
message
'
);
from="
${
msg_obj
.
get
(
'
from
'
)}
"
const
msg
=
$msg
({
to="
${
_converse
.
connection
.
jid
}
"
'
from
'
:
from
,
type="groupchat">
'
id
'
:
msg_id
,
<body>
${
msg_obj
.
get
(
'
message
'
)}
</body>
'
to
'
:
'
dummy@localhost
'
,
<stanza-id xmlns="urn:xmpp:sid:0"
'
type
'
:
'
groupchat
'
,
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
}).
c
(
'
body
'
).
t
(
body
).
up
().
tree
();
by="lounge@localhost"/>
await
view
.
model
.
onMessage
(
msg
);
<origin-id xmlns="urn:xmpp:sid:0" id="
${
msg_obj
.
get
(
'
origin_id
'
)}
"/>
</message>`
);
await
view
.
model
.
onMessage
(
stanza
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__receipt
'
).
length
).
toBe
(
1
);
expect
(
view
.
el
.
querySelectorAll
(
'
.chat-msg__receipt
'
).
length
).
toBe
(
1
);
done
();
done
();
}));
}));
it
(
"
gets updated with its stanza-id upon MUC reflection
"
,
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
],
{},
async
function
(
done
,
_converse
)
{
await
test_utils
.
openAndEnterChatRoom
(
_converse
,
'
room
'
,
'
muc.example.com
'
,
'
dummy
'
);
const
view
=
_converse
.
chatboxviews
.
get
(
'
room@muc.example.com
'
);
const
attrs
=
{
'
id
'
:
_converse
.
connection
.
getUniqueId
(),
'
origin_id
'
:
_converse
.
connection
.
getUniqueId
(),
'
fullname
'
:
'
dummy
'
,
'
references
'
:
[],
'
from
'
:
_converse
.
connection
.
jid
,
'
sender
'
:
'
me
'
,
'
time
'
:
moment
().
format
(),
'
message
'
:
'
Hello world
'
,
'
is_spoiler
'
:
false
,
'
type
'
:
'
groupchat
'
}
view
.
model
.
sendMessage
(
attrs
);
await
test_utils
.
waitUntil
(()
=>
_converse
.
api
.
chats
.
get
().
length
);
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
messages
.
length
===
1
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
stanza_id
'
)).
toBeUndefined
();
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
origin_id
'
)).
toBe
(
attrs
.
origin_id
);
const
stanza
=
u
.
toStanza
(
`
<message xmlns="jabber:client"
from="room@muc.example.com/dummy"
to="
${
_converse
.
connection
.
jid
}
"
type="groupchat">
<body>Hello world</body>
<stanza-id xmlns="urn:xmpp:sid:0"
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
by="room@muc.example.com"/>
<origin-id xmlns="urn:xmpp:sid:0" id="
${
attrs
.
origin_id
}
"/>
</message>`
);
spyOn
(
view
.
model
,
'
reflectionHandled
'
).
and
.
callThrough
();
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
await
test_utils
.
waitUntil
(()
=>
view
.
model
.
reflectionHandled
.
calls
.
count
()
===
1
);
expect
(
view
.
model
.
messages
.
length
).
toBe
(
1
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
stanza_id
'
)).
toBe
(
"
5f3dbc5e-e1d3-4077-a492-693f3769c7ad
"
);
expect
(
view
.
model
.
messages
.
at
(
0
).
get
(
'
origin_id
'
)).
toBe
(
attrs
.
origin_id
);
done
();
}));
it
(
"
can cause a delivery receipt to be returned
"
,
it
(
"
can cause a delivery receipt to be returned
"
,
mock
.
initConverse
(
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
],
{},
null
,
[
'
rosterGroupsFetched
'
],
{},
...
...
spec/muc.js
View file @
8d002946
...
@@ -1869,13 +1869,18 @@
...
@@ -1869,13 +1869,18 @@
// Let's check that if we receive the same message again, it's
// Let's check that if we receive the same message again, it's
// not shown.
// not shown.
const
message
=
$msg
({
const
stanza
=
u
.
toStanza
(
`
from
:
'
lounge@localhost/dummy
'
,
<message xmlns="jabber:client"
to
:
'
dummy@localhost.com
'
,
from="lounge@localhost/dummy"
type
:
'
groupchat
'
,
to="
${
_converse
.
connection
.
jid
}
"
id
:
view
.
model
.
messages
.
at
(
0
).
get
(
'
msgid
'
)
type="groupchat">
}).
c
(
'
body
'
).
t
(
text
);
<body>
${
text
}
</body>
await
view
.
model
.
onMessage
(
message
.
nodeTree
);
<stanza-id xmlns="urn:xmpp:sid:0"
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
by="lounge@localhost"/>
<origin-id xmlns="urn:xmpp:sid:0" id="
${
view
.
model
.
messages
.
at
(
0
).
get
(
'
origin_id
'
)}
"/>
</message>`
);
await
view
.
model
.
onMessage
(
stanza
);
expect
(
chat_content
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
chat_content
.
querySelectorAll
(
'
.chat-msg
'
).
length
).
toBe
(
1
);
expect
(
sizzle
(
'
.chat-msg__text:last
'
).
pop
().
textContent
).
toBe
(
text
);
expect
(
sizzle
(
'
.chat-msg__text:last
'
).
pop
().
textContent
).
toBe
(
text
);
expect
(
view
.
model
.
messages
.
length
).
toBe
(
1
);
expect
(
view
.
model
.
messages
.
length
).
toBe
(
1
);
...
...
src/headless/converse-muc.js
View file @
8d002946
...
@@ -999,17 +999,26 @@ converse.plugins.add('converse-muc', {
...
@@ -999,17 +999,26 @@ converse.plugins.add('converse-muc', {
const
from
=
stanza
.
getAttribute
(
'
from
'
);
const
from
=
stanza
.
getAttribute
(
'
from
'
);
const
own_message
=
Strophe
.
getResourceFromJid
(
from
)
==
this
.
get
(
'
nick
'
);
const
own_message
=
Strophe
.
getResourceFromJid
(
from
)
==
this
.
get
(
'
nick
'
);
if
(
own_message
)
{
if
(
own_message
)
{
const
msgid
=
stanza
.
getAttribute
(
'
id
'
),
const
origin_id
=
sizzle
(
`origin-id[xmlns="
${
Strophe
.
NS
.
SID
}
"]`
,
stanza
).
pop
();
jid
=
stanza
.
getAttribute
(
'
from
'
);
if
(
!
origin_id
)
{
return
false
;
// TODO: use stanza-id?
}
if
(
msgid
)
{
const
msg
=
this
.
messages
.
findWhere
({
const
msg
=
this
.
messages
.
findWhere
({
'
msgid
'
:
msgid
,
'
from
'
:
jid
});
'
origin_id
'
:
origin_id
.
getAttribute
(
'
id
'
),
if
(
msg
&&
msg
.
get
(
'
sender
'
)
===
'
me
'
&&
!
msg
.
get
(
'
received
'
))
{
'
sender
'
:
'
me
'
msg
.
save
({
'
received
'
:
moment
().
format
()});
});
return
true
;
if
(
msg
)
{
const
stanza_id
=
sizzle
(
`stanza-id[xmlns="
${
Strophe
.
NS
.
SID
}
"]`
,
stanza
).
pop
();
const
attrs
=
{
'
stanza_id
'
:
stanza_id
?
stanza_id
.
getAttribute
(
'
id
'
)
:
undefined
,
'
stanza_id_by_jid
'
:
stanza_id
?
stanza_id
.
getAttribute
(
'
by
'
)
:
undefined
}
if
(
!
msg
.
get
(
'
received
'
))
{
attrs
.
received
=
moment
().
format
();
}
}
msg
.
save
(
attrs
);
}
}
return
msg
?
true
:
false
;
}
}
},
},
...
...
tests/utils.js
View file @
8d002946
...
@@ -142,6 +142,7 @@
...
@@ -142,6 +142,7 @@
features
=
features
.
length
?
features
:
[
features
=
features
.
length
?
features
:
[
'
http://jabber.org/protocol/muc
'
,
'
http://jabber.org/protocol/muc
'
,
'
jabber:iq:register
'
,
'
jabber:iq:register
'
,
Strophe
.
NS
.
SID
,
'
muc_passwordprotected
'
,
'
muc_passwordprotected
'
,
'
muc_hidden
'
,
'
muc_hidden
'
,
'
muc_temporary
'
,
'
muc_temporary
'
,
...
...
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