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
1676258c
Commit
1676258c
authored
Mar 13, 2016
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move the MAM features to a separate plugin.
parent
da72be8f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
229 additions
and
159 deletions
+229
-159
converse.js
converse.js
+2
-0
spec/mam.js
spec/mam.js
+2
-2
src/converse-api.js
src/converse-api.js
+0
-3
src/converse-core.js
src/converse-core.js
+7
-151
src/converse-headline.js
src/converse-headline.js
+1
-1
src/converse-mam.js
src/converse-mam.js
+216
-0
src/converse-muc.js
src/converse-muc.js
+1
-2
No files found.
converse.js
View file @
1676258c
...
...
@@ -50,6 +50,7 @@ require.config({
"
converse-controlbox
"
:
"
src/converse-controlbox
"
,
"
converse-core
"
:
"
src/converse-core
"
,
"
converse-headline
"
:
"
src/converse-headline
"
,
"
converse-mam
"
:
"
src/converse-mam
"
,
"
converse-muc
"
:
"
src/converse-muc
"
,
"
converse-notification
"
:
"
src/converse-notification
"
,
"
converse-otr
"
:
"
src/converse-otr
"
,
...
...
@@ -228,6 +229,7 @@ if (typeof define !== 'undefined') {
// translations that you care about.
"
converse-chatview
"
,
// Renders standalone chat boxes for single user chat
"
converse-mam
"
,
"
converse-muc
"
,
// XEP-0045 Multi-user chat
"
converse-otr
"
,
// Off-the-record encryption for one-on-one messages
"
converse-controlbox
"
,
// The control box
...
...
spec/mam.js
View file @
1676258c
...
...
@@ -378,7 +378,7 @@
sent_stanza
=
iq
;
IQ_id
=
sendIQ
.
bind
(
this
)(
iq
,
callback
,
errback
);
});
spyOn
(
converse
.
features
,
'
onMAMPreferences
'
).
andCallThrough
();
spyOn
(
converse
,
'
onMAMPreferences
'
).
andCallThrough
();
var
feature
=
new
converse
.
Feature
({
'
var
'
:
Strophe
.
NS
.
MAM
...
...
@@ -409,7 +409,7 @@
.
c
(
'
never
'
).
c
(
'
jid
'
).
t
(
'
montague@montague.lit
'
);
converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
stanza
));
expect
(
converse
.
features
.
onMAMPreferences
).
toHaveBeenCalled
();
expect
(
converse
.
onMAMPreferences
).
toHaveBeenCalled
();
expect
(
converse
.
connection
.
sendIQ
.
callCount
).
toBe
(
2
);
expect
(
sent_stanza
.
toString
()).
toBe
(
...
...
src/converse-api.js
View file @
1676258c
...
...
@@ -122,9 +122,6 @@
return
_
.
map
(
jids
,
_
.
partial
(
_
.
compose
(
converse
.
wrappedChatBox
,
converse
.
chatboxes
.
getChatBox
.
bind
(
converse
.
chatboxes
)),
_
,
true
));
}
},
'
archive
'
:
{
'
query
'
:
converse
.
queryForArchivedMessages
.
bind
(
converse
)
},
'
tokens
'
:
{
'
get
'
:
function
(
id
)
{
if
(
!
converse
.
expose_rid_and_sid
||
typeof
converse
.
connection
===
"
undefined
"
)
{
...
...
src/converse-core.js
View file @
1676258c
...
...
@@ -107,95 +107,6 @@
9
:
'
REDIRECT
'
};
// TODO Refactor into external MAM plugin
// XEP-0059 Result Set Management
var
RSM_ATTRIBUTES
=
[
'
max
'
,
'
first
'
,
'
last
'
,
'
after
'
,
'
before
'
,
'
index
'
,
'
count
'
];
// XEP-0313 Message Archive Management
var
MAM_ATTRIBUTES
=
[
'
with
'
,
'
start
'
,
'
end
'
];
converse
.
queryForArchivedMessages
=
function
(
options
,
callback
,
errback
)
{
/* Do a MAM (XEP-0313) query for archived messages.
*
* Parameters:
* (Object) options - Query parameters, either MAM-specific or also for Result Set Management.
* (Function) callback - A function to call whenever we receive query-relevant stanza.
* (Function) errback - A function to call when an error stanza is received.
*
* The options parameter can also be an instance of
* Strophe.RSM to enable easy querying between results pages.
*
* The callback function may be called multiple times, first
* for the initial IQ result and then for each message
* returned. The last time the callback is called, a
* Strophe.RSM object is returned on which "next" or "previous"
* can be called before passing it in again to this method, to
* get the next or previous page in the result set.
*/
var
date
,
messages
=
[];
if
(
typeof
options
===
"
function
"
)
{
callback
=
options
;
errback
=
callback
;
}
if
(
!
converse
.
features
.
findWhere
({
'
var
'
:
Strophe
.
NS
.
MAM
}))
{
converse
.
log
(
'
This server does not support XEP-0313, Message Archive Management
'
);
errback
(
null
);
return
;
}
var
queryid
=
converse
.
connection
.
getUniqueId
();
var
attrs
=
{
'
type
'
:
'
set
'
};
if
(
typeof
options
!==
"
undefined
"
&&
options
.
groupchat
)
{
if
(
!
options
[
'
with
'
])
{
throw
new
Error
(
'
You need to specify a "with" value containing the chat room JID, when querying groupchat messages.
'
);
}
attrs
.
to
=
options
[
'
with
'
];
}
var
stanza
=
$iq
(
attrs
).
c
(
'
query
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
MAM
,
'
queryid
'
:
queryid
});
if
(
typeof
options
!==
"
undefined
"
)
{
stanza
.
c
(
'
x
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
XFORM
,
'
type
'
:
'
submit
'
})
.
c
(
'
field
'
,
{
'
var
'
:
'
FORM_TYPE
'
,
'
type
'
:
'
hidden
'
})
.
c
(
'
value
'
).
t
(
Strophe
.
NS
.
MAM
).
up
().
up
();
if
(
options
[
'
with
'
]
&&
!
options
.
groupchat
)
{
stanza
.
c
(
'
field
'
,
{
'
var
'
:
'
with
'
}).
c
(
'
value
'
).
t
(
options
[
'
with
'
]).
up
().
up
();
}
_
.
each
([
'
start
'
,
'
end
'
],
function
(
t
)
{
if
(
options
[
t
])
{
date
=
moment
(
options
[
t
]);
if
(
date
.
isValid
())
{
stanza
.
c
(
'
field
'
,
{
'
var
'
:
t
}).
c
(
'
value
'
).
t
(
date
.
format
()).
up
().
up
();
}
else
{
throw
new
TypeError
(
'
archive.query: invalid date provided for:
'
+
t
);
}
}
});
stanza
.
up
();
if
(
options
instanceof
Strophe
.
RSM
)
{
stanza
.
cnode
(
options
.
toXML
());
}
else
if
(
_
.
intersection
(
RSM_ATTRIBUTES
,
_
.
keys
(
options
)).
length
)
{
stanza
.
cnode
(
new
Strophe
.
RSM
(
options
).
toXML
());
}
}
converse
.
connection
.
addHandler
(
function
(
message
)
{
var
$msg
=
$
(
message
),
$fin
,
rsm
;
if
(
typeof
callback
===
"
function
"
)
{
$fin
=
$msg
.
find
(
'
fin[xmlns="
'
+
Strophe
.
NS
.
MAM
+
'
"]
'
);
if
(
$fin
.
length
)
{
rsm
=
new
Strophe
.
RSM
({
xml
:
$fin
.
find
(
'
set
'
)[
0
]});
_
.
extend
(
rsm
,
_
.
pick
(
options
,
[
'
max
'
]));
_
.
extend
(
rsm
,
_
.
pick
(
options
,
MAM_ATTRIBUTES
));
callback
(
messages
,
rsm
);
return
false
;
// We've received all messages, decommission this handler
}
else
if
(
queryid
===
$msg
.
find
(
'
result
'
).
attr
(
'
queryid
'
))
{
messages
.
push
(
message
);
}
return
true
;
}
else
{
return
false
;
// There's no callback, so no use in continuing this handler.
}
},
Strophe
.
NS
.
MAM
);
converse
.
connection
.
sendIQ
(
stanza
,
null
,
errback
,
converse
.
message_archiving_timeout
);
};
converse
.
log
=
function
(
txt
,
level
)
{
var
logger
;
if
(
typeof
console
===
"
undefined
"
||
typeof
console
.
log
===
"
undefined
"
)
{
...
...
@@ -237,7 +148,6 @@
Strophe
.
addNamespace
(
'
CARBONS
'
,
'
urn:xmpp:carbons:2
'
);
Strophe
.
addNamespace
(
'
CHATSTATES
'
,
'
http://jabber.org/protocol/chatstates
'
);
Strophe
.
addNamespace
(
'
CSI
'
,
'
urn:xmpp:csi:0
'
);
Strophe
.
addNamespace
(
'
MAM
'
,
'
urn:xmpp:mam:0
'
);
Strophe
.
addNamespace
(
'
ROSTERX
'
,
'
http://jabber.org/protocol/rosterx
'
);
Strophe
.
addNamespace
(
'
RSM
'
,
'
http://jabber.org/protocol/rsm
'
);
Strophe
.
addNamespace
(
'
XFORM
'
,
'
jabber:x:data
'
);
...
...
@@ -346,7 +256,6 @@
allow_dragresize
:
true
,
allow_logout
:
true
,
animate
:
true
,
archived_messages_page_size
:
'
20
'
,
authentication
:
'
login
'
,
// Available values are "login", "prebind", "anonymous".
auto_away
:
0
,
// Seconds after which user status is set to 'away'
auto_list_rooms
:
false
,
...
...
@@ -365,8 +274,6 @@
jid
:
undefined
,
keepalive
:
false
,
locked_domain
:
undefined
,
message_archiving
:
'
never
'
,
// Supported values are 'always', 'never', 'roster' (See https://xmpp.org/extensions/xep-0313.html#prefs )
message_archiving_timeout
:
8000
,
// The amount of time (in milliseconds) to wait before aborting a MAM (XEP-0313) request
message_carbons
:
false
,
// Support for XEP-280
no_trimming
:
false
,
// Set to true for phantomjs tests (where browser apparently has no width)
password
:
undefined
,
...
...
@@ -1378,7 +1285,7 @@
});
},
createMessage
:
function
(
$message
,
$delay
,
archive_id
)
{
createMessage
:
function
(
$message
,
$delay
)
{
$delay
=
$delay
||
$message
.
find
(
'
delay
'
);
var
body
=
$message
.
children
(
'
body
'
).
text
(),
delayed
=
$delay
.
length
>
0
,
...
...
@@ -1409,15 +1316,14 @@
}
else
{
sender
=
'
them
'
;
}
this
.
messages
.
create
({
return
this
.
messages
.
create
({
chat_state
:
chat_state
,
delayed
:
delayed
,
fullname
:
fullname
,
message
:
body
||
undefined
,
msgid
:
msgid
,
sender
:
sender
,
time
:
time
,
archive_id
:
archive_id
time
:
time
});
}
});
...
...
@@ -1466,8 +1372,7 @@
chatbox
,
resource
,
from_jid
=
$message
.
attr
(
'
from
'
),
to_jid
=
$message
.
attr
(
'
to
'
),
to_resource
=
Strophe
.
getResourceFromJid
(
to_jid
),
archive_id
=
$message
.
find
(
'
result[xmlns="
'
+
Strophe
.
NS
.
MAM
+
'
"]
'
).
attr
(
'
id
'
);
to_resource
=
Strophe
.
getResourceFromJid
(
to_jid
);
if
(
to_resource
&&
to_resource
!==
converse
.
resource
)
{
converse
.
log
(
'
Ignore incoming message intended for a different resource:
'
+
to_jid
,
'
info
'
);
...
...
@@ -1506,7 +1411,7 @@
if
(
msgid
&&
chatbox
.
messages
.
findWhere
({
msgid
:
msgid
}))
{
return
true
;
// We already have this message stored.
}
chatbox
.
createMessage
(
$message
,
$delay
,
archive_id
);
chatbox
.
createMessage
(
$message
,
$delay
);
converse
.
roster
.
addResource
(
contact_jid
,
resource
);
converse
.
emit
(
'
message
'
,
message
);
return
true
;
...
...
@@ -1943,57 +1848,7 @@
},
onFeatureAdded
:
function
(
feature
)
{
var
prefs
=
feature
.
get
(
'
preferences
'
)
||
{};
converse
.
emit
(
'
serviceDiscovered
'
,
feature
);
if
(
feature
.
get
(
'
var
'
)
===
Strophe
.
NS
.
MAM
&&
prefs
[
'
default
'
]
!==
converse
.
message_archiving
)
{
// Ask the server for archiving preferences
converse
.
connection
.
sendIQ
(
$iq
({
'
type
'
:
'
get
'
}).
c
(
'
prefs
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
MAM
}),
_
.
bind
(
this
.
onMAMPreferences
,
this
,
feature
),
_
.
bind
(
this
.
onMAMError
,
this
,
feature
)
);
}
},
onMAMPreferences
:
function
(
feature
,
iq
)
{
/* Handle returned IQ stanza containing Message Archive
* Management (XEP-0313) preferences.
*
* XXX: For now we only handle the global default preference.
* The XEP also provides for per-JID preferences, which is
* currently not supported in converse.js.
*
* Per JID preferences will be set in chat boxes, so it'll
* probbaly be handled elsewhere in any case.
*/
var
$prefs
=
$
(
iq
).
find
(
'
prefs[xmlns="
'
+
Strophe
.
NS
.
MAM
+
'
"]
'
);
var
default_pref
=
$prefs
.
attr
(
'
default
'
);
var
stanza
;
if
(
default_pref
!==
converse
.
message_archiving
)
{
stanza
=
$iq
({
'
type
'
:
'
set
'
}).
c
(
'
prefs
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
MAM
,
'
default
'
:
converse
.
message_archiving
});
$prefs
.
children
().
each
(
function
(
idx
,
child
)
{
stanza
.
cnode
(
child
).
up
();
});
converse
.
connection
.
sendIQ
(
stanza
,
_
.
bind
(
function
(
feature
,
iq
)
{
// XXX: Strictly speaking, the server should respond with the updated prefs
// (see example 18: https://xmpp.org/extensions/xep-0313.html#config)
// but Prosody doesn't do this, so we don't rely on it.
feature
.
save
({
'
preferences
'
:
{
'
default
'
:
converse
.
message_archiving
}});
},
this
,
feature
),
_
.
bind
(
this
.
onMAMError
,
this
,
feature
)
);
}
else
{
feature
.
save
({
'
preferences
'
:
{
'
default
'
:
converse
.
message_archiving
}});
}
},
onMAMError
:
function
(
iq
)
{
if
(
$
(
iq
).
find
(
'
feature-not-implemented
'
).
length
)
{
converse
.
log
(
"
Message Archive Management (XEP-0313) not supported by this browser
"
);
}
else
{
converse
.
log
(
"
An error occured while trying to set archiving preferences.
"
);
converse
.
log
(
iq
);
}
},
addClientIdentities
:
function
()
{
...
...
@@ -2009,11 +1864,12 @@
*
* See: http://xmpp.org/extensions/xep-0030.html#info
*/
// FIXME: should go into MUC
converse
.
connection
.
disco
.
addFeature
(
'
jabber:x:conference
'
);
converse
.
connection
.
disco
.
addFeature
(
Strophe
.
NS
.
BOSH
);
converse
.
connection
.
disco
.
addFeature
(
Strophe
.
NS
.
CHATSTATES
);
converse
.
connection
.
disco
.
addFeature
(
Strophe
.
NS
.
DISCO_INFO
);
converse
.
connection
.
disco
.
addFeature
(
Strophe
.
NS
.
MAM
);
// FIXME: should go into Roster view plugin?
converse
.
connection
.
disco
.
addFeature
(
Strophe
.
NS
.
ROSTERX
);
// Limited support
if
(
converse
.
use_vcards
)
{
converse
.
connection
.
disco
.
addFeature
(
Strophe
.
NS
.
VCARD
);
...
...
src/converse-headline.js
View file @
1676258c
...
...
@@ -11,7 +11,7 @@
"
converse-core
"
,
"
converse-api
"
,
// TODO: remove this dependency
"
converse-chat
"
"
converse-chat
view
"
],
factory
);
}(
this
,
function
(
converse
,
converse_api
)
{
"
use strict
"
;
...
...
src/converse-mam.js
0 → 100644
View file @
1676258c
// Converse.js (A browser based XMPP chat client)
// http://conversejs.org
//
// Copyright (c) 2012-2016, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
/*global define */
// XEP-0059 Result Set Management
(
function
(
root
,
factory
)
{
define
(
"
converse-mam
"
,
[
"
converse-core
"
,
"
converse-api
"
],
factory
);
}(
this
,
function
(
converse
,
converse_api
)
{
"
use strict
"
;
var
$
=
converse_api
.
env
.
jQuery
,
Strophe
=
converse_api
.
env
.
Strophe
,
$iq
=
converse_api
.
env
.
$iq
,
_
=
converse_api
.
env
.
_
,
moment
=
converse_api
.
env
.
moment
;
var
RSM_ATTRIBUTES
=
[
'
max
'
,
'
first
'
,
'
last
'
,
'
after
'
,
'
before
'
,
'
index
'
,
'
count
'
];
// XEP-0313 Message Archive Management
var
MAM_ATTRIBUTES
=
[
'
with
'
,
'
start
'
,
'
end
'
];
Strophe
.
addNamespace
(
'
MAM
'
,
'
urn:xmpp:mam:0
'
);
converse_api
.
plugins
.
add
(
'
mam
'
,
{
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.
Features
:
{
addClientFeatures
:
function
()
{
converse
.
connection
.
disco
.
addFeature
(
Strophe
.
NS
.
MAM
);
return
this
.
_super
.
addClientFeatures
.
apply
(
this
,
arguments
);
}
},
ChatBoxes
:
{
createMessage
:
function
(
$message
,
$delay
)
{
var
message
=
this
.
_super
.
createMessage
.
apply
(
this
,
arguments
);
message
.
save
({
archive_id
:
$message
.
find
(
'
result[xmlns="
'
+
Strophe
.
NS
.
MAM
+
'
"]
'
).
attr
(
'
id
'
)
});
}
}
},
initialize
:
function
()
{
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
this
.
updateSettings
({
archived_messages_page_size
:
'
20
'
,
message_archiving
:
'
never
'
,
// Supported values are 'always', 'never', 'roster' (https://xmpp.org/extensions/xep-0313.html#prefs)
message_archiving_timeout
:
8000
,
// Time (in milliseconds) to wait before aborting MAM request
});
converse
.
queryForArchivedMessages
=
function
(
options
,
callback
,
errback
)
{
/* Do a MAM (XEP-0313) query for archived messages.
*
* Parameters:
* (Object) options - Query parameters, either MAM-specific or also for Result Set Management.
* (Function) callback - A function to call whenever we receive query-relevant stanza.
* (Function) errback - A function to call when an error stanza is received.
*
* The options parameter can also be an instance of
* Strophe.RSM to enable easy querying between results pages.
*
* The callback function may be called multiple times, first
* for the initial IQ result and then for each message
* returned. The last time the callback is called, a
* Strophe.RSM object is returned on which "next" or "previous"
* can be called before passing it in again to this method, to
* get the next or previous page in the result set.
*/
var
date
,
messages
=
[];
if
(
typeof
options
===
"
function
"
)
{
callback
=
options
;
errback
=
callback
;
}
if
(
!
converse
.
features
.
findWhere
({
'
var
'
:
Strophe
.
NS
.
MAM
}))
{
converse
.
log
(
'
This server does not support XEP-0313, Message Archive Management
'
);
errback
(
null
);
return
;
}
var
queryid
=
converse
.
connection
.
getUniqueId
();
var
attrs
=
{
'
type
'
:
'
set
'
};
if
(
typeof
options
!==
"
undefined
"
&&
options
.
groupchat
)
{
if
(
!
options
[
'
with
'
])
{
throw
new
Error
(
'
You need to specify a "with" value containing the chat room JID, when querying groupchat messages.
'
);
}
attrs
.
to
=
options
[
'
with
'
];
}
var
stanza
=
$iq
(
attrs
).
c
(
'
query
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
MAM
,
'
queryid
'
:
queryid
});
if
(
typeof
options
!==
"
undefined
"
)
{
stanza
.
c
(
'
x
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
XFORM
,
'
type
'
:
'
submit
'
})
.
c
(
'
field
'
,
{
'
var
'
:
'
FORM_TYPE
'
,
'
type
'
:
'
hidden
'
})
.
c
(
'
value
'
).
t
(
Strophe
.
NS
.
MAM
).
up
().
up
();
if
(
options
[
'
with
'
]
&&
!
options
.
groupchat
)
{
stanza
.
c
(
'
field
'
,
{
'
var
'
:
'
with
'
}).
c
(
'
value
'
).
t
(
options
[
'
with
'
]).
up
().
up
();
}
_
.
each
([
'
start
'
,
'
end
'
],
function
(
t
)
{
if
(
options
[
t
])
{
date
=
moment
(
options
[
t
]);
if
(
date
.
isValid
())
{
stanza
.
c
(
'
field
'
,
{
'
var
'
:
t
}).
c
(
'
value
'
).
t
(
date
.
format
()).
up
().
up
();
}
else
{
throw
new
TypeError
(
'
archive.query: invalid date provided for:
'
+
t
);
}
}
});
stanza
.
up
();
if
(
options
instanceof
Strophe
.
RSM
)
{
stanza
.
cnode
(
options
.
toXML
());
}
else
if
(
_
.
intersection
(
RSM_ATTRIBUTES
,
_
.
keys
(
options
)).
length
)
{
stanza
.
cnode
(
new
Strophe
.
RSM
(
options
).
toXML
());
}
}
converse
.
connection
.
addHandler
(
function
(
message
)
{
var
$msg
=
$
(
message
),
$fin
,
rsm
;
if
(
typeof
callback
===
"
function
"
)
{
$fin
=
$msg
.
find
(
'
fin[xmlns="
'
+
Strophe
.
NS
.
MAM
+
'
"]
'
);
if
(
$fin
.
length
)
{
rsm
=
new
Strophe
.
RSM
({
xml
:
$fin
.
find
(
'
set
'
)[
0
]});
_
.
extend
(
rsm
,
_
.
pick
(
options
,
[
'
max
'
]));
_
.
extend
(
rsm
,
_
.
pick
(
options
,
MAM_ATTRIBUTES
));
callback
(
messages
,
rsm
);
return
false
;
// We've received all messages, decommission this handler
}
else
if
(
queryid
===
$msg
.
find
(
'
result
'
).
attr
(
'
queryid
'
))
{
messages
.
push
(
message
);
}
return
true
;
}
else
{
return
false
;
// There's no callback, so no use in continuing this handler.
}
},
Strophe
.
NS
.
MAM
);
converse
.
connection
.
sendIQ
(
stanza
,
null
,
errback
,
converse
.
message_archiving_timeout
);
};
_
.
extend
(
converse_api
,
{
/* Extend default converse.js API to add methods specific to MAM
*/
'
archive
'
:
{
'
query
'
:
converse
.
queryForArchivedMessages
.
bind
(
converse
)
}
});
converse
.
onMAMError
=
function
(
iq
)
{
if
(
$
(
iq
).
find
(
'
feature-not-implemented
'
).
length
)
{
converse
.
log
(
"
Message Archive Management (XEP-0313) not supported by this browser
"
);
}
else
{
converse
.
log
(
"
An error occured while trying to set archiving preferences.
"
);
converse
.
log
(
iq
);
}
};
converse
.
onMAMPreferences
=
function
(
feature
,
iq
)
{
/* Handle returned IQ stanza containing Message Archive
* Management (XEP-0313) preferences.
*
* XXX: For now we only handle the global default preference.
* The XEP also provides for per-JID preferences, which is
* currently not supported in converse.js.
*
* Per JID preferences will be set in chat boxes, so it'll
* probbaly be handled elsewhere in any case.
*/
var
$prefs
=
$
(
iq
).
find
(
'
prefs[xmlns="
'
+
Strophe
.
NS
.
MAM
+
'
"]
'
);
var
default_pref
=
$prefs
.
attr
(
'
default
'
);
var
stanza
;
if
(
default_pref
!==
converse
.
message_archiving
)
{
stanza
=
$iq
({
'
type
'
:
'
set
'
}).
c
(
'
prefs
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
MAM
,
'
default
'
:
converse
.
message_archiving
});
$prefs
.
children
().
each
(
function
(
idx
,
child
)
{
stanza
.
cnode
(
child
).
up
();
});
converse
.
connection
.
sendIQ
(
stanza
,
_
.
partial
(
function
(
feature
,
iq
)
{
// XXX: Strictly speaking, the server should respond with the updated prefs
// (see example 18: https://xmpp.org/extensions/xep-0313.html#config)
// but Prosody doesn't do this, so we don't rely on it.
feature
.
save
({
'
preferences
'
:
{
'
default
'
:
converse
.
message_archiving
}});
},
feature
),
converse
.
onMAMError
);
}
else
{
feature
.
save
({
'
preferences
'
:
{
'
default
'
:
converse
.
message_archiving
}});
}
};
var
onFeatureAdded
=
function
(
evt
,
feature
)
{
var
prefs
=
feature
.
get
(
'
preferences
'
)
||
{};
if
(
feature
.
get
(
'
var
'
)
===
Strophe
.
NS
.
MAM
&&
prefs
[
'
default
'
]
!==
converse
.
message_archiving
)
{
// Ask the server for archiving preferences
converse
.
connection
.
sendIQ
(
$iq
({
'
type
'
:
'
get
'
}).
c
(
'
prefs
'
,
{
'
xmlns
'
:
Strophe
.
NS
.
MAM
}),
_
.
partial
(
converse
.
onMAMPreferences
,
feature
),
_
.
partial
(
converse
.
onMAMError
,
feature
)
);
}
};
converse
.
on
(
'
serviceDiscovered
'
,
onFeatureAdded
.
bind
(
converse
.
features
));
}
});
}));
src/converse-muc.js
View file @
1676258c
...
...
@@ -887,7 +887,6 @@
onChatRoomMessage
:
function
(
message
)
{
var
$message
=
$
(
message
),
archive_id
=
$message
.
find
(
'
result[xmlns="
'
+
Strophe
.
NS
.
MAM
+
'
"]
'
).
attr
(
'
id
'
),
$forwarded
=
$message
.
find
(
'
forwarded
'
),
$delay
;
...
...
@@ -916,7 +915,7 @@
if
(
sender
===
''
)
{
return
true
;
}
this
.
model
.
createMessage
(
$message
,
$delay
,
archive_id
);
this
.
model
.
createMessage
(
$message
,
$delay
);
if
(
sender
!==
this
.
model
.
get
(
'
nick
'
))
{
// We only emit an event if it's not our own message
converse
.
emit
(
'
message
'
,
message
);
...
...
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