Create chat layout in Chat JavaScript application

This commit is contained in:
Dmitriy Simushev 2013-02-15 09:59:14 +00:00
parent f3ea7d790b
commit dc25058a05
12 changed files with 129 additions and 65 deletions

View File

@ -5,9 +5,9 @@
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(a,j){var f=a.Application;f.addRegions({controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:a.Regions.Messages,statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"});f.addInitializer(function(d){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,h=a.Objects.Models.Status;g.server=new a.Server(j.extend({interactionType:MibewAPIChatInteraction},d.server));c.thread=new a.Models.Thread(d.thread);c.user=new a.Models.ChatUser(d.user); (function(a,k){var h=a.Application;h.addRegions({mainRegion:"#main-region"});h.addInitializer(function(d){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,j=a.Objects.Models.Status,f=new a.Layouts.Chat({model:new Backbone.Model(d.layoutsData.chat||{})});a.Objects.chatLayout=f;h.mainRegion.show(f);g.server=new a.Server(k.extend({interactionType:MibewAPIChatInteraction},d.server));c.thread=new a.Models.Thread(d.thread);c.user=new a.Models.ChatUser(d.user);c.page=new a.Models.Page(d.page);
c.page=new a.Models.Page(d.page);var e=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),e.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:d.links.mailLink}),e.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:d.links.redirectLink}),e.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:d.links.historyLink}),e.add(b.history));b.sound=new a.Models.SoundControl({weight:160}); var e=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),e.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:d.links.mailLink}),e.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:d.links.redirectLink}),e.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:d.links.historyLink}),e.add(b.history));b.sound=new a.Models.SoundControl({weight:160});e.add(b.sound);
e.add(b.sound);b.refresh=new a.Models.RefreshControl({weight:140});e.add(b.refresh);d.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:d.links.sslLink}),e.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});e.add(b.close);g.Collections.controls=e;f.controlsRegion.show(new a.Views.ControlsCollection({collection:e}));h.message=new a.Models.StatusMessage({hideTimeout:5E3});h.typing=new a.Models.StatusTyping({hideTimeout:5E3});g.Collections.status=new a.Collections.Status([h.message, b.refresh=new a.Models.RefreshControl({weight:140});e.add(b.refresh);d.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:d.links.sslLink}),e.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});e.add(b.close);g.Collections.controls=e;f.controlsRegion.show(new a.Views.ControlsCollection({collection:e}));j.message=new a.Models.StatusMessage({hideTimeout:5E3});j.typing=new a.Models.StatusTyping({hideTimeout:5E3});g.Collections.status=new a.Collections.Status([j.message,
h.typing]);f.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,f.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(d.messageForm);f.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));f.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));c.sound=new a.Models.Sound; j.typing]);f.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,f.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(d.messageForm);f.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));f.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));c.sound=new a.Models.Sound;
f.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.callFunctionsPeriodically(function(){var b=a.Objects.Models.thread,c=a.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:b.get("id"),token:b.get("token"),lastId:b.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},function(b){b.errorCode?a.Objects.Models.Status.message.setMessage(b.errorMessage||"refresh failed"):(b.typing&&a.Objects.Models.Status.typing.show(), f.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.callFunctionsPeriodically(function(){var b=a.Objects.Models.thread,c=a.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:b.get("id"),token:b.get("token"),lastId:b.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},function(b){b.errorCode?a.Objects.Models.Status.message.setMessage(b.errorMessage||"refresh failed"):(b.typing&&a.Objects.Models.Status.typing.show(),
a.Objects.Models.user.set({canPost:b.canPost||!1}))})});f.on("start",function(){a.Objects.server.runUpdater()})})(Mibew,_); a.Objects.Models.user.set({canPost:b.canPost||!1}))})});h.on("start",function(){a.Objects.server.runUpdater()})})(Mibew,_);

View File

@ -5,4 +5,4 @@
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(a){a.Regions={};a.Objects.Models.Controls={};a.Objects.Models.Status={};a.Application=new Backbone.Marionette.Application})(Mibew); (function(a){a.Regions={};a.Layouts={};a.Objects.Models.Controls={};a.Objects.Models.Status={};a.Application=new Backbone.Marionette.Application})(Mibew);

View File

@ -0,0 +1,8 @@
/*
This file is part of Mibew Messenger project.
http://mibew.org
Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php
*/
(function(a,b){a.Layouts.Chat=b.Marionette.Layout.extend({template:Handlebars.templates.chat_layout,regions:{controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:{selector:"#messages-region",regionType:a.Regions.Messages},statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"}})})(Mibew,Backbone);

View File

@ -5,4 +5,4 @@
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(a,b){a.Regions.Messages=b.Marionette.Region.extend({el:"#messages-region",onShow:function(a){a.on("after:item:added",this.scrollToBottom,this)},scrollToBottom:function(){this.$el.scrollTop(this.$el.prop("scrollHeight"))}})})(Mibew,Backbone); (function(a,b){a.Regions.Messages=b.Marionette.Region.extend({onShow:function(a){a.on("after:item:added",this.scrollToBottom,this)},scrollToBottom:function(){this.$el.scrollTop(this.$el.prop("scrollHeight"))}})})(Mibew,Backbone);

View File

@ -4,7 +4,7 @@
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(a){a.Regions={};a.Objects.Models.Controls={};a.Objects.Models.Status={};a.Application=new Backbone.Marionette.Application})(Mibew); (function(a){a.Regions={};a.Layouts={};a.Objects.Models.Controls={};a.Objects.Models.Status={};a.Application=new Backbone.Marionette.Application})(Mibew);
/* /*
This file is part of Mibew Messenger project. This file is part of Mibew Messenger project.
http://mibew.org http://mibew.org
@ -242,16 +242,23 @@ c=""!=this.ui.message.val();c!=a.get("typing")&&a.set({typing:c})},setFocus:func
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(a,b){a.Regions.Messages=b.Marionette.Region.extend({el:"#messages-region",onShow:function(a){a.on("after:item:added",this.scrollToBottom,this)},scrollToBottom:function(){this.$el.scrollTop(this.$el.prop("scrollHeight"))}})})(Mibew,Backbone); (function(a,b){a.Regions.Messages=b.Marionette.Region.extend({onShow:function(a){a.on("after:item:added",this.scrollToBottom,this)},scrollToBottom:function(){this.$el.scrollTop(this.$el.prop("scrollHeight"))}})})(Mibew,Backbone);
/* /*
This file is part of Mibew Messenger project. This file is part of Mibew Messenger project.
http://mibew.org http://mibew.org
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(a,j){var f=a.Application;f.addRegions({controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:a.Regions.Messages,statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"});f.addInitializer(function(d){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,h=a.Objects.Models.Status;g.server=new a.Server(j.extend({interactionType:MibewAPIChatInteraction},d.server));c.thread=new a.Models.Thread(d.thread);c.user=new a.Models.ChatUser(d.user); (function(a,b){a.Layouts.Chat=b.Marionette.Layout.extend({template:Handlebars.templates.chat_layout,regions:{controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:{selector:"#messages-region",regionType:a.Regions.Messages},statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"}})})(Mibew,Backbone);
c.page=new a.Models.Page(d.page);var e=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),e.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:d.links.mailLink}),e.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:d.links.redirectLink}),e.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:d.links.historyLink}),e.add(b.history));b.sound=new a.Models.SoundControl({weight:160}); /*
e.add(b.sound);b.refresh=new a.Models.RefreshControl({weight:140});e.add(b.refresh);d.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:d.links.sslLink}),e.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});e.add(b.close);g.Collections.controls=e;f.controlsRegion.show(new a.Views.ControlsCollection({collection:e}));h.message=new a.Models.StatusMessage({hideTimeout:5E3});h.typing=new a.Models.StatusTyping({hideTimeout:5E3});g.Collections.status=new a.Collections.Status([h.message, This file is part of Mibew Messenger project.
h.typing]);f.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,f.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(d.messageForm);f.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));f.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));c.sound=new a.Models.Sound; http://mibew.org
Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php
*/
(function(a,k){var h=a.Application;h.addRegions({mainRegion:"#main-region"});h.addInitializer(function(d){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,j=a.Objects.Models.Status,f=new a.Layouts.Chat({model:new Backbone.Model(d.layoutsData.chat||{})});a.Objects.chatLayout=f;h.mainRegion.show(f);g.server=new a.Server(k.extend({interactionType:MibewAPIChatInteraction},d.server));c.thread=new a.Models.Thread(d.thread);c.user=new a.Models.ChatUser(d.user);c.page=new a.Models.Page(d.page);
var e=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),e.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:d.links.mailLink}),e.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:d.links.redirectLink}),e.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:d.links.historyLink}),e.add(b.history));b.sound=new a.Models.SoundControl({weight:160});e.add(b.sound);
b.refresh=new a.Models.RefreshControl({weight:140});e.add(b.refresh);d.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:d.links.sslLink}),e.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});e.add(b.close);g.Collections.controls=e;f.controlsRegion.show(new a.Views.ControlsCollection({collection:e}));j.message=new a.Models.StatusMessage({hideTimeout:5E3});j.typing=new a.Models.StatusTyping({hideTimeout:5E3});g.Collections.status=new a.Collections.Status([j.message,
j.typing]);f.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,f.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(d.messageForm);f.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));f.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));c.sound=new a.Models.Sound;
f.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.callFunctionsPeriodically(function(){var b=a.Objects.Models.thread,c=a.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:b.get("id"),token:b.get("token"),lastId:b.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},function(b){b.errorCode?a.Objects.Models.Status.message.setMessage(b.errorMessage||"refresh failed"):(b.typing&&a.Objects.Models.Status.typing.show(), f.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.callFunctionsPeriodically(function(){var b=a.Objects.Models.thread,c=a.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:b.get("id"),token:b.get("token"),lastId:b.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},function(b){b.errorCode?a.Objects.Models.Status.message.setMessage(b.errorMessage||"refresh failed"):(b.typing&&a.Objects.Models.Status.typing.show(),
a.Objects.Models.user.set({canPost:b.canPost||!1}))})});f.on("start",function(){a.Objects.server.runUpdater()})})(Mibew,_); a.Objects.Models.user.set({canPost:b.canPost||!1}))})});h.on("start",function(){a.Objects.server.runUpdater()})})(Mibew,_);

View File

@ -13,12 +13,7 @@
// Define regions // Define regions
App.addRegions({ App.addRegions({
controlsRegion: '#controls-region', mainRegion: '#main-region'
avatarRegion: '#avatar-region',
messagesRegion: Mibew.Regions.Messages,
statusRegion: '#status-region',
messageFormRegion: '#message-form-region',
soundRegion: '#sound-region'
}); });
// Initialize application // Initialize application
@ -29,6 +24,15 @@
var controls = Mibew.Objects.Models.Controls; var controls = Mibew.Objects.Models.Controls;
var status = Mibew.Objects.Models.Status; var status = Mibew.Objects.Models.Status;
// Create instance of the chat layout
// Use undocumented feature of layouts: passing model to layout
var layout = new Mibew.Layouts.Chat({
model: new Backbone.Model(options.layoutsData.chat || {})
});
Mibew.Objects.chatLayout = layout;
// Show layout at page
App.mainRegion.show(layout);
// Initialize Server, Thread and User // Initialize Server, Thread and User
objs.server = new Mibew.Server(_.extend( objs.server = new Mibew.Server(_.extend(
@ -109,7 +113,7 @@
objs.Collections.controls = ctrlsCollection; objs.Collections.controls = ctrlsCollection;
// Display controls // Display controls
App.controlsRegion.show(new Mibew.Views.ControlsCollection({ layout.controlsRegion.show(new Mibew.Views.ControlsCollection({
collection: ctrlsCollection collection: ctrlsCollection
})); }));
@ -128,7 +132,7 @@
]); ]);
// Display status bar // Display status bar
App.statusRegion.show(new Mibew.Views.StatusCollection({ layout.statusRegion.show(new Mibew.Views.StatusCollection({
collection: objs.Collections.status collection: objs.Collections.status
})); }));
@ -136,7 +140,7 @@
// Initialize avatar only for user // Initialize avatar only for user
if (! models.user.get('isAgent')) { if (! models.user.get('isAgent')) {
models.avatar = new Mibew.Models.Avatar(); models.avatar = new Mibew.Models.Avatar();
App.avatarRegion.show(new Mibew.Views.Avatar({ layout.avatarRegion.show(new Mibew.Views.Avatar({
model: models.avatar model: models.avatar
})); }));
} }
@ -152,23 +156,22 @@
); );
// Display message processor // Display message processor
App.messageFormRegion.show(new Mibew.Views.MessageForm({ layout.messageFormRegion.show(new Mibew.Views.MessageForm({
model: models.messageForm model: models.messageForm
})); }));
// Display messages // Display messages
App.messagesRegion.show(new Mibew.Views.MessagesCollection({ layout.messagesRegion.show(new Mibew.Views.MessagesCollection({
collection: objs.Collections.messages collection: objs.Collections.messages
})); }));
// Initialize sounds // Initialize sounds
models.sound = new Mibew.Models.Sound(); models.sound = new Mibew.Models.Sound();
App.soundRegion.show(new Mibew.Views.Sound({ layout.soundRegion.show(new Mibew.Views.Sound({
model: models.sound model: models.sound
})); }));
// TODO: May be move it somewhere else // TODO: May be move it somewhere else
// Periodically call update function at the server side // Periodically call update function at the server side
objs.server.callFunctionsPeriodically( objs.server.callFunctionsPeriodically(

View File

@ -13,6 +13,11 @@
*/ */
Mibew.Regions = {}; Mibew.Regions = {};
/**
* @namespace Holds application layouts constructors
*/
Mibew.Layouts = {};
/** /**
* @namespace Holds instances of control models * @namespace Holds instances of control models
*/ */

View File

@ -0,0 +1,41 @@
/**
* @preserve This file is part of Mibew Messenger project.
* http://mibew.org
*
* Copyright (c) 2005-2011 Mibew Messenger Community
* License: http://mibew.org/license.php
*/
(function(Mibew, Backbone){
/**
* Represents chat layout
*/
Mibew.Layouts.Chat = Backbone.Marionette.Layout.extend(
/** @lends Mibew.Layouts.Chat.prototype */
{
/**
* Template function
* @type Function
*/
template: Handlebars.templates.chat_layout,
/**
* Regions list
* @type Object
*/
regions: {
controlsRegion: '#controls-region',
avatarRegion: '#avatar-region',
messagesRegion: {
selector: '#messages-region',
regionType: Mibew.Regions.Messages
},
statusRegion: '#status-region',
messageFormRegion: '#message-form-region',
soundRegion: '#sound-region'
}
}
);
})(Mibew, Backbone);

View File

@ -14,12 +14,6 @@
Mibew.Regions.Messages = Backbone.Marionette.Region.extend( Mibew.Regions.Messages = Backbone.Marionette.Region.extend(
/** @lends Mibew.Regions.Message */ /** @lends Mibew.Regions.Message */
{ {
/**
* DOM element for the region
* @type String
*/
el: '#messages-region',
/** /**
* Show view event handler. Register handler to view's * Show view event handler. Register handler to view's
* 'after:item:added' event. * 'after:item:added' event.

View File

@ -0,0 +1,29 @@
{{! Chat header}}
<div id="chat-header">
<div class="bgc"><div class="bgl"><div class="bgr">
{{! Chat controls region}}
<div id="controls-region"></div>
</div></div></div>
</div>
{{! Chat region}}
<div id="chat">
<div class="bgl"><div class="bgr"><div class="sdwbgc"><div class="sdwbgl"><div class="sdwbgr">
{{#if user}}
<div id="avatar-region"></div>
{{/if}}
{{! Chat messages region}}
<div id="messages-region"></div>
{{! Chat status region}}
<div id="status-region"></div>
</div></div></div></div></div>
</div>
{{! Message form region}}
<div id="message-form-region"></div>
{{! Footer links}}
<div id="footer">{{L10n "chat.window.poweredby"}} <a id="poweredByLink" href="http://mibew.org" title="Mibew Community" target="_blank">mibew.org</a></div>
{{! Hidden region for some sound element}}
<div id="sound-region"></div>

File diff suppressed because one or more lines are too long

View File

@ -45,7 +45,8 @@
'chat.client.name': "${msg:chat.client.name}", 'chat.client.name': "${msg:chat.client.name}",
'chat.client.changename': "${msg:chat.client.changename}", 'chat.client.changename': "${msg:chat.client.changename}",
'chat.window.toolbar.turn_off_sound': "${msg:chat.window.toolbar.turn_off_sound}", 'chat.window.toolbar.turn_off_sound': "${msg:chat.window.toolbar.turn_off_sound}",
'chat.window.toolbar.turn_on_sound': "${msg:chat.window.toolbar.turn_on_sound}" 'chat.window.toolbar.turn_on_sound': "${msg:chat.window.toolbar.turn_on_sound}",
'chat.window.poweredby': "${msg:chat.window.poweredby}"
}); });
//--></script> //--></script>
@ -90,6 +91,11 @@
mailWindowParams: "${page:chatStyles.mailWindowParams}", mailWindowParams: "${page:chatStyles.mailWindowParams}",
historyWindowParams: "${page:coreStyles.historyWindowParams}" historyWindowParams: "${page:coreStyles.historyWindowParams}"
}, },
layoutsData: {
chat: {
user: ${if:user}true${else:user}false${endif:user}
}
},
plugins: ${page:js_plugin_options} plugins: ${page:js_plugin_options}
}); });
}); });
@ -124,35 +130,6 @@
</div> </div>
</div> </div>
<!-- Chat header --> <div id="main-region"></div>
<div id="chat-header">
<div class="bgc"><div class="bgl"><div class="bgr">
<!-- Chat controls region -->
<div id="controls-region"></div>
</div></div></div>
</div>
<!-- Chat region -->
<div id="chat">
<div class="bgl"><div class="bgr"><div class="sdwbgc"><div class="sdwbgl"><div class="sdwbgr">
${if:user}
<div id="avatar-region"></div>
${endif:user}
<!-- Chat messages region -->
<div id="messages-region"></div>
<!-- Chat status region -->
<div id="status-region"></div>
</div></div></div></div></div>
</div>
<!-- Message form region -->
<div id="message-form-region"></div>
<!-- Footer links -->
<div id="footer">${msg:chat.window.poweredby} <a id="poweredByLink" href="http://mibew.org" title="Mibew Community" target="_blank">mibew.org</a></div>
<!-- Hidden region for some sound element -->
<div id="sound-region"></div>
</body> </body>
</html> </html>