00001
00002
00003
00004
00005
00006
00007 #include "SimpleChatWidget.h"
00008 #include "SimpleChatServer.h"
00009
00010 #include <Wt/WApplication>
00011 #include <Wt/WContainerWidget>
00012 #include <Wt/WEnvironment>
00013 #include <Wt/WHBoxLayout>
00014 #include <Wt/WVBoxLayout>
00015 #include <Wt/WLabel>
00016 #include <Wt/WLineEdit>
00017 #include <Wt/WText>
00018 #include <Wt/WTextArea>
00019 #include <Wt/WPushButton>
00020
00021 #include <iostream>
00022
00023 using namespace Wt;
00024
00025 SimpleChatWidget::SimpleChatWidget(SimpleChatServer& server,
00026 Wt::WContainerWidget *parent)
00027 : WContainerWidget(parent),
00028 server_(server),
00029 app_(WApplication::instance()),
00030 messageReceived_("sounds/message_received.mp3")
00031 {
00032 user_ = server_.suggestGuest();
00033 letLogin();
00034
00035
00036
00037
00038 app_->enableUpdates();
00039 }
00040
00041 SimpleChatWidget::~SimpleChatWidget()
00042 {
00043 logout();
00044 }
00045
00046 void SimpleChatWidget::letLogin()
00047 {
00048 clear();
00049
00050 WVBoxLayout *vLayout = new WVBoxLayout();
00051 setLayout(vLayout, AlignLeft | AlignTop);
00052
00053 WHBoxLayout *hLayout = new WHBoxLayout();
00054 vLayout->addLayout(hLayout);
00055
00056 hLayout->addWidget(new WLabel("User name:"), 0, AlignMiddle);
00057 hLayout->addWidget(userNameEdit_ = new WLineEdit(user_), 0, AlignMiddle);
00058 userNameEdit_->setFocus();
00059
00060 WPushButton *b = new WPushButton("Login");
00061 hLayout->addWidget(b, 0, AlignMiddle);
00062 hLayout->addStretch(1);
00063
00064 b->clicked().connect(SLOT(this, SimpleChatWidget::login));
00065 userNameEdit_->enterPressed().connect(SLOT(this, SimpleChatWidget::login));
00066
00067 vLayout->addWidget(statusMsg_ = new WText());
00068 statusMsg_->setTextFormat(PlainText);
00069 }
00070
00071 void SimpleChatWidget::login()
00072 {
00073 WString name = WWebWidget::escapeText(userNameEdit_->text());
00074
00075 if (!startChat(name))
00076 statusMsg_->setText("Sorry, name '" + name + "' is already taken.");
00077 }
00078
00079 void SimpleChatWidget::logout()
00080 {
00081 if (eventConnection_.connected()) {
00082 eventConnection_.disconnect();
00083 server_.logout(user_);
00084
00085 letLogin();
00086 }
00087 }
00088
00089 bool SimpleChatWidget::startChat(const WString& user)
00090 {
00091 if (server_.login(user)) {
00092 eventConnection_
00093 = server_.chatEvent().connect(SLOT(this,
00094 SimpleChatWidget::processChatEvent));
00095 user_ = user;
00096
00097 clear();
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 WVBoxLayout *vLayout = new WVBoxLayout();
00118
00119
00120 WHBoxLayout *hLayout = new WHBoxLayout();
00121
00122
00123 hLayout->addWidget(messages_ = new WContainerWidget(), 1);
00124 messages_->setStyleClass("chat-msgs");
00125
00126 messages_->setOverflow(WContainerWidget::OverflowAuto);
00127
00128
00129 hLayout->addWidget(userList_ = new WContainerWidget());
00130 userList_->setStyleClass("chat-users");
00131 userList_->setOverflow(WContainerWidget::OverflowAuto);
00132
00133
00134 vLayout->addLayout(hLayout, 1);
00135
00136
00137 vLayout->addWidget(messageEdit_ = new WTextArea());
00138 messageEdit_->setStyleClass("chat-noedit");
00139 messageEdit_->setRows(2);
00140 messageEdit_->setFocus();
00141
00142
00143 hLayout = new WHBoxLayout();
00144
00145
00146 hLayout->addWidget(sendButton_ = new WPushButton("Send"));
00147 WPushButton *b;
00148
00149
00150 hLayout->addWidget(b = new WPushButton("Logout"));
00151
00152
00153 hLayout->addStretch(1);
00154
00155
00156 vLayout->addLayout(hLayout);
00157
00158 setLayout(vLayout);
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 clearInput_.setJavaScript
00173 ("function(o, e) {"
00174 "" + messageEdit_->jsRef() + ".value='';"
00175 "}");
00176
00177
00178 sendButton_->clicked().connect(SLOT(this, SimpleChatWidget::send));
00179 messageEdit_->enterPressed().connect(SLOT(this, SimpleChatWidget::send));
00180 sendButton_->clicked().connect(clearInput_);
00181 messageEdit_->enterPressed().connect(clearInput_);
00182
00183
00184
00185 messageEdit_->enterPressed().setPreventDefault(true);
00186
00187 b->clicked().connect(SLOT(this, SimpleChatWidget::logout));
00188
00189 WText *msg = new WText
00190 ("<div><span class='chat-info'>You are joining the conversation as "
00191 + user_ + "</span></div>", messages_);
00192 msg->setStyleClass("chat-msg");
00193
00194 updateUsers();
00195
00196 return true;
00197 } else
00198 return false;
00199 }
00200
00201 void SimpleChatWidget::send()
00202 {
00203 if (!messageEdit_->text().empty()) {
00204 server_.sendMessage(user_, messageEdit_->text());
00205 if (!WApplication::instance()->environment().ajax())
00206 messageEdit_->setText(WString::Empty);
00207 }
00208
00209 messageEdit_->setFocus();
00210 }
00211
00212 void SimpleChatWidget::updateUsers()
00213 {
00214 userList_->clear();
00215
00216 SimpleChatServer::UserSet users = server_.users();
00217
00218 WString usersStr;
00219
00220 for (SimpleChatServer::UserSet::iterator i = users.begin();
00221 i != users.end(); ++i) {
00222 if (*i == user_)
00223 usersStr += "<div><span class='chat-self'>" + *i + "</span></div>";
00224 else
00225 usersStr += "<div>" + *i + "</div>";
00226 }
00227
00228 userList_->addWidget(new WText(usersStr));
00229 }
00230
00231 void SimpleChatWidget::processChatEvent(const ChatEvent& event)
00232 {
00233
00234 if (event.user() != user_) {
00235 messageReceived_.play();
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 WApplication::UpdateLock lock = app_->getUpdateLock();
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 WText *w = new WText(event.formattedHTML(user_), messages_);
00259 w->setInline(false);
00260 w->setStyleClass("chat-msg");
00261
00262
00263
00264
00265 if (messages_->count() > 100)
00266 delete messages_->children()[0];
00267
00268
00269
00270
00271 if (event.type() != ChatEvent::Message)
00272 updateUsers();
00273
00274
00275
00276
00277 app_->doJavaScript(messages_->jsRef() + ".scrollTop += "
00278 + messages_->jsRef() + ".scrollHeight;");
00279
00280 app_->triggerUpdate();
00281 }