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
1ef29bee
Commit
1ef29bee
authored
May 24, 2019
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use composition instead of overrides
parent
d2b1f2c9
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
735 additions
and
784 deletions
+735
-784
docs/source/plugin_development.rst
docs/source/plugin_development.rst
+135
-147
src/converse-bookmark-views.js
src/converse-bookmark-views.js
+62
-66
src/converse-controlbox.js
src/converse-controlbox.js
+2
-18
src/converse-dragresize.js
src/converse-dragresize.js
+140
-158
src/converse-minimize.js
src/converse-minimize.js
+109
-88
src/converse-muc-views.js
src/converse-muc-views.js
+31
-28
src/converse-oauth.js
src/converse-oauth.js
+2
-2
src/converse-omemo.js
src/converse-omemo.js
+118
-123
src/converse-register.js
src/converse-register.js
+49
-45
src/converse-rosterview.js
src/converse-rosterview.js
+10
-61
src/converse-singleton.js
src/converse-singleton.js
+1
-1
src/headless/converse-bookmarks.js
src/headless/converse-bookmarks.js
+1
-3
src/headless/converse-core.js
src/headless/converse-core.js
+1
-1
src/headless/converse-mam.js
src/headless/converse-mam.js
+42
-43
src/headless/converse-roster.js
src/headless/converse-roster.js
+32
-0
No files found.
docs/source/plugin_development.rst
View file @
1ef29bee
This diff is collapsed.
Click to expand it.
src/converse-bookmark-views.js
View file @
1ef29bee
...
...
@@ -42,20 +42,67 @@ converse.plugins.add('converse-bookmark-views', {
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
ChatRoomView
:
{
events
:
{
'
click .toggle-bookmark
'
:
'
toggleBookmark
'
},
async
renderHeading
()
{
this
.
__super__
.
renderHeading
.
apply
(
this
,
arguments
);
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
allow_bookmarks
)
{
const
supported
=
await
_converse
.
checkBookmarksSupport
();
if
(
supported
)
{
this
.
renderBookmarkToggle
();
}
}
}
}
},
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
change:bookmarked
'
,
this
.
onBookmarked
,
this
);
this
.
setBookmarkState
();
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
,
{
__
}
=
_converse
;
// Configuration values for this plugin
// ====================================
// Refer to docs/source/configuration.rst for explanations of these
// configuration settings.
_converse
.
api
.
settings
.
update
({
hide_open_bookmarks
:
true
,
muc_respect_autojoin
:
true
});
Object
.
assign
(
_converse
,
{
removeBookmarkViaEvent
(
ev
)
{
/* Remove a bookmark as determined by the passed in
* event.
*/
ev
.
preventDefault
();
const
name
=
ev
.
target
.
getAttribute
(
'
data-bookmark-name
'
);
const
jid
=
ev
.
target
.
getAttribute
(
'
data-room-jid
'
);
if
(
confirm
(
__
(
"
Are you sure you want to remove the bookmark
\"
%1$s
\"
?
"
,
name
)))
{
_
.
invokeMap
(
_converse
.
bookmarks
.
where
({
'
jid
'
:
jid
}),
Backbone
.
Model
.
prototype
.
destroy
);
}
},
addBookmarkViaEvent
(
ev
)
{
/* Add a bookmark as determined by the passed in
* event.
*/
ev
.
preventDefault
();
const
jid
=
ev
.
target
.
getAttribute
(
'
data-room-jid
'
);
const
chatroom
=
_converse
.
api
.
rooms
.
open
(
jid
,
{
'
bring_to_foreground
'
:
true
});
_converse
.
chatboxviews
.
get
(
jid
).
renderBookmarkForm
();
},
});
const
bookmarkableChatRoomView
=
{
renderBookmarkToggle
()
{
if
(
this
.
el
.
querySelector
(
'
.chat-head .toggle-bookmark
'
))
{
return
;
...
...
@@ -80,21 +127,7 @@ converse.plugins.add('converse-bookmark-views', {
}
},
async
renderHeading
()
{
this
.
__super__
.
renderHeading
.
apply
(
this
,
arguments
);
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
allow_bookmarks
)
{
const
supported
=
await
_converse
.
checkBookmarksSupport
();
if
(
supported
)
{
this
.
renderBookmarkToggle
();
}
}
},
onBookmarked
()
{
const
{
_converse
}
=
this
.
__super__
,
{
__
}
=
_converse
;
const
icon
=
this
.
el
.
querySelector
(
'
.toggle-bookmark
'
);
if
(
_
.
isNull
(
icon
))
{
return
;
...
...
@@ -111,7 +144,6 @@ converse.plugins.add('converse-bookmark-views', {
setBookmarkState
()
{
/* Set whether the groupchat is bookmarked or not.
*/
const
{
_converse
}
=
this
.
__super__
;
if
(
!
_
.
isUndefined
(
_converse
.
bookmarks
))
{
const
models
=
_converse
.
bookmarks
.
where
({
'
jid
'
:
this
.
model
.
get
(
'
jid
'
)});
if
(
!
models
.
length
)
{
...
...
@@ -125,7 +157,6 @@ converse.plugins.add('converse-bookmark-views', {
renderBookmarkForm
()
{
this
.
hideChatRoomContents
();
if
(
!
this
.
bookmark_form
)
{
const
{
_converse
}
=
this
.
__super__
;
this
.
bookmark_form
=
new
_converse
.
MUCBookmarkForm
({
'
model
'
:
this
.
model
,
'
chatroomview
'
:
this
...
...
@@ -141,7 +172,6 @@ converse.plugins.add('converse-bookmark-views', {
ev
.
preventDefault
();
ev
.
stopPropagation
();
}
const
{
_converse
}
=
this
.
__super__
;
const
models
=
_converse
.
bookmarks
.
where
({
'
jid
'
:
this
.
model
.
get
(
'
jid
'
)});
if
(
!
models
.
length
)
{
this
.
renderBookmarkForm
();
...
...
@@ -151,48 +181,7 @@ converse.plugins.add('converse-bookmark-views', {
}
}
}
},
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
,
{
__
}
=
_converse
;
// Configuration values for this plugin
// ====================================
// Refer to docs/source/configuration.rst for explanations of these
// configuration settings.
_converse
.
api
.
settings
.
update
({
hide_open_bookmarks
:
true
,
muc_respect_autojoin
:
true
});
Object
.
assign
(
_converse
,
{
removeBookmarkViaEvent
(
ev
)
{
/* Remove a bookmark as determined by the passed in
* event.
*/
ev
.
preventDefault
();
const
name
=
ev
.
target
.
getAttribute
(
'
data-bookmark-name
'
);
const
jid
=
ev
.
target
.
getAttribute
(
'
data-room-jid
'
);
if
(
confirm
(
__
(
"
Are you sure you want to remove the bookmark
\"
%1$s
\"
?
"
,
name
)))
{
_
.
invokeMap
(
_converse
.
bookmarks
.
where
({
'
jid
'
:
jid
}),
Backbone
.
Model
.
prototype
.
destroy
);
}
},
addBookmarkViaEvent
(
ev
)
{
/* Add a bookmark as determined by the passed in
* event.
*/
ev
.
preventDefault
();
const
jid
=
ev
.
target
.
getAttribute
(
'
data-room-jid
'
);
const
chatroom
=
_converse
.
api
.
rooms
.
open
(
jid
,
{
'
bring_to_foreground
'
:
true
});
_converse
.
chatboxviews
.
get
(
jid
).
renderBookmarkForm
();
},
});
Object
.
assign
(
_converse
.
ChatRoomView
.
prototype
,
bookmarkableChatRoomView
);
_converse
.
MUCBookmarkForm
=
Backbone
.
VDOMView
.
extend
({
...
...
@@ -368,6 +357,7 @@ converse.plugins.add('converse-bookmark-views', {
}
});
/************************ BEGIN Event Handlers ************************/
const
initBookmarkViews
=
async
function
()
{
await
_converse
.
api
.
waitUntil
(
'
roomsPanelRendered
'
);
_converse
.
bookmarksview
=
new
_converse
.
BookmarksView
({
'
model
'
:
_converse
.
bookmarks
});
...
...
@@ -381,5 +371,11 @@ converse.plugins.add('converse-bookmark-views', {
}
_converse
.
api
.
listen
.
on
(
'
bookmarksInitialized
'
,
initBookmarkViews
);
_converse
.
api
.
listen
.
on
(
'
chatRoomOpened
'
,
view
=>
{
view
.
model
.
on
(
'
change:bookmarked
'
,
view
.
onBookmarked
,
view
);
view
.
setBookmarkState
();
});
/************************ END Event Handlers ************************/
}
});
src/converse-controlbox.js
View file @
1ef29bee
...
...
@@ -105,23 +105,6 @@ converse.plugins.add('converse-controlbox', {
view
.
close
();
});
return
this
;
},
getChatBoxWidth
(
view
)
{
const
{
_converse
}
=
this
.
__super__
;
const
controlbox
=
this
.
get
(
'
controlbox
'
);
if
(
view
.
model
.
get
(
'
id
'
)
===
'
controlbox
'
)
{
/* We return the width of the controlbox or its toggle,
* depending on which is visible.
*/
if
(
!
controlbox
||
!
u
.
isVisible
(
controlbox
.
el
))
{
return
u
.
getOuterWidth
(
_converse
.
controlboxtoggle
.
el
,
true
);
}
else
{
return
u
.
getOuterWidth
(
controlbox
.
el
,
true
);
}
}
else
{
return
this
.
__super__
.
getChatBoxWidth
.
apply
(
this
,
arguments
);
}
}
},
...
...
@@ -232,11 +215,12 @@ converse.plugins.add('converse-controlbox', {
* Triggered when the _converse.ControlBoxView has been initialized and therefore
* exists. The controlbox contains the login and register forms when the user is
* logged out and a list of the user's contacts and group chats when logged in.
* @event _converse#c
hatB
oxInitialized
* @event _converse#c
ontrolb
oxInitialized
* @type { _converse.ControlBoxView }
* @example _converse.api.listen.on('controlboxInitialized', view => { ... });
*/
_converse
.
api
.
trigger
(
'
controlboxInitialized
'
,
this
);
_converse
.
api
.
trigger
(
'
chatBoxInitialized
'
,
this
);
},
render
()
{
...
...
src/converse-dragresize.js
View file @
1ef29bee
This diff is collapsed.
Click to expand it.
src/converse-minimize.js
View file @
1ef29bee
...
...
@@ -30,7 +30,7 @@ converse.plugins.add('converse-minimize', {
*
* NB: These plugins need to have already been loaded via require.js.
*/
dependencies
:
[
"
converse-chatview
"
,
"
converse-controlbox
"
,
"
converse-muc
"
,
"
converse-muc-views
"
,
"
converse-headlin
e
"
],
dependencies
:
[
"
converse-chatview
"
,
"
converse-controlbox
"
,
"
converse-muc
-views
"
,
"
converse-headline
"
,
"
converse-dragresiz
e
"
],
enabled
(
_converse
)
{
return
_converse
.
view_mode
===
'
overlayed
'
;
...
...
@@ -57,20 +57,6 @@ converse.plugins.add('converse-minimize', {
});
},
maximize
()
{
u
.
safeSave
(
this
,
{
'
minimized
'
:
false
,
'
time_opened
'
:
(
new
Date
()).
getTime
()
});
},
minimize
()
{
u
.
safeSave
(
this
,
{
'
minimized
'
:
true
,
'
time_minimized
'
:
(
new
Date
()).
toISOString
()
});
},
maybeShow
(
force
)
{
if
(
!
force
&&
this
.
get
(
'
minimized
'
))
{
// Must return the chatbox
...
...
@@ -122,65 +108,17 @@ converse.plugins.add('converse-minimize', {
if
(
!
this
.
model
.
get
(
'
minimized
'
))
{
return
this
.
__super__
.
setChatBoxWidth
.
apply
(
this
,
arguments
);
}
},
onMinimizedChanged
(
item
)
{
if
(
item
.
get
(
'
minimized
'
))
{
this
.
minimize
();
}
else
{
this
.
maximize
();
}
},
maximize
()
{
// Restores a minimized chat box
const
{
_converse
}
=
this
.
__super__
;
this
.
insertIntoDOM
();
if
(
!
this
.
model
.
isScrolledUp
())
{
this
.
model
.
clearUnreadMsgCounter
();
}
this
.
show
();
/**
* Triggered when a previously minimized chat gets maximized
* @event _converse#chatBoxMaximized
* @type { _converse.ChatBoxView }
* @example _converse.api.listen.on('chatBoxMaximized', view => { ... });
*/
_converse
.
api
.
trigger
(
'
chatBoxMaximized
'
,
this
);
return
this
;
},
minimize
(
ev
)
{
const
{
_converse
}
=
this
.
__super__
;
if
(
ev
&&
ev
.
preventDefault
)
{
ev
.
preventDefault
();
}
// save the scroll position to restore it on maximize
if
(
this
.
model
.
collection
&&
this
.
model
.
collection
.
browserStorage
)
{
this
.
model
.
save
({
'
scroll
'
:
this
.
content
.
scrollTop
});
}
else
{
this
.
model
.
set
({
'
scroll
'
:
this
.
content
.
scrollTop
});
}
this
.
setChatState
(
_converse
.
INACTIVE
).
model
.
minimize
();
this
.
hide
();
/**
* Triggered when a previously maximized chat gets Minimized
* @event _converse#chatBoxMinimized
* @type { _converse.ChatBoxView }
* @example _converse.api.listen.on('chatBoxMinimized', view => { ... });
*/
_converse
.
api
.
trigger
(
'
chatBoxMinimized
'
,
this
);
},
}
},
ChatBoxHeading
:
{
render
()
{
const
{
_converse
}
=
this
.
__super__
,
{
__
}
=
_converse
;
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
const
new_html
=
tpl_chatbox_minimize
(
{
info_minimize
:
__
(
'
Minimize this chat box
'
)}
);
const
new_html
=
tpl_chatbox_minimize
(
{
'
info_minimize
'
:
__
(
'
Minimize this chat box
'
)
}
);
const
el
=
this
.
el
.
querySelector
(
'
.toggle-chatbox-button
'
);
if
(
el
)
{
el
.
outerHTML
=
new_html
;
...
...
@@ -227,11 +165,109 @@ converse.plugins.add('converse-minimize', {
}
return
div
.
innerHTML
;
}
},
}
},
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
,
{
__
}
=
_converse
;
// Add new HTML templates.
_converse
.
templates
.
chatbox_minimize
=
tpl_chatbox_minimize
;
_converse
.
templates
.
toggle_chats
=
tpl_toggle_chats
;
_converse
.
templates
.
trimmed_chat
=
tpl_trimmed_chat
;
_converse
.
templates
.
chats_panel
=
tpl_chats_panel
;
_converse
.
api
.
settings
.
update
({
'
no_trimming
'
:
false
,
// Set to true for tests
});
ChatBoxViews
:
{
const
minimizableChatBox
=
{
maximize
()
{
u
.
safeSave
(
this
,
{
'
minimized
'
:
false
,
'
time_opened
'
:
(
new
Date
()).
getTime
()
});
},
minimize
()
{
u
.
safeSave
(
this
,
{
'
minimized
'
:
true
,
'
time_minimized
'
:
(
new
Date
()).
toISOString
()
});
}
}
Object
.
assign
(
_converse
.
ChatBox
.
prototype
,
minimizableChatBox
);
const
minimizableChatBoxView
=
{
maximize
()
{
// Restores a minimized chat box
const
{
_converse
}
=
this
.
__super__
;
this
.
insertIntoDOM
();
if
(
!
this
.
model
.
isScrolledUp
())
{
this
.
model
.
clearUnreadMsgCounter
();
}
this
.
show
();
/**
* Triggered when a previously minimized chat gets maximized
* @event _converse#chatBoxMaximized
* @type { _converse.ChatBoxView }
* @example _converse.api.listen.on('chatBoxMaximized', view => { ... });
*/
_converse
.
api
.
trigger
(
'
chatBoxMaximized
'
,
this
);
return
this
;
},
minimize
(
ev
)
{
const
{
_converse
}
=
this
.
__super__
;
if
(
ev
&&
ev
.
preventDefault
)
{
ev
.
preventDefault
();
}
// save the scroll position to restore it on maximize
if
(
this
.
model
.
collection
&&
this
.
model
.
collection
.
browserStorage
)
{
this
.
model
.
save
({
'
scroll
'
:
this
.
content
.
scrollTop
});
}
else
{
this
.
model
.
set
({
'
scroll
'
:
this
.
content
.
scrollTop
});
}
this
.
setChatState
(
_converse
.
INACTIVE
).
model
.
minimize
();
this
.
hide
();
/**
* Triggered when a previously maximized chat gets Minimized
* @event _converse#chatBoxMinimized
* @type { _converse.ChatBoxView }
* @example _converse.api.listen.on('chatBoxMinimized', view => { ... });
*/
_converse
.
api
.
trigger
(
'
chatBoxMinimized
'
,
this
);
},
onMinimizedChanged
(
item
)
{
if
(
item
.
get
(
'
minimized
'
))
{
this
.
minimize
();
}
else
{
this
.
maximize
();
}
}
}
Object
.
assign
(
_converse
.
ChatBoxView
.
prototype
,
minimizableChatBoxView
);
const
chatTrimmer
=
{
getChatBoxWidth
(
view
)
{
if
(
!
view
.
model
.
get
(
'
minimized
'
)
&&
u
.
isVisible
(
view
.
el
))
{
if
(
view
.
model
.
get
(
'
id
'
)
===
'
controlbox
'
)
{
const
controlbox
=
this
.
get
(
'
controlbox
'
);
// We return the width of the controlbox or its toggle,
// depending on which is visible.
if
(
!
controlbox
||
!
u
.
isVisible
(
controlbox
.
el
))
{
return
u
.
getOuterWidth
(
_converse
.
controlboxtoggle
.
el
,
true
);
}
else
{
return
u
.
getOuterWidth
(
controlbox
.
el
,
true
);
}
}
else
if
(
!
view
.
model
.
get
(
'
minimized
'
)
&&
u
.
isVisible
(
view
.
el
))
{
return
u
.
getOuterWidth
(
view
.
el
,
true
);
}
return
0
;
...
...
@@ -315,25 +351,8 @@ converse.plugins.add('converse-minimize', {
return
model
;
}
}
},
Object
.
assign
(
_converse
.
ChatBoxViews
.
prototype
,
chatTrimmer
);
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
,
{
__
}
=
_converse
;
// Add new HTML templates.
_converse
.
templates
.
chatbox_minimize
=
tpl_chatbox_minimize
;
_converse
.
templates
.
toggle_chats
=
tpl_toggle_chats
;
_converse
.
templates
.
trimmed_chat
=
tpl_trimmed_chat
;
_converse
.
templates
.
chats_panel
=
tpl_chats_panel
;
_converse
.
api
.
settings
.
update
({
no_trimming
:
false
,
// Set to true for phantomjs tests (where browser apparently has no width)
});
_converse
.
api
.
promises
.
add
(
'
minimizedChatsInitialized
'
);
...
...
@@ -525,6 +544,7 @@ converse.plugins.add('converse-minimize', {
}
});
/************************ BEGIN Event Handlers ************************/
Promise
.
all
([
_converse
.
api
.
waitUntil
(
'
connectionInitialized
'
),
_converse
.
api
.
waitUntil
(
'
chatBoxViewsInitialized
'
)
...
...
@@ -559,5 +579,6 @@ converse.plugins.add('converse-minimize', {
_converse
.
chatboxviews
.
trimChats
(
chatbox
);
}
});
/************************ END Event Handlers ************************/
}
});
src/converse-muc-views.js
View file @
1ef29bee
...
...
@@ -62,41 +62,14 @@ converse.plugins.add('converse-muc-views', {
dependencies
:
[
"
converse-autocomplete
"
,
"
converse-modal
"
,
"
converse-controlbox
"
,
"
converse-chatview
"
],
overrides
:
{
ControlBoxView
:
{
renderRoomsPanel
()
{
const
{
_converse
}
=
this
.
__super__
;
if
(
this
.
roomspanel
&&
u
.
isVisible
(
this
.
roomspanel
.
el
))
{
return
;
}
this
.
roomspanel
=
new
_converse
.
RoomsPanel
({
'
model
'
:
new
(
_converse
.
RoomsPanelModel
.
extend
({
'
id
'
:
`converse.roomspanel
${
_converse
.
bare_jid
}
`
,
// Required by web storage
'
browserStorage
'
:
new
BrowserStorage
[
_converse
.
config
.
get
(
'
storage
'
)](
`converse.roomspanel
${
_converse
.
bare_jid
}
`
)
}))()
});
this
.
roomspanel
.
model
.
fetch
();
this
.
el
.
querySelector
(
'
.controlbox-pane
'
).
insertAdjacentElement
(
'
beforeEnd
'
,
this
.
roomspanel
.
render
().
el
);
/**
* Triggered once the section of the _converse.ControlBoxView
* which shows gropuchats has been rendered.
* @event _converse#roomsPanelRendered
* @example _converse.api.listen.on('roomsPanelRendered', () => { ... });
*/
_converse
.
api
.
trigger
(
'
roomsPanelRendered
'
);
},
renderControlBoxPane
()
{
const
{
_converse
}
=
this
.
__super__
;
this
.
__super__
.
renderControlBoxPane
.
apply
(
this
,
arguments
);
if
(
_converse
.
allow_muc
)
{
this
.
renderRoomsPanel
();
}
}
,
}
}
},
...
...
@@ -123,6 +96,35 @@ converse.plugins.add('converse-muc-views', {
}
});
Object
.
assign
(
_converse
.
ControlBoxView
.
prototype
,
{
renderRoomsPanel
()
{
if
(
this
.
roomspanel
&&
u
.
isVisible
(
this
.
roomspanel
.
el
))
{
return
;
}
this
.
roomspanel
=
new
_converse
.
RoomsPanel
({
'
model
'
:
new
(
_converse
.
RoomsPanelModel
.
extend
({
'
id
'
:
`converse.roomspanel
${
_converse
.
bare_jid
}
`
,
// Required by web storage
'
browserStorage
'
:
new
BrowserStorage
[
_converse
.
config
.
get
(
'
storage
'
)](
`converse.roomspanel
${
_converse
.
bare_jid
}
`
)
}))()
});
this
.
roomspanel
.
model
.
fetch
();
this
.
el
.
querySelector
(
'
.controlbox-pane
'
).
insertAdjacentElement
(
'
beforeEnd
'
,
this
.
roomspanel
.
render
().
el
);
/**
* Triggered once the section of the _converse.ControlBoxView
* which shows gropuchats has been rendered.
* @event _converse#roomsPanelRendered
* @example _converse.api.listen.on('roomsPanelRendered', () => { ... });
*/
_converse
.
api
.
trigger
(
'
roomsPanelRendered
'
);
}
});
function
___
(
str
)
{
/* This is part of a hack to get gettext to scan strings to be
* translated. Strings we cannot send to the function above because
...
...
@@ -572,6 +574,7 @@ converse.plugins.add('converse-muc-views', {
* @example _converse.api.listen.on('chatRoomOpened', view => { ... });
*/
_converse
.
api
.
trigger
(
'
chatRoomOpened
'
,
this
);
_converse
.
api
.
trigger
(
'
chatBoxInitialized
'
,
this
);
},
render
()
{
...
...
src/converse-oauth.js
View file @
1ef29bee
...
...
@@ -38,12 +38,12 @@ converse.plugins.add("converse-oauth", {
/* For example, the private *_converse* object has a
* method "onConnected". You can override that method as follows:
*/
'
LoginPanel
'
:
{
LoginPanel
:
{
insertOAuthProviders
()
{
const
{
_converse
}
=
this
.
__super__
;
if
(
_
.
isUndefined
(
this
.
oauth_providers_view
))
{
this
.
oauth_providers_view
=
this
.
oauth_providers_view
=
new
_converse
.
OAuthProvidersView
({
'
model
'
:
_converse
.
oauth_providers
});
this
.
oauth_providers_view
.
render
();
...
...
src/converse-omemo.js
View file @
1ef29bee
This diff is collapsed.
Click to expand it.
src/converse-register.js
View file @
1ef29bee
...
...
@@ -45,17 +45,6 @@ converse.plugins.add('converse-register', {
// New functions which don't exist yet can also be added.
LoginPanel
:
{
insertRegisterLink
()
{
const
{
_converse
}
=
this
.
__super__
;
if
(
_
.
isUndefined
(
this
.
registerlinkview
))
{
this
.
registerlinkview
=
new
_converse
.
RegisterLinkView
({
'
model
'
:
this
.
model
});
this
.
registerlinkview
.
render
();
this
.
el
.
querySelector
(
'
.buttons
'
).
insertAdjacentElement
(
'
afterend
'
,
this
.
registerlinkview
.
el
);
}
this
.
registerlinkview
.
render
();
},
render
(
cfg
)
{
const
{
_converse
}
=
this
.
__super__
;
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
...
...
@@ -67,11 +56,50 @@ converse.plugins.add('converse-register', {
},
ControlBoxView
:
{
renderLoginPanel
()
{
/* Also render a registration panel, when rendering the
* login panel.
*/
this
.
__super__
.
renderLoginPanel
.
apply
(
this
,
arguments
);
this
.
renderRegistrationPanel
();
return
this
;
}
}
},
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
change:active-form
'
,
this
.
showLoginOrRegisterForm
.
bind
(
this
))
},
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
,
{
__
}
=
_converse
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
REGIFAIL
]
=
'
REGIFAIL
'
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
REGISTERED
]
=
'
REGISTERED
'
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
CONFLICT
]
=
'
CONFLICT
'
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
NOTACCEPTABLE
]
=
'
NOTACCEPTABLE
'
;
_converse
.
api
.
settings
.
update
({
'
allow_registration
'
:
true
,
'
domain_placeholder
'
:
__
(
"
e.g. conversejs.org
"
),
// Placeholder text shown in the domain input on the registration form
'
providers_link
'
:
'
https://compliance.conversations.im/
'
,
// Link to XMPP providers shown on registration page
'
registration_domain
'
:
''
});
Object
.
assign
(
_converse
.
LoginPanel
.
prototype
,
{
insertRegisterLink
()
{
if
(
_
.
isUndefined
(
this
.
registerlinkview
))
{
this
.
registerlinkview
=
new
_converse
.
RegisterLinkView
({
'
model
'
:
this
.
model
});
this
.
registerlinkview
.
render
();
this
.
el
.
querySelector
(
'
.buttons
'
).
insertAdjacentElement
(
'
afterend
'
,
this
.
registerlinkview
.
el
);
}
this
.
registerlinkview
.
render
();
}
});
Object
.
assign
(
_converse
.
ControlBoxView
.
prototype
,
{
showLoginOrRegisterForm
()
{
const
{
_converse
}
=
this
.
__super__
;
...
...
@@ -88,7 +116,6 @@ converse.plugins.add('converse-register', {
},
renderRegistrationPanel
()
{
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
allow_registration
)
{
this
.
registerpanel
=
new
_converse
.
RegisterPanel
({
'
model
'
:
this
.
model
...
...
@@ -102,36 +129,7 @@ converse.plugins.add('converse-register', {
this
.
showLoginOrRegisterForm
();
}
return
this
;
},
renderLoginPanel
()
{
/* Also render a registration panel, when rendering the
* login panel.
*/
this
.
__super__
.
renderLoginPanel
.
apply
(
this
,
arguments
);
this
.
renderRegistrationPanel
();
return
this
;
}
}
},
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
,
{
__
}
=
_converse
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
REGIFAIL
]
=
'
REGIFAIL
'
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
REGISTERED
]
=
'
REGISTERED
'
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
CONFLICT
]
=
'
CONFLICT
'
;
_converse
.
CONNECTION_STATUS
[
Strophe
.
Status
.
NOTACCEPTABLE
]
=
'
NOTACCEPTABLE
'
;
_converse
.
api
.
settings
.
update
({
'
allow_registration
'
:
true
,
'
domain_placeholder
'
:
__
(
"
e.g. conversejs.org
"
),
// Placeholder text shown in the domain input on the registration form
'
providers_link
'
:
'
https://compliance.conversations.im/
'
,
// Link to XMPP providers shown on registration page
'
registration_domain
'
:
''
});
...
...
@@ -679,6 +677,12 @@ converse.plugins.add('converse-register', {
return
false
;
}
});
/************************ BEGIN Event Handlers ************************/
_converse
.
api
.
listen
.
on
(
'
controlboxInitialized
'
,
view
=>
{
view
.
model
.
on
(
'
change:active-form
'
,
view
.
showLoginOrRegisterForm
,
view
);
});
/************************ END Event Handlers ************************/
}
});
src/converse-rosterview.js
View file @
1ef29bee
...
...
@@ -29,27 +29,6 @@ converse.plugins.add('converse-rosterview', {
dependencies
:
[
"
converse-roster
"
,
"
converse-modal
"
],
overrides
:
{
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
afterReconnected
()
{
this
.
__super__
.
afterReconnected
.
apply
(
this
,
arguments
);
},
RosterGroups
:
{
comparator
()
{
// RosterGroupsComparator only gets set later (once i18n is
// set up), so we need to wrap it in this nameless function.
const
{
_converse
}
=
this
.
__super__
;
return
_converse
.
RosterGroupsComparator
.
apply
(
this
,
arguments
);
}
}
},
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
...
...
@@ -78,36 +57,6 @@ converse.plugins.add('converse-rosterview', {
'
away
'
:
__
(
'
This contact is away
'
)
};
const
LABEL_GROUPS
=
__
(
'
Groups
'
);
const
HEADER_CURRENT_CONTACTS
=
__
(
'
My contacts
'
);
const
HEADER_PENDING_CONTACTS
=
__
(
'
Pending contacts
'
);
const
HEADER_REQUESTING_CONTACTS
=
__
(
'
Contact requests
'
);
const
HEADER_UNGROUPED
=
__
(
'
Ungrouped
'
);
const
HEADER_WEIGHTS
=
{};
HEADER_WEIGHTS
[
HEADER_REQUESTING_CONTACTS
]
=
0
;
HEADER_WEIGHTS
[
HEADER_CURRENT_CONTACTS
]
=
1
;
HEADER_WEIGHTS
[
HEADER_UNGROUPED
]
=
2
;
HEADER_WEIGHTS
[
HEADER_PENDING_CONTACTS
]
=
3
;
_converse
.
RosterGroupsComparator
=
function
(
a
,
b
)
{
/* Groups are sorted alphabetically, ignoring case.
* However, Ungrouped, Requesting Contacts and Pending Contacts
* appear last and in that order.
*/
a
=
a
.
get
(
'
name
'
);
b
=
b
.
get
(
'
name
'
);
const
special_groups
=
Object
.
keys
(
HEADER_WEIGHTS
);
const
a_is_special
=
_
.
includes
(
special_groups
,
a
);
const
b_is_special
=
_
.
includes
(
special_groups
,
b
);
if
(
!
a_is_special
&&
!
b_is_special
)
{
return
a
.
toLowerCase
()
<
b
.
toLowerCase
()
?
-
1
:
(
a
.
toLowerCase
()
>
b
.
toLowerCase
()
?
1
:
0
);
}
else
if
(
a_is_special
&&
b_is_special
)
{
return
HEADER_WEIGHTS
[
a
]
<
HEADER_WEIGHTS
[
b
]
?
-
1
:
(
HEADER_WEIGHTS
[
a
]
>
HEADER_WEIGHTS
[
b
]
?
1
:
0
);
}
else
if
(
!
a_is_special
&&
b_is_special
)
{
return
(
b
===
HEADER_REQUESTING_CONTACTS
)
?
1
:
-
1
;
}
else
if
(
a_is_special
&&
!
b_is_special
)
{
return
(
a
===
HEADER_REQUESTING_CONTACTS
)
?
-
1
:
1
;
}
};
_converse
.
AddContactModal
=
_converse
.
BootstrapModal
.
extend
({
...
...
@@ -678,7 +627,7 @@ converse.plugins.add('converse-rosterview', {
let
matches
;
q
=
q
.
toLowerCase
();
if
(
type
===
'
state
'
)
{
if
(
this
.
model
.
get
(
'
name
'
)
===
HEADER_REQUESTING_CONTACTS
)
{
if
(
this
.
model
.
get
(
'
name
'
)
===
_converse
.
HEADER_REQUESTING_CONTACTS
)
{
// When filtering by chat state, we still want to
// show requesting contacts, even though they don't
// have the state in question.
...
...
@@ -747,13 +696,13 @@ converse.plugins.add('converse-rosterview', {
},
onContactSubscriptionChange
(
contact
)
{
if
((
this
.
model
.
get
(
'
name
'
)
===
HEADER_PENDING_CONTACTS
)
&&
contact
.
get
(
'
subscription
'
)
!==
'
from
'
)
{
if
((
this
.
model
.
get
(
'
name
'
)
===
_converse
.
HEADER_PENDING_CONTACTS
)
&&
contact
.
get
(
'
subscription
'
)
!==
'
from
'
)
{
this
.
removeContact
(
contact
);
}
},
onContactRequestChange
(
contact
)
{
if
((
this
.
model
.
get
(
'
name
'
)
===
HEADER_REQUESTING_CONTACTS
)
&&
!
contact
.
get
(
'
requesting
'
))
{
if
((
this
.
model
.
get
(
'
name
'
)
===
_converse
.
HEADER_REQUESTING_CONTACTS
)
&&
!
contact
.
get
(
'
requesting
'
))
{
this
.
removeContact
(
contact
);
}
},
...
...
@@ -926,16 +875,16 @@ converse.plugins.add('converse-rosterview', {
this
.
update
();
if
(
_
.
has
(
contact
.
changed
,
'
subscription
'
))
{
if
(
contact
.
changed
.
subscription
===
'
from
'
)
{
this
.
addContactToGroup
(
contact
,
HEADER_PENDING_CONTACTS
);
this
.
addContactToGroup
(
contact
,
_converse
.
HEADER_PENDING_CONTACTS
);
}
else
if
(
_
.
includes
([
'
both
'
,
'
to
'
],
contact
.
get
(
'
subscription
'
)))
{
this
.
addExistingContact
(
contact
);
}
}
if
(
_
.
has
(
contact
.
changed
,
'
ask
'
)
&&
contact
.
changed
.
ask
===
'
subscribe
'
)
{
this
.
addContactToGroup
(
contact
,
HEADER_PENDING_CONTACTS
);
this
.
addContactToGroup
(
contact
,
_converse
.
HEADER_PENDING_CONTACTS
);
}
if
(
_
.
has
(
contact
.
changed
,
'
subscription
'
)
&&
contact
.
changed
.
requesting
===
'
true
'
)
{
this
.
addContactToGroup
(
contact
,
HEADER_REQUESTING_CONTACTS
);
this
.
addContactToGroup
(
contact
,
_converse
.
HEADER_REQUESTING_CONTACTS
);
}
this
.
updateFilter
();
},
...
...
@@ -961,10 +910,10 @@ converse.plugins.add('converse-rosterview', {
if
(
_converse
.
roster_groups
)
{
groups
=
contact
.
get
(
'
groups
'
);
if
(
groups
.
length
===
0
)
{
groups
=
[
HEADER_UNGROUPED
];
groups
=
[
_converse
.
HEADER_UNGROUPED
];
}
}
else
{
groups
=
[
HEADER_CURRENT_CONTACTS
];
groups
=
[
_converse
.
HEADER_CURRENT_CONTACTS
];
}
_
.
each
(
groups
,
_
.
bind
(
this
.
addContactToGroup
,
this
,
contact
,
_
,
options
));
},
...
...
@@ -982,9 +931,9 @@ converse.plugins.add('converse-rosterview', {
return
;
}
if
((
contact
.
get
(
'
ask
'
)
===
'
subscribe
'
)
||
(
contact
.
get
(
'
subscription
'
)
===
'
from
'
))
{
this
.
addContactToGroup
(
contact
,
HEADER_PENDING_CONTACTS
,
options
);
this
.
addContactToGroup
(
contact
,
_converse
.
HEADER_PENDING_CONTACTS
,
options
);
}
else
if
(
contact
.
get
(
'
requesting
'
)
===
true
)
{
this
.
addContactToGroup
(
contact
,
HEADER_REQUESTING_CONTACTS
,
options
);
this
.
addContactToGroup
(
contact
,
_converse
.
HEADER_REQUESTING_CONTACTS
,
options
);
}
}
return
this
;
...
...
src/converse-singleton.js
View file @
1ef29bee
...
...
@@ -82,7 +82,7 @@ converse.plugins.add('converse-singleton', {
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
isUniView
())
{
return
false
;
}
else
{
}
else
{
return
this
.
__super__
.
shouldShowOnTextMessage
.
apply
(
this
,
arguments
);
}
},
...
...
src/headless/converse-bookmarks.js
View file @
1ef29bee
...
...
@@ -40,13 +40,11 @@ converse.plugins.add('converse-bookmarks', {
// New functions which don't exist yet can also be added.
ChatRoom
:
{
getAndPersistNickname
(
nick
)
{
const
{
_converse
}
=
this
.
__super__
;
nick
=
nick
||
_converse
.
getNicknameFromBookmark
(
this
.
get
(
'
jid
'
));
return
this
.
__super__
.
getAndPersistNickname
.
call
(
this
,
nick
);
},
}
}
},
...
...
src/headless/converse-core.js
View file @
1ef29bee
...
...
@@ -251,7 +251,7 @@ _converse.log = function (message, level, style='') {
message
=
message
.
outerHTML
;
}
const
prefix
=
style
?
'
%c
'
:
''
;
const
logger
=
_
.
assign
({
const
logger
=
Object
.
assign
({
'
debug
'
:
_
.
get
(
console
,
'
log
'
)
?
console
.
log
.
bind
(
console
)
:
_
.
noop
,
'
error
'
:
_
.
get
(
console
,
'
log
'
)
?
console
.
log
.
bind
(
console
)
:
_
.
noop
,
'
info
'
:
_
.
get
(
console
,
'
log
'
)
?
console
.
log
.
bind
(
console
)
:
_
.
noop
,
...
...
src/headless/converse-mam.js
View file @
1ef29bee
...
...
@@ -29,9 +29,40 @@ converse.plugins.add('converse-mam', {
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
ChatBox
:
{
async
getDuplicateMessage
(
stanza
)
{
const
message
=
await
this
.
__super__
.
getDuplicateMessage
.
apply
(
this
,
arguments
);
if
(
!
message
)
{
return
this
.
findDuplicateFromArchiveID
(
stanza
);
}
return
message
;
},
getUpdatedMessageAttributes
(
message
,
stanza
)
{
const
attrs
=
this
.
__super__
.
getUpdatedMessageAttributes
.
apply
(
this
,
arguments
);
if
(
message
&&
!
message
.
get
(
'
is_archived
'
))
{
return
Object
.
assign
(
attrs
,
{
'
is_archived
'
:
this
.
isArchived
(
stanza
)
},
this
.
getStanzaIDs
(
stanza
))
}
return
attrs
;
}
}
},
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
;
_converse
.
api
.
settings
.
update
({
archived_messages_page_size
:
'
50
'
,
message_archiving
:
undefined
,
// Supported values are 'always', 'never', 'roster' (https://xmpp.org/extensions/xep-0313.html#prefs)
message_archiving_timeout
:
20000
,
// Time (in milliseconds) to wait before aborting MAM request
});
const
MAMEnabledChat
=
{
fetchNewestMessages
()
{
/* Fetches messages that might have been archived *after*
...
...
@@ -40,7 +71,6 @@ converse.plugins.add('converse-mam', {
if
(
this
.
disable_mam
)
{
return
;
}
const
{
_converse
}
=
this
.
__super__
;
const
most_recent_msg
=
u
.
getMostRecentMessage
(
this
);
if
(
_
.
isNil
(
most_recent_msg
))
{
...
...
@@ -59,7 +89,6 @@ converse.plugins.add('converse-mam', {
if
(
this
.
disable_mam
)
{
return
;
}
const
{
_converse
}
=
this
.
__super__
;
const
is_groupchat
=
this
.
get
(
'
type
'
)
===
CHATROOMS_TYPE
;
const
mam_jid
=
is_groupchat
?
this
.
get
(
'
jid
'
)
:
_converse
.
bare_jid
;
if
(
!
(
await
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
MAM
,
mam_jid
)))
{
...
...
@@ -92,7 +121,6 @@ converse.plugins.add('converse-mam', {
},
async
findDuplicateFromArchiveID
(
stanza
)
{
const
{
_converse
}
=
this
.
__super__
;
const
result
=
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
stanza
).
pop
();
if
(
!
result
)
{
return
null
;
...
...
@@ -107,32 +135,11 @@ converse.plugins.add('converse-mam', {
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
;
},
getUpdatedMessageAttributes
(
message
,
stanza
)
{
const
attrs
=
this
.
__super__
.
getUpdatedMessageAttributes
.
apply
(
this
,
arguments
);
if
(
message
&&
!
message
.
get
(
'
is_archived
'
))
{
return
Object
.
assign
(
attrs
,
{
'
is_archived
'
:
this
.
isArchived
(
stanza
)
},
this
.
getStanzaIDs
(
stanza
))
}
return
attrs
;
}
},
}
Object
.
assign
(
_converse
.
ChatBox
.
prototype
,
MAMEnabledChat
);
ChatRoom
:
{
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
this
.
on
(
'
change:mam_enabled
'
,
this
.
fetchArchivedMessagesIfNecessary
,
this
);
this
.
on
(
'
change:connection_status
'
,
this
.
fetchArchivedMessagesIfNecessary
,
this
);
},
Object
.
assign
(
_converse
.
ChatRoom
.
prototype
,
{
fetchArchivedMessagesIfNecessary
()
{
if
(
this
.
get
(
'
connection_status
'
)
!==
converse
.
ROOMSTATUS
.
ENTERED
||
!
this
.
get
(
'
mam_enabled
'
)
||
...
...
@@ -142,22 +149,9 @@ converse.plugins.add('converse-mam', {
this
.
fetchArchivedMessages
();
this
.
save
({
'
mam_initialized
'
:
true
});
}
},
},
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
;
_converse
.
api
.
settings
.
update
({
archived_messages_page_size
:
'
50
'
,
message_archiving
:
undefined
,
// Supported values are 'always', 'never', 'roster' (https://xmpp.org/extensions/xep-0313.html#prefs)
message_archiving_timeout
:
20000
,
// Time (in milliseconds) to wait before aborting MAM request
});
_converse
.
onMAMError
=
function
(
iq
)
{
if
(
iq
.
querySelectorAll
(
'
feature-not-implemented
'
).
length
)
{
_converse
.
log
(
...
...
@@ -220,6 +214,11 @@ converse.plugins.add('converse-mam', {
_converse
.
api
.
listen
.
on
(
'
afterMessagesFetched
'
,
chat
=>
chat
.
fetchNewestMessages
());
_converse
.
api
.
listen
.
on
(
'
chatReconnected
'
,
chat
=>
chat
.
fetchNewestMessages
());
_converse
.
api
.
listen
.
on
(
'
addClientFeatures
'
,
()
=>
_converse
.
api
.
disco
.
own
.
features
.
add
(
Strophe
.
NS
.
MAM
));
_converse
.
api
.
listen
.
on
(
'
chatRoomOpened
'
,
(
room
)
=>
{
room
.
on
(
'
change:mam_enabled
'
,
room
.
fetchArchivedMessagesIfNecessary
,
room
);
room
.
on
(
'
change:connection_status
'
,
room
.
fetchArchivedMessagesIfNecessary
,
room
);
});
/************************ END Event Handlers **************************/
...
...
src/headless/converse-roster.js
View file @
1ef29bee
...
...
@@ -36,6 +36,17 @@ converse.plugins.add('converse-roster', {
'
rosterInitialized
'
,
]);
_converse
.
HEADER_CURRENT_CONTACTS
=
__
(
'
My contacts
'
);
_converse
.
HEADER_PENDING_CONTACTS
=
__
(
'
Pending contacts
'
);
_converse
.
HEADER_REQUESTING_CONTACTS
=
__
(
'
Contact requests
'
);
_converse
.
HEADER_UNGROUPED
=
__
(
'
Ungrouped
'
);
const
HEADER_WEIGHTS
=
{};
HEADER_WEIGHTS
[
_converse
.
HEADER_REQUESTING_CONTACTS
]
=
0
;
HEADER_WEIGHTS
[
_converse
.
HEADER_CURRENT_CONTACTS
]
=
1
;
HEADER_WEIGHTS
[
_converse
.
HEADER_UNGROUPED
]
=
2
;
HEADER_WEIGHTS
[
_converse
.
HEADER_PENDING_CONTACTS
]
=
3
;
_converse
.
registerPresenceHandler
=
function
()
{
_converse
.
unregisterPresenceHandler
();
...
...
@@ -381,6 +392,10 @@ converse.plugins.add('converse-roster', {
model
:
_converse
.
RosterContact
,
comparator
(
contact1
,
contact2
)
{
/* Groups are sorted alphabetically, ignoring case.
* However, Ungrouped, Requesting Contacts and Pending Contacts
* appear last and in that order.
*/
const
status1
=
contact1
.
presence
.
get
(
'
show
'
)
||
'
offline
'
;
const
status2
=
contact2
.
presence
.
get
(
'
show
'
)
||
'
offline
'
;
if
(
_converse
.
STATUS_WEIGHTS
[
status1
]
===
_converse
.
STATUS_WEIGHTS
[
status2
])
{
...
...
@@ -854,6 +869,23 @@ converse.plugins.add('converse-roster', {
_converse
.
RosterGroups
=
Backbone
.
Collection
.
extend
({
model
:
_converse
.
RosterGroup
,
comparator
(
a
,
b
)
{
a
=
a
.
get
(
'
name
'
);
b
=
b
.
get
(
'
name
'
);
const
special_groups
=
Object
.
keys
(
HEADER_WEIGHTS
);
const
a_is_special
=
_
.
includes
(
special_groups
,
a
);
const
b_is_special
=
_
.
includes
(
special_groups
,
b
);
if
(
!
a_is_special
&&
!
b_is_special
)
{
return
a
.
toLowerCase
()
<
b
.
toLowerCase
()
?
-
1
:
(
a
.
toLowerCase
()
>
b
.
toLowerCase
()
?
1
:
0
);
}
else
if
(
a_is_special
&&
b_is_special
)
{
return
HEADER_WEIGHTS
[
a
]
<
HEADER_WEIGHTS
[
b
]
?
-
1
:
(
HEADER_WEIGHTS
[
a
]
>
HEADER_WEIGHTS
[
b
]
?
1
:
0
);
}
else
if
(
!
a_is_special
&&
b_is_special
)
{
return
(
b
===
_converse
.
HEADER_REQUESTING_CONTACTS
)
?
1
:
-
1
;
}
else
if
(
a_is_special
&&
!
b_is_special
)
{
return
(
a
===
_converse
.
HEADER_REQUESTING_CONTACTS
)
?
-
1
:
1
;
}
},
fetchRosterGroups
()
{
/* Fetches all the roster groups from sessionStorage.
*
...
...
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