浏览代码

Implements the functionality to set subject to the chat room.

master
hristoterezov 11 年前
父节点
当前提交
6e55d38ca9
共有 7 个文件被更改,包括 232 次插入38 次删除
  1. 50
    2
      chat.js
  2. 98
    0
      commands.js
  3. 4
    0
      css/main.css
  4. 15
    1
      css/videolayout_default.css
  5. 37
    33
      index.html
  6. 26
    2
      muc.js
  7. 2
    0
      toolbar.js

+ 50
- 2
chat.js 查看文件

39
         $('#usermsg').keydown(function (event) {
39
         $('#usermsg').keydown(function (event) {
40
             if (event.keyCode === 13) {
40
             if (event.keyCode === 13) {
41
                 event.preventDefault();
41
                 event.preventDefault();
42
-                var message = Util.escapeHtml(this.value);
42
+                var value = this.value;
43
                 $('#usermsg').val('').trigger('autosize.resize');
43
                 $('#usermsg').val('').trigger('autosize.resize');
44
                 this.focus();
44
                 this.focus();
45
-                connection.emuc.sendMessage(message, nickname);
45
+                var command = new CommandsProcessor(value);
46
+                if(command.isCommand())
47
+                {
48
+                    command.processCommand();
49
+                }
50
+                else
51
+                {
52
+                    var message = Util.escapeHtml(value);
53
+                    connection.emuc.sendMessage(message, nickname);
54
+                }
46
             }
55
             }
47
         });
56
         });
48
 
57
 
90
                 { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
99
                 { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
91
     };
100
     };
92
 
101
 
102
+    /**
103
+     * Appends error message to the conversation
104
+     * @param errorMessage the received error message.
105
+     * @param originalText the original message.
106
+     */
107
+    my.chatAddError = function(errorMessage, originalText)
108
+    {
109
+        errorMessage = Util.escapeHtml(errorMessage);
110
+        originalText = Util.escapeHtml(originalText);
111
+
112
+        $('#chatconversation').append('<div class="errorMessage"><b>Error: </b>'
113
+            + 'Your message' + (originalText? (' \"'+ originalText + '\"') : "")
114
+            + ' was not sent.' + (errorMessage? (' Reason: ' + errorMessage) : '')
115
+            +  '</div>');
116
+        $('#chatconversation').animate(
117
+            { scrollTop: $('#chatconversation')[0].scrollHeight}, 1000);
118
+
119
+    }
120
+
121
+    /**
122
+     * Sets the subject to the UI
123
+     * @param subject the subject
124
+     */
125
+    my.chatSetSubject = function(subject)
126
+    {
127
+        if(subject)
128
+            subject = subject.trim();
129
+        $('#subject').html(linkify(Util.escapeHtml(subject)));
130
+        if(subject == "")
131
+        {
132
+            $("#subject").css({display: "none"});
133
+        }
134
+        else
135
+        {
136
+            $("#subject").css({display: "block"});
137
+        }
138
+    }
139
+
140
+
93
     /**
141
     /**
94
      * Opens / closes the chat area.
142
      * Opens / closes the chat area.
95
      */
143
      */

+ 98
- 0
commands.js 查看文件

1
+/**
2
+ * Handles commands received via chat messages.
3
+ */
4
+var CommandsProcessor = (function()
5
+{
6
+    /**
7
+     * Constructs new CommandProccessor instance from a message.
8
+     * @param message the message
9
+     * @constructor
10
+     */
11
+    function CommandsPrototype(message)
12
+    {
13
+        /**
14
+         * Extracts the command from the message.
15
+         * @param message the received message
16
+         * @returns {string} the command
17
+         */
18
+        function getCommand(message)
19
+        {
20
+            if(message)
21
+            {
22
+                for(var command in commands)
23
+                {
24
+                    if(message.indexOf("/" + command) == 0)
25
+                        return command;
26
+                }
27
+            }
28
+            return "";
29
+        };
30
+
31
+        var command = getCommand(message);
32
+
33
+        /**
34
+         * Returns the name of the command.
35
+         * @returns {String} the command
36
+         */
37
+        this.getCommand = function()
38
+        {
39
+            return command;
40
+        }
41
+
42
+
43
+        var messageArgument = message.substr(command.length + 2);
44
+
45
+        /**
46
+         * Returns the arguments of the command.
47
+         * @returns {string}
48
+         */
49
+        this.getArgument = function()
50
+        {
51
+            return messageArgument;
52
+        }
53
+    }
54
+
55
+    /**
56
+     * Checks whether this instance is valid command or not.
57
+     * @returns {boolean}
58
+     */
59
+    CommandsPrototype.prototype.isCommand = function()
60
+    {
61
+        if(this.getCommand())
62
+            return true;
63
+        return false;
64
+    }
65
+
66
+    /**
67
+     * Processes the command.
68
+     */
69
+    CommandsPrototype.prototype.processCommand = function()
70
+    {
71
+        if(!this.isCommand())
72
+            return;
73
+
74
+        commands[this.getCommand()](this.getArgument());
75
+
76
+    }
77
+
78
+    /**
79
+     * Processes the data for topic command.
80
+     * @param commandArguments the arguments of the topic command.
81
+     */
82
+    var processTopic = function(commandArguments)
83
+    {
84
+        var topic = Util.escapeHtml(commandArguments);
85
+        connection.emuc.setSubject(topic);
86
+    }
87
+
88
+    /**
89
+     * List with supported commands. The keys are the names of the commands and
90
+     * the value is the function that processes the message.
91
+     * @type {{String: function}}
92
+     */
93
+    var commands = {
94
+        "topic" : processTopic
95
+    };
96
+
97
+    return CommandsPrototype;
98
+})();

+ 4
- 0
css/main.css 查看文件

43
     color: #087dba;
43
     color: #087dba;
44
 }
44
 }
45
 
45
 
46
+.errorMessage {
47
+    color: red;
48
+}
49
+
46
 .remoteuser {
50
 .remoteuser {
47
     color: #424242;
51
     color: #424242;
48
 }
52
 }

+ 15
- 1
css/videolayout_default.css 查看文件

235
 #header{
235
 #header{
236
     display:none;
236
     display:none;
237
     position:absolute;
237
     position:absolute;
238
-    height: 0px;
239
     text-align:center;
238
     text-align:center;
240
     top:0;
239
     top:0;
241
     left:0;
240
     left:0;
256
     border-bottom-right-radius: 12px;
255
     border-bottom-right-radius: 12px;
257
 }
256
 }
258
 
257
 
258
+#subject {
259
+    position: relative;
260
+    z-index: 3;
261
+    width: auto;
262
+    padding: 5px;
263
+    margin-left: 40%;
264
+    margin-right: 40%;
265
+    text-align: center;
266
+    background: linear-gradient(to bottom, rgba(255,255,255,.85) , rgba(255,255,255,.35));
267
+    -webkit-box-shadow: 0 0 2px #000000, 0 0 10px #000000;
268
+    border-bottom-left-radius: 12px;
269
+    border-bottom-right-radius: 12px;
270
+    display: none;
271
+}
272
+
259
 .watermark {
273
 .watermark {
260
     display: block;
274
     display: block;
261
     position: absolute;
275
     position: absolute;

+ 37
- 33
index.html 查看文件

23
     <script src="libs/tooltip.js?v=1"></script><!-- bootstrap tooltip lib -->
23
     <script src="libs/tooltip.js?v=1"></script><!-- bootstrap tooltip lib -->
24
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
24
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
25
     <script src="config.js?v=2"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
25
     <script src="config.js?v=2"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
26
-    <script src="muc.js?v=11"></script><!-- simple MUC library -->
26
+    <script src="muc.js?v=12"></script><!-- simple MUC library -->
27
     <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
27
     <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
28
     <script src="desktopsharing.js?v=2"></script><!-- desktop sharing -->
28
     <script src="desktopsharing.js?v=2"></script><!-- desktop sharing -->
29
     <script src="data_channels.js?v=1"></script><!-- data channels -->
29
     <script src="data_channels.js?v=1"></script><!-- data channels -->
30
     <script src="app.js?v=28"></script><!-- application logic -->
30
     <script src="app.js?v=28"></script><!-- application logic -->
31
-    <script src="chat.js?v=5"></script><!-- chat logic -->
31
+    <script src="commands.js?v=1"></script><!-- application logic -->
32
+    <script src="chat.js?v=6"></script><!-- chat logic -->
32
     <script src="util.js?v=5"></script><!-- utility functions -->
33
     <script src="util.js?v=5"></script><!-- utility functions -->
33
     <script src="etherpad.js?v=8"></script><!-- etherpad plugin -->
34
     <script src="etherpad.js?v=8"></script><!-- etherpad plugin -->
34
     <script src="prezi.js?v=4"></script><!-- prezi plugin -->
35
     <script src="prezi.js?v=4"></script><!-- prezi plugin -->
38
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
39
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
39
     <script src="rtp_stats.js?v=1"></script><!-- RTP stats processing -->
40
     <script src="rtp_stats.js?v=1"></script><!-- RTP stats processing -->
40
     <script src="videolayout.js?v=3"></script><!-- video ui -->
41
     <script src="videolayout.js?v=3"></script><!-- video ui -->
41
-    <script src="toolbar.js?v=1"></script><!-- toolbar ui -->
42
+    <script src="toolbar.js?v=2"></script><!-- toolbar ui -->
42
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
43
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
43
     <link rel="stylesheet" href="css/font.css"/>
44
     <link rel="stylesheet" href="css/font.css"/>
44
-    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=20"/>
45
-    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=6" id="videolayout_default"/>
45
+    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=21"/>
46
+    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=7" id="videolayout_default"/>
46
     <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
47
     <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
47
     <link rel="stylesheet" href="css/modaldialog.css?v=3">
48
     <link rel="stylesheet" href="css/modaldialog.css?v=3">
48
     <link rel="stylesheet" href="css/popup_menu.css?v=2">
49
     <link rel="stylesheet" href="css/popup_menu.css?v=2">
56
     <script src="libs/prezi_player.js?v=2"></script>
57
     <script src="libs/prezi_player.js?v=2"></script>
57
   </head>
58
   </head>
58
   <body>
59
   <body>
59
-    <div id="header">
60
-        <span id="toolbar">
61
-            <a class="button" data-toggle="popover" data-placement="bottom" data-content="Mute / Unmute" onclick='toggleAudio();'>
62
-                <i id="mute" class="icon-microphone"></i></a>
63
-            <div class="header_button_separator"></div>
64
-            <a class="button" data-toggle="popover" data-placement="bottom" data-content="Start / stop camera" onclick='buttonClick("#video", "icon-camera icon-camera-disabled");toggleVideo();'>
65
-                <i id="video" class="icon-camera"></i></a>
66
-            <div class="header_button_separator"></div>
67
-            <a class="button" data-toggle="popover" data-placement="bottom" data-content="Lock / unlock room" onclick="Toolbar.openLockDialog();">
68
-                <i id="lockIcon" class="icon-security"></i></a>
69
-            <div class="header_button_separator"></div>
70
-            <a class="button" data-toggle="popover" data-placement="bottom" data-content="Invite others" onclick="Toolbar.openLinkDialog();"><i class="icon-link"></i></a>
71
-            <div class="header_button_separator"></div>
72
-            <span class="toolbar_span">
73
-                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Open / close chat" onclick='Chat.toggleChat();'><i id="chatButton" class="icon-chat"></i></a>
74
-                <span id="unreadMessages"></span>
75
-            </span>
76
-            <div class="header_button_separator"></div>
77
-            <a class="button" data-toggle="popover" data-placement="bottom" data-content="Share Prezi" onclick='Prezi.openPreziDialog();'><i class="icon-prezi"></i></a>
78
-            <span id="etherpadButton">
60
+    <div style="position: relative;" id="header_container">
61
+        <div id="header">
62
+            <span id="toolbar">
63
+                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Mute / Unmute" onclick='toggleAudio();'>
64
+                    <i id="mute" class="icon-microphone"></i></a>
79
                 <div class="header_button_separator"></div>
65
                 <div class="header_button_separator"></div>
80
-                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Shared document" onclick='Etherpad.toggleEtherpad(0);'><i class="icon-share-doc"></i></a>
81
-            </span>
82
-            <div class="header_button_separator"></div>
83
-            <span id="desktopsharing" style="display: none">
84
-                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Share screen" onclick="toggleScreenSharing();"><i class="icon-share-desktop"></i></a>
66
+                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Start / stop camera" onclick='buttonClick("#video", "icon-camera icon-camera-disabled");toggleVideo();'>
67
+                    <i id="video" class="icon-camera"></i></a>
68
+                <div class="header_button_separator"></div>
69
+                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Lock / unlock room" onclick="Toolbar.openLockDialog();">
70
+                    <i id="lockIcon" class="icon-security"></i></a>
71
+                <div class="header_button_separator"></div>
72
+                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Invite others" onclick="Toolbar.openLinkDialog();"><i class="icon-link"></i></a>
73
+                <div class="header_button_separator"></div>
74
+                <span class="toolbar_span">
75
+                    <a class="button" data-toggle="popover" data-placement="bottom" data-content="Open / close chat" onclick='Chat.toggleChat();'><i id="chatButton" class="icon-chat"></i></a>
76
+                    <span id="unreadMessages"></span>
77
+                </span>
78
+                <div class="header_button_separator"></div>
79
+                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Share Prezi" onclick='Prezi.openPreziDialog();'><i class="icon-prezi"></i></a>
80
+                <span id="etherpadButton">
81
+                    <div class="header_button_separator"></div>
82
+                    <a class="button" data-toggle="popover" data-placement="bottom" data-content="Shared document" onclick='Etherpad.toggleEtherpad(0);'><i class="icon-share-doc"></i></a>
83
+                </span>
85
                 <div class="header_button_separator"></div>
84
                 <div class="header_button_separator"></div>
85
+                <span id="desktopsharing" style="display: none">
86
+                    <a class="button" data-toggle="popover" data-placement="bottom" data-content="Share screen" onclick="toggleScreenSharing();"><i class="icon-share-desktop"></i></a>
87
+                    <div class="header_button_separator"></div>
88
+                </span>
89
+                <a class="button" data-toggle="popover" data-placement="bottom" data-content="Enter / Exit Full Screen" onclick='buttonClick("#fullScreen", "icon-full-screen icon-exit-full-screen");Toolbar.toggleFullScreen();'>
90
+                    <i id="fullScreen" class="icon-full-screen"></i></a>
86
             </span>
91
             </span>
87
-            <a class="button" data-toggle="popover" data-placement="bottom" data-content="Enter / Exit Full Screen" onclick='buttonClick("#fullScreen", "icon-full-screen icon-exit-full-screen");Toolbar.toggleFullScreen();'>
88
-                <i id="fullScreen" class="icon-full-screen"></i></a>
89
-        </span>
92
+        </div>
93
+        <div id="subject"></div>
90
     </div>
94
     </div>
91
     <div id="settings">
95
     <div id="settings">
92
       <h1>Connection Settings</h1>
96
       <h1>Connection Settings</h1>

+ 26
- 2
muc.js 查看文件

170
         }
170
         }
171
         this.connection.send(msg);
171
         this.connection.send(msg);
172
     },
172
     },
173
+    setSubject: function (subject){
174
+        var msg = $msg({to: this.roomjid, type: 'groupchat'});
175
+        msg.c('subject', subject);
176
+        this.connection.send(msg);
177
+        console.log("topic changed to " + subject);
178
+    },
173
     onMessage: function (msg) {
179
     onMessage: function (msg) {
174
-        var txt = $(msg).find('>body').text();
175
-        // TODO: <subject/>
176
         // FIXME: this is a hack. but jingle on muc makes nickchanges hard
180
         // FIXME: this is a hack. but jingle on muc makes nickchanges hard
177
         var from = msg.getAttribute('from');
181
         var from = msg.getAttribute('from');
178
         var nick = $(msg).find('>nick[xmlns="http://jabber.org/protocol/nick"]').text() || Strophe.getResourceFromJid(from);
182
         var nick = $(msg).find('>nick[xmlns="http://jabber.org/protocol/nick"]').text() || Strophe.getResourceFromJid(from);
183
+
184
+        var txt = $(msg).find('>body').text();
185
+        var type = msg.getAttribute("type");
186
+        if(type == "error")
187
+        {
188
+            Chat.chatAddError($(msg).find('>text').text(), txt);
189
+            return true;
190
+        }
191
+
192
+        var subject = $(msg).find('>subject');
193
+        if(subject.length)
194
+        {
195
+            var subjectText = subject.text();
196
+            if(subjectText || subjectText == "") {
197
+                Chat.chatSetSubject(subjectText);
198
+                console.log("Subject is changed to " + subjectText);
199
+            }
200
+        }
201
+
202
+
179
         if (txt) {
203
         if (txt) {
180
             console.log('chat', nick, txt);
204
             console.log('chat', nick, txt);
181
 
205
 

+ 2
- 0
toolbar.js 查看文件

154
     my.showToolbar = function() {
154
     my.showToolbar = function() {
155
         if (!$('#header').is(':visible')) {
155
         if (!$('#header').is(':visible')) {
156
             $('#header').show("slide", { direction: "up", duration: 300});
156
             $('#header').show("slide", { direction: "up", duration: 300});
157
+            $('#subject').animate({top: "+=40"}, 300);
157
 
158
 
158
             if (toolbarTimeout) {
159
             if (toolbarTimeout) {
159
                 clearTimeout(toolbarTimeout);
160
                 clearTimeout(toolbarTimeout);
222
 
223
 
223
         if (!isToolbarHover) {
224
         if (!isToolbarHover) {
224
             $('#header').hide("slide", { direction: "up", duration: 300});
225
             $('#header').hide("slide", { direction: "up", duration: 300});
226
+            $('#subject').animate({top: "-=40"}, 300);
225
         }
227
         }
226
         else {
228
         else {
227
             toolbarTimeout = setTimeout(hideToolbar, TOOLBAR_TIMEOUT);
229
             toolbarTimeout = setTimeout(hideToolbar, TOOLBAR_TIMEOUT);

正在加载...
取消
保存