Browse Source

Merge branch 'master' into converse-omemo

JC Brand 7 years ago
parent
commit
bf13927946
100 changed files with 16691 additions and 18072 deletions
  1. 1 1
      .eslintrc.json
  2. 1 0
      CHANGES.md
  3. 30 29
      README.md
  4. 269 277
      css/converse.css
  5. 1 1
      demo/embedded.html
  6. 206 203
      dist/converse-no-dependencies.js
  7. 304 103
      dist/converse.js
  8. 28 27
      index.html
  9. 0 0
      locale/af/LC_MESSAGES/converse.json
  10. 354 596
      locale/af/LC_MESSAGES/converse.po
  11. 0 0
      locale/ar/LC_MESSAGES/converse.json
  12. 137 9
      locale/ar/LC_MESSAGES/converse.po
  13. 0 0
      locale/bg/LC_MESSAGES/converse.json
  14. 355 598
      locale/bg/LC_MESSAGES/converse.po
  15. 0 0
      locale/ca/LC_MESSAGES/converse.json
  16. 1157 1005
      locale/ca/LC_MESSAGES/converse.po
  17. 340 391
      locale/converse.pot
  18. 0 0
      locale/de/LC_MESSAGES/converse.json
  19. 356 598
      locale/de/LC_MESSAGES/converse.po
  20. 0 0
      locale/es/LC_MESSAGES/converse.json
  21. 357 600
      locale/es/LC_MESSAGES/converse.po
  22. 0 0
      locale/eu/LC_MESSAGES/converse.json
  23. 370 604
      locale/eu/LC_MESSAGES/converse.po
  24. 0 0
      locale/fr/LC_MESSAGES/converse.json
  25. 12 75
      locale/fr/LC_MESSAGES/converse.po
  26. 0 0
      locale/he/LC_MESSAGES/converse.json
  27. 1120 965
      locale/he/LC_MESSAGES/converse.po
  28. 0 0
      locale/hu/LC_MESSAGES/converse.json
  29. 364 628
      locale/hu/LC_MESSAGES/converse.po
  30. 0 0
      locale/id/LC_MESSAGES/converse.json
  31. 1135 1000
      locale/id/LC_MESSAGES/converse.po
  32. 0 0
      locale/it/LC_MESSAGES/converse.json
  33. 354 595
      locale/it/LC_MESSAGES/converse.po
  34. 0 0
      locale/ja/LC_MESSAGES/converse.json
  35. 346 615
      locale/ja/LC_MESSAGES/converse.po
  36. 0 0
      locale/lt/LC_MESSAGES/converse.json
  37. 903 906
      locale/lt/LC_MESSAGES/converse.po
  38. 0 0
      locale/nb/LC_MESSAGES/converse.json
  39. 358 601
      locale/nb/LC_MESSAGES/converse.po
  40. 0 0
      locale/nl/LC_MESSAGES/converse.json
  41. 118 56
      locale/nl/LC_MESSAGES/converse.po
  42. 0 0
      locale/nl_BE/LC_MESSAGES/converse.json
  43. 120 33
      locale/nl_BE/LC_MESSAGES/converse.po
  44. 0 0
      locale/pl/LC_MESSAGES/converse.json
  45. 1142 984
      locale/pl/LC_MESSAGES/converse.po
  46. 0 0
      locale/pt_BR/LC_MESSAGES/converse.json
  47. 355 599
      locale/pt_BR/LC_MESSAGES/converse.po
  48. 0 643
      locale/pt_BR/LC_MESSAGES/pt_BR.js
  49. 0 0
      locale/ru/LC_MESSAGES/converse.json
  50. 358 592
      locale/ru/LC_MESSAGES/converse.po
  51. 0 0
      locale/tr/LC_MESSAGES/converse.json
  52. 776 804
      locale/tr/LC_MESSAGES/converse.po
  53. 0 0
      locale/uk/LC_MESSAGES/converse.json
  54. 1154 1001
      locale/uk/LC_MESSAGES/converse.po
  55. 0 0
      locale/zh_CN/LC_MESSAGES/converse.json
  56. 892 904
      locale/zh_CN/LC_MESSAGES/converse.po
  57. 0 0
      locale/zh_TW/LC_MESSAGES/converse.json
  58. 1103 957
      locale/zh_TW/LC_MESSAGES/converse.po
  59. 79 44
      mockup/chatbox.html
  60. 184 113
      mockup/chatroom.html
  61. 47 47
      mockup/user-panel.html
  62. 1 1
      mockup/utils.js
  63. 10 1
      sass/_bookmarks.scss
  64. 5 35
      sass/_chatbox.scss
  65. 6 8
      sass/_chatrooms.scss
  66. 70 59
      sass/_controlbox.scss
  67. 1 1
      sass/_core.scss
  68. 118 0
      sass/_lists.scss
  69. 93 21
      sass/_messages.scss
  70. 0 105
      sass/_roomslist.scss
  71. 1 33
      sass/_roster.scss
  72. 1 1
      sass/converse.scss
  73. 16 8
      spec/bookmarks.js
  74. 24 32
      spec/chatbox.js
  75. 120 113
      spec/chatroom.js
  76. 3 3
      spec/http-file-upload.js
  77. 461 157
      spec/messages.js
  78. 5 5
      spec/presence.js
  79. 47 7
      spec/roomslist.js
  80. 8 8
      spec/spoilers.js
  81. 8 8
      src/converse-bookmarks.js
  82. 98 57
      src/converse-chatboxes.js
  83. 101 23
      src/converse-chatview.js
  84. 8 3
      src/converse-controlbox.js
  85. 8 2
      src/converse-core.js
  86. 55 21
      src/converse-message-view.js
  87. 85 69
      src/converse-muc-views.js
  88. 19 15
      src/converse-muc.js
  89. 14 11
      src/converse-roomslist.js
  90. 21 1
      src/converse-roster.js
  91. 52 25
      src/converse-rosterview.js
  92. 9 5
      src/converse-singleton.js
  93. 0 6
      src/templates/action.html
  94. 2 4
      src/templates/bookmark.html
  95. 1 1
      src/templates/bookmarks_list.html
  96. 3 1
      src/templates/chatroom.html
  97. 10 3
      src/templates/chatroom_details_modal.html
  98. 7 1
      src/templates/chatroom_disconnect.html
  99. 11 11
      src/templates/chatroom_features.html
  100. 3 3
      src/templates/file_progress.html

+ 1 - 1
.eslintrc.json

@@ -34,7 +34,7 @@
         "array-bracket-spacing": "off",
         "array-callback-return": "error",
         "arrow-body-style": "off",
-        "arrow-parens": "error",
+        "arrow-parens": "off",
         "arrow-spacing": "error",
         "block-scoped-var": "off",
         "block-spacing": "off",

+ 1 - 0
CHANGES.md

@@ -7,6 +7,7 @@
 - #161 XEP-0363: HTTP File Upload
 - #194 Include entity capabilities in outgoing presence stanzas
 - #337 API call to update a VCard
+- #421 XEP-0308: Last Message Correction
 - #968 Use nickname from VCard when joining a room
 - #1091 There's now only one CSS file for all view modes.
 - #1094 Show room members who aren't currently online

+ 30 - 29
README.md

@@ -5,7 +5,7 @@
 [![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)
 
-[Converse.js](https://conversejs.org) is a web based [XMPP/Jabber](http://xmpp.org) instant messaging client.
+[Converse.js](https://conversejs.org) is a web based [XMPP/Jabber](https://xmpp.org) instant messaging client.
 
 It enables you to add chat functionality to your website, independent of
 any specific backend. You will however need an XMPP server to connect
@@ -23,13 +23,13 @@ avialable at [https://conversejs.org/demo/embedded.html](https://conversejs.org/
 
 ### Converse.js: As seen on the conversejs.org website
 
-![Screenshot of Converse.js](https://opkode.com/img/converse-screenshot.png)
+![Screenshot of Converse](https://opkode.com/img/converse-screenshot.png)
 
 ### inVerse: a fullscreen version of converse.js
 
-Converse.js is also available in a fullscreen version, called [inVerse](https://inverse.chat)
+Converse.js is also available in a fullscreen version, hosted at [inverse.chat](https://inverse.chat)
 
-![Screenshot of inVerse](https://opkode.com/img/inverse-screenshot.png)
+![Screenshot of Converse in fullscreen mode](https://opkode.com/img/inverse-screenshot.png)
 
 ## Documentation
 
@@ -43,45 +43,46 @@ which shows you how to use the CDN (content delivery network) to quickly get a d
 -   A [plugin architecture](https://conversejs.org/docs/html/plugin_development.html) based on [pluggable.js](https://conversejs.github.io/pluggable.js/)
 -   Single-user and group chats
 -   Contacts and groups
--   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)
--   vCard support [XEP 54](http://xmpp.org/extensions/xep-0054.html)
--   Service discovery [XEP 30](http://xmpp.org/extensions/xep-0030.html)
--   In-band registration [XEP 77](http://xmpp.org/extensions/xep-0077.html)
--   Chat room bookmarks [XEP 48](http://xmpp.org/extensions/xep-0048.html)
--   Roster item exchange [XEP 144](http://xmpp.org/extensions/tmp/xep-0144-1.1.html)
+-   Multi-user chat rooms [XEP 45](https://xmpp.org/extensions/xep-0045.html)
+-   Direct invitations to chat rooms [XEP 249](https://xmpp.org/extensions/xep-0249.html)
+-   vCard support [XEP 54](https://xmpp.org/extensions/xep-0054.html)
+-   Service discovery [XEP 30](https://xmpp.org/extensions/xep-0030.html)
+-   In-band registration [XEP 77](https://xmpp.org/extensions/xep-0077.html)
+-   Chat room bookmarks [XEP 48](https://xmpp.org/extensions/xep-0048.html)
+-   Roster item exchange [XEP 144](https://xmpp.org/extensions/tmp/xep-0144-1.1.html)
 -   Chat statuses (online, busy, away, offline)
 -   Custom status messages
 -   Desktop notifications
--   Typing and state notifications [XEP 85](http://xmpp.org/extensions/xep-0085.html)
--   Messages appear in all connnected chat clients [XEP 280](http://xmpp.org/extensions/xep-0280.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)
--   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)
+-   Typing and state notifications [XEP 85](https://xmpp.org/extensions/xep-0085.html)
+-   Messages appear in all connnected chat clients [XEP 280](https://xmpp.org/extensions/xep-0280.html)
+-   Third person "/me" messages [XEP 245](https://xmpp.org/extensions/xep-0245.html)
+-   XMPP Ping [XEP 199](https://xmpp.org/extensions/xep-0199.html)
+-   Server-side archiving of messages [XEP 313](https://xmpp.org/extensions/xep-0313.html)
+-   Hidden Messages (aka Spoilers) [XEP 382](https://xmpp.org/extensions/xep-0382.html)
+-   Client state indication [XEP 352](https://xmpp.org/extensions/xep-0352.html)
+-   Last Message Correction [XEP 308](https://xmpp.org/extensions/xep-0308.html)
 -   Off-the-record encryption
 -   Translated into 16 languages
 
 ## Integration into other frameworks
 
--   **[Ruby on Rails](http://rubyonrails.org)**: [conversejs-rails](https://github.com/mikemarsian/conversejs-rails)
--   **[Django](http://www.djangoproject.com)**: [django-conversejs](https://pypi.python.org/pypi/django-conversejs) or [django-xmpp](https://github.com/fpytloun/django-xmpp)
--   **[Plone](http://plone.com)**: [collective.converse](http://github.com/collective/collective.converse)
--   **[Roundcube](http://roundcube.net)**: [roundcube-converse.js-xmpp-plugin](https://github.com/devurandom/roundcube-converse.js-xmpp-plugin)
--   **[Wordpress](http://wordpress.org)**: [ConverseJS](http://wordpress.org/plugins/conversejs)
+-   **[Ruby on Rails](https://rubyonrails.org)**: [conversejs-rails](https://github.com/mikemarsian/conversejs-rails)
+-   **[Django](https://www.djangoproject.com)**: [django-conversejs](https://pypi.python.org/pypi/django-conversejs) or [django-xmpp](https://github.com/fpytloun/django-xmpp)
+-   **[Plone](https://plone.com)**: [collective.converse](https://github.com/collective/collective.converse)
+-   **[Roundcube](https://roundcube.net)**: [roundcube-converse.js-xmpp-plugin](https://github.com/devurandom/roundcube-converse.js-xmpp-plugin)
+-   **[Wordpress](https://wordpress.org)**: [ConverseJS](https://wordpress.org/plugins/conversejs/)
 -   **[Patternslib](http://patternslib.com)**: [patterns.converse](https://github.com/jcbrand/patterns.converse)
--   **[Alfresco](http://www.alfresco.com)**: [alfresco-js-chat-share](https://github.com/keensoft/alfresco-js-chat-share)
--   **[Friendica](http://friendica.com)**: [converse](https://github.com/friendica/friendica-addons/tree/master/xmpp/converse)
--   **[Tiki Wiki CMS Groupware](http://tiki.org)**: [built-in optional feature](https://doc.tiki.org/XMPP)
+-   **[Alfresco](https://www.alfresco.com)**: [alfresco-js-chat-share](https://github.com/keensoft/alfresco-js-chat-share)
+-   **[Friendica](https://friendi.ca)**: [converse](https://github.com/friendica/friendica-addons/tree/master/xmpp/converse)
+-   **[Tiki Wiki CMS Groupware](https://tiki.org)**: [built-in optional feature](https://doc.tiki.org/XMPP)
 
 ## Screencasts
 
 *Note: These screencasts are already quite old! Converse.js has grown and evolved further since then.*
 
--   [In a static HTML page](http://opkode.com/media/blog/2013/04/02/converse.js-xmpp-instant-messaging-with-javascript).
+-   [In a static HTML page](https://opkode.com/media/blog/2013/04/02/converse.js-xmpp-instant-messaging-with-javascript).
     Here we chat to external XMPP accounts on Jabber.org and Gmail.
--   [Integrated into a Plone site](http://opkode.com/media/blog/instant-messaging-for-plone-with-javascript-and-xmpp)
+-   [Integrated into a Plone site](https://opkode.com/media/blog/instant-messaging-for-plone-with-javascript-and-xmpp)
     via collective.xmpp.chat.
 -   [Off-the-record encryption](https://opkode.com/media/blog/2013/11/11/conversejs-otr-support)
     in Converse 0.7.
@@ -123,4 +124,4 @@ The following people are making recurring donations:
 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)
+* [![Wikisuite](https://conversejs.org/logo/wikisuite.png)](https://wikisuite.org)

+ 269 - 277
css/converse.css

@@ -6872,7 +6872,7 @@ body.reset {
     flex-direction: row-reverse; }
   #conversejs.converse-fullscreen .converse-chatboxes, #conversejs.converse-mobile .converse-chatboxes {
     width: 100vw;
-    right: 15px; }
+    left: -15px; }
   #conversejs.converse-overlayed {
     height: 3em; }
   #conversejs .brand-heading {
@@ -7346,9 +7346,8 @@ body.reset {
     max-width: 25%;
     padding: 0; }
   #conversejs .chat-head .user-custom-message {
-    color: white;
+    color: #e7f7ee;
     font-size: 75%;
-    font-style: italic;
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap;
@@ -7389,7 +7388,7 @@ body.reset {
     background-color: #3AA569;
     box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
     z-index: 1;
-    overflow-y: scroll;
+    overflow-y: hidden;
     width: 100%; }
     @media screen and (max-height: 450px) {
       #conversejs .chatbox .box-flyout {
@@ -7656,18 +7655,6 @@ body.reset {
   #conversejs.converse-overlayed .chatbox .box-flyout {
     min-width: 250px !important;
     width: 250px; }
-  #conversejs.converse-embedded .chatbox .chat-body .chat-message,
-  #conversejs.converse-overlayed .chatbox .chat-body .chat-message {
-    line-height: 20px; }
-    #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-author,
-    #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-author {
-      line-height: 20px; }
-    #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content,
-    #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content {
-      line-height: 20px; }
-      #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content .emojione,
-      #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content .emojione {
-        margin-bottom: -5px; }
 #conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
 #conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
   min-width: 235px; }
@@ -7709,7 +7696,7 @@ body.reset {
   font-size: 20px;
   padding: 0; }
   #conversejs.converse-fullscreen .chat-head .user-custom-message {
-    font-size: 50%;
+    font-size: 70%;
     height: auto;
     line-height: 16px; }
   #conversejs.converse-fullscreen .chat-head .chatbox-title {
@@ -7733,8 +7720,8 @@ body.reset {
   padding-left: 15px; }
   @media (min-width: 768px) {
     #conversejs.converse-fullscreen .chatbox {
-      flex: 0 0 75%;
-      max-width: 75%; } }
+      flex: 0 0 66.6666666667%;
+      max-width: 66.6666666667%; } }
   @media (min-width: 992px) {
     #conversejs.converse-fullscreen .chatbox {
       flex: 0 0 75%;
@@ -7748,21 +7735,12 @@ body.reset {
     box-shadow: none;
     height: 100vh;
     min-height: 50vh;
-    width: 100%; }
+    width: 100%;
+    overflow: hidden; }
   #conversejs.converse-fullscreen .chatbox .chat-body {
     background-color: #3AA569;
     border-top-left-radius: 4px;
     border-top-right-radius: 4px; }
-    #conversejs.converse-fullscreen .chatbox .chat-body .chat-message {
-      line-height: 16px;
-      font-size: 12px; }
-      #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-author {
-        line-height: 16px; }
-      #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content {
-        line-height: 16px; }
-        #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content .emojione {
-          height: 16px;
-          margin-bottom: -4px; }
   #conversejs.converse-fullscreen .chatbox .chat-content {
     border-top-left-radius: 4px;
     border-top-right-radius: 4px; }
@@ -7828,15 +7806,24 @@ body.reset {
         color: #578EA9;
         font-size: 20px;
         margin-right: 0.5em; }
-#conversejs .set-xmpp-status .fa-circle, #conversejs .xmpp-status .fa-circle, #conversejs .roster-contacts .fa-circle {
+#conversejs .set-xmpp-status .fa-circle,
+#conversejs .xmpp-status .fa-circle,
+#conversejs .roster-contacts .fa-circle {
   color: #3AA569; }
-#conversejs .set-xmpp-status .fa-minus-circle, #conversejs .xmpp-status .fa-minus-circle, #conversejs .roster-contacts .fa-minus-circle {
+#conversejs .set-xmpp-status .fa-minus-circle,
+#conversejs .xmpp-status .fa-minus-circle,
+#conversejs .roster-contacts .fa-minus-circle {
   color: #E77051; }
-#conversejs .set-xmpp-status .fa-dot-circle-o, #conversejs .xmpp-status .fa-dot-circle-o, #conversejs .roster-contacts .fa-dot-circle-o {
+#conversejs .set-xmpp-status .fa-dot-circle-o,
+#conversejs .xmpp-status .fa-dot-circle-o,
+#conversejs .roster-contacts .fa-dot-circle-o {
   color: #E7A151; }
-#conversejs .set-xmpp-status .fa-circle-o, #conversejs .xmpp-status .fa-circle-o, #conversejs .roster-contacts .fa-circle-o {
-  color: #A8ABA1; }
-#conversejs .set-xmpp-status .fa-times-circle, #conversejs .xmpp-status .fa-times-circle, #conversejs .roster-contacts .fa-times-circle {
+#conversejs .set-xmpp-status .fa-circle-o,
+#conversejs .set-xmpp-status .fa-times-circle,
+#conversejs .xmpp-status .fa-circle-o,
+#conversejs .xmpp-status .fa-times-circle,
+#conversejs .roster-contacts .fa-circle-o,
+#conversejs .roster-contacts .fa-times-circle {
   color: #A8ABA1; }
 #conversejs .room-info {
   font-size: 12px;
@@ -8049,37 +8036,6 @@ body.reset {
   #conversejs .toggle-controlbox span {
     color: white; }
 
-@media (max-width: 767.98px) {
-  #conversejs:not(.converse-embedded) {
-    left: 0;
-    right: 0;
-    padding-left: env(safe-area-inset-left);
-    padding-right: env(safe-area-inset-right); }
-    #conversejs:not(.converse-embedded) .converse-chatboxes {
-      margin: 0 !important;
-      flex-direction: row !important;
-      justify-content: space-between; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes .converse-chatroom {
-        font-size: 14px; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes .chatbox .box-flyout {
-        margin-left: 15px;
-        left: 0;
-        bottom: 0;
-        border-radius: 0;
-        width: 100vw !important;
-        height: 100vh !important; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox {
-        width: 100vw !important; }
-        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .box-flyout {
-          width: 100vw !important;
-          height: 100vh !important;
-          margin-left: 30px; }
-        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .sidebar {
-          display: block; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open .chatbox:not(#controlbox) {
-        display: none; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open #controlbox .controlbox-pane {
-        display: block; } }
 #conversejs.converse-overlayed #controlbox {
   order: -1;
   min-width: 250px !important;
@@ -8127,8 +8083,8 @@ body.reset {
   @media (min-width: 768px) {
     #conversejs.converse-fullscreen #controlbox,
     #conversejs.converse-mobile #controlbox {
-      flex: 0 0 25%;
-      max-width: 25%; } }
+      flex: 0 0 33.3333333333%;
+      max-width: 33.3333333333%; } }
   @media (min-width: 992px) {
     #conversejs.converse-fullscreen #controlbox,
     #conversejs.converse-mobile #controlbox {
@@ -8256,106 +8212,39 @@ body.reset {
     #conversejs.converse-mobile #controlbox #converse-login input[type=button] {
       width: auto; }
 
-#conversejs .list-container {
-  text-align: left;
-  padding: 0.3em 0; }
-  #conversejs .list-container .rooms-toggle {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-    display: block;
-    color: #666;
-    padding: 0 0 0.5rem 0; }
-    #conversejs .list-container .rooms-toggle:hover {
-      color: #585B51; }
-  #conversejs .list-container .items-list {
-    text-align: left; }
-    #conversejs .list-container .items-list .list-item {
-      border: none;
-      clear: both;
-      color: #666;
-      display: block;
-      height: 2em;
-      overflow: hidden;
-      padding-top: 0.5em;
-      text-shadow: 0 1px 0 #FAFAFA;
-      word-wrap: break-word; }
-    #conversejs .list-container .items-list .available-chatroom:hover,
-    #conversejs .list-container .items-list .open-headline:hover,
-    #conversejs .list-container .items-list .open-chatroom:hover {
-      background-color: #eff4f7; }
-      #conversejs .list-container .items-list .available-chatroom:hover a.add-bookmark,
-      #conversejs .list-container .items-list .available-chatroom:hover a.room-info,
-      #conversejs .list-container .items-list .open-headline:hover a.add-bookmark,
-      #conversejs .list-container .items-list .open-headline:hover a.room-info,
-      #conversejs .list-container .items-list .open-chatroom:hover a.add-bookmark,
-      #conversejs .list-container .items-list .open-chatroom:hover a.room-info {
-        display: block !important; }
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .msgs-indicator,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .msgs-indicator,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .msgs-indicator {
-      border-radius: 10%;
-      opacity: 1; }
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .available-room,
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .open-room,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .available-room,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .open-room,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .available-room,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .open-room {
-      width: 100%;
-      font-weight: bold; }
-    #conversejs .list-container .items-list .available-chatroom a:hover,
-    #conversejs .list-container .items-list .open-headline a:hover,
-    #conversejs .list-container .items-list .open-chatroom a:hover {
-      color: #206485; }
-    #conversejs .list-container .items-list .available-chatroom a.add-bookmark, #conversejs .list-container .items-list .available-chatroom a.room-info,
-    #conversejs .list-container .items-list .open-headline a.add-bookmark,
-    #conversejs .list-container .items-list .open-headline a.room-info,
-    #conversejs .list-container .items-list .open-chatroom a.add-bookmark,
-    #conversejs .list-container .items-list .open-chatroom a.room-info {
-      display: none; }
-      #conversejs .list-container .items-list .available-chatroom a.add-bookmark:before, #conversejs .list-container .items-list .available-chatroom a.room-info:before,
-      #conversejs .list-container .items-list .open-headline a.add-bookmark:before,
-      #conversejs .list-container .items-list .open-headline a.room-info:before,
-      #conversejs .list-container .items-list .open-chatroom a.add-bookmark:before,
-      #conversejs .list-container .items-list .open-chatroom a.room-info:before {
-        font-size: 15px; }
-    #conversejs .list-container .items-list .available-chatroom a.open-room,
-    #conversejs .list-container .items-list .open-headline a.open-room,
-    #conversejs .list-container .items-list .open-chatroom a.open-room {
-      width: 68%;
-      float: left;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      padding-right: 0.5em; }
-    #conversejs .list-container .items-list .available-chatroom a.available-room,
-    #conversejs .list-container .items-list .open-headline a.available-room,
-    #conversejs .list-container .items-list .open-chatroom a.available-room {
-      width: 85%; }
-    #conversejs .list-container .items-list .available-chatroom .add-bookmark,
-    #conversejs .list-container .items-list .available-chatroom .remove-bookmark,
-    #conversejs .list-container .items-list .open-headline .add-bookmark,
-    #conversejs .list-container .items-list .open-headline .remove-bookmark,
-    #conversejs .list-container .items-list .open-chatroom .add-bookmark,
-    #conversejs .list-container .items-list .open-chatroom .remove-bookmark {
-      color: #A8ABA1; }
-      #conversejs .list-container .items-list .available-chatroom .add-bookmark.button-on,
-      #conversejs .list-container .items-list .available-chatroom .remove-bookmark.button-on,
-      #conversejs .list-container .items-list .open-headline .add-bookmark.button-on,
-      #conversejs .list-container .items-list .open-headline .remove-bookmark.button-on,
-      #conversejs .list-container .items-list .open-chatroom .add-bookmark.button-on,
-      #conversejs .list-container .items-list .open-chatroom .remove-bookmark.button-on {
-        color: #578EA9; }
-        #conversejs .list-container .items-list .available-chatroom .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .available-chatroom .remove-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-headline .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-headline .remove-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-chatroom .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-chatroom .remove-bookmark.button-on:hover {
-          color: #206485; }
-
-#conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room {
-  width: 80%; }
+@media (max-width: 767.98px) {
+  #conversejs:not(.converse-embedded) {
+    left: 0;
+    right: 0;
+    padding-left: env(safe-area-inset-left);
+    padding-right: env(safe-area-inset-right); }
+    #conversejs:not(.converse-embedded) .converse-chatboxes {
+      margin: 0 !important;
+      flex-direction: row !important;
+      justify-content: space-between; }
+      #conversejs:not(.converse-embedded) .converse-chatboxes .converse-chatroom {
+        font-size: 14px; }
+      #conversejs:not(.converse-embedded) .converse-chatboxes .chatbox .box-flyout {
+        margin-left: 15px;
+        left: 0;
+        bottom: 0;
+        border-radius: 0;
+        width: 100vw !important;
+        height: 100vh !important; }
+      #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox {
+        width: 100vw !important; }
+        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .box-flyout {
+          width: 100vw !important;
+          height: 100vh !important; }
+        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .sidebar {
+          display: block; }
+      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open .chatbox:not(#controlbox) {
+        display: none; }
+      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open #controlbox .controlbox-pane {
+        display: block; }
 
+  #conversejs.converse-overlayed .converse-chatboxes .chatbox .box-flyout {
+    margin-left: 30px; } }
 #conversejs #converse-roster {
   text-align: left;
   width: 100%;
@@ -8405,87 +8294,142 @@ body.reset {
         padding-bottom: 0.3rem; }
         #conversejs #converse-roster .roster-contacts .roster-group .group-toggle:hover {
           color: #585B51; }
-      #conversejs #converse-roster .roster-contacts .roster-group li {
-        border: none;
-        clear: both;
-        color: #666;
-        display: block;
-        overflow-y: hidden;
-        text-shadow: 0 1px 0 #FAFAFA;
-        line-height: 14px;
-        width: 100%;
-        height: 2em;
-        padding-top: 0.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a {
-          line-height: 16px; }
-          #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a.fa {
-            width: 1.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact .req-contact-name {
-          padding: 0 0.2em 0 0; }
-        #conversejs #converse-roster .roster-contacts .roster-group li a:hover {
-          color: #206485; }
-        #conversejs #converse-roster .roster-contacts .roster-group li a .fa:hover {
-          color: white; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .open-chat {
-          margin: 0;
-          padding: 0; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs {
-            font-weight: bold; }
-            #conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs .contact-name {
-              width: 70%; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .msgs-indicator {
-            color: white;
-            background-color: #3AA569;
-            opacity: 1;
-            border-radius: 10%;
-            padding: 0.2em;
-            font-size: 12px; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name {
-            overflow: hidden;
-            white-space: nowrap;
-            text-overflow: ellipsis;
-            padding: 0;
-            margin: 0;
-            max-width: 80%;
-            float: none;
-            height: 100%; }
-            #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name.unread-msgs {
-              max-width: 60%; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .avatar {
-            float: left;
-            display: inline-block; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.current-xmpp-contact span {
-          font-size: 14px;
-          float: left;
-          margin-right: 0.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.odd {
-          background-color: #DCEAC5;
-          /* Make this difference */ }
-        #conversejs #converse-roster .roster-contacts .roster-group li a, #conversejs #converse-roster .roster-contacts .roster-group li span {
-          display: inline-block;
+      #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a {
+        line-height: 16px; }
+        #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a.fa {
+          width: 1.5em; }
+      #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact .req-contact-name {
+        padding: 0 0.2em 0 0; }
+      #conversejs #converse-roster .roster-contacts .roster-group li .open-chat {
+        margin: 0;
+        padding: 0; }
+        #conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs {
+          font-weight: bold; }
+          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs .contact-name {
+            width: 70%; }
+        #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .msgs-indicator {
+          color: white;
+          background-color: #3AA569;
+          opacity: 1;
+          border-radius: 10%;
+          padding: 0.2em;
+          font-size: 12px; }
+        #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name {
           overflow: hidden;
           white-space: nowrap;
-          text-overflow: ellipsis; }
-        #conversejs #converse-roster .roster-contacts .roster-group li span {
-          padding: 0; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .decline-xmpp-request {
-          margin-left: 5px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .remove-xmpp-contact {
-          font-size: 10px;
-          margin: 0;
+          text-overflow: ellipsis;
           padding: 0;
-          width: 2em;
-          display: none; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .remove-xmpp-contact:before {
-            font-size: 14px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li:hover {
-          background-color: #eff4f7; }
-          #conversejs #converse-roster .roster-contacts .roster-group li:hover .remove-xmpp-contact {
-            display: inline-block; }
+          margin: 0;
+          max-width: 90%;
+          float: none;
+          height: 100%; }
+          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name.unread-msgs {
+            max-width: 60%; }
+        #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .avatar {
+          float: left;
+          display: inline-block; }
+      #conversejs #converse-roster .roster-contacts .roster-group li.current-xmpp-contact span {
+        font-size: 14px;
+        float: left;
+        margin-right: 0.5em; }
+      #conversejs #converse-roster .roster-contacts .roster-group li.odd {
+        background-color: #DCEAC5;
+        /* Make this difference */ }
+      #conversejs #converse-roster .roster-contacts .roster-group li a, #conversejs #converse-roster .roster-contacts .roster-group li span {
+        display: inline-block;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis; }
+      #conversejs #converse-roster .roster-contacts .roster-group li .decline-xmpp-request {
+        margin-left: 5px; }
+      #conversejs #converse-roster .roster-contacts .roster-group li:hover {
+        background-color: #eff4f7; }
+        #conversejs #converse-roster .roster-contacts .roster-group li:hover .remove-xmpp-contact {
+          display: inline-block; }
   #conversejs #converse-roster span.pending-contact-name {
     line-height: 16px;
     width: 100%; }
 
+#conversejs .list-container {
+  text-align: left;
+  padding: 0.3em 0; }
+  #conversejs .list-container .list-toggle {
+    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
+    display: block;
+    color: #666;
+    padding: 0 0 0.5rem 0; }
+    #conversejs .list-container .list-toggle:hover {
+      color: #585B51; }
+#conversejs .items-list {
+  text-align: left; }
+  #conversejs .items-list .list-item {
+    border: none;
+    clear: both;
+    color: #666;
+    display: block;
+    height: 2em;
+    overflow: hidden;
+    padding-top: 0.5em;
+    text-shadow: 0 1px 0 #FAFAFA;
+    word-wrap: break-word; }
+    #conversejs .items-list .list-item .list-item-link {
+      font-size: 14px;
+      line-height: 14px;
+      padding-right: 0.5em;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis; }
+      #conversejs .items-list .list-item .list-item-link:hover {
+        color: #206485; }
+    #conversejs .items-list .list-item .list-item-action {
+      opacity: 0;
+      font-size: 10px;
+      padding: 0;
+      margin: 0 0 0 0.4em;
+      width: 1.6em;
+      color: #A8ABA1; }
+      #conversejs .items-list .list-item .list-item-action:before {
+        font-size: 14px; }
+      #conversejs .items-list .list-item .list-item-action.button-on {
+        color: #578EA9; }
+        #conversejs .items-list .list-item .list-item-action.button-on:hover {
+          color: #206485; }
+      #conversejs .items-list .list-item .list-item-action:hover {
+        color: #818479;
+        opacity: 1; }
+    #conversejs .items-list .list-item.open {
+      background-color: #578EA9; }
+      #conversejs .items-list .list-item.open:hover {
+        background-color: #578EA9 !important; }
+      #conversejs .items-list .list-item.open a {
+        color: white; }
+      #conversejs .items-list .list-item.open .list-item-link:hover {
+        color: white; }
+      #conversejs .items-list .list-item.open .list-item-action {
+        color: #e3eef3; }
+        #conversejs .items-list .list-item.open .list-item-action:hover {
+          color: white; }
+      #conversejs .items-list .list-item.open .fa-circle {
+        color: #89d6ab; }
+      #conversejs .items-list .list-item.open .fa-minus-circle {
+        color: #f0a794; }
+      #conversejs .items-list .list-item.open .fa-dot-circle-o {
+        color: #f0c594; }
+      #conversejs .items-list .list-item.open .fa-circle-o,
+      #conversejs .items-list .list-item.open .fa-times-circle {
+        color: #e6e7e4; }
+    #conversejs .items-list .list-item:hover {
+      background-color: #eff4f7; }
+      #conversejs .items-list .list-item:hover .fa {
+        opacity: 1; }
+    #conversejs .items-list .list-item.unread-msgs .msgs-indicator {
+      border-radius: 10%;
+      opacity: 1; }
+    #conversejs .items-list .list-item.unread-msgs .available-room,
+    #conversejs .items-list .list-item.unread-msgs .open-room {
+      width: 100%;
+      font-weight: bold; }
+
 #conversejs.converse-embedded .add-chatroom input[type="submit"],
 #conversejs.converse-embedded .add-chatroom input[type="button"],
 #conversejs .add-chatroom input[type="submit"],
@@ -8597,9 +8541,13 @@ body.reset {
       #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .mentioned,
       #conversejs .chatroom .box-flyout .chatroom-body .mentioned {
         font-weight: bold; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-msg,
-      #conversejs .chatroom .box-flyout .chatroom-body .disconnect-msg {
-        padding: 2em 2em 0 2em; }
+      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-container,
+      #conversejs .chatroom .box-flyout .chatroom-body .disconnect-container {
+        margin: 1em;
+        width: 100%; }
+        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg,
+        #conversejs .chatroom .box-flyout .chatroom-body .disconnect-container h3.disconnect-msg {
+          padding-bottom: 1em; }
       #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area,
       #conversejs .chatroom .box-flyout .chatroom-body .chat-area {
         display: flex;
@@ -8715,11 +8663,6 @@ body.reset {
         #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message {
           font-size: 90%;
           color: #A53214; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form label,
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form input[type=text],
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form label,
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form input[type=text] {
-          display: block; }
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit],
         #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],
@@ -8889,7 +8832,7 @@ body.reset {
   width: auto;
   max-height: 15em;
   max-width: 100%; }
-#conversejs .message.chat-action {
+#conversejs .message.chat-msg--action {
   font-style: italic; }
 #conversejs .message.chat-msg {
   display: flex;
@@ -8901,6 +8844,12 @@ body.reset {
     -webkit-animation: colorchange-chatmessage 1s; }
   #conversejs .message.chat-msg:hover {
     background-color: rgba(0, 0, 0, 0.035); }
+    #conversejs .message.chat-msg:hover .chat-msg__actions .chat-msg__action {
+      opacity: 1; }
+  #conversejs .message.chat-msg.correcting.groupchat {
+    background-color: #fdf1ee; }
+  #conversejs .message.chat-msg.correcting:not(.groupchat) {
+    background-color: #e7f7ee; }
   #conversejs .message.chat-msg .spoiler {
     margin-top: 0.5em; }
   #conversejs .message.chat-msg .spoiler-hint {
@@ -8913,54 +8862,94 @@ body.reset {
     #conversejs .message.chat-msg .spoiler-toggle:before {
       padding-right: 0.25em;
       whitespace: nowrap; }
-  #conversejs .message.chat-msg .chat-msg-content {
+  #conversejs .message.chat-msg .chat-msg__content {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    align-items: stretch;
     margin-left: 0.5rem;
     width: 100%; }
-  #conversejs .message.chat-msg.headline .chat-msg-content {
+  #conversejs .message.chat-msg .chat-msg__content--action {
+    margin-left: 0; }
+  #conversejs .message.chat-msg .chat-msg__body {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    width: 100%; }
+  #conversejs .message.chat-msg .chat-msg__message {
+    display: flex;
+    flex-direction: column;
+    width: 100%; }
+  #conversejs .message.chat-msg .chat-msg__edit-modal {
+    cursor: pointer;
+    padding-right: 0.5em; }
+  #conversejs .message.chat-msg.headline .chat-msg__body {
     margin-left: 0; }
-  #conversejs .message.chat-msg .chat-msg-text {
+  #conversejs .message.chat-msg .chat-msg__text {
     padding: 0;
-    color: #555; }
-    #conversejs .message.chat-msg .chat-msg-text a {
+    color: #555;
+    width: 100%; }
+    #conversejs .message.chat-msg .chat-msg__text a {
       word-wrap: break-word;
       word-break: break-all; }
-    #conversejs .message.chat-msg .chat-msg-text .emojione {
+    #conversejs .message.chat-msg .chat-msg__text .emojione {
       margin-bottom: -6px; }
-  #conversejs .message.chat-msg .chat-msg-media {
-    margin-top: 0.25rem; }
-    #conversejs .message.chat-msg .chat-msg-media a {
+  #conversejs .message.chat-msg .chat-msg__media {
+    margin-top: 0.25rem;
+    word-break: break-all; }
+    #conversejs .message.chat-msg .chat-msg__media a {
       word-wrap: break-word; }
-    #conversejs .message.chat-msg .chat-msg-media audio {
+    #conversejs .message.chat-msg .chat-msg__media audio {
       width: 100%; }
-  #conversejs .message.chat-msg .avatar {
+  #conversejs .message.chat-msg .chat-msg__actions .chat-msg__action {
+    height: 14px;
+    font-size: 14px;
+    padding: 0;
+    border: none;
+    opacity: 0;
+    background: transparent;
+    cursor: pointer; }
+    #conversejs .message.chat-msg .chat-msg__actions .chat-msg__action:focus {
+      display: block; }
+  #conversejs .message.chat-msg .chat-msg__avatar {
     margin-top: 0.5em;
     height: 36px;
     vertical-align: middle;
     width: 36px; }
-  #conversejs .message.chat-msg .chat-msg-heading {
+  #conversejs .message.chat-msg .chat-msg__heading {
+    width: 100%;
     margin-top: 0.5em;
     padding-right: 0.25rem;
     padding-bottom: 0.25rem;
     display: block; }
-    #conversejs .message.chat-msg .chat-msg-heading .chat-msg-author {
+    #conversejs .message.chat-msg .chat-msg__heading .chat-msg__author {
+      white-space: nowrap;
       font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
       font-size: 115%; }
-      #conversejs .message.chat-msg .chat-msg-heading .chat-msg-author .badge {
+      #conversejs .message.chat-msg .chat-msg__heading .chat-msg__author .badge {
         font-size: 80%;
         font-family: "Helvetica", "Arial", sans-serif; }
-    #conversejs .message.chat-msg .chat-msg-heading .chat-msg-time {
+    #conversejs .message.chat-msg .chat-msg__heading .chat-msg__time {
       padding-left: 0.25em;
       color: #8c8c8c; }
-  #conversejs .message.chat-msg.chat-action {
-    display: block; }
-    #conversejs .message.chat-msg.chat-action .chat-msg-heading {
-      float: left;
-      margin-top: 0;
-      padding-bottom: 0; }
-  #conversejs .message.chat-msg.chat-msg-followup .chat-msg-heading,
-  #conversejs .message.chat-msg.chat-msg-followup .avatar {
+  #conversejs .message.chat-msg.chat-msg--action .chat-msg__content {
+    flex-wrap: wrap;
+    flex-direction: row;
+    justify-content: flex-start; }
+  #conversejs .message.chat-msg.chat-msg--action .chat-msg__text {
+    width: auto; }
+  #conversejs .message.chat-msg.chat-msg--action .chat-msg__heading {
+    margin-top: 0;
+    padding-bottom: 0;
+    width: auto; }
+  #conversejs .message.chat-msg.chat-msg--action .chat-msg__author {
+    font-size: 14px; }
+  #conversejs .message.chat-msg.chat-msg--action .chat-msg__time {
+    margin-left: 0; }
+  #conversejs .message.chat-msg.chat-msg--followup .chat-msg__heading,
+  #conversejs .message.chat-msg.chat-msg--followup .chat-msg__avatar {
     display: none; }
-  #conversejs .message.chat-msg.chat-msg-followup .chat-msg-content {
+  #conversejs .message.chat-msg.chat-msg--followup .chat-msg__content {
     margin-left: 2.75rem; }
 #conversejs .chatroom-body .message.onload {
   animation: colorchange-chatmessage-muc 1s;
@@ -8968,11 +8957,11 @@ body.reset {
 #conversejs .chatroom-body .message .separator {
   border: 0.5px solid #E77051; }
 
-#conversejs.converse-overlayed .message.chat-msg.chat-msg-followup .chat-msg-content {
+#conversejs.converse-overlayed .message.chat-msg.chat-msg--followup .chat-msg__body {
   margin-left: 0; }
 
 @media screen and (max-width: 767px) {
-  #conversejs:not(.converse-embedded) .message.chat-msg .chat-msg-author {
+  #conversejs:not(.converse-embedded) .message.chat-msg .chat-msg__author {
     white-space: normal; } }
 #conversejs.converse-overlayed #minimized-chats {
   order: 100;
@@ -9040,6 +9029,9 @@ body.reset {
   #conversejs.converse-overlayed #minimized-chats .chat-head-message-count-hidden {
     display: none; }
 
+#conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room {
+  width: 80%; }
+
 #conversejs [hidden] {
   display: none; }
 #conversejs .visually-hidden {

+ 1 - 1
demo/embedded.html

@@ -16,7 +16,7 @@
     <noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
     <![if gte IE 11]>
         <link type="text/css" rel="stylesheet" media="screen" href="/css/converse.css" />
-        <script src="/dist/converse.min.js"></script>
+        <script src="/dist/converse.js"></script>
     <![endif]>
 
     <style>

File diff suppressed because it is too large
+ 206 - 203
dist/converse-no-dependencies.js


File diff suppressed because it is too large
+ 304 - 103
dist/converse.js


+ 28 - 27
index.html

@@ -110,7 +110,7 @@
                 <p>Take a look at the <a href="/demo">demo page</a> for other examples of how Converse can be configured and used.</a>
 
                 <p>
-                    You can connect to any publically accessible <a href="http://xmpp.org" target="_blank" rel="noopener">XMPP/Jabber</a> server,
+                    You can connect to any publically accessible <a href="https://xmpp.org" target="_blank" rel="noopener">XMPP/Jabber</a> server,
                     either from a <a href="https://xmpp.net/directory.php">public provider</a>, or one you have set up yourself.
                 </p>
                 <h3>Don't have an XMPP/Jabber account?</h3>
@@ -133,11 +133,11 @@
                             <li><a href="https://www.igniterealtime.org/projects/openfire/plugins.jsp" target="_blank" rel="noopener">Openfire</a></li>
                             <li><a href="https://modules.prosody.im/mod_conversejs.html" target="_blank" rel="noopener">Prosody</a></li>
                             <li><a href="https://github.com/mikemarsian/conversejs-rails" target="_blank" rel="noopener">Ruby on Rails</a></li>
-                            <li><a href="http://github.com/collective/collective.converse" target="_blank" rel="noopener">Plone</a></li>
+                            <li><a href="https://github.com/collective/collective.converse" target="_blank" rel="noopener">Plone</a></li>
                             <li><a href="https://pypi.python.org/pypi/django-conversejs" target="_blank" rel="noopener">Django (option 1)</a></li>
                             <li><a href="https://github.com/fpytloun/django-xmpp" target="_blank" rel="noopener">Django (option 2)</a></li>
                             <li><a href="https://github.com/devurandom/roundcube-converse.js-xmpp-plugin" target="_blank" rel="noopener">Roundcube</a></li>
-                            <li><a href="http://wordpress.org/plugins/conversejs" target="_blank" rel="noopener">Wordpress</a></li>
+                            <li><a href="https://wordpress.org/plugins/conversejs/" target="_blank" rel="noopener">Wordpress</a></li>
                             <li><a href="https://github.com/jcbrand/patterns.converse" target="_blank" rel="noopener">Patternslib</a></li>
                             <li><a href="https://github.com/keensoft/alfresco-js-chat-share" target="_blank" rel="noopener">Alfresco</a></li>
                             <li><a href="https://github.com/friendica/friendica-addons/tree/master/xmpp/converse" target="_blank" rel="noopener">Friendica</a></li>
@@ -157,23 +157,24 @@
                             </li>
                             <li><a href="https://conversejs.org/docs/html/plugin_development.html">Plugin Architecture</a></li>
                             <li>Single-user and group chat</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>Direct invitations to chat rooms (<a href="http://xmpp.org/extensions/xep-0249.html" target="_blank" rel="noopener">XEP 249</a>)</li>
-                            <li>vCard support (<a href="http://xmpp.org/extensions/xep-0054.html" target="_blank" rel="noopener">XEP 54</a>)</li>
-                            <li>Service discovery (<a href="http://xmpp.org/extensions/xep-0030.html" target="_blank" rel="noopener">XEP 30</a>)</li>
-                            <li>In-band registration (<a href="http://xmpp.org/extensions/xep-0077.html" target="_blank" rel="noopener">XEP 77</a>)</li>
-                            <li>Roster item exchange (<a href="http://xmpp.org/extensions/xep-0144.html" target="_blank" rel="noopener">XEP 144</a>)</li>
+                            <li>Multi-user chatrooms (<a href="https://xmpp.org/extensions/xep-0045.html" target="_blank" rel="noopener">XEP 45</a>)</li>
+                            <li>Chatroom bookmarks (<a href="https://xmpp.org/extensions/xep-0048.html" target="_blank" rel="noopener">XEP 48</a>)</li>
+                            <li>Direct invitations to chat rooms (<a href="https://xmpp.org/extensions/xep-0249.html" target="_blank" rel="noopener">XEP 249</a>)</li>
+                            <li>vCard support (<a href="https://xmpp.org/extensions/xep-0054.html" target="_blank" rel="noopener">XEP 54</a>)</li>
+                            <li>Service discovery (<a href="https://xmpp.org/extensions/xep-0030.html" target="_blank" rel="noopener">XEP 30</a>)</li>
+                            <li>In-band registration (<a href="https://xmpp.org/extensions/xep-0077.html" target="_blank" rel="noopener">XEP 77</a>)</li>
+                            <li>Roster item exchange (<a href="https://xmpp.org/extensions/xep-0144.html" target="_blank" rel="noopener">XEP 144</a>)</li>
                             <li>Custom status messages</li>
-                            <li>Typing and chat state notifications (<a href="http://xmpp.org/extensions/xep-0085.html" target="_blank" rel="noopener">XEP 85</a>)</li>
+                            <li>Typing and chat state notifications (<a href="https://xmpp.org/extensions/xep-0085.html" target="_blank" rel="noopener">XEP 85</a>)</li>
                             <li>Desktop notifications</li>
-                            <li>File sharing (<a href="http://xmpp.org/extensions/xep-0363.html" target="_blank" rel="noopener">XEP 363</a>)</li>
-                            <li>Messages appear in all connected chat clients (<a href="http://xmpp.org/extensions/xep-0280.html" target="_blank" rel="noopener">XEP 280</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>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>File sharing (<a href="https://xmpp.org/extensions/xep-0363.html" target="_blank" rel="noopener">XEP 363</a>)</li>
+                            <li>Messages appear in all connected chat clients (<a href="https://xmpp.org/extensions/xep-0280.html" target="_blank" rel="noopener">XEP 280</a>)</li>
+                            <li>Third person "/me" messages (<a href="https://xmpp.org/extensions/xep-0245.html" target="_blank" rel="noopener">XEP 245</a>)</li>
+                            <li>XMPP Ping (<a href="https://xmpp.org/extensions/xep-0199.html" target="_blank" rel="noopener">XEP 199</a>)</li>
+                            <li>Server-side archiving of messages (<a href="https://xmpp.org/extensions/xep-0313.html" target="_blank" rel="noopener">XEP 313</a>)</li>
+                            <li>Hidden messages (aka Spoilers) (<a href="https://xmpp.org/extensions/xep-0382.html" target="_blank" rel="noopener">XEP 382</a>)</li>
+                            <li>Client state indication (<a href="https://xmpp.org/extensions/xep-0352.html" target="_blank" rel="noopener">XEP 352</a>)</li>
+                            <li>Last Message Correction (<a href="https://xmpp.org/extensions/xep-0308.html" target="_blank" rel="noopener">XEP 308</a>)</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>Translated into 17 languages</li>
@@ -189,11 +190,11 @@
                 <div class="col-lg-8 col-lg-offset-2">
                     <h2>Contact</h2>
                     <ul class="contact">
-                        <li>Follow me on <a href="http://twitter.com/jcopkode" target="_blank" rel="noopener">Twitter</a>
+                        <li>Follow me on <a href="https://twitter.com/jcopkode" target="_blank" rel="noopener">Twitter</a>
                             or <a href="https://mastodon.xyz/@jcbrand" target="_blank" rel="noopener">Mastodon</a>
                         <li>Chat with me via XMPP at <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">jc@opkode.com</a></li>
-                        <li>For technical support, you can ask on <a href="http://stackoverflow.com/questions/tagged/converse.js">Stack Overflow</a>
-                        <li>The Converse XMPP chatroom: <a href="xmpp:discuss@conference.conversejs.org" class="xmpp JSnocheck" title="Converse chat room">discuss@conference.conversejs.org</a>.</li>
+                        <li>For technical support, you can ask on <a href="https://stackoverflow.com/questions/tagged/converse.js">Stack Overflow</a>
+                        <li>The Converse XMPP chatroom: <a href="xmpp:discuss@conference.conversejs.org?join" class="xmpp JSnocheck" title="Converse chat room">discuss@conference.conversejs.org</a>.</li>
                         <li>Please file bugs and feature requests on <a target="_blank" rel="noopener" href="https://github.com/jcbrand/converse.js/issues">Github</a>.</li>
                     </ul>
                 </div>
@@ -205,7 +206,7 @@
                         However, please don't contact me personally for free support, use
                         the other channels mentioned above.</br></br>
 
-                        Here's my <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact form</a>.</br>
+                        Here's my <a href="https://opkode.com/contact.html" target="_blank" rel="noopener">contact form</a>.</br>
                     </p>
                 </div>
             </div>
@@ -229,7 +230,7 @@
                        Sponsorships allow us to fund further development and improvements.
                        If you'd like to sponsor this project, please visit <a href="https://www.patreon.com/jcbrand" target="_blank" rel="noopener">Patreon</a>,
                        <a href="https://liberapay.com/jcbrand" target="_blank" rel="noopener">Liberapay</a> or
-                       <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
+                       <a href="https://opkode.com/contact.html" target="_blank" rel="noopener">contact us</a>.
                     </p>
                 </div>
             </div>
@@ -249,7 +250,7 @@
                     </p>
                     <p>
                         If you're interested in professional XMPP hosting under your
-                        own domain name, please <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
+                        own domain name, please <a href="https://opkode.com/contact.html" target="_blank" rel="noopener">contact us</a>.
                     </p>
 
                     <div class="privacy-policy">
@@ -303,7 +304,7 @@
                         </p>
                         <p>
                             If you'd like to have a copy of your data for
-                            transferal to another account, please <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
+                            transferal to another account, please <a href="https://opkode.com/contact.html" target="_blank" rel="noopener">contact us</a>.
                         </p>
                         <h4>Account deletion</h4>
                         <p>
@@ -314,7 +315,7 @@
                             <a href="https://xmpp.org/extensions/xep-0077.html" target="_blank" rel="noopener">XEP-0077</a>.
                         </p>
                         <p>
-                            You can always <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>
+                            You can always <a href="https://opkode.com/contact.html" target="_blank" rel="noopener">contact us</a>
                             and we'll delete your account manually.
                         </p>
                     </div>
@@ -350,7 +351,7 @@
     ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     OTHER DEALINGS IN THE SOFTWARE.
 
-    For more information, please refer to <http://unlicense.org/>
+    For more information, please refer to <https://unlicense.org/>
     @licend
     */
     converse.initialize({

File diff suppressed because it is too large
+ 0 - 0
locale/af/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 354 - 596
locale/af/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/ar/LC_MESSAGES/converse.json


+ 137 - 9
locale/ar/LC_MESSAGES/converse.po

@@ -8,7 +8,7 @@ msgstr ""
 "Project-Id-Version: Converse.js 3.3.4\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-05-17 11:19+0200\n"
-"PO-Revision-Date: 2018-05-15 11:34+0000\n"
+"PO-Revision-Date: 2018-07-02 15:32+0200\n"
 "Last-Translator: ButterflyOfFire <ButterflyOfFire@protonmail.com>\n"
 "Language-Team: Arabic <https://hosted.weblate.org/projects/conversejs/"
 "translations/ar/>\n"
@@ -18,7 +18,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
 "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.0\n"
 
 #: dist/converse-no-dependencies.js:9853 dist/converse-no-dependencies.js:9882
 msgid "Download"
@@ -153,7 +153,7 @@ msgstr ""
 
 #: dist/converse-no-dependencies.js:21257
 msgid "Sorry, could not succesfully upload your file."
-msgstr ""
+msgstr "للأسف لم نتمكّن مِن القيام برفع ملفك بنجاح."
 
 #: dist/converse-no-dependencies.js:21260
 #, javascript-format
@@ -162,7 +162,7 @@ msgstr "رد الخادم : \"%1$s\""
 
 #: dist/converse-no-dependencies.js:21442
 msgid "Sorry, looks like file upload is not supported by your server."
-msgstr ""
+msgstr "للأسف يبدو أن خاصية رفع الملفات لا يدعمها خادومكم."
 
 #: dist/converse-no-dependencies.js:21452
 #, javascript-format
@@ -171,8 +171,7 @@ msgid ""
 "which is %2$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22197
-#, fuzzy
+#: dist/converse-no-dependencies.js:18681
 msgid "Show more"
 msgstr "عرض المزيد"
 
@@ -330,7 +329,11 @@ msgstr "كتب كأنه شخص ثالث"
 msgid "Show this menu"
 msgstr "إظهار هذه القائمة"
 
+<<<<<<< HEAD
+#: dist/converse-no-dependencies.js:19614
+=======
 #: dist/converse-no-dependencies.js:23164
+>>>>>>> master
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr "هل أنت متأكد أنك تود مسح الرسائل مِن نافذة المحادثة هذه ؟"
 
@@ -344,11 +347,103 @@ msgstr "قد قطع الإتصال"
 msgid "is busy"
 msgstr "مشغول"
 
+<<<<<<< HEAD
+#: dist/converse-no-dependencies.js:19710
+msgid "is online"
+msgstr "متصل"
+
+#: dist/converse-no-dependencies.js:22577
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
+msgstr "قام %1$s بدعوتك للإلتحاق بغرفة المحادثة : %2$s"
+
+#: dist/converse-no-dependencies.js:22579
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
+msgstr ""
+
+#: dist/converse-no-dependencies.js:22956
+#: dist/converse-no-dependencies.js:23041
+#: dist/converse-no-dependencies.js:32286
+msgid "Bookmark this room"
+msgstr "إضافة هذه الغرفة إلى الفواصل المرجعية"
+
+#: dist/converse-no-dependencies.js:23042
+msgid "The name for this bookmark:"
+msgstr "تسمية الفاصلة المرجعية :"
+
+#: dist/converse-no-dependencies.js:23043
+msgid "Would you like this room to be automatically joined upon startup?"
+msgstr "هل تود الإلتحاق بهذه الغرفة آليا مباشَرةً بعد الإتصال ؟"
+
+#: dist/converse-no-dependencies.js:23044
+msgid "What should your nickname for this room be?"
+msgstr "ما هو الإسم المُستعار الذي تريد استخدامه في غرفة المحادثة هذه ؟"
+
+#: dist/converse-no-dependencies.js:23046
+#: dist/converse-no-dependencies.js:25364
+msgid "Save"
+msgstr "حفظ"
+
+#: dist/converse-no-dependencies.js:23047
+#: dist/converse-no-dependencies.js:25360
+#: dist/converse-no-dependencies.js:31362
+msgid "Cancel"
+msgstr "إلغاء"
+
+#: dist/converse-no-dependencies.js:23120
+#, javascript-format
+msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
+msgstr "هل أنت متأكد أنك تريد إزالة الفاصلة المرجعية \"%1$s\" ؟"
+
+#: dist/converse-no-dependencies.js:23236
+msgid "Sorry, something went wrong while trying to save your bookmark."
+msgstr "المعذرة، لقد طرأ هناك خطأ أثناء محاولة الإحتفاظ بالفواصل المرجعية."
+
+#: dist/converse-no-dependencies.js:23315
+#: dist/converse-no-dependencies.js:32284
+msgid "Leave this room"
+msgstr "الخروج مِن هذه الغرفة"
+
+#: dist/converse-no-dependencies.js:23316
+msgid "Remove this bookmark"
+msgstr "إزالة هذه الفاصلة المرجعية"
+
+#: dist/converse-no-dependencies.js:23317
+#: dist/converse-no-dependencies.js:32285
+msgid "Unbookmark this room"
+msgstr "تنحية غرفة المحادثة مِن الفواصل المرجعية"
+
+#: dist/converse-no-dependencies.js:23318
+#: dist/converse-no-dependencies.js:28813
+#: dist/converse-no-dependencies.js:32287
+msgid "Show more information on this room"
+msgstr "عرض المزيد مِن التفاصيل عن هذه الغرفة"
+
+#: dist/converse-no-dependencies.js:23321
+#: dist/converse-no-dependencies.js:28812
+#: dist/converse-no-dependencies.js:32289
+msgid "Click to open this room"
+msgstr "أنقر لفتح غرفة المحادثة هذه"
+
+#: dist/converse-no-dependencies.js:23357
+msgid "Click to toggle the bookmarks list"
+msgstr "أنقر للإنتقال إلى قائمة الإشارات المرجعية"
+
+#: dist/converse-no-dependencies.js:23358
+msgid "Bookmarks"
+msgstr "الفواصل المرجعية"
+
+#: dist/converse-no-dependencies.js:23546
+=======
 #: dist/converse-no-dependencies.js:23260
 msgid "is online"
 msgstr "متصل"
 
 #: dist/converse-no-dependencies.js:23501
+>>>>>>> master
 msgid "XMPP Username:"
 msgstr "إسم المستخدِم :"
 
@@ -533,6 +628,13 @@ msgstr "إضافة مراسل"
 #: dist/converse-no-dependencies.js:25288
 msgid "Your Profile"
 msgstr "ملفك الشخصي"
+<<<<<<< HEAD
+
+#: dist/converse-no-dependencies.js:25346
+#: dist/converse-no-dependencies.js:25358
+msgid "Close"
+msgstr "إغلاق"
+=======
 
 #: dist/converse-no-dependencies.js:25293
 #, fuzzy
@@ -557,6 +659,7 @@ msgstr "المعذرة، لقد طرأ هناك خطأ أثناء محاولة 
 #: dist/converse-no-dependencies.js:25325
 msgid "You can check your browser's developer console for any error output."
 msgstr ""
+>>>>>>> master
 
 #: dist/converse-no-dependencies.js:25377
 msgid "Custom status"
@@ -657,7 +760,11 @@ msgstr "غرفة المحادثة هذه ليست مجهولة"
 msgid "This room now shows unavailable members"
 msgstr ""
 
+<<<<<<< HEAD
+#: dist/converse-no-dependencies.js:28646
+=======
 #: dist/converse-no-dependencies.js:28652
+>>>>>>> master
 #, fuzzy
 msgid "This room does not show unavailable members"
 msgstr "هذه القاعة لا تقوم بعرض الأعضاء المشغولين"
@@ -827,7 +934,7 @@ msgstr "ليست تحت الإشراف"
 
 #: dist/converse-no-dependencies.js:28777
 msgid "Query for Chatrooms"
-msgstr ""
+msgstr "الإستعلام عن قاعات الدردشة"
 
 #: dist/converse-no-dependencies.js:28778
 msgid "Server address"
@@ -869,22 +976,35 @@ msgstr "الإلتحاق بالغرفة"
 msgid "Message"
 msgstr "رسالة"
 
+<<<<<<< HEAD
+#: dist/converse-no-dependencies.js:29053
+#, javascript-format
+=======
 #: dist/converse-no-dependencies.js:29058
 #, fuzzy, javascript-format
+>>>>>>> master
 msgid "%1$s is no longer a moderator"
-msgstr "لم يعُد %1$s مِن مُشْرِفي غرفة المحادثة."
+msgstr "لم يعُد %1$s مِن مُشْرِفي غرفة المحادثة"
 
 #: dist/converse-no-dependencies.js:29061
 #, fuzzy, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr "لقد تم طرد %1$s مِن غرفة المحادثة مؤقتًا"
 
+<<<<<<< HEAD
+#: dist/converse-no-dependencies.js:29059
+=======
 #: dist/converse-no-dependencies.js:29064
+>>>>>>> master
 #, javascript-format
 msgid "%1$s has been muted"
 msgstr "تم كتم %1$s"
 
+<<<<<<< HEAD
+#: dist/converse-no-dependencies.js:29062
+=======
 #: dist/converse-no-dependencies.js:29067
+>>>>>>> master
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr "أصبح %1$s مُشرفًا"
@@ -1081,9 +1201,14 @@ msgstr "غُرف المحادثة"
 msgid "Add a new room"
 msgstr "إضافة غرفة جديدة"
 
+<<<<<<< HEAD
+#: dist/converse-no-dependencies.js:29953
+#, fuzzy
+=======
 #: dist/converse-no-dependencies.js:29983
+>>>>>>> master
 msgid "Query for rooms"
-msgstr ""
+msgstr "البحث عن قاعات"
 
 #: dist/converse-no-dependencies.js:30022
 #, javascript-format
@@ -1410,6 +1535,8 @@ msgstr "تم التحقق منه"
 #: dist/converse-no-dependencies.js:31192
 msgid "finished"
 msgstr "انتهى"
+<<<<<<< HEAD
+=======
 
 #: dist/converse-no-dependencies.js:31788
 #, javascript-format
@@ -1419,6 +1546,7 @@ msgstr "المعذرة، لقد حدث هناك خطأ أثناء محاولة 
 #: dist/converse-no-dependencies.js:31936
 msgid "This client does not allow presence subscriptions"
 msgstr ""
+>>>>>>> master
 
 #: dist/converse-no-dependencies.js:32028
 msgid "Click to hide these contacts"

File diff suppressed because it is too large
+ 0 - 0
locale/bg/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 355 - 598
locale/bg/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/ca/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 1157 - 1005
locale/ca/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 340 - 391
locale/converse.pot


File diff suppressed because it is too large
+ 0 - 0
locale/de/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 356 - 598
locale/de/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/es/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 357 - 600
locale/es/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/eu/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 370 - 604
locale/eu/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/fr/LC_MESSAGES/converse.json


+ 12 - 75
locale/fr/LC_MESSAGES/converse.po

@@ -7,7 +7,7 @@ msgstr ""
 "Project-Id-Version: Converse.js 0.4\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-05-17 11:19+0200\n"
-"PO-Revision-Date: 2018-05-07 18:37+0000\n"
+"PO-Revision-Date: 2018-07-02 15:35+0200\n"
 "Last-Translator: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>\n"
 "Language-Team: French <https://hosted.weblate.org/projects/conversejs/"
 "translations/fr/>\n"
@@ -92,50 +92,9 @@ msgstr "Marquer ce salon"
 msgid "The name for this bookmark:"
 msgstr "Nom de ce marque-page :"
 
-#: dist/converse-no-dependencies.js:16466
-msgid "Would you like this room to be automatically joined upon startup?"
-msgstr "Voulez-vous rejoindre automatiquement ce salon au lancement ?"
-
-#: dist/converse-no-dependencies.js:16467
-msgid "What should your nickname for this room be?"
-msgstr "Quel alias devrait être utilisé pour ce salon ?"
-
-#: dist/converse-no-dependencies.js:16469
-#: dist/converse-no-dependencies.js:25296
-#: dist/converse-no-dependencies.js:25380
-msgid "Save"
-msgstr "Enregistrer"
-
-#: dist/converse-no-dependencies.js:16470
-#: dist/converse-no-dependencies.js:25376
-#: dist/converse-no-dependencies.js:32190
-msgid "Cancel"
-msgstr "Annuler"
-
-#: dist/converse-no-dependencies.js:16543
-#, javascript-format
-msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
-msgstr "Voulez-vous vraiment retirer le marque-page « %1$s » ?"
-
-#: dist/converse-no-dependencies.js:16659
-msgid "Sorry, something went wrong while trying to save your bookmark."
-msgstr ""
-"Désolé, quelque chose s’est mal passé pendant la sauvegarde de ce marque-"
-"page."
-
-#: dist/converse-no-dependencies.js:16738
-#: dist/converse-no-dependencies.js:33112
-msgid "Leave this room"
-msgstr "Quitter ce salon"
-
-#: dist/converse-no-dependencies.js:16739
-msgid "Remove this bookmark"
-msgstr "Retirer ce marque-page"
-
-#: dist/converse-no-dependencies.js:16740
-#: dist/converse-no-dependencies.js:33113
-msgid "Unbookmark this room"
-msgstr "Retirer ce salon"
+#: dist/converse-no-dependencies.js:17811
+msgid "Sorry, could not determine file upload URL."
+msgstr "Désolé, impossible de déterminer l’URL pour envoyer le fichier."
 
 #: dist/converse-no-dependencies.js:16741
 #: dist/converse-no-dependencies.js:28819
@@ -187,32 +146,10 @@ msgstr ""
 "La taille de votre fichier, %1$s, dépasse le maximum autorisé par votre "
 "serveur, qui est %2$s."
 
-#: dist/converse-no-dependencies.js:22197
+#: dist/converse-no-dependencies.js:18681
 msgid "Show more"
 msgstr "Afficher plus"
 
-#: dist/converse-no-dependencies.js:22248
-msgid "Typing from another device"
-msgstr "Saisie depuis un autre appareil"
-
-#: dist/converse-no-dependencies.js:22250
-msgid "is typing"
-msgstr "écrit"
-
-#: dist/converse-no-dependencies.js:22254
-msgid "Stopped typing on the other device"
-msgstr "Fin de saisie depuis l’autre appareil"
-
-#: dist/converse-no-dependencies.js:22256
-msgid "has stopped typing"
-msgstr "a arrêté d’écrire"
-
-#: dist/converse-no-dependencies.js:22259
-#: dist/converse-no-dependencies.js:23256
-#: dist/converse-no-dependencies.js:30521
-msgid "has gone away"
-msgstr "est parti"
-
 #: dist/converse-no-dependencies.js:22488
 msgid "Close this chat box"
 msgstr "Fermer cette fenêtre de discussion"
@@ -325,7 +262,7 @@ msgstr "Cliquez pour écrire votre message en tant que spoiler"
 msgid "Clear all messages"
 msgstr "Supprimer tous les messages"
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:19149
 msgid "Insert emojis"
 msgstr "Insérer un emoji"
 
@@ -347,7 +284,7 @@ msgstr "Écrire à la troisième personne"
 msgid "Show this menu"
 msgstr "Afficher ce menu"
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:19614
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr "Voulez-vous vraiment effacer les messages de cette conversation ?"
 
@@ -361,7 +298,7 @@ msgstr "s’est déconnecté"
 msgid "is busy"
 msgstr "est occupé"
 
-#: dist/converse-no-dependencies.js:23260
+#: dist/converse-no-dependencies.js:19710
 msgid "is online"
 msgstr "est en ligne"
 
@@ -891,22 +828,22 @@ msgstr "Rejoindre"
 msgid "Message"
 msgstr "Message"
 
-#: dist/converse-no-dependencies.js:29058
+#: dist/converse-no-dependencies.js:29053
 #, javascript-format
 msgid "%1$s is no longer a moderator"
 msgstr "%1$s n’est plus un modérateur"
 
-#: dist/converse-no-dependencies.js:29061
+#: dist/converse-no-dependencies.js:29056
 #, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr "%1$s peut de nouveau parler"
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:29059
 #, javascript-format
 msgid "%1$s has been muted"
 msgstr "%1$s ne peut plus parler"
 
-#: dist/converse-no-dependencies.js:29067
+#: dist/converse-no-dependencies.js:29062
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr "%1$s est désormais un modérateur"

File diff suppressed because it is too large
+ 0 - 0
locale/he/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 1120 - 965
locale/he/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/hu/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 364 - 628
locale/hu/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/id/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 1135 - 1000
locale/id/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/it/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 354 - 595
locale/it/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/ja/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 346 - 615
locale/ja/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/lt/LC_MESSAGES/converse.json


+ 903 - 906
locale/lt/LC_MESSAGES/converse.po

@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Converse.js 3.3.4\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-05-17 11:19+0200\n"
+"POT-Creation-Date: 2018-07-02 16:28+0200\n"
 "PO-Revision-Date: 2018-04-19 12:38+0000\n"
 "Last-Translator: Stasys Petraitis <stasyspetraitis2008@gmail.com>\n"
 "Language-Team: Lithuanian <https://hosted.weblate.org/projects/conversejs/"
@@ -21,1510 +21,1507 @@ msgstr ""
 "1 : 2);\n"
 "X-Generator: Weblate 3.0-dev\n"
 
-#: dist/converse-no-dependencies.js:9853 dist/converse-no-dependencies.js:9882
-msgid "Download"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9872
-#, javascript-format
-msgid "Download: \"%1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9895
-msgid "Download video file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9908
-msgid "Download audio file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11229
-msgid "The connection has dropped, attempting to reconnect."
-msgstr "Ryšys nutrūko, bandoma prisijungti iš naujo."
-
-#: dist/converse-no-dependencies.js:11327
-msgid "An error occurred while connecting to the chat server."
-msgstr "Bandant prisijungti prie pokalbių serverio įvyko klaida."
-
-#: dist/converse-no-dependencies.js:11334
-msgid "Your Jabber ID and/or password is incorrect. Please try again."
-msgstr ""
-"Jūsų vartotojo vardas ir / arba slaptažodis yra neteisingas. Prašome, "
-"pabandyki dar kartą."
-
-#: dist/converse-no-dependencies.js:11346
-#, javascript-format
-msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
-msgstr "Atsiprašome, nepavyko prisijungti prie XMPP serverio su domenu: %1$s"
-
-#: dist/converse-no-dependencies.js:11348
-msgid "The XMPP server did not offer a supported authentication mechanism"
-msgstr "XMPP serveris nepateikė palaikomo autentifikavimo mechanizmo"
-
-#: dist/converse-no-dependencies.js:16016
-#, javascript-format
-msgid "%1$s has invited you to join a chat room: %2$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16018
-#, javascript-format
-msgid ""
-"%1$s has invited you to join a chat room: %2$s, and left the following "
-"reason: \"%3$s\""
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16379
-#: dist/converse-no-dependencies.js:16464
-#: dist/converse-no-dependencies.js:33114
-msgid "Bookmark this room"
+#: dist/converse-no-dependencies.js:40690
+#: dist/converse-no-dependencies.js:40775
+#: dist/converse-no-dependencies.js:53478
+msgid "Bookmark this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16465
+#: dist/converse-no-dependencies.js:40776
 msgid "The name for this bookmark:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16466
-msgid "Would you like this room to be automatically joined upon startup?"
+#: dist/converse-no-dependencies.js:40777
+msgid "Would you like this groupchat to be automatically joined upon startup?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16467
-msgid "What should your nickname for this room be?"
+#: dist/converse-no-dependencies.js:40778
+msgid "What should your nickname for this groupchat be?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16469
-#: dist/converse-no-dependencies.js:25296
-#: dist/converse-no-dependencies.js:25380
+#: dist/converse-no-dependencies.js:40780
+#: dist/converse-no-dependencies.js:49283
+#: dist/converse-no-dependencies.js:52277
+#: dist/converse-no-dependencies.js:52361
 msgid "Save"
 msgstr "Išsaugoti"
 
-#: dist/converse-no-dependencies.js:16470
-#: dist/converse-no-dependencies.js:25376
-#: dist/converse-no-dependencies.js:32190
+#: dist/converse-no-dependencies.js:40781
+#: dist/converse-no-dependencies.js:49284
+#: dist/converse-no-dependencies.js:52357
+#: dist/converse-no-dependencies.js:58508
 msgid "Cancel"
 msgstr "Atšaukti"
 
-#: dist/converse-no-dependencies.js:16543
+#: dist/converse-no-dependencies.js:40854
 #, javascript-format
 msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16659
+#: dist/converse-no-dependencies.js:40970
 msgid "Sorry, something went wrong while trying to save your bookmark."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16738
-#: dist/converse-no-dependencies.js:33112
-msgid "Leave this room"
+#: dist/converse-no-dependencies.js:41055
+#: dist/converse-no-dependencies.js:53476
+msgid "Leave this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16739
+#: dist/converse-no-dependencies.js:41056
 msgid "Remove this bookmark"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16740
-#: dist/converse-no-dependencies.js:33113
-msgid "Unbookmark this room"
+#: dist/converse-no-dependencies.js:41057
+#: dist/converse-no-dependencies.js:53477
+msgid "Unbookmark this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16741
-#: dist/converse-no-dependencies.js:28819
-#: dist/converse-no-dependencies.js:33115
-msgid "Show more information on this room"
+#: dist/converse-no-dependencies.js:41058
+#: dist/converse-no-dependencies.js:48558
+#: dist/converse-no-dependencies.js:53479
+msgid "Show more information on this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16744
-#: dist/converse-no-dependencies.js:28818
-#: dist/converse-no-dependencies.js:33117
-msgid "Click to open this room"
-msgstr ""
+#: dist/converse-no-dependencies.js:41061
+#: dist/converse-no-dependencies.js:48557
+#: dist/converse-no-dependencies.js:53481
+#, fuzzy
+msgid "Click to open this groupchat"
+msgstr "Spustelėkite, kad paslėptumėte šiuos kontaktus"
 
-#: dist/converse-no-dependencies.js:16780
+#: dist/converse-no-dependencies.js:41097
 msgid "Click to toggle the bookmarks list"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16781
+#: dist/converse-no-dependencies.js:41098
 msgid "Bookmarks"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21217
+#: dist/converse-no-dependencies.js:41529
 msgid "Sorry, could not determine file upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21225
+#: dist/converse-no-dependencies.js:41537
 msgid "Sorry, could not determine upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21257
+#: dist/converse-no-dependencies.js:41569
 msgid "Sorry, could not succesfully upload your file."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21260
+#: dist/converse-no-dependencies.js:41572
 #, javascript-format
 msgid "Your server's response: \"%1$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21442
+#: dist/converse-no-dependencies.js:41749
 msgid "Sorry, looks like file upload is not supported by your server."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21452
+#: dist/converse-no-dependencies.js:41759
 #, javascript-format
 msgid ""
 "The size of your file, %1$s, exceeds the maximum allowed by your server, "
 "which is %2$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22197
-#, fuzzy
-msgid "Show more"
-msgstr "Rodyti šį meniu"
-
-#: dist/converse-no-dependencies.js:22248
-msgid "Typing from another device"
-msgstr "Rašoma iš kito įrenginio"
-
-#: dist/converse-no-dependencies.js:22250
-msgid "is typing"
-msgstr "rašo"
-
-#: dist/converse-no-dependencies.js:22254
-msgid "Stopped typing on the other device"
-msgstr "Nustojo rašyti kitame įrenginyje"
-
-#: dist/converse-no-dependencies.js:22256
-msgid "has stopped typing"
-msgstr "nustojo rašyti"
-
-#: dist/converse-no-dependencies.js:22259
-#: dist/converse-no-dependencies.js:23256
-#: dist/converse-no-dependencies.js:30521
-msgid "has gone away"
-msgstr "pasišalines"
+#: dist/converse-no-dependencies.js:41778
+msgid "Sorry, an error occured:"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:22488
+#: dist/converse-no-dependencies.js:42489
 msgid "Close this chat box"
 msgstr "Uždarykite šį pokalbių laukelį"
 
-#: dist/converse-no-dependencies.js:22516
+#: dist/converse-no-dependencies.js:42517
 msgid "The User's Profile Image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22519
-#: dist/converse-no-dependencies.js:25289
-#: dist/converse-no-dependencies.js:25374
+#: dist/converse-no-dependencies.js:42520
+#: dist/converse-no-dependencies.js:52270
+#: dist/converse-no-dependencies.js:52355
 msgid "Close"
 msgstr "Uždaryti"
 
-#: dist/converse-no-dependencies.js:22520
-#: dist/converse-no-dependencies.js:25290
+#: dist/converse-no-dependencies.js:42521
+#: dist/converse-no-dependencies.js:52271
 msgid "Email"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22521
-#: dist/converse-no-dependencies.js:25291
+#: dist/converse-no-dependencies.js:42522
+#: dist/converse-no-dependencies.js:52272
 msgid "Full Name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22522
+#: dist/converse-no-dependencies.js:42523
 msgid "Jabber ID"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22523
-#: dist/converse-no-dependencies.js:25292
-#: dist/converse-no-dependencies.js:29617
+#: dist/converse-no-dependencies.js:42524
+#: dist/converse-no-dependencies.js:49439
+#: dist/converse-no-dependencies.js:52273
 msgid "Nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22524
+#: dist/converse-no-dependencies.js:42525
 #, fuzzy
 msgid "Remove as contact"
 msgstr "Pridėti adresatą"
 
-#: dist/converse-no-dependencies.js:22525
+#: dist/converse-no-dependencies.js:42526
 msgid "Refresh"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22526
-#: dist/converse-no-dependencies.js:25294
+#: dist/converse-no-dependencies.js:42527
+#: dist/converse-no-dependencies.js:52275
 msgid "Role"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22527
-#: dist/converse-no-dependencies.js:25297
+#: dist/converse-no-dependencies.js:42528
+#: dist/converse-no-dependencies.js:52278
 msgid "URL"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22566
-#: dist/converse-no-dependencies.js:24293
+#: dist/converse-no-dependencies.js:42567
+#: dist/converse-no-dependencies.js:55141
 msgid "Are you sure you want to remove this contact?"
 msgstr "Ar tikrai norite pašalinti šį kontaktą?"
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:25325
+#: dist/converse-no-dependencies.js:42576
+#: dist/converse-no-dependencies.js:52306
 msgid "Error"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:24301
+#: dist/converse-no-dependencies.js:42576
+#: dist/converse-no-dependencies.js:55149
 #, javascript-format
 msgid "Sorry, there was an error while trying to remove %1$s as a contact."
 msgstr "Deja, bandant pašalinti %1$s iš kontaktų įvyko klaida."
 
-#: dist/converse-no-dependencies.js:22629
-#: dist/converse-no-dependencies.js:22667
-#: dist/converse-no-dependencies.js:29029
+#: dist/converse-no-dependencies.js:42630
+#: dist/converse-no-dependencies.js:42668
+#: dist/converse-no-dependencies.js:48794
 msgid "You have unread messages"
 msgstr "Jūs turite neperskaitytų pranešimų"
 
-#: dist/converse-no-dependencies.js:22653
+#: dist/converse-no-dependencies.js:42654
 msgid "Hidden message"
 msgstr "Paslėpta žinutė"
 
-#: dist/converse-no-dependencies.js:22655
+#: dist/converse-no-dependencies.js:42656
 msgid "Personal message"
 msgstr "Asmeninė žinutė"
 
-#: dist/converse-no-dependencies.js:22662
-#: dist/converse-no-dependencies.js:29026
+#: dist/converse-no-dependencies.js:42663
+#: dist/converse-no-dependencies.js:48791
 msgid "Send"
 msgstr "Siųsti"
 
-#: dist/converse-no-dependencies.js:22663
+#: dist/converse-no-dependencies.js:42664
 msgid "Optional hint"
 msgstr "Neprivaloma užuomina"
 
-#: dist/converse-no-dependencies.js:22692
+#: dist/converse-no-dependencies.js:42702
 msgid "Choose a file to send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22748
+#: dist/converse-no-dependencies.js:42758
 msgid "Click to write as a normal (non-spoiler) message"
 msgstr "Spustelėkite, jei norite parašyti įprastą (neatskleidžiamą) pranešimą"
 
-#: dist/converse-no-dependencies.js:22750
+#: dist/converse-no-dependencies.js:42760
 msgid "Click to write your message as a spoiler"
 msgstr "Spustelėkite, jei norite parašyti pranešimą kaip atskleidėją"
 
-#: dist/converse-no-dependencies.js:22754
+#: dist/converse-no-dependencies.js:42764
 msgid "Clear all messages"
 msgstr "Išvalyti visus pranešimus"
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:42765
 #, fuzzy
 msgid "Insert emojis"
 msgstr "Įterpti šypsenėlę"
 
-#: dist/converse-no-dependencies.js:22756
+#: dist/converse-no-dependencies.js:42766
 msgid "Start a call"
 msgstr "Pradėti skambutį"
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29265
+#: dist/converse-no-dependencies.js:43079
+#: dist/converse-no-dependencies.js:49082
 msgid "Remove messages"
 msgstr "Pašalinti pranešimus"
 
-#: dist/converse-no-dependencies.js:23069
+#: dist/converse-no-dependencies.js:43079
 msgid "Write in the third person"
 msgstr "Rašykite trečiuoju asmeniu"
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29267
+#: dist/converse-no-dependencies.js:43079
+#: dist/converse-no-dependencies.js:49082
 msgid "Show this menu"
 msgstr "Rodyti šį meniu"
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:43178
 #, fuzzy
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr "Ar tikrai norite išvalyti šio pokalbio lauko pranešimus?"
 
-#: dist/converse-no-dependencies.js:23254
-#: dist/converse-no-dependencies.js:30519
+#: dist/converse-no-dependencies.js:43267
+#: dist/converse-no-dependencies.js:51817
 msgid "has gone offline"
 msgstr "atsijungė"
 
-#: dist/converse-no-dependencies.js:23258
-#: dist/converse-no-dependencies.js:30523
+#: dist/converse-no-dependencies.js:43269
+#: dist/converse-no-dependencies.js:47480
+#: dist/converse-no-dependencies.js:51819
+msgid "has gone away"
+msgstr "pasišalines"
+
+#: dist/converse-no-dependencies.js:43271
+#: dist/converse-no-dependencies.js:51821
 msgid "is busy"
 msgstr "užsiėmęs"
 
-#: dist/converse-no-dependencies.js:23260
+#: dist/converse-no-dependencies.js:43273
 #, fuzzy
 msgid "is online"
 msgstr "prisijungęs"
 
-#: dist/converse-no-dependencies.js:23501
-msgid "XMPP Username:"
-msgstr "XMPP vartotojo vardas:"
+#: dist/converse-no-dependencies.js:43655
+#: dist/converse-no-dependencies.js:54717
+#: dist/converse-no-dependencies.js:55440
+msgid "Contacts"
+msgstr "Kontaktai"
 
-#: dist/converse-no-dependencies.js:23507
-msgid "Password:"
-msgstr "Slaptažodis:"
+#: dist/converse-no-dependencies.js:43893
+msgid "Username"
+msgstr "Vartotojo vardas"
 
-#: dist/converse-no-dependencies.js:23509
-msgid "password"
-msgstr "slaptažodis"
+#: dist/converse-no-dependencies.js:43893
+msgid "user@domain"
+msgstr "vartotojas@domenas"
 
-#: dist/converse-no-dependencies.js:23513
-#: dist/converse-no-dependencies.js:29643
-msgid "Submit"
-msgstr "Pateikti"
+#: dist/converse-no-dependencies.js:43901
+#: dist/converse-no-dependencies.js:54778
+msgid "Please enter a valid XMPP address"
+msgstr "Įveskite teisingą XMPP adresą"
 
-#: dist/converse-no-dependencies.js:23519
-msgid "Click here to log in anonymously"
-msgstr "Spauskite čia norėdami prisijungti anonimiškai"
+#: dist/converse-no-dependencies.js:43990
+msgid "Chat Contacts"
+msgstr "Pokalbių kontaktai"
 
-#: dist/converse-no-dependencies.js:23864
-msgid "This contact is busy"
-msgstr "Šis kontaktas užimtas"
+#: dist/converse-no-dependencies.js:43990
+msgid "Toggle chat"
+msgstr "Perjungti pokalbius"
 
-#: dist/converse-no-dependencies.js:23865
-msgid "This contact is online"
-msgstr "Šis kontaktas yra prisijungęs"
+#: dist/converse-no-dependencies.js:44568
+msgid "The connection has dropped, attempting to reconnect."
+msgstr "Ryšys nutrūko, bandoma prisijungti iš naujo."
 
-#: dist/converse-no-dependencies.js:23866
-msgid "This contact is offline"
-msgstr "Šis kontaktas yra atsijungęs"
+#: dist/converse-no-dependencies.js:44666
+msgid "An error occurred while connecting to the chat server."
+msgstr "Bandant prisijungti prie pokalbių serverio įvyko klaida."
 
-#: dist/converse-no-dependencies.js:23867
-msgid "This contact is unavailable"
-msgstr "Šis kontaktas yra nepasiekiamas"
+#: dist/converse-no-dependencies.js:44673
+msgid "Your Jabber ID and/or password is incorrect. Please try again."
+msgstr ""
+"Jūsų vartotojo vardas ir / arba slaptažodis yra neteisingas. Prašome, "
+"pabandyki dar kartą."
 
-#: dist/converse-no-dependencies.js:23868
-msgid "This contact is away for an extended period"
-msgstr "Šis kontaktas yra ilgai pasišalines"
+#: dist/converse-no-dependencies.js:44685
+#, javascript-format
+msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
+msgstr "Atsiprašome, nepavyko prisijungti prie XMPP serverio su domenu: %1$s"
 
-#: dist/converse-no-dependencies.js:23869
-msgid "This contact is away"
-msgstr "Šis kontaktas yra pasišalines"
+#: dist/converse-no-dependencies.js:44687
+msgid "The XMPP server did not offer a supported authentication mechanism"
+msgstr "XMPP serveris nepateikė palaikomo autentifikavimo mechanizmo"
 
-#: dist/converse-no-dependencies.js:23872
-#: dist/converse-no-dependencies.js:24584
-#: dist/converse-no-dependencies.js:25680
-msgid "Contacts"
-msgstr "Kontaktai"
+#: dist/converse-no-dependencies.js:47426
+#, fuzzy
+msgid "Show more"
+msgstr "Rodyti šį meniu"
 
-#: dist/converse-no-dependencies.js:23874
-msgid "Groups"
-msgstr "Grupės"
+#: dist/converse-no-dependencies.js:47469
+msgid "Typing from another device"
+msgstr "Rašoma iš kito įrenginio"
 
-#: dist/converse-no-dependencies.js:23876
-msgid "My contacts"
-msgstr "Mano kontaktai"
+#: dist/converse-no-dependencies.js:47471
+msgid "is typing"
+msgstr "rašo"
 
-#: dist/converse-no-dependencies.js:23878
-msgid "Pending contacts"
-msgstr "Laukiantys kontaktai"
+#: dist/converse-no-dependencies.js:47475
+msgid "Stopped typing on the other device"
+msgstr "Nustojo rašyti kitame įrenginyje"
 
-#: dist/converse-no-dependencies.js:23880
-msgid "Contact requests"
-msgstr "Prašymai pridėti prie kontaktų"
+#: dist/converse-no-dependencies.js:47477
+msgid "has stopped typing"
+msgstr "nustojo rašyti"
 
-#: dist/converse-no-dependencies.js:23882
-msgid "Ungrouped"
-msgstr "Nesugrupuota"
+#: dist/converse-no-dependencies.js:47708
+#: dist/converse-no-dependencies.js:47751
+msgid "Minimize this chat box"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:23925
-msgid "Contact name"
-msgstr "Kontakto vardas"
+#: dist/converse-no-dependencies.js:47884
+msgid "Click to restore this chat"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:23925
-#: dist/converse-no-dependencies.js:28905
-msgid "Optional nickname"
-msgstr "Neprivalomas slapyvardis"
+#: dist/converse-no-dependencies.js:48071
+msgid "Minimized"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:23928
-msgid "Add a Contact"
-msgstr "Pridėti kontaktą"
+#: dist/converse-no-dependencies.js:48400
+#, fuzzy
+msgid "This groupchat is not anonymous"
+msgstr "Šis pokalbių kambarys nėra anonimiškas"
 
-#: dist/converse-no-dependencies.js:23929
-msgid "XMPP Address"
-msgstr "XMPP adresas"
+#: dist/converse-no-dependencies.js:48401
+#, fuzzy
+msgid "This groupchat now shows unavailable members"
+msgstr "Šis pokalbių kambarys dabar rodo nepasiekiamus narius"
 
-#: dist/converse-no-dependencies.js:23931
-msgid "name@example.org"
-msgstr "vardas@pavyzdys.lt"
+#: dist/converse-no-dependencies.js:48402
+#, fuzzy
+msgid "This groupchat does not show unavailable members"
+msgstr "Šiame kambaryje nerodomi nepasiekiami nariai"
 
-#: dist/converse-no-dependencies.js:23932
-msgid "Add"
-msgstr "Pridėti"
+#: dist/converse-no-dependencies.js:48403
+#, fuzzy
+msgid "The groupchat configuration has changed"
+msgstr "Kambario konfigūracija pasikeitė"
 
-#: dist/converse-no-dependencies.js:24003
-#: dist/converse-no-dependencies.js:25917
-msgid "Please enter a valid XMPP address"
-msgstr "Įveskite teisingą XMPP adresą"
+#: dist/converse-no-dependencies.js:48404
+#, fuzzy
+msgid "groupchat logging is now enabled"
+msgstr "Kambarių loginimas dabar įgalintas"
 
-#: dist/converse-no-dependencies.js:24040
-msgid "Filter"
-msgstr "Filtras"
+#: dist/converse-no-dependencies.js:48405
+#, fuzzy
+msgid "groupchat logging is now disabled"
+msgstr "Kambarių loginimas dabar išjungtas"
 
-#: dist/converse-no-dependencies.js:24041
-msgid "Filter by contact name"
-msgstr "Filtruoti pagal kontaktinį vardą"
+#: dist/converse-no-dependencies.js:48406
+#, fuzzy
+msgid "This groupchat is now no longer anonymous"
+msgstr "Šis kambarys nebėra anonimiškas"
 
-#: dist/converse-no-dependencies.js:24042
-msgid "Filter by group name"
-msgstr "Filtruoti pagal grupės pavadinimą"
+#: dist/converse-no-dependencies.js:48407
+#, fuzzy
+msgid "This groupchat is now semi-anonymous"
+msgstr "Šis kambarys dabar yra pusiau anonimiškas"
 
-#: dist/converse-no-dependencies.js:24043
-msgid "Filter by status"
-msgstr "Filtruoti pagal būseną"
+#: dist/converse-no-dependencies.js:48408
+#, fuzzy
+msgid "This groupchat is now fully-anonymous"
+msgstr "Šis kambarys dabar visiškai anonimiškas"
 
-#: dist/converse-no-dependencies.js:24044
-msgid "Any"
-msgstr "Bet koks"
+#: dist/converse-no-dependencies.js:48409
+#, fuzzy
+msgid "A new groupchat has been created"
+msgstr "Naujas kambarys buvo sukurtas"
 
-#: dist/converse-no-dependencies.js:24045
-msgid "Unread"
-msgstr "Neskaityta"
+#: dist/converse-no-dependencies.js:48412
+#, fuzzy
+msgid "You have been banned from this groupchat"
+msgstr "Jums buvo uždrausta prieeiga prie šio kambario"
 
-#: dist/converse-no-dependencies.js:24046
-#: dist/converse-no-dependencies.js:25379
-msgid "Online"
-msgstr "Prisijungęs"
+#: dist/converse-no-dependencies.js:48413
+#, fuzzy
+msgid "You have been kicked from this groupchat"
+msgstr "Jūs buvote pašalintas iš šio kambario"
 
-#: dist/converse-no-dependencies.js:24047
-msgid "Chatty"
-msgstr "Pokalbis"
+#: dist/converse-no-dependencies.js:48414
+#, fuzzy
+msgid ""
+"You have been removed from this groupchat because of an affiliation change"
+msgstr "Jūs esate pašalinti iš šio kambario dėl priklausymo pakeitimo"
 
-#: dist/converse-no-dependencies.js:24048
-#: dist/converse-no-dependencies.js:25375
-msgid "Busy"
-msgstr "Užsiėmes"
+#: dist/converse-no-dependencies.js:48415
+#, fuzzy
+msgid ""
+"You have been removed from this groupchat because the groupchat has changed "
+"to members-only and you're not a member"
+msgstr ""
+"Jūs esate pašalinti iš šio kambario, nes kambarys pakeistas skirtas tik "
+"nariams ir jūs nesate narys"
 
-#: dist/converse-no-dependencies.js:24049
-#: dist/converse-no-dependencies.js:25373
-msgid "Away"
-msgstr "Pasišalines"
+#: dist/converse-no-dependencies.js:48416
+#, fuzzy
+msgid ""
+"You have been removed from this groupchat because the MUC (Multi-user chat) "
+"service is being shut down"
+msgstr ""
+"Jūs esate pašalinti iš šio kambario, nes MUC (daugiafunkcinis pokalbis) "
+"paslauga yra uždaryta"
 
-#: dist/converse-no-dependencies.js:24050
-msgid "Extended Away"
-msgstr "Ilgai pasišalines"
+#. XXX: Note the triple underscore function and not double
+#. * underscore.
+#. *
+#. * This is a hack. We can't pass the strings to __ because we
+#. * don't yet know what the variable to interpolate is.
+#. *
+#. * Triple underscore will just return the string again, but we
+#. * can then at least tell gettext to scan for it so that these
+#. * strings are picked up by the translation machinery.
+#.
+#: dist/converse-no-dependencies.js:48429
+#, javascript-format
+msgid "%1$s has been banned"
+msgstr "%1$s buvo užblokuotas"
 
-#: dist/converse-no-dependencies.js:24051
-#: dist/converse-no-dependencies.js:25378
-msgid "Offline"
-msgstr "Neprisijungęs"
+#: dist/converse-no-dependencies.js:48430
+#, javascript-format
+msgid "%1$s's nickname has changed"
+msgstr "%1$s slapyvardis buvo pakeistas"
 
-#: dist/converse-no-dependencies.js:24205
-#: dist/converse-no-dependencies.js:24247
+#: dist/converse-no-dependencies.js:48431
 #, javascript-format
-msgid "Click to remove %1$s as a contact"
-msgstr "Spustelėkite, jei norite pašalinti %1$s iš kontaktų"
+msgid "%1$s has been kicked out"
+msgstr "%1$s buvo pašalintas"
 
-#: dist/converse-no-dependencies.js:24214
+#: dist/converse-no-dependencies.js:48432
 #, javascript-format
-msgid "Click to accept the contact request from %1$s"
-msgstr "Spustelėkite, jei norite priimti kontaktinį prašymą iš %1$s"
+msgid "%1$s has been removed because of an affiliation change"
+msgstr "%1$s buvo pašalintas dėl priklausymo pokyčių"
 
-#: dist/converse-no-dependencies.js:24215
+#: dist/converse-no-dependencies.js:48433
 #, javascript-format
-msgid "Click to decline the contact request from %1$s"
-msgstr "Spustelėkite, jei norite atmesti kontaktinį prašymą iš %1$s"
+msgid "%1$s has been removed for not being a member"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24246
+#: dist/converse-no-dependencies.js:48436
 #, javascript-format
-msgid "Click to chat with %1$s (JID: %2$s)"
-msgstr "Spauskite, kad pradėtumėte pokalbį su %1$s (JID: %2$s)"
+msgid "Your nickname has been automatically set to %1$s"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24323
-msgid "Are you sure you want to decline this contact request?"
-msgstr "Ar tikrai norite atmesti šį kontaktinį prašymą?"
+#: dist/converse-no-dependencies.js:48437
+#, javascript-format
+msgid "Your nickname has been changed to %1$s"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24585
-msgid "Add a contact"
-msgstr "Pridėti adresatą"
-
-#: dist/converse-no-dependencies.js:25288
-msgid "Your Profile"
-msgstr "Tavo profilis"
-
-#: dist/converse-no-dependencies.js:25293
-#, fuzzy
-msgid "XMPP Address (JID)"
-msgstr "XMPP adresas"
-
-#: dist/converse-no-dependencies.js:25295
-msgid ""
-"Use commas to separate multiple roles. Your roles are shown next to your "
-"name on your chat messages."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25298
-msgid "Your avatar image"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25325
-#, fuzzy
-msgid "Sorry, an error happened while trying to save your profile data."
-msgstr "Deja, bandant pašalinti %1$s iš kontaktų įvyko klaida."
-
-#: dist/converse-no-dependencies.js:25325
-msgid "You can check your browser's developer console for any error output."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25377
-msgid "Custom status"
-msgstr "Pasirinktinis statusas"
-
-#: dist/converse-no-dependencies.js:25381
-msgid "Away for long"
-msgstr "Ilgai pasišalines"
-
-#: dist/converse-no-dependencies.js:25382
-msgid "Change chat status"
-msgstr "Keisti pokalbio būseną"
-
-#: dist/converse-no-dependencies.js:25383
-msgid "Personal status message"
-msgstr "Asmeninis statuso pranešimas"
-
-#: dist/converse-no-dependencies.js:25427
-#, javascript-format
-msgid "I am %1$s"
-msgstr "Aš esu %1$s"
-
-#: dist/converse-no-dependencies.js:25430
-msgid "Change settings"
-msgstr "Pakeisti nustatymus"
-
-#: dist/converse-no-dependencies.js:25431
-msgid "Click to change your chat status"
-msgstr "Spustelėkite norėdami pakeisti pokalbio būseną"
-
-#: dist/converse-no-dependencies.js:25432
-msgid "Log out"
-msgstr "Atsijungti"
-
-#: dist/converse-no-dependencies.js:25433
-msgid "Your profile"
-msgstr "Jūsų profilis"
-
-#: dist/converse-no-dependencies.js:25456
-msgid "Are you sure you want to log out?"
-msgstr "Ar tikrai norite atsijungti?"
-
-#: dist/converse-no-dependencies.js:25464
-#: dist/converse-no-dependencies.js:25474
-msgid "online"
-msgstr "prisijungęs"
-
-#: dist/converse-no-dependencies.js:25466
-msgid "busy"
-msgstr "užsiėmes"
-
-#: dist/converse-no-dependencies.js:25468
-msgid "away for long"
-msgstr "ilgai pasišalines"
-
-#: dist/converse-no-dependencies.js:25470
-msgid "away"
-msgstr "pasišalines"
-
-#: dist/converse-no-dependencies.js:25472
-msgid "offline"
-msgstr "neprisijungęs"
-
-#: dist/converse-no-dependencies.js:25909
-msgid "Username"
-msgstr "Vartotojo vardas"
-
-#: dist/converse-no-dependencies.js:25909
-msgid "user@domain"
-msgstr "vartotojas@domenas"
-
-#: dist/converse-no-dependencies.js:26003
-msgid "Chat Contacts"
-msgstr "Pokalbių kontaktai"
-
-#: dist/converse-no-dependencies.js:26003
-msgid "Toggle chat"
-msgstr "Perjungti pokalbius"
-
-#: dist/converse-no-dependencies.js:27529
-#: dist/converse-no-dependencies.js:27572
-msgid "Minimize this chat box"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:27705
-msgid "Click to restore this chat"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:27892
-msgid "Minimized"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28650
-msgid "This room is not anonymous"
-msgstr "Šis pokalbių kambarys nėra anonimiškas"
-
-#: dist/converse-no-dependencies.js:28651
-msgid "This room now shows unavailable members"
-msgstr "Šis pokalbių kambarys dabar rodo nepasiekiamus narius"
-
-#: dist/converse-no-dependencies.js:28652
-msgid "This room does not show unavailable members"
-msgstr "Šiame kambaryje nerodomi nepasiekiami nariai"
-
-#: dist/converse-no-dependencies.js:28653
-msgid "The room configuration has changed"
-msgstr "Kambario konfigūracija pasikeitė"
-
-#: dist/converse-no-dependencies.js:28654
-msgid "Room logging is now enabled"
-msgstr "Kambarių loginimas dabar įgalintas"
-
-#: dist/converse-no-dependencies.js:28655
-msgid "Room logging is now disabled"
-msgstr "Kambarių loginimas dabar išjungtas"
-
-#: dist/converse-no-dependencies.js:28656
-msgid "This room is now no longer anonymous"
-msgstr "Šis kambarys nebėra anonimiškas"
-
-#: dist/converse-no-dependencies.js:28657
-msgid "This room is now semi-anonymous"
-msgstr "Šis kambarys dabar yra pusiau anonimiškas"
-
-#: dist/converse-no-dependencies.js:28658
-msgid "This room is now fully-anonymous"
-msgstr "Šis kambarys dabar visiškai anonimiškas"
-
-#: dist/converse-no-dependencies.js:28659
-msgid "A new room has been created"
-msgstr "Naujas kambarys buvo sukurtas"
-
-#: dist/converse-no-dependencies.js:28663
-msgid "You have been banned from this room"
-msgstr "Jums buvo uždrausta prieeiga prie šio kambario"
-
-#: dist/converse-no-dependencies.js:28664
-msgid "You have been kicked from this room"
-msgstr "Jūs buvote pašalintas iš šio kambario"
-
-#: dist/converse-no-dependencies.js:28665
-msgid "You have been removed from this room because of an affiliation change"
-msgstr "Jūs esate pašalinti iš šio kambario dėl priklausymo pakeitimo"
-
-#: dist/converse-no-dependencies.js:28666
-msgid ""
-"You have been removed from this room because the room has changed to members-"
-"only and you're not a member"
-msgstr ""
-"Jūs esate pašalinti iš šio kambario, nes kambarys pakeistas skirtas tik "
-"nariams ir jūs nesate narys"
-
-#: dist/converse-no-dependencies.js:28667
-msgid ""
-"You have been removed from this room because the MUC (Multi-user chat) "
-"service is being shut down"
-msgstr ""
-"Jūs esate pašalinti iš šio kambario, nes MUC (daugiafunkcinis pokalbis) "
-"paslauga yra uždaryta"
-
-#. XXX: Note the triple underscore function and not double
-#. * underscore.
-#. *
-#. * This is a hack. We can't pass the strings to __ because we
-#. * don't yet know what the variable to interpolate is.
-#. *
-#. * Triple underscore will just return the string again, but we
-#. * can then at least tell gettext to scan for it so that these
-#. * strings are picked up by the translation machinery.
-#.
-#: dist/converse-no-dependencies.js:28681
-#, javascript-format
-msgid "%1$s has been banned"
-msgstr "%1$s buvo užblokuotas"
-
-#: dist/converse-no-dependencies.js:28682
-#, javascript-format
-msgid "%1$s's nickname has changed"
-msgstr "%1$s slapyvardis buvo pakeistas"
-
-#: dist/converse-no-dependencies.js:28683
-#, javascript-format
-msgid "%1$s has been kicked out"
-msgstr "%1$s buvo pašalintas"
-
-#: dist/converse-no-dependencies.js:28684
-#, javascript-format
-msgid "%1$s has been removed because of an affiliation change"
-msgstr "%1$s buvo pašalintas dėl priklausymo pokyčių"
-
-#: dist/converse-no-dependencies.js:28685
-#, javascript-format
-msgid "%1$s has been removed for not being a member"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28689
-#, javascript-format
-msgid "Your nickname has been automatically set to %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28690
-#, javascript-format
-msgid "Your nickname has been changed to %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28724
+#: dist/converse-no-dependencies.js:48468
 msgid "Description:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28725
-msgid "Room Address (JID):"
-msgstr ""
+#: dist/converse-no-dependencies.js:48469
+#, fuzzy
+msgid "Groupchat Address (JID):"
+msgstr "XMPP adresas"
 
-#: dist/converse-no-dependencies.js:28726
-msgid "Occupants:"
+#: dist/converse-no-dependencies.js:48470
+msgid "Participants:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28727
+#: dist/converse-no-dependencies.js:48471
 msgid "Features:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28728
+#: dist/converse-no-dependencies.js:48472
 msgid "Requires authentication"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28729
-#: dist/converse-no-dependencies.js:30122
+#: dist/converse-no-dependencies.js:48473
+#: dist/converse-no-dependencies.js:56917
+#: dist/converse-no-dependencies.js:57071
 msgid "Hidden"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28730
+#: dist/converse-no-dependencies.js:48474
 msgid "Requires an invitation"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28731
-#: dist/converse-no-dependencies.js:30125
+#: dist/converse-no-dependencies.js:48475
+#: dist/converse-no-dependencies.js:56981
+#: dist/converse-no-dependencies.js:57135
 msgid "Moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28732
-#: dist/converse-no-dependencies.js:30126
+#: dist/converse-no-dependencies.js:48476
 msgid "Non-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28733
-msgid "Open room"
+#: dist/converse-no-dependencies.js:48477
+#: dist/converse-no-dependencies.js:56941
+#: dist/converse-no-dependencies.js:57095
+msgid "Open"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28734
-msgid "Permanent room"
+#: dist/converse-no-dependencies.js:48478
+msgid "Permanent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28735
-#: dist/converse-no-dependencies.js:30130
+#: dist/converse-no-dependencies.js:48479
+#: dist/converse-no-dependencies.js:56925
+#: dist/converse-no-dependencies.js:57079
 msgid "Public"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28736
-#: dist/converse-no-dependencies.js:30131
+#: dist/converse-no-dependencies.js:48480
+#: dist/converse-no-dependencies.js:56973
+#: dist/converse-no-dependencies.js:57127
 msgid "Semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28737
-msgid "Temporary room"
+#: dist/converse-no-dependencies.js:48481
+#: dist/converse-no-dependencies.js:56957
+#: dist/converse-no-dependencies.js:57111
+msgid "Temporary"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28738
-#: dist/converse-no-dependencies.js:30133
+#: dist/converse-no-dependencies.js:48482
 msgid "Unmoderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28777
-msgid "Query for Chatrooms"
+#: dist/converse-no-dependencies.js:48518
+msgid "Query for Groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28778
+#: dist/converse-no-dependencies.js:48519
 msgid "Server address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28779
+#: dist/converse-no-dependencies.js:48520
 msgid "Show rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28780
+#: dist/converse-no-dependencies.js:48521
 msgid "conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28833
+#: dist/converse-no-dependencies.js:48570
 msgid "No rooms found"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28850
+#: dist/converse-no-dependencies.js:48587
 msgid "Rooms found:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28903
-msgid "Enter a new Chatroom"
+#: dist/converse-no-dependencies.js:48639
+msgid "Enter a new Groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28904
-msgid "Room address"
+#: dist/converse-no-dependencies.js:48640
+msgid "Groupchat address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28906
+#: dist/converse-no-dependencies.js:48641
+#: dist/converse-no-dependencies.js:54770
+msgid "Optional nickname"
+msgstr "Neprivalomas slapyvardis"
+
+#: dist/converse-no-dependencies.js:48642
 msgid "name@conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28907
+#: dist/converse-no-dependencies.js:48643
 msgid "Join"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29025
+#: dist/converse-no-dependencies.js:48684
+#, javascript-format
+msgid "Groupchat info for %1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48790
 msgid "Message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29058
+#: dist/converse-no-dependencies.js:48836
 #, javascript-format
 msgid "%1$s is no longer a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29061
+#: dist/converse-no-dependencies.js:48840
 #, fuzzy, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr "%1$s buvo pašalintas"
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:48844
 #, fuzzy, javascript-format
 msgid "%1$s has been muted"
 msgstr "%1$s buvo užblokuotas"
 
-#: dist/converse-no-dependencies.js:29067
+#: dist/converse-no-dependencies.js:48848
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29077
-msgid "Close and leave this room"
-msgstr ""
+#: dist/converse-no-dependencies.js:48856
+#, fuzzy
+msgid "Close and leave this groupchat"
+msgstr "Uždarykite šį pokalbių laukelį"
 
-#: dist/converse-no-dependencies.js:29078
-msgid "Configure this room"
+#: dist/converse-no-dependencies.js:48857
+#, fuzzy
+msgid "Configure this groupchat"
+msgstr "Uždarykite šį pokalbių laukelį"
+
+#: dist/converse-no-dependencies.js:48858
+msgid "Show more details about this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29122
-msgid "Hide the list of occupants"
+#: dist/converse-no-dependencies.js:48898
+msgid "Hide the list of participants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29206
+#: dist/converse-no-dependencies.js:49014
 #, javascript-format
 msgid ""
 "Error: the \"%1$s\" command takes two arguments, the user's nickname and "
 "optionally a reason."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29218
+#: dist/converse-no-dependencies.js:49023
 msgid ""
 "Sorry, an error happened while running the command. Check your browser's "
 "developer console for details."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29263
+#: dist/converse-no-dependencies.js:49082
 msgid "Change user's affiliation to admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29264
-msgid "Ban user from room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Ban user from groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29266
+#: dist/converse-no-dependencies.js:49082
 msgid "Change user role to participant"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29268
-msgid "Kick user from room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Kick user from groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29269
+#: dist/converse-no-dependencies.js:49082
 msgid "Write in 3rd person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29270
+#: dist/converse-no-dependencies.js:49082
 msgid "Grant membership to a user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29271
+#: dist/converse-no-dependencies.js:49082
 msgid "Remove user's ability to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29272
+#: dist/converse-no-dependencies.js:49082
 msgid "Change your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29273
+#: dist/converse-no-dependencies.js:49082
 msgid "Grant moderator role to user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29274
-msgid "Grant ownership of this room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Grant ownership of this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29275
+#: dist/converse-no-dependencies.js:49082
 msgid "Revoke user's membership"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29276
-msgid "Set room subject"
+#: dist/converse-no-dependencies.js:49082
+msgid "Set groupchat subject"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29277
-msgid "Set room subject (alias for /subject)"
+#: dist/converse-no-dependencies.js:49082
+msgid "Set groupchat subject (alias for /subject)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29278
+#: dist/converse-no-dependencies.js:49082
 msgid "Allow muted user to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29590
+#: dist/converse-no-dependencies.js:49412
 msgid ""
 "The nickname you chose is reserved or currently in use, please choose a "
 "different one."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29616
+#: dist/converse-no-dependencies.js:49438
 msgid "Please choose your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29618
-msgid "Enter room"
+#: dist/converse-no-dependencies.js:49440
+msgid "Enter groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29641
-msgid "This chatroom requires a password"
+#: dist/converse-no-dependencies.js:49461
+msgid "This groupchat requires a password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29642
+#: dist/converse-no-dependencies.js:49462
 msgid "Password: "
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29740
+#: dist/converse-no-dependencies.js:49463
+msgid "Submit"
+msgstr "Pateikti"
+
+#: dist/converse-no-dependencies.js:49585
 #, javascript-format
 msgid "This action was done by %1$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29743
-#: dist/converse-no-dependencies.js:29759
+#: dist/converse-no-dependencies.js:49589
+#: dist/converse-no-dependencies.js:49607
 #, javascript-format
 msgid "The reason given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29781
+#: dist/converse-no-dependencies.js:49628
 #, javascript-format
-msgid "%1$s has left and re-entered the room"
+msgid "%1$s has left and re-entered the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29786
-#, javascript-format
-msgid "%1$s has entered the room"
-msgstr ""
+#: dist/converse-no-dependencies.js:49634
+#, fuzzy, javascript-format
+msgid "%1$s has entered the groupchat"
+msgstr "%1$s buvo pašalintas"
 
-#: dist/converse-no-dependencies.js:29788
+#: dist/converse-no-dependencies.js:49636
 #, javascript-format
-msgid "%1$s has entered the room. \"%2$s\""
+msgid "%1$s has entered the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29818
+#: dist/converse-no-dependencies.js:49667
 #, javascript-format
-msgid "%1$s has entered and left the room"
+msgid "%1$s has entered and left the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29820
+#: dist/converse-no-dependencies.js:49669
 #, javascript-format
-msgid "%1$s has entered and left the room. \"%2$s\""
+msgid "%1$s has entered and left the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29832
-#, javascript-format
-msgid "%1$s has left the room"
-msgstr ""
+#: dist/converse-no-dependencies.js:49682
+#, fuzzy, javascript-format
+msgid "%1$s has left the groupchat"
+msgstr "%1$s buvo pašalintas"
 
-#: dist/converse-no-dependencies.js:29834
+#: dist/converse-no-dependencies.js:49684
 #, javascript-format
-msgid "%1$s has left the room. \"%2$s\""
+msgid "%1$s has left the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29877
-msgid "You are not on the member list of this room."
+#: dist/converse-no-dependencies.js:49730
+msgid "You are not on the member list of this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29879
-msgid "You have been banned from this room."
-msgstr ""
+#: dist/converse-no-dependencies.js:49732
+#, fuzzy
+msgid "You have been banned from this groupchat."
+msgstr "Jums buvo uždrausta prieeiga prie šio kambario"
 
-#: dist/converse-no-dependencies.js:29883
+#: dist/converse-no-dependencies.js:49736
 msgid "No nickname was specified."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29887
+#: dist/converse-no-dependencies.js:49740
 msgid "You are not allowed to create new rooms."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29889
-msgid "Your nickname doesn't conform to this room's policies."
+#: dist/converse-no-dependencies.js:49742
+msgid "Your nickname doesn't conform to this groupchat's policies."
+msgstr ""
+
+#: dist/converse-no-dependencies.js:49746
+msgid "This groupchat does not (yet) exist."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29893
-msgid "This room does not (yet) exist."
+#: dist/converse-no-dependencies.js:49748
+msgid "This groupchat has reached its maximum number of participants."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29895
-msgid "This room has reached its maximum number of occupants."
+#: dist/converse-no-dependencies.js:49750
+msgid "Remote server not found"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29950
+#: dist/converse-no-dependencies.js:49755
 #, javascript-format
-msgid "Topic set by %1$s"
+msgid "The explanation given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29981
-msgid "Chatrooms"
+#: dist/converse-no-dependencies.js:49808
+#, javascript-format
+msgid "Topic set by %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29982
+#: dist/converse-no-dependencies.js:49831
+#, fuzzy
+msgid "Groupchats"
+msgstr "Grupės"
+
+#: dist/converse-no-dependencies.js:49832
 msgid "Add a new room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29983
+#: dist/converse-no-dependencies.js:49833
 msgid "Query for rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30022
+#: dist/converse-no-dependencies.js:49871
 #, javascript-format
 msgid "Click to mention %1$s in your message."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30023
+#: dist/converse-no-dependencies.js:49872
 msgid "This user is a moderator."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30024
-msgid "This user can send messages in this room."
+#: dist/converse-no-dependencies.js:49873
+msgid "This user can send messages in this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30025
-msgid "This user can NOT send messages in this room."
+#: dist/converse-no-dependencies.js:49874
+msgid "This user can NOT send messages in this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30026
+#: dist/converse-no-dependencies.js:49875
 msgid "Moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30027
+#: dist/converse-no-dependencies.js:49876
 msgid "Visitor"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30028
+#: dist/converse-no-dependencies.js:49877
 msgid "Owner"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30029
+#: dist/converse-no-dependencies.js:49878
 msgid "Member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30030
+#: dist/converse-no-dependencies.js:49879
 msgid "Admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30082
-msgid "Occupants"
+#: dist/converse-no-dependencies.js:49921
+msgid "Participants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30102
-#: dist/converse-no-dependencies.js:30209
+#: dist/converse-no-dependencies.js:49938
+#: dist/converse-no-dependencies.js:50019
 msgid "Invite"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30121
-msgid "Features"
+#: dist/converse-no-dependencies.js:49996
+#, javascript-format
+msgid ""
+"You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
+"include a message, explaining the reason for the invitation."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30123
-msgid "Message archiving"
+#: dist/converse-no-dependencies.js:50018
+msgid "Please enter a valid XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30124
-msgid "Members only"
+#: dist/converse-no-dependencies.js:51384
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30127
-msgid "Open"
+#: dist/converse-no-dependencies.js:51386
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30128
-msgid "Password protected"
+#. workaround for Prosody which doesn't give type "headline"
+#: dist/converse-no-dependencies.js:51767
+#: dist/converse-no-dependencies.js:51773
+#, javascript-format
+msgid "Notification from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30129
-msgid "Persistent"
+#: dist/converse-no-dependencies.js:51775
+#: dist/converse-no-dependencies.js:51786
+#: dist/converse-no-dependencies.js:51789
+#, javascript-format
+msgid "%1$s says"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30132
-msgid "Temporary"
+#: dist/converse-no-dependencies.js:51823
+msgid "has come online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30134
-msgid "No password"
+#: dist/converse-no-dependencies.js:51840
+msgid "wants to be your contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30135
-msgid "This room is not publicly searchable"
+#: dist/converse-no-dependencies.js:52022
+#, javascript-format
+msgid "Log in with %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30136
-msgid "Messages are archived on the server"
-msgstr ""
+#: dist/converse-no-dependencies.js:52269
+msgid "Your Profile"
+msgstr "Tavo profilis"
 
-#: dist/converse-no-dependencies.js:30137
-msgid "This room is restricted to members only"
-msgstr ""
+#: dist/converse-no-dependencies.js:52274
+#, fuzzy
+msgid "XMPP Address (JID)"
+msgstr "XMPP adresas"
 
-#: dist/converse-no-dependencies.js:30138
-msgid "This room is being moderated"
+#: dist/converse-no-dependencies.js:52276
+msgid ""
+"Use commas to separate multiple roles. Your roles are shown next to your "
+"name on your chat messages."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30139
-msgid "All other room occupants can see your XMPP username"
+#: dist/converse-no-dependencies.js:52279
+msgid "Your avatar image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30140
-msgid "Anyone can join this room"
-msgstr ""
+#: dist/converse-no-dependencies.js:52306
+#, fuzzy
+msgid "Sorry, an error happened while trying to save your profile data."
+msgstr "Deja, bandant pašalinti %1$s iš kontaktų įvyko klaida."
 
-#: dist/converse-no-dependencies.js:30141
-msgid "This room requires a password before entry"
+#: dist/converse-no-dependencies.js:52306
+msgid "You can check your browser's developer console for any error output."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30142
-msgid "This room persists even if it's unoccupied"
-msgstr ""
+#: dist/converse-no-dependencies.js:52354
+#: dist/converse-no-dependencies.js:54896
+msgid "Away"
+msgstr "Pasišalines"
 
-#: dist/converse-no-dependencies.js:30143
-msgid "This room is publicly searchable"
-msgstr ""
+#: dist/converse-no-dependencies.js:52356
+#: dist/converse-no-dependencies.js:54895
+msgid "Busy"
+msgstr "Užsiėmes"
 
-#: dist/converse-no-dependencies.js:30144
-msgid "Only moderators can see your XMPP username"
-msgstr ""
+#: dist/converse-no-dependencies.js:52358
+msgid "Custom status"
+msgstr "Pasirinktinis statusas"
 
-#: dist/converse-no-dependencies.js:30145
-msgid "This room will disappear once the last person leaves"
+#: dist/converse-no-dependencies.js:52359
+#: dist/converse-no-dependencies.js:54898
+msgid "Offline"
+msgstr "Neprisijungęs"
+
+#: dist/converse-no-dependencies.js:52360
+#: dist/converse-no-dependencies.js:54893
+msgid "Online"
+msgstr "Prisijungęs"
+
+#: dist/converse-no-dependencies.js:52362
+msgid "Away for long"
+msgstr "Ilgai pasišalines"
+
+#: dist/converse-no-dependencies.js:52363
+msgid "Change chat status"
+msgstr "Keisti pokalbio būseną"
+
+#: dist/converse-no-dependencies.js:52364
+msgid "Personal status message"
+msgstr "Asmeninis statuso pranešimas"
+
+#: dist/converse-no-dependencies.js:52408
+#, javascript-format
+msgid "I am %1$s"
+msgstr "Aš esu %1$s"
+
+#: dist/converse-no-dependencies.js:52411
+msgid "Change settings"
+msgstr "Pakeisti nustatymus"
+
+#: dist/converse-no-dependencies.js:52412
+msgid "Click to change your chat status"
+msgstr "Spustelėkite norėdami pakeisti pokalbio būseną"
+
+#: dist/converse-no-dependencies.js:52413
+msgid "Log out"
+msgstr "Atsijungti"
+
+#: dist/converse-no-dependencies.js:52414
+msgid "Your profile"
+msgstr "Jūsų profilis"
+
+#: dist/converse-no-dependencies.js:52437
+msgid "Are you sure you want to log out?"
+msgstr "Ar tikrai norite atsijungti?"
+
+#: dist/converse-no-dependencies.js:52445
+#: dist/converse-no-dependencies.js:52455
+msgid "online"
+msgstr "prisijungęs"
+
+#: dist/converse-no-dependencies.js:52447
+msgid "busy"
+msgstr "užsiėmes"
+
+#: dist/converse-no-dependencies.js:52449
+msgid "away for long"
+msgstr "ilgai pasišalines"
+
+#: dist/converse-no-dependencies.js:52451
+msgid "away"
+msgstr "pasišalines"
+
+#: dist/converse-no-dependencies.js:52453
+msgid "offline"
+msgstr "neprisijungęs"
+
+#: dist/converse-no-dependencies.js:52755
+msgid " e.g. conversejs.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30146
-msgid "This room is not being moderated"
+#: dist/converse-no-dependencies.js:52802
+msgid "Fetch registration form"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30147
-msgid "This room does not require a password upon entry"
+#: dist/converse-no-dependencies.js:52803
+msgid "Tip: A list of public XMPP providers is available"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30187
-#, javascript-format
-msgid ""
-"You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
-"include a message, explaining the reason for the invitation."
+#: dist/converse-no-dependencies.js:52804
+msgid "here"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30208
-msgid "Please enter a valid XMPP username"
+#: dist/converse-no-dependencies.js:52852
+msgid "Sorry, we're unable to connect to your chosen provider."
 msgstr ""
 
-#. workaround for Prosody which doesn't give type "headline"
-#: dist/converse-no-dependencies.js:30469
-#: dist/converse-no-dependencies.js:30475
-#, javascript-format
-msgid "Notification from %1$s"
+#: dist/converse-no-dependencies.js:52868
+msgid ""
+"Sorry, the given provider does not support in band account registration. "
+"Please try with a different provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30477
-#: dist/converse-no-dependencies.js:30488
-#: dist/converse-no-dependencies.js:30491
+#: dist/converse-no-dependencies.js:52892
 #, javascript-format
-msgid "%1$s says"
+msgid ""
+"Something went wrong while establishing a connection with \"%1$s\". Are you "
+"sure it exists?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30525
-msgid "has come online"
+#: dist/converse-no-dependencies.js:53055
+msgid "Now logging you in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30542
-msgid "wants to be your contact"
+#: dist/converse-no-dependencies.js:53059
+msgid "Registered successfully"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30824
-msgid "Re-establishing encrypted session"
+#: dist/converse-no-dependencies.js:53168
+msgid ""
+"The provider rejected your registration attempt. Please check the values you "
+"entered for correctness."
 msgstr ""
 
-#. We need to generate a new key and instance tag
-#: dist/converse-no-dependencies.js:30835
-msgid "Generating private key."
+#: dist/converse-no-dependencies.js:53537
+msgid "Click to toggle the list of open groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30835
-msgid "Your browser might become unresponsive."
+#: dist/converse-no-dependencies.js:53538
+msgid "Open Groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30878
+#: dist/converse-no-dependencies.js:53582
+#, fuzzy, javascript-format
+msgid "Are you sure you want to leave the groupchat %1$s?"
+msgstr "Ar tikrai norite pašalinti šį kontaktą?"
+
+#: dist/converse-no-dependencies.js:54191
 #, javascript-format
-msgid ""
-"Authentication request from %1$s\n"
-"\n"
-"Your chat contact is attempting to verify your identity, by asking you the "
-"question below.\n"
-"\n"
-"%2$s"
-msgstr ""
+msgid "Sorry, there was an error while trying to add %1$s as a contact."
+msgstr "Atsiprašome, bandant pridėti %1$s kaip kontaktą įvyko klaida."
 
-#: dist/converse-no-dependencies.js:30887
-msgid "Could not verify this user's identify."
-msgstr ""
+#: dist/converse-no-dependencies.js:54402
+msgid "This client does not allow presence subscriptions"
+msgstr "Šis klientas neleidžia aktyvumo prenumeratos"
+
+#: dist/converse-no-dependencies.js:54510
+msgid "Click to hide these contacts"
+msgstr "Spustelėkite, kad paslėptumėte šiuos kontaktus"
+
+#: dist/converse-no-dependencies.js:54709
+msgid "This contact is busy"
+msgstr "Šis kontaktas užimtas"
+
+#: dist/converse-no-dependencies.js:54710
+msgid "This contact is online"
+msgstr "Šis kontaktas yra prisijungęs"
+
+#: dist/converse-no-dependencies.js:54711
+msgid "This contact is offline"
+msgstr "Šis kontaktas yra atsijungęs"
+
+#: dist/converse-no-dependencies.js:54712
+msgid "This contact is unavailable"
+msgstr "Šis kontaktas yra nepasiekiamas"
+
+#: dist/converse-no-dependencies.js:54713
+msgid "This contact is away for an extended period"
+msgstr "Šis kontaktas yra ilgai pasišalines"
 
-#: dist/converse-no-dependencies.js:30941
-msgid "Exchanging private key with contact."
+#: dist/converse-no-dependencies.js:54714
+msgid "This contact is away"
+msgstr "Šis kontaktas yra pasišalines"
+
+#: dist/converse-no-dependencies.js:54719
+msgid "Groups"
+msgstr "Grupės"
+
+#: dist/converse-no-dependencies.js:54721
+msgid "My contacts"
+msgstr "Mano kontaktai"
+
+#: dist/converse-no-dependencies.js:54723
+msgid "Pending contacts"
+msgstr "Laukiantys kontaktai"
+
+#: dist/converse-no-dependencies.js:54725
+msgid "Contact requests"
+msgstr "Prašymai pridėti prie kontaktų"
+
+#: dist/converse-no-dependencies.js:54727
+msgid "Ungrouped"
+msgstr "Nesugrupuota"
+
+#: dist/converse-no-dependencies.js:54770
+msgid "Contact name"
+msgstr "Kontakto vardas"
+
+#: dist/converse-no-dependencies.js:54773
+msgid "Add a Contact"
+msgstr "Pridėti kontaktą"
+
+#: dist/converse-no-dependencies.js:54774
+msgid "XMPP Address"
+msgstr "XMPP adresas"
+
+#: dist/converse-no-dependencies.js:54776
+msgid "name@example.org"
+msgstr "vardas@pavyzdys.lt"
+
+#: dist/converse-no-dependencies.js:54777
+msgid "Add"
+msgstr "Pridėti"
+
+#: dist/converse-no-dependencies.js:54887
+msgid "Filter"
+msgstr "Filtras"
+
+#: dist/converse-no-dependencies.js:54888
+msgid "Filter by contact name"
+msgstr "Filtruoti pagal kontaktinį vardą"
+
+#: dist/converse-no-dependencies.js:54889
+msgid "Filter by group name"
+msgstr "Filtruoti pagal grupės pavadinimą"
+
+#: dist/converse-no-dependencies.js:54890
+msgid "Filter by status"
+msgstr "Filtruoti pagal būseną"
+
+#: dist/converse-no-dependencies.js:54891
+msgid "Any"
+msgstr "Bet koks"
+
+#: dist/converse-no-dependencies.js:54892
+msgid "Unread"
+msgstr "Neskaityta"
+
+#: dist/converse-no-dependencies.js:54894
+msgid "Chatty"
+msgstr "Pokalbis"
+
+#: dist/converse-no-dependencies.js:54897
+msgid "Extended Away"
+msgstr "Ilgai pasišalines"
+
+#: dist/converse-no-dependencies.js:55053
+#: dist/converse-no-dependencies.js:55095
+#, javascript-format
+msgid "Click to remove %1$s as a contact"
+msgstr "Spustelėkite, jei norite pašalinti %1$s iš kontaktų"
+
+#: dist/converse-no-dependencies.js:55062
+#, javascript-format
+msgid "Click to accept the contact request from %1$s"
+msgstr "Spustelėkite, jei norite priimti kontaktinį prašymą iš %1$s"
+
+#: dist/converse-no-dependencies.js:55063
+#, javascript-format
+msgid "Click to decline the contact request from %1$s"
+msgstr "Spustelėkite, jei norite atmesti kontaktinį prašymą iš %1$s"
+
+#: dist/converse-no-dependencies.js:55094
+#, javascript-format
+msgid "Click to chat with %1$s (JID: %2$s)"
+msgstr "Spauskite, kad pradėtumėte pokalbį su %1$s (JID: %2$s)"
+
+#: dist/converse-no-dependencies.js:55171
+msgid "Are you sure you want to decline this contact request?"
+msgstr "Ar tikrai norite atmesti šį kontaktinį prašymą?"
+
+#: dist/converse-no-dependencies.js:55441
+msgid "Add a contact"
+msgstr "Pridėti adresatą"
+
+#: dist/converse-no-dependencies.js:56869
+msgid "Name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31038
-msgid "Your messages are not encrypted anymore"
+#: dist/converse-no-dependencies.js:56873
+#, fuzzy
+msgid "Room address (JID)"
+msgstr "XMPP adresas"
+
+#: dist/converse-no-dependencies.js:56877
+msgid "Description"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31040
-msgid ""
-"Your messages are now encrypted but your contact's identity has not been "
-"verified."
+#: dist/converse-no-dependencies.js:56883
+msgid "Topic"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31042
-msgid "Your contact's identify has been verified."
+#: dist/converse-no-dependencies.js:56887
+msgid "Topic author"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31044
-msgid "Your contact has ended encryption on their end, you should do the same."
+#: dist/converse-no-dependencies.js:56893
+#, fuzzy
+msgid "Online users"
+msgstr "Prisijungęs"
+
+#: dist/converse-no-dependencies.js:56897
+#: dist/converse-no-dependencies.js:57047
+msgid "Features"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31054
-msgid "Your message could not be sent"
+#: dist/converse-no-dependencies.js:56901
+#: dist/converse-no-dependencies.js:57055
+msgid "Password protected"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31056
-msgid "We received an unencrypted message"
+#: dist/converse-no-dependencies.js:56903
+msgid "This room requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31058
-msgid "We received an unreadable encrypted message"
+#: dist/converse-no-dependencies.js:56909
+msgid "No password required"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31084
-#, javascript-format
-msgid ""
-"Here are the fingerprints, please confirm them with %1$s, outside of this "
-"chat.\n"
-"\n"
-"Fingerprint for you, %2$s: %3$s\n"
-"\n"
-"Fingerprint for %1$s: %4$s\n"
-"\n"
-"If you have confirmed that the fingerprints match, click OK, otherwise click "
-"Cancel."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:31096
-msgid ""
-"You will be prompted to provide a security question and then an answer to "
-"that question.\n"
-"\n"
-"Your contact will then be prompted the same question and if they type the "
-"exact same answer (case sensitive), their identity will be verified."
+#: dist/converse-no-dependencies.js:56911
+msgid "This room does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31097
-msgid "What is your security question?"
+#: dist/converse-no-dependencies.js:56919
+msgid "This room is not publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31100
-msgid "What is the answer to the security question?"
+#: dist/converse-no-dependencies.js:56927
+msgid "This room is publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31104
-msgid "Invalid authentication scheme provided"
+#: dist/converse-no-dependencies.js:56933
+#: dist/converse-no-dependencies.js:57087
+msgid "Members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31121
-msgid "Your messages are not encrypted. Click here to enable OTR encryption."
+#: dist/converse-no-dependencies.js:56935
+msgid "this room is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31123
-msgid "Your messages are encrypted, but your contact has not been verified."
+#: dist/converse-no-dependencies.js:56943
+msgid "Anyone can join this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31125
-msgid "Your messages are encrypted and your contact verified."
+#: dist/converse-no-dependencies.js:56949
+#: dist/converse-no-dependencies.js:57103
+msgid "Persistent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31127
-msgid ""
-"Your contact has closed their end of the private session, you should do the "
-"same"
+#: dist/converse-no-dependencies.js:56951
+msgid "This room persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31141
-msgid "End encrypted conversation"
+#: dist/converse-no-dependencies.js:56959
+msgid "This room will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31142
-msgid "Refresh encrypted conversation"
+#: dist/converse-no-dependencies.js:56965
+#: dist/converse-no-dependencies.js:57119
+#, fuzzy
+msgid "Not anonymous"
+msgstr "Šis pokalbių kambarys nėra anonimiškas"
+
+#: dist/converse-no-dependencies.js:56967
+msgid "All other room occupants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31143
-msgid "Start encrypted conversation"
+#: dist/converse-no-dependencies.js:56975
+#: dist/converse-no-dependencies.js:57125
+msgid "Only moderators can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31144
-msgid "Verify with fingerprints"
+#: dist/converse-no-dependencies.js:56983
+msgid "This room is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31145
-msgid "Verify with SMP"
+#: dist/converse-no-dependencies.js:56989
+#: dist/converse-no-dependencies.js:57143
+msgid "Not moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31146
-msgid "What's this?"
+#: dist/converse-no-dependencies.js:56991
+msgid "This room is not being moderated"
 msgstr ""
 
-#. Translation aware constants
-#. ---------------------------
-#. We can only call the __ translation method *after* converse.js
-#. has been initialized and with it the i18n machinery. That's why
-#. we do it here in the "initialize" method and not at the top of
-#. the module.
-#: dist/converse-no-dependencies.js:31189
-msgid "unencrypted"
+#: dist/converse-no-dependencies.js:56997
+#: dist/converse-no-dependencies.js:57151
+msgid "Message archiving"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31190
-msgid "unverified"
+#: dist/converse-no-dependencies.js:56999
+#: dist/converse-no-dependencies.js:57149
+msgid "Messages are archived on the server"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31191
-msgid "verified"
+#: dist/converse-no-dependencies.js:57053
+msgid "This groupchat requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31192
-msgid "finished"
+#: dist/converse-no-dependencies.js:57061
+msgid "This groupchat does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31788
-#, javascript-format
-msgid "Sorry, there was an error while trying to add %1$s as a contact."
-msgstr "Atsiprašome, bandant pridėti %1$s kaip kontaktą įvyko klaida."
+#: dist/converse-no-dependencies.js:57063
+msgid "No password"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:31936
-msgid "This client does not allow presence subscriptions"
-msgstr "Šis klientas neleidžia aktyvumo prenumeratos"
+#: dist/converse-no-dependencies.js:57069
+msgid "This groupchat is not publicly searchable"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:32028
-msgid "Click to hide these contacts"
-msgstr "Spustelėkite, kad paslėptumėte šiuos kontaktus"
+#: dist/converse-no-dependencies.js:57077
+msgid "This groupchat is publicly searchable"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:32112
-msgid "Don't have a chat account?"
+#: dist/converse-no-dependencies.js:57085
+msgid "this groupchat is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32114
-msgid "Create an account"
+#: dist/converse-no-dependencies.js:57093
+msgid "Anyone can join this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32126
-msgid "Create your account"
+#: dist/converse-no-dependencies.js:57101
+msgid "This groupchat persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32128
-msgid "Please enter the XMPP provider to register with:"
+#: dist/converse-no-dependencies.js:57109
+msgid "This groupchat will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32148
-msgid "Already have a chat account?"
+#: dist/converse-no-dependencies.js:57117
+msgid "All other groupchat participants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32150
-msgid "Log in here"
+#: dist/converse-no-dependencies.js:57133
+msgid "This groupchat is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32162
-msgid "Account Registration:"
+#: dist/converse-no-dependencies.js:57141
+msgid "This groupchat is not being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32170
-msgid "Register"
+#: dist/converse-no-dependencies.js:58006
+msgid "XMPP Username:"
+msgstr "XMPP vartotojo vardas:"
+
+#: dist/converse-no-dependencies.js:58012
+msgid "Password:"
+msgstr "Slaptažodis:"
+
+#: dist/converse-no-dependencies.js:58014
+msgid "password"
+msgstr "slaptažodis"
+
+#: dist/converse-no-dependencies.js:58022
+msgid "This is a trusted device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32174
-msgid "Choose a different provider"
+#: dist/converse-no-dependencies.js:58024
+msgid ""
+"To improve performance, we cache your data in this browser. Uncheck this box "
+"if this is a public computer or if you want your data to be deleted when you "
+"log out. It's important that you explicitly log out, otherwise not all "
+"cached data might be deleted."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32186
-msgid "Hold tight, we're fetching the registration form…"
+#: dist/converse-no-dependencies.js:58026
+#, fuzzy
+msgid "Log in"
+msgstr "Atsijungti"
+
+#: dist/converse-no-dependencies.js:58032
+msgid "Click here to log in anonymously"
+msgstr "Spauskite čia norėdami prisijungti anonimiškai"
+
+#: dist/converse-no-dependencies.js:58403
+msgid "Don't have a chat account?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32321
-msgid " e.g. conversejs.org"
+#: dist/converse-no-dependencies.js:58405
+msgid "Create an account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32367
-msgid "Fetch registration form"
+#: dist/converse-no-dependencies.js:58426
+msgid "Create your account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32368
-msgid "Tip: A list of public XMPP providers is available"
+#: dist/converse-no-dependencies.js:58428
+msgid "Please enter the XMPP provider to register with:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32369
-msgid "here"
+#: dist/converse-no-dependencies.js:58448
+msgid "Already have a chat account?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32417
-msgid "Sorry, we're unable to connect to your chosen provider."
+#: dist/converse-no-dependencies.js:58450
+msgid "Log in here"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32433
-msgid ""
-"Sorry, the given provider does not support in band account registration. "
-"Please try with a different provider."
+#: dist/converse-no-dependencies.js:58471
+msgid "Account Registration:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32457
-#, javascript-format
-msgid ""
-"Something went wrong while establishing a connection with \"%1$s\". Are you "
-"sure it exists?"
+#: dist/converse-no-dependencies.js:58479
+msgid "Register"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32620
-msgid "Now logging you in"
+#: dist/converse-no-dependencies.js:58483
+msgid "Choose a different provider"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32624
-msgid "Registered successfully"
+#: dist/converse-no-dependencies.js:58504
+msgid "Hold tight, we're fetching the registration form…"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32733
-msgid ""
-"The provider rejected your registration attempt. Please check the values you "
-"entered for correctness."
+#: dist/converse-no-dependencies.js:59643
+#: dist/converse-no-dependencies.js:59672
+msgid "Download"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33149
-msgid "Click to toggle the rooms list"
+#: dist/converse-no-dependencies.js:59662
+#, javascript-format
+msgid "Download: \"%1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33150
-msgid "Open Rooms"
+#: dist/converse-no-dependencies.js:59685
+msgid "Download video file"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33194
-#, javascript-format
-msgid "Are you sure you want to leave the room %1$s?"
+#: dist/converse-no-dependencies.js:59698
+msgid "Download audio file"
 msgstr ""
 
 #~ msgid "Show hidden message"

File diff suppressed because it is too large
+ 0 - 0
locale/nb/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 358 - 601
locale/nb/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/nl/LC_MESSAGES/converse.json


+ 118 - 56
locale/nl/LC_MESSAGES/converse.po

@@ -8,8 +8,8 @@ msgstr ""
 "Project-Id-Version: Converse.js 0.4\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-05-17 11:19+0200\n"
-"PO-Revision-Date: 2018-04-30 19:54+0000\n"
-"Last-Translator: Nathan Follens <nathan@email.is>\n"
+"PO-Revision-Date: 2018-07-03 10:22+0000\n"
+"Last-Translator: Nathan Follens <nthn@unseen.is>\n"
 "Language-Team: Dutch <https://hosted.weblate.org/projects/conversejs/"
 "translations/nl/>\n"
 "Language: nl\n"
@@ -17,7 +17,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
 "domain: converse\n"
 "lang: nl\n"
 "plural_forms: nplurals=2; plural=(n != 1);\n"
@@ -177,39 +177,17 @@ msgstr ""
 "De grootte van het bestand, %1$s, overschrijdt het maximum toegestaan door "
 "je server, %2$s."
 
-#: dist/converse-no-dependencies.js:22197
+#: dist/converse-no-dependencies.js:18681
 msgid "Show more"
 msgstr "Meer tonen"
 
-#: dist/converse-no-dependencies.js:22248
-msgid "Typing from another device"
-msgstr "Typt op een ander apparaat"
-
-#: dist/converse-no-dependencies.js:22250
-msgid "is typing"
-msgstr "is aan typen"
-
-#: dist/converse-no-dependencies.js:22254
-msgid "Stopped typing on the other device"
-msgstr "Gestopt met typen op het andere apparaat"
-
-#: dist/converse-no-dependencies.js:22256
-msgid "has stopped typing"
-msgstr "is gestopt met typen"
-
-#: dist/converse-no-dependencies.js:22259
-#: dist/converse-no-dependencies.js:23256
-#: dist/converse-no-dependencies.js:30521
-msgid "has gone away"
-msgstr "is afwezig"
-
 #: dist/converse-no-dependencies.js:22488
 msgid "Close this chat box"
 msgstr "Dit gespreksvenster sluiten"
 
 #: dist/converse-no-dependencies.js:22516
 msgid "The User's Profile Image"
-msgstr ""
+msgstr "Profielafbeelding van gebruiker"
 
 #: dist/converse-no-dependencies.js:22519
 #: dist/converse-no-dependencies.js:25289
@@ -220,18 +198,16 @@ msgstr "Sluiten"
 #: dist/converse-no-dependencies.js:22520
 #: dist/converse-no-dependencies.js:25290
 msgid "Email"
-msgstr ""
+msgstr "E-mail"
 
 #: dist/converse-no-dependencies.js:22521
 #: dist/converse-no-dependencies.js:25291
-#, fuzzy
 msgid "Full Name"
-msgstr "Naam"
+msgstr "Volledige naam"
 
 #: dist/converse-no-dependencies.js:22522
-#, fuzzy
 msgid "Jabber ID"
-msgstr "XMPP-ID:"
+msgstr "Jabber-ID"
 
 #: dist/converse-no-dependencies.js:22523
 #: dist/converse-no-dependencies.js:25292
@@ -240,23 +216,22 @@ msgid "Nickname"
 msgstr "Bijnaam"
 
 #: dist/converse-no-dependencies.js:22524
-#, fuzzy
 msgid "Remove as contact"
-msgstr "Voeg een contact toe"
+msgstr "Contact verwijderen"
 
 #: dist/converse-no-dependencies.js:22525
 msgid "Refresh"
-msgstr ""
+msgstr "Verversen"
 
 #: dist/converse-no-dependencies.js:22526
 #: dist/converse-no-dependencies.js:25294
 msgid "Role"
-msgstr ""
+msgstr "Rol"
 
 #: dist/converse-no-dependencies.js:22527
 #: dist/converse-no-dependencies.js:25297
 msgid "URL"
-msgstr ""
+msgstr "URL"
 
 #: dist/converse-no-dependencies.js:22566
 #: dist/converse-no-dependencies.js:24293
@@ -313,7 +288,7 @@ msgstr "Klik hier om een verborgen bericht te schrijven"
 msgid "Clear all messages"
 msgstr "Alle berichten wissen"
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:19149
 msgid "Insert emojis"
 msgstr "Voeg smiley’s in"
 
@@ -335,7 +310,7 @@ msgstr "Schrijf in de derde persoon"
 msgid "Show this menu"
 msgstr "Toon dit menu"
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:19614
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr "Weet je zeker dat je de berichten in dit gesprek wil wissen?"
 
@@ -349,10 +324,96 @@ msgstr "is offline"
 msgid "is busy"
 msgstr "is bezet"
 
-#: dist/converse-no-dependencies.js:23260
+#: dist/converse-no-dependencies.js:19710
 msgid "is online"
 msgstr "is online"
 
+#: dist/converse-no-dependencies.js:22577
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
+msgstr "%1$s heeft je uitgenodigd in het groepsgesprek: %2$s"
+
+#: dist/converse-no-dependencies.js:22579
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
+msgstr ""
+"%1$s heeft je uitgenodigd in het groepsgesprek: %2$s. en gaf volgende reden: "
+"‘%3$s’"
+
+#: dist/converse-no-dependencies.js:22956
+#: dist/converse-no-dependencies.js:23041
+#: dist/converse-no-dependencies.js:32286
+msgid "Bookmark this room"
+msgstr "Gesprek toevoegen aan bladwijzers"
+
+#: dist/converse-no-dependencies.js:23042
+msgid "The name for this bookmark:"
+msgstr "De naam voor deze bladwijzer:"
+
+#: dist/converse-no-dependencies.js:23043
+msgid "Would you like this room to be automatically joined upon startup?"
+msgstr "Wil je automatisch deelnemen aan dit groepsgesprek bij opstarten?"
+
+#: dist/converse-no-dependencies.js:23044
+msgid "What should your nickname for this room be?"
+msgstr "Wat moet je bijnaam in dit groepsgesprek zijn?"
+
+#: dist/converse-no-dependencies.js:23046
+#: dist/converse-no-dependencies.js:25364
+msgid "Save"
+msgstr "Opslaan"
+
+#: dist/converse-no-dependencies.js:23047
+#: dist/converse-no-dependencies.js:25360
+#: dist/converse-no-dependencies.js:31362
+msgid "Cancel"
+msgstr "Annuleren"
+
+#: dist/converse-no-dependencies.js:23120
+#, javascript-format
+msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
+msgstr "Weet je zeker dat je de bladwijzer ‘%1$s’ wil verwijderen?"
+
+#: dist/converse-no-dependencies.js:23236
+msgid "Sorry, something went wrong while trying to save your bookmark."
+msgstr "Sorry, er ging iets mis bij het opslaan van je bladwijzer."
+
+#: dist/converse-no-dependencies.js:23315
+#: dist/converse-no-dependencies.js:32284
+msgid "Leave this room"
+msgstr "Dit gesprek verlaten"
+
+#: dist/converse-no-dependencies.js:23316
+msgid "Remove this bookmark"
+msgstr "Deze bladwijzer verwijderen"
+
+#: dist/converse-no-dependencies.js:23317
+#: dist/converse-no-dependencies.js:32285
+msgid "Unbookmark this room"
+msgstr "Bladwijzer voor dit gesprek verwijderen"
+
+#: dist/converse-no-dependencies.js:23318
+#: dist/converse-no-dependencies.js:28813
+#: dist/converse-no-dependencies.js:32287
+msgid "Show more information on this room"
+msgstr "Toon meer informatie over dit groepsgesprek"
+
+#: dist/converse-no-dependencies.js:23321
+#: dist/converse-no-dependencies.js:28812
+#: dist/converse-no-dependencies.js:32289
+msgid "Click to open this room"
+msgstr "Klik om dit groepsgesprek te openen"
+
+#: dist/converse-no-dependencies.js:23357
+msgid "Click to toggle the bookmarks list"
+msgstr "Klik om de lijst met bladwijzers te tonen/verbergen"
+
+#: dist/converse-no-dependencies.js:23358
+msgid "Bookmarks"
+msgstr "Bladwijzers"
+
 #: dist/converse-no-dependencies.js:23501
 msgid "XMPP Username:"
 msgstr "XMPP-gebruikersnaam:"
@@ -540,28 +601,29 @@ msgid "Your Profile"
 msgstr "Je profiel"
 
 #: dist/converse-no-dependencies.js:25293
-#, fuzzy
 msgid "XMPP Address (JID)"
-msgstr "XMPP-adres"
+msgstr "XMPP-adres (JID)"
 
 #: dist/converse-no-dependencies.js:25295
 msgid ""
 "Use commas to separate multiple roles. Your roles are shown next to your "
 "name on your chat messages."
 msgstr ""
+"Gebruik komma’s om meerdere rollen op te geven. Je rollen worden naast je "
+"naam op je chatberichten getoond."
 
 #: dist/converse-no-dependencies.js:25298
 msgid "Your avatar image"
-msgstr ""
+msgstr "Jouw avatarafbeelding"
 
 #: dist/converse-no-dependencies.js:25325
-#, fuzzy
 msgid "Sorry, an error happened while trying to save your profile data."
-msgstr "Sorry, er ging iets mis bij het opslaan van je bladwijzer."
+msgstr "Sorry, er ging iets mis bij het opslaan van je profielgegevens."
 
 #: dist/converse-no-dependencies.js:25325
 msgid "You can check your browser's developer console for any error output."
 msgstr ""
+"Je kan de ontwikkelaarsconsole van je browser nakijken voor foutenuitvoer."
 
 #: dist/converse-no-dependencies.js:25377
 msgid "Custom status"
@@ -878,22 +940,22 @@ msgstr "Deelnemen"
 msgid "Message"
 msgstr "Bericht"
 
-#: dist/converse-no-dependencies.js:29058
+#: dist/converse-no-dependencies.js:29053
 #, javascript-format
 msgid "%1$s is no longer a moderator"
 msgstr "%1$s is geen moderator meer"
 
-#: dist/converse-no-dependencies.js:29061
+#: dist/converse-no-dependencies.js:29056
 #, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr "%1$s heeft terug een stem"
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:29059
 #, javascript-format
 msgid "%1$s has been muted"
 msgstr "%1$s is gedempt"
 
-#: dist/converse-no-dependencies.js:29067
+#: dist/converse-no-dependencies.js:29062
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr "%1$s is nu een moderator"
@@ -924,6 +986,8 @@ msgid ""
 "Sorry, an error happened while running the command. Check your browser's "
 "developer console for details."
 msgstr ""
+"Sorry, er trad een fout op bij het uitvoeren van de opdracht. Controleer de "
+"ontwikkelaarsconsole van je browser voor details."
 
 #: dist/converse-no-dependencies.js:29263
 msgid "Change user's affiliation to admin"
@@ -1114,26 +1178,24 @@ msgid "This user can NOT send messages in this room."
 msgstr "Deze gebruiker kan GEEN berichten sturen in dit groepsgesprek."
 
 #: dist/converse-no-dependencies.js:30026
-#, fuzzy
 msgid "Moderator"
-msgstr "Gemodereerd"
+msgstr "Moderator"
 
 #: dist/converse-no-dependencies.js:30027
 msgid "Visitor"
-msgstr ""
+msgstr "Bezoeker"
 
 #: dist/converse-no-dependencies.js:30028
 msgid "Owner"
-msgstr ""
+msgstr "Eigenaar"
 
 #: dist/converse-no-dependencies.js:30029
-#, fuzzy
 msgid "Member"
-msgstr "Alleen-leden"
+msgstr "Lid"
 
 #: dist/converse-no-dependencies.js:30030
 msgid "Admin"
-msgstr ""
+msgstr "Beheerder"
 
 #: dist/converse-no-dependencies.js:30082
 msgid "Occupants"

File diff suppressed because it is too large
+ 0 - 0
locale/nl_BE/LC_MESSAGES/converse.json


+ 120 - 33
locale/nl_BE/LC_MESSAGES/converse.po

@@ -8,8 +8,8 @@ msgstr ""
 "Project-Id-Version: Converse.js 3.3.4\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-05-17 11:19+0200\n"
-"PO-Revision-Date: 2018-04-30 19:58+0000\n"
-"Last-Translator: Nathan Follens <nathan@email.is>\n"
+"PO-Revision-Date: 2018-07-03 10:26+0000\n"
+"Last-Translator: Nathan Follens <nthn@unseen.is>\n"
 "Language-Team: Flemish <https://hosted.weblate.org/projects/conversejs/"
 "translations/nl_BE/>\n"
 "Language: nl_BE\n"
@@ -17,7 +17,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.0-dev\n"
+"X-Generator: Weblate 3.1-dev\n"
 
 #: dist/converse-no-dependencies.js:9853 dist/converse-no-dependencies.js:9882
 msgid "Download"
@@ -174,7 +174,7 @@ msgstr ""
 "De grootte van het bestand, %1$s, overschrijd het maximum toegelaten door "
 "uwe server, %2$s."
 
-#: dist/converse-no-dependencies.js:22197
+#: dist/converse-no-dependencies.js:18681
 msgid "Show more"
 msgstr "Meer tonen"
 
@@ -206,7 +206,7 @@ msgstr "Dit gespreksvenster sluiten"
 
 #: dist/converse-no-dependencies.js:22516
 msgid "The User's Profile Image"
-msgstr ""
+msgstr "Profielafbeelding van gebruiker"
 
 #: dist/converse-no-dependencies.js:22519
 #: dist/converse-no-dependencies.js:25289
@@ -217,16 +217,16 @@ msgstr "Sluiten"
 #: dist/converse-no-dependencies.js:22520
 #: dist/converse-no-dependencies.js:25290
 msgid "Email"
-msgstr ""
+msgstr "E-mail"
 
 #: dist/converse-no-dependencies.js:22521
 #: dist/converse-no-dependencies.js:25291
 msgid "Full Name"
-msgstr ""
+msgstr "Volledige naam"
 
 #: dist/converse-no-dependencies.js:22522
 msgid "Jabber ID"
-msgstr ""
+msgstr "Jabber-ID"
 
 #: dist/converse-no-dependencies.js:22523
 #: dist/converse-no-dependencies.js:25292
@@ -235,23 +235,22 @@ msgid "Nickname"
 msgstr "Bijnaam"
 
 #: dist/converse-no-dependencies.js:22524
-#, fuzzy
 msgid "Remove as contact"
-msgstr "Voeg een contact toe"
+msgstr "Contact verwijderen"
 
 #: dist/converse-no-dependencies.js:22525
 msgid "Refresh"
-msgstr ""
+msgstr "Vernieuwen"
 
 #: dist/converse-no-dependencies.js:22526
 #: dist/converse-no-dependencies.js:25294
 msgid "Role"
-msgstr ""
+msgstr "Rol"
 
 #: dist/converse-no-dependencies.js:22527
 #: dist/converse-no-dependencies.js:25297
 msgid "URL"
-msgstr ""
+msgstr "URL"
 
 #: dist/converse-no-dependencies.js:22566
 #: dist/converse-no-dependencies.js:24293
@@ -261,7 +260,7 @@ msgstr "Zij’ ge zeker da’ ge dit contact wild verwijderen?"
 #: dist/converse-no-dependencies.js:22575
 #: dist/converse-no-dependencies.js:25325
 msgid "Error"
-msgstr ""
+msgstr "Fout"
 
 #: dist/converse-no-dependencies.js:22575
 #: dist/converse-no-dependencies.js:24301
@@ -308,7 +307,7 @@ msgstr "Klikt hier voor een verborgen bericht te schrijven"
 msgid "Clear all messages"
 msgstr "Alle berichten wissen"
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:19149
 msgid "Insert emojis"
 msgstr "Voegd smiley’s in"
 
@@ -330,7 +329,7 @@ msgstr "Schrijfd in den derde persoon"
 msgid "Show this menu"
 msgstr "Toond dit menu"
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:19614
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr "Zij’ ge zeker da’ ge de berichten in dit gesprek wild wissen?"
 
@@ -344,10 +343,96 @@ msgstr "is offline"
 msgid "is busy"
 msgstr "is bezet"
 
-#: dist/converse-no-dependencies.js:23260
+#: dist/converse-no-dependencies.js:19710
 msgid "is online"
 msgstr "is online"
 
+#: dist/converse-no-dependencies.js:22577
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
+msgstr "%1$s heefd u uitgenodigd in het groepsgesprek: %2$s"
+
+#: dist/converse-no-dependencies.js:22579
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
+msgstr ""
+"%1$s heefd u uitgenodigd in het groepsgesprek: %2$s. en gaf volgende reden: "
+"‘%3$s’"
+
+#: dist/converse-no-dependencies.js:22956
+#: dist/converse-no-dependencies.js:23041
+#: dist/converse-no-dependencies.js:32286
+msgid "Bookmark this room"
+msgstr "Gesprek toevoegen aan bladwijzers"
+
+#: dist/converse-no-dependencies.js:23042
+msgid "The name for this bookmark:"
+msgstr "De naam voor dezen bladwijzer:"
+
+#: dist/converse-no-dependencies.js:23043
+msgid "Would you like this room to be automatically joined upon startup?"
+msgstr "Wild g’automatisch deelnemen aan dit groepsgesprek bij opstarten?"
+
+#: dist/converse-no-dependencies.js:23044
+msgid "What should your nickname for this room be?"
+msgstr "Wa moet uwen bijnaam in dit groepsgesprek zijn?"
+
+#: dist/converse-no-dependencies.js:23046
+#: dist/converse-no-dependencies.js:25364
+msgid "Save"
+msgstr "Opslaan"
+
+#: dist/converse-no-dependencies.js:23047
+#: dist/converse-no-dependencies.js:25360
+#: dist/converse-no-dependencies.js:31362
+msgid "Cancel"
+msgstr "Annuleren"
+
+#: dist/converse-no-dependencies.js:23120
+#, javascript-format
+msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
+msgstr "Zij’ ge zeker da’ ge den bladwijzer ‘%1$s’ wild verwijderen?"
+
+#: dist/converse-no-dependencies.js:23236
+msgid "Sorry, something went wrong while trying to save your bookmark."
+msgstr "Sorry, der ging iets mis bij het opslaan van uwen bladwijzer."
+
+#: dist/converse-no-dependencies.js:23315
+#: dist/converse-no-dependencies.js:32284
+msgid "Leave this room"
+msgstr "Dit gesprek verlaten"
+
+#: dist/converse-no-dependencies.js:23316
+msgid "Remove this bookmark"
+msgstr "Dezen bladwijzer verwijderen"
+
+#: dist/converse-no-dependencies.js:23317
+#: dist/converse-no-dependencies.js:32285
+msgid "Unbookmark this room"
+msgstr "Bladwijzer voor dit gesprek verwijderen"
+
+#: dist/converse-no-dependencies.js:23318
+#: dist/converse-no-dependencies.js:28813
+#: dist/converse-no-dependencies.js:32287
+msgid "Show more information on this room"
+msgstr "Toond meer informatie over dit groepsgesprek"
+
+#: dist/converse-no-dependencies.js:23321
+#: dist/converse-no-dependencies.js:28812
+#: dist/converse-no-dependencies.js:32289
+msgid "Click to open this room"
+msgstr "Klikt voor dit groepsgesprek t’openen"
+
+#: dist/converse-no-dependencies.js:23357
+msgid "Click to toggle the bookmarks list"
+msgstr "Klikt voor de lijst met bladwijzers te tonen/verbergen"
+
+#: dist/converse-no-dependencies.js:23358
+msgid "Bookmarks"
+msgstr "Bladwijzers"
+
 #: dist/converse-no-dependencies.js:23501
 msgid "XMPP Username:"
 msgstr "XMPP-gebruikersnaam:"
@@ -535,28 +620,30 @@ msgid "Your Profile"
 msgstr "Uw profiel"
 
 #: dist/converse-no-dependencies.js:25293
-#, fuzzy
 msgid "XMPP Address (JID)"
-msgstr "XMPP-adres"
+msgstr "XMPP-adres (JID)"
 
 #: dist/converse-no-dependencies.js:25295
 msgid ""
 "Use commas to separate multiple roles. Your roles are shown next to your "
 "name on your chat messages."
 msgstr ""
+"Gebruikt komma’s voor meerdere rollen op te geven. Uw rollen worden naast "
+"uwe naam op uw berichten weergegeven."
 
 #: dist/converse-no-dependencies.js:25298
 msgid "Your avatar image"
-msgstr ""
+msgstr "Uw avatarafbeelding"
 
 #: dist/converse-no-dependencies.js:25325
-#, fuzzy
 msgid "Sorry, an error happened while trying to save your profile data."
-msgstr "Sorry, der ging iets mis bij het opslaan van uwen bladwijzer."
+msgstr ""
+"Sorry, der is een fout opgetreden bij het opslaan van uw profielgegevens."
 
 #: dist/converse-no-dependencies.js:25325
 msgid "You can check your browser's developer console for any error output."
 msgstr ""
+"Ge kunt de ontwikkelaarsconsole van uwen browser nakijken voor foutenuitvoer."
 
 #: dist/converse-no-dependencies.js:25377
 msgid "Custom status"
@@ -873,22 +960,22 @@ msgstr "Deelnemen"
 msgid "Message"
 msgstr "Bericht"
 
-#: dist/converse-no-dependencies.js:29058
+#: dist/converse-no-dependencies.js:29053
 #, javascript-format
 msgid "%1$s is no longer a moderator"
 msgstr "%1$s is gene moderator meer"
 
-#: dist/converse-no-dependencies.js:29061
+#: dist/converse-no-dependencies.js:29056
 #, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr "%1$s heefd terug een stem"
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:29059
 #, javascript-format
 msgid "%1$s has been muted"
 msgstr "%1$s is gedempt"
 
-#: dist/converse-no-dependencies.js:29067
+#: dist/converse-no-dependencies.js:29062
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr "%1$s is nu ne moderator"
@@ -919,6 +1006,8 @@ msgid ""
 "Sorry, an error happened while running the command. Check your browser's "
 "developer console for details."
 msgstr ""
+"Sorry, der is een fout opgetreden bij het uitvoeren van de opdracht. "
+"Controleert den ontwikkelaarsconsole van uwen browser voor details."
 
 #: dist/converse-no-dependencies.js:29263
 msgid "Change user's affiliation to admin"
@@ -1109,26 +1198,24 @@ msgid "This user can NOT send messages in this room."
 msgstr "Deze gebruiker kan GEEN berichten sturen in dit groepsgesprek."
 
 #: dist/converse-no-dependencies.js:30026
-#, fuzzy
 msgid "Moderator"
-msgstr "Gemodereerd"
+msgstr "Moderator"
 
 #: dist/converse-no-dependencies.js:30027
 msgid "Visitor"
-msgstr ""
+msgstr "Bezoeker"
 
 #: dist/converse-no-dependencies.js:30028
 msgid "Owner"
-msgstr ""
+msgstr "Eigenaar"
 
 #: dist/converse-no-dependencies.js:30029
-#, fuzzy
 msgid "Member"
-msgstr "Alleen-leden"
+msgstr "Lid"
 
 #: dist/converse-no-dependencies.js:30030
 msgid "Admin"
-msgstr ""
+msgstr "Beheerder"
 
 #: dist/converse-no-dependencies.js:30082
 msgid "Occupants"

File diff suppressed because it is too large
+ 0 - 0
locale/pl/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 1142 - 984
locale/pl/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/pt_BR/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 355 - 599
locale/pt_BR/LC_MESSAGES/converse.po


+ 0 - 643
locale/pt_BR/LC_MESSAGES/pt_BR.js

@@ -1,643 +0,0 @@
-(function (root, factory) {
-    var translations = {
-        "domain": "converse",
-        "locale_data": {
-            "converse": {
-                "": {
-                    "Project-Id-Version": "Converse.js 0.6.3",
-                    "Report-Msgid-Bugs-To": "",
-                    "POT-Creation-Date": "2013-09-15 21:55+0200",
-                    "PO-Revision-Date": "2014-07-07 11:02+0200",
-                    "Last-Translator": "Alan Meira <alan@engarte.com>",
-                    "Language-Team": "Brazilian Portuguese",
-                    "Language": "pt_BR",
-                    "MIME-Version": "1.0",
-                    "Content-Type": "text/plain; charset=UTF-8",
-                    "Content-Transfer-Encoding": "8bit",
-                    "Plural-Forms": "nplurals=2; plural=(n > 1);",
-                    "domain": "converse",
-                    "lang": "pt_BR",
-                    "plural_forms": "nplurals=2; plural=(n != 1);"
-                },
-                "unencrypted": [
-                    null,
-                    "não-criptografado"
-                ],
-                "unverified": [
-                    null,
-                    "não-verificado"
-                ],
-                "verified": [
-                    null,
-                    "não-verificado"
-                ],
-                "finished": [
-                    null,
-                    "finalizado"
-                ],
-                "Disconnected": [
-                    null,
-                    "Desconectado"
-                ],
-                "Error": [
-                    null,
-                    "Erro"
-                ],
-                "Connecting": [
-                    null,
-                    "Conectando"
-                ],
-                "Connection Failed": [
-                    null,
-                    "Falha de conexão"
-                ],
-                "Authenticating": [
-                    null,
-                    "Autenticando"
-                ],
-                "Authentication Failed": [
-                    null,
-                    "Falha de autenticação"
-                ],
-                "Disconnecting": [
-                    null,
-                    "Desconectando"
-                ],
-                "Re-establishing encrypted session": [
-                    null,
-                    "Reestabelecendo sessão criptografada"
-                ],
-                "Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.": [
-                    null,
-                    "Seu navegador precisa gerar uma chave-privada, que será usada em sua sessão criptografada de bate-papo. Isso pode levar até 30 segundos durante os quais seu navegador poderá se travar ou não responder."
-                ],
-                "Private key generated.": [
-                    null,
-                    "Chave-privada gerada:"
-                ],
-                "Authentication request from %1$s\n\nYour buddy is attempting to verify your identity, by asking you the question below.\n\n%2$s": [
-                    null,
-                    "Pedido de autenticação de %$s\n\nSeu contato está tentando verificar sua identidade, perguntando a questão abaixo.\n\n%2$s"
-                ],
-                "Could not verify this user's identify.": [
-                    null,
-                    "Não foi possível verificar a identidade deste usuário."
-                ],
-                "Personal message": [
-                    null,
-                    "Mensagem pessoal"
-                ],
-                "Start encrypted conversation": [
-                    null,
-                    "Iniciar conversa criptografada"
-                ],
-                "Refresh encrypted conversation": [
-                    null,
-                    "Atualizar conversa criptografada"
-                ],
-                "End encrypted conversation": [
-                    null,
-                    "Finalizar conversa criptografada"
-                ],
-                "Verify with SMP": [
-                    null,
-                    "Verificar com SMP"
-                ],
-                "Verify with fingerprints": [
-                    null,
-                    "Verificar com assinatura digital"
-                ],
-                "What's this?": [
-                    null,
-                    "O que é isso?"
-                ],
-                "me": [
-                    null,
-                    "eu"
-                ],
-                "Show this menu": [
-                    null,
-                    "Mostrar o menu"
-                ],
-                "Write in the third person": [
-                    null,
-                    "Escrever em terceira pessoa"
-                ],
-                "Remove messages": [
-                    null,
-                    "Remover mensagens"
-                ],
-                "Your message could not be sent": [
-                    null,
-                    "Sua mensagem não pôde ser enviada"
-                ],
-                "We received an unencrypted message": [
-                    null,
-                    "Recebemos uma mensagem não-criptografada"
-                ],
-                "We received an unreadable encrypted message": [
-                    null,
-                    "Recebemos uma mensagem não-criptografada ilegível"
-                ],
-                "This user has requested an encrypted session.": [
-                    null,
-                    "Usuário pediu uma sessão criptografada."
-                ],
-                "Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.": [
-                    null,
-                    "Aqui estão as assinaturas digitais, por favor confirme elas com %1$s, fora deste chat.\n\nAssinaturas para você, %2$s: %3$s\n\nAssinaturas para %1$s: %4$s\n\nSe você tiver confirmado que as assinaturas conferem, clique OK, caso contrário, clique Cancel."
-                ],
-                "You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will have been verified.": [
-                    null,
-                    "Será solicitado que você informe uma pergunta de segurança e também uma resposta.\n\nNós iremos, então, transfeir a pergunta para seu contato e caso ele envie corretamente a mesma resposta (caso sensitivo), a identidade dele será verificada."
-                ],
-                "What is your security question?": [
-                    null,
-                    "Qual é a sua pergunta de segurança?"
-                ],
-                "What is the answer to the security question?": [
-                    null,
-                    "Qual é a resposta para a pergunta de segurança?"
-                ],
-                "Invalid authentication scheme provided": [
-                    null,
-                    "Schema de autenticação fornecido é inválido"
-                ],
-                "Your messages are not encrypted anymore": [
-                    null,
-                    "Suas mensagens não estão mais criptografadas"
-                ],
-                "Your messages are now encrypted but your buddy's identity has not been verified.": [
-                    null,
-                    "Suas mensagens estão agora criptografadas mas a identidade do contato não foi confirmada."
-                ],
-                "Your buddy's identify has been verified.": [
-                    null,
-                    "A identidade do contato foi verificada."
-                ],
-                "Your buddy has ended encryption on their end, you should do the same.": [
-                    null,
-                    "Seu contato parou de usar criptografia, você deveria fazer o mesmo."
-                ],
-                "Your messages are not encrypted. Click here to enable OTR encryption.": [
-                    null,
-                    "Suas mensagens não estão criptografadas. Clique aqui para habilitar criptografia OTR."
-                ],
-                "Your messages are encrypted, but your buddy has not been verified.": [
-                    null,
-                    "Suas mensagens estão criptografadas, mas seu contato não foi verificado."
-                ],
-                "Your messages are encrypted and your buddy verified.": [
-                    null,
-                    "Suas mensagens estão criptografadas e seu contato verificado."
-                ],
-                "Your buddy has closed their end of the private session, you should do the same": [
-                    null,
-                    "Seu contato fechou a sessão privada, você deveria fazer o mesmo"
-                ],
-                "Contacts": [
-                    null,
-                    "Contatos"
-                ],
-                "Online": [
-                    null,
-                    "Online"
-                ],
-                "Busy": [
-                    null,
-                    "Ocupado"
-                ],
-                "Away": [
-                    null,
-                    "Ausente"
-                ],
-                "Offline": [
-                    null,
-                    "Offline"
-                ],
-                "Click to add new chat contacts": [
-                    null,
-                    "Clique para adicionar novos contatos ao chat"
-                ],
-                "Add a contact": [
-                    null,
-                    "Adicionar contato"
-                ],
-                "Contact username": [
-                    null,
-                    "Usuário do contatt"
-                ],
-                "Add": [
-                    null,
-                    "Adicionar"
-                ],
-                "Contact name": [
-                    null,
-                    "Nome do contato"
-                ],
-                "Search": [
-                    null,
-                    "Procurar"
-                ],
-                "No users found": [
-                    null,
-                    "Não foram encontrados usuários"
-                ],
-                "Click to add as a chat contact": [
-                    null,
-                    "Clique para adicionar como um contato do chat"
-                ],
-                "Click to open this room": [
-                    null,
-                    "CLique para abrir a sala"
-                ],
-                "Show more information on this room": [
-                    null,
-                    "Mostrar mais informações nessa sala"
-                ],
-                "Description:": [
-                    null,
-                    "Descrição:"
-                ],
-                "Occupants:": [
-                    null,
-                    "Ocupantes:"
-                ],
-                "Features:": [
-                    null,
-                    "Recursos:"
-                ],
-                "Requires authentication": [
-                    null,
-                    "Requer autenticação"
-                ],
-                "Hidden": [
-                    null,
-                    "Escondido"
-                ],
-                "Requires an invitation": [
-                    null,
-                    "Requer um convite"
-                ],
-                "Moderated": [
-                    null,
-                    "Moderado"
-                ],
-                "Non-anonymous": [
-                    null,
-                    "Não anônimo"
-                ],
-                "Open room": [
-                    null,
-                    "Sala aberta"
-                ],
-                "Permanent room": [
-                    null,
-                    "Sala permanente"
-                ],
-                "Public": [
-                    null,
-                    "Público"
-                ],
-                "Semi-anonymous": [
-                    null,
-                    "Semi anônimo"
-                ],
-                "Temporary room": [
-                    null,
-                    "Sala temporária"
-                ],
-                "Unmoderated": [
-                    null,
-                    "Sem moderação"
-                ],
-                "Rooms": [
-                    null,
-                    "Salas"
-                ],
-                "Room name": [
-                    null,
-                    "Nome da sala"
-                ],
-                "Nickname": [
-                    null,
-                    "Apelido"
-                ],
-                "Server": [
-                    null,
-                    "Server"
-                ],
-                "Join": [
-                    null,
-                    "Entrar"
-                ],
-                "Show rooms": [
-                    null,
-                    "Mostrar salas"
-                ],
-                "No rooms on %1$s": [
-                    null,
-                    "Sem salas em %1$s"
-                ],
-                "Rooms on %1$s": [
-                    null,
-                    "Salas em %1$s"
-                ],
-                "Set chatroom topic": [
-                    null,
-                    "Definir tópico do chat"
-                ],
-                "Kick user from chatroom": [
-                    null,
-                    "Expulsar usuário do chat"
-                ],
-                "Ban user from chatroom": [
-                    null,
-                    "Banir usuário do chat"
-                ],
-                "Message": [
-                    null,
-                    "Mensagem"
-                ],
-                "Save": [
-                    null,
-                    "Salvar"
-                ],
-                "Cancel": [
-                    null,
-                    "Cancelar"
-                ],
-                "An error occurred while trying to save the form.": [
-                    null,
-                    "Ocorreu um erro enquanto tentava salvar o formulário"
-                ],
-                "This chatroom requires a password": [
-                    null,
-                    "Esse chat precisa de senha"
-                ],
-                "Password: ": [
-                    null,
-                    "Senha: "
-                ],
-                "Submit": [
-                    null,
-                    "Enviar"
-                ],
-                "This room is not anonymous": [
-                    null,
-                    "Essa sala não é anônima"
-                ],
-                "This room now shows unavailable members": [
-                    null,
-                    "Agora esta sala mostra membros indisponíveis"
-                ],
-                "This room does not show unavailable members": [
-                    null,
-                    "Essa sala não mostra membros indisponíveis"
-                ],
-                "Non-privacy-related room configuration has changed": [
-                    null,
-                    "Configuraçõs não relacionadas à privacidade mudaram"
-                ],
-                "Room logging is now enabled": [
-                    null,
-                    "O log da sala está ativado"
-                ],
-                "Room logging is now disabled": [
-                    null,
-                    "O log da sala está desativado"
-                ],
-                "This room is now non-anonymous": [
-                    null,
-                    "Esse sala é não anônima"
-                ],
-                "This room is now semi-anonymous": [
-                    null,
-                    "Essa sala agora é semi anônima"
-                ],
-                "This room is now fully-anonymous": [
-                    null,
-                    "Essa sala agora é totalmente anônima"
-                ],
-                "A new room has been created": [
-                    null,
-                    "Uma nova sala foi criada"
-                ],
-                "Your nickname has been changed": [
-                    null,
-                    "Seu apelido foi mudado"
-                ],
-                "<strong>%1$s</strong> has been banned": [
-                    null,
-                    "<strong>%1$s</strong> foi banido"
-                ],
-                "<strong>%1$s</strong> has been kicked out": [
-                    null,
-                    "<strong>%1$s</strong> foi expulso"
-                ],
-                "<strong>%1$s</strong> has been removed because of an affiliation change": [
-                    null,
-                    "<srtong>%1$s</strong> foi removido por causa de troca de associação"
-                ],
-                "<strong>%1$s</strong> has been removed for not being a member": [
-                    null,
-                    "<strong>%1$s</strong> foi removido por não ser um membro"
-                ],
-                "You have been banned from this room": [
-                    null,
-                    "Você foi banido dessa sala"
-                ],
-                "You have been kicked from this room": [
-                    null,
-                    "Você foi expulso dessa sala"
-                ],
-                "You have been removed from this room because of an affiliation change": [
-                    null,
-                    "Você foi removido da sala devido a uma mudança de associação"
-                ],
-                "You have been removed from this room because the room has changed to members-only and you're not a member": [
-                    null,
-                    "Você foi removido da sala porque ela foi mudada para somente membrose você não é um membro"
-                ],
-                "You have been removed from this room because the MUC (Multi-user chat) service is being shut down.": [
-                    null,
-                    "Você foi removido da sala devido a MUC (Multi-user chat)o serviço está sendo desligado"
-                ],
-                "You are not on the member list of this room": [
-                    null,
-                    "Você não é membro dessa sala"
-                ],
-                "No nickname was specified": [
-                    null,
-                    "Você não escolheu um apelido "
-                ],
-                "You are not allowed to create new rooms": [
-                    null,
-                    "Você não tem permitição de criar novas salas"
-                ],
-                "Your nickname doesn't conform to this room's policies": [
-                    null,
-                    "Seu apelido não está de acordo com as regras da sala"
-                ],
-                "Your nickname is already taken": [
-                    null,
-                    "Seu apelido já foi escolhido"
-                ],
-                "This room does not (yet) exist": [
-                    null,
-                    "A sala não existe (ainda)"
-                ],
-                "This room has reached it's maximum number of occupants": [
-                    null,
-                    "A sala atingiu o número máximo de ocupantes"
-                ],
-                "Topic set by %1$s to: %2$s": [
-                    null,
-                    "Topico definido por %1$s para: %2$s"
-                ],
-                "This user is a moderator": [
-                    null,
-                    "Esse usuário é o moderador"
-                ],
-                "This user can send messages in this room": [
-                    null,
-                    "Esse usuário pode enviar mensagens nessa sala"
-                ],
-                "This user can NOT send messages in this room": [
-                    null,
-                    "Esse usuário NÃO pode enviar mensagens nessa sala"
-                ],
-                "Click to chat with this contact": [
-                    null,
-                    "Clique para conversar com o contato"
-                ],
-                "Click to remove this contact": [
-                    null,
-                    "Clique para remover o contato"
-                ],
-                "This contact is busy": [
-                    null,
-                    "Este contato está ocupado"
-                ],
-                "This contact is online": [
-                    null,
-                    "Este contato está online"
-                ],
-                "This contact is offline": [
-                    null,
-                    "Este contato está offline"
-                ],
-                "This contact is unavailable": [
-                    null,
-                    "Este contato está indisponível"
-                ],
-                "This contact is away for an extended period": [
-                    null,
-                    "Este contato está ausente por um longo período"
-                ],
-                "This contact is away": [
-                    null,
-                    "Este contato está ausente"
-                ],
-                "Contact requests": [
-                    null,
-                    "Solicitação de contatos"
-                ],
-                "My contacts": [
-                    null,
-                    "Meus contatos"
-                ],
-                "Pending contacts": [
-                    null,
-                    "Contados pendentes"
-                ],
-                "Custom status": [
-                    null,
-                    "Status customizado"
-                ],
-                "Click to change your chat status": [
-                    null,
-                    "Clique para mudar seu status no chat"
-                ],
-                "Click here to write a custom status message": [
-                    null,
-                    "Clique aqui para customizar a mensagem de status"
-                ],
-                "online": [
-                    null,
-                    "online"
-                ],
-                "busy": [
-                    null,
-                    "ocupado"
-                ],
-                "away for long": [
-                    null,
-                    "ausente a bastante tempo"
-                ],
-                "away": [
-                    null,
-                    "ausente"
-                ],
-                "I am %1$s": [
-                    null,
-                    "Estou %1$s"
-                ],
-                "Sign in": [
-                    null,
-                    "Conectar-se"
-                ],
-                "XMPP/Jabber Username:": [
-                    null,
-                    "Usuário XMPP/Jabber:"
-                ],
-                "Password:": [
-                    null,
-                    "Senha:"
-                ],
-                "Log In": [
-                    null,
-                    "Entrar"
-                ],
-                "BOSH Service URL:": [
-                    null,
-                    "URL de serviço BOSH:"
-                ],
-                "Online Contacts": [
-                    null,
-                    "Contatos online"
-                ],
-                "%1$s is typing": [
-                    null,
-                    "%1$s está digitando"
-                ],
-                "Connected": [
-                    null,
-                    "Conectado"
-                ],
-                "Attached": [
-                    null,
-                    "Anexado"
-                ]
-                ,
-                "Type to filter": [
-                    null,
-                    "Escreva para filtrar"
-                ]
-            }
-        }
-    };
-    if (typeof define === 'function' && define.amd) {
-        define("pt_BR", ['jed'], function () {
-            return factory(new Jed(translations));
-        });
-    } else {
-        if (!window.locales) {
-            window.locales = {};
-        }
-        window.locales.pt_BR = factory(new Jed(translations));
-    }
-  }(this, function (i18n) {
-      return i18n;
-  })
-);

File diff suppressed because it is too large
+ 0 - 0
locale/ru/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 358 - 592
locale/ru/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/tr/LC_MESSAGES/converse.json


+ 776 - 804
locale/tr/LC_MESSAGES/converse.po

@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Converse.js 3.3.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-05-17 11:19+0200\n"
+"POT-Creation-Date: 2018-07-02 16:28+0200\n"
 "PO-Revision-Date: 2018-03-30 08:45+0000\n"
 "Last-Translator: Sarp Doruk ASLAN <sarpdorukaslan@gmail.com>\n"
 "Language-Team: Turkish <https://hosted.weblate.org/projects/conversejs/"
@@ -19,1495 +19,1467 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 "X-Generator: Weblate 2.20-dev\n"
 
-#: dist/converse-no-dependencies.js:9853 dist/converse-no-dependencies.js:9882
-msgid "Download"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9872
-#, javascript-format
-msgid "Download: \"%1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9895
-msgid "Download video file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9908
-msgid "Download audio file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11229
-msgid "The connection has dropped, attempting to reconnect."
-msgstr "Bağlantı koptu, yeniden bağlanılmaya çalışılıyor."
-
-#: dist/converse-no-dependencies.js:11327
-msgid "An error occurred while connecting to the chat server."
-msgstr "Sohbet sunucusuna bağlanılırken bir hata oluştu."
-
-#: dist/converse-no-dependencies.js:11334
-msgid "Your Jabber ID and/or password is incorrect. Please try again."
-msgstr "Jabber Kimlik ve/veya parola geçersiz. Lütfen tekrar deneyin."
-
-#: dist/converse-no-dependencies.js:11346
-#, javascript-format
-msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
-msgstr "ÜZgünüz, bu XMPP hostuna bu domainle bağlanamadık :%1$s"
-
-#: dist/converse-no-dependencies.js:11348
-msgid "The XMPP server did not offer a supported authentication mechanism"
-msgstr "XMPP sunucusu desteklenen bir kimlik doğrulama mekanizması sunmadı"
-
-#: dist/converse-no-dependencies.js:16016
-#, javascript-format
-msgid "%1$s has invited you to join a chat room: %2$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16018
-#, javascript-format
-msgid ""
-"%1$s has invited you to join a chat room: %2$s, and left the following "
-"reason: \"%3$s\""
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16379
-#: dist/converse-no-dependencies.js:16464
-#: dist/converse-no-dependencies.js:33114
-msgid "Bookmark this room"
+#: dist/converse-no-dependencies.js:40690
+#: dist/converse-no-dependencies.js:40775
+#: dist/converse-no-dependencies.js:53478
+msgid "Bookmark this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16465
+#: dist/converse-no-dependencies.js:40776
 msgid "The name for this bookmark:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16466
-msgid "Would you like this room to be automatically joined upon startup?"
+#: dist/converse-no-dependencies.js:40777
+msgid "Would you like this groupchat to be automatically joined upon startup?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16467
-msgid "What should your nickname for this room be?"
+#: dist/converse-no-dependencies.js:40778
+msgid "What should your nickname for this groupchat be?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16469
-#: dist/converse-no-dependencies.js:25296
-#: dist/converse-no-dependencies.js:25380
+#: dist/converse-no-dependencies.js:40780
+#: dist/converse-no-dependencies.js:49283
+#: dist/converse-no-dependencies.js:52277
+#: dist/converse-no-dependencies.js:52361
 msgid "Save"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16470
-#: dist/converse-no-dependencies.js:25376
-#: dist/converse-no-dependencies.js:32190
+#: dist/converse-no-dependencies.js:40781
+#: dist/converse-no-dependencies.js:49284
+#: dist/converse-no-dependencies.js:52357
+#: dist/converse-no-dependencies.js:58508
 msgid "Cancel"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16543
+#: dist/converse-no-dependencies.js:40854
 #, javascript-format
 msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16659
+#: dist/converse-no-dependencies.js:40970
 msgid "Sorry, something went wrong while trying to save your bookmark."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16738
-#: dist/converse-no-dependencies.js:33112
-msgid "Leave this room"
+#: dist/converse-no-dependencies.js:41055
+#: dist/converse-no-dependencies.js:53476
+msgid "Leave this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16739
+#: dist/converse-no-dependencies.js:41056
 msgid "Remove this bookmark"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16740
-#: dist/converse-no-dependencies.js:33113
-msgid "Unbookmark this room"
+#: dist/converse-no-dependencies.js:41057
+#: dist/converse-no-dependencies.js:53477
+msgid "Unbookmark this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16741
-#: dist/converse-no-dependencies.js:28819
-#: dist/converse-no-dependencies.js:33115
-msgid "Show more information on this room"
+#: dist/converse-no-dependencies.js:41058
+#: dist/converse-no-dependencies.js:48558
+#: dist/converse-no-dependencies.js:53479
+msgid "Show more information on this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16744
-#: dist/converse-no-dependencies.js:28818
-#: dist/converse-no-dependencies.js:33117
-msgid "Click to open this room"
+#: dist/converse-no-dependencies.js:41061
+#: dist/converse-no-dependencies.js:48557
+#: dist/converse-no-dependencies.js:53481
+msgid "Click to open this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16780
+#: dist/converse-no-dependencies.js:41097
 msgid "Click to toggle the bookmarks list"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16781
+#: dist/converse-no-dependencies.js:41098
 msgid "Bookmarks"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21217
+#: dist/converse-no-dependencies.js:41529
 msgid "Sorry, could not determine file upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21225
+#: dist/converse-no-dependencies.js:41537
 msgid "Sorry, could not determine upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21257
+#: dist/converse-no-dependencies.js:41569
 msgid "Sorry, could not succesfully upload your file."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21260
+#: dist/converse-no-dependencies.js:41572
 #, javascript-format
 msgid "Your server's response: \"%1$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21442
+#: dist/converse-no-dependencies.js:41749
 msgid "Sorry, looks like file upload is not supported by your server."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21452
+#: dist/converse-no-dependencies.js:41759
 #, javascript-format
 msgid ""
 "The size of your file, %1$s, exceeds the maximum allowed by your server, "
 "which is %2$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22197
-msgid "Show more"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22248
-msgid "Typing from another device"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22250
-msgid "is typing"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22254
-msgid "Stopped typing on the other device"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22256
-msgid "has stopped typing"
+#: dist/converse-no-dependencies.js:41778
+msgid "Sorry, an error occured:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22259
-#: dist/converse-no-dependencies.js:23256
-#: dist/converse-no-dependencies.js:30521
-msgid "has gone away"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22488
+#: dist/converse-no-dependencies.js:42489
 msgid "Close this chat box"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22516
+#: dist/converse-no-dependencies.js:42517
 msgid "The User's Profile Image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22519
-#: dist/converse-no-dependencies.js:25289
-#: dist/converse-no-dependencies.js:25374
+#: dist/converse-no-dependencies.js:42520
+#: dist/converse-no-dependencies.js:52270
+#: dist/converse-no-dependencies.js:52355
 msgid "Close"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22520
-#: dist/converse-no-dependencies.js:25290
+#: dist/converse-no-dependencies.js:42521
+#: dist/converse-no-dependencies.js:52271
 msgid "Email"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22521
-#: dist/converse-no-dependencies.js:25291
+#: dist/converse-no-dependencies.js:42522
+#: dist/converse-no-dependencies.js:52272
 msgid "Full Name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22522
+#: dist/converse-no-dependencies.js:42523
 msgid "Jabber ID"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22523
-#: dist/converse-no-dependencies.js:25292
-#: dist/converse-no-dependencies.js:29617
+#: dist/converse-no-dependencies.js:42524
+#: dist/converse-no-dependencies.js:49439
+#: dist/converse-no-dependencies.js:52273
 msgid "Nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22524
+#: dist/converse-no-dependencies.js:42525
 msgid "Remove as contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22525
+#: dist/converse-no-dependencies.js:42526
 msgid "Refresh"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22526
-#: dist/converse-no-dependencies.js:25294
+#: dist/converse-no-dependencies.js:42527
+#: dist/converse-no-dependencies.js:52275
 msgid "Role"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22527
-#: dist/converse-no-dependencies.js:25297
+#: dist/converse-no-dependencies.js:42528
+#: dist/converse-no-dependencies.js:52278
 msgid "URL"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22566
-#: dist/converse-no-dependencies.js:24293
+#: dist/converse-no-dependencies.js:42567
+#: dist/converse-no-dependencies.js:55141
 msgid "Are you sure you want to remove this contact?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:25325
+#: dist/converse-no-dependencies.js:42576
+#: dist/converse-no-dependencies.js:52306
 msgid "Error"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:24301
+#: dist/converse-no-dependencies.js:42576
+#: dist/converse-no-dependencies.js:55149
 #, javascript-format
 msgid "Sorry, there was an error while trying to remove %1$s as a contact."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22629
-#: dist/converse-no-dependencies.js:22667
-#: dist/converse-no-dependencies.js:29029
+#: dist/converse-no-dependencies.js:42630
+#: dist/converse-no-dependencies.js:42668
+#: dist/converse-no-dependencies.js:48794
 msgid "You have unread messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22653
+#: dist/converse-no-dependencies.js:42654
 msgid "Hidden message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22655
+#: dist/converse-no-dependencies.js:42656
 msgid "Personal message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22662
-#: dist/converse-no-dependencies.js:29026
+#: dist/converse-no-dependencies.js:42663
+#: dist/converse-no-dependencies.js:48791
 msgid "Send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22663
+#: dist/converse-no-dependencies.js:42664
 msgid "Optional hint"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22692
+#: dist/converse-no-dependencies.js:42702
 msgid "Choose a file to send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22748
+#: dist/converse-no-dependencies.js:42758
 msgid "Click to write as a normal (non-spoiler) message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22750
+#: dist/converse-no-dependencies.js:42760
 msgid "Click to write your message as a spoiler"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22754
+#: dist/converse-no-dependencies.js:42764
 msgid "Clear all messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:42765
 msgid "Insert emojis"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22756
+#: dist/converse-no-dependencies.js:42766
 msgid "Start a call"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29265
+#: dist/converse-no-dependencies.js:43079
+#: dist/converse-no-dependencies.js:49082
 msgid "Remove messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
+#: dist/converse-no-dependencies.js:43079
 msgid "Write in the third person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29267
+#: dist/converse-no-dependencies.js:43079
+#: dist/converse-no-dependencies.js:49082
 msgid "Show this menu"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:43178
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23254
-#: dist/converse-no-dependencies.js:30519
+#: dist/converse-no-dependencies.js:43267
+#: dist/converse-no-dependencies.js:51817
 msgid "has gone offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23258
-#: dist/converse-no-dependencies.js:30523
+#: dist/converse-no-dependencies.js:43269
+#: dist/converse-no-dependencies.js:47480
+#: dist/converse-no-dependencies.js:51819
+msgid "has gone away"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:43271
+#: dist/converse-no-dependencies.js:51821
 msgid "is busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23260
+#: dist/converse-no-dependencies.js:43273
 msgid "is online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23501
-msgid "XMPP Username:"
+#: dist/converse-no-dependencies.js:43655
+#: dist/converse-no-dependencies.js:54717
+#: dist/converse-no-dependencies.js:55440
+msgid "Contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23507
-msgid "Password:"
+#: dist/converse-no-dependencies.js:43893
+msgid "Username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23509
-msgid "password"
+#: dist/converse-no-dependencies.js:43893
+msgid "user@domain"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23513
-#: dist/converse-no-dependencies.js:29643
-msgid "Submit"
+#: dist/converse-no-dependencies.js:43901
+#: dist/converse-no-dependencies.js:54778
+msgid "Please enter a valid XMPP address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23519
-msgid "Click here to log in anonymously"
+#: dist/converse-no-dependencies.js:43990
+msgid "Chat Contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23864
-msgid "This contact is busy"
+#: dist/converse-no-dependencies.js:43990
+msgid "Toggle chat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23865
-msgid "This contact is online"
-msgstr ""
+#: dist/converse-no-dependencies.js:44568
+msgid "The connection has dropped, attempting to reconnect."
+msgstr "Bağlantı koptu, yeniden bağlanılmaya çalışılıyor."
 
-#: dist/converse-no-dependencies.js:23866
-msgid "This contact is offline"
-msgstr ""
+#: dist/converse-no-dependencies.js:44666
+msgid "An error occurred while connecting to the chat server."
+msgstr "Sohbet sunucusuna bağlanılırken bir hata oluştu."
 
-#: dist/converse-no-dependencies.js:23867
-msgid "This contact is unavailable"
-msgstr ""
+#: dist/converse-no-dependencies.js:44673
+msgid "Your Jabber ID and/or password is incorrect. Please try again."
+msgstr "Jabber Kimlik ve/veya parola geçersiz. Lütfen tekrar deneyin."
 
-#: dist/converse-no-dependencies.js:23868
-msgid "This contact is away for an extended period"
-msgstr ""
+#: dist/converse-no-dependencies.js:44685
+#, javascript-format
+msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
+msgstr "ÜZgünüz, bu XMPP hostuna bu domainle bağlanamadık :%1$s"
 
-#: dist/converse-no-dependencies.js:23869
-msgid "This contact is away"
+#: dist/converse-no-dependencies.js:44687
+msgid "The XMPP server did not offer a supported authentication mechanism"
+msgstr "XMPP sunucusu desteklenen bir kimlik doğrulama mekanizması sunmadı"
+
+#: dist/converse-no-dependencies.js:47426
+msgid "Show more"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23872
-#: dist/converse-no-dependencies.js:24584
-#: dist/converse-no-dependencies.js:25680
-msgid "Contacts"
+#: dist/converse-no-dependencies.js:47469
+msgid "Typing from another device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23874
-msgid "Groups"
+#: dist/converse-no-dependencies.js:47471
+msgid "is typing"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23876
-msgid "My contacts"
+#: dist/converse-no-dependencies.js:47475
+msgid "Stopped typing on the other device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23878
-msgid "Pending contacts"
+#: dist/converse-no-dependencies.js:47477
+msgid "has stopped typing"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23880
-msgid "Contact requests"
+#: dist/converse-no-dependencies.js:47708
+#: dist/converse-no-dependencies.js:47751
+msgid "Minimize this chat box"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23882
-msgid "Ungrouped"
+#: dist/converse-no-dependencies.js:47884
+msgid "Click to restore this chat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23925
-msgid "Contact name"
+#: dist/converse-no-dependencies.js:48071
+msgid "Minimized"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23925
-#: dist/converse-no-dependencies.js:28905
-msgid "Optional nickname"
+#: dist/converse-no-dependencies.js:48400
+msgid "This groupchat is not anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23928
-msgid "Add a Contact"
+#: dist/converse-no-dependencies.js:48401
+msgid "This groupchat now shows unavailable members"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23929
-msgid "XMPP Address"
+#: dist/converse-no-dependencies.js:48402
+msgid "This groupchat does not show unavailable members"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23931
-msgid "name@example.org"
+#: dist/converse-no-dependencies.js:48403
+msgid "The groupchat configuration has changed"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23932
-msgid "Add"
+#: dist/converse-no-dependencies.js:48404
+msgid "groupchat logging is now enabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24003
-#: dist/converse-no-dependencies.js:25917
-msgid "Please enter a valid XMPP address"
+#: dist/converse-no-dependencies.js:48405
+msgid "groupchat logging is now disabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24040
-msgid "Filter"
+#: dist/converse-no-dependencies.js:48406
+msgid "This groupchat is now no longer anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24041
-msgid "Filter by contact name"
+#: dist/converse-no-dependencies.js:48407
+msgid "This groupchat is now semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24042
-msgid "Filter by group name"
+#: dist/converse-no-dependencies.js:48408
+msgid "This groupchat is now fully-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24043
-msgid "Filter by status"
+#: dist/converse-no-dependencies.js:48409
+msgid "A new groupchat has been created"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24044
-msgid "Any"
+#: dist/converse-no-dependencies.js:48412
+msgid "You have been banned from this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24045
-msgid "Unread"
+#: dist/converse-no-dependencies.js:48413
+msgid "You have been kicked from this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24046
-#: dist/converse-no-dependencies.js:25379
-msgid "Online"
+#: dist/converse-no-dependencies.js:48414
+msgid ""
+"You have been removed from this groupchat because of an affiliation change"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24047
-msgid "Chatty"
+#: dist/converse-no-dependencies.js:48415
+msgid ""
+"You have been removed from this groupchat because the groupchat has changed "
+"to members-only and you're not a member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24048
-#: dist/converse-no-dependencies.js:25375
-msgid "Busy"
+#: dist/converse-no-dependencies.js:48416
+msgid ""
+"You have been removed from this groupchat because the MUC (Multi-user chat) "
+"service is being shut down"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24049
-#: dist/converse-no-dependencies.js:25373
-msgid "Away"
+#. XXX: Note the triple underscore function and not double
+#. * underscore.
+#. *
+#. * This is a hack. We can't pass the strings to __ because we
+#. * don't yet know what the variable to interpolate is.
+#. *
+#. * Triple underscore will just return the string again, but we
+#. * can then at least tell gettext to scan for it so that these
+#. * strings are picked up by the translation machinery.
+#.
+#: dist/converse-no-dependencies.js:48429
+#, javascript-format
+msgid "%1$s has been banned"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24050
-msgid "Extended Away"
+#: dist/converse-no-dependencies.js:48430
+#, javascript-format
+msgid "%1$s's nickname has changed"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24051
-#: dist/converse-no-dependencies.js:25378
-msgid "Offline"
+#: dist/converse-no-dependencies.js:48431
+#, javascript-format
+msgid "%1$s has been kicked out"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24205
-#: dist/converse-no-dependencies.js:24247
+#: dist/converse-no-dependencies.js:48432
 #, javascript-format
-msgid "Click to remove %1$s as a contact"
+msgid "%1$s has been removed because of an affiliation change"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24214
+#: dist/converse-no-dependencies.js:48433
 #, javascript-format
-msgid "Click to accept the contact request from %1$s"
+msgid "%1$s has been removed for not being a member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24215
+#: dist/converse-no-dependencies.js:48436
 #, javascript-format
-msgid "Click to decline the contact request from %1$s"
+msgid "Your nickname has been automatically set to %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24246
+#: dist/converse-no-dependencies.js:48437
 #, javascript-format
-msgid "Click to chat with %1$s (JID: %2$s)"
+msgid "Your nickname has been changed to %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24323
-msgid "Are you sure you want to decline this contact request?"
+#: dist/converse-no-dependencies.js:48468
+msgid "Description:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24585
-msgid "Add a contact"
+#: dist/converse-no-dependencies.js:48469
+msgid "Groupchat Address (JID):"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25288
-msgid "Your Profile"
+#: dist/converse-no-dependencies.js:48470
+msgid "Participants:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25293
-msgid "XMPP Address (JID)"
+#: dist/converse-no-dependencies.js:48471
+msgid "Features:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25295
-msgid ""
-"Use commas to separate multiple roles. Your roles are shown next to your "
-"name on your chat messages."
+#: dist/converse-no-dependencies.js:48472
+msgid "Requires authentication"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25298
-msgid "Your avatar image"
+#: dist/converse-no-dependencies.js:48473
+#: dist/converse-no-dependencies.js:56917
+#: dist/converse-no-dependencies.js:57071
+msgid "Hidden"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25325
-msgid "Sorry, an error happened while trying to save your profile data."
+#: dist/converse-no-dependencies.js:48474
+msgid "Requires an invitation"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25325
-msgid "You can check your browser's developer console for any error output."
+#: dist/converse-no-dependencies.js:48475
+#: dist/converse-no-dependencies.js:56981
+#: dist/converse-no-dependencies.js:57135
+msgid "Moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25377
-msgid "Custom status"
+#: dist/converse-no-dependencies.js:48476
+msgid "Non-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25381
-msgid "Away for long"
+#: dist/converse-no-dependencies.js:48477
+#: dist/converse-no-dependencies.js:56941
+#: dist/converse-no-dependencies.js:57095
+msgid "Open"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25382
-msgid "Change chat status"
+#: dist/converse-no-dependencies.js:48478
+msgid "Permanent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25383
-msgid "Personal status message"
+#: dist/converse-no-dependencies.js:48479
+#: dist/converse-no-dependencies.js:56925
+#: dist/converse-no-dependencies.js:57079
+msgid "Public"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25427
-#, javascript-format
-msgid "I am %1$s"
+#: dist/converse-no-dependencies.js:48480
+#: dist/converse-no-dependencies.js:56973
+#: dist/converse-no-dependencies.js:57127
+msgid "Semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25430
-msgid "Change settings"
+#: dist/converse-no-dependencies.js:48481
+#: dist/converse-no-dependencies.js:56957
+#: dist/converse-no-dependencies.js:57111
+msgid "Temporary"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25431
-msgid "Click to change your chat status"
+#: dist/converse-no-dependencies.js:48482
+msgid "Unmoderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25432
-msgid "Log out"
+#: dist/converse-no-dependencies.js:48518
+msgid "Query for Groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25433
-msgid "Your profile"
+#: dist/converse-no-dependencies.js:48519
+msgid "Server address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25456
-msgid "Are you sure you want to log out?"
+#: dist/converse-no-dependencies.js:48520
+msgid "Show rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25464
-#: dist/converse-no-dependencies.js:25474
-msgid "online"
+#: dist/converse-no-dependencies.js:48521
+msgid "conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25466
-msgid "busy"
+#: dist/converse-no-dependencies.js:48570
+msgid "No rooms found"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25468
-msgid "away for long"
+#: dist/converse-no-dependencies.js:48587
+msgid "Rooms found:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25470
-msgid "away"
+#: dist/converse-no-dependencies.js:48639
+msgid "Enter a new Groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25472
-msgid "offline"
+#: dist/converse-no-dependencies.js:48640
+msgid "Groupchat address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25909
-msgid "Username"
+#: dist/converse-no-dependencies.js:48641
+#: dist/converse-no-dependencies.js:54770
+msgid "Optional nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25909
-msgid "user@domain"
+#: dist/converse-no-dependencies.js:48642
+msgid "name@conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:26003
-msgid "Chat Contacts"
+#: dist/converse-no-dependencies.js:48643
+msgid "Join"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:26003
-msgid "Toggle chat"
+#: dist/converse-no-dependencies.js:48684
+#, javascript-format
+msgid "Groupchat info for %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27529
-#: dist/converse-no-dependencies.js:27572
-msgid "Minimize this chat box"
+#: dist/converse-no-dependencies.js:48790
+msgid "Message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27705
-msgid "Click to restore this chat"
+#: dist/converse-no-dependencies.js:48836
+#, javascript-format
+msgid "%1$s is no longer a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27892
-msgid "Minimized"
+#: dist/converse-no-dependencies.js:48840
+#, javascript-format
+msgid "%1$s has been given a voice again"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28650
-msgid "This room is not anonymous"
+#: dist/converse-no-dependencies.js:48844
+#, javascript-format
+msgid "%1$s has been muted"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28651
-msgid "This room now shows unavailable members"
+#: dist/converse-no-dependencies.js:48848
+#, javascript-format
+msgid "%1$s is now a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28652
-msgid "This room does not show unavailable members"
+#: dist/converse-no-dependencies.js:48856
+msgid "Close and leave this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28653
-msgid "The room configuration has changed"
+#: dist/converse-no-dependencies.js:48857
+msgid "Configure this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28654
-msgid "Room logging is now enabled"
+#: dist/converse-no-dependencies.js:48858
+msgid "Show more details about this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28655
-msgid "Room logging is now disabled"
+#: dist/converse-no-dependencies.js:48898
+msgid "Hide the list of participants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28656
-msgid "This room is now no longer anonymous"
+#: dist/converse-no-dependencies.js:49014
+#, javascript-format
+msgid ""
+"Error: the \"%1$s\" command takes two arguments, the user's nickname and "
+"optionally a reason."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28657
-msgid "This room is now semi-anonymous"
+#: dist/converse-no-dependencies.js:49023
+msgid ""
+"Sorry, an error happened while running the command. Check your browser's "
+"developer console for details."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28658
-msgid "This room is now fully-anonymous"
+#: dist/converse-no-dependencies.js:49082
+msgid "Change user's affiliation to admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28659
-msgid "A new room has been created"
+#: dist/converse-no-dependencies.js:49082
+msgid "Ban user from groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28663
-msgid "You have been banned from this room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Change user role to participant"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28664
-msgid "You have been kicked from this room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Kick user from groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28665
-msgid "You have been removed from this room because of an affiliation change"
+#: dist/converse-no-dependencies.js:49082
+msgid "Write in 3rd person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28666
-msgid ""
-"You have been removed from this room because the room has changed to members-"
-"only and you're not a member"
+#: dist/converse-no-dependencies.js:49082
+msgid "Grant membership to a user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28667
-msgid ""
-"You have been removed from this room because the MUC (Multi-user chat) "
-"service is being shut down"
+#: dist/converse-no-dependencies.js:49082
+msgid "Remove user's ability to post messages"
 msgstr ""
 
-#. XXX: Note the triple underscore function and not double
-#. * underscore.
-#. *
-#. * This is a hack. We can't pass the strings to __ because we
-#. * don't yet know what the variable to interpolate is.
-#. *
-#. * Triple underscore will just return the string again, but we
-#. * can then at least tell gettext to scan for it so that these
-#. * strings are picked up by the translation machinery.
-#.
-#: dist/converse-no-dependencies.js:28681
-#, javascript-format
-msgid "%1$s has been banned"
+#: dist/converse-no-dependencies.js:49082
+msgid "Change your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28682
-#, javascript-format
-msgid "%1$s's nickname has changed"
+#: dist/converse-no-dependencies.js:49082
+msgid "Grant moderator role to user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28683
-#, javascript-format
-msgid "%1$s has been kicked out"
+#: dist/converse-no-dependencies.js:49082
+msgid "Grant ownership of this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28684
-#, javascript-format
-msgid "%1$s has been removed because of an affiliation change"
+#: dist/converse-no-dependencies.js:49082
+msgid "Revoke user's membership"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28685
-#, javascript-format
-msgid "%1$s has been removed for not being a member"
+#: dist/converse-no-dependencies.js:49082
+msgid "Set groupchat subject"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28689
-#, javascript-format
-msgid "Your nickname has been automatically set to %1$s"
+#: dist/converse-no-dependencies.js:49082
+msgid "Set groupchat subject (alias for /subject)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28690
-#, javascript-format
-msgid "Your nickname has been changed to %1$s"
+#: dist/converse-no-dependencies.js:49082
+msgid "Allow muted user to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28724
-msgid "Description:"
+#: dist/converse-no-dependencies.js:49412
+msgid ""
+"The nickname you chose is reserved or currently in use, please choose a "
+"different one."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28725
-msgid "Room Address (JID):"
+#: dist/converse-no-dependencies.js:49438
+msgid "Please choose your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28726
-msgid "Occupants:"
+#: dist/converse-no-dependencies.js:49440
+msgid "Enter groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28727
-msgid "Features:"
+#: dist/converse-no-dependencies.js:49461
+msgid "This groupchat requires a password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28728
-msgid "Requires authentication"
+#: dist/converse-no-dependencies.js:49462
+msgid "Password: "
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28729
-#: dist/converse-no-dependencies.js:30122
-msgid "Hidden"
+#: dist/converse-no-dependencies.js:49463
+msgid "Submit"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28730
-msgid "Requires an invitation"
+#: dist/converse-no-dependencies.js:49585
+#, javascript-format
+msgid "This action was done by %1$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28731
-#: dist/converse-no-dependencies.js:30125
-msgid "Moderated"
+#: dist/converse-no-dependencies.js:49589
+#: dist/converse-no-dependencies.js:49607
+#, javascript-format
+msgid "The reason given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28732
-#: dist/converse-no-dependencies.js:30126
-msgid "Non-anonymous"
+#: dist/converse-no-dependencies.js:49628
+#, javascript-format
+msgid "%1$s has left and re-entered the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28733
-msgid "Open room"
+#: dist/converse-no-dependencies.js:49634
+#, javascript-format
+msgid "%1$s has entered the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28734
-msgid "Permanent room"
+#: dist/converse-no-dependencies.js:49636
+#, javascript-format
+msgid "%1$s has entered the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28735
-#: dist/converse-no-dependencies.js:30130
-msgid "Public"
+#: dist/converse-no-dependencies.js:49667
+#, javascript-format
+msgid "%1$s has entered and left the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28736
-#: dist/converse-no-dependencies.js:30131
-msgid "Semi-anonymous"
+#: dist/converse-no-dependencies.js:49669
+#, javascript-format
+msgid "%1$s has entered and left the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28737
-msgid "Temporary room"
+#: dist/converse-no-dependencies.js:49682
+#, javascript-format
+msgid "%1$s has left the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28738
-#: dist/converse-no-dependencies.js:30133
-msgid "Unmoderated"
+#: dist/converse-no-dependencies.js:49684
+#, javascript-format
+msgid "%1$s has left the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28777
-msgid "Query for Chatrooms"
+#: dist/converse-no-dependencies.js:49730
+msgid "You are not on the member list of this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28778
-msgid "Server address"
+#: dist/converse-no-dependencies.js:49732
+msgid "You have been banned from this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28779
-msgid "Show rooms"
+#: dist/converse-no-dependencies.js:49736
+msgid "No nickname was specified."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28780
-msgid "conference.example.org"
+#: dist/converse-no-dependencies.js:49740
+msgid "You are not allowed to create new rooms."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28833
-msgid "No rooms found"
+#: dist/converse-no-dependencies.js:49742
+msgid "Your nickname doesn't conform to this groupchat's policies."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28850
-msgid "Rooms found:"
+#: dist/converse-no-dependencies.js:49746
+msgid "This groupchat does not (yet) exist."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28903
-msgid "Enter a new Chatroom"
+#: dist/converse-no-dependencies.js:49748
+msgid "This groupchat has reached its maximum number of participants."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28904
-msgid "Room address"
+#: dist/converse-no-dependencies.js:49750
+msgid "Remote server not found"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28906
-msgid "name@conference.example.org"
+#: dist/converse-no-dependencies.js:49755
+#, javascript-format
+msgid "The explanation given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28907
-msgid "Join"
+#: dist/converse-no-dependencies.js:49808
+#, javascript-format
+msgid "Topic set by %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29025
-msgid "Message"
+#: dist/converse-no-dependencies.js:49831
+msgid "Groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29058
-#, javascript-format
-msgid "%1$s is no longer a moderator"
+#: dist/converse-no-dependencies.js:49832
+msgid "Add a new room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29061
-#, javascript-format
-msgid "%1$s has been given a voice again"
+#: dist/converse-no-dependencies.js:49833
+msgid "Query for rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:49871
 #, javascript-format
-msgid "%1$s has been muted"
+msgid "Click to mention %1$s in your message."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29067
-#, javascript-format
-msgid "%1$s is now a moderator"
+#: dist/converse-no-dependencies.js:49872
+msgid "This user is a moderator."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29077
-msgid "Close and leave this room"
+#: dist/converse-no-dependencies.js:49873
+msgid "This user can send messages in this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29078
-msgid "Configure this room"
+#: dist/converse-no-dependencies.js:49874
+msgid "This user can NOT send messages in this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29122
-msgid "Hide the list of occupants"
+#: dist/converse-no-dependencies.js:49875
+msgid "Moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29206
-#, javascript-format
-msgid ""
-"Error: the \"%1$s\" command takes two arguments, the user's nickname and "
-"optionally a reason."
+#: dist/converse-no-dependencies.js:49876
+msgid "Visitor"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29218
-msgid ""
-"Sorry, an error happened while running the command. Check your browser's "
-"developer console for details."
+#: dist/converse-no-dependencies.js:49877
+msgid "Owner"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29263
-msgid "Change user's affiliation to admin"
+#: dist/converse-no-dependencies.js:49878
+msgid "Member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29264
-msgid "Ban user from room"
+#: dist/converse-no-dependencies.js:49879
+msgid "Admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29266
-msgid "Change user role to participant"
+#: dist/converse-no-dependencies.js:49921
+msgid "Participants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29268
-msgid "Kick user from room"
+#: dist/converse-no-dependencies.js:49938
+#: dist/converse-no-dependencies.js:50019
+msgid "Invite"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29269
-msgid "Write in 3rd person"
+#: dist/converse-no-dependencies.js:49996
+#, javascript-format
+msgid ""
+"You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
+"include a message, explaining the reason for the invitation."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29270
-msgid "Grant membership to a user"
+#: dist/converse-no-dependencies.js:50018
+msgid "Please enter a valid XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29271
-msgid "Remove user's ability to post messages"
+#: dist/converse-no-dependencies.js:51384
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29272
-msgid "Change your nickname"
+#: dist/converse-no-dependencies.js:51386
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29273
-msgid "Grant moderator role to user"
+#. workaround for Prosody which doesn't give type "headline"
+#: dist/converse-no-dependencies.js:51767
+#: dist/converse-no-dependencies.js:51773
+#, javascript-format
+msgid "Notification from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29274
-msgid "Grant ownership of this room"
+#: dist/converse-no-dependencies.js:51775
+#: dist/converse-no-dependencies.js:51786
+#: dist/converse-no-dependencies.js:51789
+#, javascript-format
+msgid "%1$s says"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29275
-msgid "Revoke user's membership"
+#: dist/converse-no-dependencies.js:51823
+msgid "has come online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29276
-msgid "Set room subject"
+#: dist/converse-no-dependencies.js:51840
+msgid "wants to be your contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29277
-msgid "Set room subject (alias for /subject)"
+#: dist/converse-no-dependencies.js:52022
+#, javascript-format
+msgid "Log in with %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29278
-msgid "Allow muted user to post messages"
+#: dist/converse-no-dependencies.js:52269
+msgid "Your Profile"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52274
+msgid "XMPP Address (JID)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29590
+#: dist/converse-no-dependencies.js:52276
 msgid ""
-"The nickname you chose is reserved or currently in use, please choose a "
-"different one."
+"Use commas to separate multiple roles. Your roles are shown next to your "
+"name on your chat messages."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29616
-msgid "Please choose your nickname"
+#: dist/converse-no-dependencies.js:52279
+msgid "Your avatar image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29618
-msgid "Enter room"
+#: dist/converse-no-dependencies.js:52306
+msgid "Sorry, an error happened while trying to save your profile data."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29641
-msgid "This chatroom requires a password"
+#: dist/converse-no-dependencies.js:52306
+msgid "You can check your browser's developer console for any error output."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29642
-msgid "Password: "
+#: dist/converse-no-dependencies.js:52354
+#: dist/converse-no-dependencies.js:54896
+msgid "Away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29740
-#, javascript-format
-msgid "This action was done by %1$s."
+#: dist/converse-no-dependencies.js:52356
+#: dist/converse-no-dependencies.js:54895
+msgid "Busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29743
-#: dist/converse-no-dependencies.js:29759
-#, javascript-format
-msgid "The reason given is: \"%1$s\"."
+#: dist/converse-no-dependencies.js:52358
+msgid "Custom status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29781
-#, javascript-format
-msgid "%1$s has left and re-entered the room"
+#: dist/converse-no-dependencies.js:52359
+#: dist/converse-no-dependencies.js:54898
+msgid "Offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29786
-#, javascript-format
-msgid "%1$s has entered the room"
+#: dist/converse-no-dependencies.js:52360
+#: dist/converse-no-dependencies.js:54893
+msgid "Online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29788
-#, javascript-format
-msgid "%1$s has entered the room. \"%2$s\""
+#: dist/converse-no-dependencies.js:52362
+msgid "Away for long"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29818
-#, javascript-format
-msgid "%1$s has entered and left the room"
+#: dist/converse-no-dependencies.js:52363
+msgid "Change chat status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29820
-#, javascript-format
-msgid "%1$s has entered and left the room. \"%2$s\""
+#: dist/converse-no-dependencies.js:52364
+msgid "Personal status message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29832
+#: dist/converse-no-dependencies.js:52408
 #, javascript-format
-msgid "%1$s has left the room"
+msgid "I am %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29834
-#, javascript-format
-msgid "%1$s has left the room. \"%2$s\""
+#: dist/converse-no-dependencies.js:52411
+msgid "Change settings"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29877
-msgid "You are not on the member list of this room."
+#: dist/converse-no-dependencies.js:52412
+msgid "Click to change your chat status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29879
-msgid "You have been banned from this room."
+#: dist/converse-no-dependencies.js:52413
+msgid "Log out"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29883
-msgid "No nickname was specified."
+#: dist/converse-no-dependencies.js:52414
+msgid "Your profile"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29887
-msgid "You are not allowed to create new rooms."
+#: dist/converse-no-dependencies.js:52437
+msgid "Are you sure you want to log out?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29889
-msgid "Your nickname doesn't conform to this room's policies."
+#: dist/converse-no-dependencies.js:52445
+#: dist/converse-no-dependencies.js:52455
+msgid "online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29893
-msgid "This room does not (yet) exist."
+#: dist/converse-no-dependencies.js:52447
+msgid "busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29895
-msgid "This room has reached its maximum number of occupants."
+#: dist/converse-no-dependencies.js:52449
+msgid "away for long"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29950
-#, javascript-format
-msgid "Topic set by %1$s"
+#: dist/converse-no-dependencies.js:52451
+msgid "away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29981
-msgid "Chatrooms"
+#: dist/converse-no-dependencies.js:52453
+msgid "offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29982
-msgid "Add a new room"
+#: dist/converse-no-dependencies.js:52755
+msgid " e.g. conversejs.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29983
-msgid "Query for rooms"
+#: dist/converse-no-dependencies.js:52802
+msgid "Fetch registration form"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52803
+msgid "Tip: A list of public XMPP providers is available"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52804
+msgid "here"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52852
+msgid "Sorry, we're unable to connect to your chosen provider."
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52868
+msgid ""
+"Sorry, the given provider does not support in band account registration. "
+"Please try with a different provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30022
+#: dist/converse-no-dependencies.js:52892
 #, javascript-format
-msgid "Click to mention %1$s in your message."
+msgid ""
+"Something went wrong while establishing a connection with \"%1$s\". Are you "
+"sure it exists?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30023
-msgid "This user is a moderator."
+#: dist/converse-no-dependencies.js:53055
+msgid "Now logging you in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30024
-msgid "This user can send messages in this room."
+#: dist/converse-no-dependencies.js:53059
+msgid "Registered successfully"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30025
-msgid "This user can NOT send messages in this room."
+#: dist/converse-no-dependencies.js:53168
+msgid ""
+"The provider rejected your registration attempt. Please check the values you "
+"entered for correctness."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30026
-msgid "Moderator"
+#: dist/converse-no-dependencies.js:53537
+msgid "Click to toggle the list of open groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30027
-msgid "Visitor"
+#: dist/converse-no-dependencies.js:53538
+msgid "Open Groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30028
-msgid "Owner"
+#: dist/converse-no-dependencies.js:53582
+#, javascript-format
+msgid "Are you sure you want to leave the groupchat %1$s?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30029
-msgid "Member"
+#: dist/converse-no-dependencies.js:54191
+#, javascript-format
+msgid "Sorry, there was an error while trying to add %1$s as a contact."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30030
-msgid "Admin"
+#: dist/converse-no-dependencies.js:54402
+msgid "This client does not allow presence subscriptions"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30082
-msgid "Occupants"
+#: dist/converse-no-dependencies.js:54510
+msgid "Click to hide these contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30102
-#: dist/converse-no-dependencies.js:30209
-msgid "Invite"
+#: dist/converse-no-dependencies.js:54709
+msgid "This contact is busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30121
-msgid "Features"
+#: dist/converse-no-dependencies.js:54710
+msgid "This contact is online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30123
-msgid "Message archiving"
+#: dist/converse-no-dependencies.js:54711
+msgid "This contact is offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30124
-msgid "Members only"
+#: dist/converse-no-dependencies.js:54712
+msgid "This contact is unavailable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30127
-msgid "Open"
+#: dist/converse-no-dependencies.js:54713
+msgid "This contact is away for an extended period"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30128
-msgid "Password protected"
+#: dist/converse-no-dependencies.js:54714
+msgid "This contact is away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30129
-msgid "Persistent"
+#: dist/converse-no-dependencies.js:54719
+msgid "Groups"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30132
-msgid "Temporary"
+#: dist/converse-no-dependencies.js:54721
+msgid "My contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30134
-msgid "No password"
+#: dist/converse-no-dependencies.js:54723
+msgid "Pending contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30135
-msgid "This room is not publicly searchable"
+#: dist/converse-no-dependencies.js:54725
+msgid "Contact requests"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30136
-msgid "Messages are archived on the server"
+#: dist/converse-no-dependencies.js:54727
+msgid "Ungrouped"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30137
-msgid "This room is restricted to members only"
+#: dist/converse-no-dependencies.js:54770
+msgid "Contact name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30138
-msgid "This room is being moderated"
+#: dist/converse-no-dependencies.js:54773
+msgid "Add a Contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30139
-msgid "All other room occupants can see your XMPP username"
+#: dist/converse-no-dependencies.js:54774
+msgid "XMPP Address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30140
-msgid "Anyone can join this room"
+#: dist/converse-no-dependencies.js:54776
+msgid "name@example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30141
-msgid "This room requires a password before entry"
+#: dist/converse-no-dependencies.js:54777
+msgid "Add"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30142
-msgid "This room persists even if it's unoccupied"
+#: dist/converse-no-dependencies.js:54887
+msgid "Filter"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30143
-msgid "This room is publicly searchable"
+#: dist/converse-no-dependencies.js:54888
+msgid "Filter by contact name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30144
-msgid "Only moderators can see your XMPP username"
+#: dist/converse-no-dependencies.js:54889
+msgid "Filter by group name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30145
-msgid "This room will disappear once the last person leaves"
+#: dist/converse-no-dependencies.js:54890
+msgid "Filter by status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30146
-msgid "This room is not being moderated"
+#: dist/converse-no-dependencies.js:54891
+msgid "Any"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30147
-msgid "This room does not require a password upon entry"
+#: dist/converse-no-dependencies.js:54892
+msgid "Unread"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:54894
+msgid "Chatty"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30187
+#: dist/converse-no-dependencies.js:54897
+msgid "Extended Away"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:55053
+#: dist/converse-no-dependencies.js:55095
 #, javascript-format
-msgid ""
-"You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
-"include a message, explaining the reason for the invitation."
+msgid "Click to remove %1$s as a contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30208
-msgid "Please enter a valid XMPP username"
+#: dist/converse-no-dependencies.js:55062
+#, javascript-format
+msgid "Click to accept the contact request from %1$s"
 msgstr ""
 
-#. workaround for Prosody which doesn't give type "headline"
-#: dist/converse-no-dependencies.js:30469
-#: dist/converse-no-dependencies.js:30475
+#: dist/converse-no-dependencies.js:55063
 #, javascript-format
-msgid "Notification from %1$s"
+msgid "Click to decline the contact request from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30477
-#: dist/converse-no-dependencies.js:30488
-#: dist/converse-no-dependencies.js:30491
+#: dist/converse-no-dependencies.js:55094
 #, javascript-format
-msgid "%1$s says"
+msgid "Click to chat with %1$s (JID: %2$s)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30525
-msgid "has come online"
+#: dist/converse-no-dependencies.js:55171
+msgid "Are you sure you want to decline this contact request?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30542
-msgid "wants to be your contact"
+#: dist/converse-no-dependencies.js:55441
+msgid "Add a contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30824
-msgid "Re-establishing encrypted session"
+#: dist/converse-no-dependencies.js:56869
+msgid "Name"
 msgstr ""
 
-#. We need to generate a new key and instance tag
-#: dist/converse-no-dependencies.js:30835
-msgid "Generating private key."
+#: dist/converse-no-dependencies.js:56873
+msgid "Room address (JID)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30835
-msgid "Your browser might become unresponsive."
+#: dist/converse-no-dependencies.js:56877
+msgid "Description"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30878
-#, javascript-format
-msgid ""
-"Authentication request from %1$s\n"
-"\n"
-"Your chat contact is attempting to verify your identity, by asking you the "
-"question below.\n"
-"\n"
-"%2$s"
+#: dist/converse-no-dependencies.js:56883
+msgid "Topic"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30887
-msgid "Could not verify this user's identify."
+#: dist/converse-no-dependencies.js:56887
+msgid "Topic author"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30941
-msgid "Exchanging private key with contact."
+#: dist/converse-no-dependencies.js:56893
+msgid "Online users"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31038
-msgid "Your messages are not encrypted anymore"
+#: dist/converse-no-dependencies.js:56897
+#: dist/converse-no-dependencies.js:57047
+msgid "Features"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31040
-msgid ""
-"Your messages are now encrypted but your contact's identity has not been "
-"verified."
+#: dist/converse-no-dependencies.js:56901
+#: dist/converse-no-dependencies.js:57055
+msgid "Password protected"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31042
-msgid "Your contact's identify has been verified."
+#: dist/converse-no-dependencies.js:56903
+msgid "This room requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31044
-msgid "Your contact has ended encryption on their end, you should do the same."
+#: dist/converse-no-dependencies.js:56909
+msgid "No password required"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31054
-msgid "Your message could not be sent"
+#: dist/converse-no-dependencies.js:56911
+msgid "This room does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31056
-msgid "We received an unencrypted message"
+#: dist/converse-no-dependencies.js:56919
+msgid "This room is not publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31058
-msgid "We received an unreadable encrypted message"
+#: dist/converse-no-dependencies.js:56927
+msgid "This room is publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31084
-#, javascript-format
-msgid ""
-"Here are the fingerprints, please confirm them with %1$s, outside of this "
-"chat.\n"
-"\n"
-"Fingerprint for you, %2$s: %3$s\n"
-"\n"
-"Fingerprint for %1$s: %4$s\n"
-"\n"
-"If you have confirmed that the fingerprints match, click OK, otherwise click "
-"Cancel."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:31096
-msgid ""
-"You will be prompted to provide a security question and then an answer to "
-"that question.\n"
-"\n"
-"Your contact will then be prompted the same question and if they type the "
-"exact same answer (case sensitive), their identity will be verified."
+#: dist/converse-no-dependencies.js:56933
+#: dist/converse-no-dependencies.js:57087
+msgid "Members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31097
-msgid "What is your security question?"
+#: dist/converse-no-dependencies.js:56935
+msgid "this room is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31100
-msgid "What is the answer to the security question?"
+#: dist/converse-no-dependencies.js:56943
+msgid "Anyone can join this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31104
-msgid "Invalid authentication scheme provided"
+#: dist/converse-no-dependencies.js:56949
+#: dist/converse-no-dependencies.js:57103
+msgid "Persistent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31121
-msgid "Your messages are not encrypted. Click here to enable OTR encryption."
+#: dist/converse-no-dependencies.js:56951
+msgid "This room persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31123
-msgid "Your messages are encrypted, but your contact has not been verified."
+#: dist/converse-no-dependencies.js:56959
+msgid "This room will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31125
-msgid "Your messages are encrypted and your contact verified."
+#: dist/converse-no-dependencies.js:56965
+#: dist/converse-no-dependencies.js:57119
+msgid "Not anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31127
-msgid ""
-"Your contact has closed their end of the private session, you should do the "
-"same"
+#: dist/converse-no-dependencies.js:56967
+msgid "All other room occupants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31141
-msgid "End encrypted conversation"
+#: dist/converse-no-dependencies.js:56975
+#: dist/converse-no-dependencies.js:57125
+msgid "Only moderators can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31142
-msgid "Refresh encrypted conversation"
+#: dist/converse-no-dependencies.js:56983
+msgid "This room is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31143
-msgid "Start encrypted conversation"
+#: dist/converse-no-dependencies.js:56989
+#: dist/converse-no-dependencies.js:57143
+msgid "Not moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31144
-msgid "Verify with fingerprints"
+#: dist/converse-no-dependencies.js:56991
+msgid "This room is not being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31145
-msgid "Verify with SMP"
+#: dist/converse-no-dependencies.js:56997
+#: dist/converse-no-dependencies.js:57151
+msgid "Message archiving"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31146
-msgid "What's this?"
+#: dist/converse-no-dependencies.js:56999
+#: dist/converse-no-dependencies.js:57149
+msgid "Messages are archived on the server"
 msgstr ""
 
-#. Translation aware constants
-#. ---------------------------
-#. We can only call the __ translation method *after* converse.js
-#. has been initialized and with it the i18n machinery. That's why
-#. we do it here in the "initialize" method and not at the top of
-#. the module.
-#: dist/converse-no-dependencies.js:31189
-msgid "unencrypted"
+#: dist/converse-no-dependencies.js:57053
+msgid "This groupchat requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31190
-msgid "unverified"
+#: dist/converse-no-dependencies.js:57061
+msgid "This groupchat does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31191
-msgid "verified"
+#: dist/converse-no-dependencies.js:57063
+msgid "No password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31192
-msgid "finished"
+#: dist/converse-no-dependencies.js:57069
+msgid "This groupchat is not publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31788
-#, javascript-format
-msgid "Sorry, there was an error while trying to add %1$s as a contact."
+#: dist/converse-no-dependencies.js:57077
+msgid "This groupchat is publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31936
-msgid "This client does not allow presence subscriptions"
+#: dist/converse-no-dependencies.js:57085
+msgid "this groupchat is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32028
-msgid "Click to hide these contacts"
+#: dist/converse-no-dependencies.js:57093
+msgid "Anyone can join this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32112
-msgid "Don't have a chat account?"
+#: dist/converse-no-dependencies.js:57101
+msgid "This groupchat persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32114
-msgid "Create an account"
+#: dist/converse-no-dependencies.js:57109
+msgid "This groupchat will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32126
-msgid "Create your account"
+#: dist/converse-no-dependencies.js:57117
+msgid "All other groupchat participants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32128
-msgid "Please enter the XMPP provider to register with:"
+#: dist/converse-no-dependencies.js:57133
+msgid "This groupchat is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32148
-msgid "Already have a chat account?"
+#: dist/converse-no-dependencies.js:57141
+msgid "This groupchat is not being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32150
-msgid "Log in here"
+#: dist/converse-no-dependencies.js:58006
+msgid "XMPP Username:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32162
-msgid "Account Registration:"
+#: dist/converse-no-dependencies.js:58012
+msgid "Password:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32170
-msgid "Register"
+#: dist/converse-no-dependencies.js:58014
+msgid "password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32174
-msgid "Choose a different provider"
+#: dist/converse-no-dependencies.js:58022
+msgid "This is a trusted device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32186
-msgid "Hold tight, we're fetching the registration form…"
+#: dist/converse-no-dependencies.js:58024
+msgid ""
+"To improve performance, we cache your data in this browser. Uncheck this box "
+"if this is a public computer or if you want your data to be deleted when you "
+"log out. It's important that you explicitly log out, otherwise not all "
+"cached data might be deleted."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32321
-msgid " e.g. conversejs.org"
+#: dist/converse-no-dependencies.js:58026
+msgid "Log in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32367
-msgid "Fetch registration form"
+#: dist/converse-no-dependencies.js:58032
+msgid "Click here to log in anonymously"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32368
-msgid "Tip: A list of public XMPP providers is available"
+#: dist/converse-no-dependencies.js:58403
+msgid "Don't have a chat account?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32369
-msgid "here"
+#: dist/converse-no-dependencies.js:58405
+msgid "Create an account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32417
-msgid "Sorry, we're unable to connect to your chosen provider."
+#: dist/converse-no-dependencies.js:58426
+msgid "Create your account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32433
-msgid ""
-"Sorry, the given provider does not support in band account registration. "
-"Please try with a different provider."
+#: dist/converse-no-dependencies.js:58428
+msgid "Please enter the XMPP provider to register with:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32457
-#, javascript-format
-msgid ""
-"Something went wrong while establishing a connection with \"%1$s\". Are you "
-"sure it exists?"
+#: dist/converse-no-dependencies.js:58448
+msgid "Already have a chat account?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32620
-msgid "Now logging you in"
+#: dist/converse-no-dependencies.js:58450
+msgid "Log in here"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32624
-msgid "Registered successfully"
+#: dist/converse-no-dependencies.js:58471
+msgid "Account Registration:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32733
-msgid ""
-"The provider rejected your registration attempt. Please check the values you "
-"entered for correctness."
+#: dist/converse-no-dependencies.js:58479
+msgid "Register"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:58483
+msgid "Choose a different provider"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33149
-msgid "Click to toggle the rooms list"
+#: dist/converse-no-dependencies.js:58504
+msgid "Hold tight, we're fetching the registration form…"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33150
-msgid "Open Rooms"
+#: dist/converse-no-dependencies.js:59643
+#: dist/converse-no-dependencies.js:59672
+msgid "Download"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33194
+#: dist/converse-no-dependencies.js:59662
 #, javascript-format
-msgid "Are you sure you want to leave the room %1$s?"
+msgid "Download: \"%1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:59685
+msgid "Download video file"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:59698
+msgid "Download audio file"
 msgstr ""

File diff suppressed because it is too large
+ 0 - 0
locale/uk/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 1154 - 1001
locale/uk/LC_MESSAGES/converse.po


File diff suppressed because it is too large
+ 0 - 0
locale/zh_CN/LC_MESSAGES/converse.json


+ 892 - 904
locale/zh_CN/LC_MESSAGES/converse.po

@@ -7,9 +7,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Converse.js 3.2.1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-05-17 11:19+0200\n"
-"PO-Revision-Date: 2018-02-16 14:35+0000\n"
-"Last-Translator: Iru Cai (vimacs) <mytbk920423@gmail.com>\n"
+"POT-Creation-Date: 2018-07-02 16:28+0200\n"
+"PO-Revision-Date: 2018-07-19 15:11+0000\n"
+"Last-Translator: MrRyan <mr.iridescent.rsy@hotmail.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "conversejs/translations/zh_Hans/>\n"
 "Language: zh_CN\n"
@@ -17,1523 +17,1511 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 2.19\n"
+"X-Generator: Weblate 3.1-dev\n"
 
-#: dist/converse-no-dependencies.js:9853 dist/converse-no-dependencies.js:9882
-msgid "Download"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9872
-#, javascript-format
-msgid "Download: \"%1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9895
-msgid "Download video file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9908
-msgid "Download audio file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11229
-msgid "The connection has dropped, attempting to reconnect."
-msgstr "连接已经掉线,正在尝试重新连接。"
-
-#: dist/converse-no-dependencies.js:11327
-msgid "An error occurred while connecting to the chat server."
-msgstr "连接至聊天服务器时出现问题。"
-
-#: dist/converse-no-dependencies.js:11334
-msgid "Your Jabber ID and/or password is incorrect. Please try again."
-msgstr "你的Jabber ID或密码不正确,请重新输入。"
-
-#: dist/converse-no-dependencies.js:11346
-#, fuzzy, javascript-format
-msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
-msgstr "抱歉,我们未能连接至此XMPP服务器: "
-
-#: dist/converse-no-dependencies.js:11348
-msgid "The XMPP server did not offer a supported authentication mechanism"
-msgstr "XMPP服务器没有提供我们支持的验证方法"
-
-#: dist/converse-no-dependencies.js:16016
-#, javascript-format
-msgid "%1$s has invited you to join a chat room: %2$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16018
-#, javascript-format
-msgid ""
-"%1$s has invited you to join a chat room: %2$s, and left the following "
-"reason: \"%3$s\""
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16379
-#: dist/converse-no-dependencies.js:16464
-#: dist/converse-no-dependencies.js:33114
-msgid "Bookmark this room"
+#: dist/converse-no-dependencies.js:40690
+#: dist/converse-no-dependencies.js:40775
+#: dist/converse-no-dependencies.js:53478
+msgid "Bookmark this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16465
+#: dist/converse-no-dependencies.js:40776
 msgid "The name for this bookmark:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16466
-msgid "Would you like this room to be automatically joined upon startup?"
+#: dist/converse-no-dependencies.js:40777
+msgid "Would you like this groupchat to be automatically joined upon startup?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16467
-msgid "What should your nickname for this room be?"
+#: dist/converse-no-dependencies.js:40778
+msgid "What should your nickname for this groupchat be?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16469
-#: dist/converse-no-dependencies.js:25296
-#: dist/converse-no-dependencies.js:25380
+#: dist/converse-no-dependencies.js:40780
+#: dist/converse-no-dependencies.js:49283
+#: dist/converse-no-dependencies.js:52277
+#: dist/converse-no-dependencies.js:52361
 msgid "Save"
 msgstr "保存"
 
-#: dist/converse-no-dependencies.js:16470
-#: dist/converse-no-dependencies.js:25376
-#: dist/converse-no-dependencies.js:32190
+#: dist/converse-no-dependencies.js:40781
+#: dist/converse-no-dependencies.js:49284
+#: dist/converse-no-dependencies.js:52357
+#: dist/converse-no-dependencies.js:58508
 msgid "Cancel"
-msgstr ""
+msgstr "取消"
 
-#: dist/converse-no-dependencies.js:16543
+#: dist/converse-no-dependencies.js:40854
 #, javascript-format
 msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16659
+#: dist/converse-no-dependencies.js:40970
 msgid "Sorry, something went wrong while trying to save your bookmark."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16738
-#: dist/converse-no-dependencies.js:33112
-msgid "Leave this room"
+#: dist/converse-no-dependencies.js:41055
+#: dist/converse-no-dependencies.js:53476
+msgid "Leave this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16739
+#: dist/converse-no-dependencies.js:41056
 msgid "Remove this bookmark"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16740
-#: dist/converse-no-dependencies.js:33113
-msgid "Unbookmark this room"
+#: dist/converse-no-dependencies.js:41057
+#: dist/converse-no-dependencies.js:53477
+msgid "Unbookmark this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16741
-#: dist/converse-no-dependencies.js:28819
-#: dist/converse-no-dependencies.js:33115
-msgid "Show more information on this room"
+#: dist/converse-no-dependencies.js:41058
+#: dist/converse-no-dependencies.js:48558
+#: dist/converse-no-dependencies.js:53479
+msgid "Show more information on this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16744
-#: dist/converse-no-dependencies.js:28818
-#: dist/converse-no-dependencies.js:33117
-msgid "Click to open this room"
-msgstr ""
+#: dist/converse-no-dependencies.js:41061
+#: dist/converse-no-dependencies.js:48557
+#: dist/converse-no-dependencies.js:53481
+#, fuzzy
+msgid "Click to open this groupchat"
+msgstr "按此隐藏联系人"
 
-#: dist/converse-no-dependencies.js:16780
+#: dist/converse-no-dependencies.js:41097
 msgid "Click to toggle the bookmarks list"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16781
+#: dist/converse-no-dependencies.js:41098
 msgid "Bookmarks"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21217
+#: dist/converse-no-dependencies.js:41529
 msgid "Sorry, could not determine file upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21225
+#: dist/converse-no-dependencies.js:41537
 msgid "Sorry, could not determine upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21257
+#: dist/converse-no-dependencies.js:41569
 msgid "Sorry, could not succesfully upload your file."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21260
+#: dist/converse-no-dependencies.js:41572
 #, javascript-format
 msgid "Your server's response: \"%1$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21442
+#: dist/converse-no-dependencies.js:41749
 msgid "Sorry, looks like file upload is not supported by your server."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21452
+#: dist/converse-no-dependencies.js:41759
 #, javascript-format
 msgid ""
 "The size of your file, %1$s, exceeds the maximum allowed by your server, "
 "which is %2$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22197
-#, fuzzy
-msgid "Show more"
-msgstr "显示此菜单"
-
-#: dist/converse-no-dependencies.js:22248
-msgid "Typing from another device"
-msgstr "正在另一个装置上输入"
-
-#: dist/converse-no-dependencies.js:22250
-msgid "is typing"
-msgstr "正在输入"
-
-#: dist/converse-no-dependencies.js:22254
-msgid "Stopped typing on the other device"
-msgstr "已在另一个装置上停止输入"
-
-#: dist/converse-no-dependencies.js:22256
-msgid "has stopped typing"
-msgstr "已停止输入"
-
-#: dist/converse-no-dependencies.js:22259
-#: dist/converse-no-dependencies.js:23256
-#: dist/converse-no-dependencies.js:30521
-msgid "has gone away"
-msgstr "已经离开"
+#: dist/converse-no-dependencies.js:41778
+msgid "Sorry, an error occured:"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:22488
+#: dist/converse-no-dependencies.js:42489
 msgid "Close this chat box"
 msgstr "关闭此聊天对话窗口"
 
-#: dist/converse-no-dependencies.js:22516
+#: dist/converse-no-dependencies.js:42517
 msgid "The User's Profile Image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22519
-#: dist/converse-no-dependencies.js:25289
-#: dist/converse-no-dependencies.js:25374
+#: dist/converse-no-dependencies.js:42520
+#: dist/converse-no-dependencies.js:52270
+#: dist/converse-no-dependencies.js:52355
 msgid "Close"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22520
-#: dist/converse-no-dependencies.js:25290
+#: dist/converse-no-dependencies.js:42521
+#: dist/converse-no-dependencies.js:52271
 msgid "Email"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22521
-#: dist/converse-no-dependencies.js:25291
+#: dist/converse-no-dependencies.js:42522
+#: dist/converse-no-dependencies.js:52272
 #, fuzzy
 msgid "Full Name"
 msgstr "名称"
 
-#: dist/converse-no-dependencies.js:22522
+#: dist/converse-no-dependencies.js:42523
 #, fuzzy
 msgid "Jabber ID"
 msgstr "Jabber ID:"
 
-#: dist/converse-no-dependencies.js:22523
-#: dist/converse-no-dependencies.js:25292
-#: dist/converse-no-dependencies.js:29617
+#: dist/converse-no-dependencies.js:42524
+#: dist/converse-no-dependencies.js:49439
+#: dist/converse-no-dependencies.js:52273
 msgid "Nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22524
+#: dist/converse-no-dependencies.js:42525
 #, fuzzy
 msgid "Remove as contact"
 msgstr "添加联系人"
 
-#: dist/converse-no-dependencies.js:22525
+#: dist/converse-no-dependencies.js:42526
 msgid "Refresh"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22526
-#: dist/converse-no-dependencies.js:25294
+#: dist/converse-no-dependencies.js:42527
+#: dist/converse-no-dependencies.js:52275
 msgid "Role"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22527
-#: dist/converse-no-dependencies.js:25297
+#: dist/converse-no-dependencies.js:42528
+#: dist/converse-no-dependencies.js:52278
 msgid "URL"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22566
-#: dist/converse-no-dependencies.js:24293
+#: dist/converse-no-dependencies.js:42567
+#: dist/converse-no-dependencies.js:55141
 msgid "Are you sure you want to remove this contact?"
 msgstr "你确定要删除此联系人吗?"
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:25325
+#: dist/converse-no-dependencies.js:42576
+#: dist/converse-no-dependencies.js:52306
 msgid "Error"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:24301
+#: dist/converse-no-dependencies.js:42576
+#: dist/converse-no-dependencies.js:55149
 #, javascript-format
 msgid "Sorry, there was an error while trying to remove %1$s as a contact."
 msgstr "抱歉,删除%1$s为联系人时出现了问题。"
 
-#: dist/converse-no-dependencies.js:22629
-#: dist/converse-no-dependencies.js:22667
-#: dist/converse-no-dependencies.js:29029
+#: dist/converse-no-dependencies.js:42630
+#: dist/converse-no-dependencies.js:42668
+#: dist/converse-no-dependencies.js:48794
 msgid "You have unread messages"
 msgstr "你有未读信息"
 
-#: dist/converse-no-dependencies.js:22653
+#: dist/converse-no-dependencies.js:42654
 #, fuzzy
 msgid "Hidden message"
 msgstr "个人信息"
 
-#: dist/converse-no-dependencies.js:22655
+#: dist/converse-no-dependencies.js:42656
 msgid "Personal message"
 msgstr "个人信息"
 
-#: dist/converse-no-dependencies.js:22662
-#: dist/converse-no-dependencies.js:29026
+#: dist/converse-no-dependencies.js:42663
+#: dist/converse-no-dependencies.js:48791
 msgid "Send"
 msgstr "发送"
 
-#: dist/converse-no-dependencies.js:22663
+#: dist/converse-no-dependencies.js:42664
 msgid "Optional hint"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22692
+#: dist/converse-no-dependencies.js:42702
 msgid "Choose a file to send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22748
+#: dist/converse-no-dependencies.js:42758
 #, fuzzy
 msgid "Click to write as a normal (non-spoiler) message"
 msgstr "按此填写个性签名"
 
-#: dist/converse-no-dependencies.js:22750
+#: dist/converse-no-dependencies.js:42760
 #, fuzzy
 msgid "Click to write your message as a spoiler"
 msgstr "按此填写个性签名"
 
-#: dist/converse-no-dependencies.js:22754
+#: dist/converse-no-dependencies.js:42764
 msgid "Clear all messages"
 msgstr "清除所有信息"
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:42765
 #, fuzzy
 msgid "Insert emojis"
 msgstr "输入表情"
 
-#: dist/converse-no-dependencies.js:22756
+#: dist/converse-no-dependencies.js:42766
 msgid "Start a call"
 msgstr "开始语音通话"
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29265
+#: dist/converse-no-dependencies.js:43079
+#: dist/converse-no-dependencies.js:49082
 msgid "Remove messages"
 msgstr "删除信息"
 
-#: dist/converse-no-dependencies.js:23069
+#: dist/converse-no-dependencies.js:43079
 msgid "Write in the third person"
 msgstr "以第三人称输入"
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29267
+#: dist/converse-no-dependencies.js:43079
+#: dist/converse-no-dependencies.js:49082
 msgid "Show this menu"
 msgstr "显示此菜单"
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:43178
 #, fuzzy
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr "你确定要清除对话窗口的所有信息?"
 
-#: dist/converse-no-dependencies.js:23254
-#: dist/converse-no-dependencies.js:30519
+#: dist/converse-no-dependencies.js:43267
+#: dist/converse-no-dependencies.js:51817
 msgid "has gone offline"
 msgstr "已离线"
 
-#: dist/converse-no-dependencies.js:23258
-#: dist/converse-no-dependencies.js:30523
+#: dist/converse-no-dependencies.js:43269
+#: dist/converse-no-dependencies.js:47480
+#: dist/converse-no-dependencies.js:51819
+msgid "has gone away"
+msgstr "已经离开"
+
+#: dist/converse-no-dependencies.js:43271
+#: dist/converse-no-dependencies.js:51821
 msgid "is busy"
 msgstr "在忙碌"
 
-#: dist/converse-no-dependencies.js:23260
+#: dist/converse-no-dependencies.js:43273
 #, fuzzy
 msgid "is online"
 msgstr "在线"
 
-#: dist/converse-no-dependencies.js:23501
-#, fuzzy
-msgid "XMPP Username:"
-msgstr "用户名"
-
-#: dist/converse-no-dependencies.js:23507
-msgid "Password:"
-msgstr "密码:"
-
-#: dist/converse-no-dependencies.js:23509
-msgid "password"
-msgstr "密码"
+#: dist/converse-no-dependencies.js:43655
+#: dist/converse-no-dependencies.js:54717
+#: dist/converse-no-dependencies.js:55440
+msgid "Contacts"
+msgstr "联系人"
 
-#: dist/converse-no-dependencies.js:23513
-#: dist/converse-no-dependencies.js:29643
-msgid "Submit"
-msgstr "提交"
+#: dist/converse-no-dependencies.js:43893
+msgid "Username"
+msgstr "用户名"
 
-#: dist/converse-no-dependencies.js:23519
-msgid "Click here to log in anonymously"
-msgstr "按此以匿名登录"
+#: dist/converse-no-dependencies.js:43893
+msgid "user@domain"
+msgstr "用户@域名"
 
-#: dist/converse-no-dependencies.js:23864
-msgid "This contact is busy"
-msgstr "此联系人正在忙碌"
+#: dist/converse-no-dependencies.js:43901
+#: dist/converse-no-dependencies.js:54778
+msgid "Please enter a valid XMPP address"
+msgstr "请输入有效的XMPP地址"
 
-#: dist/converse-no-dependencies.js:23865
-msgid "This contact is online"
-msgstr "此联系人在线"
+#: dist/converse-no-dependencies.js:43990
+#, fuzzy
+msgid "Chat Contacts"
+msgstr "联系人"
 
-#: dist/converse-no-dependencies.js:23866
-msgid "This contact is offline"
-msgstr "此联系人不在线"
+#: dist/converse-no-dependencies.js:43990
+msgid "Toggle chat"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:23867
-msgid "This contact is unavailable"
-msgstr "此联系人不可用"
+#: dist/converse-no-dependencies.js:44568
+msgid "The connection has dropped, attempting to reconnect."
+msgstr "连接已经掉线,正在尝试重新连接。"
 
-#: dist/converse-no-dependencies.js:23868
-msgid "This contact is away for an extended period"
-msgstr "此联系人已离开了一段长时间"
+#: dist/converse-no-dependencies.js:44666
+msgid "An error occurred while connecting to the chat server."
+msgstr "连接至聊天服务器时出现问题。"
 
-#: dist/converse-no-dependencies.js:23869
-msgid "This contact is away"
-msgstr "此联系人已离开"
+#: dist/converse-no-dependencies.js:44673
+msgid "Your Jabber ID and/or password is incorrect. Please try again."
+msgstr "你的Jabber ID或密码不正确,请重新输入。"
 
-#: dist/converse-no-dependencies.js:23872
-#: dist/converse-no-dependencies.js:24584
-#: dist/converse-no-dependencies.js:25680
-msgid "Contacts"
-msgstr "联系人"
+#: dist/converse-no-dependencies.js:44685
+#, fuzzy, javascript-format
+msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
+msgstr "抱歉,我们未能连接至此XMPP服务器: "
 
-#: dist/converse-no-dependencies.js:23874
-msgid "Groups"
-msgstr "群组"
+#: dist/converse-no-dependencies.js:44687
+msgid "The XMPP server did not offer a supported authentication mechanism"
+msgstr "XMPP服务器没有提供我们支持的验证方法"
 
-#: dist/converse-no-dependencies.js:23876
-msgid "My contacts"
-msgstr "我的联系人"
+#: dist/converse-no-dependencies.js:47426
+#, fuzzy
+msgid "Show more"
+msgstr "显示此菜单"
 
-#: dist/converse-no-dependencies.js:23878
-msgid "Pending contacts"
-msgstr ""
+#: dist/converse-no-dependencies.js:47469
+msgid "Typing from another device"
+msgstr "正在另一个装置上输入"
 
-#: dist/converse-no-dependencies.js:23880
-msgid "Contact requests"
-msgstr "联系人请求"
+#: dist/converse-no-dependencies.js:47471
+msgid "is typing"
+msgstr "正在输入"
 
-#: dist/converse-no-dependencies.js:23882
-msgid "Ungrouped"
-msgstr "未分组的"
+#: dist/converse-no-dependencies.js:47475
+msgid "Stopped typing on the other device"
+msgstr "已在另一个装置上停止输入"
 
-#: dist/converse-no-dependencies.js:23925
-msgid "Contact name"
-msgstr "联系人名称"
+#: dist/converse-no-dependencies.js:47477
+msgid "has stopped typing"
+msgstr "已停止输入"
 
-#: dist/converse-no-dependencies.js:23925
-#: dist/converse-no-dependencies.js:28905
-msgid "Optional nickname"
+#: dist/converse-no-dependencies.js:47708
+#: dist/converse-no-dependencies.js:47751
+msgid "Minimize this chat box"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23928
-#, fuzzy
-msgid "Add a Contact"
-msgstr "添加联系人"
+#: dist/converse-no-dependencies.js:47884
+msgid "Click to restore this chat"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:23929
-msgid "XMPP Address"
+#: dist/converse-no-dependencies.js:48071
+msgid "Minimized"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23931
+#: dist/converse-no-dependencies.js:48400
 #, fuzzy
-msgid "name@example.org"
-msgstr "例如,user@example.org"
-
-#: dist/converse-no-dependencies.js:23932
-msgid "Add"
-msgstr "添加"
+msgid "This groupchat is not anonymous"
+msgstr "此聊天室不是匿名的"
 
-#: dist/converse-no-dependencies.js:24003
-#: dist/converse-no-dependencies.js:25917
-msgid "Please enter a valid XMPP address"
-msgstr "请输入有效的XMPP地址"
+#: dist/converse-no-dependencies.js:48401
+#, fuzzy
+msgid "This groupchat now shows unavailable members"
+msgstr "此聊天室显示不可用的成员"
 
-#: dist/converse-no-dependencies.js:24040
-msgid "Filter"
-msgstr "筛选"
+#: dist/converse-no-dependencies.js:48402
+#, fuzzy
+msgid "This groupchat does not show unavailable members"
+msgstr "此聊天室不显示不可用的成员"
 
-#: dist/converse-no-dependencies.js:24041
+#: dist/converse-no-dependencies.js:48403
 #, fuzzy
-msgid "Filter by contact name"
-msgstr "联系人名称"
+msgid "The groupchat configuration has changed"
+msgstr "此聊天室设置已被更改"
 
-#: dist/converse-no-dependencies.js:24042
-msgid "Filter by group name"
+#: dist/converse-no-dependencies.js:48404
+msgid "groupchat logging is now enabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24043
-msgid "Filter by status"
+#: dist/converse-no-dependencies.js:48405
+msgid "groupchat logging is now disabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24044
-msgid "Any"
-msgstr "任意"
+#: dist/converse-no-dependencies.js:48406
+#, fuzzy
+msgid "This groupchat is now no longer anonymous"
+msgstr "这个聊天室现在不再匿名"
 
-#: dist/converse-no-dependencies.js:24045
-msgid "Unread"
-msgstr "未读"
+#: dist/converse-no-dependencies.js:48407
+#, fuzzy
+msgid "This groupchat is now semi-anonymous"
+msgstr "这个聊天室现在半匿名"
 
-#: dist/converse-no-dependencies.js:24046
-#: dist/converse-no-dependencies.js:25379
-msgid "Online"
-msgstr "在线"
+#: dist/converse-no-dependencies.js:48408
+#, fuzzy
+msgid "This groupchat is now fully-anonymous"
+msgstr "这个聊天室现在完全匿名"
 
-#: dist/converse-no-dependencies.js:24047
-msgid "Chatty"
-msgstr "经常联系"
+#: dist/converse-no-dependencies.js:48409
+#, fuzzy
+msgid "A new groupchat has been created"
+msgstr "已经创建一个聊天室"
 
-#: dist/converse-no-dependencies.js:24048
-#: dist/converse-no-dependencies.js:25375
-msgid "Busy"
-msgstr "忙碌"
+#: dist/converse-no-dependencies.js:48412
+msgid "You have been banned from this groupchat"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24049
-#: dist/converse-no-dependencies.js:25373
-msgid "Away"
-msgstr "离开"
+#: dist/converse-no-dependencies.js:48413
+msgid "You have been kicked from this groupchat"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24050
-msgid "Extended Away"
-msgstr "长期离开"
+#: dist/converse-no-dependencies.js:48414
+msgid ""
+"You have been removed from this groupchat because of an affiliation change"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24051
-#: dist/converse-no-dependencies.js:25378
-msgid "Offline"
-msgstr "离线"
+#: dist/converse-no-dependencies.js:48415
+msgid ""
+"You have been removed from this groupchat because the groupchat has changed "
+"to members-only and you're not a member"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48416
+msgid ""
+"You have been removed from this groupchat because the MUC (Multi-user chat) "
+"service is being shut down"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24205
-#: dist/converse-no-dependencies.js:24247
+#. XXX: Note the triple underscore function and not double
+#. * underscore.
+#. *
+#. * This is a hack. We can't pass the strings to __ because we
+#. * don't yet know what the variable to interpolate is.
+#. *
+#. * Triple underscore will just return the string again, but we
+#. * can then at least tell gettext to scan for it so that these
+#. * strings are picked up by the translation machinery.
+#.
+#: dist/converse-no-dependencies.js:48429
 #, javascript-format
-msgid "Click to remove %1$s as a contact"
-msgstr "按此删除%1$s为联络人"
+msgid "%1$s has been banned"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24214
+#: dist/converse-no-dependencies.js:48430
 #, javascript-format
-msgid "Click to accept the contact request from %1$s"
-msgstr "按此接受%1$s的联系人请求"
+msgid "%1$s's nickname has changed"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24215
+#: dist/converse-no-dependencies.js:48431
 #, javascript-format
-msgid "Click to decline the contact request from %1$s"
-msgstr "按此拒绝%1$s的联系人请求"
+msgid "%1$s has been kicked out"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24246
-#, fuzzy, javascript-format
-msgid "Click to chat with %1$s (JID: %2$s)"
-msgstr "按此与此联系人聊天"
+#: dist/converse-no-dependencies.js:48432
+#, javascript-format
+msgid "%1$s has been removed because of an affiliation change"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24323
-msgid "Are you sure you want to decline this contact request?"
-msgstr "你确定要拒绝此联系人请求吗?"
+#: dist/converse-no-dependencies.js:48433
+#, javascript-format
+msgid "%1$s has been removed for not being a member"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:24585
-msgid "Add a contact"
-msgstr "添加联系人"
+#: dist/converse-no-dependencies.js:48436
+#, javascript-format
+msgid "Your nickname has been automatically set to %1$s"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:25288
-msgid "Your Profile"
+#: dist/converse-no-dependencies.js:48437
+#, javascript-format
+msgid "Your nickname has been changed to %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25293
-msgid "XMPP Address (JID)"
+#: dist/converse-no-dependencies.js:48468
+msgid "Description:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25295
-msgid ""
-"Use commas to separate multiple roles. Your roles are shown next to your "
-"name on your chat messages."
+#: dist/converse-no-dependencies.js:48469
+msgid "Groupchat Address (JID):"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25298
-msgid "Your avatar image"
+#: dist/converse-no-dependencies.js:48470
+msgid "Participants:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25325
-#, fuzzy
-msgid "Sorry, an error happened while trying to save your profile data."
-msgstr "抱歉,删除%1$s为联系人时出现了问题。"
+#: dist/converse-no-dependencies.js:48471
+msgid "Features:"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:25325
-msgid "You can check your browser's developer console for any error output."
+#: dist/converse-no-dependencies.js:48472
+msgid "Requires authentication"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25377
-msgid "Custom status"
-msgstr "个性签名"
-
-#: dist/converse-no-dependencies.js:25381
-#, fuzzy
-msgid "Away for long"
-msgstr "长期离开"
-
-#: dist/converse-no-dependencies.js:25382
-#, fuzzy
-msgid "Change chat status"
-msgstr "按此更改你的聊天状态"
-
-#: dist/converse-no-dependencies.js:25383
-#, fuzzy
-msgid "Personal status message"
-msgstr "个人信息"
-
-#: dist/converse-no-dependencies.js:25427
-#, javascript-format
-msgid "I am %1$s"
-msgstr "我正%1$s"
-
-#: dist/converse-no-dependencies.js:25430
-msgid "Change settings"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25431
-msgid "Click to change your chat status"
-msgstr "按此更改你的聊天状态"
-
-#: dist/converse-no-dependencies.js:25432
-msgid "Log out"
-msgstr "登出"
-
-#: dist/converse-no-dependencies.js:25433
-msgid "Your profile"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25456
-#, fuzzy
-msgid "Are you sure you want to log out?"
-msgstr "你确定要删除此联系人吗?"
-
-#: dist/converse-no-dependencies.js:25464
-#: dist/converse-no-dependencies.js:25474
-msgid "online"
-msgstr "在线"
-
-#: dist/converse-no-dependencies.js:25466
-msgid "busy"
-msgstr "忙碌"
-
-#: dist/converse-no-dependencies.js:25468
-msgid "away for long"
-msgstr "长期离开"
-
-#: dist/converse-no-dependencies.js:25470
-msgid "away"
-msgstr "离开"
-
-#: dist/converse-no-dependencies.js:25472
-msgid "offline"
-msgstr "离线"
-
-#: dist/converse-no-dependencies.js:25909
-msgid "Username"
-msgstr "用户名"
-
-#: dist/converse-no-dependencies.js:25909
-msgid "user@domain"
-msgstr "用户@域名"
-
-#: dist/converse-no-dependencies.js:26003
-#, fuzzy
-msgid "Chat Contacts"
-msgstr "联系人"
-
-#: dist/converse-no-dependencies.js:26003
-msgid "Toggle chat"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:27529
-#: dist/converse-no-dependencies.js:27572
-msgid "Minimize this chat box"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:27705
-msgid "Click to restore this chat"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:27892
-msgid "Minimized"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28650
-msgid "This room is not anonymous"
-msgstr "此聊天室不是匿名的"
-
-#: dist/converse-no-dependencies.js:28651
-msgid "This room now shows unavailable members"
-msgstr "此聊天室显示不可用的成员"
-
-#: dist/converse-no-dependencies.js:28652
-msgid "This room does not show unavailable members"
-msgstr "此聊天室不显示不可用的成员"
-
-#: dist/converse-no-dependencies.js:28653
-msgid "The room configuration has changed"
-msgstr "此聊天室设置已被更改"
-
-#: dist/converse-no-dependencies.js:28654
-msgid "Room logging is now enabled"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28655
-msgid "Room logging is now disabled"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28656
-msgid "This room is now no longer anonymous"
-msgstr "这个聊天室现在不再匿名"
-
-#: dist/converse-no-dependencies.js:28657
-msgid "This room is now semi-anonymous"
-msgstr "这个聊天室现在半匿名"
-
-#: dist/converse-no-dependencies.js:28658
-msgid "This room is now fully-anonymous"
-msgstr "这个聊天室现在完全匿名"
-
-#: dist/converse-no-dependencies.js:28659
-msgid "A new room has been created"
-msgstr "已经创建一个聊天室"
-
-#: dist/converse-no-dependencies.js:28663
-msgid "You have been banned from this room"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28664
-msgid "You have been kicked from this room"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28665
-msgid "You have been removed from this room because of an affiliation change"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28666
-msgid ""
-"You have been removed from this room because the room has changed to members-"
-"only and you're not a member"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28667
-msgid ""
-"You have been removed from this room because the MUC (Multi-user chat) "
-"service is being shut down"
-msgstr ""
-
-#. XXX: Note the triple underscore function and not double
-#. * underscore.
-#. *
-#. * This is a hack. We can't pass the strings to __ because we
-#. * don't yet know what the variable to interpolate is.
-#. *
-#. * Triple underscore will just return the string again, but we
-#. * can then at least tell gettext to scan for it so that these
-#. * strings are picked up by the translation machinery.
-#.
-#: dist/converse-no-dependencies.js:28681
-#, javascript-format
-msgid "%1$s has been banned"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28682
-#, javascript-format
-msgid "%1$s's nickname has changed"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28683
-#, javascript-format
-msgid "%1$s has been kicked out"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28684
-#, javascript-format
-msgid "%1$s has been removed because of an affiliation change"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28685
-#, javascript-format
-msgid "%1$s has been removed for not being a member"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28689
-#, javascript-format
-msgid "Your nickname has been automatically set to %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28690
-#, javascript-format
-msgid "Your nickname has been changed to %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28724
-msgid "Description:"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28725
-msgid "Room Address (JID):"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28726
-msgid "Occupants:"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28727
-msgid "Features:"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28728
-msgid "Requires authentication"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:28729
-#: dist/converse-no-dependencies.js:30122
+#: dist/converse-no-dependencies.js:48473
+#: dist/converse-no-dependencies.js:56917
+#: dist/converse-no-dependencies.js:57071
 msgid "Hidden"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28730
+#: dist/converse-no-dependencies.js:48474
 msgid "Requires an invitation"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28731
-#: dist/converse-no-dependencies.js:30125
+#: dist/converse-no-dependencies.js:48475
+#: dist/converse-no-dependencies.js:56981
+#: dist/converse-no-dependencies.js:57135
 msgid "Moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28732
-#: dist/converse-no-dependencies.js:30126
+#: dist/converse-no-dependencies.js:48476
 msgid "Non-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28733
-msgid "Open room"
+#: dist/converse-no-dependencies.js:48477
+#: dist/converse-no-dependencies.js:56941
+#: dist/converse-no-dependencies.js:57095
+msgid "Open"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28734
-msgid "Permanent room"
+#: dist/converse-no-dependencies.js:48478
+msgid "Permanent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28735
-#: dist/converse-no-dependencies.js:30130
+#: dist/converse-no-dependencies.js:48479
+#: dist/converse-no-dependencies.js:56925
+#: dist/converse-no-dependencies.js:57079
 msgid "Public"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28736
-#: dist/converse-no-dependencies.js:30131
+#: dist/converse-no-dependencies.js:48480
+#: dist/converse-no-dependencies.js:56973
+#: dist/converse-no-dependencies.js:57127
 msgid "Semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28737
-msgid "Temporary room"
+#: dist/converse-no-dependencies.js:48481
+#: dist/converse-no-dependencies.js:56957
+#: dist/converse-no-dependencies.js:57111
+msgid "Temporary"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28738
-#: dist/converse-no-dependencies.js:30133
+#: dist/converse-no-dependencies.js:48482
 msgid "Unmoderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28777
-msgid "Query for Chatrooms"
+#: dist/converse-no-dependencies.js:48518
+msgid "Query for Groupchats"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28778
+#: dist/converse-no-dependencies.js:48519
 msgid "Server address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28779
+#: dist/converse-no-dependencies.js:48520
 msgid "Show rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28780
+#: dist/converse-no-dependencies.js:48521
 #, fuzzy
 msgid "conference.example.org"
 msgstr "例如,user@example.org"
 
-#: dist/converse-no-dependencies.js:28833
+#: dist/converse-no-dependencies.js:48570
 #, fuzzy
 msgid "No rooms found"
 msgstr "找不到用户"
 
-#: dist/converse-no-dependencies.js:28850
+#: dist/converse-no-dependencies.js:48587
 #, fuzzy
 msgid "Rooms found:"
 msgstr "找不到用户"
 
-#: dist/converse-no-dependencies.js:28903
-msgid "Enter a new Chatroom"
+#: dist/converse-no-dependencies.js:48639
+msgid "Enter a new Groupchat"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48640
+msgid "Groupchat address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28904
-msgid "Room address"
+#: dist/converse-no-dependencies.js:48641
+#: dist/converse-no-dependencies.js:54770
+msgid "Optional nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28906
+#: dist/converse-no-dependencies.js:48642
 msgid "name@conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28907
+#: dist/converse-no-dependencies.js:48643
 msgid "Join"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29025
+#: dist/converse-no-dependencies.js:48684
+#, javascript-format
+msgid "Groupchat info for %1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48790
 msgid "Message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29058
+#: dist/converse-no-dependencies.js:48836
 #, javascript-format
 msgid "%1$s is no longer a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29061
+#: dist/converse-no-dependencies.js:48840
 #, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:48844
 #, javascript-format
 msgid "%1$s has been muted"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29067
+#: dist/converse-no-dependencies.js:48848
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29077
-msgid "Close and leave this room"
-msgstr ""
+#: dist/converse-no-dependencies.js:48856
+#, fuzzy
+msgid "Close and leave this groupchat"
+msgstr "关闭此聊天对话窗口"
+
+#: dist/converse-no-dependencies.js:48857
+#, fuzzy
+msgid "Configure this groupchat"
+msgstr "关闭此聊天对话窗口"
 
-#: dist/converse-no-dependencies.js:29078
-msgid "Configure this room"
+#: dist/converse-no-dependencies.js:48858
+msgid "Show more details about this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29122
-msgid "Hide the list of occupants"
+#: dist/converse-no-dependencies.js:48898
+msgid "Hide the list of participants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29206
+#: dist/converse-no-dependencies.js:49014
 #, javascript-format
 msgid ""
 "Error: the \"%1$s\" command takes two arguments, the user's nickname and "
 "optionally a reason."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29218
+#: dist/converse-no-dependencies.js:49023
 msgid ""
 "Sorry, an error happened while running the command. Check your browser's "
 "developer console for details."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29263
+#: dist/converse-no-dependencies.js:49082
 msgid "Change user's affiliation to admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29264
-msgid "Ban user from room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Ban user from groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29266
+#: dist/converse-no-dependencies.js:49082
 msgid "Change user role to participant"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29268
-msgid "Kick user from room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Kick user from groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29269
+#: dist/converse-no-dependencies.js:49082
 msgid "Write in 3rd person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29270
+#: dist/converse-no-dependencies.js:49082
 msgid "Grant membership to a user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29271
+#: dist/converse-no-dependencies.js:49082
 msgid "Remove user's ability to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29272
+#: dist/converse-no-dependencies.js:49082
 msgid "Change your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29273
+#: dist/converse-no-dependencies.js:49082
 msgid "Grant moderator role to user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29274
-msgid "Grant ownership of this room"
+#: dist/converse-no-dependencies.js:49082
+msgid "Grant ownership of this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29275
+#: dist/converse-no-dependencies.js:49082
 msgid "Revoke user's membership"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29276
-msgid "Set room subject"
+#: dist/converse-no-dependencies.js:49082
+msgid "Set groupchat subject"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29277
-msgid "Set room subject (alias for /subject)"
+#: dist/converse-no-dependencies.js:49082
+msgid "Set groupchat subject (alias for /subject)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29278
+#: dist/converse-no-dependencies.js:49082
 msgid "Allow muted user to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29590
+#: dist/converse-no-dependencies.js:49412
 msgid ""
 "The nickname you chose is reserved or currently in use, please choose a "
 "different one."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29616
+#: dist/converse-no-dependencies.js:49438
 msgid "Please choose your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29618
-msgid "Enter room"
+#: dist/converse-no-dependencies.js:49440
+msgid "Enter groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29641
-msgid "This chatroom requires a password"
+#: dist/converse-no-dependencies.js:49461
+msgid "This groupchat requires a password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29642
+#: dist/converse-no-dependencies.js:49462
 msgid "Password: "
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29740
+#: dist/converse-no-dependencies.js:49463
+msgid "Submit"
+msgstr "提交"
+
+#: dist/converse-no-dependencies.js:49585
 #, javascript-format
 msgid "This action was done by %1$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29743
-#: dist/converse-no-dependencies.js:29759
+#: dist/converse-no-dependencies.js:49589
+#: dist/converse-no-dependencies.js:49607
 #, javascript-format
 msgid "The reason given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29781
+#: dist/converse-no-dependencies.js:49628
 #, javascript-format
-msgid "%1$s has left and re-entered the room"
+msgid "%1$s has left and re-entered the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29786
+#: dist/converse-no-dependencies.js:49634
 #, javascript-format
-msgid "%1$s has entered the room"
+msgid "%1$s has entered the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29788
+#: dist/converse-no-dependencies.js:49636
 #, javascript-format
-msgid "%1$s has entered the room. \"%2$s\""
+msgid "%1$s has entered the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29818
+#: dist/converse-no-dependencies.js:49667
 #, javascript-format
-msgid "%1$s has entered and left the room"
+msgid "%1$s has entered and left the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29820
+#: dist/converse-no-dependencies.js:49669
 #, javascript-format
-msgid "%1$s has entered and left the room. \"%2$s\""
+msgid "%1$s has entered and left the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29832
+#: dist/converse-no-dependencies.js:49682
 #, javascript-format
-msgid "%1$s has left the room"
+msgid "%1$s has left the groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29834
+#: dist/converse-no-dependencies.js:49684
 #, javascript-format
-msgid "%1$s has left the room. \"%2$s\""
+msgid "%1$s has left the groupchat. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29877
-msgid "You are not on the member list of this room."
+#: dist/converse-no-dependencies.js:49730
+msgid "You are not on the member list of this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29879
-msgid "You have been banned from this room."
+#: dist/converse-no-dependencies.js:49732
+msgid "You have been banned from this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29883
+#: dist/converse-no-dependencies.js:49736
 msgid "No nickname was specified."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29887
+#: dist/converse-no-dependencies.js:49740
 msgid "You are not allowed to create new rooms."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29889
-msgid "Your nickname doesn't conform to this room's policies."
+#: dist/converse-no-dependencies.js:49742
+msgid "Your nickname doesn't conform to this groupchat's policies."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29893
-msgid "This room does not (yet) exist."
+#: dist/converse-no-dependencies.js:49746
+msgid "This groupchat does not (yet) exist."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29895
-msgid "This room has reached its maximum number of occupants."
+#: dist/converse-no-dependencies.js:49748
+msgid "This groupchat has reached its maximum number of participants."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29950
+#: dist/converse-no-dependencies.js:49750
+msgid "Remote server not found"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:49755
 #, javascript-format
-msgid "Topic set by %1$s"
+msgid "The explanation given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29981
-msgid "Chatrooms"
+#: dist/converse-no-dependencies.js:49808
+#, javascript-format
+msgid "Topic set by %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29982
+#: dist/converse-no-dependencies.js:49831
+#, fuzzy
+msgid "Groupchats"
+msgstr "群组"
+
+#: dist/converse-no-dependencies.js:49832
 msgid "Add a new room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29983
+#: dist/converse-no-dependencies.js:49833
 msgid "Query for rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30022
+#: dist/converse-no-dependencies.js:49871
 #, javascript-format
 msgid "Click to mention %1$s in your message."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30023
+#: dist/converse-no-dependencies.js:49872
 msgid "This user is a moderator."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30024
-msgid "This user can send messages in this room."
+#: dist/converse-no-dependencies.js:49873
+msgid "This user can send messages in this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30025
-msgid "This user can NOT send messages in this room."
+#: dist/converse-no-dependencies.js:49874
+msgid "This user can NOT send messages in this groupchat."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30026
+#: dist/converse-no-dependencies.js:49875
 msgid "Moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30027
+#: dist/converse-no-dependencies.js:49876
 msgid "Visitor"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30028
+#: dist/converse-no-dependencies.js:49877
 msgid "Owner"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30029
+#: dist/converse-no-dependencies.js:49878
 msgid "Member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30030
+#: dist/converse-no-dependencies.js:49879
 msgid "Admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30082
-msgid "Occupants"
+#: dist/converse-no-dependencies.js:49921
+msgid "Participants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30102
-#: dist/converse-no-dependencies.js:30209
+#: dist/converse-no-dependencies.js:49938
+#: dist/converse-no-dependencies.js:50019
 msgid "Invite"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30121
-msgid "Features"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:30123
-msgid "Message archiving"
+#: dist/converse-no-dependencies.js:49996
+#, javascript-format
+msgid ""
+"You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
+"include a message, explaining the reason for the invitation."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30124
-msgid "Members only"
+#: dist/converse-no-dependencies.js:50018
+msgid "Please enter a valid XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30127
-msgid "Open"
+#: dist/converse-no-dependencies.js:51384
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30128
-msgid "Password protected"
+#: dist/converse-no-dependencies.js:51386
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30129
-msgid "Persistent"
+#. workaround for Prosody which doesn't give type "headline"
+#: dist/converse-no-dependencies.js:51767
+#: dist/converse-no-dependencies.js:51773
+#, javascript-format
+msgid "Notification from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30132
-msgid "Temporary"
+#: dist/converse-no-dependencies.js:51775
+#: dist/converse-no-dependencies.js:51786
+#: dist/converse-no-dependencies.js:51789
+#, javascript-format
+msgid "%1$s says"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30134
-msgid "No password"
+#: dist/converse-no-dependencies.js:51823
+msgid "has come online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30135
-msgid "This room is not publicly searchable"
+#: dist/converse-no-dependencies.js:51840
+msgid "wants to be your contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30136
-msgid "Messages are archived on the server"
+#: dist/converse-no-dependencies.js:52022
+#, javascript-format
+msgid "Log in with %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30137
-msgid "This room is restricted to members only"
+#: dist/converse-no-dependencies.js:52269
+msgid "Your Profile"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30138
-msgid "This room is being moderated"
+#: dist/converse-no-dependencies.js:52274
+msgid "XMPP Address (JID)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30139
-msgid "All other room occupants can see your XMPP username"
+#: dist/converse-no-dependencies.js:52276
+msgid ""
+"Use commas to separate multiple roles. Your roles are shown next to your "
+"name on your chat messages."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30140
-msgid "Anyone can join this room"
+#: dist/converse-no-dependencies.js:52279
+msgid "Your avatar image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30141
-msgid "This room requires a password before entry"
-msgstr ""
+#: dist/converse-no-dependencies.js:52306
+#, fuzzy
+msgid "Sorry, an error happened while trying to save your profile data."
+msgstr "抱歉,删除%1$s为联系人时出现了问题。"
 
-#: dist/converse-no-dependencies.js:30142
-msgid "This room persists even if it's unoccupied"
+#: dist/converse-no-dependencies.js:52306
+msgid "You can check your browser's developer console for any error output."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30143
-msgid "This room is publicly searchable"
-msgstr ""
+#: dist/converse-no-dependencies.js:52354
+#: dist/converse-no-dependencies.js:54896
+msgid "Away"
+msgstr "离开"
 
-#: dist/converse-no-dependencies.js:30144
-msgid "Only moderators can see your XMPP username"
-msgstr ""
+#: dist/converse-no-dependencies.js:52356
+#: dist/converse-no-dependencies.js:54895
+msgid "Busy"
+msgstr "忙碌"
 
-#: dist/converse-no-dependencies.js:30145
-msgid "This room will disappear once the last person leaves"
-msgstr ""
+#: dist/converse-no-dependencies.js:52358
+msgid "Custom status"
+msgstr "个性签名"
 
-#: dist/converse-no-dependencies.js:30146
-msgid "This room is not being moderated"
-msgstr ""
+#: dist/converse-no-dependencies.js:52359
+#: dist/converse-no-dependencies.js:54898
+msgid "Offline"
+msgstr "离线"
 
-#: dist/converse-no-dependencies.js:30147
-msgid "This room does not require a password upon entry"
-msgstr ""
+#: dist/converse-no-dependencies.js:52360
+#: dist/converse-no-dependencies.js:54893
+msgid "Online"
+msgstr "在线"
 
-#: dist/converse-no-dependencies.js:30187
-#, javascript-format
-msgid ""
-"You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
-"include a message, explaining the reason for the invitation."
-msgstr ""
+#: dist/converse-no-dependencies.js:52362
+#, fuzzy
+msgid "Away for long"
+msgstr "长期离开"
 
-#: dist/converse-no-dependencies.js:30208
-msgid "Please enter a valid XMPP username"
-msgstr ""
+#: dist/converse-no-dependencies.js:52363
+#, fuzzy
+msgid "Change chat status"
+msgstr "按此更改你的聊天状态"
 
-#. workaround for Prosody which doesn't give type "headline"
-#: dist/converse-no-dependencies.js:30469
-#: dist/converse-no-dependencies.js:30475
+#: dist/converse-no-dependencies.js:52364
+#, fuzzy
+msgid "Personal status message"
+msgstr "个人信息"
+
+#: dist/converse-no-dependencies.js:52408
 #, javascript-format
-msgid "Notification from %1$s"
+msgid "I am %1$s"
+msgstr "我正%1$s"
+
+#: dist/converse-no-dependencies.js:52411
+msgid "Change settings"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30477
-#: dist/converse-no-dependencies.js:30488
-#: dist/converse-no-dependencies.js:30491
-#, javascript-format
-msgid "%1$s says"
+#: dist/converse-no-dependencies.js:52412
+msgid "Click to change your chat status"
+msgstr "按此更改你的聊天状态"
+
+#: dist/converse-no-dependencies.js:52413
+msgid "Log out"
+msgstr "登出"
+
+#: dist/converse-no-dependencies.js:52414
+msgid "Your profile"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30525
-msgid "has come online"
+#: dist/converse-no-dependencies.js:52437
+#, fuzzy
+msgid "Are you sure you want to log out?"
+msgstr "你确定要删除此联系人吗?"
+
+#: dist/converse-no-dependencies.js:52445
+#: dist/converse-no-dependencies.js:52455
+msgid "online"
+msgstr "在线"
+
+#: dist/converse-no-dependencies.js:52447
+msgid "busy"
+msgstr "忙碌"
+
+#: dist/converse-no-dependencies.js:52449
+msgid "away for long"
+msgstr "长期离开"
+
+#: dist/converse-no-dependencies.js:52451
+msgid "away"
+msgstr "离开"
+
+#: dist/converse-no-dependencies.js:52453
+msgid "offline"
+msgstr "离线"
+
+#: dist/converse-no-dependencies.js:52755
+msgid " e.g. conversejs.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30542
-msgid "wants to be your contact"
+#: dist/converse-no-dependencies.js:52802
+msgid "Fetch registration form"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30824
-msgid "Re-establishing encrypted session"
+#: dist/converse-no-dependencies.js:52803
+msgid "Tip: A list of public XMPP providers is available"
 msgstr ""
 
-#. We need to generate a new key and instance tag
-#: dist/converse-no-dependencies.js:30835
-msgid "Generating private key."
+#: dist/converse-no-dependencies.js:52804
+msgid "here"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30835
-msgid "Your browser might become unresponsive."
+#: dist/converse-no-dependencies.js:52852
+msgid "Sorry, we're unable to connect to your chosen provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30878
-#, javascript-format
+#: dist/converse-no-dependencies.js:52868
 msgid ""
-"Authentication request from %1$s\n"
-"\n"
-"Your chat contact is attempting to verify your identity, by asking you the "
-"question below.\n"
-"\n"
-"%2$s"
+"Sorry, the given provider does not support in band account registration. "
+"Please try with a different provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30887
-msgid "Could not verify this user's identify."
+#: dist/converse-no-dependencies.js:52892
+#, javascript-format
+msgid ""
+"Something went wrong while establishing a connection with \"%1$s\". Are you "
+"sure it exists?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30941
-msgid "Exchanging private key with contact."
+#: dist/converse-no-dependencies.js:53055
+msgid "Now logging you in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31038
-msgid "Your messages are not encrypted anymore"
+#: dist/converse-no-dependencies.js:53059
+msgid "Registered successfully"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31040
+#: dist/converse-no-dependencies.js:53168
 msgid ""
-"Your messages are now encrypted but your contact's identity has not been "
-"verified."
+"The provider rejected your registration attempt. Please check the values you "
+"entered for correctness."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31042
-msgid "Your contact's identify has been verified."
+#: dist/converse-no-dependencies.js:53537
+msgid "Click to toggle the list of open groupchats"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:53538
+msgid "Open Groupchats"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:53582
+#, fuzzy, javascript-format
+msgid "Are you sure you want to leave the groupchat %1$s?"
+msgstr "你确定要删除此联系人吗?"
+
+#: dist/converse-no-dependencies.js:54191
+#, javascript-format
+msgid "Sorry, there was an error while trying to add %1$s as a contact."
+msgstr "抱歉,添加%1$s为联系人时出现了问题。"
+
+#: dist/converse-no-dependencies.js:54402
+msgid "This client does not allow presence subscriptions"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31044
-msgid "Your contact has ended encryption on their end, you should do the same."
+#: dist/converse-no-dependencies.js:54510
+msgid "Click to hide these contacts"
+msgstr "按此隐藏联系人"
+
+#: dist/converse-no-dependencies.js:54709
+msgid "This contact is busy"
+msgstr "此联系人正在忙碌"
+
+#: dist/converse-no-dependencies.js:54710
+msgid "This contact is online"
+msgstr "此联系人在线"
+
+#: dist/converse-no-dependencies.js:54711
+msgid "This contact is offline"
+msgstr "此联系人不在线"
+
+#: dist/converse-no-dependencies.js:54712
+msgid "This contact is unavailable"
+msgstr "此联系人不可用"
+
+#: dist/converse-no-dependencies.js:54713
+msgid "This contact is away for an extended period"
+msgstr "此联系人已离开了一段长时间"
+
+#: dist/converse-no-dependencies.js:54714
+msgid "This contact is away"
+msgstr "此联系人已离开"
+
+#: dist/converse-no-dependencies.js:54719
+msgid "Groups"
+msgstr "群组"
+
+#: dist/converse-no-dependencies.js:54721
+msgid "My contacts"
+msgstr "我的联系人"
+
+#: dist/converse-no-dependencies.js:54723
+msgid "Pending contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31054
-msgid "Your message could not be sent"
+#: dist/converse-no-dependencies.js:54725
+msgid "Contact requests"
+msgstr "联系人请求"
+
+#: dist/converse-no-dependencies.js:54727
+msgid "Ungrouped"
+msgstr "未分组的"
+
+#: dist/converse-no-dependencies.js:54770
+msgid "Contact name"
+msgstr "联系人名称"
+
+#: dist/converse-no-dependencies.js:54773
+#, fuzzy
+msgid "Add a Contact"
+msgstr "添加联系人"
+
+#: dist/converse-no-dependencies.js:54774
+msgid "XMPP Address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31056
-msgid "We received an unencrypted message"
+#: dist/converse-no-dependencies.js:54776
+#, fuzzy
+msgid "name@example.org"
+msgstr "例如,user@example.org"
+
+#: dist/converse-no-dependencies.js:54777
+msgid "Add"
+msgstr "添加"
+
+#: dist/converse-no-dependencies.js:54887
+msgid "Filter"
+msgstr "筛选"
+
+#: dist/converse-no-dependencies.js:54888
+#, fuzzy
+msgid "Filter by contact name"
+msgstr "联系人名称"
+
+#: dist/converse-no-dependencies.js:54889
+msgid "Filter by group name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31058
-msgid "We received an unreadable encrypted message"
+#: dist/converse-no-dependencies.js:54890
+msgid "Filter by status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31084
+#: dist/converse-no-dependencies.js:54891
+msgid "Any"
+msgstr "任意"
+
+#: dist/converse-no-dependencies.js:54892
+msgid "Unread"
+msgstr "未读"
+
+#: dist/converse-no-dependencies.js:54894
+msgid "Chatty"
+msgstr "经常联系"
+
+#: dist/converse-no-dependencies.js:54897
+msgid "Extended Away"
+msgstr "长期离开"
+
+#: dist/converse-no-dependencies.js:55053
+#: dist/converse-no-dependencies.js:55095
 #, javascript-format
-msgid ""
-"Here are the fingerprints, please confirm them with %1$s, outside of this "
-"chat.\n"
-"\n"
-"Fingerprint for you, %2$s: %3$s\n"
-"\n"
-"Fingerprint for %1$s: %4$s\n"
-"\n"
-"If you have confirmed that the fingerprints match, click OK, otherwise click "
-"Cancel."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:31096
-msgid ""
-"You will be prompted to provide a security question and then an answer to "
-"that question.\n"
-"\n"
-"Your contact will then be prompted the same question and if they type the "
-"exact same answer (case sensitive), their identity will be verified."
+msgid "Click to remove %1$s as a contact"
+msgstr "按此删除%1$s为联络人"
+
+#: dist/converse-no-dependencies.js:55062
+#, javascript-format
+msgid "Click to accept the contact request from %1$s"
+msgstr "按此接受%1$s的联系人请求"
+
+#: dist/converse-no-dependencies.js:55063
+#, javascript-format
+msgid "Click to decline the contact request from %1$s"
+msgstr "按此拒绝%1$s的联系人请求"
+
+#: dist/converse-no-dependencies.js:55094
+#, fuzzy, javascript-format
+msgid "Click to chat with %1$s (JID: %2$s)"
+msgstr "按此与此联系人聊天"
+
+#: dist/converse-no-dependencies.js:55171
+msgid "Are you sure you want to decline this contact request?"
+msgstr "你确定要拒绝此联系人请求吗?"
+
+#: dist/converse-no-dependencies.js:55441
+msgid "Add a contact"
+msgstr "添加联系人"
+
+#: dist/converse-no-dependencies.js:56869
+#, fuzzy
+msgid "Name"
+msgstr "名称"
+
+#: dist/converse-no-dependencies.js:56873
+msgid "Room address (JID)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31097
-msgid "What is your security question?"
+#: dist/converse-no-dependencies.js:56877
+msgid "Description"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31100
-msgid "What is the answer to the security question?"
+#: dist/converse-no-dependencies.js:56883
+msgid "Topic"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31104
-msgid "Invalid authentication scheme provided"
+#: dist/converse-no-dependencies.js:56887
+msgid "Topic author"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31121
-msgid "Your messages are not encrypted. Click here to enable OTR encryption."
+#: dist/converse-no-dependencies.js:56893
+#, fuzzy
+msgid "Online users"
+msgstr "在线"
+
+#: dist/converse-no-dependencies.js:56897
+#: dist/converse-no-dependencies.js:57047
+msgid "Features"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31123
-msgid "Your messages are encrypted, but your contact has not been verified."
+#: dist/converse-no-dependencies.js:56901
+#: dist/converse-no-dependencies.js:57055
+msgid "Password protected"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31125
-msgid "Your messages are encrypted and your contact verified."
+#: dist/converse-no-dependencies.js:56903
+msgid "This room requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31127
-msgid ""
-"Your contact has closed their end of the private session, you should do the "
-"same"
+#: dist/converse-no-dependencies.js:56909
+msgid "No password required"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31141
-msgid "End encrypted conversation"
+#: dist/converse-no-dependencies.js:56911
+msgid "This room does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31142
-msgid "Refresh encrypted conversation"
+#: dist/converse-no-dependencies.js:56919
+msgid "This room is not publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31143
-msgid "Start encrypted conversation"
+#: dist/converse-no-dependencies.js:56927
+msgid "This room is publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31144
-msgid "Verify with fingerprints"
+#: dist/converse-no-dependencies.js:56933
+#: dist/converse-no-dependencies.js:57087
+msgid "Members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31145
-msgid "Verify with SMP"
+#: dist/converse-no-dependencies.js:56935
+msgid "this room is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31146
-msgid "What's this?"
+#: dist/converse-no-dependencies.js:56943
+msgid "Anyone can join this room"
 msgstr ""
 
-#. Translation aware constants
-#. ---------------------------
-#. We can only call the __ translation method *after* converse.js
-#. has been initialized and with it the i18n machinery. That's why
-#. we do it here in the "initialize" method and not at the top of
-#. the module.
-#: dist/converse-no-dependencies.js:31189
-msgid "unencrypted"
+#: dist/converse-no-dependencies.js:56949
+#: dist/converse-no-dependencies.js:57103
+msgid "Persistent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31190
-msgid "unverified"
+#: dist/converse-no-dependencies.js:56951
+msgid "This room persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31191
-msgid "verified"
+#: dist/converse-no-dependencies.js:56959
+msgid "This room will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31192
-msgid "finished"
+#: dist/converse-no-dependencies.js:56965
+#: dist/converse-no-dependencies.js:57119
+#, fuzzy
+msgid "Not anonymous"
+msgstr "此聊天室不是匿名的"
+
+#: dist/converse-no-dependencies.js:56967
+msgid "All other room occupants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31788
-#, javascript-format
-msgid "Sorry, there was an error while trying to add %1$s as a contact."
-msgstr "抱歉,添加%1$s为联系人时出现了问题。"
+#: dist/converse-no-dependencies.js:56975
+#: dist/converse-no-dependencies.js:57125
+msgid "Only moderators can see your XMPP username"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:31936
-msgid "This client does not allow presence subscriptions"
+#: dist/converse-no-dependencies.js:56983
+msgid "This room is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32028
-msgid "Click to hide these contacts"
-msgstr "按此隐藏联系人"
+#: dist/converse-no-dependencies.js:56989
+#: dist/converse-no-dependencies.js:57143
+msgid "Not moderated"
+msgstr ""
 
-#: dist/converse-no-dependencies.js:32112
-msgid "Don't have a chat account?"
+#: dist/converse-no-dependencies.js:56991
+msgid "This room is not being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32114
-msgid "Create an account"
+#: dist/converse-no-dependencies.js:56997
+#: dist/converse-no-dependencies.js:57151
+msgid "Message archiving"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32126
-msgid "Create your account"
+#: dist/converse-no-dependencies.js:56999
+#: dist/converse-no-dependencies.js:57149
+msgid "Messages are archived on the server"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32128
-msgid "Please enter the XMPP provider to register with:"
+#: dist/converse-no-dependencies.js:57053
+msgid "This groupchat requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32148
-msgid "Already have a chat account?"
+#: dist/converse-no-dependencies.js:57061
+msgid "This groupchat does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32150
-msgid "Log in here"
+#: dist/converse-no-dependencies.js:57063
+msgid "No password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32162
-msgid "Account Registration:"
+#: dist/converse-no-dependencies.js:57069
+msgid "This groupchat is not publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32170
-msgid "Register"
+#: dist/converse-no-dependencies.js:57077
+msgid "This groupchat is publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32174
-msgid "Choose a different provider"
+#: dist/converse-no-dependencies.js:57085
+msgid "this groupchat is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32186
-msgid "Hold tight, we're fetching the registration form…"
+#: dist/converse-no-dependencies.js:57093
+msgid "Anyone can join this groupchat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32321
-msgid " e.g. conversejs.org"
+#: dist/converse-no-dependencies.js:57101
+msgid "This groupchat persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32367
-msgid "Fetch registration form"
+#: dist/converse-no-dependencies.js:57109
+msgid "This groupchat will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32368
-msgid "Tip: A list of public XMPP providers is available"
+#: dist/converse-no-dependencies.js:57117
+msgid "All other groupchat participants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32369
-msgid "here"
+#: dist/converse-no-dependencies.js:57133
+msgid "This groupchat is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32417
-msgid "Sorry, we're unable to connect to your chosen provider."
+#: dist/converse-no-dependencies.js:57141
+msgid "This groupchat is not being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32433
-msgid ""
-"Sorry, the given provider does not support in band account registration. "
-"Please try with a different provider."
+#: dist/converse-no-dependencies.js:58006
+#, fuzzy
+msgid "XMPP Username:"
+msgstr "用户名"
+
+#: dist/converse-no-dependencies.js:58012
+msgid "Password:"
+msgstr "密码:"
+
+#: dist/converse-no-dependencies.js:58014
+msgid "password"
+msgstr "密码"
+
+#: dist/converse-no-dependencies.js:58022
+msgid "This is a trusted device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32457
-#, javascript-format
+#: dist/converse-no-dependencies.js:58024
 msgid ""
-"Something went wrong while establishing a connection with \"%1$s\". Are you "
-"sure it exists?"
+"To improve performance, we cache your data in this browser. Uncheck this box "
+"if this is a public computer or if you want your data to be deleted when you "
+"log out. It's important that you explicitly log out, otherwise not all "
+"cached data might be deleted."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32620
-msgid "Now logging you in"
+#: dist/converse-no-dependencies.js:58026
+#, fuzzy
+msgid "Log in"
+msgstr "登出"
+
+#: dist/converse-no-dependencies.js:58032
+msgid "Click here to log in anonymously"
+msgstr "按此以匿名登录"
+
+#: dist/converse-no-dependencies.js:58403
+msgid "Don't have a chat account?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32624
-msgid "Registered successfully"
+#: dist/converse-no-dependencies.js:58405
+msgid "Create an account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32733
-msgid ""
-"The provider rejected your registration attempt. Please check the values you "
-"entered for correctness."
+#: dist/converse-no-dependencies.js:58426
+msgid "Create your account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33149
-msgid "Click to toggle the rooms list"
+#: dist/converse-no-dependencies.js:58428
+msgid "Please enter the XMPP provider to register with:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33150
-msgid "Open Rooms"
+#: dist/converse-no-dependencies.js:58448
+msgid "Already have a chat account?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33194
-#, fuzzy, javascript-format
-msgid "Are you sure you want to leave the room %1$s?"
-msgstr "你确定要删除此联系人吗?"
+#: dist/converse-no-dependencies.js:58450
+msgid "Log in here"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:58471
+msgid "Account Registration:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:58479
+msgid "Register"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:58483
+msgid "Choose a different provider"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:58504
+msgid "Hold tight, we're fetching the registration form…"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:59643
+#: dist/converse-no-dependencies.js:59672
+msgid "Download"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:59662
+#, javascript-format
+msgid "Download: \"%1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:59685
+msgid "Download video file"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:59698
+msgid "Download audio file"
+msgstr "下载音频文件"
 
 #, fuzzy
 #~ msgid "Show hidden message"

File diff suppressed because it is too large
+ 0 - 0
locale/zh_TW/LC_MESSAGES/converse.json


File diff suppressed because it is too large
+ 1103 - 957
locale/zh_TW/LC_MESSAGES/converse.po


+ 79 - 44
mockup/chatbox.html

@@ -9,7 +9,7 @@
 </head>
 
 <body class="reset">
-    <div id="conversejs" class="fullscreen">
+    <div id="conversejs" class="fullscreen converse-fullscreen">
         <div class="sidebar"></div>
         <div class="converse-chatboxes row no-gutters">
             <div id="controlbox" class="chatbox">
@@ -42,15 +42,22 @@
                             <div class="message chat-info chat-error">This is an error message</div>
 
                             <div class="message chat-msg">
-                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                <div class="chat-msg-content">
-                                    <span class="chat-msg-heading">
-                                        <span class="chat-msg-author">Romeo Montague</span>
-                                        <span class="chat-msg-time">15:31</span>
-                                    </span>
-                                    <span class="chat-msg-text">
-                                        He jests at scars that never felt a wound.
+                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar chat-msg__avatar"></canvas>
+                                <div class="chat-msg__content">
+                                    <span class="chat-msg__heading">
+                                        <span class="chat-msg__author">Romeo Montague</span>
+                                        <span class="chat-msg__time">15:31</span>
                                     </span>
+                                    <div class="chat-msg__body">
+                                        <div class="chat-msg__message">
+                                            <span class="chat-msg__text">
+                                                He jests at scars that never felt a wound.
+                                            </span>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="chat-msg__actions">
+                                    <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
                                 </div>
                             </div>
 
@@ -60,59 +67,87 @@
                             </div>
 
                             <div class="message chat-msg">
-                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                <div class="chat-msg-content">
-                                    <span class="chat-msg-heading">
-                                        <span class="chat-msg-author">Romeo Montague</span>
-                                        <span class="chat-msg-time">15:31</span>
-                                    </span>
-                                    <span class="chat-msg-text">
-                                        But soft, what light through yonder window breaks?
+                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar chat-msg__avatar"></canvas>
+                                <div class="chat-msg__content">
+                                    <span class="chat-msg__heading">
+                                        <span class="chat-msg__author">Romeo Montague</span>
+                                        <span class="chat-msg__time">15:31</span>
                                     </span>
+                                    <div class="chat-msg__body">
+                                        <div class="chat-msg__message">
+                                            <span class="chat-msg__text">
+                                                But soft, what light through yonder window breaks?
+                                            </span>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="chat-msg__actions">
+                                    <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
                                 </div>
                             </div>
 
                             <div class="message chat-msg chat-msg-followup">
-                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                <div class="chat-msg-content">
-                                    <span class="chat-msg-heading">
-                                        <span class="chat-msg-author">Romeo Montague</span>
-                                        <span class="chat-msg-time">15:31</span>
-                                    </span>
-                                    <span class="chat-msg-text">
-                                        It is the east and Juliet is the sun!
+                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar chat-msg__avatar"></canvas>
+                                <div class="chat-msg__content">
+                                    <span class="chat-msg__heading">
+                                        <span class="chat-msg__author">Romeo Montague</span>
+                                        <span class="chat-msg__time">15:31</span>
                                     </span>
+                                    <div class="chat-msg__body">
+                                        <div class="chat-msg__message">
+                                            <span class="chat-msg__text">
+                                                It is the east and Juliet is the sun!
+                                            </span>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="chat-msg__actions">
+                                    <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
                                 </div>
                             </div>
 
                             <div class="message chat-msg chat-msg-followup">
-                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                <div class="chat-msg-content">
-                                    <span class="chat-msg-heading">
-                                        <span class="chat-msg-author">Romeo Montague</span>
-                                        <span class="chat-msg-time">15:31</span>
-                                    </span>
-                                    <span class="chat-msg-text">
-                                        Arise, fair sun, and kill the envious moon,
+                                <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar chat-msg__avatar"></canvas>
+                                <div class="chat-msg__content">
+                                    <span class="chat-msg__heading">
+                                        <span class="chat-msg__author">Romeo Montague</span>
+                                        <span class="chat-msg__time">15:31</span>
                                     </span>
+                                    <div class="chat-msg__body">
+                                        <div class="chat-msg__message">
+                                            <span class="chat-msg__text">
+                                                Arise, fair sun, and kill the envious moon,
+                                            </span>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="chat-msg__actions">
+                                    <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
                                 </div>
                             </div>
 
                             <div class="message chat-info chat-event">Romeo Montague is busy</div>
 
                             <div class="message chat-msg">
-                                <canvas height="36" width="36" class="avatar"></canvas>
-                                <div class="chat-msg-content">
-                                    <span class="chat-msg-heading">
-                                        <span class="chat-msg-author">Juliet Capulet</span>
-                                        <span class="chat-msg-time">15:31</span>
-                                    </span>
-                                    <span class="chat-msg-text">
-                                    O Romeo, Romeo! wherefore art thou Romeo?
-                                    Deny thy father and refuse thy name;
-                                    Or, if thou wilt not, be but sworn my love,
-                                    And I'll no longer be a Capulet.
+                                <canvas height="36" width="36" class="avatar chat-msg__avatar"></canvas>
+                                <div class="chat-msg__content">
+                                    <span class="chat-msg__heading">
+                                        <span class="chat-msg__author">Juliet Capulet</span>
+                                        <span class="chat-msg__time">15:31</span>
                                     </span>
+                                    <div class="chat-msg__body">
+                                        <div class="chat-msg__message">
+                                            <span class="chat-msg__text">
+                                            O Romeo, Romeo! wherefore art thou Romeo?
+                                            Deny thy father and refuse thy name;
+                                            Or, if thou wilt not, be but sworn my love,
+                                            And I'll no longer be a Capulet.
+                                            </span>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="chat-msg__actions">
+                                    <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
                                 </div>
                             </div>
                         </div>

+ 184 - 113
mockup/chatroom.html

@@ -44,21 +44,31 @@
                                 <div class="message chat-info chat-event" data-isodate="2018-04-36T18:07:36+02:00" data-join="&quot;Romeo Montague&quot;">
                                     Romeo Montague has entered the room</div>
 
-                                <div class="message chat-msg chat-action" data-isodate="2018-04-36T18:07:38+02:00">
-                                    <span class="chat-msg-heading">
-                                        <span class="chat-msg-author">**Romeo Montague</span>
-                                    </span>
-                                    <span class="chat-msg-text">looks around</span>
+                                <div class="message chat-msg chat-msg--action" data-isodate="2018-04-36T18:07:38+02:00">
+                                    <div class="chat-msg__content chat-msg__content--action">
+                                        <span class="chat-msg__heading">
+                                            <time timestamp="2018-12-29" class="chat-msg__time">15:29</time>
+                                            <span class="chat-msg__author">**Romeo Montague</span>
+                                        </span>
+                                        <span class="chat-msg__text">looks around</span>
+                                    </div>
                                 </div>
 
 								<div class="message chat-msg">
-                                    <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Romeo Montague <span class="badge badge-primary">Developer</span></span>
-                                            <span class="chat-msg-time">15:31</span>
-                                        </span>
-                                        <span class="chat-msg-text">He jests at scars that never felt a wound.</span>
+                                    <canvas class="avatar chat-msg__avatar" data-avatar="/mockup/images/romeo.jpg" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Romeo Montague <span class="badge badge-primary">Developer</span></span>
+                                            <span class="chat-msg__time">15:31</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <div class="chat-msg__text">He jests at scars that never felt a wound.</div>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
 
@@ -71,144 +81,205 @@
                                     Juliet has entered the room</div>
 
 								<div class="message chat-msg">
-                                    <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Romeo Montague</span>
-                                            <span class="chat-msg-time">19:36</span>
-                                        </span>
-                                        <span class="chat-msg-text">
-                                            But, soft! what light through yonder window breaks?
-                                        </span>
+                                    <canvas class="avatar chat-msg__avatar" data-avatar="/mockup/images/romeo.jpg" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Romeo Montague</span>
+                                            <span class="chat-msg__time">19:36</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <div class="chat-msg__text">But, soft! what light through yonder window breaks?</div>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
-								<div class="message chat-msg chat-msg-followup">
-                                    <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Romeo Montague</span>
-                                            <span class="chat-msg-time">19:36</span>
-                                        </span>
-                                        <span class="chat-msg-text">It is the east, and Juliet is the sun.</span>
+								<div class="message chat-msg chat-msg--followup">
+                                    <canvas class="avatar chat-msg__avatar" data-avatar="/mockup/images/romeo.jpg" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Romeo Montague</span>
+                                            <span class="chat-msg__time">19:36</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <div class="chat-msg__text">It is the east, and Juliet is the sun.</div>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
-								<div class="message chat-msg chat-msg-followup">
-                                    <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Romeo Montague</span>
-                                            <span class="chat-msg-time">19:36</span>
-                                        </span>
-                                        <span class="chat-msg-text">Arise, fair sun, and kill the envious moon, Who is already sick and pale with grief</span>
+								<div class="message chat-msg chat-msg--followup">
+                                    <canvas class="avatar chat-msg__avatar" data-avatar="/mockup/images/romeo.jpg" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Romeo Montague</span>
+                                            <span class="chat-msg__time">19:36</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <div class="chat-msg__text">Arise, fair sun, and kill the envious moon, Who is already sick and pale with grief</div>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
 
 								<div class="message chat-msg">
-                                    <canvas height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Juliet Capulet</span>
-                                            <span class="chat-msg-time">19:43</span>
-                                        </span>
-                                        <span class="chat-msg-text">
-                                            O Romeo, Romeo! wherefore art thou Romeo?
-                                            Deny thy father and refuse thy name;
-                                            Or, if thou wilt not, be but sworn my love,
-                                            And I'll no longer be a Capulet.
-                                        </span>
-                                        <div class="chat-msg-media"></div>
+                                    <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Juliet Capulet</span>
+                                            <span class="chat-msg__time">19:43</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <div class="chat-msg__text">
+                                                    O Romeo, Romeo! wherefore art thou Romeo?
+                                                    Deny thy father and refuse thy name;
+                                                    Or, if thou wilt not, be but sworn my love,
+                                                    And I'll no longer be a Capulet.
+                                                </div>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
 
                                 <div class="message chat-msg">
-                                    <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Romeo Montague</span>
-                                            <span class="chat-msg-time">19:36</span>
-                                        </span>
-                                        <span class="chat-msg-text">Uploading file: <strong>juliet.jpg</strong>, 120kb</span>
-                                        <progress value="50" max="100"/>
+                                    <canvas class="avatar chat-msg__avatar" data-avatar="/mockup/images/romeo.jpg" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Romeo Montague</span>
+                                            <span class="chat-msg__time">19:36</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <span class="chat-msg__text">Uploading file: <strong>juliet.jpg</strong>, 120kb</span>
+                                                <progress value="50" max="100"/>
+                                            </div>
+                                        </div>
                                     </div>
                                 </div>
 
 								<div class="message chat-msg">
-                                    <canvas height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Juliet Capulet</span>
-                                            <span class="chat-msg-time">19:45</span>
-                                        </span>
-                                        <span class="chat-msg-text"></span>
-                                        <div class="chat-msg-media">
-                                            <a href="https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb"
-                                               target="_blank" rel="noopener">
-                                                <img class="chat-image img-thumbnail" src="https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb"> 
-                                            </a>
+                                    <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Juliet Capulet</span>
+                                            <span class="chat-msg__time">19:45</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <div class="chat-msg__media">
+                                                    <a href="https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb"
+                                                    target="_blank" rel="noopener">
+                                                        <img class="chat-image img-thumbnail" src="https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb"> 
+                                                    </a>
+                                                </div>
+                                            </div>
                                         </div>
                                     </div>
 								</div>
 
                                 <div class="message chat-msg" data-isodate="2018-04-36T18:07:36+02:00" data-msgid="some-long-id">
-                                    <canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Romeo Montague</span>
-                                            <span class="chat-msg-time">19:36</span>
+                                    <canvas class="avatar chat-msg__avatar" data-avatar="/mockup/images/romeo.jpg" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <span class="chat-msg__heading">
+                                            <span class="chat-msg__author">Romeo Montague</span>
+                                            <span class="chat-msg__time">19:36</span>
                                         </span>
-                                        <div>
-                                            <span class="spoiler-hint">By a name</span>
-                                            <a class="badge badge-info spoiler-toggle" data-toggle-state="closed" href="#"><i class="fa fa-eye"></i>Show more</a>
-                                        </div>
-                                        <div class="chat-msg-text spoiler collapsed">
-                                            I know not how to tell thee who I am: My name, dear saint, is hateful to
-                                            myself, Because it is an enemy to thee. Had I it written, I would tear the word. 
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <div class="chat-msg__spoiler-hint">
+                                                    <span class="spoiler-hint">By a name</span>
+                                                    <a class="badge badge-info spoiler-toggle" data-toggle-state="closed" href="#"><i class="fa fa-eye"></i>Show more</a>
+                                                </div>
+                                                <div class="chat-msg__text spoiler collapsed">
+                                                    I know not how to tell thee who I am: My name, dear saint, is hateful to
+                                                    myself, Because it is an enemy to thee. Had I it written, I would tear the word. 
+                                                </div>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
                                         </div>
-                                        <div class="chat-msg-media"></div>
                                     </div>
                                 </div>
 
                                 <div class="message chat-info chat-event" data-isodate="2018-03-07T10:21:09+01:00" data-join="&quot;Mercutio&quot;">Mercutio has entered the room</div>
                                 <div class="message chat-info chat-event" data-isodate="2018-03-07T10:21:09+01:00" data-join="&quot;Mercutio&quot;">Topic set by Mercutio</div>
-                                <div class="message chat-info chat-topic" data-isodate="2018-03-07T10:21:09+01:00">Converse.js: The latest release is 3.3.4. Please be
-                                        patient if your questions aren't answered immediately. We're all in different timezones.</div>
+                                <div class="message chat-info chat-topic" data-isodate="2018-03-07T10:21:09+01:00">
+                                    Converse.js: The latest release is 3.3.4. Please be patient if your questions aren't answered immediately. We're all in different timezones.
+                                </div>
 
 								<div class="message chat-msg">
-                                    <canvas height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Mercutio</span>
-                                            <span class="chat-msg-time">19:49</span>
-                                        </span>
-                                        <span class="chat-msg-text">I mean, sir, in delay We waste our lights in vain, like lamps by day.</span>
+                                    <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Mercutio</span>
+                                            <span class="chat-msg__time">19:49</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <i title="This message has been edited" class="fa fa-edit chat-msg__edit-modal"></i>
+                                            <div class="chat-msg__message">
+                                                <span class="chat-msg__text">I mean, sir, in delay We waste our lights in vain, like lamps by day.</span>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
 
-								<div class="message chat-msg chat-msg-followup">
-                                    <canvas height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Mercutio</span>
-                                            <span class="chat-msg-time">19:49</span>
-                                        </span>
-                                        <span class="chat-msg-text">
-                                        Take our good meaning, for our judgment sits.
-                                        Five times in that ere once in our five wits.</span>
+								<div class="message chat-msg chat-msg--followup">
+                                    <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <div class="chat-msg__heading">
+                                            <span class="chat-msg__author">Mercutio</span>
+                                            <span class="chat-msg__time">19:49</span>
+                                        </div>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <span class="chat-msg__text">
+                                                Take our good meaning, for our judgment sits.
+                                                Five times in that ere once in our five wits.</span>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
 
-								<div class="message chat-msg chat-msg-followup">
-                                    <canvas height="36" width="36" class="avatar"></canvas>
-                                    <div class="chat-msg-content">
-                                        <span class="chat-msg-heading">
-                                            <span class="chat-msg-author">Mercutio</span>
-                                            <span class="chat-msg-time">19:49</span>
+								<div class="message chat-msg chat-msg--followup">
+                                    <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
+                                    <div class="chat-msg__content">
+                                        <span class="chat-msg__heading">
+                                            <span class="chat-msg__author">Mercutio</span>
+                                            <span class="chat-msg__time">19:49</span>
                                         </span>
-                                        <span class="chat-msg-text">
-                                        True, I talk of dreams, Which are the children of an idle brain, Begot of nothing but vain fantasy,
-                                        Which is as thin of substance as the air And more inconstant than the wind, who wooes
-                                        Even now the frozen bosom of the north, And, being anger'd, puffs away from thence,
-                                        Turning his face to the dew-dropping south.</span>
+                                        <div class="chat-msg__body">
+                                            <div class="chat-msg__message">
+                                                <span class="chat-msg__text">
+                                                True, I talk of dreams, Which are the children of an idle brain, Begot of nothing but vain fantasy,
+                                                Which is as thin of substance as the air And more inconstant than the wind, who wooes
+                                                Even now the frozen bosom of the north, And, being anger'd, puffs away from thence,
+                                                Turning his face to the dew-dropping south.</span>
+                                            </div>
+                                            <div class="chat-msg__actions">
+                                                <button class="chat-msg__action fa fa-pencil" title="Edit this message">&nbsp;</button>
+                                            </div>
+                                        </div>
                                     </div>
 								</div>
 

+ 47 - 47
mockup/user-panel.html

@@ -35,24 +35,24 @@
         <span class="w-100 controlbox-heading">Group Chats</span>
         <a class="chatbox-btn fa fa-users" title="Click to add a new room" data-toggle="modal" data-target="#chatroomsModal"></a>
     </div>
-    <div class="list-container rooms-list-container">
-        <div class="rooms-list items-list">
-            <div class="controlbox-padded list-item available-chatroom d-flex flex-row">
-                <a class="open-room available-room w-100" data-room-jid="public@conference.test.com" title="Click to open this room" href="chatroom.html">Capulet's orchard</a>
+    <div class="list-container items-list-container">
+        <div class="items-list">
+            <div class="controlbox-padded list-item available-chatroom d-flex flex-row open">
+                <a class="list-item-link open-room available-room w-100" data-room-jid="public@conference.test.com" title="Click to open this room" href="chatroom.html">Capulet's orchard</a>
                 <!-- <span class="badge badge-info msgs-indicator">1</span> -->
                 <a href="#"
-                   class="room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
+                   class="list-item-action room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
                    data-html="true" data-content="<b>Room Address (JID): </b><br>public@conference.test.com<br><b>Discussions: </b><br>Public discussions<br><b>Participants: </b>1<br><b>Features: </b><br>Non-anonymous">
                    &nbsp;</a>
-                <a href="#" class="fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
+                <a href="#" class="list-item-action fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
             </div>
             <div class="controlbox-padded list-item available-chatroom d-flex flex-row">
-                <a class="open-room available-room w-100" data-room-jid="team@conference.test.com" title="Click to open this room" href="chatroom.html">Juliet's Balcony</a>
+                <a class="list-item-link open-room available-room w-100" data-room-jid="team@conference.test.com" title="Click to open this room" href="chatroom.html">Juliet's Balcony</a>
                 <a href="#"
-                   class="room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
+                   class="list-item-action room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
                     data-html="true" data-content="<b>Room Address (JID): </b><br>public@conference.test.com<br><b>Discussions: </b><br>Public discussions<br><b>Participants: </b>1<br><b>Features: </b><br>Non-anonymous">
                     &nbsp;</a>
-                <a href="#" class="fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
+                <a href="#" class="list-item-action fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
             </div>
         </div>
     </div>
@@ -62,24 +62,24 @@
     <div class="d-flex controlbox-padded">
         <span class="w-100 controlbox-heading">Bookmarks</span>
     </div>
-    <div class="list-container rooms-list-container">
-        <div class="rooms-list items-list">
+    <div class="list-container items-list-container">
+        <div class="items-list">
             <div class="controlbox-padded list-item available-chatroom d-flex flex-row">
-                <a class="open-room available-room w-100" data-room-jid="public@conference.test.com" title="Click to open this room" href="chatroom.html">Capulet's orchard</a>
+                <a class="list-item-link open-room available-room w-100" data-room-jid="public@conference.test.com" title="Click to open this room" href="chatroom.html">Capulet's orchard</a>
                 <!-- <span class="badge badge-info msgs-indicator">1</span> -->
                 <a href="#"
-                   class="room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
+                   class="list-item-action room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
                    data-html="true" data-content="<b>Room Address (JID): </b><br>public@conference.test.com<br><b>Discussions: </b><br>Public discussions<br><b>Participants: </b>1<br><b>Features: </b><br>Non-anonymous">
                    &nbsp;</a>
-                <a href="#" class="fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
+                <a href="#" class="list-item-action fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
             </div>
             <div class="controlbox-padded list-item available-chatroom d-flex flex-row">
-                <a class="open-room available-room w-100" data-room-jid="team@conference.test.com" title="Click to open this room" href="chatroom.html">Juliet's Balcony</a>
+                <a class="list-item-link open-room available-room w-100" data-room-jid="team@conference.test.com" title="Click to open this room" href="chatroom.html">Juliet's Balcony</a>
                 <a href="#"
-                   class="room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
+                   class="list-item-action room-info fa fa-info-circle" data-container="body" data-toggle="popover" title="Room info"
                     data-html="true" data-content="<b>Room Address (JID): </b><br>public@conference.test.com<br><b>Discussions: </b><br>Public discussions<br><b>Participants: </b>1<br><b>Features: </b><br>Non-anonymous">
                     &nbsp;</a>
-                <a href="#" class="fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
+                <a href="#" class="list-item-action fa fa-bookmark" title="Click to bookmark this room">&nbsp;</a>
             </div>
         </div>
     </div>
@@ -108,13 +108,13 @@
         <div class="roster-group" id="xmpp-contact-requests">
             <a href="#" class="group-toggle controlbox-padded " title="Click to hide these contacts">
                 <span class="fa fa-caret-down"></span> Contact Requests</a>
-            <ul class="roster-group-contacts">
-                <li class=" controlbox-padded offline requesting-xmpp-contact d-flex">
+            <ul class="items-list roster-group-contacts">
+                <li class="list-item controlbox-padded offline requesting-xmpp-contact d-flex">
                     <span class="req-contact-name w-100">The Nurse</span>
                     <a class="accept-xmpp-request fa fa-check" title="Click here to accept this contact's request" href="#"></a>
                     <a class="decline-xmpp-request fa fa-times" title="Click here to decline this contact's request" href="#"></a>
                 </li>
-                <li class=" controlbox-padded offline requesting-xmpp-contact d-flex">
+                <li class="list-item controlbox-padded offline requesting-xmpp-contact d-flex">
                     <span class="req-contact-name w-100">Friar Laurence</span>
                     <a class="accept-xmpp-request fa fa-check" title="Click here to accept this contact's request" href="#"></a>
                     <a class="decline-xmpp-request fa fa-times" title="Click here to decline this contact's request" href="#"></a>
@@ -125,16 +125,16 @@
         <div class="roster-group" data-group="Colleagues">
             <a href="#" data-group="Colleagues" class="group-toggle controlbox-padded " title="Click to hide these contacts">
                 <span class="fa fa-caret-down"></span> Colleagues</a>
-            <ul>
-                <li class=" controlbox-padded away current-xmpp-contact d-flex">
+            <ul class="items-list roster-group-contacts">
+                <li class="list-item controlbox-padded away current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-circle-o" title="this contact is away"></span> Balthasar</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
-                <li class=" controlbox-padded dnd current-xmpp-contact d-flex">
+                <li class="list-item controlbox-padded dnd current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-minus-circle" title="This contact is busy"></span> Escalus, Prince of Verona</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
             </li>
         </div>
@@ -142,21 +142,21 @@
         <div class="roster-group" data-group="Family">
             <a href="#" data-group="Family" class="group-toggle controlbox-padded " title="Click to hide these contacts">
                 <span class="fa fa-caret-down"></span> Family</a>
-            <ul>
-                <li class=" controlbox-padded online current-xmpp-contact d-flex">
+            <ul class="items-list roster-group-contacts">
+                <li class="list-item controlbox-padded online current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-circle" title="This contact is online"></span> Benvolio Montague</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
-                <li class=" controlbox-padded offline current-xmpp-contact d-flex">
+                <li class="list-item controlbox-padded offline current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-times-circle" title="This contact is offline"></span> Montague</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
-                <li class=" controlbox-padded offline current-xmpp-contact d-flex">
+                <li class="list-item controlbox-padded offline current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-times-circle" title="This contact is offline"></span> Lady Montague</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
             </ul>
         </div>
@@ -164,11 +164,11 @@
         <div class="roster-group" data-group="Friends">
             <a href="#" data-group="Friends" class="group-toggle controlbox-padded " title="Click to hide these contacts">
                 <span class="fa fa-caret-down"></span> Friends</a>
-            <ul>
-                <li class=" controlbox-padded online current-xmpp-contact d-flex">
+            <ul class="items-list roster-group-contacts">
+                <li class="list-item controlbox-padded online current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-circle" title="This contact is online"></span> Mercutio</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
             </ul>
         </div>
@@ -176,21 +176,21 @@
         <div class="roster-group" data-group="Ungrouped">
             <a href="#" class="group-toggle controlbox-padded " title="Click to hide these contacts">
                 <span class="fa fa-caret-down"></span> Ungrouped</a>
-            <ul>
-                <li class=" controlbox-padded online current-xmpp-contact d-flex">
+            <ul class="items-list roster-group-contacts">
+                <li class="list-item controlbox-padded online current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-circle" title="This contact is online"></span> Gregory</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
-                <li class=" controlbox-padded online current-xmpp-contact d-flex">
+                <li class="list-item controlbox-padded online current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-circle" title="This contact is online"></span> Peter</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
-                <li class=" controlbox-padded online current-xmpp-contact d-flex">
+                <li class="list-item controlbox-padded online current-xmpp-contact d-flex">
                     <a class="open-chat w-100" title="Click to chat with this contact" href="chatbox.html">
                         <span class="fa fa-circle" title="This contact is online"></span> Sampson</a>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
             </ul>
         </div>
@@ -198,14 +198,14 @@
         <div class="roster-group" id="pending-xmpp-contacts">
             <a href="#" class="group-toggle controlbox-padded " title="Click to hide these contacts">
                 <span class="fa fa-caret-down"></span> Pending Contacts</a>
-            <ul>
-                <li class=" controlbox-padded offline pending-xmpp-contact d-flex">
+            <ul class="items-list roster-group-contacts">
+                <li class="list-item controlbox-padded offline pending-xmpp-contact d-flex">
                     <span class="pending-contact-name w-100">An Apothecary</span>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
-                <li class=" controlbox-padded offline pending-xmpp-contact d-flex">
+                <li class="list-item controlbox-padded offline pending-xmpp-contact d-flex">
                     <span class="pending-contact-name w-100">Abram</span>
-                    <a class="remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
+                    <a class="list-item-action remove-xmpp-contact fa fa-trash" title="Click to remove this contact" href="#"></a>
                 </li>
             </ul>
         </div>

+ 1 - 1
mockup/utils.js

@@ -3,7 +3,7 @@ const u = converse_utils;
 
 window.renderAvatars = function (el) {
     el = el || document;
-    const canvasses = el.querySelectorAll('canvas.avatar');
+    const canvasses = el.querySelectorAll('canvas.chat-msg__avatar');
     _.each(canvasses, (canvas_el) => {
         const avatar_url = canvas_el.getAttribute('data-avatar');
         if (!avatar_url) {

+ 10 - 1
sass/_bookmarks.scss

@@ -1,7 +1,16 @@
-#conversejs {
+#conversejs.fullscreen {
     #controlbox {
         #chatrooms {
             .bookmarks-list {
+                dl.rooms-list.bookmarks {
+                    dd.available-chatroom {
+                        a {
+                            &.open-room {
+                                width: 80%;
+                            }
+                        }
+                    }
+                }
             }
         }
     }

+ 5 - 35
sass/_chatbox.scss

@@ -67,9 +67,8 @@
         }
 
         .user-custom-message {
-            color: white;
+            color: lighten($chat-head-color, 50%);
             font-size: 75%;
-            font-style: italic;
             overflow: hidden;
             text-overflow: ellipsis;
             white-space: nowrap;
@@ -127,7 +126,7 @@
             background-color: $chat-head-color;
             box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
             z-index: 1;
-            overflow-y: scroll;
+            overflow-y: hidden;
             width: 100%;
 
             @media screen and (max-height: $mobile-landscape-height) {
@@ -467,21 +466,6 @@
             min-width: $overlayed-chat-width!important;
             width: $overlayed-chat-width;
         }
-
-        .chat-body {
-            .chat-message {
-                line-height: $line-height-large;
-                .chat-msg-author {
-                    line-height: $line-height-large;
-                }
-                .chat-msg-content {
-                    line-height: $line-height-large;
-                    .emojione {
-                        margin-bottom: -5px;
-                    }
-                }
-            }
-        }
     }
     .chatbox {
         form.sendXMPPMessage {
@@ -554,7 +538,7 @@
         font-size: $font-size-huge;
         padding: 0;
         .user-custom-message {
-            font-size: 50%;
+            font-size: 70%;
             height: auto;
             line-height: $line-height;
         }
@@ -579,7 +563,7 @@
 
         @include make-col-ready();
         @include media-breakpoint-up(md) {
-            @include make-col(9);
+            @include make-col(8);
         }
         @include media-breakpoint-up(lg) {
             @include make-col(9);
@@ -594,26 +578,12 @@
             height: $fullpage-chat-height;
             min-height: $fullpage-chat-height/2;
             width: $fullpage-chat-width;
+            overflow: hidden;
         }
         .chat-body {
             background-color: $chat-head-color;
             border-top-left-radius: $chatbox-border-radius;
             border-top-right-radius: $chatbox-border-radius;
-
-            .chat-message {
-                line-height: $line-height;
-                font-size: $font-size-small;
-                .chat-msg-author {
-                    line-height: $line-height;
-                }
-                .chat-msg-content {
-                    line-height: $line-height;
-                    .emojione {
-                        height: $line-height;
-                        margin-bottom: -$line-height/4;
-                    }
-                }
-            }
         }
         .chat-content {
             border-top-left-radius: $chatbox-border-radius;

+ 6 - 8
sass/_chatrooms.scss

@@ -119,8 +119,12 @@
                 .mentioned {
                     font-weight: bold;
                 }
-                .disconnect-msg {
-                    padding: 2em 2em 0 2em;
+                .disconnect-container {
+                    margin: 1em;
+                    width: 100%;
+                    h3.disconnect-msg {
+                        padding-bottom: 1em;
+                    }
                 }
                 .chat-area {
                     display: flex;
@@ -245,12 +249,6 @@
                         font-size: 90%;
                         color: $error-color;
                     }
-                    .chatroom-form {
-                        label,
-                        input[type=text] {
-                            display: block;
-                        }
-                    }
                     input[type=button],
                     input[type=submit] {
                         margin: 0 0.5em;

+ 70 - 59
sass/_controlbox.scss

@@ -20,7 +20,9 @@
         }
     }
 
-    .set-xmpp-status, .xmpp-status, .roster-contacts {
+    .set-xmpp-status,
+    .xmpp-status,
+    .roster-contacts {
         .fa-circle {
             color: $green;
         }
@@ -30,9 +32,7 @@
         .fa-dot-circle-o {
             color: $orange,
         }
-        .fa-circle-o {
-            color: $subdued-color;
-        }
+        .fa-circle-o,
         .fa-times-circle {
             color: $subdued-color;
         }
@@ -350,60 +350,6 @@
     }
 }
 
-@include media-breakpoint-down(sm) {
-
-    #conversejs:not(.converse-embedded)  {
-        left: 0;
-        right: 0;
-        padding-left: env(safe-area-inset-left);
-        padding-right: env(safe-area-inset-right);
-
-        .converse-chatboxes {
-            margin: 0 !important;
-            flex-direction: row !important;
-            justify-content: space-between;
-
-            .converse-chatroom {
-                font-size: 14px;
-            }
-
-            .chatbox { 
-                .box-flyout {
-                    margin-left: 15px; // Counteracts Bootstrap margins, but
-                                       // not clear why needed...
-                    left: 0;
-                    bottom: 0;
-                    border-radius: 0;
-                    width: 100vw !important;
-                    height: 100vh !important;
-                }
-            }
-
-            #controlbox {
-                width: 100vw !important;
-                .box-flyout {
-                    width: 100vw !important;
-                    height: 100vh !important;
-                    margin-left: 30px;
-                }
-                .sidebar {
-                    display: block;
-                }
-            }
-
-            &.sidebar-open {
-                .chatbox:not(#controlbox) {
-                    display: none;
-                }
-                #controlbox {
-                    .controlbox-pane {
-                        display: block;
-                    }
-                }
-            }
-        }
-    }
-}
 
 #conversejs.converse-overlayed {
     #controlbox {
@@ -461,8 +407,9 @@
 #conversejs.converse-mobile {
     #controlbox {
         @include make-col-ready();
+
         @include media-breakpoint-up(md) {
-            @include make-col(3);
+            @include make-col(4);
         }
         @include media-breakpoint-up(lg) {
             @include make-col(3);
@@ -563,3 +510,67 @@
         }
     }
 }
+
+@include media-breakpoint-down(sm) {
+
+    #conversejs:not(.converse-embedded)  {
+        left: 0;
+        right: 0;
+        padding-left: env(safe-area-inset-left);
+        padding-right: env(safe-area-inset-right);
+
+        .converse-chatboxes {
+            margin: 0 !important;
+            flex-direction: row !important;
+            justify-content: space-between;
+
+            .converse-chatroom {
+                font-size: 14px;
+            }
+
+            .chatbox { 
+                .box-flyout {
+                    margin-left: 15px; // Counteracts Bootstrap margins, but
+                                       // not clear why needed...
+                    left: 0;
+                    bottom: 0;
+                    border-radius: 0;
+                    width: 100vw !important;
+                    height: 100vh !important;
+                }
+            }
+
+            #controlbox {
+                width: 100vw !important;
+                .box-flyout {
+                    width: 100vw !important;
+                    height: 100vh !important;
+                }
+                .sidebar {
+                    display: block;
+                }
+            }
+
+            &.sidebar-open {
+                .chatbox:not(#controlbox) {
+                    display: none;
+                }
+                #controlbox {
+                    .controlbox-pane {
+                        display: block;
+                    }
+                }
+            }
+        }
+    }
+    #conversejs.converse-overlayed {
+        .converse-chatboxes {
+            .chatbox { 
+                .box-flyout {
+                    margin-left: 30px; // Counteracts Bootstrap margins, but
+                                       // not clear why needed...
+                }
+            }
+        }
+    }
+}

+ 1 - 1
sass/_core.scss

@@ -71,7 +71,7 @@ body.reset {
     &.converse-mobile {
         .converse-chatboxes {
             width: 100vw;
-            right: 15px; // Hack due to padding added by bootstrap
+            left: -15px; // Hack due to padding added by bootstrap
         }
     }
     &.converse-overlayed {

+ 118 - 0
sass/_lists.scss

@@ -0,0 +1,118 @@
+#conversejs {
+    .list-container {
+        text-align: left;
+        padding: 0.3em 0;
+
+        .list-toggle {
+            font-family: $heading-font; 
+            display: block;
+            color: $text-color;
+            padding: 0 0 0.5rem 0;
+            &:hover {
+                color: $dark-gray-color;
+            }
+        }
+    }
+
+    .items-list {
+        text-align: left;
+
+        .list-item {
+            border: none;
+            clear: both;
+            color: $text-color;
+            display: block;
+            height: 2em;
+            overflow: hidden;
+            padding-top: 0.5em;
+            text-shadow: 0 1px 0 $text-shadow-color;
+            word-wrap: break-word;
+
+            .list-item-link {
+                &:hover {
+                    color: $dark-link-color;
+                }
+                font-size: $font-size;
+                line-height: $font-size;
+                padding-right: 0.5em;
+                overflow: hidden;
+                white-space: nowrap;
+                text-overflow: ellipsis;
+            }
+
+            .list-item-action {
+                opacity: 0;
+                font-size: $font-size-tiny;
+                padding: 0;
+                margin: 0 0 0 0.4em;
+                width: 1.6em;
+                &:before {
+                    font-size: $font-size;
+                }
+                &.button-on {
+                    color: $link-color;
+                    &:hover {
+                        color: $dark-link-color;
+                    }
+                }
+                color: $subdued-color;
+                &:hover {
+                    color: $gray-color;
+                    opacity: 1;
+                }
+            }
+
+            &.open {
+                background-color: $controlbox-head-color;
+                &:hover {
+                    background-color: $controlbox-head-color !important;
+                }
+                a {
+                    color: white;
+                }
+                .list-item-link {
+                    &:hover {
+                        color: white;
+                    }
+                }
+                .list-item-action {
+                    color: lighten($lightest-blue, 25%);
+                    &:hover {
+                        color: white;
+                    }
+                }
+                .fa-circle {
+                    color: lighten($green, 25%);
+                }
+                .fa-minus-circle {
+                    color: lighten($red, 15%);
+                }
+                .fa-dot-circle-o {
+                    color: lighten($orange, 15%);
+                }
+                .fa-circle-o,
+                .fa-times-circle {
+                    color: lighten($subdued-color, 25%);
+                }
+            }
+
+            &:hover {
+                background-color: lighten($controlbox-head-color, 45%);
+                .fa {
+                    opacity: 1;
+                }
+            }
+            &.unread-msgs {
+                .msgs-indicator {
+                    border-radius: 10%;
+                    opacity: 1;
+                }
+                .available-room,
+                .open-room {
+                    width: 100%;
+                    font-weight: bold;
+                }
+            }
+        }
+    }
+}

+ 93 - 21
sass/_messages.scss

@@ -56,7 +56,7 @@
             max-height: 15em;
             max-width: 100%;
         }
-        &.chat-action {
+        &.chat-msg--action {
             font-style: italic;
         }
 
@@ -72,6 +72,19 @@
             }
             &:hover {
                 background-color: rgba(0, 0, 0, 0.035);
+                .chat-msg__actions {
+                    .chat-msg__action {
+                        opacity: 1;
+                    }
+                }
+            }
+            &.correcting {
+                &.groupchat  {
+                    background-color: lighten($chatroom-head-color, 35%);
+                }
+                &:not(.groupchat) {
+                    background-color: lighten($chat-head-color, 50%);
+                }
             }
 
             .spoiler {
@@ -91,19 +104,46 @@
                     whitespace: nowrap;
                 }
             }
-            .chat-msg-content {
+
+            .chat-msg__content {
+                display: flex;
+                flex-direction: column;
+                justify-content: space-between;
+                align-items: stretch;
                 margin-left: 0.5rem;
                 width: 100%;
             }
+            .chat-msg__content--action {
+                margin-left: 0;
+            }
+
+            .chat-msg__body {
+                display: flex;
+                flex-direction: row;
+                justify-content: space-between;
+                width: 100%;
+            }
+
+            .chat-msg__message {
+                display: flex;
+                flex-direction: column;
+                width: 100%;
+            }
+
+            .chat-msg__edit-modal {
+                cursor: pointer;
+                padding-right: 0.5em;
+            }
             &.headline {
-                .chat-msg-content {
+                .chat-msg__body {
                     margin-left: 0;
                 }
             }
 
-            .chat-msg-text {
+            .chat-msg__text {
                 padding: 0;
                 color: $message-text-color;
+                width: 100%;
                 a {
                     word-wrap: break-word;
                     word-break: break-all;
@@ -113,8 +153,9 @@
                 }
             }
             
-            .chat-msg-media {
+            .chat-msg__media {
                 margin-top: 0.25rem;
+                word-break: break-all;
                 a {
                     word-wrap: break-word;
                 }
@@ -123,19 +164,37 @@
                 }
             }
 
-            .avatar {
+            .chat-msg__actions {
+                .chat-msg__action {
+                    height: $message-font-size;
+                    font-size: $message-font-size;
+                    padding: 0;
+                    border: none;
+                    opacity: 0;
+                    background: transparent;
+                    cursor: pointer;
+                    &:focus {
+                        display: block;
+                    }
+                }
+            }
+
+            .chat-msg__avatar {
                 margin-top: 0.5em;
                 height: 36px;
                 vertical-align: middle;
                 width: 36px;
             }
-            .chat-msg-heading {
+
+            .chat-msg__heading {
+                width: 100%;
                 margin-top: 0.5em;
                 padding-right: 0.25rem;
                 padding-bottom: 0.25rem;
                 display: block;
 
-                .chat-msg-author {
+                .chat-msg__author {
+                    white-space: nowrap;
                     font-family: $heading-font; 
                     font-size: 115%;
                     .badge {
@@ -143,26 +202,39 @@
                         font-family: $normal_font;
                     }
                 }
-                .chat-msg-time {
+                .chat-msg__time {
                     padding-left: 0.25em;
                     color: lighten($text-color, 15%);
                 }
             }
-            &.chat-action {
-                display: block;
-
-                .chat-msg-heading {
-                    float: left;
+            &.chat-msg--action {
+                .chat-msg__content {
+                    flex-wrap: wrap;
+                    flex-direction: row;
+                    justify-content: flex-start;
+                }
+                .chat-msg__text {
+                    width: auto;
+                }
+                .chat-msg__heading {
                     margin-top: 0;
                     padding-bottom: 0;
+                    width: auto;
+                }
+                .chat-msg__author {
+                    font-size: $message-font-size;
+                }
+                .chat-msg__time {
+                    margin-left: 0;
                 }
             }
-            &.chat-msg-followup {
-                .chat-msg-heading,
-                .avatar {
+
+            &.chat-msg--followup {
+                .chat-msg__heading,
+                .chat-msg__avatar {
                     display: none;
                 }
-                .chat-msg-content {
+                .chat-msg__content {
                     margin-left: 2.75rem;
                 }
             }
@@ -183,8 +255,8 @@
 #conversejs.converse-overlayed {
     .message {
         &.chat-msg {
-            &.chat-msg-followup {
-                .chat-msg-content {
+            &.chat-msg--followup {
+                .chat-msg__body {
                     margin-left: 0;
                 }
             }
@@ -196,7 +268,7 @@
     #conversejs:not(.converse-embedded)  {
         .message {
             &.chat-msg {
-                .chat-msg-author {
+                .chat-msg__author {
                     white-space: normal;
                 }
             }

+ 0 - 105
sass/_roomslist.scss

@@ -1,105 +0,0 @@
-#conversejs {
-    .list-container {
-        text-align: left;
-        padding: 0.3em 0;
-
-        .rooms-toggle {
-            font-family: $heading-font; 
-            display: block;
-            color: $text-color;
-            padding: 0 0 0.5rem 0;
-            &:hover {
-                color: $dark-gray-color;
-            }
-        }
-        .items-list {
-            text-align: left;
-
-            .list-item {
-                border: none;
-                clear: both;
-                color: $text-color;
-                display: block;
-                height: 2em;
-                overflow: hidden;
-                padding-top: 0.5em;
-                text-shadow: 0 1px 0 $text-shadow-color;
-                word-wrap: break-word;
-            }
-
-            .available-chatroom,
-            .open-headline,
-            .open-chatroom {
-                &:hover {
-                    background-color: lighten($controlbox-head-color, 45%);
-                    a.add-bookmark,
-                    a.room-info {
-                        display: block !important;
-                    }
-                }
-                &.unread-msgs {
-                    .msgs-indicator {
-                        border-radius: 10%;
-                        opacity: 1;
-                    }
-                    .available-room,
-                    .open-room {
-                        width: 100%;
-                        font-weight: bold;
-                    }
-                }
-                a {
-                    &:hover {
-                        color: $dark-link-color;
-                    }
-                    &.add-bookmark,
-                    &.room-info {
-                        display: none;
-                        &:before {
-                            font-size: 15px;
-                        }
-                    }
-                    &.open-room {
-                        width: 68%;
-                        float: left;
-                        overflow: hidden;
-                        text-overflow: ellipsis;
-                        white-space: nowrap;
-                        padding-right: 0.5em;
-                    }
-                    &.available-room {
-                        width: 85%;
-                    }
-                }
-                .add-bookmark,
-                .remove-bookmark {
-                    &.button-on {
-                        color: $link-color;
-                        &:hover {
-                            color: $dark-link-color;
-                        }
-                    }
-                    color: $subdued-color;
-                }
-            }
-        }
-    }
-}
-
-#conversejs.fullscreen {
-    #controlbox {
-        #chatrooms {
-            .bookmarks-list {
-                dl.rooms-list.bookmarks {
-                    dd.available-chatroom {
-                        a {
-                            &.open-room {
-                                width: 80%;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}

+ 1 - 33
sass/_roster.scss

@@ -72,17 +72,6 @@
             }
 
             li {
-                border: none;
-                clear: both;
-                color: $text-color;
-                display: block;
-                overflow-y: hidden;
-                text-shadow: 0 1px 0 $text-shadow-color;
-                line-height: $font-size;
-                width: 100%;
-                height: 2em;
-                padding-top: 0.5em;
-
                 &.requesting-xmpp-contact {
                     a {
                         line-height: $line-height;
@@ -94,14 +83,6 @@
                         padding: 0 0.2em 0 0;
                     }
                 }
-                a {
-                    &:hover {
-                        color: $dark-link-color;
-                    }
-                    .fa:hover {
-                        color: white;
-                    }
-                }
 
                 .open-chat {
                     margin: 0;
@@ -128,7 +109,7 @@
                         text-overflow: ellipsis;
                         padding: 0;
                         margin: 0;
-                        max-width: 80%;
+                        max-width: 90%;
                         float: none;
                         height: 100%;
                         &.unread-msgs {
@@ -156,22 +137,9 @@
                     white-space: nowrap;
                     text-overflow: ellipsis;
                 }
-                span {
-                    padding: 0;
-                }
                 .decline-xmpp-request {
                     margin-left: 5px;
                 }
-                .remove-xmpp-contact {
-                    font-size: $font-size-tiny;
-                    margin: 0;
-                    padding: 0;
-                    width: 2em;
-                    display: none;
-                    &:before {
-                        font-size: $font-size;
-                    }
-                }
                 &:hover {
                     background-color: lighten($controlbox-head-color, 45%);
                     .remove-xmpp-contact {

+ 1 - 1
sass/converse.scss

@@ -43,8 +43,8 @@
 @import "profile";
 @import "chatbox";
 @import "controlbox";
-@import "roomslist";
 @import "roster";
+@import "lists";
 @import "chatrooms";
 @import "headline";
 @import "messages";

+ 16 - 8
spec/bookmarks.js

@@ -518,20 +518,28 @@
                     _converse.connection._dataRecv(test_utils.createRequest(stanza));
 
                     test_utils.waitUntil(function () {
-                        return $('#chatrooms div.bookmarks.rooms-list .room-item').length;
+                        return document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length;
                     }, 300).then(function () {
-                        expect($('#chatrooms div.bookmarks.rooms-list .room-item').length).toBe(4);
-                        expect($('#chatrooms div.bookmarks.rooms-list .room-item a').text().trim()).toBe(
-                            "1st Bookmark  Another room  Bookmark with a very very long name that will be shortened  The Play's the Thing")
+                        expect(document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length).toBe(4);
+                        const els = document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link');
+                        expect(els[0].textContent).toBe("1st Bookmark");
+                        expect(els[1].textContent).toBe("Another room");
+                        expect(els[2].textContent).toBe("Bookmark with a very very long name that will be shortened");
+                        expect(els[3].textContent).toBe("The Play's the Thing");
 
                         spyOn(window, 'confirm').and.returnValue(true);
-                        $('#chatrooms .bookmarks.rooms-list .room-item:nth-child(2) a:nth-child(2)')[0].click();
+                        document.querySelector('#chatrooms .bookmarks.rooms-list .room-item:nth-child(2) a:nth-child(2)').click();
                         expect(window.confirm).toHaveBeenCalled();
                         return test_utils.waitUntil(function () {
-                            return $('#chatrooms .bookmarks.rooms-list .room-item a').text().trim() ===
-                                "1st Bookmark  Bookmark with a very very long name that will be shortened  The Play's the Thing";
+                            return document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length === 3;
                         }, 300)
-                    }).then(done);
+                    }).then(() => {
+                        const els = document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link');
+                        expect(els[0].textContent).toBe("1st Bookmark");
+                        expect(els[1].textContent).toBe("Bookmark with a very very long name that will be shortened");
+                        expect(els[2].textContent).toBe("The Play's the Thing");
+                        done();
+                    }).catch(_.partial(console.error, _));
                 });
             }));
 

+ 24 - 32
spec/chatbox.js

@@ -76,33 +76,33 @@
                     test_utils.waitUntil(function () {
                         return u.isVisible(view.el);
                     }).then(function () {
-                        expect(view.el.querySelectorAll('.chat-action').length).toBe(1);
-                        expect(_.includes(view.el.querySelector('.chat-msg-author').textContent, '**Max Frankfurter')).toBeTruthy();
-                        expect($(view.el).find('.chat-msg-text').text()).toBe(' is tired');
+                        expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(1);
+                        expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, '**Max Frankfurter')).toBeTruthy();
+                        expect($(view.el).find('.chat-msg__text').text()).toBe(' is tired');
 
                         message = '/me is as well';
                         test_utils.sendMessage(view, message);
-                        expect(view.el.querySelectorAll('.chat-action').length).toBe(2);
+                        expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(2);
 
-                        return test_utils.waitUntil(() => $(view.el).find('.chat-msg-author:last').text() === '**Max Mustermann');
+                        return test_utils.waitUntil(() => $(view.el).find('.chat-msg__author:last').text().trim() === '**Max Mustermann');
                     }).then(function () {
-                        expect($(view.el).find('.chat-msg-text:last').text()).toBe(' is as well');
-                        expect($(view.el).find('.chat-msg:last').hasClass('chat-msg-followup')).toBe(false);
+                        expect($(view.el).find('.chat-msg__text:last').text()).toBe(' is as well');
+                        expect($(view.el).find('.chat-msg:last').hasClass('chat-msg--followup')).toBe(false);
 
                         // Check that /me messages after a normal message don't
-                        // get the 'chat-msg-followup' class.
+                        // get the 'chat-msg--followup' class.
                         message = 'This a normal message';
                         test_utils.sendMessage(view, message);
                         let message_el = view.el.querySelector('.message:last-child');
-                        expect(u.hasClass('chat-msg-followup', message_el)).toBeFalsy();
+                        expect(u.hasClass('chat-msg--followup', message_el)).toBeFalsy();
 
                         message = '/me wrote a 3rd person message';
                         test_utils.sendMessage(view, message);
                         message_el = view.el.querySelector('.message:last-child');
-                        expect(view.el.querySelectorAll('.chat-action').length).toBe(3);
-                        expect($(view.el).find('.chat-msg-text:last').text()).toBe(' wrote a 3rd person message');
-                        expect($(view.el).find('.chat-msg-author:last').is(':visible')).toBeTruthy();
-                        expect(u.hasClass('chat-msg-followup', message_el)).toBeFalsy();
+                        expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(3);
+                        expect($(view.el).find('.chat-msg__text:last').text()).toBe(' wrote a 3rd person message');
+                        expect($(view.el).find('.chat-msg__author:last').is(':visible')).toBeTruthy();
+                        expect(u.hasClass('chat-msg--followup', message_el)).toBeFalsy();
                         done();
                     });
                 });
@@ -635,7 +635,7 @@
                             spyOn(_converse.connection, 'send');
                             spyOn(_converse, 'emit');
                             view.keyPressed({
-                                target: $(view.el).find('textarea.chat-textarea'),
+                                target: view.el.querySelector('textarea.chat-textarea'),
                                 keyCode: 1
                             });
                             expect(view.model.get('chat_state')).toBe('composing');
@@ -648,7 +648,7 @@
 
                             // The notification is not sent again
                             view.keyPressed({
-                                target: $(view.el).find('textarea.chat-textarea'),
+                                target: view.el.querySelector('textarea.chat-textarea'),
                                 keyCode: 1
                             });
                             expect(view.model.get('chat_state')).toBe('composing');
@@ -776,7 +776,7 @@
                             spyOn(view, 'setChatState').and.callThrough();
                             expect(view.model.get('chat_state')).toBe('active');
                             view.keyPressed({
-                                target: $(view.el).find('textarea.chat-textarea'),
+                                target: view.el.querySelector('textarea.chat-textarea'),
                                 keyCode: 1
                             });
                             expect(view.model.get('chat_state')).toBe('composing');
@@ -803,14 +803,14 @@
                             // out if the user simply types longer than the
                             // timeout.
                             view.keyPressed({
-                                target: $(view.el).find('textarea.chat-textarea'),
+                                target: view.el.querySelector('textarea.chat-textarea'),
                                 keyCode: 1
                             });
                             expect(view.setChatState).toHaveBeenCalled();
                             expect(view.model.get('chat_state')).toBe('composing');
 
                             view.keyPressed({
-                                target: $(view.el).find('textarea.chat-textarea'),
+                                target: view.el.querySelector('textarea.chat-textarea'),
                                 keyCode: 1
                             });
                             expect(view.model.get('chat_state')).toBe('composing');
@@ -921,33 +921,25 @@
                             contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                             test_utils.openChatBoxFor(_converse, contact_jid);
                             view = _converse.chatboxviews.get(contact_jid);
-                            return test_utils.waitUntil(function () {
-                                return view.model.get('chat_state') === 'active';
-                            }, 500);
+                            return test_utils.waitUntil(() => view.model.get('chat_state') === 'active', 500);
                         }).then(function () {
                             console.log('chat_state set to active');
                             view = _converse.chatboxviews.get(contact_jid);
                             expect(view.model.get('chat_state')).toBe('active');
                             view.keyPressed({
-                                target: $(view.el).find('textarea.chat-textarea'),
+                                target: view.el.querySelector('textarea.chat-textarea'),
                                 keyCode: 1
                             });
-                            return test_utils.waitUntil(function () {
-                                return view.model.get('chat_state') === 'composing';
-                            }, 500);
+                            return test_utils.waitUntil(() => view.model.get('chat_state') === 'composing', 500);
                         }).then(function () {
                             console.log('chat_state set to composing');
                             view = _converse.chatboxviews.get(contact_jid);
                             expect(view.model.get('chat_state')).toBe('composing');
                             spyOn(_converse.connection, 'send');
-                            return test_utils.waitUntil(function () {
-                                return view.model.get('chat_state') === 'paused';
-                            }, 500);
+                            return test_utils.waitUntil(() => view.model.get('chat_state') === 'paused', 500);
                         }).then(function () {
                             console.log('chat_state set to paused');
-                            return test_utils.waitUntil(function () {
-                                return view.model.get('chat_state') === 'inactive';
-                            }, 500);
+                            return test_utils.waitUntil(() => view.model.get('chat_state') === 'inactive', 500);
                         }).then(function () {
                             console.log('chat_state set to inactive');
                             expect(_converse.connection.send).toHaveBeenCalled();
@@ -1635,7 +1627,7 @@
                         return $(view.el).find('.chat-content').find('.chat-msg').length;
                     }, 1000).then(function () {
                         expect(view.model.sendMessage).toHaveBeenCalled();
-                        var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg-text');
+                        var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text');
                         expect(msg.html()).toEqual(
                             '<a target="_blank" rel="noopener" href="https://www.openstreetmap.org/?mlat=37.786971&amp;'+
                             'mlon=-122.399677#map=18/37.786971/-122.399677">https://www.openstreetmap.org/?mlat=37.7869'+

+ 120 - 113
spec/chatroom.js

@@ -177,7 +177,7 @@
                             'membersonly': true,
                             'persistentroom': true,
                             'publicroom': true,
-                            'roomdesc': 'Welcome to this room',
+                            'roomdesc': 'Welcome to this groupchat',
                             'whois': 'anyone'
                         }
                     });
@@ -262,7 +262,7 @@
                             sent_stanza = sent_IQ_els.pop();
                         }
                         expect(sizzle('field[var="muc#roomconfig_roomname"] value', sent_stanza).pop().textContent).toBe('Room');
-                        expect(sizzle('field[var="muc#roomconfig_roomdesc"] value', sent_stanza).pop().textContent).toBe('Welcome to this room');
+                        expect(sizzle('field[var="muc#roomconfig_roomdesc"] value', sent_stanza).pop().textContent).toBe('Welcome to this groupchat');
                         expect(sizzle('field[var="muc#roomconfig_persistentroom"] value', sent_stanza).pop().textContent).toBe('1');
                         expect(sizzle('field[var="muc#roomconfig_publicroom"] value ', sent_stanza).pop().textContent).toBe('1');
                         expect(sizzle('field[var="muc#roomconfig_changesubject"] value', sent_stanza).pop().textContent).toBe('0');
@@ -390,7 +390,7 @@
 
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
                     var info_text = view.el.querySelector('.chat-content .chat-info').textContent;
-                    expect(info_text).toBe('A new room has been created');
+                    expect(info_text).toBe('A new groupchat has been created');
 
                     // An instant room is created by saving the default configuratoin.
                     //
@@ -453,7 +453,7 @@
                     }).up()
                     .c('status', {code: '110'});
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
-                expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has entered the room");
+                expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has entered the groupchat");
 
                 presence = $pres({
                         to: 'dummy@localhost/_converse.js-29092160',
@@ -467,7 +467,7 @@
                     });
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(2);
-                expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the room");
+                expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the groupchat");
 
                 // Add another entrant, otherwise the above message will be
                 // collapsed if "newguy" leaves immediately again
@@ -483,7 +483,7 @@
                     });
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(3);
-                expect($chat_content.find('div.chat-info:last').html()).toBe("newgirl has entered the room");
+                expect($chat_content.find('div.chat-info:last').html()).toBe("newgirl has entered the groupchat");
 
                 // Don't show duplicate join messages
                 presence = $pres({
@@ -525,7 +525,7 @@
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content.find('div.chat-info').length).toBe(4);
                 expect($chat_content.find('div.chat-info:last').html()).toBe(
-                    'newguy has left the room. '+
+                    'newguy has left the groupchat. '+
                     '"Disconnected: Replaced by new connection"');
 
                 // When the user immediately joins again, we collapse the
@@ -542,7 +542,7 @@
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content.find('div.chat-info').length).toBe(4);
                 var $msg_el = $chat_content.find('div.chat-info:last');
-                expect($msg_el.html()).toBe("newguy has left and re-entered the room");
+                expect($msg_el.html()).toBe("newguy has left and re-entered the groupchat");
                 expect($msg_el.data('leavejoin')).toBe('"newguy"');
 
                 presence = $pres({
@@ -559,7 +559,7 @@
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content.find('div.chat-info').length).toBe(4);
                 $msg_el = $chat_content.find('div.chat-info:last');
-                expect($msg_el.html()).toBe('newguy has left the room');
+                expect($msg_el.html()).toBe('newguy has left the groupchat');
                 expect($msg_el.data('leave')).toBe('"newguy"');
 
                 presence = $pres({
@@ -574,7 +574,7 @@
                     });
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(5);
-                expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the room");
+                expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the groupchat");
 
                 presence = $pres({
                         to: 'dummy@localhost/_converse.js-290918392',
@@ -588,7 +588,7 @@
                     });
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(5);
-                expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered and left the room");
+                expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered and left the groupchat");
 
                 presence = $pres({
                         to: 'dummy@localhost/_converse.js-29092160',
@@ -602,7 +602,7 @@
                     });
                 _converse.connection._dataRecv(test_utils.createRequest(presence));
                 expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(5);
-                expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the room");
+                expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the groupchat");
                 done();
             }));
 
@@ -622,7 +622,7 @@
                     expect(indicator.querySelector('time').textContent).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
                     expect(chat_content.querySelectorAll('div.chat-info').length).toBe(1);
                     expect(chat_content.querySelector('div.chat-info').textContent).toBe(
-                        "dummy has entered the room"
+                        "dummy has entered the groupchat"
                     );
 
                     var baseTime = new Date();
@@ -659,7 +659,7 @@
                     expect(indicator.querySelector('time').textContent).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
                     expect(chat_content.querySelectorAll('div.chat-info').length).toBe(2);
                     expect(chat_content.querySelector('div.chat-info:last-child').textContent).toBe(
-                        "some1 has entered the room"
+                        "some1 has entered the groupchat"
                     );
 
                     jasmine.clock().tick(ONE_DAY_LATER);
@@ -688,7 +688,7 @@
                     expect(indicator.querySelector('time').textContent).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
                     expect(chat_content.querySelectorAll('div.chat-info').length).toBe(3);
                     expect($(chat_content).find('div.chat-info:last').html()).toBe(
-                        'some1 has left the room. '+
+                        'some1 has left the groupchat. '+
                         '"Disconnected: Replaced by new connection"');
 
                     jasmine.clock().tick(ONE_DAY_LATER);
@@ -722,7 +722,7 @@
                     expect($indicator.data('isodate')).toEqual(moment().startOf('day').format());
                     expect($indicator.find('time').text()).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
                     expect(chat_content.querySelectorAll('div.chat-info').length).toBe(4);
-                    expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the room");
+                    expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the groupchat");
 
                     jasmine.clock().tick(ONE_DAY_LATER);
 
@@ -763,7 +763,7 @@
                     expect($indicator.find('time').text()).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
                     expect(chat_content.querySelectorAll('div.chat-info').length).toBe(5);
                     expect($chat_content.find('div.chat-info:last').html()).toBe(
-                        'newguy has left the room. '+
+                        'newguy has left the groupchat. '+
                         '"Disconnected: Replaced by new connection"');
 
                     jasmine.clock().uninstall();
@@ -811,7 +811,7 @@
                                 .c('value').t('http://jabber.org/protocol/muc#roominfo').up().up()
                             .c('field', {'type':'text-single', 'var':'muc#roominfo_description', 'label':'Description'})
                                 .c('value').t('This is the description').up().up()
-                            .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 participants'})
                                 .c('value').t(0);
                 _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
                 test_utils.waitUntil(() => _.get(view.el.querySelector('.chatroom-description'), 'textContent'))
@@ -867,8 +867,8 @@
                             'type': 'groupchat'
                         }).c('body').t(message).tree();
                     view.model.onMessage(msg);
-                    expect(_.includes($(view.el).find('.chat-msg-author').text(), '**Dyon van de Wege')).toBeTruthy();
-                    expect($(view.el).find('.chat-msg-text').text()).toBe(' is tired');
+                    expect(_.includes($(view.el).find('.chat-msg__author').text(), '**Dyon van de Wege')).toBeTruthy();
+                    expect($(view.el).find('.chat-msg__text').text()).toBe(' is tired');
 
                     message = '/me is as well';
                     msg = $msg({
@@ -878,8 +878,8 @@
                         type: 'groupchat'
                     }).c('body').t(message).tree();
                     view.model.onMessage(msg);
-                    expect(_.includes($(view.el).find('.chat-msg-author:last').text(), '**Max Mustermann')).toBeTruthy();
-                    expect($(view.el).find('.chat-msg-text:last').text()).toBe(' is as well');
+                    expect(_.includes($(view.el).find('.chat-msg__author:last').text(), '**Max Mustermann')).toBeTruthy();
+                    expect($(view.el).find('.chat-msg__text:last').text()).toBe(' is as well');
                     done();
                 });
             }));
@@ -1065,7 +1065,7 @@
                                 'var': 'muc#roomconfig_passwordprotectedroom'})
                                 .c('value').t(1).up().up()
                             .c('field', {'type': 'fixed'})
-                                .c('value').t('If a password is required to enter this room,'+
+                                .c('value').t('If a password is required to enter this groupchat,'+
                                             'you must specify the password below.').up().up()
                             .c('field', {
                                 'label': 'Password',
@@ -1113,7 +1113,7 @@
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
             }));
 
-            it("shows all members even if they're not currently present in the room",
+            it("shows all members even if they're not currently present in the groupchat",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -1145,7 +1145,7 @@
                         expect(occupants.querySelectorAll('li .occupant-nick')[index].textContent.trim()).toBe(mock.chatroom_names[i]);
                     }
 
-                    // Test users leaving the room
+                    // Test users leaving the groupchat
                     // http://xmpp.org/extensions/xep-0045.html#exit
                     for (i=mock.chatroom_names.length-1; i>-1; i--) {
                         name = mock.chatroom_names[i];
@@ -1168,7 +1168,7 @@
                 }).catch(_.partial(console.error, _));
             }));
 
-            it("shows users currently present in the room",
+            it("shows users currently present in the groupchat",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -1200,7 +1200,7 @@
                         expect(occupants.querySelectorAll('li .occupant-nick')[index].textContent.trim()).toBe(mock.chatroom_names[i]);
                     }
 
-                    // Test users leaving the room
+                    // Test users leaving the groupchat
                     // http://xmpp.org/extensions/xep-0045.html#exit
                     for (i=mock.chatroom_names.length-1; i>-1; i--) {
                         name = mock.chatroom_names[i];
@@ -1310,7 +1310,7 @@
                     expect($(occupants).last().find('.badge').length).toBe(1);
                     expect($(occupants).last().find('.badge').last().text()).toBe('Visitor');
                     expect($(occupants).last().attr('title')).toBe(
-                        contact_jid + ' This user can NOT send messages in this room. Click to mention visitorwoman in your message.'
+                        contact_jid + ' This user can NOT send messages in this groupchat. Click to mention visitorwoman in your message.'
                     );
                     done();
                 }).catch(_.partial(console.error, _));
@@ -1395,7 +1395,7 @@
 
                     expect(view.join).toHaveBeenCalled();
 
-                    // The user has just entered the room (because join was called)
+                    // The user has just entered the groupchat (because join was called)
                     // and receives their own presence from the server.
                     // See example 24:
                     // http://xmpp.org/extensions/xep-0045.html#enter-pres
@@ -1437,7 +1437,7 @@
                 var view = _converse.chatboxviews.get('lounge@localhost');
 
                 // XXX: cheating a lttle bit, normally this'll be set after
-                // receiving the features for the room.
+                // receiving the features for the groupchat.
                 view.model.set('open', 'true');
 
                 spyOn(view.model, 'directInvite').and.callThrough();
@@ -1545,7 +1545,7 @@
                     view.model.onMessage(message.nodeTree);
                     var $chat_content = $(view.el).find('.chat-content');
                     expect($chat_content.find('.chat-msg').length).toBe(1);
-                    expect($chat_content.find('.chat-msg-text').text()).toBe(text);
+                    expect($chat_content.find('.chat-msg__text').text()).toBe(text);
                     expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
                     done();
                 });
@@ -1583,7 +1583,7 @@
                     }).c('body').t(text);
                     view.model.onMessage(message.nodeTree);
                     expect($chat_content.find('.chat-msg').length).toBe(1);
-                    expect($chat_content.find('.chat-msg-text').last().text()).toBe(text);
+                    expect($chat_content.find('.chat-msg__text').last().text()).toBe(text);
                     // We don't emit an event if it's our own message
                     expect(_converse.emit.calls.count(), 1);
                     done();
@@ -1624,7 +1624,7 @@
 
                         // Now check that the message appears inside the chatbox in the DOM
                         var $chat_content = $(view.el).find('.chat-content');
-                        var msg_txt = $chat_content.find('.chat-msg:last').find('.chat-msg-text').text();
+                        var msg_txt = $chat_content.find('.chat-msg:last').find('.chat-msg__text').text();
                         expect(msg_txt).toEqual(message);
                         expect(view.content.scrollTop).toBe(0);
                         done();
@@ -1632,7 +1632,7 @@
                 });
             }));
 
-            it("shows received chatroom subject messages",
+            it("shows received groupchat subject messages",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -1724,7 +1724,7 @@
                     expect($occupants.children().first(0).find('.occupant-nick').text().trim()).toBe("oldnick");
 
                     expect($chat_content.find('div.chat-info').length).toBe(1);
-                    expect($chat_content.find('div.chat-info:first').html()).toBe("oldnick has entered the room");
+                    expect($chat_content.find('div.chat-info:first').html()).toBe("oldnick has entered the groupchat");
 
                     var presence = $pres().attrs({
                             from:'lounge@localhost/oldnick',
@@ -1765,7 +1765,7 @@
                         .c('status').attrs({code:'110'}).nodeTree;
 
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    // XXX: currently we still have an additional "has entered the room"
+                    // XXX: currently we still have an additional "has entered the groupchat"
                     // notification for the new nickname. Ideally we'd not have
                     // that, but that's probably not possible without some
                     // significant refactoring.
@@ -1780,7 +1780,7 @@
                 });
             }));
 
-            it("queries for the room information before attempting to join the user",
+            it("queries for the groupchat information before attempting to join the user",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -1794,7 +1794,7 @@
 
                 _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
 
-                // Check that the room queried for the feautures.
+                // Check that the groupchat queried for the feautures.
                 expect(sent_IQ.toLocaleString()).toBe(
                     "<iq from='dummy@localhost/resource' to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
                         "<query xmlns='http://jabber.org/protocol/disco#info'/>"+
@@ -1854,7 +1854,7 @@
                 });
             }));
 
-            it("updates the shown features when the room configuration has changed",
+            it("updates the shown features when the groupchat configuration has changed",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -1954,7 +1954,7 @@
                         .c('status', {code: '172'});
                     _converse.connection._dataRecv(test_utils.createRequest(message));
                     var $chat_body = $(view.el.querySelector('.chatroom-body'));
-                    expect($chat_body.find('.message:last').text()).toBe('This room is now no longer anonymous');
+                    expect($chat_body.find('.message:last').text()).toBe('This groupchat is now no longer anonymous');
                     done();
                 });
             }));
@@ -1997,15 +1997,17 @@
                         .c('status').attrs({code:'307'}).nodeTree;
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
 
-                    var view = _converse.chatboxviews.get('lounge@localhost');
+                    const view = _converse.chatboxviews.get('lounge@localhost');
                     expect($(view.el.querySelector('.chat-area')).is(':visible')).toBeFalsy();
                     expect($(view.el.querySelector('.occupants')).is(':visible')).toBeFalsy();
-                    var $chat_body = $(view.el.querySelector('.chatroom-body'));
-                    expect($chat_body.find('.disconnect-msg').text()).toBe(
-                        'You have been kicked from this room'+
-                        'This action was done by Fluellen.'+
-                        'The reason given is: "Avaunt, you cullion!".'
-                    );
+                    const chat_body = view.el.querySelector('.chatroom-body');
+                    expect(chat_body.querySelectorAll('.disconnect-msg').length).toBe(3);
+                    expect(chat_body.querySelector('.disconnect-msg:first-child').textContent).toBe(
+                        'You have been kicked from this groupchat');
+                    expect(chat_body.querySelector('.disconnect-msg:nth-child(2)').textContent).toBe(
+                        'This action was done by Fluellen.');
+                    expect(chat_body.querySelector('.disconnect-msg:nth-child(3)').textContent).toBe(
+                        'The reason given is: "Avaunt, you cullion!".');
                     done();
                 });
             }));
@@ -2091,7 +2093,7 @@
         });
 
 
-        describe("Each chat room can take special commands", function () {
+        describe("Each chat groupchat can take special commands", function () {
 
             it("/help to show the available commands",
                 mock.initConverseWithPromises(
@@ -2102,7 +2104,7 @@
                     var view = _converse.chatboxviews.get('lounge@localhost');
                     spyOn(view, 'onMessageSubmitted').and.callThrough();
                     var textarea = view.el.querySelector('.chat-textarea');
-                    textarea.value = '/help This is the room subject';
+                    textarea.value = '/help This is the groupchat subject';
                     view.keyPressed({
                         target: textarea,
                         preventDefault: _.noop,
@@ -2113,26 +2115,26 @@
                     const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
                     expect(info_messages.length).toBe(17);
                     expect(info_messages.pop().textContent).toBe('/voice: Allow muted user to post messages');
-                    expect(info_messages.pop().textContent).toBe('/topic: Set room subject (alias for /subject)');
-                    expect(info_messages.pop().textContent).toBe('/subject: Set room subject');
+                    expect(info_messages.pop().textContent).toBe('/topic: Set groupchat subject (alias for /subject)');
+                    expect(info_messages.pop().textContent).toBe('/subject: Set groupchat subject');
                     expect(info_messages.pop().textContent).toBe('/revoke: Revoke user\'s membership');
-                    expect(info_messages.pop().textContent).toBe('/owner: Grant ownership of this room');
+                    expect(info_messages.pop().textContent).toBe('/owner: Grant ownership of this groupchat');
                     expect(info_messages.pop().textContent).toBe('/op: Grant moderator role to user');
                     expect(info_messages.pop().textContent).toBe('/nick: Change your nickname');
                     expect(info_messages.pop().textContent).toBe('/mute: Remove user\'s ability to post messages');
                     expect(info_messages.pop().textContent).toBe('/member: Grant membership to a user');
                     expect(info_messages.pop().textContent).toBe('/me: Write in 3rd person');
-                    expect(info_messages.pop().textContent).toBe('/kick: Kick user from room');
+                    expect(info_messages.pop().textContent).toBe('/kick: Kick user from groupchat');
                     expect(info_messages.pop().textContent).toBe('/help: Show this menu');
                     expect(info_messages.pop().textContent).toBe('/deop: Change user role to participant');
                     expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
-                    expect(info_messages.pop().textContent).toBe('/ban: Ban user from room');
+                    expect(info_messages.pop().textContent).toBe('/ban: Ban user from groupchat');
                     expect(info_messages.pop().textContent).toBe('/admin: Change user\'s affiliation to admin');
                     done();
                 });
             }));
 
-            it("/topic to set the room topic",
+            it("/topic to set the groupchat topic",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -2147,7 +2149,7 @@
                     });
                     // Check the alias /topic
                     var textarea = view.el.querySelector('.chat-textarea');
-                    textarea.value = '/topic This is the room subject';
+                    textarea.value = '/topic This is the groupchat subject';
                     view.keyPressed({
                         target: textarea,
                         preventDefault: _.noop,
@@ -2155,7 +2157,7 @@
                     });
                     expect(view.onMessageSubmitted).toHaveBeenCalled();
                     expect(_converse.connection.send).toHaveBeenCalled();
-                    expect(sent_stanza.textContent).toBe('This is the room subject');
+                    expect(sent_stanza.textContent).toBe('This is the groupchat subject');
 
                     // Check /subject
                     textarea.value = '/subject This is a new subject';
@@ -2413,7 +2415,7 @@
                     spyOn(view, 'showChatEvent').and.callThrough();
                     spyOn(view, 'validateRoleChangeCommand').and.callThrough();
 
-                    // New user enters the room
+                    // New user enters the groupchat
                     /* <presence
                      *     from='coven@chat.shakespeare.lit/thirdwitch'
                      *     id='27C55F89-1C6A-459A-9EB5-77690145D624'
@@ -2436,7 +2438,7 @@
                             });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
                     var info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
-                    expect(info_msgs.pop().textContent).toBe("trustworthyguy has entered the room");
+                    expect(info_msgs.pop().textContent).toBe("trustworthyguy has entered the groupchat");
 
                     var textarea = view.el.querySelector('.chat-textarea')
                     textarea.value = '/op';
@@ -2553,7 +2555,7 @@
                     spyOn(view, 'showChatEvent').and.callThrough();
                     spyOn(view, 'validateRoleChangeCommand').and.callThrough();
 
-                    // New user enters the room
+                    // New user enters the groupchat
                     /* <presence
                      *     from='coven@chat.shakespeare.lit/thirdwitch'
                      *     id='27C55F89-1C6A-459A-9EB5-77690145D624'
@@ -2576,7 +2578,7 @@
                             });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
                     var info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
-                    expect(info_msgs.pop().textContent).toBe("annoyingGuy has entered the room");
+                    expect(info_msgs.pop().textContent).toBe("annoyingGuy has entered the groupchat");
 
                     var textarea = view.el.querySelector('.chat-textarea')
                     textarea.value = '/mute';
@@ -2675,9 +2677,9 @@
             }));
         });
 
-        describe("When attempting to enter a chatroom", function () {
+        describe("When attempting to enter a groupchat", function () {
 
-            it("will show an error message if the room requires a password",
+            it("will show an error message if the groupchat requires a password",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
                     function (done, _converse) {
@@ -2701,7 +2703,7 @@
                     var $chat_body = $(view.el).find('.chatroom-body');
                     expect(view.renderPasswordForm).toHaveBeenCalled();
                     expect($chat_body.find('form.chatroom-form').length).toBe(1);
-                    expect($chat_body.find('legend').text()).toBe('This chatroom requires a password');
+                    expect($chat_body.find('legend').text()).toBe('This groupchat requires a password');
 
                     // Let's submit the form
                     spyOn(view, 'join');
@@ -2713,7 +2715,7 @@
                 }).catch(_.partial(console.error, _));
             }));
 
-            it("will show an error message if the room is members-only and the user not included",
+            it("will show an error message if the groupchat is members-only and the user not included",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -2731,7 +2733,8 @@
                     var view = _converse.chatboxviews.get('problematic@muc.localhost');
                     spyOn(view, 'showErrorMessage').and.callThrough();
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($(view.el).find('.chatroom-body p:last').text()).toBe('You are not on the member list of this room.');
+                    expect(view.el.querySelector('.chatroom-body .disconnect-container .disconnect-msg:last-child').textContent)
+                        .toBe('You are not on the member list of this groupchat.');
                     done();
                 }).catch(_.partial(console.error, _));
             }));
@@ -2754,7 +2757,8 @@
                     var view = _converse.chatboxviews.get('problematic@muc.localhost');
                     spyOn(view, 'showErrorMessage').and.callThrough();
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($(view.el).find('.chatroom-body p:last').text()).toBe('You have been banned from this room.');
+                    expect(view.el.querySelector('.chatroom-body .disconnect-container .disconnect-msg:last-child').textContent)
+                        .toBe('You have been banned from this groupchat.');
                     done();
                 }).catch(_.partial(console.error, _));
             }));
@@ -2821,7 +2825,7 @@
                     spyOn(view, 'showErrorMessage').and.callThrough();
                     spyOn(view, 'join').and.callThrough();
 
-                    // Simulate repeatedly that there's already someone in the room
+                    // Simulate repeatedly that there's already someone in the groupchat
                     // with that nickname
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
                     expect(view.join).toHaveBeenCalledWith('dummy-2');
@@ -2848,7 +2852,7 @@
                 }).catch(_.partial(console.error, _));
             }));
 
-            it("will show an error message if the user is not allowed to have created the room",
+            it("will show an error message if the user is not allowed to have created the groupchat",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -2866,7 +2870,8 @@
                     var view = _converse.chatboxviews.get('problematic@muc.localhost');
                     spyOn(view, 'showErrorMessage').and.callThrough();
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($(view.el).find('.chatroom-body p:last').text()).toBe('You are not allowed to create new rooms.');
+                    expect(view.el.querySelector('.chatroom-body .disconnect-container .disconnect-msg:last-child').textContent)
+                        .toBe('You are not allowed to create new rooms.');
                     done();
                 }).catch(_.partial(console.error, _));
             }));
@@ -2889,12 +2894,13 @@
                     var view = _converse.chatboxviews.get('problematic@muc.localhost');
                     spyOn(view, 'showErrorMessage').and.callThrough();
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($(view.el).find('.chatroom-body p:last').text()).toBe("Your nickname doesn't conform to this room's policies.");
+                    expect(view.el.querySelector('.chatroom-body .disconnect-container .disconnect-msg:last-child').textContent)
+                        .toBe("Your nickname doesn't conform to this groupchat's policies.");
                     done();
                 }).catch(_.partial(console.error, _));
             }));
 
-            it("will show an error message if the room doesn't yet exist",
+            it("will show an error message if the groupchat doesn't yet exist",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -2912,12 +2918,13 @@
                     var view = _converse.chatboxviews.get('problematic@muc.localhost');
                     spyOn(view, 'showErrorMessage').and.callThrough();
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($(view.el).find('.chatroom-body p:last').text()).toBe("This room does not (yet) exist.");
+                    expect(view.el.querySelector('.chatroom-body .disconnect-container .disconnect-msg:last-child').textContent)
+                        .toBe("This groupchat does not (yet) exist.");
                     done();
                 }).catch(_.partial(console.error, _));
             }));
 
-            it("will show an error message if the room has reached its maximum number of occupants",
+            it("will show an error message if the groupchat has reached its maximum number of participants",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -2935,7 +2942,8 @@
                     var view = _converse.chatboxviews.get('problematic@muc.localhost');
                     spyOn(view, 'showErrorMessage').and.callThrough();
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($(view.el).find('.chatroom-body p:last').text()).toBe("This room has reached its maximum number of occupants.");
+                    expect(view.el.querySelector('.chatroom-body .disconnect-container .disconnect-msg:last-child').textContent)
+                        .toBe("This groupchat has reached its maximum number of participants.");
                     done();
                 }).catch(_.partial(console.error, _));
             }));
@@ -3173,9 +3181,8 @@
                 roomspanel.el.querySelector('.show-add-muc-modal').click();
                 test_utils.closeControlBox(_converse);
                 const modal = roomspanel.add_room_modal;
-                test_utils.waitUntil(function () {
-                    return u.isVisible(modal.el);
-                }, 1000).then(function () {
+                test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
+               .then(function () {
                     spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(function () {
                         var deferred = new $.Deferred();
                         deferred.resolve();
@@ -3263,7 +3270,7 @@
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {'allow_bookmarks': false},
                     function (done, _converse) {
-                // XXX: we set `allow_bookmarks` to false, so that the rooms
+                // XXX: we set `allow_bookmarks` to false, so that the groupchats
                 // list gets rendered. Otherwise we would have to mock
                 // the bookmark stanza exchange.
 
@@ -3351,7 +3358,7 @@
                                 .c('status', {code: '110'});
                             _converse.connection._dataRecv(test_utils.createRequest(presence));
                             expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(2);
-                            expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has entered the room");
+                            expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has entered the groupchat");
                             expect($chat_content.find('div.chat-info:last').html()).toBe("some1 is now a moderator");
 
                             presence = $pres({
@@ -3366,7 +3373,7 @@
                                 });
                             _converse.connection._dataRecv(test_utils.createRequest(presence));
                             expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(3);
-                            expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the room");
+                            expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the groupchat");
 
                             presence = $pres({
                                     to: 'dummy@localhost/_converse.js-29092160',
@@ -3380,7 +3387,7 @@
                                 });
                             _converse.connection._dataRecv(test_utils.createRequest(presence));
                             expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(4);
-                            expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the room");
+                            expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the groupchat");
 
                             // See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
 
@@ -3397,10 +3404,10 @@
                             // Check that the notification appears inside the chatbox in the DOM
                             var events = view.el.querySelectorAll('.chat-event');
                             expect(events.length).toBe(4);
-                            expect(events[0].textContent).toEqual('some1 has entered the room');
+                            expect(events[0].textContent).toEqual('some1 has entered the groupchat');
                             expect(events[1].textContent).toEqual('some1 is now a moderator');
-                            expect(events[2].textContent).toEqual('newguy has entered the room');
-                            expect(events[3].textContent).toEqual('nomorenicks has entered the room');
+                            expect(events[2].textContent).toEqual('newguy has entered the groupchat');
+                            expect(events[3].textContent).toEqual('nomorenicks has entered the groupchat');
 
                             var notifications = view.el.querySelectorAll('.chat-state-notification');
                             expect(notifications.length).toBe(1);
@@ -3422,10 +3429,10 @@
 
                             events = view.el.querySelectorAll('.chat-event');
                             expect(events.length).toBe(4);
-                            expect(events[0].textContent).toEqual('some1 has entered the room');
+                            expect(events[0].textContent).toEqual('some1 has entered the groupchat');
                             expect(events[1].textContent).toEqual('some1 is now a moderator');
-                            expect(events[2].textContent).toEqual('newguy has entered the room');
-                            expect(events[3].textContent).toEqual('nomorenicks has entered the room');
+                            expect(events[2].textContent).toEqual('newguy has entered the groupchat');
+                            expect(events[3].textContent).toEqual('nomorenicks has entered the groupchat');
 
                             notifications = view.el.querySelectorAll('.chat-state-notification');
                             expect(notifications.length).toBe(1);
@@ -3443,10 +3450,10 @@
                             view.model.onMessage(msg);
                             events = view.el.querySelectorAll('.chat-event');
                             expect(events.length).toBe(4);
-                            expect(events[0].textContent).toEqual('some1 has entered the room');
+                            expect(events[0].textContent).toEqual('some1 has entered the groupchat');
                             expect(events[1].textContent).toEqual('some1 is now a moderator');
-                            expect(events[2].textContent).toEqual('newguy has entered the room');
-                            expect(events[3].textContent).toEqual('nomorenicks has entered the room');
+                            expect(events[2].textContent).toEqual('newguy has entered the groupchat');
+                            expect(events[3].textContent).toEqual('nomorenicks has entered the groupchat');
 
                             notifications = view.el.querySelectorAll('.chat-state-notification');
                             expect(notifications.length).toBe(2);
@@ -3467,17 +3474,17 @@
                             var messages = view.el.querySelectorAll('.message');
                             expect(messages.length).toBe(8);
                             expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
-                            expect(view.el.querySelector('.chat-msg .chat-msg-text').textContent).toBe('hello world');
+                            expect(view.el.querySelector('.chat-msg .chat-msg__text').textContent).toBe('hello world');
 
                             // Test that the composing notifications get removed
                             // via timeout.
                             timeout_functions[0]();
                             events = view.el.querySelectorAll('.chat-event');
                             expect(events.length).toBe(4);
-                            expect(events[0].textContent).toEqual('some1 has entered the room');
+                            expect(events[0].textContent).toEqual('some1 has entered the groupchat');
                             expect(events[1].textContent).toEqual('some1 is now a moderator');
-                            expect(events[2].textContent).toEqual('newguy has entered the room');
-                            expect(events[3].textContent).toEqual('nomorenicks has entered the room');
+                            expect(events[2].textContent).toEqual('newguy has entered the groupchat');
+                            expect(events[3].textContent).toEqual('nomorenicks has entered the groupchat');
 
                             notifications = view.el.querySelectorAll('.chat-state-notification');
                             expect(notifications.length).toBe(1);
@@ -3486,10 +3493,10 @@
                             timeout_functions[1]();
                             events = view.el.querySelectorAll('.chat-event');
                             expect(events.length).toBe(4);
-                            expect(events[0].textContent).toEqual('some1 has entered the room');
+                            expect(events[0].textContent).toEqual('some1 has entered the groupchat');
                             expect(events[1].textContent).toEqual('some1 is now a moderator');
-                            expect(events[2].textContent).toEqual('newguy has entered the room');
-                            expect(events[3].textContent).toEqual('nomorenicks has entered the room');
+                            expect(events[2].textContent).toEqual('newguy has entered the groupchat');
+                            expect(events[3].textContent).toEqual('nomorenicks has entered the groupchat');
 
                             notifications = view.el.querySelectorAll('.chat-state-notification');
                             expect(notifications.length).toBe(0);
@@ -3528,7 +3535,7 @@
                             }).up()
                             .c('status', {code: '110'});
                         _converse.connection._dataRecv(test_utils.createRequest(presence));
-                        expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has entered the room");
+                        expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has entered the groupchat");
 
                         presence = $pres({
                                 to: 'dummy@localhost/_converse.js-29092160',
@@ -3542,7 +3549,7 @@
                             });
                         _converse.connection._dataRecv(test_utils.createRequest(presence));
                         expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(2);
-                        expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the room");
+                        expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the groupchat");
 
                         presence = $pres({
                                 to: 'dummy@localhost/_converse.js-29092160',
@@ -3556,7 +3563,7 @@
                             });
                         _converse.connection._dataRecv(test_utils.createRequest(presence));
                         expect($chat_content[0].querySelectorAll('div.chat-info').length).toBe(3);
-                        expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the room");
+                        expect($chat_content.find('div.chat-info:last').html()).toBe("nomorenicks has entered the groupchat");
 
                         // See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
 
@@ -3572,9 +3579,9 @@
                         // Check that the notification appears inside the chatbox in the DOM
                         var events = view.el.querySelectorAll('.chat-event');
                         expect(events.length).toBe(3);
-                        expect(events[0].textContent).toEqual('some1 has entered the room');
-                        expect(events[1].textContent).toEqual('newguy has entered the room');
-                        expect(events[2].textContent).toEqual('nomorenicks has entered the room');
+                        expect(events[0].textContent).toEqual('some1 has entered the groupchat');
+                        expect(events[1].textContent).toEqual('newguy has entered the groupchat');
+                        expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
 
                         var notifications = view.el.querySelectorAll('.chat-state-notification');
                         expect(notifications.length).toBe(1);
@@ -3591,9 +3598,9 @@
 
                         events = view.el.querySelectorAll('.chat-event');
                         expect(events.length).toBe(3);
-                        expect(events[0].textContent).toEqual('some1 has entered the room');
-                        expect(events[1].textContent).toEqual('newguy has entered the room');
-                        expect(events[2].textContent).toEqual('nomorenicks has entered the room');
+                        expect(events[0].textContent).toEqual('some1 has entered the groupchat');
+                        expect(events[1].textContent).toEqual('newguy has entered the groupchat');
+                        expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
 
                         notifications = view.el.querySelectorAll('.chat-state-notification');
                         expect(notifications.length).toBe(1);
@@ -3609,9 +3616,9 @@
                         view.model.onMessage(msg);
                         events = view.el.querySelectorAll('.chat-event');
                         expect(events.length).toBe(3);
-                        expect(events[0].textContent).toEqual('some1 has entered the room');
-                        expect(events[1].textContent).toEqual('newguy has entered the room');
-                        expect(events[2].textContent).toEqual('nomorenicks has entered the room');
+                        expect(events[0].textContent).toEqual('some1 has entered the groupchat');
+                        expect(events[1].textContent).toEqual('newguy has entered the groupchat');
+                        expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
 
                         notifications = view.el.querySelectorAll('.chat-state-notification');
                         expect(notifications.length).toBe(2);
@@ -3628,9 +3635,9 @@
                         view.model.onMessage(msg);
                         events = view.el.querySelectorAll('.chat-event');
                         expect(events.length).toBe(3);
-                        expect(events[0].textContent).toEqual('some1 has entered the room');
-                        expect(events[1].textContent).toEqual('newguy has entered the room');
-                        expect(events[2].textContent).toEqual('nomorenicks has entered the room');
+                        expect(events[0].textContent).toEqual('some1 has entered the groupchat');
+                        expect(events[1].textContent).toEqual('newguy has entered the groupchat');
+                        expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
 
                         notifications = view.el.querySelectorAll('.chat-state-notification');
                         expect(notifications.length).toBe(2);

+ 3 - 3
spec/http-file-upload.js

@@ -364,7 +364,7 @@
                                             }, 1000);
                                         }).then(function () {
                                             // Check that the image renders
-                                            expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
+                                            expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
                                                 '<!-- src/templates/image.html -->\n'+
                                                 '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                                                     '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg">'+
@@ -472,7 +472,7 @@
                                                 }, 1000);
                                             }).then(function () {
                                                 // Check that the image renders
-                                                expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
+                                                expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
                                                     '<!-- src/templates/image.html -->\n'+
                                                     '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                                                         '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg"></a>')
@@ -683,7 +683,7 @@
                                         expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0.5');
                                         message.set('progress', 1);
                                         expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('1');
-                                        expect(view.el.querySelector('.chat-content .chat-msg-text').textContent).toBe('Uploading file: my-juliet.jpg, 22.91 KB');
+                                        expect(view.el.querySelector('.chat-content .chat-msg__text').textContent).toBe('Uploading file: my-juliet.jpg, 22.91 KB');
                                         done();
                                     });
                                     var sent_stanza;

File diff suppressed because it is too large
+ 461 - 157
spec/messages.js


+ 5 - 5
spec/presence.js

@@ -47,7 +47,7 @@
                 "<presence xmlns='jabber:client'>"+
                     "<status>Hello world</status>"+
                     "<priority>0</priority>"+
-                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
+                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='nE765l4CRVrSUEIPAdtgCw4+5cc='/>"+
                 "</presence>"
             );
             _converse.priority = 2;
@@ -57,7 +57,7 @@
                     "<show>away</show>"+
                     "<status>Going jogging</status>"+
                     "<priority>2</priority>"+
-                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
+                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='nE765l4CRVrSUEIPAdtgCw4+5cc='/>"+
                 "</presence>"
             );
 
@@ -68,7 +68,7 @@
                     "<show>dnd</show>"+
                     "<status>Doing taxes</status>"+
                     "<priority>0</priority>"+
-                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
+                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='nE765l4CRVrSUEIPAdtgCw4+5cc='/>"+
                 "</presence>"
             );
         }));
@@ -97,7 +97,7 @@
                     .toBe("<presence xmlns='jabber:client'>"+
                           "<status>My custom status</status>"+
                           "<priority>0</priority>"+
-                          "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
+                          "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='nE765l4CRVrSUEIPAdtgCw4+5cc='/>"+
                           "</presence>")
 
                 return test_utils.waitUntil(function () {
@@ -113,7 +113,7 @@
                 modal.el.querySelector('[type="submit"]').click();
                 expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
                     .toBe("<presence xmlns='jabber:client'><show>dnd</show><status>My custom status</status><priority>0</priority>"+
-                          "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
+                          "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='nE765l4CRVrSUEIPAdtgCw4+5cc='/>"+
                           "</presence>")
                 done();
             });

+ 47 - 7
spec/roomslist.js

@@ -54,7 +54,38 @@
         ));
     });
 
-    describe("A room shown in the rooms list", function () {
+    describe("A groupchat shown in the groupchats list", function () {
+
+        it("is highlighted if its currently open", mock.initConverseWithPromises(
+            null, ['rosterGroupsFetched'],
+            { whitelisted_plugins: ['converse-roomslist'],
+              allow_bookmarks: false // Makes testing easier, otherwise we
+                                     // have to mock stanza traffic.
+            }, function (done, _converse) {
+
+            spyOn(_converse, 'isSingleton').and.callFake(function () {
+                return true;
+            });
+
+            test_utils.openControlBox();
+            _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
+            let room_els = _converse.rooms_list_view.el.querySelectorAll(".available-chatroom");
+            expect(room_els.length).toBe(1);
+
+            let item = room_els[0];
+            expect(u.hasClass('open', item)).toBe(true);
+            expect(item.textContent.trim()).toBe('coven@chat.shakespeare.lit');
+
+            _converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'});
+            room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
+            expect(room_els.length).toBe(2);
+
+            room_els = _converse.rooms_list_view.el.querySelectorAll(".available-chatroom.open");
+            expect(room_els.length).toBe(1);
+            item = room_els[0];
+            expect(item.textContent.trim()).toBe('balcony@chat.shakespeare.lit');
+            done();
+        }));
 
         it("has an info icon which opens a details modal when clicked", mock.initConverseWithPromises(
             null, ['rosterGroupsFetched'],
@@ -114,7 +145,7 @@
 
                 const room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
                 expect(room_els.length).toBe(1);
-                var info_el = _converse.rooms_list_view.el.querySelector(".room-info");
+                const info_el = _converse.rooms_list_view.el.querySelector(".room-info");
                 info_el.click();
 
                 const modal = view.model.room_details_modal;
@@ -122,8 +153,8 @@
             }).then(() => {
                 const modal = view.model.room_details_modal;
                 let els = modal.el.querySelectorAll('p.room-info');
-                expect(els[0].textContent).toBe("Room address (JID): coven@chat.shakespeare.lit")
-                expect(els[1].textContent).toBe("Name: A Dark Cave")
+                expect(els[0].textContent).toBe("Name: A Dark Cave")
+                expect(els[1].textContent).toBe("Room address (JID): coven@chat.shakespeare.lit")
                 expect(els[2].textContent).toBe("Description: This is the description")
                 expect(els[3].textContent).toBe("Online users: 1")
                 const features_list = modal.el.querySelector('.features-list');
@@ -149,8 +180,17 @@
 
                 els = modal.el.querySelectorAll('p.room-info');
                 expect(els[3].textContent).toBe("Online users: 2")
+
+                view.model.set({'subject': {'author': 'someone', 'text': 'Hatching dark plots'}});
+                els = modal.el.querySelectorAll('p.room-info');
+                expect(els[0].textContent).toBe("Name: A Dark Cave")
+                expect(els[1].textContent).toBe("Room address (JID): coven@chat.shakespeare.lit")
+                expect(els[2].textContent).toBe("Description: This is the description")
+                expect(els[3].textContent).toBe("Topic: Hatching dark plots")
+                expect(els[4].textContent).toBe("Topic author: someone")
+                expect(els[5].textContent).toBe("Online users: 2")
                 done();
-            });
+            }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
         }));
 
         it("can be closed", mock.initConverseWithPromises(
@@ -173,7 +213,7 @@
             var close_el = _converse.rooms_list_view.el.querySelector(".close-room");
             close_el.click();
             expect(window.confirm).toHaveBeenCalledWith(
-                'Are you sure you want to leave the room lounge@conference.shakespeare.lit?');
+                'Are you sure you want to leave the groupchat lounge@conference.shakespeare.lit?');
             room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
             expect(room_els.length).toBe(0);
             expect(_converse.chatboxes.length).toBe(1);
@@ -206,7 +246,7 @@
                             type: 'groupchat'
                         }).c('body').t('foo').tree());
 
-                    // If the user isn't mentioned, the counter doesn't get incremented, but the text of the room is bold
+                    // If the user isn't mentioned, the counter doesn't get incremented, but the text of the groupchat is bold
                     var room_el = _converse.rooms_list_view.el.querySelector(
                         ".available-chatroom"
                     );

+ 8 - 8
spec/spoilers.js

@@ -40,9 +40,9 @@
 
             return test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Max Frankfurter')
             .then(function () {
-                expect(view.el.querySelector('.chat-msg-author').textContent).toBe('Max Frankfurter');
+                expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Frankfurter');
 
-                var message_content = view.el.querySelector('.chat-msg-text');
+                var message_content = view.el.querySelector('.chat-msg__text');
                 expect(message_content.textContent).toBe(spoiler);
 
                 var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
@@ -79,9 +79,9 @@
             var view = _converse.chatboxviews.get(sender_jid);
             return test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Max Frankfurter')
             .then(function () {
-                expect(_.includes(view.el.querySelector('.chat-msg-author').textContent, 'Max Frankfurter')).toBeTruthy();
+                expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, 'Max Frankfurter')).toBeTruthy();
 
-                var message_content = view.el.querySelector('.chat-msg-text');
+                var message_content = view.el.querySelector('.chat-msg__text');
                 expect(message_content.textContent).toBe(spoiler);
 
                 var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
@@ -148,9 +148,9 @@
                 expect(body_el.textContent).toBe('This is the spoiler');
 
                 /* Test the HTML spoiler message */
-                expect(view.el.querySelector('.chat-msg-author').textContent).toBe('Max Mustermann');
+                expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Mustermann');
 
-                var spoiler_msg_el = view.el.querySelector('.chat-msg-text.spoiler');
+                var spoiler_msg_el = view.el.querySelector('.chat-msg__text.spoiler');
                 expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
                 expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
 
@@ -227,9 +227,9 @@
                 expect(body_el.textContent).toBe('This is the spoiler');
 
                 /* Test the HTML spoiler message */
-                expect(view.el.querySelector('.chat-msg-author').textContent).toBe('Max Mustermann');
+                expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Mustermann');
 
-                var spoiler_msg_el = view.el.querySelector('.chat-msg-text.spoiler');
+                var spoiler_msg_el = view.el.querySelector('.chat-msg__text.spoiler');
                 expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
                 expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
 

+ 8 - 8
src/converse-bookmarks.js

@@ -67,7 +67,7 @@
                           { __ } = _converse;
                     const bookmark_button = tpl_chatroom_bookmark_toggle(
                         _.assignIn(this.model.toJSON(), {
-                            info_toggle_bookmark: __('Bookmark this room'),
+                            info_toggle_bookmark: __('Bookmark this groupchat'),
                             bookmarked: this.model.get('bookmarked')
                         }));
                     const close_button = this.el.querySelector('.close-chatbox-button');
@@ -143,10 +143,10 @@
                     body.insertAdjacentHTML(
                         'beforeend',
                         tpl_chatroom_bookmark_form({
-                            heading: __('Bookmark this room'),
+                            heading: __('Bookmark this groupchat'),
                             label_name: __('The name for this bookmark:'),
-                            label_autojoin: __('Would you like this room to be automatically joined upon startup?'),
-                            label_nick: __('What should your nickname for this room be?'),
+                            label_autojoin: __('Would you like this groupchat to be automatically joined upon startup?'),
+                            label_nick: __('What should your nickname for this groupchat be?'),
                             default_nick: this.model.get('nick'),
                             label_submit: __('Save'),
                             label_cancel: __('Cancel')
@@ -410,13 +410,13 @@
                         'hidden': _converse.hide_open_bookmarks &&
                                   _converse.chatboxes.where({'jid': this.model.get('jid')}).length,
                         'bookmarked': true,
-                        'info_leave_room': __('Leave this room'),
+                        'info_leave_room': __('Leave this groupchat'),
                         'info_remove': __('Remove this bookmark'),
-                        'info_remove_bookmark': __('Unbookmark this room'),
-                        'info_title': __('Show more information on this room'),
+                        'info_remove_bookmark': __('Unbookmark this groupchat'),
+                        'info_title': __('Show more information on this groupchat'),
                         'jid': this.model.get('jid'),
                         'name': Strophe.xmlunescape(this.model.get('name')),
-                        'open_title': __('Click to open this room')
+                        'open_title': __('Click to open this groupchat')
                     });
                 }
             });

+ 98 - 57
src/converse-chatboxes.js

@@ -19,6 +19,8 @@
     const { $msg, Backbone, Promise, Strophe, b64_sha1, moment, sizzle, utils, _ } = converse.env;
     const u = converse.env.utils;
 
+    Strophe.addNamespace('MESSAGE_CORRECT', 'urn:xmpp:message-correct:0');
+
 
     converse.plugins.add('converse-chatboxes', {
 
@@ -43,7 +45,7 @@
              * loaded by converse.js's plugin machinery.
              */
             const { _converse } = this,
-                { __ } = _converse;
+                  { __ } = _converse;
 
             // Configuration values for this plugin
             // ====================================
@@ -215,9 +217,11 @@
                     }, false);
 
                     xhr.onerror = () => {
-                        let  message = __('Sorry, could not succesfully upload your file.');
+                        let message;
                         if (xhr.responseText) {
-                            message += ' ' + __('Your server\'s response: "%1$s"', xhr.responseText)
+                            message = __('Sorry, could not succesfully upload your file. Your server’s response: "%1$s"', xhr.responseText)
+                        } else {
+                            message = __('Sorry, could not succesfully upload your file.');
                         }
                         this.save({
                             'type': 'error',
@@ -290,6 +294,23 @@
                     return this.vcard.get('fullname') || this.get('jid');
                 },
 
+                handleMessageCorrection (stanza) {
+                    const replace = sizzle(`replace[xmlns="${Strophe.NS.MESSAGE_CORRECT}"]`, stanza).pop();
+                    if (replace) {
+                        const msgid = replace && replace.getAttribute('id') || stanza.getAttribute('id'),
+                            message = msgid && this.messages.findWhere({msgid}),
+                            older_versions = message.get('older_versions') || [];
+                        older_versions.push(message.get('message'));
+                        message.save({
+                            'message': _converse.chatboxes.getMessageBody(stanza),
+                            'older_versions': older_versions,
+                            'edited': true
+                        });
+                        return true;
+                    }
+                    return false;
+                },
+
                 createMessageStanza (message) {
                     /* Given a _converse.Message Backbone.Model, return the XML
                      * stanza that represents it.
@@ -301,7 +322,7 @@
                             'from': _converse.connection.jid,
                             'to': this.get('jid'),
                             'type': this.get('message_type'),
-                            'id': message.get('msgid')
+                            'id': message.get('edited') && _converse.connection.getUniqueId() || message.get('msgid'),
                         }).c('body').t(message.get('message')).up()
                           .c(_converse.ACTIVE, {'xmlns': Strophe.NS.CHATSTATES}).up();
 
@@ -315,6 +336,12 @@
                     if (message.get('file')) {
                         stanza.c('x', {'xmlns': Strophe.NS.OUTOFBAND}).c('url').t(message.get('message')).up();
                     }
+                    if (message.get('edited')) {
+                        stanza.c('replace', {
+                            'xmlns': Strophe.NS.MESSAGE_CORRECT,
+                            'id': message.get('msgid')
+                        }).up();
+                    }
                     return stanza;
                 },
 
@@ -357,8 +384,20 @@
                      *  Parameters:
                      *    (Message) message - The chat message
                      */
-                    const message = this.messages.create(attrs);
-                    this.sendMessageStanza(this.createMessageStanza(message));
+                    let message = this.messages.findWhere('correcting')
+                    if (message) {
+                        const older_versions = message.get('older_versions') || [];
+                        older_versions.push(message.get('message'));
+                        message.save({
+                            'message': attrs.message,
+                            'older_versions': older_versions,
+                            'edited': true,
+                            'correcting': false
+                        });
+                    } else {
+                        message = this.messages.create(attrs);
+                    }
+                    return this.sendMessageStanza(this.createMessageStanza(message));
                 },
 
                 sendChatState () {
@@ -410,24 +449,12 @@
                     }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
                 },
 
-                getMessageBody (message) {
-                    const type = message.getAttribute('type');
-                    if (type === 'error') {
-                        const error = message.querySelector('error');
-                        return _.propertyOf(error.querySelector('text'))('textContent') ||
-                            __('Sorry, an error occured:') + ' ' + error.innerHTML;
-                    } else {
-                        return _.propertyOf(message.querySelector('body'))('textContent');
-                    }
-
-                },
-
-                getMessageAttributesFromStanza (message, original_stanza) {
+                getMessageAttributesFromStanza (stanza, original_stanza) {
                     /* Parses a passed in message stanza and returns an object
                      * of attributes.
                      *
                      * Parameters:
-                     *    (XMLElement) message - The message stanza
+                     *    (XMLElement) stanza - The message stanza
                      *    (XMLElement) delay - The <delay> node from the
                      *      stanza, if there was one.
                      *    (XMLElement) original_stanza - The original stanza,
@@ -439,24 +466,24 @@
                           archive = sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop(),
                           spoiler = sizzle(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`, original_stanza).pop(),
                           delay = sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, original_stanza).pop(),
-                          chat_state = message.getElementsByTagName(_converse.COMPOSING).length && _converse.COMPOSING ||
-                                message.getElementsByTagName(_converse.PAUSED).length && _converse.PAUSED ||
-                                message.getElementsByTagName(_converse.INACTIVE).length && _converse.INACTIVE ||
-                                message.getElementsByTagName(_converse.ACTIVE).length && _converse.ACTIVE ||
-                                message.getElementsByTagName(_converse.GONE).length && _converse.GONE;
+                          chat_state = stanza.getElementsByTagName(_converse.COMPOSING).length && _converse.COMPOSING ||
+                                stanza.getElementsByTagName(_converse.PAUSED).length && _converse.PAUSED ||
+                                stanza.getElementsByTagName(_converse.INACTIVE).length && _converse.INACTIVE ||
+                                stanza.getElementsByTagName(_converse.ACTIVE).length && _converse.ACTIVE ||
+                                stanza.getElementsByTagName(_converse.GONE).length && _converse.GONE;
 
                     const attrs = {
                         'chat_state': chat_state,
                         'is_archived': !_.isNil(archive),
                         'is_delayed': !_.isNil(delay),
                         'is_spoiler': !_.isNil(spoiler),
-                        'message': this.getMessageBody(message) || undefined,
-                        'msgid': message.getAttribute('id'),
+                        'message': _converse.chatboxes.getMessageBody(stanza) || undefined,
+                        'msgid': stanza.getAttribute('id'),
                         'time': delay ? delay.getAttribute('stamp') : moment().format(),
-                        'type': message.getAttribute('type')
+                        'type': stanza.getAttribute('type')
                     };
                     if (attrs.type === 'groupchat') {
-                        attrs.from = message.getAttribute('from');
+                        attrs.from = stanza.getAttribute('from');
                         attrs.nick = Strophe.unescapeNode(Strophe.getResourceFromJid(attrs.from));
                         if (attrs.from === this.get('nick')) {
                             attrs.sender = 'me';
@@ -464,7 +491,7 @@
                             attrs.sender = 'them';
                         }
                     } else {
-                        attrs.from = Strophe.getBareJidFromJid(message.getAttribute('from'));
+                        attrs.from = Strophe.getBareJidFromJid(stanza.getAttribute('from'));
                         if (attrs.from === _converse.bare_jid) {
                             attrs.sender = 'me';
                             attrs.fullname = _converse.xmppstatus.get('fullname');
@@ -473,7 +500,7 @@
                             attrs.fullname = this.get('fullname');
                         }
                     }
-                    _.each(sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, message), (xform) => {
+                    _.each(sizzle(`x[xmlns="${Strophe.NS.OUTOFBAND}"]`, stanza), (xform) => {
                         attrs['oob_url'] = xform.querySelector('url').textContent;
                         attrs['oob_desc'] = xform.querySelector('url').textContent;
                     });
@@ -591,19 +618,29 @@
                     return true;
                 },
 
-                onMessage (message) {
+                getMessageBody (stanza) {
+                    /* Given a message stanza, return the text contained in its body.
+                     */
+                    const type = stanza.getAttribute('type');
+                    if (type === 'error') {
+                        const error = stanza.querySelector('error');
+                        return _.propertyOf(error.querySelector('text'))('textContent') ||
+                            __('Sorry, an error occurred:') + ' ' + error.innerHTML;
+                    } else {
+                        return _.propertyOf(stanza.querySelector('body'))('textContent');
+                    }
+                },
+
+                onMessage (stanza) {
                     /* Handler method for all incoming single-user chat "message"
                      * stanzas.
                      *
                      * Parameters:
-                     *    (XMLElement) message - The incoming message stanza
+                     *    (XMLElement) stanza - The incoming message stanza
                      */
-                    let from_jid = message.getAttribute('from'),
-                        to_jid = message.getAttribute('to');
-
-                    const original_stanza = message,
-                        to_resource = Strophe.getResourceFromJid(to_jid),
-                        is_carbon = !_.isNull(message.querySelector(`received[xmlns="${Strophe.NS.CARBONS}"]`));
+                    let from_jid = stanza.getAttribute('from'),
+                        to_jid = stanza.getAttribute('to');
+                    const to_resource = Strophe.getResourceFromJid(to_jid);
 
                     if (_converse.filter_by_resource && (to_resource && to_resource !== _converse.resource)) {
                         _converse.log(
@@ -611,7 +648,7 @@
                             Strophe.LogLevel.INFO
                         );
                         return true;
-                    } else if (utils.isHeadlineMessage(_converse, message)) {
+                    } else if (utils.isHeadlineMessage(_converse, stanza)) {
                         // XXX: Ideally we wouldn't have to check for headline
                         // messages, but Prosody sends headline messages with the
                         // wrong type ('chat'), so we need to filter them out here.
@@ -621,23 +658,28 @@
                         );
                         return true;
                     }
-                    const forwarded = message.querySelector('forwarded');
+
+                    const forwarded = stanza.querySelector('forwarded'),
+                          original_stanza = stanza;
+
                     if (!_.isNull(forwarded)) {
-                        const forwarded_message = forwarded.querySelector('message');
-                        const forwarded_from = forwarded_message.getAttribute('from');
+                        const forwarded_message = forwarded.querySelector('message'),
+                              forwarded_from = forwarded_message.getAttribute('from'),
+                              is_carbon = !_.isNull(stanza.querySelector(`received[xmlns="${Strophe.NS.CARBONS}"]`));
+
                         if (is_carbon && Strophe.getBareJidFromJid(forwarded_from) !== from_jid) {
                             // Prevent message forging via carbons
                             // https://xmpp.org/extensions/xep-0280.html#security
                             return true;
                         }
-                        message = forwarded_message;
-                        from_jid = message.getAttribute('from');
-                        to_jid = message.getAttribute('to');
+                        stanza = forwarded_message;
+                        from_jid = stanza.getAttribute('from');
+                        to_jid = stanza.getAttribute('to');
                     }
 
                     const from_bare_jid = Strophe.getBareJidFromJid(from_jid),
-                        from_resource = Strophe.getResourceFromJid(from_jid),
-                        is_me = from_bare_jid === _converse.bare_jid;
+                          from_resource = Strophe.getResourceFromJid(from_jid),
+                          is_me = from_bare_jid === _converse.bare_jid;
 
                     let contact_jid;
                     if (is_me) {
@@ -650,16 +692,14 @@
                     const attrs = {
                         'fullname': _.get(_converse.api.contacts.get(contact_jid), 'attributes.fullname')
                     }
-                    const chatbox = this.getChatBox(contact_jid, attrs, !_.isNull(message.querySelector('body'))),
-                          msgid = message.getAttribute('id');
-
-                    if (chatbox) {
-                        const messages = msgid && chatbox.messages.findWhere({msgid}) || [];
-                        if (_.isEmpty(messages)) {
-                            // Only create the message when we're sure it's not a
-                            // duplicate
+                    const chatbox = this.getChatBox(contact_jid, attrs, !_.isNull(stanza.querySelector('body')));
+                    if (chatbox && !chatbox.handleMessageCorrection(stanza)) {
+                        const msgid = stanza.getAttribute('id'),
+                              message = msgid && chatbox.messages.findWhere({msgid});
+                        if (!message) {
+                            // Only create the message when we're sure it's not a duplicate
                             chatbox.incrementUnreadMsgCounter(original_stanza);
-                            chatbox.createMessage(message, original_stanza);
+                            chatbox.createMessage(stanza, original_stanza);
                         }
                     }
                     _converse.emit('message', {'stanza': original_stanza, 'chatbox': chatbox});
@@ -813,6 +853,7 @@
 
 
             _converse.on('addClientFeatures', () => {
+                _converse.api.disco.own.features.add(Strophe.NS.MESSAGE_CORRECT);
                 _converse.api.disco.own.features.add(Strophe.NS.HTTPUPLOAD);
                 _converse.api.disco.own.features.add(Strophe.NS.OUTOFBAND);
             });

+ 101 - 23
src/converse-chatview.js

@@ -9,7 +9,6 @@
             "bootstrap",
             "emojione",
             "xss",
-            "templates/action.html",
             "templates/chatbox.html",
             "templates/chatbox_head.html",
             "templates/chatbox_message_form.html",
@@ -33,7 +32,6 @@
             bootstrap,
             emojione,
             xss,
-            tpl_action,
             tpl_chatbox,
             tpl_chatbox_head,
             tpl_chatbox_message_form,
@@ -54,6 +52,8 @@
     const u = converse.env.utils;
     const KEY = {
         ENTER: 13,
+        UP_ARROW: 38,
+        DOWN_ARROW: 40,
         FORWARD_SLASH: 47
     };
 
@@ -237,7 +237,7 @@
 
             _converse.UserDetailsModal = _converse.BootstrapModal.extend({
 
-                events: { 
+                events: {
                     'click button.remove-contact': 'removeContact',
                     'click button.refresh-contact': 'refreshContact'
                 },
@@ -321,6 +321,7 @@
 
                 events: {
                     'change input.fileupload': 'onFileSelection',
+                    'click .chat-msg__action-edit': 'onMessageEditButtonClicked',
                     'click .chatbox-navback': 'showControlBox',
                     'click .close-chatbox-button': 'close',
                     'click .new-msgs-indicator': 'viewUnreadMessages',
@@ -333,8 +334,8 @@
                     'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
                     'click .toggle-smiley': 'toggleEmojiMenu',
                     'click .upload-file': 'toggleFileUpload',
-                    'keypress .chat-textarea': 'keyPressed',
-                    'input .chat-textarea': 'inputChanged'
+                    'input .chat-textarea': 'inputChanged',
+                    'keydown .chat-textarea': 'keyPressed'
                 },
 
                 initialize () {
@@ -746,19 +747,19 @@
                           date = moment(el.getAttribute('data-isodate')),
                           next_el = el.nextElementSibling;
 
-                    if (!u.hasClass('chat-action', el) && !u.hasClass('chat-action', previous_el) &&
+                    if (!u.hasClass('chat-msg--action', el) && !u.hasClass('chat-msg--action', previous_el) &&
                             previous_el.getAttribute('data-from') === from &&
                             date.isBefore(moment(previous_el.getAttribute('data-isodate')).add(10, 'minutes'))) {
-                        u.addClass('chat-msg-followup', el);
+                        u.addClass('chat-msg--followup', el);
                     }
                     if (!next_el) { return; }
 
-                    if (!u.hasClass('chat-action', 'el') &&
+                    if (!u.hasClass('chat-msg--action', 'el') &&
                             next_el.getAttribute('data-from') === from &&
                             moment(next_el.getAttribute('data-isodate')).isBefore(date.add(10, 'minutes'))) {
-                        u.addClass('chat-msg-followup', next_el);
+                        u.addClass('chat-msg--followup', next_el);
                     } else {
-                        u.removeClass('chat-msg-followup', next_el);
+                        u.removeClass('chat-msg--followup', next_el);
                     }
                 },
 
@@ -802,7 +803,9 @@
                      *    (Object) message - The message Backbone object that was added.
                      */
                     this.showMessage(message);
-
+                    if (message.get('correcting')) {
+                        this.insertIntoTextArea(message.get('message'), true);
+                    }
                     _converse.emit('messageAdded', {
                         'message': message,
                         'chatbox': this.model
@@ -911,8 +914,14 @@
                 keyPressed (ev) {
                     /* Event handler for when a key is pressed in a chat box textarea.
                      */
-                    if (ev.keyCode === KEY.ENTER && !ev.shiftKey) {
+                    if (ev.shiftKey) { return; }
+
+                    if (ev.keyCode === KEY.ENTER) {
                         this.onFormSubmitted(ev);
+                    } else if (ev.keyCode === KEY.UP_ARROW && !ev.target.selectionEnd) {
+                        this.editEarlierMessage();
+                    } else if (ev.keyCode === KEY.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length) {
+                        this.editLaterMessage();
                     } else if (ev.keyCode !== KEY.FORWARD_SLASH && this.model.get('chat_state') !== _converse.COMPOSING) {
                         // Set chat state to composing if keyCode is not a forward-slash
                         // (which would imply an internal command and not a message).
@@ -920,6 +929,71 @@
                     }
                 },
 
+                getOwnMessages () {
+                    return f(this.model.messages.filter({'sender': 'me'}));
+                },
+
+                onMessageEditButtonClicked (ev) {
+                    const idx = this.model.messages.findLastIndex('correcting'),
+                          currently_correcting = idx >=0 ? this.model.messages.at(idx) : null,
+                          message_el = u.ancestor(ev.target, '.chat-msg'),
+                          message = this.model.messages.findWhere({'msgid': message_el.getAttribute('data-msgid')});
+
+                    if (currently_correcting !== message) {
+                        if (!_.isNil(currently_correcting)) {
+                            currently_correcting.save('correcting', false);
+                        }
+                        message.save('correcting', true);
+                        this.insertIntoTextArea(message.get('message'), true);
+                    } else {
+                        message.save('correcting', false);
+                        this.insertIntoTextArea('', true);
+                    }
+                },
+
+                editLaterMessage () {
+                    let message;
+                    let idx = this.model.messages.findLastIndex('correcting');
+                    if (idx >= 0) {
+                        this.model.messages.at(idx).save('correcting', false);
+                        while (idx < this.model.messages.length-1) {
+                            idx += 1;
+                            const candidate = this.model.messages.at(idx);
+                            if (candidate.get('sender') === 'me' && candidate.get('message')) {
+                                message = candidate;
+                                break;
+                            }
+                        }
+                    }
+                    if (message) {
+                        this.insertIntoTextArea(message.get('message'), true);
+                        message.save('correcting', true);
+                    } else {
+                        this.insertIntoTextArea('', true);
+                    }
+                },
+
+                editEarlierMessage () {
+                    let message;
+                    let idx = this.model.messages.findLastIndex('correcting');
+                    if (idx >= 0) {
+                        this.model.messages.at(idx).save('correcting', false);
+                        while (idx > 0) {
+                            idx -= 1;
+                            const candidate = this.model.messages.at(idx);
+                            if (candidate.get('sender') === 'me' && candidate.get('message')) {
+                                message = candidate;
+                                break;
+                            }
+                        }
+                    }
+                    message = message || this.getOwnMessages().findLast((msg) => msg.get('message'));
+                    if (message) {
+                        this.insertIntoTextArea(message.get('message'), true);
+                        message.save('correcting', true);
+                    }
+                },
+
                 inputChanged (ev) {
                     ev.target.style.height = 'auto'; // Fixes weirdness
                     ev.target.style.height = (ev.target.scrollHeight) + 'px';
@@ -936,14 +1010,18 @@
                     return this;
                 },
 
-                insertIntoTextArea (value) {
-                    const textbox_el = this.el.querySelector('.chat-textarea');
-                    let existing = textbox_el.value;
-                    if (existing && (existing[existing.length-1] !== ' ')) {
-                        existing = existing + ' ';
+                insertIntoTextArea (value, replace=false) {
+                    const textarea = this.el.querySelector('.chat-textarea');
+                    if (replace) {
+                        textarea.value = value;
+                    } else {
+                        let existing = textarea.value;
+                        if (existing && (existing[existing.length-1] !== ' ')) {
+                            existing = existing + ' ';
+                        }
+                        textarea.value = existing+value+' ';
                     }
-                    textbox_el.value = existing+value+' ';
-                    textbox_el.focus()
+                    textarea.focus()
                 },
 
                 createEmojiPicker () {
@@ -1017,13 +1095,13 @@
                     let text;
                     if (u.isVisible(this.el)) {
                         if (show === 'offline') {
-                            text = fullname+' '+__('has gone offline');
+                            text = __('%1$s has gone offline', fullname);
                         } else if (show === 'away') {
-                            text = fullname+' '+__('has gone away');
+                            text = __('%1$s has gone away', fullname);
                         } else if ((show === 'dnd')) {
-                            text = fullname+' '+__('is busy');
+                            text = __('%1$s is busy', fullname);
                         } else if (show === 'online') {
-                            text = fullname+' '+__('is online');
+                            text = __('%1$s is online', fullname);
                         }
                         if (text) {
                             this.content.insertAdjacentHTML(

+ 8 - 3
src/converse-controlbox.js

@@ -200,8 +200,6 @@
 
             _converse.api.promises.add('controlboxInitialized');
 
-            const LABEL_CONTACTS = __('Contacts');
-
             _converse.addControlBox = () =>
                 _converse.chatboxes.add({
                     id: 'controlbox',
@@ -269,6 +267,9 @@
                 },
 
                 insertRoster () {
+                    if (_converse.authentication === _converse.ANONYMOUS) {
+                        return;
+                    }
                     /* Place the rosterview inside the "Contacts" panel. */
                     _converse.api.waitUntil('rosterViewInitialized')
                         .then(() => this.controlbox_pane.el.insertAdjacentElement('beforeEnd', _converse.rosterview.el))
@@ -470,7 +471,11 @@
 
                     let jid = form_data.get('jid');
                     if (_converse.locked_domain) {
-                        jid = Strophe.escapeNode(jid) + '@' + _converse.locked_domain;
+                        const last_part = '@' + _converse.locked_domain;
+                        if (jid.endsWith(last_part)) {
+                            jid = jid.substr(0, jid.length - last_part.length);
+                        }
+                        jid = Strophe.escapeNode(jid) + last_part;
                     } else if (_converse.default_domain && !_.includes(jid, '@')) {
                         jid = jid + '@' + _converse.default_domain;
                     }

+ 8 - 2
src/converse-core.js

@@ -228,6 +228,8 @@
         }
         if (message instanceof Error) {
             message = message.stack;
+        } else if (_.isElement(message)) {
+            message = message.outerHTML;
         }
         const prefix = style ? '%c' : '';
         const logger = _.assign({
@@ -294,6 +296,10 @@
         }
     };
 
+    _converse.isSingleton = function () {
+        return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
+    }
+
     _converse.router = new Backbone.Router();
 
 
@@ -735,8 +741,8 @@
             this.connection.addHandler((iq) => {
                 if (iq.querySelectorAll('error').length > 0) {
                     _converse.log(
-                        'An error occured while trying to enable message carbons.',
-                        Strophe.LogLevel.ERROR);
+                        'An error occurred while trying to enable message carbons.',
+                        Strophe.LogLevel.WARN);
                 } else {
                     this.session.save({'carbons_enabled': true});
                     _converse.log('Message carbons have been enabled.');

+ 55 - 21
src/converse-message-view.js

@@ -10,24 +10,22 @@
         "xss",
         "emojione",
         "filesize",
-        "templates/action.html",
         "templates/csn.html",
         "templates/file_progress.html",
         "templates/info.html",
         "templates/message.html",
-        "templates/spoiler_message.html"
+        "templates/message_versions_modal.html",
     ], factory);
 }(this, function (
         converse,
         xss,
         emojione,
         filesize,
-        tpl_action,
         tpl_csn,
         tpl_file_progress,
         tpl_info,
         tpl_message,
-        tpl_spoiler_message
+        tpl_message_versions_modal
     ) {
     "use strict";
     const { Backbone, _, moment } = converse.env;
@@ -69,10 +67,27 @@
                 },
             });
 
+
+            _converse.MessageVersionsModal = _converse.BootstrapModal.extend({
+
+                toHTML () {
+                    return tpl_message_versions_modal(_.extend(
+                        this.model.toJSON(), {
+                        '__': __
+                    }));
+                }
+            });
+
+
             _converse.MessageView = _converse.ViewWithAvatar.extend({
+                events: {
+                    'click .chat-msg__edit-modal': 'showMessageVersionsModal'
+                },
 
                 initialize () {
                     this.model.vcard.on('change', this.render, this);
+                    this.model.on('change:correcting', this.onMessageCorrection, this);
+                    this.model.on('change:message', this.render, this);
                     this.model.on('change:progress', this.renderFileUploadProgresBar, this);
                     this.model.on('change:type', this.render, this);
                     this.model.on('change:upload', this.render, this);
@@ -81,7 +96,7 @@
                 },
 
                 render () {
-                    const is_followup = u.hasClass('chat-msg-followup', this.el);
+                    const is_followup = u.hasClass('chat-msg--followup', this.el);
                     let msg;
                     if (this.model.isOnlyChatStateNotification()) {
                         this.renderChatStateNotification()
@@ -93,11 +108,19 @@
                         this.renderChatMessage();
                     }
                     if (is_followup) {
-                        u.addClass('chat-msg-followup', this.el);
+                        u.addClass('chat-msg--followup', this.el);
                     }
                     return this.el;
                 },
 
+                onMessageCorrection () {
+                    this.render();
+                    if (!this.model.get('correcting') && this.model.changed.message) {
+                        this.el.addEventListener('animationend', () => u.removeClass('onload', this.el));
+                        u.addClass('onload', this.el);
+                    }
+                },
+
                 replaceElement (msg) {
                     if (!_.isNil(this.el.parentElement)) {
                         this.el.parentElement.replaceChild(msg, this.el);
@@ -107,20 +130,16 @@
                 },
 
                 renderChatMessage () {
-                    let template, text = this.model.get('message');
-                    if (this.isMeCommand()) {
-                        template = tpl_action;
-                        text = this.model.get('message').replace(/^\/me/, '');
-                    } else {
-                        template = this.model.get('is_spoiler') ? tpl_spoiler_message : tpl_message;
-                    }
-                    const moment_time = moment(this.model.get('time')),
+                    const is_me_message = this.isMeCommand(),
+                          moment_time = moment(this.model.get('time')),
                           role = this.model.vcard.get('role'),
                           roles = role ? role.split(',') : [];
 
-                    const msg = u.stringToElement(template(
+                    const msg = u.stringToElement(tpl_message(
                         _.extend(
                             this.model.toJSON(), {
+                            '__': __,
+                            'is_me_message': is_me_message,
                             'roles': roles,
                             'pretty_time': moment_time.format(_converse.time_format),
                             'time': moment_time.format(),
@@ -130,16 +149,20 @@
                         })
                     ));
 
-                    var url = this.model.get('oob_url');
+                    const url = this.model.get('oob_url');
                     if (url) {
-                        msg.querySelector('.chat-msg-media').innerHTML = _.flow(
+                        msg.querySelector('.chat-msg__media').innerHTML = _.flow(
                             _.partial(u.renderFileURL, _converse),
                             _.partial(u.renderMovieURL, _converse),
                             _.partial(u.renderAudioURL, _converse),
                             _.partial(u.renderImageURL, _converse))(url);
                     }
 
-                    const msg_content = msg.querySelector('.chat-msg-text');
+                    let text = this.model.get('message');
+                    if (is_me_message) {
+                        text = text.replace(/^\/me/, '');
+                    }
+                    const msg_content = msg.querySelector('.chat-msg__text');
                     if (text !== url) {
                         text = xss.filterXSS(text, {'whiteList': {}});
                         msg_content.innerHTML = _.flow(
@@ -179,16 +202,16 @@
                         if (this.model.get('sender') === 'me') {
                             text = __('Typing from another device');
                         } else {
-                            text = name +' '+__('is typing');
+                            text = __('%1$s is typing', name);
                         }
                     } else if (this.model.get('chat_state') === _converse.PAUSED) {
                         if (this.model.get('sender') === 'me') {
                             text = __('Stopped typing on the other device');
                         } else {
-                            text = name +' '+__('has stopped typing');
+                            text = __('%1$s has stopped typing', name);
                         }
                     } else if (this.model.get('chat_state') === _converse.GONE) {
-                        text = name +' '+__('has gone away');
+                        text = __('%1$s has gone away', name);
                     } else {
                         return;
                     }
@@ -211,6 +234,14 @@
                     this.renderAvatar();
                 },
 
+                showMessageVersionsModal (ev) {
+                    ev.preventDefault();
+                    if (_.isUndefined(this.model.message_versions_modal)) {
+                        this.model.message_versions_modal = new _converse.MessageVersionsModal({'model': this.model});
+                    }
+                    this.model.message_versions_modal.show(ev);
+                },
+
                 isMeCommand () {
                     const text = this.model.get('message');
                     if (!text) {
@@ -234,6 +265,9 @@
                             extra_classes += ' mentioned';
                         }
                     }
+                    if (this.model.get('correcting')) {
+                        extra_classes += ' correcting';
+                    }
                     return extra_classes;
                 }
             });

+ 85 - 69
src/converse-muc-views.js

@@ -8,6 +8,7 @@
     define([
         "converse-core",
         "utils/muc",
+        "xss",
         "templates/add_chatroom_modal.html",
         "templates/chatarea.html",
         "templates/chatroom.html",
@@ -35,6 +36,7 @@
 }(this, function (
     converse,
     muc_utils,
+    xss,
     tpl_add_chatroom_modal,
     tpl_chatarea,
     tpl_chatroom,
@@ -196,24 +198,24 @@
              */
             _converse.muc = {
                 info_messages: {
-                    100: __('This room is not anonymous'),
-                    102: __('This room now shows unavailable members'),
-                    103: __('This room does not show unavailable members'),
-                    104: __('The room configuration has changed'),
-                    170: __('Room logging is now enabled'),
-                    171: __('Room logging is now disabled'),
-                    172: __('This room is now no longer anonymous'),
-                    173: __('This room is now semi-anonymous'),
-                    174: __('This room is now fully-anonymous'),
-                    201: __('A new room has been created')
+                    100: __('This groupchat is not anonymous'),
+                    102: __('This groupchat now shows unavailable members'),
+                    103: __('This groupchat does not show unavailable members'),
+                    104: __('The groupchat configuration has changed'),
+                    170: __('groupchat logging is now enabled'),
+                    171: __('groupchat logging is now disabled'),
+                    172: __('This groupchat is now no longer anonymous'),
+                    173: __('This groupchat is now semi-anonymous'),
+                    174: __('This groupchat is now fully-anonymous'),
+                    201: __('A new groupchat has been created')
                 },
 
                 disconnect_messages: {
-                    301: __('You have been banned from this room'),
-                    307: __('You have been kicked from this room'),
-                    321: __("You have been removed from this room because of an affiliation change"),
-                    322: __("You have been removed from this room because the room has changed to members-only and you're not a member"),
-                    332: __("You have been removed from this room because the MUC (Multi-user chat) service is being shut down")
+                    301: __('You have been banned from this groupchat'),
+                    307: __('You have been kicked from this groupchat'),
+                    321: __("You have been removed from this groupchat because of an affiliation change"),
+                    322: __("You have been removed from this groupchat because the groupchat has changed to members-only and you're not a member"),
+                    332: __("You have been removed from this groupchat because the MUC (Multi-user chat) service is being shut down")
                 },
 
                 action_info_messages: {
@@ -271,19 +273,19 @@
                         'temporary': sizzle('feature[var="muc_temporary"]', stanza).length,
                         'unmoderated': sizzle('feature[var="muc_unmoderated"]', stanza).length,
                         'label_desc': __('Description:'),
-                        'label_jid': __('Room Address (JID):'),
-                        'label_occ': __('Occupants:'),
+                        'label_jid': __('Groupchat Address (JID):'),
+                        'label_occ': __('Participants:'),
                         'label_features': __('Features:'),
                         'label_requires_auth': __('Requires authentication'),
                         'label_hidden': __('Hidden'),
                         'label_requires_invite': __('Requires an invitation'),
                         'label_moderated': __('Moderated'),
                         'label_non_anon': __('Non-anonymous'),
-                        'label_open_room': __('Open room'),
-                        'label_permanent_room': __('Permanent room'),
+                        'label_open_room': __('Open'),
+                        'label_permanent_room': __('Permanent'),
                         'label_public': __('Public'),
                         'label_semi_anon':  __('Semi-anonymous'),
-                        'label_temp_room':  __('Temporary room'),
+                        'label_temp_room':  __('Temporary'),
                         'label_unmoderated': __('Unmoderated')
                     }));
             }
@@ -321,7 +323,7 @@
 
                 toHTML () {
                     return tpl_list_chatrooms_modal(_.extend(this.model.toJSON(), {
-                        'heading_list_chatrooms': __('Query for Chatrooms'),
+                        'heading_list_chatrooms': __('Query for Groupchats'),
                         'label_server_address': __('Server address'),
                         'label_query': __('Show rooms'),
                         'server_placeholder': __('conference.example.org')
@@ -362,8 +364,8 @@
                     div.innerHTML = tpl_room_item({
                         'name': Strophe.xmlunescape(name),
                         'jid': room.getAttribute('jid'),
-                        'open_title': __('Click to open this room'),
-                        'info_title': __('Show more information on this room')
+                        'open_title': __('Click to open this groupchat'),
+                        'info_title': __('Show more information on this groupchat')
                     });
                     return div.firstElementChild;
                 },
@@ -447,8 +449,8 @@
 
                 toHTML () {
                     return tpl_add_chatroom_modal(_.extend(this.model.toJSON(), {
-                        'heading_new_chatroom': __('Enter a new Chatroom'),
-                        'label_room_address': __('Room address'),
+                        'heading_new_chatroom': __('Enter a new Groupchat'),
+                        'label_room_address': __('Groupchat address'),
                         'label_nickname': __('Optional nickname'),
                         'chatroom_placeholder': __('name@conference.example.org'),
                         'label_join': __('Join'),
@@ -493,8 +495,10 @@
                 toHTML () {
                     return tpl_chatroom_details_modal(_.extend(
                         this.model.toJSON(), {
+                            '_': _,
                             '__': __,
-                            'display_name': this.model.getDisplayName(),
+                            'topic': u.addHyperlinks(xss.filterXSS(_.get(this.model.get('subject'), 'text'), {'whiteList': {}})),
+                            'display_name': __('Groupchat info for %1$s', this.model.getDisplayName()),
                             'num_occupants': this.model.occupants.length
                         })
                     );
@@ -525,7 +529,7 @@
                     'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
                     'click .toggle-smiley': 'toggleEmojiMenu',
                     'click .upload-file': 'toggleFileUpload',
-                    'keypress .chat-textarea': 'keyPressed',
+                    'keydown .chat-textarea': 'keyPressed',
                     'input .chat-textarea': 'inputChanged'
                 },
 
@@ -601,13 +605,13 @@
                      */
                     if (_.isNull(this.el.querySelector('.chat-area'))) {
                         const container_el = this.el.querySelector('.chatroom-body');
-                        container_el.innerHTML = tpl_chatarea({
+                        container_el.insertAdjacentHTML('beforeend', tpl_chatarea({
                             'label_message': __('Message'),
                             'label_send': __('Send'),
                             'show_send_button': _converse.show_send_button,
                             'show_toolbar': _converse.show_toolbar,
                             'unread_msgs': __('You have unread messages')
-                        });
+                        }));
                         container_el.insertAdjacentElement('beforeend', this.occupantsview.el);
                         this.renderToolbar(tpl_chatroom_toolbar);
                         this.content = this.el.querySelector('.chat-content');
@@ -662,9 +666,9 @@
                     return tpl_chatroom_head(
                         _.extend(this.model.toJSON(), {
                             'Strophe': Strophe,
-                            'info_close': __('Close and leave this room'),
-                            'info_configure': __('Configure this room'),
-                            'info_details': __('Show more details about this room'),
+                            'info_close': __('Close and leave this groupchat'),
+                            'info_configure': __('Configure this groupchat'),
+                            'info_details': __('Show more details about this groupchat'),
                             'description': this.model.get('description') || ''
                     }));
                 },
@@ -708,7 +712,7 @@
                     return _.extend(
                         _converse.ChatBoxView.prototype.getToolbarOptions.apply(this, arguments),
                         {
-                          label_hide_occupants: __('Hide the list of occupants'),
+                          label_hide_occupants: __('Hide the list of participants'),
                           show_occupants_toggle: this.is_chatroom && _converse.visible_toolbar_buttons.toggle_occupants
                         }
                     );
@@ -867,20 +871,20 @@
                         case 'help':
                             this.showHelpMessages([
                                 `<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`,
-                                `<strong>/ban</strong>: ${__('Ban user from room')}`,
+                                `<strong>/ban</strong>: ${__('Ban user from groupchat')}`,
                                 `<strong>/clear</strong>: ${__('Remove messages')}`,
                                 `<strong>/deop</strong>: ${__('Change user role to participant')}`,
                                 `<strong>/help</strong>: ${__('Show this menu')}`,
-                                `<strong>/kick</strong>: ${__('Kick user from room')}`,
+                                `<strong>/kick</strong>: ${__('Kick user from groupchat')}`,
                                 `<strong>/me</strong>: ${__('Write in 3rd person')}`,
                                 `<strong>/member</strong>: ${__('Grant membership to a user')}`,
                                 `<strong>/mute</strong>: ${__("Remove user's ability to post messages")}`,
                                 `<strong>/nick</strong>: ${__('Change your nickname')}`,
                                 `<strong>/op</strong>: ${__('Grant moderator role to user')}`,
-                                `<strong>/owner</strong>: ${__('Grant ownership of this room')}`,
+                                `<strong>/owner</strong>: ${__('Grant ownership of this groupchat')}`,
                                 `<strong>/revoke</strong>: ${__("Revoke user's membership")}`,
-                                `<strong>/subject</strong>: ${__('Set room subject')}`,
-                                `<strong>/topic</strong>: ${__('Set room subject (alias for /subject)')}`,
+                                `<strong>/subject</strong>: ${__('Set groupchat subject')}`,
+                                `<strong>/topic</strong>: ${__('Set groupchat subject (alias for /subject)')}`,
                                 `<strong>/voice</strong>: ${__('Allow muted user to post messages')}`
                             ]);
                             break;
@@ -1044,7 +1048,7 @@
                     fieldset_el.insertAdjacentHTML('beforeend', `<legend>${title}</legend>`);
 
                     if (instructions && instructions !== title) {
-                        fieldset_el.insertAdjacentHTML('beforeend', `<p class="instructions">${instructions}</p>`);
+                        fieldset_el.insertAdjacentHTML('beforeend', `<p class="form-help">${instructions}</p>`);
                     }
                     _.each(fields, function (field) {
                         fieldset_el.insertAdjacentHTML('beforeend', u.xForm2webForm(field, stanza));
@@ -1226,7 +1230,7 @@
                         tpl_chatroom_nickname_form({
                             heading: __('Please choose your nickname'),
                             label_nickname: __('Nickname'),
-                            label_join: __('Enter room'),
+                            label_join: __('Enter groupchat'),
                             validation_message: message
                         }));
                     this.model.save('connection_status', converse.ROOMSTATUS.NICKNAME_REQUIRED);
@@ -1249,7 +1253,7 @@
 
                     container_el.insertAdjacentHTML('beforeend',
                         tpl_chatroom_password_form({
-                            heading: __('This chatroom requires a password'),
+                            heading: __('This groupchat requires a password'),
                             label_password: __('Password: '),
                             label_submit: __('Submit')
                         }));
@@ -1259,16 +1263,19 @@
                         'submit', this.submitPassword.bind(this), false);
                 },
 
-                showDisconnectMessage (msg) {
+                showDisconnectMessages (msgs) {
+                    if (_.isString(msgs)) {
+                        msgs = [msgs];
+                    }
                     u.hideElement(this.el.querySelector('.chat-area'));
                     u.hideElement(this.el.querySelector('.occupants'));
                     _.each(this.el.querySelectorAll('.spinner'), u.removeElement);
-                    this.el.querySelector('.chatroom-body').insertAdjacentHTML(
-                        'beforeend',
-                        tpl_chatroom_disconnect({
-                            'disconnect_message': msg
-                        })
-                    );
+                    const container = this.el.querySelector('.disconnect-container');
+                    container.innerHTML = tpl_chatroom_disconnect({
+                        '_': _,
+                        'disconnect_messages': msgs
+                    })
+                    u.showElement(container);
                 },
 
                 getMessageFromStatus (stat, stanza, is_self) {
@@ -1346,13 +1353,15 @@
                      * information to the user.
                      */
                     if (notification.disconnected) {
-                        this.showDisconnectMessage(notification.disconnection_message);
+                        const messages = [];
+                        messages.push(notification.disconnection_message);
                         if (notification.actor) {
-                            this.showDisconnectMessage(__('This action was done by %1$s.', notification.actor));
+                            messages.push(__('This action was done by %1$s.', notification.actor));
                         }
                         if (notification.reason) {
-                            this.showDisconnectMessage(__('The reason given is: "%1$s".', notification.reason));
+                            messages.push(__('The reason given is: "%1$s".', notification.reason));
                         }
+                        this.showDisconnectMessages(messages);
                         this.model.save('connection_status', converse.ROOMSTATUS.DISCONNECTED);
                         return;
                     }
@@ -1389,14 +1398,14 @@
                                 'data': `data-leavejoin="${nick}"`,
                                 'isodate': moment().format(),
                                 'extra_classes': 'chat-event',
-                                'message': __('%1$s has left and re-entered the room', nick)
+                                'message': __('%1$s has left and re-entered the groupchat', nick)
                             });
                     } else {
                         let  message;
                         if (_.isNil(stat)) {
-                            message = __('%1$s has entered the room', nick);
+                            message = __('%1$s has entered the groupchat', nick);
                         } else {
-                            message = __('%1$s has entered the room. "%2$s"', nick, stat);
+                            message = __('%1$s has entered the groupchat. "%2$s"', nick, stat);
                         }
                         const data = {
                             'data': `data-join="${nick}"`,
@@ -1429,9 +1438,9 @@
 
                         let message;
                         if (_.isNil(stat)) {
-                            message = __('%1$s has entered and left the room', nick);
+                            message = __('%1$s has entered and left the groupchat', nick);
                         } else {
-                            message = __('%1$s has entered and left the room. "%2$s"', nick, stat);
+                            message = __('%1$s has entered and left the groupchat. "%2$s"', nick, stat);
                         }
                         last_el.outerHTML =
                             tpl_info({
@@ -1443,9 +1452,9 @@
                     } else {
                         let message;
                         if (_.isNil(stat)) {
-                            message = __('%1$s has left the room', nick);
+                            message = __('%1$s has left the groupchat', nick);
                         } else {
-                            message = __('%1$s has left the room. "%2$s"', nick, stat);
+                            message = __('%1$s has left the groupchat. "%2$s"', nick, stat);
                         }
                         const data = {
                             'message': message,
@@ -1488,25 +1497,32 @@
                         if (!_.isNull(error.querySelector('not-authorized'))) {
                             this.renderPasswordForm();
                         } else if (!_.isNull(error.querySelector('registration-required'))) {
-                            this.showDisconnectMessage(__('You are not on the member list of this room.'));
+                            this.showDisconnectMessages(__('You are not on the member list of this groupchat.'));
                         } else if (!_.isNull(error.querySelector('forbidden'))) {
-                            this.showDisconnectMessage(__('You have been banned from this room.'));
+                            this.showDisconnectMessages(__('You have been banned from this groupchat.'));
                         }
                     } else if (error.getAttribute('type') === 'modify') {
                         if (!_.isNull(error.querySelector('jid-malformed'))) {
-                            this.showDisconnectMessage(__('No nickname was specified.'));
+                            this.showDisconnectMessages(__('No nickname was specified.'));
                         }
                     } else if (error.getAttribute('type') === 'cancel') {
                         if (!_.isNull(error.querySelector('not-allowed'))) {
-                            this.showDisconnectMessage(__('You are not allowed to create new rooms.'));
+                            this.showDisconnectMessages(__('You are not allowed to create new rooms.'));
                         } else if (!_.isNull(error.querySelector('not-acceptable'))) {
-                            this.showDisconnectMessage(__("Your nickname doesn't conform to this room's policies."));
+                            this.showDisconnectMessages(__("Your nickname doesn't conform to this groupchat's policies."));
                         } else if (!_.isNull(error.querySelector('conflict'))) {
                             this.onNicknameClash(presence);
                         } else if (!_.isNull(error.querySelector('item-not-found'))) {
-                            this.showDisconnectMessage(__("This room does not (yet) exist."));
+                            this.showDisconnectMessages(__("This groupchat does not (yet) exist."));
                         } else if (!_.isNull(error.querySelector('service-unavailable'))) {
-                            this.showDisconnectMessage(__("This room has reached its maximum number of occupants."));
+                            this.showDisconnectMessages(__("This groupchat has reached its maximum number of participants."));
+                        } else if (!_.isNull(error.querySelector('remote-server-not-found'))) {
+                            const messages = [__("Remote server not found")];
+                            const reason = _.get(error.querySelector('text'), 'textContent');
+                            if (reason) {
+                                messages.push(__('The explanation given is: "%1$s".', reason));
+                            }
+                            this.showDisconnectMessages(messages);
                         }
                     }
                 },
@@ -1589,7 +1605,7 @@
 
                 render () {
                     this.el.innerHTML = tpl_room_panel({
-                        'heading_chatrooms': __('Chatrooms'),
+                        'heading_chatrooms': __('Groupchats'),
                         'title_new_room': __('Add a new room'),
                         'title_list_rooms': __('Query for rooms')
                     });
@@ -1630,8 +1646,8 @@
                               'hint_show': _converse.PRETTY_CHAT_STATUS[show],
                               'hint_occupant': __('Click to mention %1$s in your message.', this.model.get('nick')),
                               'desc_moderator': __('This user is a moderator.'),
-                              'desc_participant': __('This user can send messages in this room.'),
-                              'desc_visitor': __('This user can NOT send messages in this room.'),
+                              'desc_participant': __('This user can send messages in this groupchat.'),
+                              'desc_visitor': __('This user can NOT send messages in this groupchat.'),
                               'label_moderator': __('Moderator'),
                               'label_visitor': __('Visitor'),
                               'label_owner': __('Owner'),
@@ -1688,7 +1704,7 @@
                     this.el.innerHTML = tpl_chatroom_sidebar(
                         _.extend(this.chatroomview.model.toJSON(), {
                             'allow_muc_invitations': _converse.allow_muc_invitations,
-                            'label_occupants': __('Occupants')
+                            'label_occupants': __('Participants')
                         })
                     );
                     if (_converse.allow_muc_invitations) {

+ 19 - 15
src/converse-muc.js

@@ -204,7 +204,7 @@
                             this.onPresence(stanza);
                             return true;
                         },
-                        Strophe.NS.MUC, 'presence', null, null, room_jid,
+                        null, 'presence', null, null, room_jid,
                         {'ignoreNamespaceFragment': true, 'matchBareFromJid': true}
                     );
                     this.message_handler = _converse.connection.addHandler((stanza) => {
@@ -331,8 +331,9 @@
                                 this.parseRoomFeatures(stanza);
                                 resolve()
                             }).catch((err) => {
-                                _converse.log(err, Strophe.LogLevel.ERROR);
-                                reject(new Error("Could not parse the room features"));
+                                _converse.log("Could not parse the room features", Strophe.LogLevel.WARN);
+                                _converse.log(err, Strophe.LogLevel.WARN);
+                                reject(err);
                             });
                     });
                 },
@@ -848,22 +849,24 @@
                     if (!_.isNull(forwarded)) {
                         stanza = forwarded.querySelector('message');
                     }
-                    const jid = stanza.getAttribute('from'),
-                        resource = Strophe.getResourceFromJid(jid),
-                        sender = resource && Strophe.unescapeNode(resource) || '',
-                        subject = _.propertyOf(stanza.querySelector('subject'))('textContent');
-
                     if (this.isDuplicate(stanza, original_stanza)) {
                         return;
                     }
-                    if (subject) {
-                        u.safeSave(this, {'subject': {'author': sender, 'text': subject}});
-                    }
-                    if (sender === '') {
-                        return;
+                    const jid = stanza.getAttribute('from'),
+                          resource = Strophe.getResourceFromJid(jid),
+                          sender = resource && Strophe.unescapeNode(resource) || '';
+
+                    if (!this.handleMessageCorrection(stanza)) {
+                        const subject = _.propertyOf(stanza.querySelector('subject'))('textContent');
+                        if (subject) {
+                            u.safeSave(this, {'subject': {'author': sender, 'text': subject}});
+                        }
+                        if (sender === '') {
+                            return;
+                        }
+                        this.incrementUnreadMsgCounter(original_stanza);
+                        this.createMessage(stanza, original_stanza);
                     }
-                    this.incrementUnreadMsgCounter(original_stanza);
-                    this.createMessage(stanza, original_stanza);
                     if (sender !== this.get('nick')) {
                         // We only emit an event if it's not our own message
                         _converse.emit('message', {'stanza': original_stanza, 'chatbox': this});
@@ -1040,6 +1043,7 @@
                         _.each(_.difference(old_jids, jids), (removed_jid) => {
                             // Remove absent occupants who've been removed from
                             // the members lists.
+                            if (removed_jid === _converse.bare_jid) { return; }
                             const occupant = this.findOccupant({'jid': removed_jid});
                             if (!occupant) { return; }
                             if (occupant.get('show') === 'offline') {

+ 14 - 11
src/converse-roomslist.js

@@ -33,7 +33,7 @@
          *
          * NB: These plugins need to have already been loaded via require.js.
          */
-        dependencies: ["converse-controlbox", "converse-muc", "converse-bookmarks"],
+        dependencies: ["converse-singleton", "converse-controlbox", "converse-muc", "converse-bookmarks"],
 
         initialize () {
             /* The initialize function gets called as soon as the plugin is
@@ -58,6 +58,7 @@
                     this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
                         b64_sha1(`converse.open-rooms-{_converse.bare_jid}`));
                     _converse.chatboxes.on('add', this.onChatBoxAdded, this);
+                    _converse.chatboxes.on('change:hidden', this.onChatBoxChanged, this);
                     _converse.chatboxes.on('change:bookmarked', this.onChatBoxChanged, this);
                     _converse.chatboxes.on('change:name', this.onChatBoxChanged, this);
                     _converse.chatboxes.on('change:num_unread', this.onChatBoxChanged, this);
@@ -98,13 +99,14 @@
 
             _converse.RoomsListElementView = Backbone.VDOMView.extend({
                 events: {
-                    'click a.room-info': 'showRoomDetailsModal'
+                    'click .room-info': 'showRoomDetailsModal'
                 },
 
                 initialize () {
                     this.model.on('destroy', this.remove, this);
                     this.model.on('remove', this.remove, this);
                     this.model.on('change:bookmarked', this.render, this);
+                    this.model.on('change:hidden', this.render, this);
                     this.model.on('change:name', this.render, this);
                     this.model.on('change:num_unread', this.render, this);
                     this.model.on('change:num_unread_general', this.render, this);
@@ -118,12 +120,13 @@
                             // supported by the XMPP server. So we can use it
                             // as a check for support (other ways of checking are async).
                             'allow_bookmarks': _converse.allow_bookmarks && _converse.bookmarks,
-                            'info_leave_room': __('Leave this room'),
-                            'info_remove_bookmark': __('Unbookmark this room'),
-                            'info_add_bookmark': __('Bookmark this room'),
-                            'info_title': __('Show more information on this room'),
+                            'currently_open': _converse.isSingleton() && !this.model.get('hidden'),
+                            'info_leave_room': __('Leave this groupchat'),
+                            'info_remove_bookmark': __('Unbookmark this groupchat'),
+                            'info_add_bookmark': __('Bookmark this groupchat'),
+                            'info_title': __('Show more information on this groupchat'),
                             'name': this.getRoomsListElementName(),
-                            'open_title': __('Click to open this room')
+                            'open_title': __('Click to open this groupchat')
                         }));
                 },
 
@@ -153,7 +156,7 @@
                 events: {
                     'click .add-bookmark': 'addBookmark',
                     'click .close-room': 'closeRoom',
-                    'click .rooms-toggle': 'toggleRoomsList',
+                    'click .list-toggle': 'toggleRoomsList',
                     'click .remove-bookmark': 'removeBookmark',
                     'click .open-room': 'openRoom',
                 },
@@ -181,8 +184,8 @@
                 render () {
                     this.el.innerHTML = tpl_rooms_list({
                         'toggle_state': this.list_model.get('toggle-state'),
-                        'desc_rooms': __('Click to toggle the rooms list'),
-                        'label_rooms': __('Open Rooms'),
+                        'desc_rooms': __('Click to toggle the list of open groupchats'),
+                        'label_rooms': __('Open Groupchats'),
                         '_converse': _converse
                     });
                     if (this.list_model.get('toggle-state') !== _converse.OPENED) {
@@ -225,7 +228,7 @@
                     ev.preventDefault();
                     const name = ev.target.getAttribute('data-room-name');
                     const jid = ev.target.getAttribute('data-room-jid');
-                    if (confirm(__("Are you sure you want to leave the room %1$s?", name))) {
+                    if (confirm(__("Are you sure you want to leave the groupchat %1$s?", name))) {
                         // TODO: replace with API call
                         _converse.chatboxviews.get(jid).close();
                     }

+ 21 - 1
src/converse-roster.js

@@ -232,10 +232,20 @@
                         'user_id': Strophe.getNodeFromJid(jid)
                     }, attributes));
 
+                    this.setChatBox();
+
                     this.presence.on('change:show', () => _converse.emit('contactPresenceChanged', this));
                     this.presence.on('change:show', () => this.trigger('presenceChanged'));
                 },
 
+                setChatBox (chatbox=null) {
+                    chatbox = chatbox || _converse.chatboxes.get(this.get('jid'));
+                    if (chatbox) {
+                        this.chatbox = chatbox;
+                        this.chatbox.on('change:hidden', this.render, this);
+                    }
+                },
+
                 getDisplayName () {
                     return this.vcard.get('fullname') || this.get('jid');
                 },
@@ -450,7 +460,7 @@
                      *    (String) name - The name of that user
                      *    (Array of Strings) groups - Any roster groups the user might belong to
                      *    (Function) callback - A function to call once the IQ is returned
-                     *    (Function) errback - A function to call if an error occured
+                     *    (Function) errback - A function to call if an error occurred
                      */
                     name = _.isEmpty(name)? jid: name;
                     const iq = $iq({type: 'set'})
@@ -798,6 +808,16 @@
 
             /********** Event Handlers *************/
 
+            function updateUnreadCounter (chatbox) {
+                const contact = _converse.roster.findWhere({'jid': chatbox.get('jid')});
+                if (!_.isUndefined(contact)) {
+                    contact.save({'num_unread': chatbox.get('num_unread')});
+                }
+            }
+            _converse.api.listen.on('chatBoxesInitialized', () => {
+                _converse.chatboxes.on('change:num_unread', updateUnreadCounter)
+            });
+
             _converse.api.listen.on('beforeTearDown', _converse.unregisterPresenceHandler());
 
             _converse.api.listen.on('afterTearDown', () => {

+ 52 - 25
src/converse-rosterview.js

@@ -96,7 +96,6 @@
                 'xa': __('This contact is away for an extended period'),
                 'away': __('This contact is away')
             };
-            const LABEL_CONTACTS = __('Contacts');
             const LABEL_GROUPS = __('Groups');
             const HEADER_CURRENT_CONTACTS =  __('My contacts');
             const HEADER_PENDING_CONTACTS = __('Pending contacts');
@@ -358,7 +357,7 @@
 
             _converse.RosterContactView = Backbone.NativeView.extend({
                 tagName: 'li',
-                className: 'd-flex hidden controlbox-padded',
+                className: 'list-item d-flex hidden controlbox-padded',
 
                 events: {
                     "click .accept-xmpp-request": "acceptRequest",
@@ -369,10 +368,11 @@
 
                 initialize () {
                     this.model.on("change", this.render, this);
+                    this.model.on("highlight", this.highlight, this);
                     this.model.on("destroy", this.remove, this);
                     this.model.on("open", this.openChat, this);
                     this.model.on("remove", this.remove, this);
-                    
+
                     this.model.presence.on("change:show", this.render, this);
                     this.model.vcard.on('change:fullname', this.render, this);
                 },
@@ -383,11 +383,10 @@
                         u.hideElement(this.el);
                         return this;
                     }
-                    const item = this.model,
-                        ask = item.get('ask'),
-                        show = item.presence.get('show'),
-                        requesting  = item.get('requesting'),
-                        subscription = item.get('subscription');
+                    const ask = this.model.get('ask'),
+                        show = this.model.presence.get('show'),
+                        requesting  = this.model.get('requesting'),
+                        subscription = this.model.get('subscription');
 
                     const classes_to_remove = [
                         'current-xmpp-contact',
@@ -403,6 +402,18 @@
                         });
                     this.el.classList.add(show);
                     this.el.setAttribute('data-status', show);
+                    this.highlight();
+
+                    if (_converse.isSingleton()) {
+                        const chatbox = _converse.chatboxes.get(this.model.get('jid'));
+                        if (chatbox) {
+                            if (chatbox.get('hidden')) {
+                                this.el.classList.remove('open');
+                            } else {
+                                this.el.classList.add('open');
+                            }
+                        }
+                    }
 
                     if ((ask === 'subscribe') || (subscription === 'from')) {
                         /* ask === 'subscribe'
@@ -416,20 +427,20 @@
                          *
                          *  So in both cases the user is a "pending" contact.
                          */
-                        const display_name = item.getDisplayName();
+                        const display_name = this.model.getDisplayName();
                         this.el.classList.add('pending-xmpp-contact');
                         this.el.innerHTML = tpl_pending_contact(
-                            _.extend(item.toJSON(), {
+                            _.extend(this.model.toJSON(), {
                                 'display_name': display_name,
                                 'desc_remove': __('Click to remove %1$s as a contact', display_name),
                                 'allow_chat_pending_contacts': _converse.allow_chat_pending_contacts
                             })
                         );
                     } else if (requesting === true) {
-                        const display_name = item.getDisplayName();
+                        const display_name = this.model.getDisplayName();
                         this.el.classList.add('requesting-xmpp-contact');
                         this.el.innerHTML = tpl_requesting_contact(
-                            _.extend(item.toJSON(), {
+                            _.extend(this.model.toJSON(), {
                                 'display_name': display_name,
                                 'desc_accept': __("Click to accept the contact request from %1$s", display_name),
                                 'desc_decline': __("Click to decline the contact request from %1$s", display_name),
@@ -440,11 +451,26 @@
                         this.el.classList.add('current-xmpp-contact');
                         this.el.classList.remove(_.without(['both', 'to'], subscription)[0]);
                         this.el.classList.add(subscription);
-                        this.renderRosterItem(item);
+                        this.renderRosterItem(this.model);
                     }
                     return this;
                 },
 
+                highlight () {
+                    /* If appropriate, highlight the contact (by adding the 'open' class).
+                     */
+                    if (_converse.isSingleton()) {
+                        const chatbox = _converse.chatboxes.get(this.model.get('jid'));
+                        if (chatbox) {
+                            if (chatbox.get('hidden')) {
+                                this.el.classList.remove('open');
+                            } else {
+                                this.el.classList.add('open');
+                            }
+                        }
+                    }
+                },
+
                 renderRosterItem (item) {
                     let status_icon = 'fa-times-circle';
                     const show = item.presence.get('show') || 'offline';
@@ -880,15 +906,14 @@
                 },
 
                 updateChatBox (contact) {
-                    const chatbox = _converse.chatboxes.get(contact.get('jid')),
-                        changes = {};
-                    if (!chatbox) {
+                    if (!this.model.chatbox) {
                         return this;
                     }
+                    const changes = {};
                     if (_.has(contact.changed, 'status')) {
                         changes.status = contact.get('status');
                     }
-                    chatbox.save(changes);
+                    this.model.chatbox.save(changes);
                     return this;
                 },
 
@@ -937,21 +962,23 @@
 
 
             /* -------- Event Handlers ----------- */
-
-            function updateUnreadCounter (chatbox) {
-                const contact = _.head(_converse.roster.where({'jid': chatbox.get('jid')}));
-                if (!_.isUndefined(contact)) {
-                    contact.save({'num_unread': chatbox.get('num_unread')});
-                }
-            }
             _converse.api.listen.on('chatBoxesInitialized', () => {
-                _converse.chatboxes.on('change:num_unread', updateUnreadCounter)
+
+                _converse.chatboxes.on('change:hidden', (chatbox) => {
+                    const contact = _converse.roster.findWhere({'jid': chatbox.get('jid')});
+                    if (!_.isUndefined(contact)) {
+                        contact.trigger('highlight', contact);
+                    }
+                });
             });
 
             function initRoster () {
                 /* Create an instance of RosterView once the RosterGroups
                  * collection has been created (in converse-core.js)
                  */
+                if (_converse.authentication === _converse.ANONYMOUS) {
+                    return;
+                }
                 _converse.rosterview = new _converse.RosterView({
                     'model': _converse.rostergroups
                 });

+ 9 - 5
src/converse-singleton.js

@@ -50,7 +50,7 @@
                     if (chatbox.get('id') === 'controlbox') {
                         return true;
                     }
-                    if (_.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode)) {
+                    if (_converse.isSingleton()) {
                         const any_chats_visible = _converse.chatboxes
                             .filter((cb) => cb.get('id') != 'controlbox')
                             .filter((cb) => !cb.get('hidden')).length > 0;
@@ -67,7 +67,8 @@
 
                 createChatBox (jid, attrs) {
                     /* Make sure new chat boxes are hidden by default. */
-                    if (_.includes(['mobile', 'fullscreen', 'embedded'], this.__super__._converse.view_mode)) {
+                    const { _converse } = this.__super__;
+                    if (_converse.isSingleton()) {
                         attrs = attrs || {};
                         attrs.hidden = true;
                     }
@@ -77,7 +78,8 @@
 
             ChatBoxView: {
                 shouldShowOnTextMessage () {
-                    if (_.includes(['mobile', 'fullscreen', 'embedded'], this.__super__._converse.view_mode)) {
+                    const { _converse } = this.__super__;
+                    if (_converse.isSingleton()) {
                         return false;
                     } else { 
                         return this.__super__.shouldShowOnTextMessage.apply(this, arguments);
@@ -89,7 +91,8 @@
                      * time. So before opening a chat, we make sure all other
                      * chats are hidden.
                      */
-                    if (_.includes(['mobile', 'fullscreen', 'embedded'], this.__super__._converse.view_mode)) {
+                    const { _converse } = this.__super__;
+                    if (_converse.isSingleton()) {
                         _.each(this.__super__._converse.chatboxviews.xget(this.model.get('id')), hideChat);
                         this.model.set('hidden', false);
                     }
@@ -99,7 +102,8 @@
 
             ChatRoomView: {
                 show (focus) {
-                    if (_.includes(['mobile', 'fullscreen', 'embedded'], this.__super__._converse.view_mode)) {
+                    const { _converse } = this.__super__;
+                    if (_converse.isSingleton()) {
                         _.each(this.__super__._converse.chatboxviews.xget(this.model.get('id')), hideChat);
                         this.model.set('hidden', false);
                     }

+ 0 - 6
src/templates/action.html

@@ -1,6 +0,0 @@
-<div class="message chat-msg chat-action {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-from="{{{o.from}}}">
-    <span class="chat-msg-heading">
-        <span class="chat-msg-author">**{{{o.username}}}</span>
-    </span>
-    <p class="chat-msg-text"><!-- message gets added here via renderMessage --></p>
-</div>

+ 2 - 4
src/templates/bookmark.html

@@ -1,8 +1,6 @@
 <div class="list-item controlbox-padded room-item available-chatroom d-flex flex-row {[ if (o.hidden) { ]} hidden {[ } ]}" data-room-jid="{{{o.jid}}}">
-    <a class="open-room w-100" data-room-jid="{{{o.jid}}}" title="{{{o.open_title}}}" href="#">{{{o.name}}}</a>
-    <a class="remove-bookmark fa fa-bookmark align-self-center {[ if (o.bookmarked) { ]} button-on {[ } ]}"
+    <a class="list-item-link open-room w-100" data-room-jid="{{{o.jid}}}" title="{{{o.open_title}}}" href="#">{{{o.name}}}</a>
+    <a class="list-item-action remove-bookmark fa fa-bookmark align-self-center {[ if (o.bookmarked) { ]} button-on {[ } ]}"
         data-room-jid="{{{o.jid}}}" data-bookmark-name="{{{o.name}}}"
         title="{{{o.info_remove_bookmark}}}" href="#">&nbsp;</a>
-    <a class="room-info fa fa-info-circle align-self-center" data-room-jid="{{{o.jid}}}"
-        title="{{{o.info_title}}}" href="#">&nbsp;</a>
 </div>

+ 1 - 1
src/templates/bookmarks_list.html

@@ -1,4 +1,4 @@
-<a href="#" class="rooms-toggle bookmarks-toggle controlbox-padded" title="{{{o.desc_bookmarks}}}">
+<a href="#" class="list-toggle bookmarks-toggle controlbox-padded" title="{{{o.desc_bookmarks}}}">
     <span class="fa {[ if (o.toggle_state === o._converse.OPENED) { ]} fa-caret-down {[ } else { ]} fa-caret-right {[ } ]}">
     </span> {{{o.label_bookmarks}}}</a>
 <div class="items-list bookmarks rooms-list {[ if (o.toggle_state !== o._converse.OPENED) { ]} hidden {[ } ]}"></div>

+ 3 - 1
src/templates/chatroom.html

@@ -1,4 +1,6 @@
 <div class="flyout box-flyout">
     <div class="chat-head chat-head-chatroom row no-gutters"></div>
-    <div class="chat-body chatroom-body row no-gutters"></div>
+    <div class="chat-body chatroom-body row no-gutters">
+        <div class="disconnect-container hidden"></div>
+    </div>
 </div>

+ 10 - 3
src/templates/chatroom_details_modal.html

@@ -1,15 +1,19 @@
-<div class="modal fade" id="room-details-modal" tabindex="-1" role="dialog" aria-labelledby="user-profile-modal-label" aria-hidden="true">
+<div class="modal fade" id="room-details-modal" tabindex="-1" role="dialog" aria-labelledby="room-details-modal-label" aria-hidden="true">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title" id="user-profile-modal-label">{{{o.display_name}}}</h5>
+                <h5 class="modal-title" id="room-details-modal-label">{{{o.display_name}}}</h5>
                 <button type="button" class="close" data-dismiss="modal" aria-label="{{{o.label_close}}}"><span aria-hidden="true">&times;</span></button>
             </div>
             <div class="modal-body">
                 <div class="room-info">
-                    <p class="room-info"><strong>{{{o.__('Room address (JID)')}}}</strong>: {{{o.jid}}}</p>
                     <p class="room-info"><strong>{{{o.__('Name')}}}</strong>: {{{o.name}}}</p>
+                    <p class="room-info"><strong>{{{o.__('Room address (JID)')}}}</strong>: {{{o.jid}}}</p>
                     <p class="room-info"><strong>{{{o.__('Description')}}}</strong>: {{{o.description}}}</p>
+                    {[ if (o.subject) { ]}
+                    <p class="room-info"><strong>{{{o.__('Topic')}}}</strong>: {{o.topic}}</p> <!-- Sanitized in converse-muc-views. We want to render links. -->
+                        <p class="room-info"><strong>{{{o.__('Topic author')}}}</strong>: {{{o._.get(o.subject, 'author')}}}</p>
+                    {[ } ]}
                     <p class="room-info"><strong>{{{o.__('Online users')}}}</strong>: {{{o.num_occupants}}}</p>
                     <p class="room-info"><strong>{{{o.__('Features')}}}</strong>:
                         <div class="chatroom-features">
@@ -58,6 +62,9 @@
                     </p>
                 </div>
             </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">{{{o.__('Close')}}}</button>
+            </div>
         </div>
     </div>
 </div>

+ 7 - 1
src/templates/chatroom_disconnect.html

@@ -1 +1,7 @@
-<p class="disconnect-msg">{{{o.disconnect_message}}}</p>
+<div class="alert alert-danger">
+    <h3 class="alert-heading disconnect-msg">{{{o.disconnect_messages[0]}}}</h3>
+
+    {[ o._.forEach(o.disconnect_messages.slice(1), function (msg) { ]}
+        <p class="disconnect-msg">{{{msg}}}</p>
+    {[ }); ]}
+</div>

+ 11 - 11
src/templates/chatroom_features.html

@@ -3,40 +3,40 @@
 {[ } ]}
 <ul class="features-list">
 {[ if (o.passwordprotected) { ]}
-<li class="feature" title="{{{ o.__('This room requires a password before entry') }}}"><span class="fa fa-lock"></span>{{{ o.__('Password protected') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat requires a password before entry') }}}"><span class="fa fa-lock"></span>{{{ o.__('Password protected') }}}</li>
 {[ } ]}
 {[ if (o.unsecured) { ]}
-<li class="feature" title="{{{ o.__('This room does not require a password upon entry') }}}"><span class="fa fa-unlock"></span>{{{ o.__('No password') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat does not require a password upon entry') }}}"><span class="fa fa-unlock"></span>{{{ o.__('No password') }}}</li>
 {[ } ]}
 {[ if (o.hidden) { ]}
-<li class="feature" title="{{{ o.__('This room is not publicly searchable') }}}"><span class="fa fa-eye-slash"></span>{{{ o.__('Hidden') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat is not publicly searchable') }}}"><span class="fa fa-eye-slash"></span>{{{ o.__('Hidden') }}}</li>
 {[ } ]}
 {[ if (o.public_room) { ]}
-<li class="feature" title="{{{ o.__('This room is publicly searchable') }}}"><span class="fa fa-eye"></span>{{{ o.__('Public') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat is publicly searchable') }}}"><span class="fa fa-eye"></span>{{{ o.__('Public') }}}</li>
 {[ } ]}
 {[ if (o.membersonly) { ]}
-<li class="feature" title="{{{ o.__('this room is restricted to members only') }}}"><span class="fa fa-address-book"></span>{{{ o.__('Members only') }}}</li>
+<li class="feature" title="{{{ o.__('this groupchat is restricted to members only') }}}"><span class="fa fa-address-book"></span>{{{ o.__('Members only') }}}</li>
 {[ } ]}
 {[ if (o.open) { ]}
-<li class="feature" title="{{{ o.__('Anyone can join this room') }}}"><span class="fa fa-globe"></span>{{{ o.__('Open') }}}</li>
+<li class="feature" title="{{{ o.__('Anyone can join this groupchat') }}}"><span class="fa fa-globe"></span>{{{ o.__('Open') }}}</li>
 {[ } ]}
 {[ if (o.persistent) { ]}
-<li class="feature" title="{{{ o.__('This room persists even if it\'s unoccupied') }}}"><span class="fa fa-save"></span>{{{ o.__('Persistent') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat persists even if it\'s unoccupied') }}}"><span class="fa fa-save"></span>{{{ o.__('Persistent') }}}</li>
 {[ } ]}
 {[ if (o.temporary) { ]}
-<li class="feature" title="{{{ o.__('This room will disappear once the last person leaves') }}}"><span class="fa fa-snowflake-o"></span>{{{ o.__('Temporary') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat will disappear once the last person leaves') }}}"><span class="fa fa-snowflake-o"></span>{{{ o.__('Temporary') }}}</li>
 {[ } ]}
 {[ if (o.nonanonymous) { ]}
-<li class="feature" title="{{{ o.__('All other room occupants can see your XMPP username') }}}"><span class="fa fa-id-card"></span>{{{ o.__('Not anonymous') }}}</li>
+<li class="feature" title="{{{ o.__('All other groupchat participants can see your XMPP username') }}}"><span class="fa fa-id-card"></span>{{{ o.__('Not anonymous') }}}</li>
 {[ } ]}
 {[ if (o.semianonymous) { ]}
 <li class="feature" title="{{{ o.__('Only moderators can see your XMPP username') }}}"><span class="fa fa-user-secret"></span>{{{ o.__('Semi-anonymous') }}}</li>
 {[ } ]}
 {[ if (o.moderated) { ]}
-<li class="feature" title="{{{ o.__('This room is being moderated') }}}"><span class="fa fa-gavel"></span>{{{ o.__('Moderated') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat is being moderated') }}}"><span class="fa fa-gavel"></span>{{{ o.__('Moderated') }}}</li>
 {[ } ]}
 {[ if (o.unmoderated) { ]}
-<li class="feature" title="{{{ o.__('This room is not being moderated') }}}"><span class="fa fa-info-circle"></span>{{{ o.__('Not moderated') }}}</li>
+<li class="feature" title="{{{ o.__('This groupchat is not being moderated') }}}"><span class="fa fa-info-circle"></span>{{{ o.__('Not moderated') }}}</li>
 {[ } ]}
 {[ if (o.mam_enabled) { ]}
 <li class="feature" title="{{{ o.__('Messages are archived on the server') }}}"><span class="fa fa-database"></span>{{{ o.__('Message archiving') }}}</li>

+ 3 - 3
src/templates/file_progress.html

@@ -1,7 +1,7 @@
 <div class="message chat-msg" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
-    <canvas class="avatar" height="36" width="36"></canvas>
-    <div class="chat-msg-content">
-        <span class="chat-msg-text">Uploading file: <strong>{{{o.file.name}}}</strong>, {{{o.filesize}}}</span>
+    <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
+    <div class="chat-msg__content">
+        <span class="chat-msg__text">Uploading file: <strong>{{{o.file.name}}}</strong>, {{{o.filesize}}}</span>
         <progress value="{{{o.progress}}}"/>
     </div>
 </div>

Some files were not shown because too many files changed in this diff