Merge remote-tracking branch 'origin' into bootstrap4
This commit is contained in:
commit
617019af0e
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -2,7 +2,7 @@ Thanks for making a pull request to converse.js!
|
|||||||
|
|
||||||
Before submitting your request, please make sure the following conditions are met:
|
Before submitting your request, please make sure the following conditions are met:
|
||||||
|
|
||||||
- [ ] Add a changelog entry for your change in `docs/CHANGES.md`
|
- [ ] Add a changelog entry for your change in `CHANGES.md`
|
||||||
- [ ] When adding a configuration variable, please make sure to
|
- [ ] When adding a configuration variable, please make sure to
|
||||||
document it in `docs/source/configuration.rst`
|
document it in `docs/source/configuration.rst`
|
||||||
- [ ] Please add a test for your change. Tests can be run in the commandline
|
- [ ] Please add a test for your change. Tests can be run in the commandline
|
||||||
|
61
CHANGES.md
61
CHANGES.md
@ -1,5 +1,66 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 3.3.3 (2018-02-14)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- Attribute error when empty IQ stanza is returned for vCard query
|
||||||
|
- In fullscreen view, sometimes a background MUC would come into the foreground
|
||||||
|
when a new message appears inside it.
|
||||||
|
|
||||||
|
### Security fixes
|
||||||
|
|
||||||
|
- CVE-2018-6591: Don't allow PEP bookmarks if `pubsub#publish-options` is not advertised by the server.
|
||||||
|
|
||||||
|
In previous versions of converse.js, bookmarks sent to servers that don't
|
||||||
|
support `pubsub#publish-options` were visible to all your contacts, even
|
||||||
|
though they should be kept private. This is due to those servers simply
|
||||||
|
ignoring the `pubsub#publish-options` directive and converse.js not checking
|
||||||
|
first whether `pubsub#publish-options` is supported before setting bookmarks
|
||||||
|
via PEP.
|
||||||
|
|
||||||
|
More info here: https://gultsch.de/converse_bookmarks.html
|
||||||
|
|
||||||
|
### New features
|
||||||
|
- XEP-0382 Spoiler Messages (currently only for private chats)
|
||||||
|
- Listen for new room bookmarks pushed from the user's PEP service.
|
||||||
|
- Simplified the [embedded](https://conversejs.org/demo/embedded.html) usecase.
|
||||||
|
- No need to manually blacklist or whitelist any plugins.
|
||||||
|
- Relies on the [view_mode](https://conversejs.org/docs/html/configurations.html#view-mode) being set to `'embedded'`.
|
||||||
|
- The main `converse.js` build can be used for the embedded usecase.
|
||||||
|
- Maintain MUC session upon page reload
|
||||||
|
|
||||||
|
### API changes
|
||||||
|
- New API method `_converse.disco.getIdentity` to check whether a JID has a given identity.
|
||||||
|
|
||||||
|
### Configuration settings
|
||||||
|
- `auto_reconnect` is now set to `true` by default.
|
||||||
|
- New configuration setting [allow_public_bookmarks](https://conversejs.org/docs/html/configurations.html#allow-public-bookmarks)
|
||||||
|
- New configuration setting [root](https://conversejs.org/docs/html/configurations.html#root)
|
||||||
|
- The [view_mode](https://conversejs.org/docs/html/configurations.html#view-mode) setting now has a new possible value: `embedded`
|
||||||
|
|
||||||
|
### Translation updates
|
||||||
|
- Chinese (Traditional), French, German, Portuguese (Brazil), Russian, Ukrainian
|
||||||
|
|
||||||
|
## 3.3.2 (2018-01-29)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Various fixes for IE11.
|
||||||
|
- Could not register on Ejabberd 18. `"Missing attribute 'id' in tag qualified by namespace 'jabber:client'"`
|
||||||
|
- #878 Ending slash in link not recognized
|
||||||
|
- #921 FATAL error when `visible_toolbar_buttons.emoji = false`
|
||||||
|
- #959 Add padding for the iPhone X (to the mobile CSS).
|
||||||
|
- #993 `moment.format` is not a function error when sending a message.
|
||||||
|
- #994 TypeError when using the `user.login` API.
|
||||||
|
- #995 `ChildNode.replaceWith` is not available in Internet Explorer or Safari. Use `Node.replaceChild` instead.
|
||||||
|
- #999 MUC Chat Send button causes page reload
|
||||||
|
- #1000 Scroll to bottom when maximizing a chat room.
|
||||||
|
- #1003 Handle bare MUC room JIDs
|
||||||
|
|
||||||
|
### Translation changes
|
||||||
|
|
||||||
|
- Updated Dutch, French, Japanese, Norwegian Bokmål and Ukrainian translations
|
||||||
|
|
||||||
## 3.3.1 (2018-01-18)
|
## 3.3.1 (2018-01-18)
|
||||||
|
|
||||||
### UI/UX changes
|
### UI/UX changes
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* An XMPP chat client that runs in the browser.
|
* An XMPP chat client that runs in the browser.
|
||||||
*
|
*
|
||||||
* Version: 3.3.1
|
* Version: 3.3.3
|
||||||
*
|
*
|
||||||
* Copyright: JC Brand 2012-2017
|
* Copyright: JC Brand 2012-2017
|
||||||
* Except for 3rd party dependencies.
|
* Except for 3rd party dependencies.
|
||||||
|
20
Makefile
20
Makefile
@ -72,7 +72,7 @@ serve_bg: dev
|
|||||||
########################################################################
|
########################################################################
|
||||||
## Translation machinery
|
## Translation machinery
|
||||||
|
|
||||||
GETTEXT = xgettext --language="JavaScript" --keyword=__ --keyword=___ --from-code=UTF-8 --output=locale/converse.pot dist/converse-no-dependencies.js --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=3.3.1 -c
|
GETTEXT = xgettext --language="JavaScript" --keyword=__ --keyword=___ --from-code=UTF-8 --output=locale/converse.pot dist/converse-no-dependencies.js --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=3.3.3 -c
|
||||||
|
|
||||||
.PHONY: pot
|
.PHONY: pot
|
||||||
pot: dist/converse-no-dependencies.js
|
pot: dist/converse-no-dependencies.js
|
||||||
@ -101,6 +101,7 @@ release:
|
|||||||
$(SED) -ri s/version\ =\ \'[0-9]\+\.[0-9]\+\.[0-9]\+\'/version\ =\ \'$(VERSION)\'/ docs/source/conf.py
|
$(SED) -ri s/version\ =\ \'[0-9]\+\.[0-9]\+\.[0-9]\+\'/version\ =\ \'$(VERSION)\'/ docs/source/conf.py
|
||||||
$(SED) -ri s/release\ =\ \'[0-9]\+\.[0-9]\+\.[0-9]\+\'/release\ =\ \'$(VERSION)\'/ docs/source/conf.py
|
$(SED) -ri s/release\ =\ \'[0-9]\+\.[0-9]\+\.[0-9]\+\'/release\ =\ \'$(VERSION)\'/ docs/source/conf.py
|
||||||
$(SED) -ri "s/(Unreleased)/`date +%Y-%m-%d`/" CHANGES.md
|
$(SED) -ri "s/(Unreleased)/`date +%Y-%m-%d`/" CHANGES.md
|
||||||
|
$(SED) -ri "s/cdn.conversejs.org\/[0-9]+\.[0-9]+\.[0-9]+/cdn.conversejs.org\/$(VERSION)/" docs/source/quickstart.rst
|
||||||
make pot
|
make pot
|
||||||
make po
|
make po
|
||||||
make po2json
|
make po2json
|
||||||
@ -131,21 +132,21 @@ dev: stamp-bundler stamp-npm
|
|||||||
## Builds
|
## Builds
|
||||||
|
|
||||||
.PHONY: css
|
.PHONY: css
|
||||||
css: sass/*.scss css/converse.css css/converse.min.css css/mobile.min.css css/theme.min.css css/converse-muc-embedded.min.css css/inverse.css css/inverse.min.css
|
css: sass/*.scss css/converse.css css/converse.min.css css/mobile.min.css css/theme.min.css css/converse-muc-embedded.min.css css/inverse.css css/inverse.min.css css/fonts.css
|
||||||
|
|
||||||
css/inverse.css:: stamp-bundler sass sass/*
|
css/inverse.css:: stamp-bundler sass sass/*.scss
|
||||||
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/inverse/inverse.scss css/inverse.css
|
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/inverse/inverse.scss css/inverse.css
|
||||||
|
|
||||||
css/inverse.min.css:: css/inverse.css
|
css/inverse.min.css:: css/inverse.css
|
||||||
$(CLEANCSS) css/inverse.css > css/inverse.min.css
|
$(CLEANCSS) css/inverse.css > css/inverse.min.css
|
||||||
|
|
||||||
css/converse-muc-embedded.css:: stamp-bundler sass/*
|
css/converse-muc-embedded.css:: stamp-bundler sass/*.scss
|
||||||
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/_muc_embedded.scss css/converse-muc-embedded.css
|
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/_muc_embedded.scss css/converse-muc-embedded.css
|
||||||
|
|
||||||
css/converse-muc-embedded.min.css:: stamp-bundler sass css/converse-muc-embedded.css
|
css/converse-muc-embedded.min.css:: dev sass css/converse-muc-embedded.css
|
||||||
$(CLEANCSS) css/converse-muc-embedded.css > css/converse-muc-embedded.min.css
|
$(CLEANCSS) css/converse-muc-embedded.css > css/converse-muc-embedded.min.css
|
||||||
|
|
||||||
css/converse.css:: stamp-bundler sass/*
|
css/converse.css:: stamp-bundler sass/*.scss
|
||||||
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/converse/converse.scss css/converse.css
|
$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/converse/converse.scss css/converse.css
|
||||||
|
|
||||||
css/converse.min.css:: css/converse.css
|
css/converse.min.css:: css/converse.css
|
||||||
@ -154,9 +155,12 @@ css/converse.min.css:: css/converse.css
|
|||||||
css/theme.min.css:: stamp-npm css/theme.css
|
css/theme.min.css:: stamp-npm css/theme.css
|
||||||
$(CLEANCSS) css/theme.css > css/theme.min.css
|
$(CLEANCSS) css/theme.css > css/theme.min.css
|
||||||
|
|
||||||
css/mobile.min.css:: stamp-npm sass/*
|
css/mobile.min.css:: stamp-npm sass/*.scss
|
||||||
$(CLEANCSS) css/mobile.css > css/mobile.min.css
|
$(CLEANCSS) css/mobile.css > css/mobile.min.css
|
||||||
|
|
||||||
|
css/fonts.css:: dev sass/*.scss
|
||||||
|
$(SASS) -I $(BOURBON_TEMPLATES) sass/only-fonts.scss css/fonts.css
|
||||||
|
|
||||||
.PHONY: watch
|
.PHONY: watch
|
||||||
watch: stamp-bundler
|
watch: stamp-bundler
|
||||||
$(SASS) --watch -I $(BOURBON) -I $(BOOTSTRAP) sass/converse/converse.scss:css/converse.css sass/_muc_embedded.scss:css/converse-muc-embedded.css sass/inverse/inverse.scss:css/inverse.css
|
$(SASS) --watch -I $(BOURBON) -I $(BOOTSTRAP) sass/converse/converse.scss:css/converse.css sass/_muc_embedded.scss:css/converse-muc-embedded.css sass/inverse/inverse.scss:css/inverse.css
|
||||||
@ -219,7 +223,7 @@ eslint: stamp-npm
|
|||||||
|
|
||||||
.PHONY: check
|
.PHONY: check
|
||||||
check: eslint
|
check: eslint
|
||||||
LOG_CR_VERBOSITY=INFO $(CHROMIUM) --no-sandbox http://localhost:$(HTTPSERVE_PORT)/tests.html
|
LOG_CR_VERBOSITY=INFO $(CHROMIUM) --no-sandbox http://localhost:$(HTTPSERVE_PORT)/tests/index.html
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## Documentation
|
## Documentation
|
||||||
|
26
README.md
26
README.md
@ -1,7 +1,6 @@
|
|||||||
# converse.js
|
# converse.js
|
||||||
|
|
||||||
[![Greenkeeper badge](https://badges.greenkeeper.io/jcbrand/converse.js.svg)](https://greenkeeper.io/)
|
[![inVerse](https://inverse.chat/badge.svg?room=discuss@conference.conversejs.org)](https://inverse.chat/#converse/room?jid=discuss@conference.conversejs.org)
|
||||||
|
|
||||||
[![Travis](https://api.travis-ci.org/jcbrand/converse.js.png?branch=master)](https://travis-ci.org/jcbrand/converse.js)
|
[![Travis](https://api.travis-ci.org/jcbrand/converse.js.png?branch=master)](https://travis-ci.org/jcbrand/converse.js)
|
||||||
[![Bountysource bounties](https://img.shields.io/bountysource/team/converse.js/activity.svg?maxAge=2592000)](https://www.bountysource.com/teams/converse.js/issues?tracker_ids=194169)
|
[![Bountysource bounties](https://img.shields.io/bountysource/team/converse.js/activity.svg?maxAge=2592000)](https://www.bountysource.com/teams/converse.js/issues?tracker_ids=194169)
|
||||||
[![Translation status](https://hosted.weblate.org/widgets/conversejs/-/svg-badge.svg)](https://hosted.weblate.org/engage/conversejs/?utm_source=widget)
|
[![Translation status](https://hosted.weblate.org/widgets/conversejs/-/svg-badge.svg)](https://hosted.weblate.org/engage/conversejs/?utm_source=widget)
|
||||||
@ -42,7 +41,7 @@ which shows you how to use the CDN (content delivery network) to quickly get a d
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- A [plugin architecture](https://conversejs.org/docs/html/plugin_development.html) based on [pluggable.js](https://jcbrand.github.io/pluggable.js/)
|
- A [plugin architecture](https://conversejs.org/docs/html/plugin_development.html) based on [pluggable.js](https://jcbrand.github.io/pluggable.js/)
|
||||||
- Single-user chat
|
- Single-user and group chats
|
||||||
- Contacts and groups
|
- Contacts and groups
|
||||||
- Multi-user chat rooms [XEP 45](http://xmpp.org/extensions/xep-0045.html)
|
- Multi-user chat rooms [XEP 45](http://xmpp.org/extensions/xep-0045.html)
|
||||||
- Direct invitations to chat rooms [XEP 249](http://xmpp.org/extensions/xep-0249.html)
|
- Direct invitations to chat rooms [XEP 249](http://xmpp.org/extensions/xep-0249.html)
|
||||||
@ -59,6 +58,7 @@ which shows you how to use the CDN (content delivery network) to quickly get a d
|
|||||||
- Third person "/me" messages [XEP 245](http://xmpp.org/extensions/xep-0245.html)
|
- Third person "/me" messages [XEP 245](http://xmpp.org/extensions/xep-0245.html)
|
||||||
- XMPP Ping [XEP 199](http://xmpp.org/extensions/xep-0199.html)
|
- XMPP Ping [XEP 199](http://xmpp.org/extensions/xep-0199.html)
|
||||||
- Server-side archiving of messages [XEP 313](http://xmpp.org/extensions/xep-0313.html)
|
- Server-side archiving of messages [XEP 313](http://xmpp.org/extensions/xep-0313.html)
|
||||||
|
- Hidden Messages (aka Spoilers) [XEP 382](http://xmpp.org/extensions/xep-0382.html)
|
||||||
- Client state indication [XEP 352](http://xmpp.org/extensions/xep-0352.html)
|
- Client state indication [XEP 352](http://xmpp.org/extensions/xep-0352.html)
|
||||||
- Off-the-record encryption
|
- Off-the-record encryption
|
||||||
- Translated into 16 languages
|
- Translated into 16 languages
|
||||||
@ -103,3 +103,23 @@ For support queries and discussions, please join the mailing list: <conversejs@l
|
|||||||
Also take a look at the [mailing list archives](http://librelist.com/browser/conversejs).
|
Also take a look at the [mailing list archives](http://librelist.com/browser/conversejs).
|
||||||
|
|
||||||
Issues can be logged on the [Github issue tracker](https://github.com/jcbrand/converse.js/issues).
|
Issues can be logged on the [Github issue tracker](https://github.com/jcbrand/converse.js/issues).
|
||||||
|
|
||||||
|
## Donations
|
||||||
|
|
||||||
|
A heartfelt thanks for everyone who has supported this project over the years.
|
||||||
|
Many people have contributed testing, bugfixes, features and corrections.
|
||||||
|
|
||||||
|
Recently we have started accepting donations via [Patreon](https://www.patreon.com/jcbrand) and [Liberapay](https://liberapay.com/jcbrand).
|
||||||
|
|
||||||
|
The following people are making recurring donations:
|
||||||
|
|
||||||
|
* [Rafael](https://www.patreon.com/user/creators?u=4340078)
|
||||||
|
* [mt7479](https://www.patreon.com/user/creators?u=3892290)
|
||||||
|
* [roelra](https://www.patreon.com/user/creators?u=5958918)
|
||||||
|
* [Guus der Kinderen](https://www.patreon.com/user/creators?u=8302585)
|
||||||
|
* An anonymous backer on Liberapay
|
||||||
|
|
||||||
|
Additionally this project is supported by
|
||||||
|
|
||||||
|
* [![KeyCDN](https://conversejs.org/logo/keycdn.png)](https://www.keycdn.com/)
|
||||||
|
* [![Wikisuite](https://conversejs.org/logo/wikisuite.png)](http://wikisuite.org)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
https://coolors.co/app/264653-2a9d8f-e9c46a-f4a261-e76f51
|
https://coolors.co/app/264653-2a9d8f-e9c46a-f4a261-e76f51
|
||||||
http://paletton.com/#uid=70a0u0kkNs+b4JOgryLpxqpsbkI
|
http://paletton.com/#uid=70a0u0kkNs+b4JOgryLpxqpsbkI
|
||||||
*/
|
*/
|
||||||
#converse-embedded-chat {
|
#conversejs.converse-embedded {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -11,56 +11,56 @@
|
|||||||
right: auto;
|
right: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%; }
|
width: 100%; }
|
||||||
#converse-embedded-chat *, #converse-embedded-chat *:before, #converse-embedded-chat *:after {
|
#conversejs.converse-embedded *, #conversejs.converse-embedded *:before, #conversejs.converse-embedded *:after {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
box-sizing: border-box; }
|
box-sizing: border-box; }
|
||||||
#converse-embedded-chat form.pure-form.converse-centered-form {
|
#conversejs.converse-embedded form.pure-form.converse-centered-form {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 30%;
|
top: 30%;
|
||||||
transform: translateY(-50%); }
|
transform: translateY(-50%); }
|
||||||
#converse-embedded-chat .chatroom {
|
#conversejs.converse-embedded .chatroom {
|
||||||
width: auto; }
|
width: auto; }
|
||||||
#converse-embedded-chat .flyout {
|
#conversejs.converse-embedded .flyout {
|
||||||
bottom: auto;
|
bottom: auto;
|
||||||
display: block;
|
display: block;
|
||||||
position: relative; }
|
position: relative; }
|
||||||
#converse-embedded-chat .chatbox {
|
#conversejs.converse-embedded .chatbox {
|
||||||
float: none; }
|
float: none; }
|
||||||
#converse-embedded-chat .chatbox .box-flyout {
|
#conversejs.converse-embedded .chatbox .box-flyout {
|
||||||
box-shadow: none; }
|
box-shadow: none; }
|
||||||
#converse-embedded-chat .chatbox .chat-title {
|
#conversejs.converse-embedded .chatbox .chat-title {
|
||||||
padding: 0.3em;
|
padding: 0.3em;
|
||||||
font-size: 120%; }
|
font-size: 120%; }
|
||||||
#converse-embedded-chat .chatbox-btn {
|
#conversejs.converse-embedded .chatbox-btn {
|
||||||
display: none; }
|
display: none; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout {
|
#conversejs.converse-embedded .chatroom .box-flyout {
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 55vh; }
|
height: 55vh; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .chat-body {
|
#conversejs.converse-embedded .chatroom .box-flyout .chat-body {
|
||||||
height: -webkit-calc(100% - 55px);
|
height: -webkit-calc(100% - 55px);
|
||||||
height: calc(100% - 55px); }
|
height: calc(100% - 55px); }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .occupants-heading {
|
#conversejs.converse-embedded .chatroom .box-flyout .occupants-heading {
|
||||||
font-size: 120%; }
|
font-size: 120%; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .chat-content {
|
#conversejs.converse-embedded .chatroom .box-flyout .chat-content {
|
||||||
height: calc(100% - 97px); }
|
height: calc(100% - 97px); }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .chat-content .chat-message {
|
#conversejs.converse-embedded .chatroom .box-flyout .chat-content .chat-message {
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
font-size: 120%; }
|
font-size: 120%; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .sendXMPPMessage .chat-textarea {
|
#conversejs.converse-embedded .chatroom .box-flyout .sendXMPPMessage .chat-textarea {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
font-size: 110%; }
|
font-size: 110%; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .chatroom-body .chatroom-form-container {
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container {
|
||||||
font-size: 180%;
|
font-size: 180%;
|
||||||
float: left;
|
float: left;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative; }
|
position: relative; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .chatroom-body .chatroom-form-container input {
|
#conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input {
|
||||||
font-size: 60%; }
|
font-size: 60%; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .occupants .occupant-list {
|
#conversejs.converse-embedded .chatroom .box-flyout .occupants .occupant-list {
|
||||||
padding-left: 0.3em; }
|
padding-left: 0.3em; }
|
||||||
#converse-embedded-chat .chatroom .box-flyout .occupants .occupant-list li.occupant {
|
#conversejs.converse-embedded .chatroom .box-flyout .occupants .occupant-list li.occupant {
|
||||||
font-size: 120%; }
|
font-size: 120%; }
|
||||||
|
|
||||||
/*# sourceMappingURL=converse-muc-embedded.css.map */
|
/*# sourceMappingURL=converse-muc-embedded.css.map */
|
||||||
|
@ -4758,6 +4758,8 @@
|
|||||||
#converse-embedded-chat,
|
#converse-embedded-chat,
|
||||||
#conversejs {
|
#conversejs {
|
||||||
margin-left: -0.5em;
|
margin-left: -0.5em;
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
padding-right: env(safe-area-inset-right);
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
height: auto;
|
height: auto;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
@ -5250,6 +5252,9 @@
|
|||||||
#conversejs .chatbox {
|
#conversejs .chatbox {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 100%; } }
|
width: 100%; } }
|
||||||
|
#converse-embedded-chat .chatbox .spoiler,
|
||||||
|
#conversejs .chatbox .spoiler {
|
||||||
|
background-color: #e7f7ee; }
|
||||||
#converse-embedded-chat .chatbox .box-flyout,
|
#converse-embedded-chat .chatbox .box-flyout,
|
||||||
#conversejs .chatbox .box-flyout {
|
#conversejs .chatbox .box-flyout {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -5328,6 +5333,8 @@
|
|||||||
margin-top: 1em; }
|
margin-top: 1em; }
|
||||||
#converse-embedded-chat .chatbox .chat-body .chat-image,
|
#converse-embedded-chat .chatbox .chat-body .chat-image,
|
||||||
#conversejs .chatbox .chat-body .chat-image {
|
#conversejs .chatbox .chat-body .chat-image {
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
max-height: 24em;
|
max-height: 24em;
|
||||||
max-width: 100%; }
|
max-width: 100%; }
|
||||||
#converse-embedded-chat .chatbox .chat-body .chat-action,
|
#converse-embedded-chat .chatbox .chat-body .chat-action,
|
||||||
@ -5358,6 +5365,10 @@
|
|||||||
#conversejs .chatbox .chat-body .chat-message .chat-msg-content {
|
#conversejs .chatbox .chat-body .chat-message .chat-msg-content {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
word-wrap: break-word; }
|
word-wrap: break-word; }
|
||||||
|
#converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content.spoiler,
|
||||||
|
#conversejs .chatbox .chat-body .chat-message .chat-msg-content.spoiler {
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.5em; }
|
||||||
#converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content .emojione,
|
#converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content .emojione,
|
||||||
#conversejs .chatbox .chat-body .chat-message .chat-msg-content .emojione {
|
#conversejs .chatbox .chat-body .chat-message .chat-msg-content .emojione {
|
||||||
margin-bottom: -6px; }
|
margin-bottom: -6px; }
|
||||||
@ -5391,6 +5402,10 @@
|
|||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
height: 206px;
|
height: 206px;
|
||||||
height: calc(100% - 96px); }
|
height: calc(100% - 96px); }
|
||||||
|
#converse-embedded-chat .chatbox .chat-content .toggle-spoiler:before,
|
||||||
|
#conversejs .chatbox .chat-content .toggle-spoiler:before {
|
||||||
|
padding-right: 0.25em;
|
||||||
|
whitespace: nowrap; }
|
||||||
#converse-embedded-chat .chatbox .chat-content-sendbutton,
|
#converse-embedded-chat .chatbox .chat-content-sendbutton,
|
||||||
#conversejs .chatbox .chat-content-sendbutton {
|
#conversejs .chatbox .chat-content-sendbutton {
|
||||||
height: calc(100% - 128px); }
|
height: calc(100% - 128px); }
|
||||||
@ -5424,6 +5439,9 @@
|
|||||||
#converse-embedded-chat .chatbox .sendXMPPMessage,
|
#converse-embedded-chat .chatbox .sendXMPPMessage,
|
||||||
#conversejs .chatbox .sendXMPPMessage {
|
#conversejs .chatbox .sendXMPPMessage {
|
||||||
width: 100%; } }
|
width: 100%; } }
|
||||||
|
#converse-embedded-chat .chatbox .sendXMPPMessage .spoiler-hint,
|
||||||
|
#conversejs .chatbox .sendXMPPMessage .spoiler-hint {
|
||||||
|
width: 100%; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-textarea,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-textarea,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-textarea {
|
#conversejs .chatbox .sendXMPPMessage .chat-textarea {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
@ -5435,6 +5453,9 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
resize: none; }
|
resize: none; }
|
||||||
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-textarea.spoiler,
|
||||||
|
#conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler {
|
||||||
|
height: 42px; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .send-button,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .send-button,
|
||||||
#conversejs .chatbox .sendXMPPMessage .send-button {
|
#conversejs .chatbox .sendXMPPMessage .send-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -5450,20 +5471,17 @@
|
|||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar {
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px;
|
padding: 0.25em;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
display: block;
|
display: block;
|
||||||
background-color: #E7FBF0; }
|
background-color: #50c282;
|
||||||
|
color: white; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar a,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar a,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar a {
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar a {
|
||||||
font-size: 14px;
|
color: white;
|
||||||
color: #777;
|
font-size: 16px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: none; }
|
text-shadow: none; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .chat-toolbar-text,
|
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar .chat-toolbar-text {
|
|
||||||
font-size: 12px;
|
|
||||||
padding-right: 3px; }
|
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
||||||
@ -5554,10 +5572,7 @@
|
|||||||
color: #8f2831; }
|
color: #8f2831; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu {
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu {
|
||||||
color: #777; }
|
color: white; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley,
|
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley {
|
|
||||||
padding-left: 5px; }
|
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
||||||
@ -5964,7 +5979,8 @@
|
|||||||
padding: 1px;
|
padding: 1px;
|
||||||
float: right; }
|
float: right; }
|
||||||
#conversejs #controlbox .controlbox-panes {
|
#conversejs #controlbox .controlbox-panes {
|
||||||
overflow-y: scroll; }
|
height: 100%;
|
||||||
|
overflow-y: auto; }
|
||||||
#conversejs #controlbox .controlbox-pane {
|
#conversejs #controlbox .controlbox-pane {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -6472,7 +6488,7 @@
|
|||||||
background-color: #E77051; }
|
background-color: #E77051; }
|
||||||
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-toolbar,
|
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-toolbar,
|
||||||
#conversejs .chatroom .sendXMPPMessage .chat-toolbar {
|
#conversejs .chatroom .sendXMPPMessage .chat-toolbar {
|
||||||
background-color: #FFECE7; }
|
background-color: #ed957e; }
|
||||||
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-textarea,
|
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-textarea,
|
||||||
#conversejs .chatroom .sendXMPPMessage .chat-textarea {
|
#conversejs .chatroom .sendXMPPMessage .chat-textarea {
|
||||||
border-bottom-right-radius: 0; }
|
border-bottom-right-radius: 0; }
|
||||||
|
292
css/fonts.css
Normal file
292
css/fonts.css
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
/*
|
||||||
|
Color scheme helpers:
|
||||||
|
https://coolors.co/app/264653-2a9d8f-e9c46a-f4a261-e76f51
|
||||||
|
http://paletton.com/#uid=70a0u0kkNs+b4JOgryLpxqpsbkI
|
||||||
|
*/
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Converse-js';
|
||||||
|
src: url("../fonticons/fonts/icomoon.eot?wvi0ht");
|
||||||
|
src: url("../fonticons/fonts/icomoon.eot?wvi0ht#iefix") format("embedded-opentype"), url("../fonticons/fonts/icomoon.ttf?wvi0ht") format("truetype"), url("../fonticons/fonts/icomoon.woff?wvi0ht") format("woff"), url("../fonticons/fonts/icomoon.svg?wvi0ht#icomoon") format("svg");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal; }
|
||||||
|
.icon-conversejs {
|
||||||
|
padding-right: 0.2em;
|
||||||
|
font-family: 'Converse-js';
|
||||||
|
speak: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 1;
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale; }
|
||||||
|
|
||||||
|
.icon-conversejs:before {
|
||||||
|
content: "\e600"; }
|
||||||
|
|
||||||
|
#converse-embedded-chat .icon-address-book:before,
|
||||||
|
#conversejs .icon-address-book:before {
|
||||||
|
content: "\270f"; }
|
||||||
|
#converse-embedded-chat .icon-attachment:before,
|
||||||
|
#conversejs .icon-attachment:before {
|
||||||
|
content: "\e032"; }
|
||||||
|
#converse-embedded-chat .icon-away:before,
|
||||||
|
#conversejs .icon-away:before {
|
||||||
|
content: "\25fb"; }
|
||||||
|
#converse-embedded-chat .icon-blocked:before,
|
||||||
|
#conversejs .icon-blocked:before {
|
||||||
|
content: "\2718"; }
|
||||||
|
#converse-embedded-chat .icon-bold:before,
|
||||||
|
#conversejs .icon-bold:before {
|
||||||
|
content: "\e04d"; }
|
||||||
|
#converse-embedded-chat .icon-bubbles2:before,
|
||||||
|
#conversejs .icon-bubbles2:before {
|
||||||
|
content: "\e016"; }
|
||||||
|
#converse-embedded-chat .icon-bubbles3:before,
|
||||||
|
#conversejs .icon-bubbles3:before {
|
||||||
|
content: "\e017"; }
|
||||||
|
#converse-embedded-chat .icon-bubbles:before,
|
||||||
|
#conversejs .icon-bubbles:before {
|
||||||
|
content: "\e015"; }
|
||||||
|
#converse-embedded-chat .icon-busy:before,
|
||||||
|
#conversejs .icon-busy:before {
|
||||||
|
content: "\e004"; }
|
||||||
|
#converse-embedded-chat .icon-dnd:before,
|
||||||
|
#conversejs .icon-dnd:before {
|
||||||
|
content: "\e004"; }
|
||||||
|
#converse-embedded-chat .icon-cancel-circle:before,
|
||||||
|
#conversejs .icon-cancel-circle:before {
|
||||||
|
content: "\e058"; }
|
||||||
|
#converse-embedded-chat .icon-checkmark:before,
|
||||||
|
#conversejs .icon-checkmark:before {
|
||||||
|
content: "\2713"; }
|
||||||
|
#converse-embedded-chat .icon-close:before,
|
||||||
|
#conversejs .icon-close:before {
|
||||||
|
content: "\2715"; }
|
||||||
|
#converse-embedded-chat .icon-closed:before,
|
||||||
|
#conversejs .icon-closed:before {
|
||||||
|
content: "\25ba"; }
|
||||||
|
#converse-embedded-chat .icon-cog:before,
|
||||||
|
#conversejs .icon-cog:before {
|
||||||
|
content: "\e02f"; }
|
||||||
|
#converse-embedded-chat .icon-cogs:before,
|
||||||
|
#conversejs .icon-cogs:before {
|
||||||
|
content: "\e022"; }
|
||||||
|
#converse-embedded-chat .icon-conversejs:before,
|
||||||
|
#conversejs .icon-conversejs:before {
|
||||||
|
content: "\e600"; }
|
||||||
|
#converse-embedded-chat .icon-database:before,
|
||||||
|
#conversejs .icon-database:before {
|
||||||
|
content: "\f1c0"; }
|
||||||
|
#converse-embedded-chat .icon-envelope:before,
|
||||||
|
#conversejs .icon-envelope:before {
|
||||||
|
content: "\f003"; }
|
||||||
|
#converse-embedded-chat .icon-exit:before,
|
||||||
|
#conversejs .icon-exit:before {
|
||||||
|
content: "\e601"; }
|
||||||
|
#converse-embedded-chat .icon-eye-blocked:before,
|
||||||
|
#conversejs .icon-eye-blocked:before {
|
||||||
|
content: "\e031"; }
|
||||||
|
#converse-embedded-chat .icon-eye:before,
|
||||||
|
#conversejs .icon-eye:before {
|
||||||
|
content: "\e030"; }
|
||||||
|
#converse-embedded-chat .icon-github:before,
|
||||||
|
#conversejs .icon-github:before {
|
||||||
|
content: "\eab0"; }
|
||||||
|
#converse-embedded-chat .icon-globe:before,
|
||||||
|
#conversejs .icon-globe:before {
|
||||||
|
content: "\f0ac"; }
|
||||||
|
#converse-embedded-chat .icon-google2:before,
|
||||||
|
#conversejs .icon-google2:before {
|
||||||
|
content: "\ea89"; }
|
||||||
|
#converse-embedded-chat .icon-group:before,
|
||||||
|
#conversejs .icon-group:before {
|
||||||
|
content: "\f0c0"; }
|
||||||
|
#converse-embedded-chat .icon-happy:before,
|
||||||
|
#conversejs .icon-happy:before {
|
||||||
|
content: "\263b"; }
|
||||||
|
#converse-embedded-chat .icon-heart2:before,
|
||||||
|
#conversejs .icon-heart2:before {
|
||||||
|
content: "\f004"; }
|
||||||
|
#converse-embedded-chat .icon-heart:before,
|
||||||
|
#conversejs .icon-heart:before {
|
||||||
|
content: "\2764"; }
|
||||||
|
#converse-embedded-chat .icon-heart_empty:before,
|
||||||
|
#conversejs .icon-heart_empty:before {
|
||||||
|
content: "\f08a"; }
|
||||||
|
#converse-embedded-chat .icon-hide-users:before,
|
||||||
|
#conversejs .icon-hide-users:before {
|
||||||
|
content: "\e01c"; }
|
||||||
|
#converse-embedded-chat .icon-home:before,
|
||||||
|
#conversejs .icon-home:before {
|
||||||
|
content: "\e000"; }
|
||||||
|
#converse-embedded-chat .icon-idcard-dark:before,
|
||||||
|
#conversejs .icon-idcard-dark:before {
|
||||||
|
content: "\f2c2"; }
|
||||||
|
#converse-embedded-chat .icon-idcard:before,
|
||||||
|
#conversejs .icon-idcard:before {
|
||||||
|
content: "\f2c3"; }
|
||||||
|
#converse-embedded-chat .icon-image:before,
|
||||||
|
#conversejs .icon-image:before {
|
||||||
|
content: "\2b14"; }
|
||||||
|
#converse-embedded-chat .icon-info:before,
|
||||||
|
#conversejs .icon-info:before {
|
||||||
|
content: "\2360"; }
|
||||||
|
#converse-embedded-chat .icon-italic:before,
|
||||||
|
#conversejs .icon-italic:before {
|
||||||
|
content: "\e04f"; }
|
||||||
|
#converse-embedded-chat .icon-key:before,
|
||||||
|
#conversejs .icon-key:before {
|
||||||
|
content: "\e028"; }
|
||||||
|
#converse-embedded-chat .icon-legal:before,
|
||||||
|
#conversejs .icon-legal:before {
|
||||||
|
content: "\f0e3"; }
|
||||||
|
#converse-embedded-chat .icon-lock-2:before,
|
||||||
|
#conversejs .icon-lock-2:before {
|
||||||
|
content: "\e027"; }
|
||||||
|
#converse-embedded-chat .icon-minus:before,
|
||||||
|
#conversejs .icon-minus:before {
|
||||||
|
content: "\e05a"; }
|
||||||
|
#converse-embedded-chat .icon-music:before,
|
||||||
|
#conversejs .icon-music:before {
|
||||||
|
content: "\266b"; }
|
||||||
|
#converse-embedded-chat .icon-newtab:before,
|
||||||
|
#conversejs .icon-newtab:before {
|
||||||
|
content: "\e053"; }
|
||||||
|
#converse-embedded-chat .icon-notebook:before,
|
||||||
|
#conversejs .icon-notebook:before {
|
||||||
|
content: "\2710"; }
|
||||||
|
#converse-embedded-chat .icon-notification:before,
|
||||||
|
#conversejs .icon-notification:before {
|
||||||
|
content: "\e01f"; }
|
||||||
|
#converse-embedded-chat .icon-offline:before,
|
||||||
|
#conversejs .icon-offline:before {
|
||||||
|
content: "\e002"; }
|
||||||
|
#converse-embedded-chat .icon-logout:before,
|
||||||
|
#conversejs .icon-logout:before {
|
||||||
|
content: "\e002"; }
|
||||||
|
#converse-embedded-chat .icon-online:before,
|
||||||
|
#conversejs .icon-online:before {
|
||||||
|
content: "\25fc"; }
|
||||||
|
#converse-embedded-chat .icon-opened:before,
|
||||||
|
#conversejs .icon-opened:before {
|
||||||
|
content: "\25bc"; }
|
||||||
|
#converse-embedded-chat .icon-pencil:before,
|
||||||
|
#conversejs .icon-pencil:before {
|
||||||
|
content: "\270e"; }
|
||||||
|
#converse-embedded-chat .icon-phone-hang-up:before,
|
||||||
|
#conversejs .icon-phone-hang-up:before {
|
||||||
|
content: "\260e"; }
|
||||||
|
#converse-embedded-chat .icon-phone:before,
|
||||||
|
#conversejs .icon-phone:before {
|
||||||
|
content: "\260f"; }
|
||||||
|
#converse-embedded-chat .icon-plus:before,
|
||||||
|
#conversejs .icon-plus:before {
|
||||||
|
content: "\271a"; }
|
||||||
|
#converse-embedded-chat .icon-pushpin:before,
|
||||||
|
#conversejs .icon-pushpin:before {
|
||||||
|
content: "\e012"; }
|
||||||
|
#converse-embedded-chat .icon-quotes-left:before,
|
||||||
|
#conversejs .icon-quotes-left:before {
|
||||||
|
content: "\e01d"; }
|
||||||
|
#converse-embedded-chat .icon-reddit:before,
|
||||||
|
#conversejs .icon-reddit:before {
|
||||||
|
content: "\eac6"; }
|
||||||
|
#converse-embedded-chat .icon-remove:before,
|
||||||
|
#conversejs .icon-remove:before {
|
||||||
|
content: "\e02d"; }
|
||||||
|
#converse-embedded-chat .icon-room-info:before,
|
||||||
|
#conversejs .icon-room-info:before {
|
||||||
|
content: "\e059"; }
|
||||||
|
#converse-embedded-chat .icon-save:before,
|
||||||
|
#conversejs .icon-save:before {
|
||||||
|
content: "\f0c7"; }
|
||||||
|
#converse-embedded-chat .icon-search:before,
|
||||||
|
#conversejs .icon-search:before {
|
||||||
|
content: "\e021"; }
|
||||||
|
#converse-embedded-chat .icon-show-users:before,
|
||||||
|
#conversejs .icon-show-users:before {
|
||||||
|
content: "\e01e"; }
|
||||||
|
#converse-embedded-chat .icon-smiley:before,
|
||||||
|
#conversejs .icon-smiley:before {
|
||||||
|
content: "\263a"; }
|
||||||
|
#converse-embedded-chat .icon-snowflake:before,
|
||||||
|
#conversejs .icon-snowflake:before {
|
||||||
|
content: "\f2dc"; }
|
||||||
|
#converse-embedded-chat .icon-spell-check:before,
|
||||||
|
#conversejs .icon-spell-check:before {
|
||||||
|
content: "\e045"; }
|
||||||
|
#converse-embedded-chat .icon-spinner:before,
|
||||||
|
#conversejs .icon-spinner:before {
|
||||||
|
content: "\231b"; }
|
||||||
|
#converse-embedded-chat .icon-star:before,
|
||||||
|
#conversejs .icon-star:before {
|
||||||
|
content: "\f005"; }
|
||||||
|
#converse-embedded-chat .icon-star_empty:before,
|
||||||
|
#conversejs .icon-star_empty:before {
|
||||||
|
content: "\f006"; }
|
||||||
|
#converse-embedded-chat .icon-strikethrough:before,
|
||||||
|
#conversejs .icon-strikethrough:before {
|
||||||
|
content: "\e050"; }
|
||||||
|
#converse-embedded-chat .icon-twitter:before,
|
||||||
|
#conversejs .icon-twitter:before {
|
||||||
|
content: "\ea96"; }
|
||||||
|
#converse-embedded-chat .icon-underline:before,
|
||||||
|
#conversejs .icon-underline:before {
|
||||||
|
content: "\e04e"; }
|
||||||
|
#converse-embedded-chat .icon-unlocked:before,
|
||||||
|
#conversejs .icon-unlocked:before {
|
||||||
|
content: "\e025"; }
|
||||||
|
#converse-embedded-chat .icon-user:before,
|
||||||
|
#conversejs .icon-user:before {
|
||||||
|
content: "\e01a"; }
|
||||||
|
#converse-embedded-chat .icon-users:before,
|
||||||
|
#conversejs .icon-users:before {
|
||||||
|
content: "\e01b"; }
|
||||||
|
#converse-embedded-chat .icon-warning:before,
|
||||||
|
#conversejs .icon-warning:before {
|
||||||
|
content: "\26a0"; }
|
||||||
|
#converse-embedded-chat .icon-wrench:before,
|
||||||
|
#conversejs .icon-wrench:before {
|
||||||
|
content: "\e024"; }
|
||||||
|
#converse-embedded-chat .icon-xa:before,
|
||||||
|
#conversejs .icon-xa:before {
|
||||||
|
content: "\e602"; }
|
||||||
|
#converse-embedded-chat .icon-zoomin:before,
|
||||||
|
#conversejs .icon-zoomin:before {
|
||||||
|
content: "\e02b"; }
|
||||||
|
#converse-embedded-chat .icon-zoomout:before,
|
||||||
|
#conversejs .icon-zoomout:before {
|
||||||
|
content: "\e02a"; }
|
||||||
|
#converse-embedded-chat [data-icon]:before,
|
||||||
|
#conversejs [data-icon]:before {
|
||||||
|
content: attr(data-icon);
|
||||||
|
font-family: 'Converse-js';
|
||||||
|
font-variant: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1;
|
||||||
|
speak: none;
|
||||||
|
text-transform: none;
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale; }
|
||||||
|
#converse-embedded-chat [class^="icon-"]:before, #converse-embedded-chat [class*=" icon-"]:before,
|
||||||
|
#conversejs [class^="icon-"]:before,
|
||||||
|
#conversejs [class*=" icon-"]:before {
|
||||||
|
background-position: 14px 14px;
|
||||||
|
background-image: none;
|
||||||
|
font-family: 'Converse-js';
|
||||||
|
font-style: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
line-height: 1;
|
||||||
|
speak: none;
|
||||||
|
text-transform: none;
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale; }
|
||||||
|
|
||||||
|
/*# sourceMappingURL=fonts.css.map */
|
@ -4758,6 +4758,8 @@
|
|||||||
#converse-embedded-chat,
|
#converse-embedded-chat,
|
||||||
#conversejs {
|
#conversejs {
|
||||||
margin-left: -0.5em;
|
margin-left: -0.5em;
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
padding-right: env(safe-area-inset-right);
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
height: auto;
|
height: auto;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
@ -5306,6 +5308,9 @@ body {
|
|||||||
#conversejs .chatbox {
|
#conversejs .chatbox {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 100%; } }
|
width: 100%; } }
|
||||||
|
#converse-embedded-chat .chatbox .spoiler,
|
||||||
|
#conversejs .chatbox .spoiler {
|
||||||
|
background-color: #e7f7ee; }
|
||||||
#converse-embedded-chat .chatbox .box-flyout,
|
#converse-embedded-chat .chatbox .box-flyout,
|
||||||
#conversejs .chatbox .box-flyout {
|
#conversejs .chatbox .box-flyout {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -5384,6 +5389,8 @@ body {
|
|||||||
margin-top: 1em; }
|
margin-top: 1em; }
|
||||||
#converse-embedded-chat .chatbox .chat-body .chat-image,
|
#converse-embedded-chat .chatbox .chat-body .chat-image,
|
||||||
#conversejs .chatbox .chat-body .chat-image {
|
#conversejs .chatbox .chat-body .chat-image {
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
max-height: 24em;
|
max-height: 24em;
|
||||||
max-width: 100%; }
|
max-width: 100%; }
|
||||||
#converse-embedded-chat .chatbox .chat-body .chat-action,
|
#converse-embedded-chat .chatbox .chat-body .chat-action,
|
||||||
@ -5414,6 +5421,10 @@ body {
|
|||||||
#conversejs .chatbox .chat-body .chat-message .chat-msg-content {
|
#conversejs .chatbox .chat-body .chat-message .chat-msg-content {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
word-wrap: break-word; }
|
word-wrap: break-word; }
|
||||||
|
#converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content.spoiler,
|
||||||
|
#conversejs .chatbox .chat-body .chat-message .chat-msg-content.spoiler {
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.5em; }
|
||||||
#converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content .emojione,
|
#converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content .emojione,
|
||||||
#conversejs .chatbox .chat-body .chat-message .chat-msg-content .emojione {
|
#conversejs .chatbox .chat-body .chat-message .chat-msg-content .emojione {
|
||||||
margin-bottom: -6px; }
|
margin-bottom: -6px; }
|
||||||
@ -5447,6 +5458,10 @@ body {
|
|||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
height: 206px;
|
height: 206px;
|
||||||
height: calc(100% - 100px); }
|
height: calc(100% - 100px); }
|
||||||
|
#converse-embedded-chat .chatbox .chat-content .toggle-spoiler:before,
|
||||||
|
#conversejs .chatbox .chat-content .toggle-spoiler:before {
|
||||||
|
padding-right: 0.25em;
|
||||||
|
whitespace: nowrap; }
|
||||||
#converse-embedded-chat .chatbox .chat-content-sendbutton,
|
#converse-embedded-chat .chatbox .chat-content-sendbutton,
|
||||||
#conversejs .chatbox .chat-content-sendbutton {
|
#conversejs .chatbox .chat-content-sendbutton {
|
||||||
height: calc(100% - 132px); }
|
height: calc(100% - 132px); }
|
||||||
@ -5480,6 +5495,9 @@ body {
|
|||||||
#converse-embedded-chat .chatbox .sendXMPPMessage,
|
#converse-embedded-chat .chatbox .sendXMPPMessage,
|
||||||
#conversejs .chatbox .sendXMPPMessage {
|
#conversejs .chatbox .sendXMPPMessage {
|
||||||
width: 100%; } }
|
width: 100%; } }
|
||||||
|
#converse-embedded-chat .chatbox .sendXMPPMessage .spoiler-hint,
|
||||||
|
#conversejs .chatbox .sendXMPPMessage .spoiler-hint {
|
||||||
|
width: 100%; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-textarea,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-textarea,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-textarea {
|
#conversejs .chatbox .sendXMPPMessage .chat-textarea {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
@ -5491,6 +5509,9 @@ body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
resize: none; }
|
resize: none; }
|
||||||
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-textarea.spoiler,
|
||||||
|
#conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler {
|
||||||
|
height: 42px; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .send-button,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .send-button,
|
||||||
#conversejs .chatbox .sendXMPPMessage .send-button {
|
#conversejs .chatbox .sendXMPPMessage .send-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -5506,20 +5527,17 @@ body {
|
|||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar {
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px;
|
padding: 0.25em;
|
||||||
height: 29px;
|
height: 29px;
|
||||||
display: block;
|
display: block;
|
||||||
background-color: #E7FBF0; }
|
background-color: #50c282;
|
||||||
|
color: white; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar a,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar a,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar a {
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar a {
|
||||||
font-size: 16px;
|
color: white;
|
||||||
color: #777;
|
font-size: 18px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: none; }
|
text-shadow: none; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .chat-toolbar-text,
|
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar .chat-toolbar-text {
|
|
||||||
font-size: 12px;
|
|
||||||
padding-right: 3px; }
|
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar .unencrypted,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
|
||||||
@ -5610,10 +5628,7 @@ body {
|
|||||||
color: #8f2831; }
|
color: #8f2831; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu {
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-toolbar-menu {
|
||||||
color: #777; }
|
color: white; }
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley,
|
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley {
|
|
||||||
padding-left: 5px; }
|
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
||||||
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover,
|
#converse-embedded-chat .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover,
|
||||||
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
|
||||||
@ -6036,7 +6051,8 @@ body {
|
|||||||
padding: 1px;
|
padding: 1px;
|
||||||
float: right; }
|
float: right; }
|
||||||
#conversejs #controlbox .controlbox-panes {
|
#conversejs #controlbox .controlbox-panes {
|
||||||
overflow-y: scroll; }
|
height: 100%;
|
||||||
|
overflow-y: auto; }
|
||||||
#conversejs #controlbox .controlbox-pane {
|
#conversejs #controlbox .controlbox-pane {
|
||||||
padding: 1.2em;
|
padding: 1.2em;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -6602,7 +6618,7 @@ body {
|
|||||||
background-color: #E77051; }
|
background-color: #E77051; }
|
||||||
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-toolbar,
|
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-toolbar,
|
||||||
#conversejs .chatroom .sendXMPPMessage .chat-toolbar {
|
#conversejs .chatroom .sendXMPPMessage .chat-toolbar {
|
||||||
background-color: #FFECE7; }
|
background-color: #ed957e; }
|
||||||
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-textarea,
|
#converse-embedded-chat .chatroom .sendXMPPMessage .chat-textarea,
|
||||||
#conversejs .chatroom .sendXMPPMessage .chat-textarea {
|
#conversejs .chatroom .sendXMPPMessage .chat-textarea {
|
||||||
border-bottom-right-radius: 0; }
|
border-bottom-right-radius: 0; }
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#conversejs {
|
#conversejs {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
padding-right: env(safe-area-inset-right);
|
||||||
}
|
}
|
||||||
.converse-chatroom {
|
.converse-chatroom {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -285,7 +285,7 @@ a:focus {
|
|||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
}
|
}
|
||||||
.banner-social-buttons {
|
.banner-social-buttons {
|
||||||
padding-top: 7em;
|
padding-top: 5em;
|
||||||
}
|
}
|
||||||
::-moz-selection {
|
::-moz-selection {
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
@ -357,6 +357,13 @@ ul.features {
|
|||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mastodon {
|
||||||
|
width: 4em;
|
||||||
|
height: 4em;
|
||||||
|
margin-top: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
.sponsors {
|
.sponsors {
|
||||||
clear: both;
|
clear: both;
|
||||||
font-size: 1.4em;
|
font-size: 1.4em;
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<h1 class="brand-heading"><i class="icon-conversejs"></i>Converse.js</h1>
|
<h1 class="brand-heading"><i class="icon-conversejs"></i>Converse</h1>
|
||||||
<p class="intro-text">Anonymous login demo</p>
|
<p class="intro-text">Anonymous login demo</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,19 +5,19 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="description" content="Converse.js: A free chat client for your website" />
|
<meta name="description" content="Converse.js: An XMPP chat client which can be integrated into any website" />
|
||||||
<meta name="author" content="JC Brand" />
|
<meta name="author" content="JC Brand" />
|
||||||
<meta name="keywords" content="xmpp chat webchat converse.js" />
|
<meta name="keywords" content="xmpp chat webchat converse.js" />
|
||||||
<link rel="shortcut icon" type="image/ico" href="../css/images/favicon.ico"/>
|
<link rel="shortcut icon" type="image/ico" href="../css/images/favicon.ico"/>
|
||||||
<link type="text/css" rel="stylesheet" media="screen" href="../node_modules/bootstrap/dist/css/bootstrap.min.css" />
|
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/node_modules/bootstrap/dist/css/bootstrap.min.css" />
|
||||||
<link type="text/css" rel="stylesheet" media="screen" href="../node_modules/font-awesome/css/font-awesome.min.css" />
|
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/node_modules/font-awesome/css/font-awesome.min.css" />
|
||||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/theme.min.css" />
|
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/theme.min.css" />
|
||||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse.min.css" />
|
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse.min.css" />
|
||||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse-muc-embedded.min.css" />
|
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse-muc-embedded.min.css" />
|
||||||
<script type="text/javascript" src="../analytics.js"></script>
|
<script type="text/javascript" src="https://cdn.conversejs.org/analytics.js"></script>
|
||||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||||
<![if gte IE 9]>
|
<![if gte IE 11]>
|
||||||
<script src="../dist/converse-muc-embedded.min.js"></script>
|
<script src="https://cdn.conversejs.org/dist/converse.min.js"></script>
|
||||||
<![endif]>
|
<![endif]>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -41,10 +41,10 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<h1 class="brand-heading brand-heading-embedded"><a style="color: white;" href="/"><i class="icon-conversejs"></i>Converse.js</a></h1>
|
<h1 class="brand-heading brand-heading-embedded"><a style="color: white;" href="/"><i class="icon-conversejs"></i>Converse</a></h1>
|
||||||
<p class="intro-text">Embedded MUC chat demo</p>
|
<p class="intro-text">Embedded MUC chat demo</p>
|
||||||
|
|
||||||
<div id="converse-embedded-chat"></div>
|
<div id="conversejs"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -54,44 +54,19 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
converse.initialize({
|
converse.initialize({
|
||||||
allow_logout: false, // No point in logging out when we have auto_login as true.
|
|
||||||
allow_muc_invitations: false, // Doesn't make sense to allow because only
|
|
||||||
// roster contacts can be invited
|
|
||||||
allow_contact_requests: false, // Contacts from other servers cannot,
|
|
||||||
// be added and anonymous users don't
|
|
||||||
// know one another's JIDs, so disabling.
|
|
||||||
auto_reconnect: true,
|
|
||||||
authentication: 'anonymous',
|
authentication: 'anonymous',
|
||||||
auto_login: true,
|
auto_login: true,
|
||||||
auto_join_rooms: [
|
auto_join_rooms: [
|
||||||
'anonymous@conference.nomnom.im',
|
'anonymous@conference.nomnom.im',
|
||||||
],
|
],
|
||||||
// Whitelist non-core plugins that we need
|
|
||||||
whitelisted_plugins: ['converse-muc-embedded'],
|
|
||||||
// Blacklist plugins which aren't included in the build file,
|
|
||||||
// so that other code cannot register their own plugins under
|
|
||||||
// those names.
|
|
||||||
blacklisted_plugins: [
|
|
||||||
"converse-bookmarks",
|
|
||||||
"converse-controlbox",
|
|
||||||
"converse-dragresize",
|
|
||||||
"converse-headline",
|
|
||||||
"converse-minimize",
|
|
||||||
"converse-otr",
|
|
||||||
"converse-register",
|
|
||||||
"converse-vcard",
|
|
||||||
],
|
|
||||||
notify_all_room_messages: [
|
|
||||||
'anonymous@conference.nomnom.im',
|
|
||||||
],
|
|
||||||
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||||
jid: 'nomnom.im', // XMPP server which allows anonymous login (doesn't
|
jid: 'nomnom.im', // XMPP server which allows anonymous login (doesn't
|
||||||
// allow chatting with other XMPP servers).
|
// allow chatting with other XMPP servers).
|
||||||
keepalive: true,
|
notify_all_room_messages: [
|
||||||
hide_muc_server: true, // Federation is disabled, so no use in
|
'anonymous@conference.nomnom.im',
|
||||||
// showing the MUC server.
|
],
|
||||||
play_sounds: true,
|
locales_url: "../locale/{{{locale}}}/LC_MESSAGES/converse.json",
|
||||||
strict_plugin_dependencies: false
|
view_mode: 'embedded',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
<section class="intro" class="container">
|
<section class="intro" class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1 class="brand-heading"><i class="icon-conversejs"></i> Converse.js</h1>
|
<h1 class="brand-heading"><i class="icon-conversejs"></i> Converse</h1>
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<p class="intro-text">Demos:</p>
|
<p class="intro-text">Demos:</p>
|
||||||
<p class="intro-text">
|
<p class="intro-text">
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<h1 class="brand-heading"><i class="icon-conversejs"></i>Converse.js</h1>
|
<h1 class="brand-heading"><i class="icon-conversejs"></i>Converse</h1>
|
||||||
<p class="intro-text">An example page where external dependencies are loaded seperately and not within the converse.js bundle.</p>
|
<p class="intro-text">An example page where external dependencies are loaded seperately and not within the converse.js bundle.</p>
|
||||||
<p class="intro-text">Look at the page source for details.</p>
|
<p class="intro-text">Look at the page source for details.</p>
|
||||||
<p class="intro-text">For this page to work, you'll need to
|
<p class="intro-text">For this page to work, you'll need to
|
||||||
|
4
dev.html
4
dev.html
@ -65,8 +65,8 @@
|
|||||||
'discuss@conference.conversejs.org'
|
'discuss@conference.conversejs.org'
|
||||||
],
|
],
|
||||||
auto_reconnect: true,
|
auto_reconnect: true,
|
||||||
bosh_service_url: 'http://chat.example.org:5280/http-bind/',
|
// bosh_service_url: 'http://chat.example.org:5280/http-bind/',
|
||||||
// bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||||
message_archiving: 'always',
|
message_archiving: 'always',
|
||||||
show_controlbox_by_default: true,
|
show_controlbox_by_default: true,
|
||||||
strict_plugin_dependencies: false,
|
strict_plugin_dependencies: false,
|
||||||
|
53378
dist/converse-muc-embedded.js
vendored
Normal file
53378
dist/converse-muc-embedded.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1554
dist/converse-no-dependencies.js
vendored
1554
dist/converse-no-dependencies.js
vendored
File diff suppressed because it is too large
Load Diff
4205
dist/converse.js
vendored
4205
dist/converse.js
vendored
File diff suppressed because it is too large
Load Diff
@ -48,9 +48,9 @@ copyright = u'2017, JC Brand'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '3.3.1'
|
version = '3.3.3'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '3.3.1'
|
release = '3.3.3'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
Configuration
|
Configuration
|
||||||
=============
|
=============
|
||||||
|
|
||||||
The included minified JS and CSS files can be used for demoing or testing, but
|
The included minified JavaScript and CSS files can be used for demoing or testing, but
|
||||||
you'll want to configure *Converse.js* to suit your needs before you deploy it
|
you'll want to configure *Converse.js* to suit your needs before you deploy it
|
||||||
on your website.
|
on your website.
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ Please refer to the `Configuration settings`_ section below for info on
|
|||||||
all the available configuration settings.
|
all the available configuration settings.
|
||||||
|
|
||||||
After you have configured *Converse.js*, you'll have to regenerate the minified
|
After you have configured *Converse.js*, you'll have to regenerate the minified
|
||||||
JS file so that it will include the new settings. Please refer to the
|
JavaScript file so that it will include the new settings. Please refer to the
|
||||||
:ref:`minification` section for more info on how to do this.
|
:ref:`minification` section for more info on how to do this.
|
||||||
|
|
||||||
.. _`configuration-settings`:
|
.. _`configuration-settings`:
|
||||||
@ -118,6 +118,8 @@ allow_bookmarks
|
|||||||
Enables/disables chatroom bookmarks functionality.
|
Enables/disables chatroom bookmarks functionality.
|
||||||
This setting is only applicable if the ``converse-bookmarks`` plugin is loaded.
|
This setting is only applicable if the ``converse-bookmarks`` plugin is loaded.
|
||||||
|
|
||||||
|
See also: `allow_public_bookmarks`_
|
||||||
|
|
||||||
allow_chat_pending_contacts
|
allow_chat_pending_contacts
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
@ -131,7 +133,7 @@ allow_contact_removal
|
|||||||
* Default: ``true``
|
* Default: ``true``
|
||||||
|
|
||||||
Allow the user to remove roster contacts by clicking on the delete icon
|
Allow the user to remove roster contacts by clicking on the delete icon
|
||||||
(i.e. traschcan) next to a contact's name in the roster.
|
(i.e. trashcan) next to a contact's name in the roster.
|
||||||
|
|
||||||
allow_contact_requests
|
allow_contact_requests
|
||||||
----------------------
|
----------------------
|
||||||
@ -190,6 +192,24 @@ allow_otr
|
|||||||
|
|
||||||
Allow Off-the-record encryption of single-user chat messages.
|
Allow Off-the-record encryption of single-user chat messages.
|
||||||
|
|
||||||
|
allow_public_bookmarks
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
* Default: ``false``
|
||||||
|
|
||||||
|
Some XMPP servers don't support private PEP/PubSub nodes, as required for
|
||||||
|
private bookmarks and outlined in `XEP-0223 <https://xmpp.org/extensions/xep-0223.html>`_.
|
||||||
|
|
||||||
|
Even though Converse.js asks for the bookmarks to be kept private (via the
|
||||||
|
`<publish-options>` XML node), the server simply ignores the privacy settings
|
||||||
|
and publishes the node contents under the default privacy setting, which makes
|
||||||
|
the information available to all roster contacts.
|
||||||
|
|
||||||
|
If your your XMPP server does not support `XEP-0223`'s ``#publish-options``
|
||||||
|
feature and you don't mind that your room bookmarks are visible to all
|
||||||
|
contacts, then you can set this setting to ``true``. Otherwise you won't be
|
||||||
|
able to have any room bookmarks at all for an account on that XMPP server.
|
||||||
|
|
||||||
allow_registration
|
allow_registration
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@ -1071,6 +1091,35 @@ providers_link
|
|||||||
The hyperlink on the registration form which points to a directory of public
|
The hyperlink on the registration form which points to a directory of public
|
||||||
XMPP servers.
|
XMPP servers.
|
||||||
|
|
||||||
|
root
|
||||||
|
----
|
||||||
|
|
||||||
|
* Default: ``window.document``
|
||||||
|
|
||||||
|
When using converse.js inside a web component's shadow DOM, you will need to set this settings'
|
||||||
|
value to the shadow-root of the shadow DOM.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
class CustomChatComponent extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
const shadowRoot = this.attachShadow({mode: "open"});
|
||||||
|
this.initConverse(shadowRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
initConverse(shadowRoot) {
|
||||||
|
window.addEventListener("converse-loaded", function(event) {
|
||||||
|
converse.initialize({
|
||||||
|
root: shadowRoot,
|
||||||
|
// Other settings go here...
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
roster_groups
|
roster_groups
|
||||||
-------------
|
-------------
|
||||||
@ -1368,20 +1417,21 @@ view_mode
|
|||||||
---------
|
---------
|
||||||
|
|
||||||
* Default: ``overlayed``
|
* Default: ``overlayed``
|
||||||
* Allowed values: ``overlayed``, ``fullscreen``, ``mobile``
|
* Allowed values: ``overlayed``, ``fullscreen``, ``mobile``, ``embedded``
|
||||||
|
|
||||||
The ``view_mode`` setting configures converse.js's mode and resulting behavior.
|
The ``view_mode`` setting configures converse.js's mode and resulting behavior.
|
||||||
|
|
||||||
Before the introduction of this setting (in version 3.3.0), there were there
|
Before the introduction of this setting (in version 3.3.0), there were there
|
||||||
different builds, each for the diffent modes.
|
different builds, each for the different modes.
|
||||||
|
|
||||||
These were:
|
These were:
|
||||||
|
|
||||||
* ``converse.js`` for the ``overlayed`` mode
|
|
||||||
* ``converse-mobile.js`` for the ``mobile`` mode
|
* ``converse-mobile.js`` for the ``mobile`` mode
|
||||||
|
* ``converse-muc-embedded.js`` for embedding a single MUC room into the page.
|
||||||
|
* ``converse.js`` for the ``overlayed`` mode
|
||||||
* ``inverse.js`` for the ``fullscreen`` mode
|
* ``inverse.js`` for the ``fullscreen`` mode
|
||||||
|
|
||||||
Besides having three different builds, certain plugins had to be whitelisted
|
Besides having different builds, certain plugins had to be whitelisted
|
||||||
and blacklisted for the different modes.
|
and blacklisted for the different modes.
|
||||||
|
|
||||||
``converse-singleton`` had to be whitelisted for the ``mobile`` and ``fullscreen``
|
``converse-singleton`` had to be whitelisted for the ``mobile`` and ``fullscreen``
|
||||||
@ -1391,11 +1441,25 @@ modes, additionally ``converse-inverse`` had to be whitelisted for the
|
|||||||
For both those modes the ``converse-minimize`` and ``converse-dragresize``
|
For both those modes the ``converse-minimize`` and ``converse-dragresize``
|
||||||
plugins had to be blacklisted.
|
plugins had to be blacklisted.
|
||||||
|
|
||||||
Since version 3.3.0, the last two builds no longer exist, and instead the
|
When using ``converse-muc-embedded.js`` various plugins also had to manually be
|
||||||
standard ``converse.js`` build is used, together with the appropraite
|
blacklisted.
|
||||||
``view_mode`` value.
|
|
||||||
|
|
||||||
Furthermore, it's no longer necessary to whitelist or blacklist any plugins.
|
Since version 3.3.0 it's no longer necessary to blacklist any plugins (except
|
||||||
|
for ``converse-muc-embedded.js``, which is from version 3.3.3).
|
||||||
|
|
||||||
|
Blacklisting now happens automatically.
|
||||||
|
|
||||||
|
Since version 3.3.0, the ``inverse.js`` and ``converse-mobile.js`` builds no
|
||||||
|
longer exist. Instead the standard ``converse.js`` build is used, together with
|
||||||
|
the appropriate ``view_mode`` value.
|
||||||
|
|
||||||
|
The ``converse-muc-embedded.js`` build is still kept, because it's smaller than
|
||||||
|
``converse.js`` due to unused code being removed. It doesn't however contain
|
||||||
|
any new code, so the full ``converse.js`` build could be used instead, as long
|
||||||
|
as ``view_mode`` is set to ``embedded``.
|
||||||
|
|
||||||
|
Furthermore, it's no longer necessary to whitelist or blacklist any plugins
|
||||||
|
when switching view modes.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Although the ``view_mode`` setting has removed the need for different
|
Although the ``view_mode`` setting has removed the need for different
|
||||||
@ -1499,7 +1563,9 @@ xhr_user_search
|
|||||||
There are two ways to add users.
|
There are two ways to add users.
|
||||||
|
|
||||||
* The user inputs a valid JID (Jabber ID), and the user is added as a pending contact.
|
* The user inputs a valid JID (Jabber ID), and the user is added as a pending contact.
|
||||||
* The user inputs some text (for example part of a firstname or lastname), an XHR (Ajax Request) will be made to a remote server, and a list of matches are returned. The user can then choose one of the matches to add as a contact.
|
* The user inputs some text (for example part of a first name or last name),
|
||||||
|
an XHR (Ajax Request) will be made to a remote server, and a list of matches are returned.
|
||||||
|
The user can then choose one of the matches to add as a contact.
|
||||||
|
|
||||||
This setting enables the second mechanism, otherwise by default the first will be used.
|
This setting enables the second mechanism, otherwise by default the first will be used.
|
||||||
|
|
||||||
|
@ -437,6 +437,39 @@ The **disco** grouping
|
|||||||
This grouping collects API functions related to `service discovery
|
This grouping collects API functions related to `service discovery
|
||||||
<https://xmpp.org/extensions/xep-0030.html>`_.
|
<https://xmpp.org/extensions/xep-0030.html>`_.
|
||||||
|
|
||||||
|
getIdentity
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
Paramters:
|
||||||
|
|
||||||
|
* (String) category
|
||||||
|
* (String) type
|
||||||
|
* (String) entity JID
|
||||||
|
|
||||||
|
Get the identity (with the given category and type) for a given disco entity.
|
||||||
|
|
||||||
|
For example, when determining support for PEP (personal eventing protocol), you
|
||||||
|
want to know whether the user's own JID has an identity with
|
||||||
|
``category='pubsub'`` and ``type='pep'`` as explained in this section of
|
||||||
|
XEP-0163: https://xmpp.org/extensions/xep-0163.html#support
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
converse.plugins.add('myplugin', {
|
||||||
|
initialize: function () {
|
||||||
|
|
||||||
|
_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid).then(
|
||||||
|
function (identity) {
|
||||||
|
if (_.isNil(identity)) {
|
||||||
|
// The entity DOES NOT have this identity
|
||||||
|
} else {
|
||||||
|
// The entity DOES have this identity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
supports
|
supports
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
@ -450,7 +483,7 @@ Returns a `Promise` which, when resolved, returns a map/object with keys
|
|||||||
converse.plugins.add('myplugin', {
|
converse.plugins.add('myplugin', {
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
|
|
||||||
_converse.api.disco.supports(_converse.bare_jid, Strophe.NS.MAM).then(
|
_converse.api.disco.supports(Strophe.NS.MAM, _converse.bare_jid).then(
|
||||||
function (value) {
|
function (value) {
|
||||||
// `value` is a map with two keys, `supported` and `feature`.
|
// `value` is a map with two keys, `supported` and `feature`.
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ If you only need one, or a subset of the available languages, it's better to
|
|||||||
make a custom build which includes only those languages that you need.
|
make a custom build which includes only those languages that you need.
|
||||||
|
|
||||||
Moderating chatrooms
|
Moderating chatrooms
|
||||||
=====================
|
====================
|
||||||
|
|
||||||
Here are the different commands that may be used to moderate a chatroom:
|
Here are the different commands that may be used to moderate a chatroom:
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ The latest versions of these files are available at these URLs:
|
|||||||
|
|
||||||
To load a specific version of Converse.js you can put the version in the URL, like so:
|
To load a specific version of Converse.js you can put the version in the URL, like so:
|
||||||
|
|
||||||
* https://cdn.conversejs.org/3.0.3/dist/converse.min.js
|
* https://cdn.conversejs.org/3.3.3/dist/converse.min.js
|
||||||
* https://cdn.conversejs.org/3.0.3/css/converse.min.css
|
* https://cdn.conversejs.org/3.3.3/css/converse.min.css
|
||||||
|
|
||||||
You can include these two URLs inside the *<head>* element of your website
|
You can include these two URLs inside the *<head>* element of your website
|
||||||
via the *script* and *link* tags:
|
via the *script* and *link* tags:
|
||||||
|
28
index.html
28
index.html
@ -16,8 +16,8 @@
|
|||||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||||
<script src="src/website.js"></script>
|
<script src="src/website.js"></script>
|
||||||
<![if gte IE 11]>
|
<![if gte IE 11]>
|
||||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/3.3.1/css/converse.min.css" />
|
<link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
|
||||||
<script src="https://cdn.conversejs.org/3.3.1/dist/converse.min.js"></script>
|
<script src="dist/converse.js"></script>
|
||||||
<![endif]>
|
<![endif]>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -85,10 +85,9 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2 banner-social-buttons">
|
<div class="col-md-8 col-md-offset-2 banner-social-buttons">
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
<li><a href="https://twitter.com/jcopkode" class="btn btn-circle btn-lg" title="Twitter" target="_blank" rel="noopener"><i class="fa fa-twitter"></i></a>
|
<li><a href="https://twitter.com/jcopkode" class="btn btn-circle btn-lg" title="Twitter" target="_blank" rel="noopener"><i class="fa fa-twitter"></i></a></li>
|
||||||
</li>
|
<li><a href="https://mastodon.xyz/@jcbrand" class="btn btn-lg" title="Mastodon" target="_blank" rel="noopener"><img class="mastodon" src="/logo/mastodon.svg"/></a></li>
|
||||||
<li><a href="https://github.com/jcbrand/converse.js" class="btn btn-circle btn-lg" title="GitHub" target="_blank" rel="noopener"><i class="fa fa-github"></i></a>
|
<li><a href="https://github.com/jcbrand/converse.js" class="btn btn-circle btn-lg" title="GitHub" target="_blank" rel="noopener"><i class="fa fa-github"></i></a></li>
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -144,11 +143,8 @@
|
|||||||
<li>Available as overlayed chat boxes or as a fullscreen application.
|
<li>Available as overlayed chat boxes or as a fullscreen application.
|
||||||
See <a href="https://inverse.chat" target="_blank" rel="noopener">inverse.chat</a> for the fullscreen version.
|
See <a href="https://inverse.chat" target="_blank" rel="noopener">inverse.chat</a> for the fullscreen version.
|
||||||
</li>
|
</li>
|
||||||
<li><a href="https://conversejs.org/docs/html/plugin_development.html">Plugin Architecture</a> based on
|
<li><a href="https://conversejs.org/docs/html/plugin_development.html">Plugin Architecture</a></li>
|
||||||
<a href="https://jcbrand.github.io/pluggable.js/" target="_blank" rel="noopener">pluggable.js</a></li>
|
<li>Single-user and group chat</li>
|
||||||
<li>Presence information (online, busy, away)</li>
|
|
||||||
<li>Single-user chat</li>
|
|
||||||
<li>Contacts and groups</li>
|
|
||||||
<li>Multi-user chatrooms (<a href="http://xmpp.org/extensions/xep-0045.html" target="_blank" rel="noopener">XEP 45</a>)</li>
|
<li>Multi-user chatrooms (<a href="http://xmpp.org/extensions/xep-0045.html" target="_blank" rel="noopener">XEP 45</a>)</li>
|
||||||
<li>Chatroom bookmarks (<a href="http://xmpp.org/extensions/xep-0048.html" target="_blank" rel="noopener">XEP 48</a>)</li>
|
<li>Chatroom bookmarks (<a href="http://xmpp.org/extensions/xep-0048.html" target="_blank" rel="noopener">XEP 48</a>)</li>
|
||||||
<li>Direct invitations to chat rooms (<a href="http://xmpp.org/extensions/xep-0249.html" target="_blank" rel="noopener">XEP 249</a>)</li>
|
<li>Direct invitations to chat rooms (<a href="http://xmpp.org/extensions/xep-0249.html" target="_blank" rel="noopener">XEP 249</a>)</li>
|
||||||
@ -163,10 +159,11 @@
|
|||||||
<li>Third person "/me" messages (<a href="http://xmpp.org/extensions/xep-0245.html" target="_blank" rel="noopener">XEP 245</a>)</li>
|
<li>Third person "/me" messages (<a href="http://xmpp.org/extensions/xep-0245.html" target="_blank" rel="noopener">XEP 245</a>)</li>
|
||||||
<li>XMPP Ping (<a href="http://xmpp.org/extensions/xep-0199.html" target="_blank" rel="noopener">XEP 199</a>)</li>
|
<li>XMPP Ping (<a href="http://xmpp.org/extensions/xep-0199.html" target="_blank" rel="noopener">XEP 199</a>)</li>
|
||||||
<li>Server-side archiving of messages (<a href="http://xmpp.org/extensions/xep-0313.html" target="_blank" rel="noopener">XEP 313</a>)</li>
|
<li>Server-side archiving of messages (<a href="http://xmpp.org/extensions/xep-0313.html" target="_blank" rel="noopener">XEP 313</a>)</li>
|
||||||
|
<li>Hidden messages (aka Spoilers) (<a href="http://xmpp.org/extensions/xep-0382.html" target="_blank" rel="noopener">XEP 382</a>)</li>
|
||||||
<li>Client state indication (<a href="http://xmpp.org/extensions/xep-0352.html" target="_blank" rel="noopener">XEP 352</a>)</li>
|
<li>Client state indication (<a href="http://xmpp.org/extensions/xep-0352.html" target="_blank" rel="noopener">XEP 352</a>)</li>
|
||||||
<li>Off-the-record encryption</li>
|
<li>Off-the-record encryption</li>
|
||||||
<li>Supports anonymous logins, see the <a href="https://conversejs.org/demo/anonymous.html" target="_blank" rel="noopener">anonymous login demo</a>.</li>
|
<li>Supports anonymous logins, see the <a href="https://conversejs.org/demo/anonymous.html" target="_blank" rel="noopener">anonymous login demo</a>.</li>
|
||||||
<li>Translated into 16 languages</li>
|
<li>Translated into 17 languages</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
@ -233,15 +230,16 @@
|
|||||||
<div class="sponsors">
|
<div class="sponsors">
|
||||||
<h2>Converse.js is supported by:</h2>
|
<h2>Converse.js is supported by:</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://www.keycdn.com/" target="_blank" rel="noopener"><img style="height: 2em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
|
<li><a href="https://www.keycdn.com/" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
|
||||||
|
<li><a href="http://wikisuite.org" target="_blank" rel="noopener"><img style="height: 4em" src="/logo/wikisuite-white.png" alt="WikiSuite"></a></li>
|
||||||
<li><a href="https://diasporing.ch" target="_blank" rel="noopener"><img style="height: 2em" src="/logo/diasporing.svg" alt="Diasporing.ch"></a></li>
|
<li><a href="https://diasporing.ch" target="_blank" rel="noopener"><img style="height: 2em" src="/logo/diasporing.svg" alt="Diasporing.ch"></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="sponsors-text">Converse.js is a software commons; available at no cost to you and every other person on earth.
|
<p class="sponsors-text">Converse.js is a software commons; available at no cost to you or anyone else.
|
||||||
Sponsorships allow us to fund further development and improvements and are greatly appreciated.
|
Sponsorships allow us to fund further development and improvements and are greatly appreciated.
|
||||||
If you'd like to sponsor this project, please visit <a href="https://www.patreon.com/jcbrand" target="_blank" rel="noopener">Patreon page</a>
|
If you'd like to sponsor this project, please visit <a href="https://www.patreon.com/jcbrand" target="_blank" rel="noopener">Patreon page</a>
|
||||||
or <a href="https://liberapay.com/jcbrand" target="_blank" rel="noopener">Liberapay</a>
|
or <a href="https://liberapay.com/jcbrand" target="_blank" rel="noopener">Liberapay</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
BIN
logo/keycdn.png
Normal file
BIN
logo/keycdn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
77
logo/mastodon.svg
Normal file
77
logo/mastodon.svg
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
id="svg899"
|
||||||
|
version="1.1"
|
||||||
|
sodipodi:docname="mastodon.svg"
|
||||||
|
>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
id="namedview868"
|
||||||
|
showgrid="false"
|
||||||
|
/>
|
||||||
|
<metadata
|
||||||
|
id="metadata903">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs891">
|
||||||
|
<g
|
||||||
|
id="Layer0_0_FILL">
|
||||||
|
<path
|
||||||
|
id="path887"
|
||||||
|
d=" M 280.35 204.05 Q 280.35 202.3 279.1 201.05 277.85 199.8 276.1 199.8 274.35 199.8 273.1 201.05 271.85 202.3 271.85 204.05 271.85 205 272.25 205.8 272.55 206.5 273.1 207.05 274.35 208.3 276.1 208.3 277.85 208.3 279.1 207.05 279.65 206.5 280 205.8 280.35 205 280.35 204.05 M 273.1 187.05 Q 271.85 188.3 271.85 190.05 271.85 191.8 273.1 193.05 274.35 194.3 276.1 194.3 277.85 194.3 279.1 193.05 279.5 192.65 279.8 192.2 280.35 191.25 280.35 190.05 280.35 188.3 279.1 187.05 278.75 186.7 278.35 186.45 277.35 185.8 276.1 185.8 274.35 185.8 273.1 187.05 M 276.1 171.8 Q 274.35 171.8 273.1 173.05 271.85 174.3 271.85 176.05 271.85 177.8 273.1 179.05 274.35 180.3 276.1 180.3 277.85 180.3 279.1 179.05 280.35 177.8 280.35 176.05 280.35 174.3 279.1 173.05 277.85 171.8 276.1 171.8 M 236.1 208.55 Q 234.85 207.3 233.1 207.3 231.35 207.3 230.1 208.55 228.85 209.8 228.85 211.55 228.85 213.3 230.1 214.55 231.35 215.8 233.1 215.8 234.85 215.8 236.1 214.55 237.35 213.3 237.35 211.55 237.35 209.8 236.1 208.55 M 230.1 194.55 Q 228.85 195.8 228.85 197.55 228.85 199.3 230.1 200.55 231.35 201.8 233.1 201.8 234.35 201.8 235.35 201.15 235.75 200.9 236.1 200.55 237.35 199.3 237.35 197.55 237.35 196.35 236.8 195.4 236.5 194.95 236.1 194.55 234.85 193.3 233.1 193.3 231.35 193.3 230.1 194.55 M 236.1 180.55 Q 234.85 179.3 233.1 179.3 231.35 179.3 230.1 180.55 229.55 181.1 229.25 181.8 228.85 182.6 228.85 183.55 228.85 185.3 230.1 186.55 231.35 187.8 233.1 187.8 234.85 187.8 236.1 186.55 237.35 185.3 237.35 183.55 237.35 182.6 237 181.8 236.65 181.1 236.1 180.55 M 318.6 207.3 Q 316.85 207.3 315.6 208.55 314.35 209.8 314.35 211.55 314.35 213.3 315.6 214.55 316.85 215.8 318.6 215.8 320.35 215.8 321.6 214.55 322.85 213.3 322.85 211.55 322.85 209.8 321.6 208.55 320.35 207.3 318.6 207.3 M 321.6 194.55 Q 320.35 193.3 318.6 193.3 316.85 193.3 315.6 194.55 315.2 194.95 314.9 195.4 314.35 196.35 314.35 197.55 314.35 199.3 315.6 200.55 315.95 200.9 316.35 201.15 317.35 201.8 318.6 201.8 320.35 201.8 321.6 200.55 322.85 199.3 322.85 197.55 322.85 195.8 321.6 194.55 M 314.7 181.8 Q 314.35 182.6 314.35 183.55 314.35 185.3 315.6 186.55 316.85 187.8 318.6 187.8 320.35 187.8 321.6 186.55 322.85 185.3 322.85 183.55 322.85 182.6 322.45 181.8 322.15 181.1 321.6 180.55 320.35 179.3 318.6 179.3 316.85 179.3 315.6 180.55 315.05 181.1 314.7 181.8 Z"
|
||||||
|
stroke="none"
|
||||||
|
fill="white" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
d=" M 334.35 213.3 L 334.35 181.9 Q 334.35 181.85 334.35 181.8 334.15 175.65 329.85 171.35 325.3 166.8 318.85 166.8 312.4 166.8 307.9 171.35 303.5 175.7 303.35 181.9 L 303.35 214.8 Q 303 223.05 296.35 228.8 L 318.35 228.8 Q 318.6 228.8 318.85 228.8 325.3 228.8 329.85 224.3 334.35 219.75 334.35 213.3 Z M 351.2 197.5 Q 351.2 228.55 329.25 250.5 307.3 272.45 276.25 272.45 245.25 272.45 223.3 250.5 201.35 228.55 201.35 197.5 201.35 166.5 223.3 144.55 245.25 122.55 276.25 122.55 307.3 122.55 329.25 144.55 351.2 166.5 351.2 197.5 Z M 217.35 213.3 L 217.35 181.9 Q 217.35 181.85 217.35 181.8 217.55 175.65 221.85 171.35 226.4 166.8 232.85 166.8 239.3 166.8 243.8 171.35 248.2 175.7 248.35 181.9 L 248.35 214.8 Q 248.7 223.05 255.35 228.8 L 233.35 228.8 Q 233.1 228.8 232.85 228.8 226.4 228.8 221.85 224.3 217.35 219.75 217.35 213.3 Z M 260.35 174.3 L 260.35 205.7 Q 260.35 205.75 260.35 205.8 260.55 211.95 264.85 216.25 269.4 220.8 275.85 220.8 282.3 220.8 286.8 216.25 291.2 211.9 291.35 205.7 L 291.35 172.8 Q 291.7 164.55 298.35 158.8 L 276.35 158.8 Q 276.1 158.8 275.85 158.8 269.4 158.8 264.85 163.3 260.35 167.85 260.35 174.3 Z"
|
||||||
|
fill="none"
|
||||||
|
stroke-miterlimit="3"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="miter"
|
||||||
|
stroke-width="4"
|
||||||
|
stroke="white"
|
||||||
|
id="Layer0_0_1_STROKES" />
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
id="g872"
|
||||||
|
transform="matrix(1.2351757,0,0,1.2586523,-10.042372,-11.404917)">
|
||||||
|
<use
|
||||||
|
y="0"
|
||||||
|
x="0"
|
||||||
|
id="use893"
|
||||||
|
xlink:href="#Layer0_0_FILL"
|
||||||
|
transform="matrix(0.52842775,0,0,0.50807109,-97.047903,-51.777426)"
|
||||||
|
width="100%"
|
||||||
|
height="100%" />
|
||||||
|
<use
|
||||||
|
y="0"
|
||||||
|
x="0"
|
||||||
|
id="use895"
|
||||||
|
xlink:href="#Layer0_0_1_STROKES"
|
||||||
|
transform="matrix(0.52842775,0,0,0.50807109,-97.047903,-51.777426)"
|
||||||
|
width="100%"
|
||||||
|
height="100%" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.3 KiB |
BIN
logo/wikisuite-white.png
Normal file
BIN
logo/wikisuite-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
BIN
logo/wikisuite.png
Normal file
BIN
logo/wikisuite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -16,8 +16,8 @@
|
|||||||
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/mobile.min.css" />
|
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/mobile.min.css" />
|
||||||
<script type="text/javascript" src="analytics.js"></script>
|
<script type="text/javascript" src="analytics.js"></script>
|
||||||
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||||
<![if gte IE 9]>
|
<![if gte IE 11]>
|
||||||
<script src="https://cdn.conversejs.org/dist/converse-mobile.min.js"></script>
|
<script src="https://cdn.conversejs.org/dist/converse.min.js"></script>
|
||||||
<![endif]>
|
<![endif]>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
4368
package-lock.json
generated
4368
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "converse.js",
|
"name": "converse.js",
|
||||||
"version": "3.3.1",
|
"version": "3.3.3",
|
||||||
"description": "Browser based XMPP instant messaging client",
|
"description": "Browser based XMPP instant messaging client",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@ -37,10 +37,10 @@
|
|||||||
"backbone": "1.3.3",
|
"backbone": "1.3.3",
|
||||||
"backbone.browserStorage": "0.0.3",
|
"backbone.browserStorage": "0.0.3",
|
||||||
"backbone.nativeview": "^0.3.3",
|
"backbone.nativeview": "^0.3.3",
|
||||||
"backbone.overview": "1.0.0",
|
|
||||||
"backbone.vdomview": "1.0.0",
|
|
||||||
"bootstrap": "^4.0.0",
|
"bootstrap": "^4.0.0",
|
||||||
"bootstrap.native": "^2.0.21",
|
"bootstrap.native": "^2.0.21",
|
||||||
|
"backbone.overview": "1.0.2",
|
||||||
|
"backbone.vdomview": "1.0.1",
|
||||||
"bourbon": "^4.3.2",
|
"bourbon": "^4.3.2",
|
||||||
"clean-css-cli": "^4.0.10",
|
"clean-css-cli": "^4.0.10",
|
||||||
"emojione": "^3.0.3",
|
"emojione": "^3.0.3",
|
||||||
@ -57,15 +57,14 @@
|
|||||||
"lodash": "4.17.4",
|
"lodash": "4.17.4",
|
||||||
"lodash-template-loader": "^2.0.0",
|
"lodash-template-loader": "^2.0.0",
|
||||||
"moment": "~2.18.1",
|
"moment": "~2.18.1",
|
||||||
"npm": "^4.1.1",
|
"otr": "jcbrand/otr",
|
||||||
"otr": "0.2.16",
|
|
||||||
"pluggable.js": "2.0.0",
|
"pluggable.js": "2.0.0",
|
||||||
"po2json": "^0.4.4",
|
"po2json": "^0.4.4",
|
||||||
"requirejs": "2.3.5",
|
"requirejs": "2.3.5",
|
||||||
"run-headless-chromium": "^0.1.1",
|
"run-headless-chromium": "^0.1.1",
|
||||||
"sinon": "^2.1.0",
|
"sinon": "^2.1.0",
|
||||||
"sizzle": "^2.3.3",
|
"sizzle": "^2.3.3",
|
||||||
"snabbdom": "jcbrand/snabbdom",
|
"snabbdom": "0.7.1",
|
||||||
"snyk": "^1.21.2",
|
"snyk": "^1.21.2",
|
||||||
"strophe.js": "1.2.14",
|
"strophe.js": "1.2.14",
|
||||||
"strophejs-plugin-disco": "0.0.1",
|
"strophejs-plugin-disco": "0.0.1",
|
||||||
|
@ -85,6 +85,11 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
width: $mobile-chat-width;
|
width: $mobile-chat-width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spoiler {
|
||||||
|
background-color: lighten($chat-head-color, 50%);
|
||||||
|
}
|
||||||
|
|
||||||
.box-flyout {
|
.box-flyout {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
|
box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
|
||||||
@ -157,6 +162,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.chat-image {
|
.chat-image {
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
max-height: 24em;
|
max-height: 24em;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
@ -189,6 +196,12 @@
|
|||||||
.chat-msg-content {
|
.chat-msg-content {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
&.spoiler {
|
||||||
|
border-radius: $chatbox-border-radius;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
.emojione {
|
.emojione {
|
||||||
margin-bottom: -6px;
|
margin-bottom: -6px;
|
||||||
}
|
}
|
||||||
@ -226,6 +239,11 @@
|
|||||||
line-height: 1.3em;
|
line-height: 1.3em;
|
||||||
height: 206px;
|
height: 206px;
|
||||||
height: calc(100% - #{$toolbar-height + $chat-textarea-height +1px});
|
height: calc(100% - #{$toolbar-height + $chat-textarea-height +1px});
|
||||||
|
|
||||||
|
.toggle-spoiler:before {
|
||||||
|
padding-right: 0.25em;
|
||||||
|
whitespace: nowrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.chat-content-sendbutton {
|
.chat-content-sendbutton {
|
||||||
height: calc(100% - #{$toolbar-height + $chat-textarea-height + $send-button-height + 2*$send-button-margin});
|
height: calc(100% - #{$toolbar-height + $chat-textarea-height + $send-button-height + 2*$send-button-margin});
|
||||||
@ -239,6 +257,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sendXMPPMessage {
|
.sendXMPPMessage {
|
||||||
-moz-background-clip: padding;
|
-moz-background-clip: padding;
|
||||||
-webkit-background-clip: padding-box;
|
-webkit-background-clip: padding-box;
|
||||||
@ -257,6 +276,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spoiler-hint {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.chat-textarea {
|
.chat-textarea {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
@ -266,6 +289,9 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
resize: none;
|
resize: none;
|
||||||
|
&.spoiler {
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-button {
|
.send-button {
|
||||||
@ -282,20 +308,17 @@
|
|||||||
.chat-toolbar {
|
.chat-toolbar {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px;
|
padding: 0.25em;
|
||||||
height: $toolbar-height;
|
height: $toolbar-height;
|
||||||
display: block;
|
display: block;
|
||||||
background-color: $toolbar-color;
|
background-color: lighten($chat-head-color, 10%);
|
||||||
|
color: white;
|
||||||
a {
|
a {
|
||||||
font-size: $font-size;
|
color: white;
|
||||||
color: $text-color;
|
font-size: $font-size-large;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
.chat-toolbar-text {
|
|
||||||
font-size: 12px;
|
|
||||||
padding-right: 3px;
|
|
||||||
}
|
|
||||||
.unencrypted a,
|
.unencrypted a,
|
||||||
.unencrypted {
|
.unencrypted {
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
@ -384,10 +407,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.toggle-toolbar-menu {
|
&.toggle-toolbar-menu {
|
||||||
color: $text-color;
|
color: white;
|
||||||
}
|
}
|
||||||
&.toggle-smiley {
|
&.toggle-smiley {
|
||||||
padding-left: 5px;
|
|
||||||
.emoji-toolbar {
|
.emoji-toolbar {
|
||||||
.emoji-category-picker,
|
.emoji-category-picker,
|
||||||
.emoji-skintone-picker {
|
.emoji-skintone-picker {
|
||||||
|
@ -249,7 +249,7 @@
|
|||||||
|
|
||||||
.sendXMPPMessage {
|
.sendXMPPMessage {
|
||||||
.chat-toolbar {
|
.chat-toolbar {
|
||||||
background-color: $chatroom-toolbar-color;
|
background-color: lighten($chatroom-head-color, 10%);
|
||||||
}
|
}
|
||||||
.chat-textarea {
|
.chat-textarea {
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
|
@ -404,7 +404,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.controlbox-panes {
|
.controlbox-panes {
|
||||||
overflow-y: scroll;
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.controlbox-pane {
|
.controlbox-pane {
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#converse-embedded-chat,
|
#converse-embedded-chat,
|
||||||
#conversejs {
|
#conversejs {
|
||||||
margin-left: -$chat-gutter; // Mystery why this is necessary
|
margin-left: -$chat-gutter; // Mystery why this is necessary
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
padding-right: env(safe-area-inset-right);
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
height: auto;
|
height: auto;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
@ -32,6 +34,7 @@
|
|||||||
:-moz-placeholder { /* Firefox 18- */
|
:-moz-placeholder { /* Firefox 18- */
|
||||||
color: $subdued-color;
|
color: $subdued-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
::placeholder {
|
::placeholder {
|
||||||
color: $subdued-color;
|
color: $subdued-color;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@import "bourbon";
|
@import "bourbon";
|
||||||
@import "converse/variables";
|
@import "converse/variables";
|
||||||
#converse-embedded-chat {
|
#conversejs.converse-embedded {
|
||||||
|
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
*, *:before, *:after {
|
*, *:before, *:after {
|
||||||
|
3
sass/only-fonts.scss
Normal file
3
sass/only-fonts.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@import "bourbon";
|
||||||
|
@import "converse/variables";
|
||||||
|
@import "fonts";
|
@ -12,6 +12,8 @@
|
|||||||
} (this, function (jasmine, $, converse, utils, mock, test_utils) {
|
} (this, function (jasmine, $, converse, utils, mock, test_utils) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var $iq = converse.env.$iq,
|
var $iq = converse.env.$iq,
|
||||||
|
$msg = converse.env.$msg,
|
||||||
|
Backbone = converse.env.Backbone,
|
||||||
Strophe = converse.env.Strophe,
|
Strophe = converse.env.Strophe,
|
||||||
_ = converse.env._,
|
_ = converse.env._,
|
||||||
u = converse.env.utils;
|
u = converse.env.utils;
|
||||||
@ -21,6 +23,11 @@
|
|||||||
it("can be bookmarked", mock.initConverseWithPromises(
|
it("can be bookmarked", mock.initConverseWithPromises(
|
||||||
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
var sent_stanza, IQ_id;
|
var sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
var sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
@ -35,6 +42,9 @@
|
|||||||
spyOn(view, 'renderBookmarkForm').and.callThrough();
|
spyOn(view, 'renderBookmarkForm').and.callThrough();
|
||||||
spyOn(view, 'closeForm').and.callThrough();
|
spyOn(view, 'closeForm').and.callThrough();
|
||||||
|
|
||||||
|
test_utils.waitUntil(function () {
|
||||||
|
return !_.isNull(view.el.querySelector('.toggle-bookmark'));
|
||||||
|
}, 300).then(function () {
|
||||||
var $bookmark = $(view.el).find('.icon-pushpin');
|
var $bookmark = $(view.el).find('.icon-pushpin');
|
||||||
$bookmark[0].click();
|
$bookmark[0].click();
|
||||||
expect(view.renderBookmarkForm).toHaveBeenCalled();
|
expect(view.renderBookmarkForm).toHaveBeenCalled();
|
||||||
@ -129,11 +139,18 @@
|
|||||||
// We ignore this IQ stanza... (unless it's an error stanza), so
|
// We ignore this IQ stanza... (unless it's an error stanza), so
|
||||||
// nothing to test for here.
|
// nothing to test for here.
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("will be automatically opened if 'autojoin' is set on the bookmark", mock.initConverseWithPromises(
|
it("will be automatically opened if 'autojoin' is set on the bookmark", mock.initConverseWithPromises(
|
||||||
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
var jid = 'lounge@localhost';
|
var jid = 'lounge@localhost';
|
||||||
_converse.bookmarks.create({
|
_converse.bookmarks.create({
|
||||||
'jid': jid,
|
'jid': jid,
|
||||||
@ -152,6 +169,7 @@
|
|||||||
});
|
});
|
||||||
expect(_.isUndefined(_converse.chatboxviews.get(jid))).toBeFalsy();
|
expect(_.isUndefined(_converse.chatboxviews.get(jid))).toBeFalsy();
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe("when bookmarked", function () {
|
describe("when bookmarked", function () {
|
||||||
@ -159,28 +177,50 @@
|
|||||||
it("displays that it's bookmarked through its bookmark icon", mock.initConverseWithPromises(
|
it("displays that it's bookmarked through its bookmark icon", mock.initConverseWithPromises(
|
||||||
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||||
var view = _converse.chatboxviews.get('lounge@localhost');
|
var view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
var $bookmark_icon = $(view.el.querySelector('.icon-pushpin'));
|
|
||||||
expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
|
test_utils.waitUntil(function () {
|
||||||
|
return !_.isNull(view.el.querySelector('.toggle-bookmark'));
|
||||||
|
}, 300).then(function () {
|
||||||
|
var bookmark_icon = view.el.querySelector('.icon-pushpin');
|
||||||
|
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy();
|
||||||
view.model.set('bookmarked', true);
|
view.model.set('bookmarked', true);
|
||||||
expect($bookmark_icon.hasClass('button-on')).toBeTruthy();
|
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeTruthy();
|
||||||
view.model.set('bookmarked', false);
|
view.model.set('bookmarked', false);
|
||||||
expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
|
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy();
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("can be unbookmarked", mock.initConverseWithPromises(
|
it("can be unbookmarked", mock.initConverseWithPromises(
|
||||||
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
var sent_stanza, IQ_id;
|
var sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
var sendIQ = _converse.connection.sendIQ;
|
||||||
|
|
||||||
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
|
test_utils.openChatRoom(_converse, 'theplay', 'conference.shakespeare.lit', 'JC');
|
||||||
var jid = 'theplay@conference.shakespeare.lit';
|
var jid = 'theplay@conference.shakespeare.lit';
|
||||||
var view = _converse.chatboxviews.get(jid);
|
var view = _converse.chatboxviews.get(jid);
|
||||||
|
|
||||||
|
test_utils.waitUntil(function () {
|
||||||
|
return !_.isNull(view.el.querySelector('.toggle-bookmark'));
|
||||||
|
}, 300).then(function () {
|
||||||
spyOn(view, 'toggleBookmark').and.callThrough();
|
spyOn(view, 'toggleBookmark').and.callThrough();
|
||||||
spyOn(_converse.bookmarks, 'sendBookmarkStanza').and.callThrough();
|
spyOn(_converse.bookmarks, 'sendBookmarkStanza').and.callThrough();
|
||||||
view.delegateEvents();
|
view.delegateEvents();
|
||||||
|
|
||||||
_converse.bookmarks.create({
|
_converse.bookmarks.create({
|
||||||
'jid': view.model.get('jid'),
|
'jid': view.model.get('jid'),
|
||||||
'autojoin': false,
|
'autojoin': false,
|
||||||
@ -230,12 +270,21 @@
|
|||||||
"</iq>"
|
"</iq>"
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("and when autojoin is set", function () {
|
describe("and when autojoin is set", function () {
|
||||||
|
|
||||||
it("will be be opened and joined automatically upon login", mock.initConverse(function (_converse) {
|
it("will be be opened and joined automatically upon login", mock.initConverseWithPromises(
|
||||||
|
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
spyOn(_converse.api.rooms, 'open');
|
spyOn(_converse.api.rooms, 'open');
|
||||||
var jid = 'theplay@conference.shakespeare.lit';
|
var jid = 'theplay@conference.shakespeare.lit';
|
||||||
var model = _converse.bookmarks.create({
|
var model = _converse.bookmarks.create({
|
||||||
@ -254,14 +303,27 @@
|
|||||||
'nick': ''
|
'nick': ''
|
||||||
});
|
});
|
||||||
expect(_converse.api.rooms.open).toHaveBeenCalled();
|
expect(_converse.api.rooms.open).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Bookmarks", function () {
|
describe("Bookmarks", function () {
|
||||||
|
|
||||||
xit("can be pushed from the XMPP server", mock.initConverse(function (_converse) {
|
it("can be pushed from the XMPP server", mock.initConverseWithPromises(
|
||||||
// TODO
|
['send'], ['rosterGroupsFetched', 'connected'], {},
|
||||||
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
|
test_utils.openControlBox().openRoomsPanel(_converse);
|
||||||
|
test_utils.waitUntil(function () {
|
||||||
|
return _converse.bookmarks;
|
||||||
|
}, 300).then(function () {
|
||||||
/* The stored data is automatically pushed to all of the user's
|
/* The stored data is automatically pushed to all of the user's
|
||||||
* connected resources.
|
* connected resources.
|
||||||
*
|
*
|
||||||
@ -285,31 +347,38 @@
|
|||||||
* </items>
|
* </items>
|
||||||
* </event>
|
* </event>
|
||||||
* </message>
|
* </message>
|
||||||
|
|
||||||
* <message from='juliet@capulet.lit'
|
|
||||||
* to='juliet@capulet.lit/chamber'
|
|
||||||
* type='headline'
|
|
||||||
* id='rnfoo2'>
|
|
||||||
* <event xmlns='http://jabber.org/protocol/pubsub#event'>
|
|
||||||
* <items node='storage:bookmarks'>
|
|
||||||
* <item id='current'>
|
|
||||||
* <storage xmlns='storage:bookmarks'>
|
|
||||||
* <conference name='The Play's the Thing'
|
|
||||||
* autojoin='true'
|
|
||||||
* jid='theplay@conference.shakespeare.lit'>
|
|
||||||
* <nick>JC</nick>
|
|
||||||
* </conference>
|
|
||||||
* </storage>
|
|
||||||
* </item>
|
|
||||||
* </items>
|
|
||||||
* </event>
|
|
||||||
* </message>
|
|
||||||
*/
|
*/
|
||||||
|
var stanza = $msg({
|
||||||
|
'from': 'dummy@localhost',
|
||||||
|
'to': 'dummy@localhost/resource',
|
||||||
|
'type': 'headline',
|
||||||
|
'id': 'rnfoo1'
|
||||||
|
}).c('event', {'xmlns': 'http://jabber.org/protocol/pubsub#event'})
|
||||||
|
.c('items', {'node': 'storage:bookmarks'})
|
||||||
|
.c('item', {'id': 'current'})
|
||||||
|
.c('storage', {'xmlns': 'storage:bookmarks'})
|
||||||
|
.c('conference', {'name': 'The Play's the Thing',
|
||||||
|
'autojoin': 'true',
|
||||||
|
'jid':'theplay@conference.shakespeare.lit'})
|
||||||
|
.c('nick').t('JC');
|
||||||
|
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||||
|
expect(_converse.bookmarks.length).toBe(1);
|
||||||
|
expect(_converse.chatboxviews.get('theplay@conference.shakespeare.lit')).not.toBeUndefined();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("can be retrieved from the XMPP server", mock.initConverseWithPromises(
|
it("can be retrieved from the XMPP server", mock.initConverseWithPromises(
|
||||||
['send'], ['rosterGroupsFetched'], {}, function (done, _converse) {
|
['send'], ['chatBoxesFetched', 'roomsPanelRendered', 'rosterGroupsFetched'], {},
|
||||||
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
/* Client requests all items
|
/* Client requests all items
|
||||||
* -------------------------
|
* -------------------------
|
||||||
*
|
*
|
||||||
@ -382,6 +451,7 @@
|
|||||||
expect(_converse.bookmarks.findWhere({'jid': 'theplay@conference.shakespeare.lit'}).get('autojoin')).toBe(true);
|
expect(_converse.bookmarks.findWhere({'jid': 'theplay@conference.shakespeare.lit'}).get('autojoin')).toBe(true);
|
||||||
expect(_converse.bookmarks.findWhere({'jid': 'another@conference.shakespeare.lit'}).get('autojoin')).toBe(false);
|
expect(_converse.bookmarks.findWhere({'jid': 'another@conference.shakespeare.lit'}).get('autojoin')).toBe(false);
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe("The rooms panel", function () {
|
describe("The rooms panel", function () {
|
||||||
@ -389,6 +459,12 @@
|
|||||||
it("shows a list of bookmarks", mock.initConverseWithPromises(
|
it("shows a list of bookmarks", mock.initConverseWithPromises(
|
||||||
['send'], ['rosterGroupsFetched'], {}, function (done, _converse) {
|
['send'], ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
|
|
||||||
test_utils.openControlBox().openRoomsPanel(_converse);
|
test_utils.openControlBox().openRoomsPanel(_converse);
|
||||||
var IQ_id;
|
var IQ_id;
|
||||||
expect(_.filter(_converse.connection.send.calls.all(), function (call) {
|
expect(_.filter(_converse.connection.send.calls.all(), function (call) {
|
||||||
@ -454,11 +530,17 @@
|
|||||||
"1st Bookmark Bookmark with a very very long name that will be shortened The Play's the Thing";
|
"1st Bookmark Bookmark with a very very long name that will be shortened The Play's the Thing";
|
||||||
}, 300)
|
}, 300)
|
||||||
}).then(done);
|
}).then(done);
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("remembers the toggle state of the bookmarks list", mock.initConverseWithPromises(
|
it("remembers the toggle state of the bookmarks list", mock.initConverseWithPromises(
|
||||||
['send'], ['rosterGroupsFetched'], {}, function (done, _converse) {
|
['send'], ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
var IQ_id;
|
var IQ_id;
|
||||||
expect(_.filter(_converse.connection.send.calls.all(), function (call) {
|
expect(_.filter(_converse.connection.send.calls.all(), function (call) {
|
||||||
var stanza = call.args[0];
|
var stanza = call.args[0];
|
||||||
@ -510,6 +592,7 @@
|
|||||||
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
|
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -521,6 +604,11 @@
|
|||||||
{ hide_open_bookmarks: true },
|
{ hide_open_bookmarks: true },
|
||||||
function (done, _converse) {
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(
|
||||||
|
_converse, _converse.bare_jid,
|
||||||
|
[{'category': 'pubsub', 'type': 'pep'}],
|
||||||
|
['http://jabber.org/protocol/pubsub#publish-options']
|
||||||
|
).then(function () {
|
||||||
test_utils.openControlBox().openRoomsPanel(_converse);
|
test_utils.openControlBox().openRoomsPanel(_converse);
|
||||||
// XXX Create bookmarks view here, otherwise we need to mock stanza
|
// XXX Create bookmarks view here, otherwise we need to mock stanza
|
||||||
// traffic for it to get created.
|
// traffic for it to get created.
|
||||||
@ -551,6 +639,7 @@
|
|||||||
view.close();
|
view.close();
|
||||||
expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeFalsy();
|
expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeFalsy();
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
null, ['rosterGroupsFetched'], {},
|
null, ['rosterGroupsFetched'], {},
|
||||||
function (done, _converse) {
|
function (done, _converse) {
|
||||||
|
|
||||||
test_utils.waitUntilFeatureSupportConfirmed(_converse, 'vcard-temp')
|
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return test_utils.waitUntil(function () {
|
return test_utils.waitUntil(function () {
|
||||||
return _converse.xmppstatus.get('fullname');
|
return _converse.xmppstatus.get('fullname');
|
||||||
@ -1228,7 +1228,7 @@
|
|||||||
function (done, _converse) {
|
function (done, _converse) {
|
||||||
|
|
||||||
var contact, sent_stanza, IQ_id, stanza;
|
var contact, sent_stanza, IQ_id, stanza;
|
||||||
test_utils.waitUntilFeatureSupportConfirmed(_converse, 'vcard-temp')
|
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return test_utils.waitUntil(function () {
|
return test_utils.waitUntil(function () {
|
||||||
return _converse.xmppstatus.get('fullname');
|
return _converse.xmppstatus.get('fullname');
|
||||||
@ -1842,7 +1842,7 @@
|
|||||||
function (done, _converse) {
|
function (done, _converse) {
|
||||||
|
|
||||||
var contact, sent_stanza, IQ_id, stanza;
|
var contact, sent_stanza, IQ_id, stanza;
|
||||||
test_utils.waitUntilFeatureSupportConfirmed(_converse, 'vcard-temp')
|
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return test_utils.waitUntil(function () {
|
return test_utils.waitUntil(function () {
|
||||||
return _converse.xmppstatus.get('fullname');
|
return _converse.xmppstatus.get('fullname');
|
||||||
@ -1989,7 +1989,7 @@
|
|||||||
function (done, _converse) {
|
function (done, _converse) {
|
||||||
|
|
||||||
var contact, sent_stanza, IQ_id, stanza;
|
var contact, sent_stanza, IQ_id, stanza;
|
||||||
test_utils.waitUntilFeatureSupportConfirmed(_converse, 'vcard-temp')
|
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return test_utils.waitUntil(function () {
|
return test_utils.waitUntil(function () {
|
||||||
return _converse.xmppstatus.get('fullname');
|
return _converse.xmppstatus.get('fullname');
|
||||||
|
@ -762,7 +762,6 @@
|
|||||||
});
|
});
|
||||||
var view = _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
|
var view = _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
|
||||||
|
|
||||||
spyOn(view, 'generateHeadingHTML').and.callThrough();
|
|
||||||
var features_stanza = $iq({
|
var features_stanza = $iq({
|
||||||
from: 'coven@chat.shakespeare.lit',
|
from: 'coven@chat.shakespeare.lit',
|
||||||
'id': IQ_id,
|
'id': IQ_id,
|
||||||
@ -791,10 +790,12 @@
|
|||||||
.c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
|
.c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
|
||||||
.c('value').t(0);
|
.c('value').t(0);
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
|
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
|
||||||
|
test_utils.waitUntil(function () {
|
||||||
expect(view.generateHeadingHTML).toHaveBeenCalled();
|
return _.get(view.el.querySelector('.chatroom-description'), 'textContent');
|
||||||
|
}).then(function () {
|
||||||
expect($(view.el.querySelector('.chatroom-description')).text()).toBe('This is the description');
|
expect($(view.el.querySelector('.chatroom-description')).text()).toBe('This is the description');
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("will specially mark messages in which you are mentioned",
|
it("will specially mark messages in which you are mentioned",
|
||||||
@ -825,8 +826,7 @@
|
|||||||
null, ['rosterGroupsFetched'], {},
|
null, ['rosterGroupsFetched'], {},
|
||||||
function (done, _converse) {
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
|
||||||
test_utils.waitUntilFeatureSupportConfirmed(_converse, 'vcard-temp')
|
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return test_utils.waitUntil(function () {
|
return test_utils.waitUntil(function () {
|
||||||
return _converse.xmppstatus.get('fullname');
|
return _converse.xmppstatus.get('fullname');
|
||||||
@ -890,6 +890,7 @@
|
|||||||
|
|
||||||
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
|
_converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
|
||||||
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
||||||
|
|
||||||
spyOn(view, 'saveAffiliationAndRole').and.callThrough();
|
spyOn(view, 'saveAffiliationAndRole').and.callThrough();
|
||||||
|
|
||||||
// We pretend this is a new room, so no disco info is returned.
|
// We pretend this is a new room, so no disco info is returned.
|
||||||
@ -922,9 +923,13 @@
|
|||||||
.c('status', {code: '110'});
|
.c('status', {code: '110'});
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
expect(view.saveAffiliationAndRole).toHaveBeenCalled();
|
expect(view.saveAffiliationAndRole).toHaveBeenCalled();
|
||||||
expect($(view.el.querySelector('.configure-chatroom-button')).is(':visible')).toBeTruthy();
|
|
||||||
expect($(view.el.querySelector('.toggle-chatbox-button')).is(':visible')).toBeTruthy();
|
expect($(view.el.querySelector('.toggle-chatbox-button')).is(':visible')).toBeTruthy();
|
||||||
expect($(view.el.querySelector('.toggle-bookmark')).is(':visible')).toBeTruthy();
|
|
||||||
|
test_utils.waitUntil(function () {
|
||||||
|
return !_.isNull(view.el.querySelector('.configure-chatroom-button'));
|
||||||
|
}, 300).then(function () {
|
||||||
|
expect($(view.el.querySelector('.configure-chatroom-button')).is(':visible')).toBeTruthy();
|
||||||
|
|
||||||
view.el.querySelector('.configure-chatroom-button').click();
|
view.el.querySelector('.configure-chatroom-button').click();
|
||||||
|
|
||||||
/* Check that an IQ is sent out, asking for the
|
/* Check that an IQ is sent out, asking for the
|
||||||
@ -1095,6 +1100,7 @@
|
|||||||
expect($sent_stanza.find('field[var="muc#roomconfig_allowpm"] value').text()).toBe('moderators');
|
expect($sent_stanza.find('field[var="muc#roomconfig_allowpm"] value').text()).toBe('moderators');
|
||||||
expect($sent_stanza.find('field[var="muc#roomconfig_presencebroadcast"] value').text()).toBe('moderator');
|
expect($sent_stanza.find('field[var="muc#roomconfig_presencebroadcast"] value').text()).toBe('moderator');
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||||
|
|
||||||
var entities = _converse.disco_entities;
|
var entities = _converse.disco_entities;
|
||||||
expect(entities.length).toBe(1);
|
expect(entities.length).toBe(2); // We have an extra entity, which is the user's JID
|
||||||
expect(entities.get(_converse.domain).features.length).toBe(5);
|
expect(entities.get(_converse.domain).features.length).toBe(5);
|
||||||
expect(entities.get(_converse.domain).identities.length).toBe(3);
|
expect(entities.get(_converse.domain).identities.length).toBe(3);
|
||||||
expect(entities.get('localhost').features.where({'var': 'jabber:iq:version'}).length).toBe(1);
|
expect(entities.get('localhost').features.where({'var': 'jabber:iq:version'}).length).toBe(1);
|
||||||
@ -159,7 +159,7 @@
|
|||||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||||
|
|
||||||
entities = _converse.disco_entities;
|
entities = _converse.disco_entities;
|
||||||
expect(entities.length).toBe(4);
|
expect(entities.length).toBe(5); // We have an extra entity, which is the user's JID
|
||||||
expect(entities.get(_converse.domain).identities.where({'category': 'conference'}).length).toBe(1);
|
expect(entities.get(_converse.domain).identities.where({'category': 'conference'}).length).toBe(1);
|
||||||
expect(entities.get(_converse.domain).identities.where({'category': 'directory'}).length).toBe(1);
|
expect(entities.get(_converse.domain).identities.where({'category': 'directory'}).length).toBe(1);
|
||||||
done();
|
done();
|
||||||
|
67
spec/otr.js
67
spec/otr.js
@ -3,8 +3,73 @@
|
|||||||
} (this, function ($, jasmine, mock, converse, test_utils) {
|
} (this, function ($, jasmine, mock, converse, test_utils) {
|
||||||
var Strophe = converse.env.Strophe;
|
var Strophe = converse.env.Strophe;
|
||||||
var b64_sha1 = converse.env.b64_sha1;
|
var b64_sha1 = converse.env.b64_sha1;
|
||||||
|
var $pres = converse.env.$pres;
|
||||||
|
var _ = converse.env._;
|
||||||
|
|
||||||
return describe("The OTR module", function() {
|
describe("A chatbox with an active OTR session", function() {
|
||||||
|
|
||||||
|
it("will not show the spoiler toolbar button",
|
||||||
|
mock.initConverseWithPromises(
|
||||||
|
null, ['rosterGroupsFetched'], {},
|
||||||
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.createContacts(_converse, 'current');
|
||||||
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
|
||||||
|
// XXX: We need to send a presence from the contact, so that we
|
||||||
|
// have a resource, that resource is then queried to see
|
||||||
|
// whether Strophe.NS.SPOILER is supported, in which case
|
||||||
|
// the spoiler button will appear.
|
||||||
|
var presence = $pres({
|
||||||
|
'from': contact_jid+'/phone',
|
||||||
|
'to': 'dummy@localhost'
|
||||||
|
});
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
|
test_utils.openChatBoxFor(_converse, contact_jid);
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
|
||||||
|
var spoiler_toggle;
|
||||||
|
var view = _converse.chatboxviews.get(contact_jid);
|
||||||
|
spyOn(view, 'addSpoilerButton').and.callThrough();
|
||||||
|
view.model.set('otr_status', 1);
|
||||||
|
|
||||||
|
test_utils.waitUntil(function () {
|
||||||
|
return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
|
||||||
|
}).then(function () {
|
||||||
|
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
|
||||||
|
expect(spoiler_toggle).toBe(null);
|
||||||
|
|
||||||
|
view.model.set('otr_status', 3);
|
||||||
|
|
||||||
|
return test_utils.waitUntil(function () {
|
||||||
|
return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
|
||||||
|
});
|
||||||
|
}).then(function () {
|
||||||
|
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
|
||||||
|
expect(spoiler_toggle).not.toBe(null);
|
||||||
|
|
||||||
|
view.model.set('otr_status', 2);
|
||||||
|
return test_utils.waitUntil(function () {
|
||||||
|
return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
|
||||||
|
});
|
||||||
|
}).then(function () {
|
||||||
|
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
|
||||||
|
expect(spoiler_toggle).toBe(null);
|
||||||
|
|
||||||
|
view.model.set('otr_status', 4);
|
||||||
|
return test_utils.waitUntil(function () {
|
||||||
|
return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
|
||||||
|
});
|
||||||
|
}).then(function () {
|
||||||
|
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
|
||||||
|
expect(spoiler_toggle).not.toBe(null);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("The OTR module", function() {
|
||||||
|
|
||||||
it("will add processing hints to sent out encrypted <message> stanzas",
|
it("will add processing hints to sent out encrypted <message> stanzas",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
function (done, _converse) {
|
function (done, _converse) {
|
||||||
|
|
||||||
var contact, sent_stanza, IQ_id, stanza;
|
var contact, sent_stanza, IQ_id, stanza;
|
||||||
test_utils.waitUntilFeatureSupportConfirmed(_converse, 'vcard-temp')
|
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return test_utils.waitUntil(function () {
|
return test_utils.waitUntil(function () {
|
||||||
return _converse.xmppstatus.get('fullname');
|
return _converse.xmppstatus.get('fullname');
|
||||||
|
240
spec/spoilers.js
Normal file
240
spec/spoilers.js
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
(function (root, factory) {
|
||||||
|
define([
|
||||||
|
"jasmine",
|
||||||
|
"utils",
|
||||||
|
"mock",
|
||||||
|
"converse-core",
|
||||||
|
"test-utils"
|
||||||
|
], factory);
|
||||||
|
} (this, function (jasmine, utils, mock, converse, test_utils) {
|
||||||
|
|
||||||
|
var _ = converse.env._;
|
||||||
|
var Strophe = converse.env.Strophe;
|
||||||
|
var $msg = converse.env.$msg;
|
||||||
|
var $pres = converse.env.$pres;
|
||||||
|
var u = converse.env.utils;
|
||||||
|
|
||||||
|
return describe("A spoiler message", function () {
|
||||||
|
|
||||||
|
it("can be received with a hint",
|
||||||
|
mock.initConverseWithPromises(
|
||||||
|
null, ['rosterGroupsFetched'], {},
|
||||||
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.createContacts(_converse, 'current');
|
||||||
|
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
|
||||||
|
/* <message to='romeo@montague.net/orchard' from='juliet@capulet.net/balcony' id='spoiler2'>
|
||||||
|
* <body>And at the end of the story, both of them die! It is so tragic!</body>
|
||||||
|
* <spoiler xmlns='urn:xmpp:spoiler:0'>Love story end</spoiler>
|
||||||
|
* </message>
|
||||||
|
*/
|
||||||
|
var spoiler_hint = "Love story end"
|
||||||
|
var spoiler = "And at the end of the story, both of them die! It is so tragic!";
|
||||||
|
var msg = $msg({
|
||||||
|
'xmlns': 'jabber:client',
|
||||||
|
'to': _converse.bare_jid,
|
||||||
|
'from': sender_jid,
|
||||||
|
'type': 'chat'
|
||||||
|
}).c('body').t(spoiler).up()
|
||||||
|
.c('spoiler', {
|
||||||
|
'xmlns': 'urn:xmpp:spoiler:0',
|
||||||
|
}).t(spoiler_hint)
|
||||||
|
.tree();
|
||||||
|
_converse.chatboxes.onMessage(msg);
|
||||||
|
|
||||||
|
var view = _converse.chatboxviews.get(sender_jid);
|
||||||
|
var message_content = view.el.querySelector('.chat-msg-content');
|
||||||
|
expect(message_content.textContent).toBe(spoiler);
|
||||||
|
|
||||||
|
var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
|
||||||
|
expect(spoiler_hint_el.textContent).toBe(spoiler_hint);
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("can be received without a hint",
|
||||||
|
mock.initConverseWithPromises(
|
||||||
|
null, ['rosterGroupsFetched'], {},
|
||||||
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.createContacts(_converse, 'current');
|
||||||
|
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
|
||||||
|
/* <message to='romeo@montague.net/orchard' from='juliet@capulet.net/balcony' id='spoiler2'>
|
||||||
|
* <body>And at the end of the story, both of them die! It is so tragic!</body>
|
||||||
|
* <spoiler xmlns='urn:xmpp:spoiler:0'>Love story end</spoiler>
|
||||||
|
* </message>
|
||||||
|
*/
|
||||||
|
var spoiler = "And at the end of the story, both of them die! It is so tragic!";
|
||||||
|
var msg = $msg({
|
||||||
|
'xmlns': 'jabber:client',
|
||||||
|
'to': _converse.bare_jid,
|
||||||
|
'from': sender_jid,
|
||||||
|
'type': 'chat'
|
||||||
|
}).c('body').t(spoiler).up()
|
||||||
|
.c('spoiler', {
|
||||||
|
'xmlns': 'urn:xmpp:spoiler:0',
|
||||||
|
}).tree();
|
||||||
|
_converse.chatboxes.onMessage(msg);
|
||||||
|
|
||||||
|
var view = _converse.chatboxviews.get(sender_jid);
|
||||||
|
var message_content = view.el.querySelector('.chat-msg-content');
|
||||||
|
expect(message_content.textContent).toBe(spoiler);
|
||||||
|
|
||||||
|
var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
|
||||||
|
expect(spoiler_hint_el.textContent).toBe('');
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("can be sent without a hint",
|
||||||
|
mock.initConverseWithPromises(
|
||||||
|
null, ['rosterGroupsFetched'], {},
|
||||||
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.createContacts(_converse, 'current');
|
||||||
|
test_utils.openControlBox();
|
||||||
|
test_utils.openContactsPanel(_converse);
|
||||||
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
|
||||||
|
// XXX: We need to send a presence from the contact, so that we
|
||||||
|
// have a resource, that resource is then queried to see
|
||||||
|
// whether Strophe.NS.SPOILER is supported, in which case
|
||||||
|
// the spoiler button will appear.
|
||||||
|
var presence = $pres({
|
||||||
|
'from': contact_jid+'/phone',
|
||||||
|
'to': 'dummy@localhost'
|
||||||
|
});
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
|
test_utils.openChatBoxFor(_converse, contact_jid);
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
|
||||||
|
var view = _converse.chatboxviews.get(contact_jid);
|
||||||
|
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
||||||
|
spyOn(_converse.connection, 'send');
|
||||||
|
|
||||||
|
var spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
|
||||||
|
spoiler_toggle.click();
|
||||||
|
|
||||||
|
var textarea = view.el.querySelector('.chat-textarea');
|
||||||
|
textarea.value = 'This is the spoiler';
|
||||||
|
view.keyPressed({
|
||||||
|
target: textarea,
|
||||||
|
preventDefault: _.noop,
|
||||||
|
keyCode: 13
|
||||||
|
});
|
||||||
|
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
||||||
|
|
||||||
|
/* Test the XML stanza
|
||||||
|
*
|
||||||
|
* <message from="dummy@localhost/resource"
|
||||||
|
* to="max.frankfurter@localhost"
|
||||||
|
* type="chat"
|
||||||
|
* id="4547c38b-d98b-45a5-8f44-b4004dbc335e"
|
||||||
|
* xmlns="jabber:client">
|
||||||
|
* <body>This is the spoiler</body>
|
||||||
|
* <active xmlns="http://jabber.org/protocol/chatstates"/>
|
||||||
|
* <spoiler xmlns="urn:xmpp:spoiler:0"/>
|
||||||
|
* </message>"
|
||||||
|
*/
|
||||||
|
var stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
|
||||||
|
var spoiler_el = stanza.querySelector('spoiler[xmlns="urn:xmpp:spoiler:0"]');
|
||||||
|
expect(_.isNull(spoiler_el)).toBeFalsy();
|
||||||
|
expect(spoiler_el.textContent).toBe('');
|
||||||
|
|
||||||
|
var body_el = stanza.querySelector('body');
|
||||||
|
expect(body_el.textContent).toBe('This is the spoiler');
|
||||||
|
|
||||||
|
/* Test the HTML spoiler message */
|
||||||
|
var spoiler_msg_el = view.el.querySelector('.chat-msg-content.spoiler');
|
||||||
|
expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
|
||||||
|
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
|
||||||
|
|
||||||
|
spoiler_toggle = view.el.querySelector('.toggle-spoiler');
|
||||||
|
expect(spoiler_toggle.textContent).toBe('Show hidden message');
|
||||||
|
spoiler_toggle.click();
|
||||||
|
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeFalsy();
|
||||||
|
expect(spoiler_toggle.textContent).toBe('Hide hidden message');
|
||||||
|
spoiler_toggle.click();
|
||||||
|
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("can be sent with a hint",
|
||||||
|
mock.initConverseWithPromises(
|
||||||
|
null, ['rosterGroupsFetched'], {},
|
||||||
|
function (done, _converse) {
|
||||||
|
|
||||||
|
test_utils.createContacts(_converse, 'current');
|
||||||
|
test_utils.openControlBox();
|
||||||
|
test_utils.openContactsPanel(_converse);
|
||||||
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
|
||||||
|
// XXX: We need to send a presence from the contact, so that we
|
||||||
|
// have a resource, that resource is then queried to see
|
||||||
|
// whether Strophe.NS.SPOILER is supported, in which case
|
||||||
|
// the spoiler button will appear.
|
||||||
|
var presence = $pres({
|
||||||
|
'from': contact_jid+'/phone',
|
||||||
|
'to': 'dummy@localhost'
|
||||||
|
});
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
|
test_utils.openChatBoxFor(_converse, contact_jid);
|
||||||
|
|
||||||
|
test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
|
||||||
|
var view = _converse.chatboxviews.get(contact_jid);
|
||||||
|
var spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
|
||||||
|
spoiler_toggle.click();
|
||||||
|
|
||||||
|
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
||||||
|
spyOn(_converse.connection, 'send');
|
||||||
|
|
||||||
|
var textarea = view.el.querySelector('.chat-textarea');
|
||||||
|
textarea.value = 'This is the spoiler';
|
||||||
|
var hint_input = view.el.querySelector('.spoiler-hint');
|
||||||
|
hint_input.value = 'This is the hint';
|
||||||
|
|
||||||
|
view.keyPressed({
|
||||||
|
target: textarea,
|
||||||
|
preventDefault: _.noop,
|
||||||
|
keyCode: 13
|
||||||
|
});
|
||||||
|
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
||||||
|
|
||||||
|
/* Test the XML stanza
|
||||||
|
*
|
||||||
|
* <message from="dummy@localhost/resource"
|
||||||
|
* to="max.frankfurter@localhost"
|
||||||
|
* type="chat"
|
||||||
|
* id="4547c38b-d98b-45a5-8f44-b4004dbc335e"
|
||||||
|
* xmlns="jabber:client">
|
||||||
|
* <body>This is the spoiler</body>
|
||||||
|
* <active xmlns="http://jabber.org/protocol/chatstates"/>
|
||||||
|
* <spoiler xmlns="urn:xmpp:spoiler:0">This is the hint</spoiler>
|
||||||
|
* </message>"
|
||||||
|
*/
|
||||||
|
var stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
|
||||||
|
var spoiler_el = stanza.querySelector('spoiler[xmlns="urn:xmpp:spoiler:0"]');
|
||||||
|
expect(_.isNull(spoiler_el)).toBeFalsy();
|
||||||
|
expect(spoiler_el.textContent).toBe('This is the hint');
|
||||||
|
|
||||||
|
var body_el = stanza.querySelector('body');
|
||||||
|
expect(body_el.textContent).toBe('This is the spoiler');
|
||||||
|
|
||||||
|
/* Test the HTML spoiler message */
|
||||||
|
var spoiler_msg_el = view.el.querySelector('.chat-msg-content.spoiler');
|
||||||
|
expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
|
||||||
|
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
|
||||||
|
|
||||||
|
spoiler_toggle = view.el.querySelector('.toggle-spoiler');
|
||||||
|
expect(spoiler_toggle.textContent).toBe('Show hidden message');
|
||||||
|
spoiler_toggle.click();
|
||||||
|
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeFalsy();
|
||||||
|
expect(spoiler_toggle.textContent).toBe('Hide hidden message');
|
||||||
|
spoiler_toggle.click();
|
||||||
|
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}));
|
@ -71,26 +71,29 @@
|
|||||||
this.setBookmarkState();
|
this.setBookmarkState();
|
||||||
},
|
},
|
||||||
|
|
||||||
generateHeadingHTML () {
|
renderBookmarkToggle () {
|
||||||
const { _converse } = this.__super__,
|
const { _converse } = this.__super__,
|
||||||
{ __ } = _converse,
|
{ __ } = _converse;
|
||||||
html = this.__super__.generateHeadingHTML.apply(this, arguments);
|
|
||||||
if (_converse.allow_bookmarks) {
|
|
||||||
const div = document.createElement('div');
|
|
||||||
div.innerHTML = html;
|
|
||||||
const bookmark_button = tpl_chatroom_bookmark_toggle(
|
const bookmark_button = tpl_chatroom_bookmark_toggle(
|
||||||
_.assignIn(
|
_.assignIn(this.model.toJSON(), {
|
||||||
this.model.toJSON(),
|
|
||||||
{
|
|
||||||
info_toggle_bookmark: __('Bookmark this room'),
|
info_toggle_bookmark: __('Bookmark this room'),
|
||||||
bookmarked: this.model.get('bookmarked')
|
bookmarked: this.model.get('bookmarked')
|
||||||
}
|
}));
|
||||||
));
|
const close_button = this.el.querySelector('.close-chatbox-button');
|
||||||
const close_button = div.querySelector('.close-chatbox-button');
|
|
||||||
close_button.insertAdjacentHTML('afterend', bookmark_button);
|
close_button.insertAdjacentHTML('afterend', bookmark_button);
|
||||||
return div.innerHTML;
|
},
|
||||||
|
|
||||||
|
renderHeading () {
|
||||||
|
this.__super__.renderHeading.apply(this, arguments);
|
||||||
|
const { _converse } = this.__super__;
|
||||||
|
if (_converse.allow_bookmarks) {
|
||||||
|
_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid).then((identity) => {
|
||||||
|
if (_.isNil(identity)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.renderBookmarkToggle();
|
||||||
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
}
|
}
|
||||||
return html;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
checkForReservedNick () {
|
checkForReservedNick () {
|
||||||
@ -112,6 +115,9 @@
|
|||||||
|
|
||||||
onBookmarked () {
|
onBookmarked () {
|
||||||
const icon = this.el.querySelector('.icon-pushpin');
|
const icon = this.el.querySelector('.icon-pushpin');
|
||||||
|
if (_.isNull(icon)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.model.get('bookmarked')) {
|
if (this.model.get('bookmarked')) {
|
||||||
icon.classList.add('button-on');
|
icon.classList.add('button-on');
|
||||||
} else {
|
} else {
|
||||||
@ -212,6 +218,7 @@
|
|||||||
// configuration settings.
|
// configuration settings.
|
||||||
_converse.api.settings.update({
|
_converse.api.settings.update({
|
||||||
allow_bookmarks: true,
|
allow_bookmarks: true,
|
||||||
|
allow_public_bookmarks: false,
|
||||||
hide_open_bookmarks: true
|
hide_open_bookmarks: true
|
||||||
});
|
});
|
||||||
// Promises exposed by this plugin
|
// Promises exposed by this plugin
|
||||||
@ -360,10 +367,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onBookmarksReceived (deferred, iq) {
|
createBookmarksFromStanza (stanza) {
|
||||||
const bookmarks = sizzle(
|
const bookmarks = sizzle(
|
||||||
'items[node="storage:bookmarks"] item[id="current"] storage conference',
|
'items[node="storage:bookmarks"] '+
|
||||||
iq
|
'item#current '+
|
||||||
|
'storage[xmlns="storage:bookmarks"] '+
|
||||||
|
'conference',
|
||||||
|
stanza
|
||||||
)
|
)
|
||||||
_.forEach(bookmarks, (bookmark) => {
|
_.forEach(bookmarks, (bookmark) => {
|
||||||
this.create({
|
this.create({
|
||||||
@ -373,6 +383,10 @@
|
|||||||
'nick': bookmark.querySelector('nick').textContent
|
'nick': bookmark.querySelector('nick').textContent
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onBookmarksReceived (deferred, iq) {
|
||||||
|
this.createBookmarksFromStanza(iq);
|
||||||
if (!_.isUndefined(deferred)) {
|
if (!_.isUndefined(deferred)) {
|
||||||
return deferred.resolve();
|
return deferred.resolve();
|
||||||
}
|
}
|
||||||
@ -464,7 +478,7 @@
|
|||||||
insertIntoControlBox () {
|
insertIntoControlBox () {
|
||||||
const controlboxview = _converse.chatboxviews.get('controlbox');
|
const controlboxview = _converse.chatboxviews.get('controlbox');
|
||||||
if (!_.isUndefined(controlboxview) &&
|
if (!_.isUndefined(controlboxview) &&
|
||||||
!document.body.contains(this.el)) {
|
!_converse.root.contains(this.el)) {
|
||||||
const container = controlboxview.el.querySelector('#chatrooms');
|
const container = controlboxview.el.querySelector('#chatrooms');
|
||||||
if (!_.isNull(container)) {
|
if (!_.isNull(container)) {
|
||||||
container.insertBefore(this.el, container.firstChild);
|
container.insertBefore(this.el, container.firstChild);
|
||||||
@ -520,16 +534,30 @@
|
|||||||
if (!_converse.allow_bookmarks) {
|
if (!_converse.allow_bookmarks) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Promise.all([
|
||||||
|
_converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid),
|
||||||
|
_converse.api.disco.supports(Strophe.NS.PUBSUB+'#publish-options', _converse.bare_jid)
|
||||||
|
]).then((args) => {
|
||||||
|
const identity = args[0],
|
||||||
|
options_support = args[1];
|
||||||
|
|
||||||
|
if (_.isNil(identity) || (!options_support.supported && !_converse.allow_public_bookmarks)) {
|
||||||
|
_converse.emit('bookmarksInitialized');
|
||||||
|
return;
|
||||||
|
}
|
||||||
_converse.bookmarks = new _converse.Bookmarks();
|
_converse.bookmarks = new _converse.Bookmarks();
|
||||||
_converse.bookmarks.fetchBookmarks().then(() => {
|
_converse.bookmarks.fetchBookmarks().then(() => {
|
||||||
_converse.bookmarksview = new _converse.BookmarksView(
|
_converse.bookmarksview = new _converse.BookmarksView(
|
||||||
{'model': _converse.bookmarks}
|
{'model': _converse.bookmarks}
|
||||||
);
|
);
|
||||||
})
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR))
|
||||||
.catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR))
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
_converse.emit('bookmarksInitialized');
|
_converse.emit('bookmarksInitialized');
|
||||||
});
|
});
|
||||||
|
}).catch((e) => {
|
||||||
|
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||||
|
_converse.emit('bookmarksInitialized');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
@ -538,6 +566,16 @@
|
|||||||
]).then(initBookmarks)
|
]).then(initBookmarks)
|
||||||
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
|
|
||||||
|
_converse.on('connected', () => {
|
||||||
|
// Add a handler for bookmarks pushed from other connected clients
|
||||||
|
// (from the same user obviously)
|
||||||
|
_converse.connection.addHandler((message) => {
|
||||||
|
if (message.querySelector('event[xmlns="'+Strophe.NS.PUBSUB+'#event"]')) {
|
||||||
|
_converse.bookmarks.createBookmarksFromStanza(message);
|
||||||
|
}
|
||||||
|
}, null, 'message', 'headline', null, _converse.bare_jid);
|
||||||
|
});
|
||||||
|
|
||||||
const afterReconnection = function () {
|
const afterReconnection = function () {
|
||||||
if (!_converse.allow_bookmarks) {
|
if (!_converse.allow_bookmarks) {
|
||||||
return;
|
return;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
/*global define */
|
/*global define */
|
||||||
|
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
define(["converse-core"], factory);
|
define(["converse-core", "backbone.overview"], factory);
|
||||||
}(this, function (converse) {
|
}(this, function (converse) {
|
||||||
"use strict";
|
"use strict";
|
||||||
const { Backbone, Promise, Strophe, b64_sha1, moment, utils, _ } = converse.env;
|
const { Backbone, Promise, Strophe, b64_sha1, moment, utils, _ } = converse.env;
|
||||||
@ -117,6 +117,20 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
getMessageAttributes (message, delay, original_stanza) {
|
getMessageAttributes (message, delay, original_stanza) {
|
||||||
|
/* Parses a passed in message stanza and returns an object
|
||||||
|
* of attributes.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (XMLElement) message - The message stanza
|
||||||
|
* (XMLElement) delay - The <delay> node from the
|
||||||
|
* stanza, if there was one.
|
||||||
|
* (XMLElement) original_stanza - The original stanza,
|
||||||
|
* that contains the message stanza, if it was
|
||||||
|
* contained, otherwise it's the message stanza itself.
|
||||||
|
*/
|
||||||
|
const { _converse } = this.__super__,
|
||||||
|
{ __ } = _converse;
|
||||||
|
|
||||||
delay = delay || message.querySelector('delay');
|
delay = delay || message.querySelector('delay');
|
||||||
const type = message.getAttribute('type'),
|
const type = message.getAttribute('type'),
|
||||||
body = this.getMessageBody(message);
|
body = this.getMessageBody(message);
|
||||||
@ -144,7 +158,8 @@
|
|||||||
sender = 'them';
|
sender = 'them';
|
||||||
fullname = this.get('fullname') || from;
|
fullname = this.get('fullname') || from;
|
||||||
}
|
}
|
||||||
return {
|
const spoiler = message.querySelector(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`);
|
||||||
|
const attrs = {
|
||||||
'type': type,
|
'type': type,
|
||||||
'chat_state': chat_state,
|
'chat_state': chat_state,
|
||||||
'delayed': delayed,
|
'delayed': delayed,
|
||||||
@ -152,11 +167,19 @@
|
|||||||
'message': body || undefined,
|
'message': body || undefined,
|
||||||
'msgid': message.getAttribute('id'),
|
'msgid': message.getAttribute('id'),
|
||||||
'sender': sender,
|
'sender': sender,
|
||||||
'time': time
|
'time': time,
|
||||||
|
'is_spoiler': !_.isNull(spoiler)
|
||||||
};
|
};
|
||||||
|
if (spoiler) {
|
||||||
|
attrs.spoiler_hint = spoiler.textContent.length > 0 ? spoiler.textContent : '';
|
||||||
|
}
|
||||||
|
return attrs;
|
||||||
},
|
},
|
||||||
|
|
||||||
createMessage (message, delay, original_stanza) {
|
createMessage (message, delay, original_stanza) {
|
||||||
|
/* Create a Backbone.Message object inside this chat box
|
||||||
|
* based on the identified message stanza.
|
||||||
|
*/
|
||||||
return this.messages.create(this.getMessageAttributes.apply(this, arguments));
|
return this.messages.create(this.getMessageAttributes.apply(this, arguments));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -257,6 +280,9 @@
|
|||||||
onMessage (message) {
|
onMessage (message) {
|
||||||
/* Handler method for all incoming single-user chat "message"
|
/* Handler method for all incoming single-user chat "message"
|
||||||
* stanzas.
|
* stanzas.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (XMLElement) message - The incoming message stanza
|
||||||
*/
|
*/
|
||||||
let contact_jid, delay, resource,
|
let contact_jid, delay, resource,
|
||||||
from_jid = message.getAttribute('from'),
|
from_jid = message.getAttribute('from'),
|
||||||
@ -272,7 +298,7 @@
|
|||||||
Strophe.LogLevel.INFO
|
Strophe.LogLevel.INFO
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} else if (utils.isHeadlineMessage(message)) {
|
} else if (utils.isHeadlineMessage(_converse, message)) {
|
||||||
// XXX: Ideally we wouldn't have to check for headline
|
// XXX: Ideally we wouldn't have to check for headline
|
||||||
// messages, but Prosody sends headline messages with the
|
// messages, but Prosody sends headline messages with the
|
||||||
// wrong type ('chat'), so we need to filter them out here.
|
// wrong type ('chat'), so we need to filter them out here.
|
||||||
@ -392,17 +418,21 @@
|
|||||||
* If the #conversejs element doesn't exist, create it.
|
* If the #conversejs element doesn't exist, create it.
|
||||||
*/
|
*/
|
||||||
if (!this.el) {
|
if (!this.el) {
|
||||||
let el = document.querySelector('#conversejs');
|
let el = _converse.root.querySelector('#conversejs');
|
||||||
if (_.isNull(el)) {
|
if (_.isNull(el)) {
|
||||||
el = document.createElement('div');
|
el = document.createElement('div');
|
||||||
el.setAttribute('id', 'conversejs');
|
el.setAttribute('id', 'conversejs');
|
||||||
|
const body = _converse.root.querySelector('body');
|
||||||
|
if (body) {
|
||||||
|
body.appendChild(el);
|
||||||
|
} else {
|
||||||
|
// Perhaps inside a web component?
|
||||||
|
_converse.root.appendChild(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_.includes(['mobile', 'fullscreen'], _converse.view_mode)) {
|
if (_.includes(['mobile', 'fullscreen'], _converse.view_mode)) {
|
||||||
el.classList.add('fullscreen');
|
el.classList.add('fullscreen');
|
||||||
}
|
}
|
||||||
// Converse.js expects a <body> tag to be present.
|
|
||||||
document.querySelector('body').appendChild(el);
|
|
||||||
|
|
||||||
}
|
|
||||||
el.innerHTML = '';
|
el.innerHTML = '';
|
||||||
this.setElement(el, false);
|
this.setElement(el, false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,12 +15,15 @@
|
|||||||
"tpl!action",
|
"tpl!action",
|
||||||
"tpl!chatbox",
|
"tpl!chatbox",
|
||||||
"tpl!chatbox_head",
|
"tpl!chatbox_head",
|
||||||
|
"tpl!chatbox_message_form",
|
||||||
"tpl!emojis",
|
"tpl!emojis",
|
||||||
"tpl!help_message",
|
"tpl!help_message",
|
||||||
"tpl!info",
|
"tpl!info",
|
||||||
"tpl!message",
|
"tpl!message",
|
||||||
"tpl!new_day",
|
"tpl!new_day",
|
||||||
"tpl!spinner",
|
"tpl!spinner",
|
||||||
|
"tpl!spoiler_button",
|
||||||
|
"tpl!spoiler_message",
|
||||||
"tpl!toolbar"
|
"tpl!toolbar"
|
||||||
], factory);
|
], factory);
|
||||||
}(this, function (
|
}(this, function (
|
||||||
@ -31,16 +34,19 @@
|
|||||||
tpl_action,
|
tpl_action,
|
||||||
tpl_chatbox,
|
tpl_chatbox,
|
||||||
tpl_chatbox_head,
|
tpl_chatbox_head,
|
||||||
|
tpl_chatbox_message_form,
|
||||||
tpl_emojis,
|
tpl_emojis,
|
||||||
tpl_help_message,
|
tpl_help_message,
|
||||||
tpl_info,
|
tpl_info,
|
||||||
tpl_message,
|
tpl_message,
|
||||||
tpl_new_day,
|
tpl_new_day,
|
||||||
tpl_spinner,
|
tpl_spinner,
|
||||||
|
tpl_spoiler_button,
|
||||||
|
tpl_spoiler_message,
|
||||||
tpl_toolbar
|
tpl_toolbar
|
||||||
) {
|
) {
|
||||||
"use strict";
|
"use strict";
|
||||||
const { $msg, Backbone, Strophe, _, b64_sha1, sizzle, moment } = converse.env;
|
const { $msg, Backbone, Promise, Strophe, _, b64_sha1, f, sizzle, moment } = converse.env;
|
||||||
const u = converse.env.utils;
|
const u = converse.env.utils;
|
||||||
const KEY = {
|
const KEY = {
|
||||||
ENTER: 13,
|
ENTER: 13,
|
||||||
@ -58,7 +64,7 @@
|
|||||||
*
|
*
|
||||||
* 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-chatboxes"],
|
dependencies: ["converse-chatboxes", "converse-disco"],
|
||||||
|
|
||||||
overrides: {
|
overrides: {
|
||||||
// Overrides mentioned here will be picked up by converse.js's
|
// Overrides mentioned here will be picked up by converse.js's
|
||||||
@ -68,15 +74,16 @@
|
|||||||
// New functions which don't exist yet can also be added.
|
// New functions which don't exist yet can also be added.
|
||||||
//
|
//
|
||||||
registerGlobalEventHandlers: function () {
|
registerGlobalEventHandlers: function () {
|
||||||
|
const { _converse } = this.__super__;
|
||||||
this.__super__.registerGlobalEventHandlers();
|
this.__super__.registerGlobalEventHandlers();
|
||||||
document.addEventListener(
|
_converse.root.addEventListener(
|
||||||
'click', function (ev) {
|
'click', function (ev) {
|
||||||
if (_.includes(ev.target.classList, 'toggle-toolbar-menu') ||
|
if (_.includes(ev.target.classList, 'toggle-toolbar-menu') ||
|
||||||
_.includes(ev.target.classList, 'insert-emoji')) {
|
_.includes(ev.target.classList, 'insert-emoji')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
u.slideInAllElements(
|
u.slideInAllElements(
|
||||||
document.querySelectorAll('.toolbar-menu')
|
_converse.root.querySelectorAll('.toolbar-menu')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -113,9 +120,10 @@
|
|||||||
'show_message_load_animation': false,
|
'show_message_load_animation': false,
|
||||||
'time_format': 'HH:mm',
|
'time_format': 'HH:mm',
|
||||||
'visible_toolbar_buttons': {
|
'visible_toolbar_buttons': {
|
||||||
'emoji': true,
|
|
||||||
'call': false,
|
'call': false,
|
||||||
'clear': true
|
'clear': true,
|
||||||
|
'emoji': true,
|
||||||
|
'spoiler': true
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
emojione.imagePathPNG = _converse.emojione_image_path;
|
emojione.imagePathPNG = _converse.emojione_image_path;
|
||||||
@ -201,7 +209,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
setScrollPosition (ev) {
|
setScrollPosition (ev) {
|
||||||
this.model.save('scroll_position', ev.target.scrollTop);
|
this.model.save('scroll_position', this.content);
|
||||||
},
|
},
|
||||||
|
|
||||||
chooseSkinTone (ev) {
|
chooseSkinTone (ev) {
|
||||||
@ -258,6 +266,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
_converse.ChatBoxView = Backbone.NativeView.extend({
|
_converse.ChatBoxView = Backbone.NativeView.extend({
|
||||||
length: 200,
|
length: 200,
|
||||||
className: 'chatbox hidden',
|
className: 'chatbox hidden',
|
||||||
@ -265,13 +274,15 @@
|
|||||||
|
|
||||||
events: {
|
events: {
|
||||||
'click .close-chatbox-button': 'close',
|
'click .close-chatbox-button': 'close',
|
||||||
'keypress .chat-textarea': 'keyPressed',
|
'click .new-msgs-indicator': 'viewUnreadMessages',
|
||||||
'click .send-button': 'onFormSubmitted',
|
'click .send-button': 'onFormSubmitted',
|
||||||
'click .toggle-smiley': 'toggleEmojiMenu',
|
|
||||||
'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
|
|
||||||
'click .toggle-clear': 'clearMessages',
|
|
||||||
'click .toggle-call': 'toggleCall',
|
'click .toggle-call': 'toggleCall',
|
||||||
'click .new-msgs-indicator': 'viewUnreadMessages'
|
'click .toggle-clear': 'clearMessages',
|
||||||
|
'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
|
||||||
|
'click .toggle-smiley': 'toggleEmojiMenu',
|
||||||
|
'click .toggle-spoiler': 'toggleSpoilerMessage',
|
||||||
|
'click .toggle-compose-spoiler': 'toggleComposeSpoilerMessage',
|
||||||
|
'keypress .chat-textarea': 'keyPressed'
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize () {
|
initialize () {
|
||||||
@ -286,8 +297,8 @@
|
|||||||
this.model.on('change:chat_status', this.onChatStatusChanged, this);
|
this.model.on('change:chat_status', this.onChatStatusChanged, this);
|
||||||
this.model.on('showHelpMessages', this.showHelpMessages, this);
|
this.model.on('showHelpMessages', this.showHelpMessages, this);
|
||||||
this.model.on('sendMessage', this.sendMessage, this);
|
this.model.on('sendMessage', this.sendMessage, this);
|
||||||
|
this.render();
|
||||||
this.render().renderToolbar().insertHeading().fetchMessages();
|
this.fetchMessages();
|
||||||
_converse.emit('chatBoxOpened', this);
|
_converse.emit('chatBoxOpened', this);
|
||||||
_converse.emit('chatBoxInitialized', this);
|
_converse.emit('chatBoxInitialized', this);
|
||||||
},
|
},
|
||||||
@ -296,18 +307,80 @@
|
|||||||
this.el.setAttribute('id', this.model.get('box_id'));
|
this.el.setAttribute('id', this.model.get('box_id'));
|
||||||
this.el.innerHTML = tpl_chatbox(
|
this.el.innerHTML = tpl_chatbox(
|
||||||
_.extend(this.model.toJSON(), {
|
_.extend(this.model.toJSON(), {
|
||||||
label_personal_message: __('Personal message'),
|
|
||||||
label_send: __('Send'),
|
|
||||||
show_send_button: _converse.show_send_button,
|
|
||||||
show_textarea: true,
|
|
||||||
show_toolbar: _converse.show_toolbar,
|
|
||||||
unread_msgs: __('You have unread messages')
|
unread_msgs: __('You have unread messages')
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
this.content = this.el.querySelector('.chat-content');
|
this.content = this.el.querySelector('.chat-content');
|
||||||
|
this.renderMessageForm();
|
||||||
|
this.insertHeading();
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderToolbar (toolbar, options) {
|
||||||
|
if (!_converse.show_toolbar) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
toolbar = toolbar || tpl_toolbar;
|
||||||
|
options = _.assign(
|
||||||
|
this.model.toJSON(),
|
||||||
|
this.getToolbarOptions(options || {})
|
||||||
|
);
|
||||||
|
this.el.querySelector('.chat-toolbar').innerHTML = toolbar(options);
|
||||||
|
this.addSpoilerButton(options);
|
||||||
|
this.insertEmojiPicker();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderMessageForm () {
|
||||||
|
let placeholder;
|
||||||
|
if (this.model.get('composing_spoiler')) {
|
||||||
|
placeholder = __('Hidden message');
|
||||||
|
} else {
|
||||||
|
placeholder = __('Personal message');
|
||||||
|
}
|
||||||
|
const form_container = this.el.querySelector('.message-form-container');
|
||||||
|
form_container.innerHTML = tpl_chatbox_message_form(
|
||||||
|
_.extend(this.model.toJSON(), {
|
||||||
|
'hint_value': _.get(this.el.querySelector('.spoiler-hint'), 'value'),
|
||||||
|
'label_personal_message': placeholder,
|
||||||
|
'label_send': __('Send'),
|
||||||
|
'label_spoiler_hint': __('Optional hint'),
|
||||||
|
'message_value': _.get(this.el.querySelector('.chat-textarea'), 'value'),
|
||||||
|
'show_send_button': _converse.show_send_button,
|
||||||
|
'show_toolbar': _converse.show_toolbar,
|
||||||
|
'unread_msgs': __('You have unread messages')
|
||||||
|
}));
|
||||||
|
this.renderToolbar();
|
||||||
|
},
|
||||||
|
|
||||||
|
addSpoilerButton (options) {
|
||||||
|
/* Asynchronously adds a button for writing spoiler
|
||||||
|
* messages, based on whether the contact's client supports
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
if (!options.show_spoiler_button || this.model.get('type') === 'chatroom') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const contact_jid = this.model.get('jid');
|
||||||
|
const resources = this.model.get('resources');
|
||||||
|
if (_.isEmpty(resources)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Promise.all(_.map(_.keys(resources), (resource) =>
|
||||||
|
_converse.api.disco.supports(Strophe.NS.SPOILER, `${contact_jid}/${resource}`)
|
||||||
|
)).then((results) => {
|
||||||
|
const supported = _.every(f.map(f.get('supported'))(results));
|
||||||
|
if (supported) {
|
||||||
|
const html = tpl_spoiler_button(this.model.toJSON());
|
||||||
|
if (_converse.visible_toolbar_buttons.emoji) {
|
||||||
|
this.el.querySelector('.toggle-smiley').insertAdjacentHTML('afterEnd', html);
|
||||||
|
} else {
|
||||||
|
this.el.querySelector('.chat-toolbar').insertAdjacentHTML('afterBegin', html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
insertHeading () {
|
insertHeading () {
|
||||||
this.heading = new _converse.ChatBoxHeading({'model': this.model});
|
this.heading = new _converse.ChatBoxHeading({'model': this.model});
|
||||||
this.heading.render();
|
this.heading.render();
|
||||||
@ -318,13 +391,22 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
createEmojiPicker () {
|
getToolbarOptions (options) {
|
||||||
if (_.isUndefined(_converse.emojipicker)) {
|
let label_toggle_spoiler;
|
||||||
_converse.emojipicker = new _converse.EmojiPicker();
|
if (this.model.get('composing_spoiler')) {
|
||||||
_converse.emojipicker.fetch();
|
label_toggle_spoiler = __('Click to write as a normal (non-spoiler) message');
|
||||||
|
} else {
|
||||||
|
label_toggle_spoiler = __('Click to write your message as a spoiler');
|
||||||
}
|
}
|
||||||
this.emoji_picker_view = new _converse.EmojiPickerView({
|
return _.extend(options || {}, {
|
||||||
'model': _converse.emojipicker
|
'label_clear': __('Clear all messages'),
|
||||||
|
'label_insert_smiley': __('Insert a smiley'),
|
||||||
|
'label_start_call': __('Start a call'),
|
||||||
|
'label_toggle_spoiler': label_toggle_spoiler,
|
||||||
|
'show_call_button': _converse.visible_toolbar_buttons.call,
|
||||||
|
'show_clear_button': _converse.visible_toolbar_buttons.clear,
|
||||||
|
'show_spoiler_button': _converse.visible_toolbar_buttons.spoiler,
|
||||||
|
'use_emoji': _converse.visible_toolbar_buttons.emoji,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -349,7 +431,7 @@
|
|||||||
* as well as src/converse-muc.js (if those plugins are
|
* as well as src/converse-muc.js (if those plugins are
|
||||||
* enabled).
|
* enabled).
|
||||||
*/
|
*/
|
||||||
const container = document.querySelector('#conversejs');
|
const container = _converse.root.querySelector('#conversejs');
|
||||||
if (this.el.parentNode !== container) {
|
if (this.el.parentNode !== container) {
|
||||||
container.insertBefore(this.el, container.firstChild);
|
container.insertBefore(this.el, container.firstChild);
|
||||||
}
|
}
|
||||||
@ -510,14 +592,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getExtraMessageTemplateAttributes () {
|
getExtraMessageTemplateAttributes (attrs) {
|
||||||
/* Provides a hook for sending more attributes to the
|
/* Provides a hook for sending more attributes to the
|
||||||
* message template.
|
* message template.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* (Object) attrs: An object containing message attributes.
|
* (Object) attrs: An object containing message attributes.
|
||||||
*/
|
*/
|
||||||
return {};
|
if (attrs.is_spoiler) {
|
||||||
|
return {'label_show': __('Show hidden message')};
|
||||||
|
} else {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getExtraMessageClasses (attrs) {
|
getExtraMessageClasses (attrs) {
|
||||||
@ -528,6 +614,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderSpoilerMessage (msg, attrs) {
|
||||||
|
/* Render a "spoiler" message, as defined in XEP-0382
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (HTMLElement) msg: The chat message DOM element
|
||||||
|
* (Object) attrs: An object containing the message attributes.
|
||||||
|
*/
|
||||||
|
const hint = msg.querySelector('.spoiler-hint');
|
||||||
|
hint.appendChild(document.createTextNode(attrs.spoiler_hint || ''));
|
||||||
|
},
|
||||||
|
|
||||||
renderMessage (attrs) {
|
renderMessage (attrs) {
|
||||||
/* Renders a chat message based on the passed in attributes.
|
/* Renders a chat message based on the passed in attributes.
|
||||||
*
|
*
|
||||||
@ -551,6 +648,8 @@
|
|||||||
} else {
|
} else {
|
||||||
username = attrs.fullname;
|
username = attrs.fullname;
|
||||||
}
|
}
|
||||||
|
} else if (attrs.is_spoiler) {
|
||||||
|
template = tpl_spoiler_message;
|
||||||
} else {
|
} else {
|
||||||
template = tpl_message;
|
template = tpl_message;
|
||||||
username = attrs.sender === 'me' && __('me') || fullname;
|
username = attrs.sender === 'me' && __('me') || fullname;
|
||||||
@ -568,12 +667,16 @@
|
|||||||
})
|
})
|
||||||
));
|
));
|
||||||
if (_converse.show_message_load_animation) {
|
if (_converse.show_message_load_animation) {
|
||||||
window.setTimeout(_.partial(u.removeClass, 'onload', msg), 2000);
|
window.setTimeout(
|
||||||
|
_.partial(u.removeClass, 'onload', msg), 2000);
|
||||||
}
|
}
|
||||||
const msg_content = msg.querySelector('.chat-msg-content');
|
const msg_content = msg.querySelector('.chat-msg-content');
|
||||||
msg_content.innerHTML = u.addEmoji(
|
msg_content.innerHTML = u.addEmoji(
|
||||||
_converse, emojione, u.addHyperlinks(xss.filterXSS(text, {'whiteList': {}}))
|
_converse, emojione, u.addHyperlinks(xss.filterXSS(text, {'whiteList': {}}))
|
||||||
);
|
);
|
||||||
|
if (attrs.is_spoiler) {
|
||||||
|
this.renderSpoilerMessage(msg, attrs)
|
||||||
|
}
|
||||||
u.renderImageURLs(msg_content).then(this.scrollDown.bind(this));
|
u.renderImageURLs(msg_content).then(this.scrollDown.bind(this));
|
||||||
return msg;
|
return msg;
|
||||||
},
|
},
|
||||||
@ -688,13 +791,22 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
createMessageStanza (message) {
|
createMessageStanza (message) {
|
||||||
return $msg({
|
const stanza = $msg({
|
||||||
from: _converse.connection.jid,
|
'from': _converse.connection.jid,
|
||||||
to: this.model.get('jid'),
|
'to': this.model.get('jid'),
|
||||||
type: 'chat',
|
'type': 'chat',
|
||||||
id: message.get('msgid')
|
'id': message.get('msgid')
|
||||||
}).c('body').t(message.get('message')).up()
|
}).c('body').t(message.get('message')).up()
|
||||||
.c(_converse.ACTIVE, {'xmlns': Strophe.NS.CHATSTATES}).up();
|
.c(_converse.ACTIVE, {'xmlns': Strophe.NS.CHATSTATES}).up();
|
||||||
|
|
||||||
|
if (message.get('is_spoiler')) {
|
||||||
|
if (message.get('spoiler_hint')) {
|
||||||
|
stanza.c('spoiler', {'xmlns': Strophe.NS.SPOILER }, message.get('spoiler_hint'));
|
||||||
|
} else {
|
||||||
|
stanza.c('spoiler', {'xmlns': Strophe.NS.SPOILER });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stanza;
|
||||||
},
|
},
|
||||||
|
|
||||||
sendMessage (message) {
|
sendMessage (message) {
|
||||||
@ -714,31 +826,19 @@
|
|||||||
.c('forwarded', {'xmlns': Strophe.NS.FORWARD})
|
.c('forwarded', {'xmlns': Strophe.NS.FORWARD})
|
||||||
.c('delay', {
|
.c('delay', {
|
||||||
'xmns': Strophe.NS.DELAY,
|
'xmns': Strophe.NS.DELAY,
|
||||||
'stamp': moment.format()
|
'stamp': moment().format()
|
||||||
}).up()
|
}).up()
|
||||||
.cnode(messageStanza.tree())
|
.cnode(messageStanza.tree())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onMessageSubmitted (text) {
|
parseMessageForCommands (text) {
|
||||||
/* This method gets called once the user has typed a message
|
|
||||||
* and then pressed enter in a chat box.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* (string) text - The chat message text.
|
|
||||||
*/
|
|
||||||
if (!_converse.connection.authenticated) {
|
|
||||||
return this.showHelpMessages(
|
|
||||||
['Sorry, the connection has been lost, '+
|
|
||||||
'and your message could not be sent'],
|
|
||||||
'error'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/);
|
const match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/);
|
||||||
if (match) {
|
if (match) {
|
||||||
if (match[1] === "clear") {
|
if (match[1] === "clear") {
|
||||||
return this.clearMessages();
|
this.clearMessages();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (match[1] === "help") {
|
else if (match[1] === "help") {
|
||||||
const msgs = [
|
const msgs = [
|
||||||
@ -747,21 +847,54 @@
|
|||||||
`<strong>/help</strong>: ${__('Show this menu')}`
|
`<strong>/help</strong>: ${__('Show this menu')}`
|
||||||
];
|
];
|
||||||
this.showHelpMessages(msgs);
|
this.showHelpMessages(msgs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onMessageSubmitted (text, spoiler_hint) {
|
||||||
|
/* This method gets called once the user has typed a message
|
||||||
|
* and then pressed enter in a chat box.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (String) text - The chat message text.
|
||||||
|
* (String) spoiler_hint - A hint in case the message
|
||||||
|
* text is a hidden/spoiler message. See XEP-0382
|
||||||
|
*/
|
||||||
|
if (!_converse.connection.authenticated) {
|
||||||
|
return this.showHelpMessages(
|
||||||
|
['Sorry, the connection has been lost, '+
|
||||||
|
'and your message could not be sent'],
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.parseMessageForCommands(text)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
const attrs = this.getOutgoingMessageAttributes(text, spoiler_hint)
|
||||||
let fullname = _converse.xmppstatus.get('fullname');
|
const message = this.model.messages.create(attrs);
|
||||||
fullname = _.isEmpty(fullname)? _converse.bare_jid: fullname;
|
|
||||||
|
|
||||||
const message = this.model.messages.create({
|
|
||||||
fullname,
|
|
||||||
sender: 'me',
|
|
||||||
time: moment().format(),
|
|
||||||
message: emojione.shortnameToUnicode(text)
|
|
||||||
});
|
|
||||||
this.sendMessage(message);
|
this.sendMessage(message);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getOutgoingMessageAttributes (text, spoiler_hint) {
|
||||||
|
/* Overridable method which returns the attributes to be
|
||||||
|
* passed to Backbone.Message's constructor.
|
||||||
|
*/
|
||||||
|
const fullname = _converse.xmppstatus.get('fullname'),
|
||||||
|
is_spoiler = this.model.get('composing_spoiler'),
|
||||||
|
attrs = {
|
||||||
|
'fullname': _.isEmpty(fullname) ? _converse.bare_jid : fullname,
|
||||||
|
'sender': 'me',
|
||||||
|
'time': moment().format(),
|
||||||
|
'message': emojione.shortnameToUnicode(text),
|
||||||
|
'is_spoiler': is_spoiler
|
||||||
|
};
|
||||||
|
if (is_spoiler) {
|
||||||
|
attrs.spoiler_hint = spoiler_hint;
|
||||||
|
}
|
||||||
|
return attrs;
|
||||||
|
},
|
||||||
|
|
||||||
sendChatState () {
|
sendChatState () {
|
||||||
/* Sends a message with the status of the user in this chat session
|
/* Sends a message with the status of the user in this chat session
|
||||||
* as taken from the 'chat_state' attribute of the chat box.
|
* as taken from the 'chat_state' attribute of the chat box.
|
||||||
@ -814,10 +947,17 @@
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const textarea = this.el.querySelector('.chat-textarea'),
|
const textarea = this.el.querySelector('.chat-textarea'),
|
||||||
message = textarea.value;
|
message = textarea.value;
|
||||||
|
|
||||||
|
let spoiler_hint;
|
||||||
|
if (this.model.get('composing_spoiler')) {
|
||||||
|
const hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint');
|
||||||
|
spoiler_hint = hint_el.value;
|
||||||
|
hint_el.value = '';
|
||||||
|
}
|
||||||
textarea.value = '';
|
textarea.value = '';
|
||||||
textarea.focus();
|
textarea.focus();
|
||||||
if (message !== '') {
|
if (message !== '') {
|
||||||
this.onMessageSubmitted(message);
|
this.onMessageSubmitted(message, spoiler_hint);
|
||||||
_converse.emit('messageSend', message);
|
_converse.emit('messageSend', message);
|
||||||
}
|
}
|
||||||
this.setChatState(_converse.ACTIVE);
|
this.setChatState(_converse.ACTIVE);
|
||||||
@ -856,6 +996,16 @@
|
|||||||
textbox_el.focus()
|
textbox_el.focus()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createEmojiPicker () {
|
||||||
|
if (_.isUndefined(_converse.emojipicker)) {
|
||||||
|
_converse.emojipicker = new _converse.EmojiPicker();
|
||||||
|
_converse.emojipicker.fetch();
|
||||||
|
}
|
||||||
|
this.emoji_picker_view = new _converse.EmojiPickerView({
|
||||||
|
'model': _converse.emojipicker
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
insertEmoji (ev) {
|
insertEmoji (ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const target = ev.target.nodeName === 'IMG' ? ev.target.parentElement : ev.target;
|
const target = ev.target.nodeName === 'IMG' ? ev.target.parentElement : ev.target;
|
||||||
@ -875,7 +1025,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const elements = _.difference(
|
const elements = _.difference(
|
||||||
document.querySelectorAll('.toolbar-menu'),
|
_converse.root.querySelectorAll('.toolbar-menu'),
|
||||||
[this.emoji_picker_view.el]
|
[this.emoji_picker_view.el]
|
||||||
);
|
);
|
||||||
u.slideInAllElements(elements)
|
u.slideInAllElements(elements)
|
||||||
@ -893,6 +1043,33 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleComposeSpoilerMessage () {
|
||||||
|
this.model.set('composing_spoiler', !this.model.get('composing_spoiler'));
|
||||||
|
this.renderMessageForm();
|
||||||
|
this.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleSpoilerMessage (ev) {
|
||||||
|
if (ev && ev.preventDefault) {
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
const toggle_el = ev.target;
|
||||||
|
u.slideToggleElement(
|
||||||
|
toggle_el.parentElement.querySelector('.spoiler')
|
||||||
|
);
|
||||||
|
if (toggle_el.getAttribute("data-toggle-state") == "closed") {
|
||||||
|
toggle_el.textContent = __('Hide hidden message');
|
||||||
|
toggle_el.classList.remove("icon-eye");
|
||||||
|
toggle_el.classList.add("icon-eye-blocked");
|
||||||
|
toggle_el.setAttribute("data-toggle-state", "open");
|
||||||
|
} else {
|
||||||
|
toggle_el.textContent = __('Show hidden message');
|
||||||
|
toggle_el.classList.remove("icon-eye-blocked");
|
||||||
|
toggle_el.classList.add("icon-eye");
|
||||||
|
toggle_el.setAttribute("data-toggle-state", "closed");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
onChatStatusChanged (item) {
|
onChatStatusChanged (item) {
|
||||||
const chat_status = item.get('chat_status');
|
const chat_status = item.get('chat_status');
|
||||||
let fullname = item.get('fullname');
|
let fullname = item.get('fullname');
|
||||||
@ -931,33 +1108,16 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
getToolbarOptions (options) {
|
|
||||||
return _.extend(options || {}, {
|
|
||||||
'label_clear': __('Clear all messages'),
|
|
||||||
'label_insert_smiley': __('Insert a smiley'),
|
|
||||||
'label_start_call': __('Start a call'),
|
|
||||||
'show_call_button': _converse.visible_toolbar_buttons.call,
|
|
||||||
'show_clear_button': _converse.visible_toolbar_buttons.clear,
|
|
||||||
'use_emoji': _converse.visible_toolbar_buttons.emoji,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
renderToolbar (toolbar, options) {
|
|
||||||
if (!_converse.show_toolbar) { return; }
|
|
||||||
toolbar = toolbar || tpl_toolbar;
|
|
||||||
options = _.assign(
|
|
||||||
this.model.toJSON(),
|
|
||||||
this.getToolbarOptions(options || {})
|
|
||||||
);
|
|
||||||
this.el.querySelector('.chat-toolbar').innerHTML = toolbar(options);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
renderEmojiPicker () {
|
renderEmojiPicker () {
|
||||||
var toggle = this.el.querySelector('.toggle-smiley');
|
this.emoji_picker_view.render();
|
||||||
toggle.innerHTML = '';
|
},
|
||||||
toggle.appendChild(this.emoji_picker_view.render().el);
|
|
||||||
|
insertEmojiPicker () {
|
||||||
|
var picker_el = this.el.querySelector('.emoji-picker');
|
||||||
|
if (!_.isNull(picker_el)) {
|
||||||
|
picker_el.innerHTML = '';
|
||||||
|
picker_el.appendChild(this.emoji_picker_view.el);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
focus () {
|
focus () {
|
||||||
@ -976,11 +1136,12 @@
|
|||||||
|
|
||||||
afterShown (focus) {
|
afterShown (focus) {
|
||||||
if (u.isPersistableModel(this.model)) {
|
if (u.isPersistableModel(this.model)) {
|
||||||
|
this.model.clearUnreadMsgCounter();
|
||||||
this.model.save();
|
this.model.save();
|
||||||
}
|
}
|
||||||
this.setChatState(_converse.ACTIVE);
|
this.setChatState(_converse.ACTIVE);
|
||||||
this.renderEmojiPicker();
|
|
||||||
this.scrollDown();
|
this.scrollDown();
|
||||||
|
this.renderEmojiPicker();
|
||||||
if (focus) {
|
if (focus) {
|
||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
@ -992,11 +1153,7 @@
|
|||||||
if (focus) { this.focus(); }
|
if (focus) { this.focus(); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const that = this;
|
u.fadeIn(this.el, _.bind(this.afterShown, this, focus));
|
||||||
u.fadeIn(this.el, function () {
|
|
||||||
that.afterShown();
|
|
||||||
if (focus) { that.focus(); }
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
show (focus) {
|
show (focus) {
|
||||||
@ -1077,6 +1234,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
_converse.on('connected', () => {
|
||||||
|
// Advertise that we support XEP-0382 Message Spoilers
|
||||||
|
_converse.connection.disco.addFeature(Strophe.NS.SPOILER);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -115,12 +115,15 @@
|
|||||||
|
|
||||||
clearSession () {
|
clearSession () {
|
||||||
this.__super__.clearSession.apply(this, arguments);
|
this.__super__.clearSession.apply(this, arguments);
|
||||||
const controlbox = this.chatboxes.get('controlbox');
|
const chatboxes = _.get(this, 'chatboxes', null);
|
||||||
|
if (!_.isNil(chatboxes)) {
|
||||||
|
const controlbox = chatboxes.get('controlbox');
|
||||||
if (controlbox &&
|
if (controlbox &&
|
||||||
controlbox.collection &&
|
controlbox.collection &&
|
||||||
controlbox.collection.browserStorage) {
|
controlbox.collection.browserStorage) {
|
||||||
controlbox.save({'connected': false});
|
controlbox.save({'connected': false});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ChatBoxes: {
|
ChatBoxes: {
|
||||||
@ -423,8 +426,8 @@
|
|||||||
const tab = ev.target,
|
const tab = ev.target,
|
||||||
sibling_li = tab.parentNode.nextElementSibling || tab.parentNode.previousElementSibling,
|
sibling_li = tab.parentNode.nextElementSibling || tab.parentNode.previousElementSibling,
|
||||||
sibling = sibling_li.firstChild,
|
sibling = sibling_li.firstChild,
|
||||||
sibling_panel = document.querySelector(sibling.getAttribute('href')),
|
sibling_panel = _converse.root.querySelector(sibling.getAttribute('href')),
|
||||||
tab_panel = document.querySelector(tab.getAttribute('href'));
|
tab_panel = _converse.root.querySelector(tab.getAttribute('href'));
|
||||||
|
|
||||||
u.hideElement(sibling_panel);
|
u.hideElement(sibling_panel);
|
||||||
u.removeClass('current', sibling);
|
u.removeClass('current', sibling);
|
||||||
@ -448,6 +451,8 @@
|
|||||||
|
|
||||||
_converse.LoginPanelModel = Backbone.Model.extend({
|
_converse.LoginPanelModel = Backbone.Model.extend({
|
||||||
defaults: {
|
defaults: {
|
||||||
|
// Passed-by-reference. Fine in this case because there's
|
||||||
|
// only one such model.
|
||||||
'errors': [],
|
'errors': [],
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -594,6 +599,9 @@
|
|||||||
|
|
||||||
renderTab () {
|
renderTab () {
|
||||||
const controlbox = _converse.chatboxes.get('controlbox');
|
const controlbox = _converse.chatboxes.get('controlbox');
|
||||||
|
if (_.isNil(controlbox)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const chats = fp.filter(_.partial(u.isOfType, CHATBOX_TYPE), _converse.chatboxes.models);
|
const chats = fp.filter(_.partial(u.isOfType, CHATBOX_TYPE), _converse.chatboxes.models);
|
||||||
this.tab_el.innerHTML = tpl_contacts_tab({
|
this.tab_el.innerHTML = tpl_contacts_tab({
|
||||||
'label_contacts': LABEL_CONTACTS,
|
'label_contacts': LABEL_CONTACTS,
|
||||||
@ -648,7 +656,7 @@
|
|||||||
xhr.onload = function () {
|
xhr.onload = function () {
|
||||||
if (xhr.status >= 200 && xhr.status < 400) {
|
if (xhr.status >= 200 && xhr.status < 400) {
|
||||||
const data = JSON.parse(xhr.responseText),
|
const data = JSON.parse(xhr.responseText),
|
||||||
ul = document.querySelector('.search-xmpp ul');
|
ul = _converse.root.querySelector('.search-xmpp ul');
|
||||||
u.removeElement(ul.querySelector('li.found-user'));
|
u.removeElement(ul.querySelector('li.found-user'));
|
||||||
u.removeElement(ul.querySelector('li.chat-info'));
|
u.removeElement(ul.querySelector('li.chat-info'));
|
||||||
if (!data.length) {
|
if (!data.length) {
|
||||||
@ -682,7 +690,7 @@
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const input = ev.target.querySelector('input');
|
const input = ev.target.querySelector('input');
|
||||||
const jid = input.value;
|
const jid = input.value;
|
||||||
if (!jid || _.filter(jid.split('@')).length < 2) {
|
if (!jid || _.compact(jid.split('@')).length < 2) {
|
||||||
this.el.querySelector('.search-xmpp div').innerHTML =
|
this.el.querySelector('.search-xmpp div').innerHTML =
|
||||||
this.generateAddContactHTML({
|
this.generateAddContactHTML({
|
||||||
error_message: __('Please enter a valid XMPP address'),
|
error_message: __('Please enter a valid XMPP address'),
|
||||||
@ -761,7 +769,7 @@
|
|||||||
|
|
||||||
onClick (e) {
|
onClick (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (u.isVisible(document.querySelector("#controlbox"))) {
|
if (u.isVisible(_converse.root.querySelector("#controlbox"))) {
|
||||||
const controlbox = _converse.chatboxes.get('controlbox');
|
const controlbox = _converse.chatboxes.get('controlbox');
|
||||||
if (_converse.connection.connected) {
|
if (_converse.connection.connected) {
|
||||||
controlbox.save({closed: true});
|
controlbox.save({closed: true});
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
|
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
|
||||||
// Licensed under the Mozilla Public License (MPLv2)
|
// Licensed under the Mozilla Public License (MPLv2)
|
||||||
//
|
//
|
||||||
/*global Backbone, define, window, document, JSON */
|
/*global Backbone, define, window, JSON */
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
define(["sizzle",
|
define(["sizzle",
|
||||||
"es6-promise",
|
"es6-promise",
|
||||||
"lodash.noconflict",
|
"lodash.noconflict",
|
||||||
|
"lodash.fp",
|
||||||
"polyfill",
|
"polyfill",
|
||||||
"i18n",
|
"i18n",
|
||||||
"utils",
|
"utils",
|
||||||
@ -19,7 +20,7 @@
|
|||||||
"backbone.nativeview",
|
"backbone.nativeview",
|
||||||
"backbone.browserStorage"
|
"backbone.browserStorage"
|
||||||
], factory);
|
], factory);
|
||||||
}(this, function (sizzle, Promise, _, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) {
|
}(this, function (sizzle, Promise, _, f, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) {
|
||||||
|
|
||||||
/* Cannot use this due to Safari bug.
|
/* Cannot use this due to Safari bug.
|
||||||
* See https://github.com/jcbrand/converse.js/issues/196
|
* See https://github.com/jcbrand/converse.js/issues/196
|
||||||
@ -44,6 +45,7 @@
|
|||||||
Strophe.addNamespace('ROSTERX', 'http://jabber.org/protocol/rosterx');
|
Strophe.addNamespace('ROSTERX', 'http://jabber.org/protocol/rosterx');
|
||||||
Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm');
|
Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm');
|
||||||
Strophe.addNamespace('SID', 'urn:xmpp:sid:0');
|
Strophe.addNamespace('SID', 'urn:xmpp:sid:0');
|
||||||
|
Strophe.addNamespace('SPOILER', 'urn:xmpp:spoiler:0');
|
||||||
Strophe.addNamespace('XFORM', 'jabber:x:data');
|
Strophe.addNamespace('XFORM', 'jabber:x:data');
|
||||||
|
|
||||||
// Use Mustache style syntax for variable interpolation
|
// Use Mustache style syntax for variable interpolation
|
||||||
@ -77,6 +79,7 @@
|
|||||||
'converse-mam',
|
'converse-mam',
|
||||||
'converse-minimize',
|
'converse-minimize',
|
||||||
'converse-muc',
|
'converse-muc',
|
||||||
|
'converse-muc-embedded',
|
||||||
'converse-notification',
|
'converse-notification',
|
||||||
'converse-otr',
|
'converse-otr',
|
||||||
'converse-ping',
|
'converse-ping',
|
||||||
@ -85,6 +88,7 @@
|
|||||||
'converse-roomslist',
|
'converse-roomslist',
|
||||||
'converse-rosterview',
|
'converse-rosterview',
|
||||||
'converse-singleton',
|
'converse-singleton',
|
||||||
|
'converse-spoilers',
|
||||||
'converse-vcard'
|
'converse-vcard'
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -163,21 +167,13 @@
|
|||||||
'warn': _.get(console, 'log') ? console.log.bind(console) : _.noop
|
'warn': _.get(console, 'log') ? console.log.bind(console) : _.noop
|
||||||
}, console);
|
}, console);
|
||||||
if (level === Strophe.LogLevel.ERROR) {
|
if (level === Strophe.LogLevel.ERROR) {
|
||||||
if (_converse.debug) {
|
|
||||||
logger.trace(`${prefix} ${moment().format()} ERROR: ${message}`, style);
|
|
||||||
} else {
|
|
||||||
logger.error(`${prefix} ERROR: ${message}`, style);
|
logger.error(`${prefix} ERROR: ${message}`, style);
|
||||||
}
|
|
||||||
} else if (level === Strophe.LogLevel.WARN) {
|
} else if (level === Strophe.LogLevel.WARN) {
|
||||||
if (_converse.debug) {
|
if (_converse.debug) {
|
||||||
logger.warn(`${prefix} ${moment().format()} WARNING: ${message}`, style);
|
logger.warn(`${prefix} ${moment().format()} WARNING: ${message}`, style);
|
||||||
}
|
}
|
||||||
} else if (level === Strophe.LogLevel.FATAL) {
|
} else if (level === Strophe.LogLevel.FATAL) {
|
||||||
if (_converse.debug) {
|
|
||||||
logger.trace(`${prefix} ${moment().format()} FATAL: ${message}`, style);
|
|
||||||
} else {
|
|
||||||
logger.error(`${prefix} FATAL: ${message}`, style);
|
logger.error(`${prefix} FATAL: ${message}`, style);
|
||||||
}
|
|
||||||
} else if (_converse.debug) {
|
} else if (_converse.debug) {
|
||||||
if (level === Strophe.LogLevel.DEBUG) {
|
if (level === Strophe.LogLevel.DEBUG) {
|
||||||
logger.debug(`${prefix} ${moment().format()} DEBUG: ${message}`, style);
|
logger.debug(`${prefix} ${moment().format()} DEBUG: ${message}`, style);
|
||||||
@ -293,7 +289,7 @@
|
|||||||
authentication: 'login', // Available values are "login", "prebind", "anonymous" and "external".
|
authentication: 'login', // Available values are "login", "prebind", "anonymous" and "external".
|
||||||
auto_away: 0, // Seconds after which user status is set to 'away'
|
auto_away: 0, // Seconds after which user status is set to 'away'
|
||||||
auto_login: false, // Currently only used in connection with anonymous login
|
auto_login: false, // Currently only used in connection with anonymous login
|
||||||
auto_reconnect: false,
|
auto_reconnect: true,
|
||||||
auto_subscribe: false,
|
auto_subscribe: false,
|
||||||
auto_xa: 0, // Seconds after which user status is set to 'xa'
|
auto_xa: 0, // Seconds after which user status is set to 'xa'
|
||||||
blacklisted_plugins: [],
|
blacklisted_plugins: [],
|
||||||
@ -310,7 +306,7 @@
|
|||||||
include_offline_state: false,
|
include_offline_state: false,
|
||||||
jid: undefined,
|
jid: undefined,
|
||||||
keepalive: true,
|
keepalive: true,
|
||||||
locales_url: '/locale/{{{locale}}}/LC_MESSAGES/converse.json',
|
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
|
||||||
locales: [
|
locales: [
|
||||||
'af', 'ca', 'de', 'es', 'en', 'fr', 'he',
|
'af', 'ca', 'de', 'es', 'en', 'fr', 'he',
|
||||||
'hu', 'id', 'it', 'ja', 'nb', 'nl',
|
'hu', 'id', 'it', 'ja', 'nb', 'nl',
|
||||||
@ -323,6 +319,7 @@
|
|||||||
priority: 0,
|
priority: 0,
|
||||||
registration_domain: '',
|
registration_domain: '',
|
||||||
rid: undefined,
|
rid: undefined,
|
||||||
|
root: window.document,
|
||||||
roster_groups: true,
|
roster_groups: true,
|
||||||
show_only_online_users: false,
|
show_only_online_users: false,
|
||||||
show_send_button: false,
|
show_send_button: false,
|
||||||
@ -373,7 +370,7 @@
|
|||||||
// Module-level functions
|
// Module-level functions
|
||||||
// ----------------------
|
// ----------------------
|
||||||
|
|
||||||
this.generateResource = () => `/converse.js-${Math.floor(Math.random()*139749825).toString()}`;
|
this.generateResource = () => `/converse.js-${Math.floor(Math.random()*139749528).toString()}`;
|
||||||
|
|
||||||
this.sendCSI = function (stat) {
|
this.sendCSI = function (stat) {
|
||||||
/* Send out a Chat Status Notification (XEP-0352)
|
/* Send out a Chat Status Notification (XEP-0352)
|
||||||
@ -596,19 +593,25 @@
|
|||||||
this.incrementMsgCounter = function () {
|
this.incrementMsgCounter = function () {
|
||||||
this.msg_counter += 1;
|
this.msg_counter += 1;
|
||||||
const unreadMsgCount = this.msg_counter;
|
const unreadMsgCount = this.msg_counter;
|
||||||
if (document.title.search(/^Messages \(\d+\) /) === -1) {
|
let title = document.title;
|
||||||
document.title = `Messages (${unreadMsgCount}) ${document.title}`;
|
if (_.isNil(title)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (title.search(/^Messages \(\d+\) /) === -1) {
|
||||||
|
title = `Messages (${unreadMsgCount}) ${title}`;
|
||||||
} else {
|
} else {
|
||||||
document.title = document.title.replace(
|
title = title.replace(/^Messages \(\d+\) /, `Messages (${unreadMsgCount})`);
|
||||||
/^Messages \(\d+\) /, `Messages (${unreadMsgCount}) `
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.clearMsgCounter = function () {
|
this.clearMsgCounter = function () {
|
||||||
this.msg_counter = 0;
|
this.msg_counter = 0;
|
||||||
if (document.title.search(/^Messages \(\d+\) /) !== -1) {
|
let title = document.title;
|
||||||
document.title = document.title.replace(/^Messages \(\d+\) /, "");
|
if (_.isNil(title)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (title.search(/^Messages \(\d+\) /) !== -1) {
|
||||||
|
title = title.replace(/^Messages \(\d+\) /, "");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -863,10 +866,8 @@
|
|||||||
this.RosterContact = Backbone.Model.extend({
|
this.RosterContact = Backbone.Model.extend({
|
||||||
|
|
||||||
defaults: {
|
defaults: {
|
||||||
'bookmarked': false,
|
|
||||||
'chat_state': undefined,
|
'chat_state': undefined,
|
||||||
'chat_status': 'offline',
|
'chat_status': 'offline',
|
||||||
'groups': [],
|
|
||||||
'image': _converse.DEFAULT_IMAGE,
|
'image': _converse.DEFAULT_IMAGE,
|
||||||
'image_type': _converse.DEFAULT_IMAGE_TYPE,
|
'image_type': _converse.DEFAULT_IMAGE_TYPE,
|
||||||
'num_unread': 0,
|
'num_unread': 0,
|
||||||
@ -879,11 +880,12 @@
|
|||||||
const resource = Strophe.getResourceFromJid(jid);
|
const resource = Strophe.getResourceFromJid(jid);
|
||||||
attributes.jid = bare_jid;
|
attributes.jid = bare_jid;
|
||||||
this.set(_.assignIn({
|
this.set(_.assignIn({
|
||||||
|
'fullname': bare_jid,
|
||||||
|
'groups': [],
|
||||||
'id': bare_jid,
|
'id': bare_jid,
|
||||||
'jid': bare_jid,
|
'jid': bare_jid,
|
||||||
'fullname': bare_jid,
|
'resources': {},
|
||||||
'user_id': Strophe.getNodeFromJid(jid),
|
'user_id': Strophe.getNodeFromJid(jid)
|
||||||
'resources': resource ? {resource :0} : {},
|
|
||||||
}, attributes));
|
}, attributes));
|
||||||
|
|
||||||
this.on('destroy', () => { this.removeFromRoster(); });
|
this.on('destroy', () => { this.removeFromRoster(); });
|
||||||
@ -979,6 +981,7 @@
|
|||||||
|
|
||||||
const resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
|
const resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
|
||||||
resources[resource] = {
|
resources[resource] = {
|
||||||
|
'name': resource,
|
||||||
'priority': priority,
|
'priority': priority,
|
||||||
'status': chat_status,
|
'status': chat_status,
|
||||||
'timestamp': timestamp
|
'timestamp': timestamp
|
||||||
@ -1479,6 +1482,7 @@
|
|||||||
this.connfeedback = new this.ConnectionFeedback();
|
this.connfeedback = new this.ConnectionFeedback();
|
||||||
|
|
||||||
this.XMPPStatus = Backbone.Model.extend({
|
this.XMPPStatus = Backbone.Model.extend({
|
||||||
|
|
||||||
initialize () {
|
initialize () {
|
||||||
this.set({
|
this.set({
|
||||||
'status' : this.getStatus()
|
'status' : this.getStatus()
|
||||||
@ -1799,6 +1803,21 @@
|
|||||||
const whitelist = _converse.core_plugins.concat(
|
const whitelist = _converse.core_plugins.concat(
|
||||||
_converse.whitelisted_plugins);
|
_converse.whitelisted_plugins);
|
||||||
|
|
||||||
|
if (_converse.view_mode === 'embedded') {
|
||||||
|
_.forEach([ // eslint-disable-line lodash/prefer-map
|
||||||
|
"converse-bookmarks",
|
||||||
|
"converse-controlbox",
|
||||||
|
"converse-dragresize",
|
||||||
|
"converse-headline",
|
||||||
|
"converse-minimize",
|
||||||
|
"converse-otr",
|
||||||
|
"converse-register",
|
||||||
|
"converse-vcard",
|
||||||
|
], (name) => {
|
||||||
|
_converse.blacklisted_plugins.push(name)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_converse.pluggable.initializePlugins({
|
_converse.pluggable.initializePlugins({
|
||||||
'updateSettings' () {
|
'updateSettings' () {
|
||||||
_converse.log(
|
_converse.log(
|
||||||
@ -1843,13 +1862,10 @@
|
|||||||
i18n.fetchTranslations(
|
i18n.fetchTranslations(
|
||||||
_converse.locale,
|
_converse.locale,
|
||||||
_converse.locales,
|
_converse.locales,
|
||||||
_.template(_converse.locales_url)({'locale': _converse.locale})
|
_.template(_converse.locales_url)({'locale': _converse.locale}))
|
||||||
).then(() => {
|
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
|
||||||
finishInitialization();
|
.then(finishInitialization)
|
||||||
}).catch((reason) => {
|
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
finishInitialization();
|
|
||||||
_converse.log(reason, Strophe.LogLevel.ERROR);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return init_promise;
|
return init_promise;
|
||||||
};
|
};
|
||||||
@ -2000,7 +2016,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The public API
|
// The public API
|
||||||
return {
|
window.converse = {
|
||||||
'initialize' (settings, callback) {
|
'initialize' (settings, callback) {
|
||||||
return _converse.initialize(settings, callback);
|
return _converse.initialize(settings, callback);
|
||||||
},
|
},
|
||||||
@ -2025,10 +2041,13 @@
|
|||||||
'Promise': Promise,
|
'Promise': Promise,
|
||||||
'Strophe': Strophe,
|
'Strophe': Strophe,
|
||||||
'_': _,
|
'_': _,
|
||||||
|
'f': f,
|
||||||
'b64_sha1': b64_sha1,
|
'b64_sha1': b64_sha1,
|
||||||
'moment': moment,
|
'moment': moment,
|
||||||
'sizzle': sizzle,
|
'sizzle': sizzle,
|
||||||
'utils': utils
|
'utils': utils
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
window.dispatchEvent(new Event('converse-loaded'));
|
||||||
|
return window.converse;
|
||||||
}));
|
}));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
/* This is a Converse.js plugin which add support for XEP-0030: Service Discovery */
|
/* This is a Converse.js plugin which add support for XEP-0030: Service Discovery */
|
||||||
|
|
||||||
/*global Backbone, define, window, document */
|
/*global Backbone, define, window */
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
define(["converse-core", "sizzle", "strophe.disco"], factory);
|
define(["converse-core", "sizzle", "strophe.disco"], factory);
|
||||||
}(this, function (converse, sizzle) {
|
}(this, function (converse, sizzle) {
|
||||||
@ -65,6 +65,29 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getIdentity (category, type) {
|
||||||
|
/* Returns a Promise which resolves with a map indicating
|
||||||
|
* whether a given identity is provided.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (String) category - The identity category
|
||||||
|
* (String) type - The identity type
|
||||||
|
*/
|
||||||
|
const entity = this;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
function fulfillPromise () {
|
||||||
|
const model = entity.identities.findWhere({
|
||||||
|
'category': category,
|
||||||
|
'type': type
|
||||||
|
});
|
||||||
|
resolve(model);
|
||||||
|
}
|
||||||
|
entity.waitUntilFeaturesDiscovered
|
||||||
|
.then(fulfillPromise)
|
||||||
|
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
hasFeature (feature) {
|
hasFeature (feature) {
|
||||||
/* Returns a Promise which resolves with a map indicating
|
/* Returns a Promise which resolves with a map indicating
|
||||||
* whether a given feature is supported.
|
* whether a given feature is supported.
|
||||||
@ -130,8 +153,8 @@
|
|||||||
_.forEach(stanza.querySelectorAll('identity'), (identity) => {
|
_.forEach(stanza.querySelectorAll('identity'), (identity) => {
|
||||||
this.identities.create({
|
this.identities.create({
|
||||||
'category': identity.getAttribute('category'),
|
'category': identity.getAttribute('category'),
|
||||||
'type': stanza.getAttribute('type'),
|
'type': identity.getAttribute('type'),
|
||||||
'name': stanza.getAttribute('name')
|
'name': identity.getAttribute('name')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (stanza.querySelector('feature[var="'+Strophe.NS.DISCO_ITEMS+'"]')) {
|
if (stanza.querySelector('feature[var="'+Strophe.NS.DISCO_ITEMS+'"]')) {
|
||||||
@ -245,7 +268,28 @@
|
|||||||
return _converse.api.waitUntil('discoInitialized').then(() => {
|
return _converse.api.waitUntil('discoInitialized').then(() => {
|
||||||
const entity = _converse.api.disco.entities.get(entity_jid, true);
|
const entity = _converse.api.disco.entities.get(entity_jid, true);
|
||||||
return entity.hasFeature(feature);
|
return entity.hasFeature(feature);
|
||||||
});
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
|
},
|
||||||
|
|
||||||
|
'getIdentity' (category, type, entity_jid) {
|
||||||
|
/* Returns a Promise which resolves with a map indicating
|
||||||
|
* whether an identity with a given type is provided by
|
||||||
|
* the entity.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (String) category - The identity category.
|
||||||
|
* In the XML stanza, this is the `category`
|
||||||
|
* attribute of the `<identity>` element.
|
||||||
|
* For example: 'pubsub'
|
||||||
|
* (String) type - The identity type.
|
||||||
|
* In the XML stanza, this is the `type`
|
||||||
|
* attribute of the `<identity>` element.
|
||||||
|
* For example: 'pep'
|
||||||
|
*/
|
||||||
|
return _converse.api.waitUntil('discoInitialized').then(() => {
|
||||||
|
const entity = _converse.api.disco.entities.get(entity_jid, true);
|
||||||
|
return entity.getIdentity(category, type);
|
||||||
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
|
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
|
||||||
// Licensed under the Mozilla Public License (MPLv2)
|
// Licensed under the Mozilla Public License (MPLv2)
|
||||||
//
|
//
|
||||||
/*global define, window */
|
/*global define, window, document */
|
||||||
|
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
define(["converse-core",
|
define(["converse-core",
|
||||||
@ -175,7 +175,10 @@
|
|||||||
} else {
|
} else {
|
||||||
height = "";
|
height = "";
|
||||||
}
|
}
|
||||||
this.el.querySelector('.box-flyout').style.height = height;
|
const flyout_el = this.el.querySelector('.box-flyout');
|
||||||
|
if (!_.isNull(flyout_el)) {
|
||||||
|
flyout_el.style.height = height;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setChatBoxWidth (width) {
|
setChatBoxWidth (width) {
|
||||||
@ -186,10 +189,12 @@
|
|||||||
width = "";
|
width = "";
|
||||||
}
|
}
|
||||||
this.el.style.width = width;
|
this.el.style.width = width;
|
||||||
this.el.querySelector('.box-flyout').style.width = width;
|
const flyout_el = this.el.querySelector('.box-flyout');
|
||||||
|
if (!_.isNull(flyout_el)) {
|
||||||
|
flyout_el.style.width = width;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
adjustToViewport () {
|
adjustToViewport () {
|
||||||
/* Event handler called when viewport gets resized. We remove
|
/* Event handler called when viewport gets resized. We remove
|
||||||
* custom width/height from chat boxes.
|
* custom width/height from chat boxes.
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
converse.plugins.add('converse-fullscreen', {
|
converse.plugins.add('converse-fullscreen', {
|
||||||
|
|
||||||
enabled (_converse) {
|
enabled (_converse) {
|
||||||
return _.includes(['mobile', 'fullscreen'], _converse.view_mode);
|
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
|
||||||
},
|
},
|
||||||
|
|
||||||
overrides: {
|
overrides: {
|
||||||
@ -37,7 +37,8 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
insertBrandHeading () {
|
insertBrandHeading () {
|
||||||
const el = document.getElementById('converse-login-panel');
|
const { _converse } = this.__super__;
|
||||||
|
const el = _converse.root.getElementById('converse-login-panel');
|
||||||
el.parentNode.insertAdjacentHTML(
|
el.parentNode.insertAdjacentHTML(
|
||||||
'afterbegin',
|
'afterbegin',
|
||||||
this.createBrandHeadingHTML()
|
this.createBrandHeadingHTML()
|
||||||
|
@ -113,7 +113,6 @@
|
|||||||
info_close: '',
|
info_close: '',
|
||||||
label_personal_message: '',
|
label_personal_message: '',
|
||||||
show_send_button: false,
|
show_send_button: false,
|
||||||
show_textarea: false,
|
|
||||||
show_toolbar: false,
|
show_toolbar: false,
|
||||||
unread_msgs: ''
|
unread_msgs: ''
|
||||||
}
|
}
|
||||||
@ -122,14 +121,15 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override to avoid the method in converse-chatview.js
|
// Override to avoid the methods in converse-chatview.js
|
||||||
|
'renderMessageForm': _.noop,
|
||||||
'afterShown': _.noop
|
'afterShown': _.noop
|
||||||
});
|
});
|
||||||
|
|
||||||
function onHeadlineMessage (message) {
|
function onHeadlineMessage (message) {
|
||||||
/* Handler method for all incoming messages of type "headline". */
|
/* Handler method for all incoming messages of type "headline". */
|
||||||
const from_jid = message.getAttribute('from');
|
const from_jid = message.getAttribute('from');
|
||||||
if (utils.isHeadlineMessage(message)) {
|
if (utils.isHeadlineMessage(_converse, message)) {
|
||||||
if (_.includes(from_jid, '@') && !_converse.allow_non_roster_messaging) {
|
if (_.includes(from_jid, '@') && !_converse.allow_non_roster_messaging) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -146,8 +146,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function registerHeadlineHandler () {
|
function registerHeadlineHandler () {
|
||||||
_converse.connection.addHandler(
|
_converse.connection.addHandler(onHeadlineMessage, null, 'message');
|
||||||
onHeadlineMessage, null, 'message');
|
|
||||||
}
|
}
|
||||||
_converse.on('connected', registerHeadlineHandler);
|
_converse.on('connected', registerHeadlineHandler);
|
||||||
_converse.on('reconnected', registerHeadlineHandler);
|
_converse.on('reconnected', registerHeadlineHandler);
|
||||||
|
@ -83,12 +83,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const messages = [];
|
const messages = [];
|
||||||
const message_handler = _converse.connection.addHandler(function (message) {
|
const message_handler = _converse.connection.addHandler((message) => {
|
||||||
if (options.groupchat) {
|
if (options.groupchat && message.getAttribute('from') !== options['with']) { // eslint-disable-line dot-notation
|
||||||
if (message.getAttribute('from') !== options['with']) { // eslint-disable-line dot-notation
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
const result = message.querySelector('result');
|
const result = message.querySelector('result');
|
||||||
if (!_.isNull(result) && result.getAttribute('queryid') === queryid) {
|
if (!_.isNull(result) && result.getAttribute('queryid') === queryid) {
|
||||||
messages.push(message);
|
messages.push(message);
|
||||||
@ -255,7 +253,7 @@
|
|||||||
|
|
||||||
onScroll (ev) {
|
onScroll (ev) {
|
||||||
const { _converse } = this.__super__;
|
const { _converse } = this.__super__;
|
||||||
if (ev.target.scrollTop === 0 && this.model.messages.length) {
|
if (this.content.scrollTop === 0 && this.model.messages.length) {
|
||||||
const oldest_message = this.model.messages.at(0);
|
const oldest_message = this.model.messages.at(0);
|
||||||
const archive_id = oldest_message.get('archive_id');
|
const archive_id = oldest_message.get('archive_id');
|
||||||
if (archive_id) {
|
if (archive_id) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
|
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
|
||||||
// Licensed under the Mozilla Public License (MPLv2)
|
// Licensed under the Mozilla Public License (MPLv2)
|
||||||
//
|
//
|
||||||
/*global define, window */
|
/*global define, window, document */
|
||||||
|
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
define(["converse-core",
|
define(["converse-core",
|
||||||
|
@ -11,6 +11,11 @@
|
|||||||
const { Backbone, _ } = converse.env;
|
const { Backbone, _ } = converse.env;
|
||||||
|
|
||||||
converse.plugins.add('converse-muc-embedded', {
|
converse.plugins.add('converse-muc-embedded', {
|
||||||
|
|
||||||
|
enabled (_converse) {
|
||||||
|
return _converse.view_mode === 'embedded';
|
||||||
|
},
|
||||||
|
|
||||||
overrides: {
|
overrides: {
|
||||||
// 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
|
||||||
@ -18,33 +23,10 @@
|
|||||||
//
|
//
|
||||||
// New functions which don't exist yet can also be added.
|
// New functions which don't exist yet can also be added.
|
||||||
|
|
||||||
ChatBoxes: {
|
ChatBoxViews: {
|
||||||
onConnected () {
|
initialize () {
|
||||||
// Override to avoid storing or fetching chat boxes from session
|
this.__super__.initialize.apply(this, arguments);
|
||||||
// storage.
|
this.el.classList.add('converse-embedded');
|
||||||
const { _converse } = this.__super__;
|
|
||||||
this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
|
|
||||||
converse.env.b64_sha1(`converse.chatboxes-${_converse.bare_jid}`));
|
|
||||||
this.registerMessageHandler();
|
|
||||||
/* This is disabled:
|
|
||||||
*
|
|
||||||
* this.fetch({
|
|
||||||
* add: true,
|
|
||||||
* success: this.onChatBoxesFetched.bind(this)
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
this.onChatBoxesFetched(new Backbone.Collection());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
ChatRoomView: {
|
|
||||||
insertIntoDOM () {
|
|
||||||
if (!document.body.contains(this.el)) {
|
|
||||||
const container = document.querySelector('#converse-embedded-chat');
|
|
||||||
container.innerHTML = '';
|
|
||||||
container.appendChild(this.el);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -53,6 +35,13 @@
|
|||||||
/* 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.
|
||||||
*/
|
*/
|
||||||
|
this._converse.api.settings.update({
|
||||||
|
'allow_logout': false, // No point in logging out when we have auto_login as true.
|
||||||
|
'allow_muc_invitations': false, // Doesn't make sense to allow because only
|
||||||
|
// roster contacts can be invited
|
||||||
|
'hide_muc_server': true, // Federation is disabled, so no use in
|
||||||
|
// showing the MUC server.
|
||||||
|
});
|
||||||
const { _converse } = this;
|
const { _converse } = this;
|
||||||
if (!_.isArray(_converse.auto_join_rooms)) {
|
if (!_.isArray(_converse.auto_join_rooms)) {
|
||||||
throw new Error("converse-muc-embedded: auto_join_rooms must be an Array");
|
throw new Error("converse-muc-embedded: auto_join_rooms must be an Array");
|
||||||
|
@ -319,14 +319,14 @@
|
|||||||
|
|
||||||
|
|
||||||
function openRoom (jid) {
|
function openRoom (jid) {
|
||||||
if (!u.isValidJID(jid)) {
|
if (!u.isValidMUCJID(jid)) {
|
||||||
return converse.log(
|
return _converse.log(
|
||||||
`Invalid JID "${jid}" provided in URL fragment`,
|
`Invalid JID "${jid}" provided in URL fragment`,
|
||||||
Strophe.LogLevel.WARN
|
Strophe.LogLevel.WARN
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const promises = [_converse.api.waitUntil('roomsAutoJoined')]
|
const promises = [_converse.api.waitUntil('roomsAutoJoined')]
|
||||||
if (!_converse.allow_bookmarks) {
|
if (_converse.allow_bookmarks) {
|
||||||
promises.push( _converse.api.waitUntil('bookmarksInitialized'));
|
promises.push( _converse.api.waitUntil('bookmarksInitialized'));
|
||||||
}
|
}
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
@ -435,7 +435,7 @@
|
|||||||
'click .new-msgs-indicator': 'viewUnreadMessages',
|
'click .new-msgs-indicator': 'viewUnreadMessages',
|
||||||
'click .occupant': 'onOccupantClicked',
|
'click .occupant': 'onOccupantClicked',
|
||||||
'keypress .chat-textarea': 'keyPressed',
|
'keypress .chat-textarea': 'keyPressed',
|
||||||
'click .send-button': 'onSendButtonClicked'
|
'click .send-button': 'onFormSubmitted'
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize () {
|
initialize () {
|
||||||
@ -486,8 +486,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderChatArea () {
|
renderChatArea () {
|
||||||
/* Render the UI container in which chat room messages will
|
/* Render the UI container in which chat room messages will appear.
|
||||||
* appear.
|
|
||||||
*/
|
*/
|
||||||
if (_.isNull(this.el.querySelector('.chat-area'))) {
|
if (_.isNull(this.el.querySelector('.chat-area'))) {
|
||||||
const container_el = this.el.querySelector('.chatroom-body');
|
const container_el = this.el.querySelector('.chatroom-body');
|
||||||
@ -553,18 +552,19 @@
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
afterShown () {
|
afterShown (focus) {
|
||||||
/* Override from converse-chatview, specifically to avoid
|
/* Override from converse-chatview, specifically to avoid
|
||||||
* the 'active' chat state from being sent out prematurely.
|
* the 'active' chat state from being sent out prematurely.
|
||||||
*
|
*
|
||||||
* This is instead done in `afterConnected` below.
|
* This is instead done in `afterConnected` below.
|
||||||
*/
|
*/
|
||||||
if (this.model.collection && this.model.collection.browserStorage) {
|
if (u.isPersistableModel(this.model)) {
|
||||||
// Without a connection, we haven't yet initialized
|
this.model.clearUnreadMsgCounter();
|
||||||
// localstorage
|
|
||||||
this.model.save();
|
this.model.save();
|
||||||
}
|
}
|
||||||
this.occupantsview.setOccupantsHeight();
|
this.occupantsview.setOccupantsHeight();
|
||||||
|
this.scrollDown();
|
||||||
|
if (focus) { this.focus(); }
|
||||||
},
|
},
|
||||||
|
|
||||||
show (focus) {
|
show (focus) {
|
||||||
@ -575,15 +575,14 @@
|
|||||||
// Override from converse-chatview in order to not use
|
// Override from converse-chatview in order to not use
|
||||||
// "fadeIn", which causes flashing.
|
// "fadeIn", which causes flashing.
|
||||||
u.showElement(this.el);
|
u.showElement(this.el);
|
||||||
this.afterShown();
|
this.afterShown(focus);
|
||||||
if (focus) { this.focus(); }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
afterConnected () {
|
afterConnected () {
|
||||||
if (this.model.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
|
if (this.model.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
|
||||||
this.setChatState(_converse.ACTIVE);
|
this.setChatState(_converse.ACTIVE);
|
||||||
this.renderEmojiPicker();
|
|
||||||
this.scrollDown();
|
this.scrollDown();
|
||||||
|
this.renderEmojiPicker();
|
||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1186,9 +1185,8 @@
|
|||||||
nick = this.model.get('nick');
|
nick = this.model.get('nick');
|
||||||
}
|
}
|
||||||
const room = this.model.get('jid');
|
const room = this.model.get('jid');
|
||||||
const node = Strophe.getNodeFromJid(room);
|
const jid = Strophe.getBareJidFromJid(room);
|
||||||
const domain = Strophe.getDomainFromJid(room);
|
return jid + (nick !== null ? `/${nick}` : "");
|
||||||
return node + "@" + domain + (nick !== null ? `/${nick}` : "");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
registerHandlers () {
|
registerHandlers () {
|
||||||
@ -1241,6 +1239,7 @@
|
|||||||
// so we don't send out a presence stanza again.
|
// so we don't send out a presence stanza again.
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stanza = $pres({
|
const stanza = $pres({
|
||||||
'from': _converse.connection.jid,
|
'from': _converse.connection.jid,
|
||||||
'to': this.getRoomJIDAndNick(nick)
|
'to': this.getRoomJIDAndNick(nick)
|
||||||
@ -2487,7 +2486,7 @@
|
|||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
const el = evt.target.querySelector('input.invited-contact'),
|
const el = evt.target.querySelector('input.invited-contact'),
|
||||||
jid = el.value;
|
jid = el.value;
|
||||||
if (!jid || _.filter(jid.split('@')).length < 2) {
|
if (!jid || _.compact(jid.split('@')).length < 2) {
|
||||||
evt.target.outerHTML = tpl_chatroom_invite({
|
evt.target.outerHTML = tpl_chatroom_invite({
|
||||||
'error_message': __('Please enter a valid XMPP username'),
|
'error_message': __('Please enter a valid XMPP username'),
|
||||||
'label_invitation': __('Invite'),
|
'label_invitation': __('Invite'),
|
||||||
@ -2649,6 +2648,21 @@
|
|||||||
this.removeSpinner();
|
this.removeSpinner();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
roomStanzaItemToHTMLElement (room) {
|
||||||
|
const name = Strophe.unescapeNode(
|
||||||
|
room.getAttribute('name') ||
|
||||||
|
room.getAttribute('jid')
|
||||||
|
);
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerHTML = tpl_room_item({
|
||||||
|
'name': name,
|
||||||
|
'jid': room.getAttribute('jid'),
|
||||||
|
'open_title': __('Click to open this room'),
|
||||||
|
'info_title': __('Show more information on this room')
|
||||||
|
});
|
||||||
|
return div.firstChild;
|
||||||
|
},
|
||||||
|
|
||||||
onRoomsFound (iq) {
|
onRoomsFound (iq) {
|
||||||
/* Handle the IQ stanza returned from the server, containing
|
/* Handle the IQ stanza returned from the server, containing
|
||||||
* all its public rooms.
|
* all its public rooms.
|
||||||
@ -2661,21 +2675,9 @@
|
|||||||
available_chatrooms.innerHTML = tpl_rooms_results({
|
available_chatrooms.innerHTML = tpl_rooms_results({
|
||||||
'feedback_text': __('Rooms found')
|
'feedback_text': __('Rooms found')
|
||||||
});
|
});
|
||||||
const div = document.createElement('div');
|
|
||||||
const fragment = document.createDocumentFragment();
|
const fragment = document.createDocumentFragment();
|
||||||
for (let i=0; i<this.rooms.length; i++) {
|
const children = _.reject(_.map(this.rooms, this.roomStanzaItemToHTMLElement), _.isNil)
|
||||||
const name = Strophe.unescapeNode(
|
_.each(children, (child) => fragment.appendChild(child));
|
||||||
this.rooms[i].getAttribute('name') ||
|
|
||||||
this.rooms[i].getAttribute('jid')
|
|
||||||
);
|
|
||||||
div.innerHTML = tpl_room_item({
|
|
||||||
'name': name,
|
|
||||||
'jid': this.rooms[i].getAttribute('jid'),
|
|
||||||
'open_title': __('Click to open this room'),
|
|
||||||
'info_title': __('Show more information on this room')
|
|
||||||
});
|
|
||||||
fragment.appendChild(div.firstChild);
|
|
||||||
}
|
|
||||||
available_chatrooms.appendChild(fragment);
|
available_chatrooms.appendChild(fragment);
|
||||||
const input_el = this.el.querySelector('input#show-rooms');
|
const input_el = this.el.querySelector('input#show-rooms');
|
||||||
input_el.classList.remove('hidden')
|
input_el.classList.remove('hidden')
|
||||||
@ -2806,7 +2808,7 @@
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
'jid': jid,
|
'jid': jid,
|
||||||
'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
|
'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)) || jid
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2891,6 +2893,9 @@
|
|||||||
* settings).
|
* settings).
|
||||||
*/
|
*/
|
||||||
_.each(_converse.auto_join_rooms, function (room) {
|
_.each(_converse.auto_join_rooms, function (room) {
|
||||||
|
if (_converse.chatboxes.where({'jid': room}).length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_.isString(room)) {
|
if (_.isString(room)) {
|
||||||
_converse.api.rooms.open(room);
|
_converse.api.rooms.open(room);
|
||||||
} else if (_.isObject(room)) {
|
} else if (_.isObject(room)) {
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
_converse.isMessageToHiddenChat = function (message) {
|
_converse.isMessageToHiddenChat = function (message) {
|
||||||
if (_.includes(['mobile', 'fullscreen'], _converse.view_mode)) {
|
if (_.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode)) {
|
||||||
const jid = Strophe.getBareJidFromJid(message.getAttribute('from'));
|
const jid = Strophe.getBareJidFromJid(message.getAttribute('from'));
|
||||||
const model = _converse.chatboxes.get(jid);
|
const model = _converse.chatboxes.get(jid);
|
||||||
if (!_.isNil(model)) {
|
if (!_.isNil(model)) {
|
||||||
@ -93,7 +93,7 @@
|
|||||||
return false;
|
return false;
|
||||||
} else if (message.getAttribute('type') === 'groupchat') {
|
} else if (message.getAttribute('type') === 'groupchat') {
|
||||||
return _converse.shouldNotifyOfGroupMessage(message);
|
return _converse.shouldNotifyOfGroupMessage(message);
|
||||||
} else if (utils.isHeadlineMessage(message)) {
|
} else if (utils.isHeadlineMessage(_converse, message)) {
|
||||||
// We want to show notifications for headline messages.
|
// We want to show notifications for headline messages.
|
||||||
return _converse.isMessageToHiddenChat(message);
|
return _converse.isMessageToHiddenChat(message);
|
||||||
}
|
}
|
||||||
|
@ -283,25 +283,34 @@
|
|||||||
return stanza;
|
return stanza;
|
||||||
},
|
},
|
||||||
|
|
||||||
onMessageSubmitted (text) {
|
parseMessageForCommands (text) {
|
||||||
const { _converse } = this.__super__;
|
const { _converse } = this.__super__;
|
||||||
if (!_converse.connection.authenticated) {
|
|
||||||
return this.showHelpMessages(
|
|
||||||
['Sorry, the connection has been lost, '+
|
|
||||||
'and your message could not be sent'],
|
|
||||||
'error'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/);
|
const match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/);
|
||||||
if (match) {
|
if (match) {
|
||||||
if ((_converse.allow_otr) && (match[1] === "endotr")) {
|
if ((_converse.allow_otr) && (match[1] === "endotr")) {
|
||||||
return this.endOTR();
|
this.endOTR();
|
||||||
|
return true;
|
||||||
} else if ((_converse.allow_otr) && (match[1] === "otr")) {
|
} else if ((_converse.allow_otr) && (match[1] === "otr")) {
|
||||||
return this.model.initiateOTR();
|
this.model.initiateOTR();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_.includes([UNVERIFIED, VERIFIED], this.model.get('otr_status'))) {
|
return this.__super__.parseMessageForCommands.apply(this, arguments);
|
||||||
// Off-the-record encryption is active
|
},
|
||||||
|
|
||||||
|
isOTREncryptedSession () {
|
||||||
|
return _.includes([UNVERIFIED, VERIFIED], this.model.get('otr_status'));
|
||||||
|
},
|
||||||
|
|
||||||
|
onMessageSubmitted (text, spoiler_hint) {
|
||||||
|
const { _converse } = this.__super__;
|
||||||
|
if (!_converse.connection.authenticated) {
|
||||||
|
this.__super__.onMessageSubmitted.apply(this, arguments);
|
||||||
|
}
|
||||||
|
if (this.parseMessageForCommands(text)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.isOTREncryptedSession()) {
|
||||||
this.model.otr.sendMsg(text);
|
this.model.otr.sendMsg(text);
|
||||||
this.model.trigger('showSentOTRMessage', text);
|
this.model.trigger('showSentOTRMessage', text);
|
||||||
} else {
|
} else {
|
||||||
@ -394,9 +403,10 @@
|
|||||||
|
|
||||||
toggleOTRMenu (ev) {
|
toggleOTRMenu (ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
const { _converse } = this.__super__;
|
||||||
const menu = this.el.querySelector('.toggle-otr ul');
|
const menu = this.el.querySelector('.toggle-otr ul');
|
||||||
const elements = _.difference(
|
const elements = _.difference(
|
||||||
document.querySelectorAll('.toolbar-menu'),
|
_converse.root.querySelectorAll('.toolbar-menu'),
|
||||||
[menu]
|
[menu]
|
||||||
);
|
);
|
||||||
utils.slideInAllElements(elements).then(
|
utils.slideInAllElements(elements).then(
|
||||||
@ -419,13 +429,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
renderToolbar (toolbar, options) {
|
addOTRToolbarButton (options) {
|
||||||
const { _converse } = this.__super__,
|
const { _converse } = this.__super__,
|
||||||
{ __ } = _converse;
|
{ __ } = _converse,
|
||||||
if (!_converse.show_toolbar) {
|
data = this.model.toJSON();
|
||||||
return;
|
|
||||||
}
|
|
||||||
const data = this.model.toJSON();
|
|
||||||
options = _.extend(options || {}, {
|
options = _.extend(options || {}, {
|
||||||
FINISHED,
|
FINISHED,
|
||||||
UNENCRYPTED,
|
UNENCRYPTED,
|
||||||
@ -443,13 +450,25 @@
|
|||||||
otr_tooltip: this.getOTRTooltip(),
|
otr_tooltip: this.getOTRTooltip(),
|
||||||
otr_translated_status: OTR_TRANSLATED_MAPPING[data.otr_status],
|
otr_translated_status: OTR_TRANSLATED_MAPPING[data.otr_status],
|
||||||
});
|
});
|
||||||
this.__super__.renderToolbar.apply(this, arguments);
|
|
||||||
this.el.querySelector('.chat-toolbar').insertAdjacentHTML(
|
this.el.querySelector('.chat-toolbar').insertAdjacentHTML(
|
||||||
'beforeend',
|
'beforeend',
|
||||||
tpl_toolbar_otr(
|
tpl_toolbar_otr(
|
||||||
_.extend(this.model.toJSON(), options || {})
|
_.extend(this.model.toJSON(), options || {})
|
||||||
));
|
));
|
||||||
return this;
|
},
|
||||||
|
|
||||||
|
getToolbarOptions (options) {
|
||||||
|
options = this.__super__.getToolbarOptions();
|
||||||
|
if (this.isOTREncryptedSession()) {
|
||||||
|
options.show_spoiler_button = false;
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderToolbar (toolbar, options) {
|
||||||
|
const result = this.__super__.renderToolbar.apply(this, arguments);
|
||||||
|
this.addOTRToolbarButton(options);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
// Replace the default dropdown with something nicer
|
// Replace the default dropdown with something nicer
|
||||||
const select = this.el.querySelector('select#select-xmpp-status')
|
const options = this.el.querySelectorAll('#select-xmpp-status option');
|
||||||
const chat_status = this.model.get('status') || 'offline';
|
const chat_status = this.model.get('status') || 'offline';
|
||||||
this.el.innerHTML = tpl_choose_status();
|
this.el.innerHTML = tpl_choose_status();
|
||||||
|
|
||||||
@ -67,15 +67,10 @@
|
|||||||
|
|
||||||
// iterate through all the <option> elements and add option values
|
// iterate through all the <option> elements and add option values
|
||||||
const options_list = _.map(
|
const options_list = _.map(
|
||||||
select.querySelectorAll('option'),
|
options,
|
||||||
function (el) {
|
(el) => tpl_status_option({'value': el.value, 'text': el.text })
|
||||||
return tpl_status_option({
|
|
||||||
'value': el.value,
|
|
||||||
'text': el.text
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
const options_target = this.el.querySelector("#target dd ul");
|
const options_target = this.el.querySelector(".xmpp-status-menu");
|
||||||
options_target.classList.add('collapsed');
|
options_target.classList.add('collapsed');
|
||||||
options_target.innerHTML = options_list.join('');
|
options_target.innerHTML = options_list.join('');
|
||||||
return this;
|
return this;
|
||||||
@ -84,7 +79,7 @@
|
|||||||
toggleOptions (ev) {
|
toggleOptions (ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
utils.slideInAllElements(
|
utils.slideInAllElements(
|
||||||
document.querySelectorAll('#conversejs .contact-form-container')
|
_converse.root.querySelectorAll('#conversejs .contact-form-container')
|
||||||
);
|
);
|
||||||
utils.slideToggleElement(this.el.querySelector("#target dd ul"));
|
utils.slideToggleElement(this.el.querySelector("#target dd ul"));
|
||||||
},
|
},
|
||||||
|
@ -334,7 +334,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
form.querySelector('input[type=submit]').classList.add('hidden');
|
form.querySelector('input[type=submit]').classList.add('hidden');
|
||||||
this.fetchRegistrationForm(domain);
|
this.fetchRegistrationForm(domain.trim());
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchRegistrationForm (domain_name) {
|
fetchRegistrationForm (domain_name) {
|
||||||
@ -603,7 +603,8 @@
|
|||||||
if (has_empty_inputs) { return; }
|
if (has_empty_inputs) { return; }
|
||||||
|
|
||||||
const inputs = sizzle(':input:not([type=button]):not([type=submit])', form),
|
const inputs = sizzle(':input:not([type=button]):not([type=submit])', form),
|
||||||
iq = $iq({type: "set"}).c("query", {xmlns:Strophe.NS.REGISTER});
|
iq = $iq({'type': 'set', 'id': _converse.connection.getUniqueId()})
|
||||||
|
.c("query", {xmlns:Strophe.NS.REGISTER});
|
||||||
|
|
||||||
if (this.form_type === 'xform') {
|
if (this.form_type === 'xform') {
|
||||||
iq.c("x", {xmlns: Strophe.NS.XFORM, type: 'submit'});
|
iq.c("x", {xmlns: Strophe.NS.XFORM, type: 'submit'});
|
||||||
|
@ -176,7 +176,7 @@
|
|||||||
insertIntoControlBox () {
|
insertIntoControlBox () {
|
||||||
const controlboxview = _converse.chatboxviews.get('controlbox');
|
const controlboxview = _converse.chatboxviews.get('controlbox');
|
||||||
if (!_.isUndefined(controlboxview) &&
|
if (!_.isUndefined(controlboxview) &&
|
||||||
!document.body.contains(this.el)) {
|
!_converse.root.contains(this.el)) {
|
||||||
const container = controlboxview.el.querySelector('#chatrooms');
|
const container = controlboxview.el.querySelector('#chatrooms');
|
||||||
if (!_.isNull(container)) {
|
if (!_.isNull(container)) {
|
||||||
container.insertBefore(this.el, container.firstChild);
|
container.insertBefore(this.el, container.firstChild);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user