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
c1efb0d2
Commit
c1efb0d2
authored
Apr 19, 2020
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add an external API for sending presences
parent
edf7f6b8
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
68 additions
and
55 deletions
+68
-55
spec/controlbox.js
spec/controlbox.js
+6
-4
spec/presence.js
spec/presence.js
+17
-10
spec/xmppstatus.js
spec/xmppstatus.js
+4
-2
src/converse-rosterview.js
src/converse-rosterview.js
+1
-1
src/headless/converse-core.js
src/headless/converse-core.js
+0
-2
src/headless/converse-muc.js
src/headless/converse-muc.js
+1
-13
src/headless/converse-roster.js
src/headless/converse-roster.js
+2
-2
src/headless/converse-status.js
src/headless/converse-status.js
+37
-21
No files found.
spec/controlbox.js
View file @
c1efb0d2
...
...
@@ -140,8 +140,9 @@
const
view
=
_converse
.
xmppstatusview
;
modal
.
el
.
querySelector
(
'
label[for="radio-busy"]
'
).
click
();
// Change status to "dnd"
modal
.
el
.
querySelector
(
'
[type="submit"]
'
).
click
();
const
last_stanza
=
_converse
.
connection
.
sent_stanzas
.
pop
();
expect
(
Strophe
.
serialize
(
last_stanza
)).
toBe
(
const
sent_stanzas
=
_converse
.
connection
.
sent_stanzas
;
const
sent_presence
=
await
u
.
waitUntil
(()
=>
sent_stanzas
.
filter
(
s
=>
Strophe
.
serialize
(
s
).
match
(
'
presence
'
)).
pop
());
expect
(
Strophe
.
serialize
(
sent_presence
)).
toBe
(
`<presence xmlns="jabber:client">`
+
`<show>dnd</show>`
+
`<priority>0</priority>`
+
...
...
@@ -169,8 +170,9 @@
const
msg
=
'
I am happy
'
;
modal
.
el
.
querySelector
(
'
input[name="status_message"]
'
).
value
=
msg
;
modal
.
el
.
querySelector
(
'
[type="submit"]
'
).
click
();
const
last_stanza
=
_converse
.
connection
.
sent_stanzas
.
pop
();
expect
(
Strophe
.
serialize
(
last_stanza
)).
toBe
(
const
sent_stanzas
=
_converse
.
connection
.
sent_stanzas
;
const
sent_presence
=
await
u
.
waitUntil
(()
=>
sent_stanzas
.
filter
(
s
=>
Strophe
.
serialize
(
s
).
match
(
'
presence
'
)).
pop
());
expect
(
Strophe
.
serialize
(
sent_presence
)).
toBe
(
`<presence xmlns="jabber:client">`
+
`<status>I am happy</status>`
+
`<priority>0</priority>`
+
...
...
spec/presence.js
View file @
c1efb0d2
...
...
@@ -8,6 +8,7 @@
],
factory
);
}
(
this
,
function
(
jasmine
,
mock
,
test_utils
)
{
"
use strict
"
;
const
Strophe
=
converse
.
env
.
Strophe
;
const
u
=
converse
.
env
.
utils
;
// See: https://xmpp.org/rfcs/rfc3921.html
...
...
@@ -37,7 +38,7 @@
}));
it
(
"
has a given priority
"
,
mock
.
initConverse
((
done
,
_converse
)
=>
{
let
pres
=
_converse
.
xmppstatus
.
constructPresence
(
'
online
'
,
'
Hello world
'
);
let
pres
=
_converse
.
xmppstatus
.
constructPresence
(
'
online
'
,
null
,
'
Hello world
'
);
expect
(
pres
.
toLocaleString
()).
toBe
(
`<presence xmlns="jabber:client">`
+
`<status>Hello world</status>`
+
...
...
@@ -46,7 +47,7 @@
`</presence>`
);
_converse
.
priority
=
2
;
pres
=
_converse
.
xmppstatus
.
constructPresence
(
'
away
'
,
'
Going jogging
'
);
pres
=
_converse
.
xmppstatus
.
constructPresence
(
'
away
'
,
null
,
'
Going jogging
'
);
expect
(
pres
.
toLocaleString
()).
toBe
(
`<presence xmlns="jabber:client">`
+
`<show>away</show>`
+
...
...
@@ -57,7 +58,7 @@
);
delete
_converse
.
priority
;
pres
=
_converse
.
xmppstatus
.
constructPresence
(
'
dnd
'
,
'
Doing taxes
'
);
pres
=
_converse
.
xmppstatus
.
constructPresence
(
'
dnd
'
,
null
,
'
Doing taxes
'
);
expect
(
pres
.
toLocaleString
()).
toBe
(
`<presence xmlns="jabber:client">`
+
`<show>dnd</show>`
+
...
...
@@ -75,8 +76,6 @@
async
(
done
,
_converse
)
=>
{
test_utils
.
openControlBox
(
_converse
);
const
view
=
_converse
.
xmppstatusview
;
spyOn
(
view
.
model
,
'
sendPresence
'
).
and
.
callThrough
();
spyOn
(
_converse
.
connection
,
'
send
'
).
and
.
callThrough
();
const
cbview
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
);
...
...
@@ -86,8 +85,10 @@
const
msg
=
'
My custom status
'
;
modal
.
el
.
querySelector
(
'
input[name="status_message"]
'
).
value
=
msg
;
modal
.
el
.
querySelector
(
'
[type="submit"]
'
).
click
();
expect
(
view
.
model
.
sendPresence
).
toHaveBeenCalled
();
expect
(
_converse
.
connection
.
send
.
calls
.
mostRecent
().
args
[
0
].
toLocaleString
())
const
sent_stanzas
=
_converse
.
connection
.
sent_stanzas
;
let
sent_presence
=
await
u
.
waitUntil
(()
=>
sent_stanzas
.
filter
(
s
=>
Strophe
.
serialize
(
s
).
match
(
'
presence
'
)).
pop
());
expect
(
Strophe
.
serialize
(
sent_presence
))
.
toBe
(
`<presence xmlns="jabber:client">`
+
`<status>My custom status</status>`
+
`<priority>0</priority>`
+
...
...
@@ -100,10 +101,16 @@
await
u
.
waitUntil
(()
=>
modal
.
el
.
getAttribute
(
'
aria-hidden
'
)
===
"
false
"
,
1000
);
modal
.
el
.
querySelector
(
'
label[for="radio-busy"]
'
).
click
();
// Change status to "dnd"
modal
.
el
.
querySelector
(
'
[type="submit"]
'
).
click
();
expect
(
_converse
.
connection
.
send
.
calls
.
mostRecent
().
args
[
0
].
toLocaleString
())
.
toBe
(
`<presence xmlns="jabber:client"><show>dnd</show><status>My custom status</status><priority>0</priority>`
+
await
u
.
waitUntil
(()
=>
sent_stanzas
.
filter
(
s
=>
Strophe
.
serialize
(
s
).
match
(
'
presence
'
)).
length
===
2
);
sent_presence
=
sent_stanzas
.
filter
(
s
=>
Strophe
.
serialize
(
s
).
match
(
'
presence
'
)).
pop
();
expect
(
Strophe
.
serialize
(
sent_presence
))
.
toBe
(
`<presence xmlns="jabber:client">`
+
`<show>dnd</show>`
+
`<status>My custom status</status>`
+
`<priority>0</priority>`
+
`<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`
+
`</presence>`
)
`</presence>`
)
done
();
}));
});
...
...
spec/xmppstatus.js
View file @
c1efb0d2
(
function
(
root
,
factory
)
{
define
([
"
jasmine
"
,
"
mock
"
],
factory
);
}
(
this
,
function
(
jasmine
,
mock
)
{
const
u
=
converse
.
env
.
utils
;
return
describe
(
"
The XMPPStatus model
"
,
function
()
{
it
(
"
won't send <show>online</show> when setting a custom status message
"
,
mock
.
initConverse
((
done
,
_converse
)
=>
{
it
(
"
won't send <show>online</show> when setting a custom status message
"
,
mock
.
initConverse
(
async
(
done
,
_converse
)
=>
{
_converse
.
xmppstatus
.
save
({
'
status
'
:
'
online
'
});
spyOn
(
_converse
.
connection
,
'
send
'
);
_converse
.
api
.
user
.
status
.
message
.
set
(
"
I'm also happy!
"
);
expect
(
_converse
.
connection
.
send
).
toHaveBeenCalled
(
);
await
u
.
waitUntil
(()
=>
_converse
.
connection
.
send
.
calls
.
count
()
);
const
stanza
=
_converse
.
connection
.
send
.
calls
.
argsFor
(
0
)[
0
].
tree
();
expect
(
stanza
.
childNodes
.
length
).
toBe
(
3
);
expect
(
stanza
.
querySelectorAll
(
'
status
'
).
length
).
toBe
(
1
);
...
...
src/converse-rosterview.js
View file @
c1efb0d2
...
...
@@ -834,7 +834,7 @@ converse.plugins.add('converse-rosterview', {
u
.
addClass
(
'
fa-spin
'
,
ev
.
target
);
_converse
.
roster
.
data
.
save
(
'
version
'
,
null
);
await
_converse
.
roster
.
fetchFromServer
();
_converse
.
xmppstatus
.
sendPresence
();
api
.
user
.
presence
.
send
();
u
.
removeClass
(
'
fa-spin
'
,
ev
.
target
);
},
...
...
src/headless/converse-core.js
View file @
c1efb0d2
...
...
@@ -90,7 +90,6 @@ const PROMISES = [
'
connectionInitialized
'
,
'
initialized
'
,
'
pluginsInitialized
'
,
'
statusInitialized
'
];
// Core plugins are whitelisted automatically
...
...
@@ -712,7 +711,6 @@ export const api = _converse.api = {
* * [rosterContactsFetched](/docs/html/events.html#rosterContactsFetched)
* * [rosterGroupsFetched](/docs/html/events.html#rosterGroupsFetched)
* * [rosterInitialized](/docs/html/events.html#rosterInitialized)
* * [statusInitialized](/docs/html/events.html#statusInitialized)
* * [roomsPanelRendered](/docs/html/events.html#roomsPanelRendered)
*
* The various plugins might also provide promises, and they do this by using the
...
...
src/headless/converse-muc.js
View file @
c1efb0d2
...
...
@@ -852,7 +852,7 @@ converse.plugins.add('converse-muc', {
}
}
if
(
api
.
connection
.
connected
())
{
this
.
sendUnavailablePresence
(
exit_msg
);
api
.
user
.
presence
.
send
(
'
unavailable
'
,
this
.
getRoomJIDAndNick
(),
exit_msg
);
}
u
.
safeSave
(
this
.
session
,
{
'
connection_status
'
:
converse
.
ROOMSTATUS
.
DISCONNECTED
});
this
.
removeHandlers
();
...
...
@@ -877,18 +877,6 @@ converse.plugins.add('converse-muc', {
return
self
&&
self
.
isModerator
()
&&
api
.
disco
.
supports
(
Strophe
.
NS
.
MODERATE
,
this
.
get
(
'
jid
'
));
},
sendUnavailablePresence
(
exit_msg
)
{
const
presence
=
$pres
({
type
:
"
unavailable
"
,
from
:
_converse
.
connection
.
jid
,
to
:
this
.
getRoomJIDAndNick
()
});
if
(
exit_msg
!==
null
)
{
presence
.
c
(
"
status
"
,
exit_msg
);
}
_converse
.
connection
.
sendPresence
(
presence
);
},
/**
* Return an array of unique nicknames based on all occupants and messages in this MUC.
* @private
...
...
src/headless/converse-roster.js
View file @
c1efb0d2
...
...
@@ -80,7 +80,7 @@ converse.plugins.add('converse-roster', {
_converse
.
sendInitialPresence
=
function
()
{
if
(
_converse
.
send_initial_presence
)
{
_converse
.
xmppstatus
.
sendPresence
();
api
.
user
.
presence
.
send
();
}
};
...
...
@@ -771,7 +771,7 @@ converse.plugins.add('converse-roster', {
//
// As a workaround for now we simply send our presence again,
// otherwise we're treated as offline.
_converse
.
xmppstatus
.
sendPresence
();
api
.
user
.
presence
.
send
();
}
},
...
...
src/headless/converse-status.js
View file @
c1efb0d2
...
...
@@ -23,6 +23,7 @@ converse.plugins.add('converse-status', {
default_state
:
'
online
'
,
priority
:
0
,
});
api
.
promises
.
add
([
'
statusInitialized
'
]);
_converse
.
XMPPStatus
=
Model
.
extend
({
defaults
()
{
...
...
@@ -35,7 +36,7 @@ converse.plugins.add('converse-status', {
return
;
}
if
(
'
status
'
in
item
.
changed
||
'
status_message
'
in
item
.
changed
)
{
this
.
sendPresence
(
this
.
get
(
'
status
'
)
,
this
.
get
(
'
status_message
'
));
api
.
user
.
presence
.
send
(
this
.
get
(
'
status
'
),
null
,
this
.
get
(
'
status_message
'
));
}
});
},
...
...
@@ -49,12 +50,11 @@ converse.plugins.add('converse-status', {
return
''
;
},
constructPresence
(
type
,
status_message
)
{
let
presence
;
constructPresence
(
type
,
to
=
null
,
status_message
)
{
type
=
isString
(
type
)
?
type
:
(
this
.
get
(
'
status
'
)
||
api
.
settings
.
get
(
"
default_state
"
));
status_message
=
isString
(
status_message
)
?
status_message
:
this
.
get
(
'
status_message
'
);
// Most of these presence types are actually not explicitly sent,
// but I add all of them here for reference and future proofing.
let
presence
;
const
attrs
=
{
to
};
if
((
type
===
'
unavailable
'
)
||
(
type
===
'
probe
'
)
||
(
type
===
'
error
'
)
||
...
...
@@ -62,14 +62,17 @@ converse.plugins.add('converse-status', {
(
type
===
'
unsubscribed
'
)
||
(
type
===
'
subscribe
'
)
||
(
type
===
'
subscribed
'
))
{
presence
=
$pres
({
'
type
'
:
type
});
attrs
[
'
type
'
]
=
type
;
presence
=
$pres
(
attrs
);
}
else
if
(
type
===
'
offline
'
)
{
presence
=
$pres
({
'
type
'
:
'
unavailable
'
});
attrs
[
'
type
'
]
=
'
unavailable
'
;
presence
=
$pres
(
attrs
);
}
else
if
(
type
===
'
online
'
)
{
presence
=
$pres
();
presence
=
$pres
(
attrs
);
}
else
{
presence
=
$pres
().
c
(
'
show
'
).
t
(
type
).
up
();
presence
=
$pres
(
attrs
).
c
(
'
show
'
).
t
(
type
).
up
();
}
if
(
status_message
)
{
presence
.
c
(
'
status
'
).
t
(
status_message
).
up
();
}
...
...
@@ -82,10 +85,6 @@ converse.plugins.add('converse-status', {
presence
.
c
(
'
idle
'
,
{
xmlns
:
Strophe
.
NS
.
IDLE
,
since
:
idle_since
.
toISOString
()});
}
return
presence
;
},
sendPresence
(
type
,
status_message
)
{
api
.
send
(
this
.
constructPresence
(
type
,
status_message
));
}
});
...
...
@@ -118,7 +117,7 @@ converse.plugins.add('converse-status', {
}
if
(
_converse
.
idle
)
{
_converse
.
idle
=
false
;
_converse
.
xmppstatus
.
sendPresence
();
api
.
user
.
presence
.
send
();
}
if
(
_converse
.
auto_changed_status
===
true
)
{
_converse
.
auto_changed_status
=
false
;
...
...
@@ -148,7 +147,7 @@ converse.plugins.add('converse-status', {
_converse
.
idle_seconds
>
api
.
settings
.
get
(
"
idle_presence_timeout
"
)
&&
!
_converse
.
idle
)
{
_converse
.
idle
=
true
;
_converse
.
xmppstatus
.
sendPresence
();
api
.
user
.
presence
.
send
();
}
if
(
api
.
settings
.
get
(
"
auto_away
"
)
>
0
&&
_converse
.
idle_seconds
>
api
.
settings
.
get
(
"
auto_away
"
)
&&
...
...
@@ -245,21 +244,39 @@ converse.plugins.add('converse-status', {
/************************ BEGIN API ************************/
Object
.
assign
(
_converse
.
api
.
user
,
{
/**
* @namespace _converse.api.user.presence
* @memberOf _converse.api.user
*/
presence
:
{
/**
* Send out a presence stanza
* @method _converse.api.user.presence.send
* @param { String } type
* @param { String } to
* @param { String } [status] - An optional status message
*/
async
send
(
type
,
to
,
status
)
{
await
api
.
waitUntil
(
'
statusInitialized
'
);
api
.
send
(
_converse
.
xmppstatus
.
constructPresence
(
type
,
to
,
status
));
}
},
/**
* Set and get the user's chat status, also called their *availability*.
*
* @namespace _converse.api.user.status
* @memberOf _converse.api.user
*/
status
:
{
/**
Return the current user's availability status.
*
/**
*
Return the current user's availability status.
* @method _converse.api.user.status.get
* @example _converse.api.user.status.get();
*/
get
()
{
return
_converse
.
xmppstatus
.
get
(
'
status
'
);
},
/**
* The user's status can be set to one of the following values:
*
...
...
@@ -267,8 +284,8 @@ converse.plugins.add('converse-status', {
* @param {string} value The user's chat status (e.g. 'away', 'dnd', 'offline', 'online', 'unavailable' or 'xa')
* @param {string} [message] A custom status message
*
* @example
this.
_converse.api.user.status.set('dnd');
* @example
this.
_converse.api.user.status.set('dnd', 'In a meeting');
* @example _converse.api.user.status.set('dnd');
* @example _converse.api.user.status.set('dnd', 'In a meeting');
*/
set
(
value
,
message
)
{
const
data
=
{
'
status
'
:
value
};
...
...
@@ -280,7 +297,6 @@ converse.plugins.add('converse-status', {
if
(
isString
(
message
))
{
data
.
status_message
=
message
;
}
_converse
.
xmppstatus
.
sendPresence
(
value
);
_converse
.
xmppstatus
.
save
(
data
);
},
...
...
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