Selaa lähdekoodia

Merge remote-tracking branch 'origin/master'

Weblate 7 vuotta sitten
vanhempi
commit
394cd2bca1

+ 3 - 1
css/converse.css

@@ -1439,7 +1439,7 @@
   #converse-embedded-chat .chat-head .avatar,
   #conversejs .chat-head .avatar {
     margin-right: 0.5em;
-    border-radius: 50%;
+    border-radius: 25%;
     float: left; }
   #converse-embedded-chat .chat-head.chat-head-chatbox,
   #conversejs .chat-head.chat-head-chatbox {
@@ -2270,6 +2270,8 @@
   #conversejs #controlbox .xmpp-status-menu {
     text-align: left;
     box-shadow: 1px 4px 10px 1px rgba(0, 0, 0, 0.4); }
+    #conversejs #controlbox .xmpp-status-menu.collapsed {
+      box-shadow: none; }
     #conversejs #controlbox .xmpp-status-menu li {
       padding: 2px; }
       #conversejs #controlbox .xmpp-status-menu li a {

+ 3 - 3
css/inverse.css

@@ -1504,7 +1504,7 @@ body {
   #converse-embedded-chat .chat-head .avatar,
   #conversejs .chat-head .avatar {
     margin-right: 0.5em;
-    border-radius: 50%;
+    border-radius: 25%;
     float: left; }
   #converse-embedded-chat .chat-head.chat-head-chatbox,
   #conversejs .chat-head.chat-head-chatbox {
@@ -1921,8 +1921,6 @@ body {
     line-height: 22px; }
   #conversejs .chat-head.chat-head-chatbox .close-chatbox-button {
     display: none; }
-  #conversejs .chat-head .avatar {
-    border-radius: 25%; }
 #conversejs .chatbox {
   height: 100%;
   margin: 0;
@@ -2358,6 +2356,8 @@ body {
   #conversejs #controlbox .xmpp-status-menu {
     text-align: left;
     box-shadow: 1px 4px 10px 1px rgba(0, 0, 0, 0.4); }
+    #conversejs #controlbox .xmpp-status-menu.collapsed {
+      box-shadow: none; }
     #conversejs #controlbox .xmpp-status-menu li {
       padding: 2px; }
       #conversejs #controlbox .xmpp-status-menu li a {

+ 1 - 1
sass/_chatbox.scss

@@ -27,7 +27,7 @@
         position: relative;
         .avatar {
             margin-right: 0.5em;
-            border-radius: 50%;
+            border-radius: 25%;
             float: left;
         }
         &.chat-head-chatbox {

+ 3 - 0
sass/_controlbox.scss

@@ -506,6 +506,9 @@
         .xmpp-status-menu {
             text-align: left;
             box-shadow: 1px 4px 10px 1px rgba(0, 0, 0, 0.4);
+            &.collapsed {
+                box-shadow: none;
+            }
             li {
                 padding: 2px;
                 a {

+ 0 - 3
sass/inverse/_chatbox.scss

@@ -22,9 +22,6 @@
                 display: none;
             }
         }
-        .avatar {
-            border-radius: 25%;
-        }
     }
     .chatbox {
         height: 100%;

+ 1 - 0
src/config.js

@@ -72,6 +72,7 @@ require.config({
         "converse-notification":    "src/converse-notification",
         "converse-otr":             "src/converse-otr",
         "converse-ping":            "src/converse-ping",
+        "converse-profile":         "src/converse-profile",
         "converse-register":        "src/converse-register",
         "converse-roomslist":       "src/converse-roomslist",
         "converse-rosterview":      "src/converse-rosterview",

+ 4 - 36
src/converse-chatview.js

@@ -218,55 +218,23 @@
                 }
             });
 
-            _converse.ChatBoxHeading = Backbone.VDOMView.extend({
+            _converse.ChatBoxHeading = Backbone.View.extend({
 
                 initialize () {
                     this.model.on('change:image', this.setAvatar, this);
                     this.model.on('change:status', this.onStatusMessageChanged, this);
                     this.model.on('change:fullname', this.render, this);
-                    this.initializeAvatar();
                 },
 
-                renderHTML () {
-                    return tpl_chatbox_head(
+                render () {
+                    this.el.innerHTML = tpl_chatbox_head(
                         _.extend(this.model.toJSON(), {
                             'avatar_width': _converse.chatview_avatar_width,
                             'avatar_height': _converse.chatview_avatar_height,
                             'info_close': __('Close this chat box'),
                         })
                     );
-                },
-
-                afterRender () {
-                    this.setAvatar();
-                },
-
-                setAvatar () {
-                    this.avatar.src = `data:${this.model.get('image_type')};base64,${this.model.get('image')}`;
-                },
-
-                initializeAvatar () {
-                    var that = this;
-                    this.avatar = new Image();
-                    this.avatar.onload = function () {
-                        const canvas = that.el.querySelector('canvas');
-                        const avatar_width = _converse.chatview_avatar_width;
-                        const avatar_height = _converse.chatview_avatar_height;
-
-                        // XXX: this seems to be needed to work around the
-                        // chrome setting width/height to 0 (possible due to
-                        // no canvas data being there?)
-                        canvas.setAttribute('width', avatar_width);
-                        canvas.setAttribute('height', avatar_height);
-
-                        const ctx = canvas.getContext('2d');
-                        const ratio = this.width/this.height;
-                        if (ratio < 1) {
-                            ctx.drawImage(this, 0,0, avatar_width, avatar_height*(1/ratio));
-                        } else {
-                            ctx.drawImage(this, 0,0, avatar_width, avatar_height*ratio);
-                        }
-                    };
+                    return this;
                 },
 
                 onStatusMessageChanged (item) {

+ 2 - 127
src/converse-controlbox.js

@@ -10,44 +10,33 @@
     define(["jquery.noconflict",
             "converse-core",
             "lodash.fp",
-            "virtual-dom",
-            "vdom-parser",
             "tpl!add_contact_dropdown",
             "tpl!add_contact_form",
             "tpl!converse_brand_heading",
-            "tpl!change_status_message",
-            "tpl!chat_status",
-            "tpl!choose_status",
             "tpl!contacts_panel",
             "tpl!contacts_tab",
             "tpl!controlbox",
             "tpl!controlbox_toggle",
             "tpl!login_panel",
             "tpl!search_contact",
-            "tpl!status_option",
             "tpl!spinner",
             "converse-chatview",
-            "converse-rosterview"
+            "converse-rosterview",
+            "converse-profile"
     ], factory);
 }(this, function (
             $,
             converse,
             fp,
-            vdom,
-            vdom_parser,
             tpl_add_contact_dropdown,
             tpl_add_contact_form,
             tpl_brand_heading,
-            tpl_change_status_message,
-            tpl_chat_status,
-            tpl_choose_status,
             tpl_contacts_panel,
             tpl_contacts_tab,
             tpl_controlbox,
             tpl_controlbox_toggle,
             tpl_login_panel,
             tpl_search_contact,
-            tpl_status_option,
             tpl_spinner
         ) {
     "use strict";
@@ -552,120 +541,6 @@
             });
 
 
-            _converse.XMPPStatusView = Backbone.View.extend({
-                el: "form#set-xmpp-status",
-                events: {
-                    "click a.choose-xmpp-status": "toggleOptions",
-                    "click #fancy-xmpp-status-select a.change-xmpp-status-message": "renderStatusChangeForm",
-                    "submit": "setStatusMessage",
-                    "click .dropdown dd ul li a": "setStatus"
-                },
-
-                initialize () {
-                    this.model.on("change:status", this.updateStatusUI, this);
-                    this.model.on("change:status_message", this.updateStatusUI, this);
-                    this.model.on("update-status-ui", this.updateStatusUI, this);
-                },
-
-                render () {
-                    // Replace the default dropdown with something nicer
-                    const $select = this.$el.find('select#select-xmpp-status');
-                    const chat_status = this.model.get('status') || 'offline';
-                    const options = $('option', $select);
-                    const options_list = [];
-                    this.$el.html(tpl_choose_status());
-                    this.$el.find('#fancy-xmpp-status-select')
-                            .html(tpl_chat_status({
-                                'status_message': this.model.get('status_message') || __("I am %1$s", this.getPrettyStatus(chat_status)),
-                                'chat_status': chat_status,
-                                'desc_custom_status': __('Click here to write a custom status message'),
-                                'desc_change_status': __('Click to change your chat status')
-                                }));
-                    // iterate through all the <option> elements and add option values
-                    options.each(function () {
-                        options_list.push(tpl_status_option({
-                            'value': $(this).val(),
-                            'text': this.text
-                        }));
-                    });
-                    const $options_target = this.$el.find("#target dd ul").hide();
-                    $options_target.append(options_list.join(''));
-                    $select.remove();
-                    return this;
-                },
-
-                toggleOptions (ev) {
-                    ev.preventDefault();
-                    utils.slideInAllElements(
-                        document.querySelectorAll('#conversejs .contact-form-container')
-                    );
-                    $(ev.target).parent().parent().siblings('dd').find('ul').toggle('fast');
-                },
-
-                renderStatusChangeForm (ev) {
-                    ev.preventDefault();
-                    const status_message = _converse.xmppstatus.get('status_message') || '';
-                    const input = tpl_change_status_message({
-                        'status_message': status_message,
-                        'label_custom_status': __('Custom status'),
-                        'label_save': __('Save')
-                    });
-                    const $xmppstatus = this.$el.find('.xmpp-status');
-                    $xmppstatus.parent().addClass('no-border');
-                    $xmppstatus.replaceWith(input);
-                    this.$el.find('.custom-xmpp-status').focus().focus();
-                },
-
-                setStatusMessage (ev) {
-                    ev.preventDefault();
-                    this.model.setStatusMessage($(ev.target).find('input').val());
-                },
-
-                setStatus (ev) {
-                    ev.preventDefault();
-                    const $el = $(ev.currentTarget),
-                        value = $el.attr('data-value');
-                    if (value === 'logout') {
-                        this.$el.find(".dropdown dd ul").hide();
-                        _converse.logOut();
-                    } else {
-                        this.model.setStatus(value);
-                        this.$el.find(".dropdown dd ul").hide();
-                    }
-                },
-
-                getPrettyStatus (stat) {
-                    if (stat === 'chat') {
-                        return __('online');
-                    } else if (stat === 'dnd') {
-                        return __('busy');
-                    } else if (stat === 'xa') {
-                        return __('away for long');
-                    } else if (stat === 'away') {
-                        return __('away');
-                    } else if (stat === 'offline') {
-                        return __('offline');
-                    } else {
-                        return __(stat) || __('online');
-                    }
-                },
-
-                updateStatusUI (model) {
-                    const stat = model.get('status');
-                    // For translators: the %1$s part gets replaced with the status
-                    // Example, I am online
-                    const status_message = model.get('status_message') || __("I am %1$s", this.getPrettyStatus(stat));
-                    this.$el.find('#fancy-xmpp-status-select').removeClass('no-border').html(
-                        tpl_chat_status({
-                            'chat_status': stat,
-                            'status_message': status_message,
-                            'desc_custom_status': __('Click here to write a custom status message'),
-                            'desc_change_status': __('Click to change your chat status')
-                        }));
-                }
-            });
-
-
             _converse.ContactsPanel = Backbone.View.extend({
                 tagName: 'div',
                 className: 'controlbox-pane',

+ 1 - 0
src/converse-core.js

@@ -78,6 +78,7 @@
         'converse-notification',
         'converse-otr',
         'converse-ping',
+        'converse-profile',
         'converse-register',
         'converse-roomslist',
         'converse-rosterview',

+ 153 - 0
src/converse-profile.js

@@ -0,0 +1,153 @@
+// Converse.js (A browser based XMPP chat client)
+// http://conversejs.org
+//
+// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
+// Licensed under the Mozilla Public License (MPLv2)
+//
+/*global define */
+
+(function (root, factory) {
+    define(["converse-core",
+            "tpl!change_status_message",
+            "tpl!chat_status",
+            "tpl!choose_status",
+            "tpl!status_option",
+            "converse-vcard"
+    ], factory);
+}(this, function (
+            converse,
+            tpl_change_status_message,
+            tpl_chat_status,
+            tpl_choose_status,
+            tpl_status_option
+        ) {
+    "use strict";
+
+    const { Strophe, Backbone, Promise, utils, _, moment } = converse.env;
+
+
+    converse.plugins.add('converse-profile', {
+
+        initialize () {
+            /* The initialize function gets called as soon as the plugin is
+             * loaded by converse.js's plugin machinery.
+             */
+            const { _converse } = this,
+                { __ } = _converse;
+
+            _converse.XMPPStatusView = Backbone.View.extend({
+                el: "form#set-xmpp-status",
+                events: {
+                    "click a.choose-xmpp-status": "toggleOptions",
+                    "click #fancy-xmpp-status-select a.change-xmpp-status-message": "renderStatusChangeForm",
+                    "submit": "setStatusMessage",
+                    "click .dropdown dd ul li a": "setStatus"
+                },
+
+                initialize () {
+                    this.model.on("change:status", this.updateStatusUI, this);
+                    this.model.on("change:status_message", this.updateStatusUI, this);
+                    this.model.on("update-status-ui", this.updateStatusUI, this);
+                },
+
+                render () {
+                    // Replace the default dropdown with something nicer
+                    const select = this.el.querySelector('select#select-xmpp-status')
+                    const chat_status = this.model.get('status') || 'offline';
+                    this.el.innerHTML = tpl_choose_status();
+
+                    this.el.querySelector('#fancy-xmpp-status-select')
+                        .innerHTML = tpl_chat_status({
+                            'status_message': this.model.get('status_message') ||
+                                              __("I am %1$s", this.getPrettyStatus(chat_status)),
+                            'chat_status': chat_status,
+                            'desc_custom_status': __('Click here to write a custom status message'),
+                            'desc_change_status': __('Click to change your chat status')
+                        });
+
+                    // iterate through all the <option> elements and add option values
+                    const options_list = _.map(
+                        select.querySelectorAll('option'),
+                        function (el) {
+                            return tpl_status_option({
+                                'value': el.value,
+                                'text': el.text
+                            });
+                        }
+                    );
+                    const options_target = this.el.querySelector("#target dd ul");
+                    options_target.classList.add('collapsed');
+                    options_target.innerHTML = options_list.join('');
+                    return this;
+                },
+
+                toggleOptions (ev) {
+                    ev.preventDefault();
+                    utils.slideInAllElements(
+                        document.querySelectorAll('#conversejs .contact-form-container')
+                    );
+                    utils.slideToggleElement(this.el.querySelector("#target dd ul"));
+                },
+
+                renderStatusChangeForm (ev) {
+                    ev.preventDefault();
+                    const xmppstatus = this.el.querySelector('.xmpp-status');
+                    xmppstatus.parentNode.classList.add('no-border');
+                    xmppstatus.outerHTML = tpl_change_status_message({
+                        'status_message': _converse.xmppstatus.get('status_message') || '',
+                        'label_custom_status': __('Custom status'),
+                        'label_save': __('Save')
+                    });
+                    this.el.querySelector('.custom-xmpp-status').focus();
+                },
+
+                setStatusMessage (ev) {
+                    ev.preventDefault();
+                    this.model.setStatusMessage(ev.target.querySelector('input').value);
+                },
+
+                setStatus (ev) {
+                    ev.preventDefault();
+                    const value = ev.currentTarget.getAttribute('data-value');
+                    if (value === 'logout') {
+                        _converse.logOut();
+                    } else {
+                        this.model.setStatus(value);
+                    }
+                    utils.slideIn(this.el.querySelector("#target dd ul"));
+                },
+
+                getPrettyStatus (stat) {
+                    if (stat === 'chat') {
+                        return __('online');
+                    } else if (stat === 'dnd') {
+                        return __('busy');
+                    } else if (stat === 'xa') {
+                        return __('away for long');
+                    } else if (stat === 'away') {
+                        return __('away');
+                    } else if (stat === 'offline') {
+                        return __('offline');
+                    } else {
+                        return __(stat) || __('online');
+                    }
+                },
+
+                updateStatusUI (model) {
+                    const stat = model.get('status');
+                    // For translators: the %1$s part gets replaced with the status
+                    // Example, I am online
+                    const status_message = model.get('status_message') || __("I am %1$s", this.getPrettyStatus(stat));
+                    const fancy_select = this.el.querySelector('#fancy-xmpp-status-select');
+                    fancy_select.classList.remove('no-border');
+                    fancy_select.innerHTML = tpl_chat_status({
+                        'chat_status': stat,
+                        'status_message': status_message,
+                        'desc_custom_status': __('Click here to write a custom status message'),
+                        'desc_change_status': __('Click to change your chat status')
+                    });
+                }
+            });
+        }
+    });
+}));

+ 4 - 1
src/templates/chatbox_head.html

@@ -1,6 +1,9 @@
 <div class="chat-head chat-head-chatbox">
     <a class="chatbox-btn close-chatbox-button icon-close" title="{{{o.info_close}}}"></a>
-    <canvas height="{{{o.avatar_height}}}px" width="{{{o.avatar_width}}}px" class="avatar"></canvas>
+    <img alt="User Avatar"
+         class="avatar"
+         height="{{{o.avatar_height}}}px" width="{{{o.avatar_width}}}px"
+         src="data:{{{o.image_type}}};base64,{{{o.image}}}"/>
     <div class="chat-title">
         {[ if (o.url) { ]}
             <a href="{{{o.url}}}" target="_blank" rel="noopener" class="user">