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
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
...
@@ -189,14 +189,13 @@ The code for it would look something like this:
...
@@ -189,14 +189,13 @@ The code for it would look something like this:
// Commonly used utilities and variables can be found under the "env"
// Commonly used utilities and variables can be found under the "env"
// namespace of the "converse" global.
// namespace of the "converse" global.
var Strophe = converse.env.Strophe,
const Strophe = converse.env.Strophe,
$iq = converse.env.$iq,
$iq = converse.env.$iq,
$msg = converse.env.$msg,
$msg = converse.env.$msg,
$pres = converse.env.$pres,
$pres = converse.env.$pres,
$build = converse.env.$build,
$build = converse.env.$build,
b64_sha1 = converse.env.b64_sha1,
_ = converse.env._,
_ = converse.env._,
dayjs = converse.env.dayjs;
dayjs = converse.env.dayjs;
These dependencies are closured so that they don't pollute the global
These dependencies are closured so that they don't pollute the global
namespace, that's why you need to access them in such a way inside the module.
namespace, that's why you need to access them in such a way inside the module.
...
@@ -300,7 +299,7 @@ In this case, you should first listen for the ``connection`` event, and then do
...
@@ -300,7 +299,7 @@ In this case, you should first listen for the ``connection`` event, and then do
converse.plugins.add('myplugin', {
converse.plugins.add('myplugin', {
initialize: function () {
initialize: function () {
var
_converse = this._converse;
const
_converse = this._converse;
_converse.api.listen.on('connected', function () {
_converse.api.listen.on('connected', function () {
_converse.api.archive.query({'with': 'admin2@localhost'});
_converse.api.archive.query({'with': 'admin2@localhost'});
...
@@ -363,152 +362,141 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
...
@@ -363,152 +362,141 @@ generated by `generator-conversejs <https://github.com/jcbrand/generator-convers
.. code-block:: javascript
.. code-block:: javascript
(function (root, factory) {
import converse from "@converse/headless/converse-core";
if (typeof define === 'function' && define.amd) {
// AMD. Register as a module called "myplugin"
// Commonly used utilities and variables can be found under the "env"
define(["converse"], factory);
// namespace of the "converse" global.
} else {
const Strophe = converse.env.Strophe,
// Browser globals. If you're not using a module loader such as require.js,
$iq = converse.env.$iq,
// then this line below executes. Make sure that your plugin's <script> tag
$msg = converse.env.$msg,
// appears after the one from converse.js.
$pres = converse.env.$pres,
factory(converse);
$build = converse.env.$build,
}
_ = converse.env._,
}(this, function (converse) {
dayjs = converse.env.dayjs;
// The following line registers your plugin.
converse.plugins.add("myplugin", {
/* Dependencies are other plugins which might be
* overridden or relied upon, and therefore need to be loaded before
* this plugin. They are "optional" because they might not be
* available, in which case any overrides applicable to them will be
* ignored.
*
* NB: These plugins need to have already been imported or loaded,
* either in your plugin or somewhere else.
*
* It's possible to make these dependencies "non-optional".
* If the setting "strict_plugin_dependencies" is set to true,
* an error will be raised if the plugin is not found.
*/
'dependencies': [],
/* Converse.js's plugin mechanism will call the initialize
* method on any plugin (if it exists) as soon as the plugin has
* been loaded.
*/
'initialize': function () {
/* Inside this method, you have access to the private
* `_converse` object.
*/
const _converse = this._converse;
_converse.log("The \"myplugin\" plugin is being initialized");
/* From the `_converse` object you can get any configuration
* options that the user might have passed in via
* `converse.initialize`.
*
* You can also specify new configuration settings for this
* plugin, or override the default values of existing
* configuration settings. This is done like so:
*/
_converse.api.settings.update({
'initialize_message': 'Initializing myplugin!'
});
/* The user can then pass in values for the configuration
* settings when `converse.initialize` gets called.
* For example:
*
* converse.initialize({
* "initialize_message": "My plugin has been initialized"
* });
*/
alert(this._converse.initialize_message);
// Commonly used utilities and variables can be found under the "env"
/* Besides `_converse.api.settings.update`, there is also a
// namespace of the "converse" global.
* `_converse.api.promises.add` method, which allows you to
var Strophe = converse.env.Strophe,
* add new promises that your plugin is obligated to fulfill.
$iq = converse.env.$iq,
*
$msg = converse.env.$msg,
* This method takes a string or a list of strings which
$pres = converse.env.$pres,
* represent the promise names:
$build = converse.env.$build,
*
b64_sha1 = converse.env.b64_sha1,
* _converse.api.promises.add('myPromise');
_ = converse.env._,
*
dayjs = converse.env.dayjs;
* Your plugin should then, when appropriate, resolve the
* promise by calling `_converse.api.emit`, which will also
// The following line registers your plugin.
* emit an event with the same name as the promise.
converse.plugins.add("myplugin", {
* For example:
/* Dependencies are other plugins which might be
* overridden or relied upon, and therefore need to be loaded before
* this plugin. They are "optional" because they might not be
* available, in which case any overrides applicable to them will be
* ignored.
*
*
*
NB: These plugins need to have already been loaded via require.js.
*
_converse.api.trigger('operationCompleted');
*
*
* It's possible to make these dependencies "non-optional".
* Other plugins can then either listen for the event
* If the setting "strict_plugin_dependencies" is set to true,
* `operationCompleted` like so:
* an error will be raised if the plugin is not found.
*
* _converse.api.listen.on('operationCompleted', function { ... });
*
* or they can wait for the promise to be fulfilled like so:
*
* _converse.api.waitUntil('operationCompleted', function { ... });
*/
*/
'dependencies': []
,
}
,
/* Converse.js's plugin mechanism will call the initialize
/* If you want to override some function or a Backbone model or
* method on any plugin (if it exists) as soon as the plugin has
* view defined elsewhere in converse.js, then you do that under
* been loaded.
* the "overrides" namespace.
*/
'overrides': {
/* For example, the private *_converse* object has a
* method "onConnected". You can override that method as follows:
*/
*/
'initialize': function () {
'onConnected': function () {
/* Inside this method, you have access to the private
// Overrides the onConnected method in converse.js
* `_converse` object.
*/
// Top-level functions in "overrides" are bound to the
var _converse = this._converse;
// inner "_converse" object.
_converse.log("The \"myplugin\" plugin is being initialized");
const _converse = this;
/* From the `_converse` object you can get any configuration
// Your custom code can come here ...
* options that the user might have passed in via
* `converse.initialize`.
// You can access the original function being overridden
*
// via the __super__ attribute.
* You can also specify new configuration settings for this
// Make sure to pass on the arguments supplied to this
* plugin, or override the default values of existing
// function and also to apply the proper "this" object.
* configuration settings. This is done like so:
_converse.__super__.onConnected.apply(this, arguments);
*/
_converse.api.settings.update({
// Your custom code can come here ...
'initialize_message': 'Initializing myplugin!'
});
/* The user can then pass in values for the configuration
* settings when `converse.initialize` gets called.
* For example:
*
* converse.initialize({
* "initialize_message": "My plugin has been initialized"
* });
*/
alert(this._converse.initialize_message);
/* Besides `_converse.api.settings.update`, there is also a
* `_converse.api.promises.add` method, which allows you to
* add new promises that your plugin is obligated to fulfill.
*
* This method takes a string or a list of strings which
* represent the promise names:
*
* _converse.api.promises.add('myPromise');
*
* Your plugin should then, when appropriate, resolve the
* promise by calling `_converse.api.emit`, which will also
* emit an event with the same name as the promise.
* For example:
*
* _converse.api.trigger('operationCompleted');
*
* Other plugins can then either listen for the event
* `operationCompleted` like so:
*
* _converse.api.listen.on('operationCompleted', function { ... });
*
* or they can wait for the promise to be fulfilled like so:
*
* _converse.api.waitUntil('operationCompleted', function { ... });
*/
},
},
/* If you want to override some function or a Backbone model or
/* Override converse.js's XMPPStatus Backbone model so that we can override the
* view defined elsewhere in converse.js, then you do that under
* function that sends out the presence stanza.
* the "overrides" namespace.
*/
*/
'overrides': {
'XMPPStatus': {
/* For example, the private *_converse* object has a
'sendPresence': function (type, status_message, jid) {
* method "onConnected". You can override that method as follows:
// The "_converse" object is available via the __super__
*/
// attribute.
'onConnected': function () {
const _converse = this.__super__._converse;
// Overrides the onConnected method in converse.js
// Custom code can come here ...
// Top-level functions in "overrides" are bound to the
// inner "_converse" object.
// You can call the original overridden method, by
var _converse = this;
// accessing it via the __super__ attribute.
// When calling it, you need to apply the proper
// Your custom code can come here ...
// context as reference by the "this" variable.
this.__super__.sendPresence.apply(this, arguments);
// You can access the original function being overridden
// via the __super__ attribute.
// Custom code can come here ...
// Make sure to pass on the arguments supplied to this
// function and also to apply the proper "this" object.
_converse.__super__.onConnected.apply(this, arguments);
// Your custom code can come here ...
},
/* Override converse.js's XMPPStatus Backbone model so that we can override the
* function that sends out the presence stanza.
*/
'XMPPStatus': {
'sendPresence': function (type, status_message, jid) {
// The "_converse" object is available via the __super__
// attribute.
var _converse = this.__super__._converse;
// Custom code can come here ...
// You can call the original overridden method, by
// accessing it via the __super__ attribute.
// When calling it, you need to apply the proper
// context as reference by the "this" variable.
this.__super__.sendPresence.apply(this, arguments);
// Custom code can come here ...
}
}
}
}
}
}
);
}
})
)
;
});
src/converse-bookmark-views.js
View file @
1ef29bee
...
@@ -42,20 +42,67 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -42,20 +42,67 @@ converse.plugins.add('converse-bookmark-views', {
// Overrides mentioned here will be picked up by converse.js's
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
ChatRoomView
:
{
ChatRoomView
:
{
events
:
{
events
:
{
'
click .toggle-bookmark
'
:
'
toggleBookmark
'
'
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
()
{
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
/* The initialize function gets called as soon as the plugin is
this
.
model
.
on
(
'
change:bookmarked
'
,
this
.
onBookmarked
,
this
);
* loaded by converse.js's plugin machinery.
this
.
setBookmarkState
();
*/
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
()
{
renderBookmarkToggle
()
{
if
(
this
.
el
.
querySelector
(
'
.chat-head .toggle-bookmark
'
))
{
if
(
this
.
el
.
querySelector
(
'
.chat-head .toggle-bookmark
'
))
{
return
;
return
;
...
@@ -80,21 +127,7 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -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
()
{
onBookmarked
()
{
const
{
_converse
}
=
this
.
__super__
,
{
__
}
=
_converse
;
const
icon
=
this
.
el
.
querySelector
(
'
.toggle-bookmark
'
);
const
icon
=
this
.
el
.
querySelector
(
'
.toggle-bookmark
'
);
if
(
_
.
isNull
(
icon
))
{
if
(
_
.
isNull
(
icon
))
{
return
;
return
;
...
@@ -111,7 +144,6 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -111,7 +144,6 @@ converse.plugins.add('converse-bookmark-views', {
setBookmarkState
()
{
setBookmarkState
()
{
/* Set whether the groupchat is bookmarked or not.
/* Set whether the groupchat is bookmarked or not.
*/
*/
const
{
_converse
}
=
this
.
__super__
;
if
(
!
_
.
isUndefined
(
_converse
.
bookmarks
))
{
if
(
!
_
.
isUndefined
(
_converse
.
bookmarks
))
{
const
models
=
_converse
.
bookmarks
.
where
({
'
jid
'
:
this
.
model
.
get
(
'
jid
'
)});
const
models
=
_converse
.
bookmarks
.
where
({
'
jid
'
:
this
.
model
.
get
(
'
jid
'
)});
if
(
!
models
.
length
)
{
if
(
!
models
.
length
)
{
...
@@ -125,7 +157,6 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -125,7 +157,6 @@ converse.plugins.add('converse-bookmark-views', {
renderBookmarkForm
()
{
renderBookmarkForm
()
{
this
.
hideChatRoomContents
();
this
.
hideChatRoomContents
();
if
(
!
this
.
bookmark_form
)
{
if
(
!
this
.
bookmark_form
)
{
const
{
_converse
}
=
this
.
__super__
;
this
.
bookmark_form
=
new
_converse
.
MUCBookmarkForm
({
this
.
bookmark_form
=
new
_converse
.
MUCBookmarkForm
({
'
model
'
:
this
.
model
,
'
model
'
:
this
.
model
,
'
chatroomview
'
:
this
'
chatroomview
'
:
this
...
@@ -141,7 +172,6 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -141,7 +172,6 @@ converse.plugins.add('converse-bookmark-views', {
ev
.
preventDefault
();
ev
.
preventDefault
();
ev
.
stopPropagation
();
ev
.
stopPropagation
();
}
}
const
{
_converse
}
=
this
.
__super__
;
const
models
=
_converse
.
bookmarks
.
where
({
'
jid
'
:
this
.
model
.
get
(
'
jid
'
)});
const
models
=
_converse
.
bookmarks
.
where
({
'
jid
'
:
this
.
model
.
get
(
'
jid
'
)});
if
(
!
models
.
length
)
{
if
(
!
models
.
length
)
{
this
.
renderBookmarkForm
();
this
.
renderBookmarkForm
();
...
@@ -151,48 +181,7 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -151,48 +181,7 @@ converse.plugins.add('converse-bookmark-views', {
}
}
}
}
}
}
},
Object
.
assign
(
_converse
.
ChatRoomView
.
prototype
,
bookmarkableChatRoomView
);
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
();
},
});
_converse
.
MUCBookmarkForm
=
Backbone
.
VDOMView
.
extend
({
_converse
.
MUCBookmarkForm
=
Backbone
.
VDOMView
.
extend
({
...
@@ -368,6 +357,7 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -368,6 +357,7 @@ converse.plugins.add('converse-bookmark-views', {
}
}
});
});
/************************ BEGIN Event Handlers ************************/
const
initBookmarkViews
=
async
function
()
{
const
initBookmarkViews
=
async
function
()
{
await
_converse
.
api
.
waitUntil
(
'
roomsPanelRendered
'
);
await
_converse
.
api
.
waitUntil
(
'
roomsPanelRendered
'
);
_converse
.
bookmarksview
=
new
_converse
.
BookmarksView
({
'
model
'
:
_converse
.
bookmarks
});
_converse
.
bookmarksview
=
new
_converse
.
BookmarksView
({
'
model
'
:
_converse
.
bookmarks
});
...
@@ -381,5 +371,11 @@ converse.plugins.add('converse-bookmark-views', {
...
@@ -381,5 +371,11 @@ converse.plugins.add('converse-bookmark-views', {
}
}
_converse
.
api
.
listen
.
on
(
'
bookmarksInitialized
'
,
initBookmarkViews
);
_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', {
...
@@ -105,23 +105,6 @@ converse.plugins.add('converse-controlbox', {
view
.
close
();
view
.
close
();
});
});
return
this
;
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', {
...
@@ -232,11 +215,12 @@ converse.plugins.add('converse-controlbox', {
* Triggered when the _converse.ControlBoxView has been initialized and therefore
* Triggered when the _converse.ControlBoxView has been initialized and therefore
* exists. The controlbox contains the login and register forms when the user is
* 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.
* 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 }
* @type { _converse.ControlBoxView }
* @example _converse.api.listen.on('controlboxInitialized', view => { ... });
* @example _converse.api.listen.on('controlboxInitialized', view => { ... });
*/
*/
_converse
.
api
.
trigger
(
'
controlboxInitialized
'
,
this
);
_converse
.
api
.
trigger
(
'
controlboxInitialized
'
,
this
);
_converse
.
api
.
trigger
(
'
chatBoxInitialized
'
,
this
);
},
},
render
()
{
render
()
{
...
...
src/converse-dragresize.js
View file @
1ef29bee
...
@@ -45,42 +45,6 @@ converse.plugins.add('converse-dragresize', {
...
@@ -45,42 +45,6 @@ converse.plugins.add('converse-dragresize', {
// Overrides mentioned here will be picked up by converse.js's
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
registerGlobalEventHandlers
()
{
const
that
=
this
;
document
.
addEventListener
(
'
mousemove
'
,
function
(
ev
)
{
if
(
!
that
.
resizing
||
!
that
.
allow_dragresize
)
{
return
true
;
}
ev
.
preventDefault
();
that
.
resizing
.
chatbox
.
resizeChatBox
(
ev
);
});
document
.
addEventListener
(
'
mouseup
'
,
function
(
ev
)
{
if
(
!
that
.
resizing
||
!
that
.
allow_dragresize
)
{
return
true
;
}
ev
.
preventDefault
();
const
height
=
that
.
applyDragResistance
(
that
.
resizing
.
chatbox
.
height
,
that
.
resizing
.
chatbox
.
model
.
get
(
'
default_height
'
)
);
const
width
=
that
.
applyDragResistance
(
that
.
resizing
.
chatbox
.
width
,
that
.
resizing
.
chatbox
.
model
.
get
(
'
default_width
'
)
);
if
(
that
.
connection
.
connected
)
{
that
.
resizing
.
chatbox
.
model
.
save
({
'
height
'
:
height
});
that
.
resizing
.
chatbox
.
model
.
save
({
'
width
'
:
width
});
}
else
{
that
.
resizing
.
chatbox
.
model
.
set
({
'
height
'
:
height
});
that
.
resizing
.
chatbox
.
model
.
set
({
'
width
'
:
width
});
}
that
.
resizing
=
null
;
});
return
this
.
__super__
.
registerGlobalEventHandlers
.
apply
(
this
,
arguments
);
},
ChatBox
:
{
ChatBox
:
{
initialize
()
{
initialize
()
{
const
{
_converse
}
=
this
.
__super__
;
const
{
_converse
}
=
this
.
__super__
;
...
@@ -102,9 +66,24 @@ converse.plugins.add('converse-dragresize', {
...
@@ -102,9 +66,24 @@ converse.plugins.add('converse-dragresize', {
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
},
},
initialize
()
{
render
()
{
window
.
addEventListener
(
'
resize
'
,
_
.
debounce
(
this
.
setDimensions
.
bind
(
this
),
100
));
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
this
.
setWidth
();
return
result
;
},
_show
()
{
this
.
initDragResize
().
setDimensions
();
this
.
__super__
.
_show
.
apply
(
this
,
arguments
);
}
},
HeadlinesBoxView
:
{
events
:
{
'
mousedown .dragresize-top
'
:
'
onStartVerticalResize
'
,
'
mousedown .dragresize-left
'
:
'
onStartHorizontalResize
'
,
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
},
},
render
()
{
render
()
{
...
@@ -112,27 +91,70 @@ converse.plugins.add('converse-dragresize', {
...
@@ -112,27 +91,70 @@ converse.plugins.add('converse-dragresize', {
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
this
.
setWidth
();
this
.
setWidth
();
return
result
;
return
result
;
}
},
ControlBoxView
:
{
events
:
{
'
mousedown .dragresize-top
'
:
'
onStartVerticalResize
'
,
'
mousedown .dragresize-left
'
:
'
onStartHorizontalResize
'
,
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
},
},
setWidth
()
{
render
()
{
// If a custom width is applied (due to drag-resizing),
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
// then we need to set the width of the .chatbox element as well.
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
if
(
this
.
model
.
get
(
'
width
'
))
{
this
.
setWidth
();
this
.
el
.
style
.
width
=
this
.
model
.
get
(
'
width
'
);
return
result
;
}
},
},
_show
()
{
renderLoginPanel
()
{
const
result
=
this
.
__super__
.
renderLoginPanel
.
apply
(
this
,
arguments
);
this
.
initDragResize
().
setDimensions
();
this
.
initDragResize
().
setDimensions
();
this
.
__super__
.
_show
.
apply
(
this
,
arguments
);
return
result
;
},
renderControlBoxPane
()
{
const
result
=
this
.
__super__
.
renderControlBoxPane
.
apply
(
this
,
arguments
);
this
.
initDragResize
().
setDimensions
();
return
result
;
}
},
ChatRoomView
:
{
events
:
{
'
mousedown .dragresize-top
'
:
'
onStartVerticalResize
'
,
'
mousedown .dragresize-left
'
:
'
onStartHorizontalResize
'
,
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
},
},
render
()
{
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
this
.
setWidth
();
return
result
;
}
}
},
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
({
'
allow_dragresize
'
:
true
,
});
const
dragResizable
=
{
initDragResize
()
{
initDragResize
()
{
/* Determine and store the default box size.
/* Determine and store the default box size.
* We need this information for the drag-resizing feature.
* We need this information for the drag-resizing feature.
*/
*/
const
{
_converse
}
=
this
.
__super__
,
const
flyout
=
this
.
el
.
querySelector
(
'
.box-flyout
'
),
flyout
=
this
.
el
.
querySelector
(
'
.box-flyout
'
),
style
=
window
.
getComputedStyle
(
flyout
);
style
=
window
.
getComputedStyle
(
flyout
);
if
(
_
.
isUndefined
(
this
.
model
.
get
(
'
height
'
)))
{
if
(
_
.
isUndefined
(
this
.
model
.
get
(
'
height
'
)))
{
...
@@ -157,6 +179,34 @@ converse.plugins.add('converse-dragresize', {
...
@@ -157,6 +179,34 @@ converse.plugins.add('converse-dragresize', {
return
this
;
return
this
;
},
},
resizeChatBox
(
ev
)
{
let
diff
;
if
(
_converse
.
resizing
.
direction
.
indexOf
(
'
top
'
)
===
0
)
{
diff
=
ev
.
pageY
-
this
.
prev_pageY
;
if
(
diff
)
{
this
.
height
=
((
this
.
height
-
diff
)
>
(
this
.
model
.
get
(
'
min_height
'
)
||
0
))
?
(
this
.
height
-
diff
)
:
this
.
model
.
get
(
'
min_height
'
);
this
.
prev_pageY
=
ev
.
pageY
;
this
.
setChatBoxHeight
(
this
.
height
);
}
}
if
(
_
.
includes
(
_converse
.
resizing
.
direction
,
'
left
'
))
{
diff
=
this
.
prev_pageX
-
ev
.
pageX
;
if
(
diff
)
{
this
.
width
=
((
this
.
width
+
diff
)
>
(
this
.
model
.
get
(
'
min_width
'
)
||
0
))
?
(
this
.
width
+
diff
)
:
this
.
model
.
get
(
'
min_width
'
);
this
.
prev_pageX
=
ev
.
pageX
;
this
.
setChatBoxWidth
(
this
.
width
);
}
}
},
setWidth
()
{
// If a custom width is applied (due to drag-resizing),
// then we need to set the width of the .chatbox element as well.
if
(
this
.
model
.
get
(
'
width
'
))
{
this
.
el
.
style
.
width
=
this
.
model
.
get
(
'
width
'
);
}
},
setDimensions
()
{
setDimensions
()
{
// Make sure the chat box has the right height and width.
// Make sure the chat box has the right height and width.
this
.
adjustToViewport
();
this
.
adjustToViewport
();
...
@@ -165,7 +215,6 @@ converse.plugins.add('converse-dragresize', {
...
@@ -165,7 +215,6 @@ converse.plugins.add('converse-dragresize', {
},
},
setChatBoxHeight
(
height
)
{
setChatBoxHeight
(
height
)
{
const
{
_converse
}
=
this
.
__super__
;
if
(
height
)
{
if
(
height
)
{
height
=
_converse
.
applyDragResistance
(
height
,
this
.
model
.
get
(
'
default_height
'
))
+
'
px
'
;
height
=
_converse
.
applyDragResistance
(
height
,
this
.
model
.
get
(
'
default_height
'
))
+
'
px
'
;
}
else
{
}
else
{
...
@@ -178,7 +227,6 @@ converse.plugins.add('converse-dragresize', {
...
@@ -178,7 +227,6 @@ converse.plugins.add('converse-dragresize', {
},
},
setChatBoxWidth
(
width
)
{
setChatBoxWidth
(
width
)
{
const
{
_converse
}
=
this
.
__super__
;
if
(
width
)
{
if
(
width
)
{
width
=
_converse
.
applyDragResistance
(
width
,
this
.
model
.
get
(
'
default_width
'
))
+
'
px
'
;
width
=
_converse
.
applyDragResistance
(
width
,
this
.
model
.
get
(
'
default_width
'
))
+
'
px
'
;
}
else
{
}
else
{
...
@@ -208,7 +256,6 @@ converse.plugins.add('converse-dragresize', {
...
@@ -208,7 +256,6 @@ converse.plugins.add('converse-dragresize', {
},
},
onStartVerticalResize
(
ev
)
{
onStartVerticalResize
(
ev
)
{
const
{
_converse
}
=
this
.
__super__
;
if
(
!
_converse
.
allow_dragresize
)
{
return
true
;
}
if
(
!
_converse
.
allow_dragresize
)
{
return
true
;
}
// Record element attributes for mouseMove().
// Record element attributes for mouseMove().
const
flyout
=
this
.
el
.
querySelector
(
'
.box-flyout
'
),
const
flyout
=
this
.
el
.
querySelector
(
'
.box-flyout
'
),
...
@@ -222,7 +269,6 @@ converse.plugins.add('converse-dragresize', {
...
@@ -222,7 +269,6 @@ converse.plugins.add('converse-dragresize', {
},
},
onStartHorizontalResize
(
ev
)
{
onStartHorizontalResize
(
ev
)
{
const
{
_converse
}
=
this
.
__super__
;
if
(
!
_converse
.
allow_dragresize
)
{
return
true
;
}
if
(
!
_converse
.
allow_dragresize
)
{
return
true
;
}
const
flyout
=
this
.
el
.
querySelector
(
'
.box-flyout
'
),
const
flyout
=
this
.
el
.
querySelector
(
'
.box-flyout
'
),
style
=
window
.
getComputedStyle
(
flyout
);
style
=
window
.
getComputedStyle
(
flyout
);
...
@@ -235,116 +281,13 @@ converse.plugins.add('converse-dragresize', {
...
@@ -235,116 +281,13 @@ converse.plugins.add('converse-dragresize', {
},
},
onStartDiagonalResize
(
ev
)
{
onStartDiagonalResize
(
ev
)
{
const
{
_converse
}
=
this
.
__super__
;
this
.
onStartHorizontalResize
(
ev
);
this
.
onStartHorizontalResize
(
ev
);
this
.
onStartVerticalResize
(
ev
);
this
.
onStartVerticalResize
(
ev
);
_converse
.
resizing
.
direction
=
'
topleft
'
;
_converse
.
resizing
.
direction
=
'
topleft
'
;
},
},
};
Object
.
assign
(
_converse
.
ChatBoxView
.
prototype
,
dragResizable
);
resizeChatBox
(
ev
)
{
let
diff
;
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
resizing
.
direction
.
indexOf
(
'
top
'
)
===
0
)
{
diff
=
ev
.
pageY
-
this
.
prev_pageY
;
if
(
diff
)
{
this
.
height
=
((
this
.
height
-
diff
)
>
(
this
.
model
.
get
(
'
min_height
'
)
||
0
))
?
(
this
.
height
-
diff
)
:
this
.
model
.
get
(
'
min_height
'
);
this
.
prev_pageY
=
ev
.
pageY
;
this
.
setChatBoxHeight
(
this
.
height
);
}
}
if
(
_
.
includes
(
_converse
.
resizing
.
direction
,
'
left
'
))
{
diff
=
this
.
prev_pageX
-
ev
.
pageX
;
if
(
diff
)
{
this
.
width
=
((
this
.
width
+
diff
)
>
(
this
.
model
.
get
(
'
min_width
'
)
||
0
))
?
(
this
.
width
+
diff
)
:
this
.
model
.
get
(
'
min_width
'
);
this
.
prev_pageX
=
ev
.
pageX
;
this
.
setChatBoxWidth
(
this
.
width
);
}
}
}
},
HeadlinesBoxView
:
{
events
:
{
'
mousedown .dragresize-top
'
:
'
onStartVerticalResize
'
,
'
mousedown .dragresize-left
'
:
'
onStartHorizontalResize
'
,
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
},
initialize
()
{
window
.
addEventListener
(
'
resize
'
,
_
.
debounce
(
this
.
setDimensions
.
bind
(
this
),
100
));
return
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
},
render
()
{
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
this
.
setWidth
();
return
result
;
}
},
ControlBoxView
:
{
events
:
{
'
mousedown .dragresize-top
'
:
'
onStartVerticalResize
'
,
'
mousedown .dragresize-left
'
:
'
onStartHorizontalResize
'
,
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
},
initialize
()
{
window
.
addEventListener
(
'
resize
'
,
_
.
debounce
(
this
.
setDimensions
.
bind
(
this
),
100
));
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
},
render
()
{
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
this
.
setWidth
();
return
result
;
},
renderLoginPanel
()
{
const
result
=
this
.
__super__
.
renderLoginPanel
.
apply
(
this
,
arguments
);
this
.
initDragResize
().
setDimensions
();
return
result
;
},
renderControlBoxPane
()
{
const
result
=
this
.
__super__
.
renderControlBoxPane
.
apply
(
this
,
arguments
);
this
.
initDragResize
().
setDimensions
();
return
result
;
}
},
ChatRoomView
:
{
events
:
{
'
mousedown .dragresize-top
'
:
'
onStartVerticalResize
'
,
'
mousedown .dragresize-left
'
:
'
onStartHorizontalResize
'
,
'
mousedown .dragresize-topleft
'
:
'
onStartDiagonalResize
'
},
initialize
()
{
window
.
addEventListener
(
'
resize
'
,
_
.
debounce
(
this
.
setDimensions
.
bind
(
this
),
100
));
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
},
render
()
{
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
renderDragResizeHandles
(
this
.
__super__
.
_converse
,
this
);
this
.
setWidth
();
return
result
;
}
}
},
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
({
allow_dragresize
:
true
,
});
_converse
.
applyDragResistance
=
function
(
value
,
default_value
)
{
_converse
.
applyDragResistance
=
function
(
value
,
default_value
)
{
/* This method applies some resistance around the
/* This method applies some resistance around the
...
@@ -363,6 +306,45 @@ converse.plugins.add('converse-dragresize', {
...
@@ -363,6 +306,45 @@ converse.plugins.add('converse-dragresize', {
}
}
return
value
;
return
value
;
};
};
/************************ BEGIN Event Handlers ************************/
function
registerGlobalEventHandlers
()
{
document
.
addEventListener
(
'
mousemove
'
,
function
(
ev
)
{
if
(
!
_converse
.
resizing
||
!
_converse
.
allow_dragresize
)
{
return
true
;
}
ev
.
preventDefault
();
_converse
.
resizing
.
chatbox
.
resizeChatBox
(
ev
);
});
document
.
addEventListener
(
'
mouseup
'
,
function
(
ev
)
{
if
(
!
_converse
.
resizing
||
!
_converse
.
allow_dragresize
)
{
return
true
;
}
ev
.
preventDefault
();
const
height
=
_converse
.
applyDragResistance
(
_converse
.
resizing
.
chatbox
.
height
,
_converse
.
resizing
.
chatbox
.
model
.
get
(
'
default_height
'
)
);
const
width
=
_converse
.
applyDragResistance
(
_converse
.
resizing
.
chatbox
.
width
,
_converse
.
resizing
.
chatbox
.
model
.
get
(
'
default_width
'
)
);
if
(
_converse
.
connection
.
connected
)
{
_converse
.
resizing
.
chatbox
.
model
.
save
({
'
height
'
:
height
});
_converse
.
resizing
.
chatbox
.
model
.
save
({
'
width
'
:
width
});
}
else
{
_converse
.
resizing
.
chatbox
.
model
.
set
({
'
height
'
:
height
});
_converse
.
resizing
.
chatbox
.
model
.
set
({
'
width
'
:
width
});
}
_converse
.
resizing
=
null
;
});
}
_converse
.
api
.
listen
.
on
(
'
registeredGlobalEventHandlers
'
,
registerGlobalEventHandlers
);
_converse
.
api
.
listen
.
on
(
'
chatBoxInitialized
'
,
view
=>
{
window
.
addEventListener
(
'
resize
'
,
_
.
debounce
(()
=>
view
.
setDimensions
(),
100
));
});
/************************ END Event Handlers ************************/
}
}
});
});
src/converse-minimize.js
View file @
1ef29bee
...
@@ -30,7 +30,7 @@ converse.plugins.add('converse-minimize', {
...
@@ -30,7 +30,7 @@ converse.plugins.add('converse-minimize', {
*
*
* NB: These plugins need to have already been loaded via require.js.
* 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
)
{
enabled
(
_converse
)
{
return
_converse
.
view_mode
===
'
overlayed
'
;
return
_converse
.
view_mode
===
'
overlayed
'
;
...
@@ -57,20 +57,6 @@ converse.plugins.add('converse-minimize', {
...
@@ -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
)
{
maybeShow
(
force
)
{
if
(
!
force
&&
this
.
get
(
'
minimized
'
))
{
if
(
!
force
&&
this
.
get
(
'
minimized
'
))
{
// Must return the chatbox
// Must return the chatbox
...
@@ -122,65 +108,17 @@ converse.plugins.add('converse-minimize', {
...
@@ -122,65 +108,17 @@ converse.plugins.add('converse-minimize', {
if
(
!
this
.
model
.
get
(
'
minimized
'
))
{
if
(
!
this
.
model
.
get
(
'
minimized
'
))
{
return
this
.
__super__
.
setChatBoxWidth
.
apply
(
this
,
arguments
);
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
:
{
ChatBoxHeading
:
{
render
()
{
render
()
{
const
{
_converse
}
=
this
.
__super__
,
const
{
_converse
}
=
this
.
__super__
,
{
__
}
=
_converse
;
{
__
}
=
_converse
;
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
const
result
=
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
const
new_html
=
tpl_chatbox_minimize
(
const
new_html
=
tpl_chatbox_minimize
(
{
{
info_minimize
:
__
(
'
Minimize this chat box
'
)}
'
info_minimize
'
:
__
(
'
Minimize this chat box
'
)
);
}
);
const
el
=
this
.
el
.
querySelector
(
'
.toggle-chatbox-button
'
);
const
el
=
this
.
el
.
querySelector
(
'
.toggle-chatbox-button
'
);
if
(
el
)
{
if
(
el
)
{
el
.
outerHTML
=
new_html
;
el
.
outerHTML
=
new_html
;
...
@@ -227,11 +165,109 @@ converse.plugins.add('converse-minimize', {
...
@@ -227,11 +165,109 @@ converse.plugins.add('converse-minimize', {
}
}
return
div
.
innerHTML
;
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
)
{
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
u
.
getOuterWidth
(
view
.
el
,
true
);
}
}
return
0
;
return
0
;
...
@@ -315,25 +351,8 @@ converse.plugins.add('converse-minimize', {
...
@@ -315,25 +351,8 @@ converse.plugins.add('converse-minimize', {
return
model
;
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
'
);
_converse
.
api
.
promises
.
add
(
'
minimizedChatsInitialized
'
);
...
@@ -525,6 +544,7 @@ converse.plugins.add('converse-minimize', {
...
@@ -525,6 +544,7 @@ converse.plugins.add('converse-minimize', {
}
}
});
});
/************************ BEGIN Event Handlers ************************/
Promise
.
all
([
Promise
.
all
([
_converse
.
api
.
waitUntil
(
'
connectionInitialized
'
),
_converse
.
api
.
waitUntil
(
'
connectionInitialized
'
),
_converse
.
api
.
waitUntil
(
'
chatBoxViewsInitialized
'
)
_converse
.
api
.
waitUntil
(
'
chatBoxViewsInitialized
'
)
...
@@ -559,5 +579,6 @@ converse.plugins.add('converse-minimize', {
...
@@ -559,5 +579,6 @@ converse.plugins.add('converse-minimize', {
_converse
.
chatboxviews
.
trimChats
(
chatbox
);
_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', {
...
@@ -62,41 +62,14 @@ converse.plugins.add('converse-muc-views', {
dependencies
:
[
"
converse-autocomplete
"
,
"
converse-modal
"
,
"
converse-controlbox
"
,
"
converse-chatview
"
],
dependencies
:
[
"
converse-autocomplete
"
,
"
converse-modal
"
,
"
converse-controlbox
"
,
"
converse-chatview
"
],
overrides
:
{
overrides
:
{
ControlBoxView
:
{
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
()
{
renderControlBoxPane
()
{
const
{
_converse
}
=
this
.
__super__
;
const
{
_converse
}
=
this
.
__super__
;
this
.
__super__
.
renderControlBoxPane
.
apply
(
this
,
arguments
);
this
.
__super__
.
renderControlBoxPane
.
apply
(
this
,
arguments
);
if
(
_converse
.
allow_muc
)
{
if
(
_converse
.
allow_muc
)
{
this
.
renderRoomsPanel
();
this
.
renderRoomsPanel
();
}
}
}
,
}
}
}
},
},
...
@@ -123,6 +96,35 @@ converse.plugins.add('converse-muc-views', {
...
@@ -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
)
{
function
___
(
str
)
{
/* This is part of a hack to get gettext to scan strings to be
/* This is part of a hack to get gettext to scan strings to be
* translated. Strings we cannot send to the function above because
* translated. Strings we cannot send to the function above because
...
@@ -572,6 +574,7 @@ converse.plugins.add('converse-muc-views', {
...
@@ -572,6 +574,7 @@ converse.plugins.add('converse-muc-views', {
* @example _converse.api.listen.on('chatRoomOpened', view => { ... });
* @example _converse.api.listen.on('chatRoomOpened', view => { ... });
*/
*/
_converse
.
api
.
trigger
(
'
chatRoomOpened
'
,
this
);
_converse
.
api
.
trigger
(
'
chatRoomOpened
'
,
this
);
_converse
.
api
.
trigger
(
'
chatBoxInitialized
'
,
this
);
},
},
render
()
{
render
()
{
...
...
src/converse-oauth.js
View file @
1ef29bee
...
@@ -38,12 +38,12 @@ converse.plugins.add("converse-oauth", {
...
@@ -38,12 +38,12 @@ converse.plugins.add("converse-oauth", {
/* For example, the private *_converse* object has a
/* For example, the private *_converse* object has a
* method "onConnected". You can override that method as follows:
* method "onConnected". You can override that method as follows:
*/
*/
'
LoginPanel
'
:
{
LoginPanel
:
{
insertOAuthProviders
()
{
insertOAuthProviders
()
{
const
{
_converse
}
=
this
.
__super__
;
const
{
_converse
}
=
this
.
__super__
;
if
(
_
.
isUndefined
(
this
.
oauth_providers_view
))
{
if
(
_
.
isUndefined
(
this
.
oauth_providers_view
))
{
this
.
oauth_providers_view
=
this
.
oauth_providers_view
=
new
_converse
.
OAuthProvidersView
({
'
model
'
:
_converse
.
oauth_providers
});
new
_converse
.
OAuthProvidersView
({
'
model
'
:
_converse
.
oauth_providers
});
this
.
oauth_providers_view
.
render
();
this
.
oauth_providers_view
.
render
();
...
...
src/converse-omemo.js
View file @
1ef29bee
...
@@ -172,6 +172,90 @@ converse.plugins.add('converse-omemo', {
...
@@ -172,6 +172,90 @@ converse.plugins.add('converse-omemo', {
},
},
ChatBox
:
{
ChatBox
:
{
async
getMessageAttributesFromStanza
(
stanza
,
original_stanza
)
{
const
{
_converse
}
=
this
.
__super__
;
const
encrypted
=
sizzle
(
`encrypted[xmlns="
${
Strophe
.
NS
.
OMEMO
}
"]`
,
original_stanza
).
pop
(),
attrs
=
await
this
.
__super__
.
getMessageAttributesFromStanza
.
apply
(
this
,
arguments
);
if
(
!
encrypted
||
!
_converse
.
config
.
get
(
'
trusted
'
))
{
return
attrs
;
}
else
{
return
this
.
getEncryptionAttributesfromStanza
(
stanza
,
original_stanza
,
attrs
);
}
},
async
sendMessage
(
text
,
spoiler_hint
)
{
if
(
this
.
get
(
'
omemo_active
'
)
&&
text
)
{
const
{
_converse
}
=
this
.
__super__
;
const
attrs
=
this
.
getOutgoingMessageAttributes
(
text
,
spoiler_hint
);
attrs
[
'
is_encrypted
'
]
=
true
;
attrs
[
'
plaintext
'
]
=
attrs
.
message
;
try
{
const
devices
=
await
_converse
.
getBundlesAndBuildSessions
(
this
);
const
stanza
=
await
_converse
.
createOMEMOMessageStanza
(
this
,
this
.
messages
.
create
(
attrs
),
devices
);
_converse
.
api
.
send
(
stanza
);
}
catch
(
e
)
{
this
.
handleMessageSendError
(
e
);
return
false
;
}
return
true
;
}
else
{
return
this
.
__super__
.
sendMessage
.
apply
(
this
,
arguments
);
}
}
},
ChatBoxView
:
{
events
:
{
'
click .toggle-omemo
'
:
'
toggleOMEMO
'
},
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
change:omemo_active
'
,
this
.
renderOMEMOToolbarButton
,
this
);
this
.
model
.
on
(
'
change:omemo_supported
'
,
this
.
onOMEMOSupportedDetermined
,
this
);
},
showMessage
(
message
)
{
// We don't show a message if it's only keying material
if
(
!
message
.
get
(
'
is_only_key
'
))
{
return
this
.
__super__
.
showMessage
.
apply
(
this
,
arguments
);
}
}
},
ChatRoomView
:
{
events
:
{
'
click .toggle-omemo
'
:
'
toggleOMEMO
'
},
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
change:omemo_active
'
,
this
.
renderOMEMOToolbarButton
,
this
);
this
.
model
.
on
(
'
change:omemo_supported
'
,
this
.
onOMEMOSupportedDetermined
,
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
.
api
.
promises
.
add
([
'
OMEMOInitialized
'
]);
_converse
.
NUM_PREKEYS
=
100
;
// Set here so that tests can override
/**
* Mixin object that contains OMEMO-related methods for
* {@link _converse.ChatBox} or {@link _converse.ChatRoom} objects.
*
* @typedef {Object} OMEMOEnabledChatBox
*/
const
OMEMOEnabledChatBox
=
{
async
encryptMessage
(
plaintext
)
{
async
encryptMessage
(
plaintext
)
{
// The client MUST use fresh, randomly generated key/IV pairs
// The client MUST use fresh, randomly generated key/IV pairs
...
@@ -219,7 +303,6 @@ converse.plugins.add('converse-omemo', {
...
@@ -219,7 +303,6 @@ converse.plugins.add('converse-omemo', {
},
},
reportDecryptionError
(
e
)
{
reportDecryptionError
(
e
)
{
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
debug
)
{
if
(
_converse
.
debug
)
{
const
{
__
}
=
_converse
;
const
{
__
}
=
_converse
;
this
.
messages
.
create
({
this
.
messages
.
create
({
...
@@ -231,8 +314,7 @@ converse.plugins.add('converse-omemo', {
...
@@ -231,8 +314,7 @@ converse.plugins.add('converse-omemo', {
},
},
async
handleDecryptedWhisperMessage
(
attrs
,
key_and_tag
)
{
async
handleDecryptedWhisperMessage
(
attrs
,
key_and_tag
)
{
const
{
_converse
}
=
this
.
__super__
,
const
encrypted
=
attrs
.
encrypted
,
encrypted
=
attrs
.
encrypted
,
devicelist
=
_converse
.
devicelists
.
getDeviceList
(
this
.
get
(
'
jid
'
));
devicelist
=
_converse
.
devicelists
.
getDeviceList
(
this
.
get
(
'
jid
'
));
this
.
save
(
'
omemo_supported
'
,
true
);
this
.
save
(
'
omemo_supported
'
,
true
);
...
@@ -250,8 +332,7 @@ converse.plugins.add('converse-omemo', {
...
@@ -250,8 +332,7 @@ converse.plugins.add('converse-omemo', {
},
},
decrypt
(
attrs
)
{
decrypt
(
attrs
)
{
const
{
_converse
}
=
this
.
__super__
,
const
session_cipher
=
this
.
getSessionCipher
(
attrs
.
from
,
parseInt
(
attrs
.
encrypted
.
device_id
,
10
));
session_cipher
=
this
.
getSessionCipher
(
attrs
.
from
,
parseInt
(
attrs
.
encrypted
.
device_id
,
10
));
// https://xmpp.org/extensions/xep-0384.html#usecases-receiving
// https://xmpp.org/extensions/xep-0384.html#usecases-receiving
if
(
attrs
.
encrypted
.
prekey
===
true
)
{
if
(
attrs
.
encrypted
.
prekey
===
true
)
{
...
@@ -284,8 +365,7 @@ converse.plugins.add('converse-omemo', {
...
@@ -284,8 +365,7 @@ converse.plugins.add('converse-omemo', {
},
},
getEncryptionAttributesfromStanza
(
stanza
,
original_stanza
,
attrs
)
{
getEncryptionAttributesfromStanza
(
stanza
,
original_stanza
,
attrs
)
{
const
{
_converse
}
=
this
.
__super__
,
const
encrypted
=
sizzle
(
`encrypted[xmlns="
${
Strophe
.
NS
.
OMEMO
}
"]`
,
original_stanza
).
pop
(),
encrypted
=
sizzle
(
`encrypted[xmlns="
${
Strophe
.
NS
.
OMEMO
}
"]`
,
original_stanza
).
pop
(),
header
=
encrypted
.
querySelector
(
'
header
'
),
header
=
encrypted
.
querySelector
(
'
header
'
),
key
=
sizzle
(
`key[rid="
${
_converse
.
omemo_store
.
get
(
'
device_id
'
)}
"]`
,
encrypted
).
pop
();
key
=
sizzle
(
`key[rid="
${
_converse
.
omemo_store
.
get
(
'
device_id
'
)}
"]`
,
encrypted
).
pop
();
if
(
key
)
{
if
(
key
)
{
...
@@ -303,22 +383,8 @@ converse.plugins.add('converse-omemo', {
...
@@ -303,22 +383,8 @@ converse.plugins.add('converse-omemo', {
}
}
},
},
async
getMessageAttributesFromStanza
(
stanza
,
original_stanza
)
{
const
{
_converse
}
=
this
.
__super__
,
encrypted
=
sizzle
(
`encrypted[xmlns="
${
Strophe
.
NS
.
OMEMO
}
"]`
,
original_stanza
).
pop
(),
attrs
=
await
this
.
__super__
.
getMessageAttributesFromStanza
.
apply
(
this
,
arguments
);
if
(
!
encrypted
||
!
_converse
.
config
.
get
(
'
trusted
'
))
{
return
attrs
;
}
else
{
return
this
.
getEncryptionAttributesfromStanza
(
stanza
,
original_stanza
,
attrs
);
}
},
getSessionCipher
(
jid
,
id
)
{
getSessionCipher
(
jid
,
id
)
{
const
{
_converse
}
=
this
.
__super__
,
const
address
=
new
libsignal
.
SignalProtocolAddress
(
jid
,
id
);
address
=
new
libsignal
.
SignalProtocolAddress
(
jid
,
id
);
this
.
session_cipher
=
new
window
.
libsignal
.
SessionCipher
(
_converse
.
omemo_store
,
address
);
this
.
session_cipher
=
new
window
.
libsignal
.
SessionCipher
(
_converse
.
omemo_store
,
address
);
return
this
.
session_cipher
;
return
this
.
session_cipher
;
},
},
...
@@ -330,8 +396,6 @@ converse.plugins.add('converse-omemo', {
...
@@ -330,8 +396,6 @@ converse.plugins.add('converse-omemo', {
},
},
handleMessageSendError
(
e
)
{
handleMessageSendError
(
e
)
{
const
{
_converse
}
=
this
.
__super__
,
{
__
}
=
_converse
;
if
(
e
.
name
===
'
IQError
'
)
{
if
(
e
.
name
===
'
IQError
'
)
{
this
.
save
(
'
omemo_supported
'
,
false
);
this
.
save
(
'
omemo_supported
'
,
false
);
...
@@ -355,46 +419,12 @@ converse.plugins.add('converse-omemo', {
...
@@ -355,46 +419,12 @@ converse.plugins.add('converse-omemo', {
}
else
{
}
else
{
throw
e
;
throw
e
;
}
}
},
async
sendMessage
(
text
,
spoiler_hint
)
{
if
(
this
.
get
(
'
omemo_active
'
)
&&
text
)
{
const
{
_converse
}
=
this
.
__super__
;
const
attrs
=
this
.
getOutgoingMessageAttributes
(
text
,
spoiler_hint
);
attrs
[
'
is_encrypted
'
]
=
true
;
attrs
[
'
plaintext
'
]
=
attrs
.
message
;
try
{
const
devices
=
await
_converse
.
getBundlesAndBuildSessions
(
this
);
const
stanza
=
await
_converse
.
createOMEMOMessageStanza
(
this
,
this
.
messages
.
create
(
attrs
),
devices
);
_converse
.
api
.
send
(
stanza
);
}
catch
(
e
)
{
this
.
handleMessageSendError
(
e
);
return
false
;
}
return
true
;
}
else
{
return
this
.
__super__
.
sendMessage
.
apply
(
this
,
arguments
);
}
}
}
},
}
Object
.
assign
(
_converse
.
ChatBox
.
prototype
,
OMEMOEnabledChatBox
);
ChatBoxView
:
{
events
:
{
'
click .toggle-omemo
'
:
'
toggleOMEMO
'
},
initialize
()
{
const
OMEMOEnabledChatView
=
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
change:omemo_active
'
,
this
.
renderOMEMOToolbarButton
,
this
);
this
.
model
.
on
(
'
change:omemo_supported
'
,
this
.
onOMEMOSupportedDetermined
,
this
);
},
showMessage
(
message
)
{
// We don't show a message if it's only keying material
if
(
!
message
.
get
(
'
is_only_key
'
))
{
return
this
.
__super__
.
showMessage
.
apply
(
this
,
arguments
);
}
},
onOMEMOSupportedDetermined
()
{
onOMEMOSupportedDetermined
()
{
if
(
!
this
.
model
.
get
(
'
omemo_supported
'
)
&&
this
.
model
.
get
(
'
omemo_active
'
))
{
if
(
!
this
.
model
.
get
(
'
omemo_supported
'
)
&&
this
.
model
.
get
(
'
omemo_active
'
))
{
...
@@ -405,82 +435,47 @@ converse.plugins.add('converse-omemo', {
...
@@ -405,82 +435,47 @@ converse.plugins.add('converse-omemo', {
},
},
renderOMEMOToolbarButton
()
{
renderOMEMOToolbarButton
()
{
const
{
_converse
}
=
this
.
__super__
,
if
(
this
.
model
.
get
(
'
type
'
)
!==
_converse
.
CHATROOMS_TYPE
||
{
__
}
=
_converse
,
this
.
model
.
features
.
get
(
'
membersonly
'
)
&&
icon
=
this
.
el
.
querySelector
(
'
.toggle-omemo
'
),
this
.
model
.
features
.
get
(
'
nonanonymous
'
))
{
html
=
tpl_toolbar_omemo
(
Object
.
assign
(
this
.
model
.
toJSON
(),
{
'
__
'
:
__
}));
if
(
icon
)
{
const
icon
=
this
.
el
.
querySelector
(
'
.toggle-omemo
'
);
icon
.
outerHTML
=
html
;
const
html
=
tpl_toolbar_omemo
(
Object
.
assign
(
this
.
model
.
toJSON
(),
{
'
__
'
:
__
}));
if
(
icon
)
{
icon
.
outerHTML
=
html
;
}
else
{
this
.
el
.
querySelector
(
'
.chat-toolbar
'
).
insertAdjacentHTML
(
'
beforeend
'
,
html
);
}
}
else
{
}
else
{
this
.
el
.
querySelector
(
'
.chat-toolbar
'
).
insertAdjacentHTML
(
'
beforeend
'
,
html
);
const
icon
=
this
.
el
.
querySelector
(
'
.toggle-omemo
'
);
if
(
icon
)
{
icon
.
parentElement
.
removeChild
(
icon
);
}
}
}
},
},
toggleOMEMO
(
ev
)
{
toggleOMEMO
(
ev
)
{
const
{
_converse
}
=
this
.
__super__
,
{
__
}
=
_converse
;
if
(
!
this
.
model
.
get
(
'
omemo_supported
'
))
{
if
(
!
this
.
model
.
get
(
'
omemo_supported
'
))
{
return
_converse
.
api
.
alert
.
show
(
let
messages
;
Strophe
.
LogLevel
.
ERROR
,
if
(
this
.
model
.
get
(
'
type
'
)
===
_converse
.
CHATROOMS_TYPE
)
{
__
(
'
Error
'
),
messages
=
[
__
(
[
__
(
"
Cannot use end-to-end encryption because %1$s uses a client that doesn't support OMEMO.
"
,
'
Cannot use end-to-end encryption in this groupchat,
'
+
'
either the groupchat has some anonymity or not all participants support OMEMO.
'
)];
}
else
{
messages
=
[
__
(
"
Cannot use end-to-end encryption because %1$s uses a client that doesn't support OMEMO.
"
,
this
.
model
.
contact
.
getDisplayName
()
this
.
model
.
contact
.
getDisplayName
()
)]
)];
)
}
}
return
_converse
.
api
.
alert
.
show
(
Strophe
.
LogLevel
.
ERROR
,
__
(
'
Error
'
),
messages
);
ev
.
preventDefault
();
this
.
model
.
save
({
'
omemo_active
'
:
!
this
.
model
.
get
(
'
omemo_active
'
)});
}
},
ChatRoomView
:
{
events
:
{
'
click .toggle-omemo
'
:
'
toggleOMEMO
'
},
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
change:omemo_active
'
,
this
.
renderOMEMOToolbarButton
,
this
);
this
.
model
.
on
(
'
change:omemo_supported
'
,
this
.
onOMEMOSupportedDetermined
,
this
);
},
toggleOMEMO
(
ev
)
{
const
{
_converse
}
=
this
.
__super__
,
{
__
}
=
_converse
;
if
(
!
this
.
model
.
get
(
'
omemo_supported
'
))
{
return
_converse
.
api
.
alert
.
show
(
Strophe
.
LogLevel
.
ERROR
,
__
(
'
Error
'
),
[
__
(
'
Cannot use end-to-end encryption in this groupchat,
'
+
'
either the groupchat has some anonymity or not all participants support OMEMO.
'
)]
);
}
}
ev
.
preventDefault
();
ev
.
preventDefault
();
this
.
model
.
save
({
'
omemo_active
'
:
!
this
.
model
.
get
(
'
omemo_active
'
)});
this
.
model
.
save
({
'
omemo_active
'
:
!
this
.
model
.
get
(
'
omemo_active
'
)});
},
renderOMEMOToolbarButton
()
{
if
(
this
.
model
.
features
.
get
(
'
membersonly
'
)
&&
this
.
model
.
features
.
get
(
'
nonanonymous
'
))
{
this
.
__super__
.
renderOMEMOToolbarButton
.
apply
(
arguments
);
}
else
{
const
icon
=
this
.
el
.
querySelector
(
'
.toggle-omemo
'
);
if
(
icon
)
{
icon
.
parentElement
.
removeChild
(
icon
);
}
}
}
}
}
}
},
Object
.
assign
(
_converse
.
ChatBoxView
.
prototype
,
OMEMOEnabledChatView
);
initialize
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by Converse.js's plugin machinery.
*/
const
{
_converse
}
=
this
,
{
__
}
=
_converse
;
_converse
.
api
.
promises
.
add
([
'
OMEMOInitialized
'
]);
_converse
.
NUM_PREKEYS
=
100
;
// Set here so that tests can override
async
function
generateFingerprint
(
device
)
{
async
function
generateFingerprint
(
device
)
{
if
(
_
.
get
(
device
.
get
(
'
bundle
'
),
'
fingerprint
'
))
{
if
(
_
.
get
(
device
.
get
(
'
bundle
'
),
'
fingerprint
'
))
{
...
...
src/converse-register.js
View file @
1ef29bee
...
@@ -45,17 +45,6 @@ converse.plugins.add('converse-register', {
...
@@ -45,17 +45,6 @@ converse.plugins.add('converse-register', {
// New functions which don't exist yet can also be added.
// New functions which don't exist yet can also be added.
LoginPanel
:
{
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
)
{
render
(
cfg
)
{
const
{
_converse
}
=
this
.
__super__
;
const
{
_converse
}
=
this
.
__super__
;
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
this
.
__super__
.
render
.
apply
(
this
,
arguments
);
...
@@ -67,11 +56,50 @@ converse.plugins.add('converse-register', {
...
@@ -67,11 +56,50 @@ converse.plugins.add('converse-register', {
},
},
ControlBoxView
:
{
ControlBoxView
:
{
renderLoginPanel
()
{
/* Also render a registration panel, when rendering the
* login panel.
*/
this
.
__super__
.
renderLoginPanel
.
apply
(
this
,
arguments
);
this
.
renderRegistrationPanel
();
return
this
;
}
}
},
initialize
()
{
initialize
()
{
this
.
__super__
.
initialize
.
apply
(
this
,
arguments
);
/* The initialize function gets called as soon as the plugin is
this
.
model
.
on
(
'
change:active-form
'
,
this
.
showLoginOrRegisterForm
.
bind
(
this
))
* 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
()
{
showLoginOrRegisterForm
()
{
const
{
_converse
}
=
this
.
__super__
;
const
{
_converse
}
=
this
.
__super__
;
...
@@ -88,7 +116,6 @@ converse.plugins.add('converse-register', {
...
@@ -88,7 +116,6 @@ converse.plugins.add('converse-register', {
},
},
renderRegistrationPanel
()
{
renderRegistrationPanel
()
{
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
allow_registration
)
{
if
(
_converse
.
allow_registration
)
{
this
.
registerpanel
=
new
_converse
.
RegisterPanel
({
this
.
registerpanel
=
new
_converse
.
RegisterPanel
({
'
model
'
:
this
.
model
'
model
'
:
this
.
model
...
@@ -102,36 +129,7 @@ converse.plugins.add('converse-register', {
...
@@ -102,36 +129,7 @@ converse.plugins.add('converse-register', {
this
.
showLoginOrRegisterForm
();
this
.
showLoginOrRegisterForm
();
}
}
return
this
;
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', {
...
@@ -679,6 +677,12 @@ converse.plugins.add('converse-register', {
return
false
;
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', {
...
@@ -29,27 +29,6 @@ converse.plugins.add('converse-rosterview', {
dependencies
:
[
"
converse-roster
"
,
"
converse-modal
"
],
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
()
{
initialize
()
{
/* The initialize function gets called as soon as the plugin is
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
* loaded by converse.js's plugin machinery.
...
@@ -78,36 +57,6 @@ converse.plugins.add('converse-rosterview', {
...
@@ -78,36 +57,6 @@ converse.plugins.add('converse-rosterview', {
'
away
'
:
__
(
'
This contact is away
'
)
'
away
'
:
__
(
'
This contact is away
'
)
};
};
const
LABEL_GROUPS
=
__
(
'
Groups
'
);
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
({
_converse
.
AddContactModal
=
_converse
.
BootstrapModal
.
extend
({
...
@@ -678,7 +627,7 @@ converse.plugins.add('converse-rosterview', {
...
@@ -678,7 +627,7 @@ converse.plugins.add('converse-rosterview', {
let
matches
;
let
matches
;
q
=
q
.
toLowerCase
();
q
=
q
.
toLowerCase
();
if
(
type
===
'
state
'
)
{
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
// When filtering by chat state, we still want to
// show requesting contacts, even though they don't
// show requesting contacts, even though they don't
// have the state in question.
// have the state in question.
...
@@ -747,13 +696,13 @@ converse.plugins.add('converse-rosterview', {
...
@@ -747,13 +696,13 @@ converse.plugins.add('converse-rosterview', {
},
},
onContactSubscriptionChange
(
contact
)
{
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
);
this
.
removeContact
(
contact
);
}
}
},
},
onContactRequestChange
(
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
);
this
.
removeContact
(
contact
);
}
}
},
},
...
@@ -926,16 +875,16 @@ converse.plugins.add('converse-rosterview', {
...
@@ -926,16 +875,16 @@ converse.plugins.add('converse-rosterview', {
this
.
update
();
this
.
update
();
if
(
_
.
has
(
contact
.
changed
,
'
subscription
'
))
{
if
(
_
.
has
(
contact
.
changed
,
'
subscription
'
))
{
if
(
contact
.
changed
.
subscription
===
'
from
'
)
{
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
'
)))
{
}
else
if
(
_
.
includes
([
'
both
'
,
'
to
'
],
contact
.
get
(
'
subscription
'
)))
{
this
.
addExistingContact
(
contact
);
this
.
addExistingContact
(
contact
);
}
}
}
}
if
(
_
.
has
(
contact
.
changed
,
'
ask
'
)
&&
contact
.
changed
.
ask
===
'
subscribe
'
)
{
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
'
)
{
if
(
_
.
has
(
contact
.
changed
,
'
subscription
'
)
&&
contact
.
changed
.
requesting
===
'
true
'
)
{
this
.
addContactToGroup
(
contact
,
HEADER_REQUESTING_CONTACTS
);
this
.
addContactToGroup
(
contact
,
_converse
.
HEADER_REQUESTING_CONTACTS
);
}
}
this
.
updateFilter
();
this
.
updateFilter
();
},
},
...
@@ -961,10 +910,10 @@ converse.plugins.add('converse-rosterview', {
...
@@ -961,10 +910,10 @@ converse.plugins.add('converse-rosterview', {
if
(
_converse
.
roster_groups
)
{
if
(
_converse
.
roster_groups
)
{
groups
=
contact
.
get
(
'
groups
'
);
groups
=
contact
.
get
(
'
groups
'
);
if
(
groups
.
length
===
0
)
{
if
(
groups
.
length
===
0
)
{
groups
=
[
HEADER_UNGROUPED
];
groups
=
[
_converse
.
HEADER_UNGROUPED
];
}
}
}
else
{
}
else
{
groups
=
[
HEADER_CURRENT_CONTACTS
];
groups
=
[
_converse
.
HEADER_CURRENT_CONTACTS
];
}
}
_
.
each
(
groups
,
_
.
bind
(
this
.
addContactToGroup
,
this
,
contact
,
_
,
options
));
_
.
each
(
groups
,
_
.
bind
(
this
.
addContactToGroup
,
this
,
contact
,
_
,
options
));
},
},
...
@@ -982,9 +931,9 @@ converse.plugins.add('converse-rosterview', {
...
@@ -982,9 +931,9 @@ converse.plugins.add('converse-rosterview', {
return
;
return
;
}
}
if
((
contact
.
get
(
'
ask
'
)
===
'
subscribe
'
)
||
(
contact
.
get
(
'
subscription
'
)
===
'
from
'
))
{
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
)
{
}
else
if
(
contact
.
get
(
'
requesting
'
)
===
true
)
{
this
.
addContactToGroup
(
contact
,
HEADER_REQUESTING_CONTACTS
,
options
);
this
.
addContactToGroup
(
contact
,
_converse
.
HEADER_REQUESTING_CONTACTS
,
options
);
}
}
}
}
return
this
;
return
this
;
...
...
src/converse-singleton.js
View file @
1ef29bee
...
@@ -82,7 +82,7 @@ converse.plugins.add('converse-singleton', {
...
@@ -82,7 +82,7 @@ converse.plugins.add('converse-singleton', {
const
{
_converse
}
=
this
.
__super__
;
const
{
_converse
}
=
this
.
__super__
;
if
(
_converse
.
isUniView
())
{
if
(
_converse
.
isUniView
())
{
return
false
;
return
false
;
}
else
{
}
else
{
return
this
.
__super__
.
shouldShowOnTextMessage
.
apply
(
this
,
arguments
);
return
this
.
__super__
.
shouldShowOnTextMessage
.
apply
(
this
,
arguments
);
}
}
},
},
...
...
src/headless/converse-bookmarks.js
View file @
1ef29bee
...
@@ -40,13 +40,11 @@ converse.plugins.add('converse-bookmarks', {
...
@@ -40,13 +40,11 @@ converse.plugins.add('converse-bookmarks', {
// New functions which don't exist yet can also be added.
// New functions which don't exist yet can also be added.
ChatRoom
:
{
ChatRoom
:
{
getAndPersistNickname
(
nick
)
{
getAndPersistNickname
(
nick
)
{
const
{
_converse
}
=
this
.
__super__
;
const
{
_converse
}
=
this
.
__super__
;
nick
=
nick
||
_converse
.
getNicknameFromBookmark
(
this
.
get
(
'
jid
'
));
nick
=
nick
||
_converse
.
getNicknameFromBookmark
(
this
.
get
(
'
jid
'
));
return
this
.
__super__
.
getAndPersistNickname
.
call
(
this
,
nick
);
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='') {
...
@@ -251,7 +251,7 @@ _converse.log = function (message, level, style='') {
message
=
message
.
outerHTML
;
message
=
message
.
outerHTML
;
}
}
const
prefix
=
style
?
'
%c
'
:
''
;
const
prefix
=
style
?
'
%c
'
:
''
;
const
logger
=
_
.
assign
({
const
logger
=
Object
.
assign
({
'
debug
'
:
_
.
get
(
console
,
'
log
'
)
?
console
.
log
.
bind
(
console
)
:
_
.
noop
,
'
debug
'
:
_
.
get
(
console
,
'
log
'
)
?
console
.
log
.
bind
(
console
)
:
_
.
noop
,
'
error
'
:
_
.
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
,
'
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', {
...
@@ -29,9 +29,40 @@ converse.plugins.add('converse-mam', {
// Overrides mentioned here will be picked up by converse.js's
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
ChatBox
:
{
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
()
{
fetchNewestMessages
()
{
/* Fetches messages that might have been archived *after*
/* Fetches messages that might have been archived *after*
...
@@ -40,7 +71,6 @@ converse.plugins.add('converse-mam', {
...
@@ -40,7 +71,6 @@ converse.plugins.add('converse-mam', {
if
(
this
.
disable_mam
)
{
if
(
this
.
disable_mam
)
{
return
;
return
;
}
}
const
{
_converse
}
=
this
.
__super__
;
const
most_recent_msg
=
u
.
getMostRecentMessage
(
this
);
const
most_recent_msg
=
u
.
getMostRecentMessage
(
this
);
if
(
_
.
isNil
(
most_recent_msg
))
{
if
(
_
.
isNil
(
most_recent_msg
))
{
...
@@ -59,7 +89,6 @@ converse.plugins.add('converse-mam', {
...
@@ -59,7 +89,6 @@ converse.plugins.add('converse-mam', {
if
(
this
.
disable_mam
)
{
if
(
this
.
disable_mam
)
{
return
;
return
;
}
}
const
{
_converse
}
=
this
.
__super__
;
const
is_groupchat
=
this
.
get
(
'
type
'
)
===
CHATROOMS_TYPE
;
const
is_groupchat
=
this
.
get
(
'
type
'
)
===
CHATROOMS_TYPE
;
const
mam_jid
=
is_groupchat
?
this
.
get
(
'
jid
'
)
:
_converse
.
bare_jid
;
const
mam_jid
=
is_groupchat
?
this
.
get
(
'
jid
'
)
:
_converse
.
bare_jid
;
if
(
!
(
await
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
MAM
,
mam_jid
)))
{
if
(
!
(
await
_converse
.
api
.
disco
.
supports
(
Strophe
.
NS
.
MAM
,
mam_jid
)))
{
...
@@ -92,7 +121,6 @@ converse.plugins.add('converse-mam', {
...
@@ -92,7 +121,6 @@ converse.plugins.add('converse-mam', {
},
},
async
findDuplicateFromArchiveID
(
stanza
)
{
async
findDuplicateFromArchiveID
(
stanza
)
{
const
{
_converse
}
=
this
.
__super__
;
const
result
=
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
stanza
).
pop
();
const
result
=
sizzle
(
`result[xmlns="
${
Strophe
.
NS
.
MAM
}
"]`
,
stanza
).
pop
();
if
(
!
result
)
{
if
(
!
result
)
{
return
null
;
return
null
;
...
@@ -107,32 +135,11 @@ converse.plugins.add('converse-mam', {
...
@@ -107,32 +135,11 @@ converse.plugins.add('converse-mam', {
return
this
.
messages
.
findWhere
(
query
);
return
this
.
messages
.
findWhere
(
query
);
},
},
async
getDuplicateMessage
(
stanza
)
{
}
const
message
=
await
this
.
__super__
.
getDuplicateMessage
.
apply
(
this
,
arguments
);
Object
.
assign
(
_converse
.
ChatBox
.
prototype
,
MAMEnabledChat
);
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
;
}
},
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
()
{
fetchArchivedMessagesIfNecessary
()
{
if
(
this
.
get
(
'
connection_status
'
)
!==
converse
.
ROOMSTATUS
.
ENTERED
||
if
(
this
.
get
(
'
connection_status
'
)
!==
converse
.
ROOMSTATUS
.
ENTERED
||
!
this
.
get
(
'
mam_enabled
'
)
||
!
this
.
get
(
'
mam_enabled
'
)
||
...
@@ -142,22 +149,9 @@ converse.plugins.add('converse-mam', {
...
@@ -142,22 +149,9 @@ converse.plugins.add('converse-mam', {
this
.
fetchArchivedMessages
();
this
.
fetchArchivedMessages
();
this
.
save
({
'
mam_initialized
'
:
true
});
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
)
{
_converse
.
onMAMError
=
function
(
iq
)
{
if
(
iq
.
querySelectorAll
(
'
feature-not-implemented
'
).
length
)
{
if
(
iq
.
querySelectorAll
(
'
feature-not-implemented
'
).
length
)
{
_converse
.
log
(
_converse
.
log
(
...
@@ -220,6 +214,11 @@ converse.plugins.add('converse-mam', {
...
@@ -220,6 +214,11 @@ converse.plugins.add('converse-mam', {
_converse
.
api
.
listen
.
on
(
'
afterMessagesFetched
'
,
chat
=>
chat
.
fetchNewestMessages
());
_converse
.
api
.
listen
.
on
(
'
afterMessagesFetched
'
,
chat
=>
chat
.
fetchNewestMessages
());
_converse
.
api
.
listen
.
on
(
'
chatReconnected
'
,
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
(
'
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 **************************/
/************************ END Event Handlers **************************/
...
...
src/headless/converse-roster.js
View file @
1ef29bee
...
@@ -36,6 +36,17 @@ converse.plugins.add('converse-roster', {
...
@@ -36,6 +36,17 @@ converse.plugins.add('converse-roster', {
'
rosterInitialized
'
,
'
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
.
registerPresenceHandler
=
function
()
{
_converse
.
unregisterPresenceHandler
();
_converse
.
unregisterPresenceHandler
();
...
@@ -381,6 +392,10 @@ converse.plugins.add('converse-roster', {
...
@@ -381,6 +392,10 @@ converse.plugins.add('converse-roster', {
model
:
_converse
.
RosterContact
,
model
:
_converse
.
RosterContact
,
comparator
(
contact1
,
contact2
)
{
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
status1
=
contact1
.
presence
.
get
(
'
show
'
)
||
'
offline
'
;
const
status2
=
contact2
.
presence
.
get
(
'
show
'
)
||
'
offline
'
;
const
status2
=
contact2
.
presence
.
get
(
'
show
'
)
||
'
offline
'
;
if
(
_converse
.
STATUS_WEIGHTS
[
status1
]
===
_converse
.
STATUS_WEIGHTS
[
status2
])
{
if
(
_converse
.
STATUS_WEIGHTS
[
status1
]
===
_converse
.
STATUS_WEIGHTS
[
status2
])
{
...
@@ -854,6 +869,23 @@ converse.plugins.add('converse-roster', {
...
@@ -854,6 +869,23 @@ converse.plugins.add('converse-roster', {
_converse
.
RosterGroups
=
Backbone
.
Collection
.
extend
({
_converse
.
RosterGroups
=
Backbone
.
Collection
.
extend
({
model
:
_converse
.
RosterGroup
,
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
()
{
fetchRosterGroups
()
{
/* Fetches all the roster groups from sessionStorage.
/* 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