Added some usefull informations for users
Fixed bug with auto logout
This commit is contained in:
@@ -177,3 +177,11 @@ main {
|
||||
.flag-icon {
|
||||
margin: 0.25em 0.5em 0 0;
|
||||
}
|
||||
.menu-info-text {
|
||||
display: inline-block;
|
||||
padding: 0.375em 0.4em;
|
||||
color: #2E7D32;
|
||||
border: 1px solid #fff;
|
||||
background-color: lightgray;
|
||||
margin: 0.1em 0.2em;
|
||||
}
|
||||
|
||||
54
src/app.cpp
54
src/app.cpp
@@ -36,6 +36,7 @@
|
||||
#include <Wt/WSlider.h>
|
||||
#include <Wt/WGridLayout.h>
|
||||
#include <Wt/WCheckBox.h>
|
||||
#include <Wt/WTimer.h>
|
||||
|
||||
App::App(const Wt::WEnvironment &env, Broadcast &server):
|
||||
Wt::WApplication(env),
|
||||
@@ -786,6 +787,8 @@ void App::createMenu() {
|
||||
addSearchButton();
|
||||
addInboxButton();
|
||||
addHistoryButton();
|
||||
addLoginTimeView();
|
||||
addTimeoutView();
|
||||
}
|
||||
|
||||
void App::addLeaveButton() {
|
||||
@@ -833,6 +836,7 @@ void App::addInboxButton() {
|
||||
}
|
||||
|
||||
void App::showSearchWindow() {
|
||||
setActivity();
|
||||
auto contentLayout = resetSearchFields();
|
||||
auto userNameField = setupNameSearchField(contentLayout);
|
||||
auto ageSearchFields = setupSearchFields(contentLayout);
|
||||
@@ -975,6 +979,7 @@ void App::removeUserFromSearch(Wt::Json::Object) {
|
||||
}
|
||||
|
||||
void App::requestHistory() {
|
||||
setActivity();
|
||||
server_.sendHistory(sessionId());
|
||||
}
|
||||
|
||||
@@ -1000,6 +1005,51 @@ void App::showHistory(Wt::Json::Object broadcast) {
|
||||
triggerUpdate();
|
||||
}
|
||||
|
||||
void App::connectionTimedOut() {
|
||||
showLogin();
|
||||
triggerUpdate();
|
||||
}
|
||||
|
||||
void App::addLoginTimeView() {
|
||||
auto loggedinTimeWidget = menuContainer_->addNew<Wt::WText>();
|
||||
loggedinTimeWidget->setStyleClass("menu-info-text");
|
||||
auto loginTimer = root()->addChild(std::make_unique<Wt::WTimer>());
|
||||
loginTimer->setInterval(std::chrono::seconds(1));
|
||||
auto loggedInRefresh = [=, this]() {
|
||||
auto currentLoginSeconds = currentlyLoggedInSeconds();
|
||||
int hours = currentLoginSeconds / 3600;
|
||||
int minutes = (currentLoginSeconds % 3600) / 60;
|
||||
std::stringstream elapsedTimeStream;
|
||||
elapsedTimeStream << std::setw(2) << std::setfill('0') << hours << ":"
|
||||
<< std::setw(2) << std::setfill('0') << minutes << " h";
|
||||
std::string elapsedTimeString = elapsedTimeStream.str();
|
||||
loggedinTimeWidget->setText(Wt::WString("In chat for {1}").arg(elapsedTimeString));
|
||||
};
|
||||
loginTimer->timeout().connect(loggedInRefresh);
|
||||
loggedInRefresh();
|
||||
loginTimer->start();
|
||||
}
|
||||
|
||||
void App::addTimeoutView() {
|
||||
auto timeoutRemainingWidget = menuContainer_->addNew<Wt::WText>();
|
||||
timeoutRemainingWidget->setStyleClass("menu-info-text");
|
||||
auto timeoutRemainingTimer = root()->addChild(std::make_unique<Wt::WTimer>());
|
||||
timeoutRemainingTimer->setInterval(std::chrono::milliseconds(500));
|
||||
auto timeoutRemainingRefresh = [=, this]() {
|
||||
auto remainingLoginSeconds = remainingSecondsToTimeout();
|
||||
int minutes = remainingLoginSeconds / 60;
|
||||
int seconds = (remainingLoginSeconds % 60);
|
||||
std::stringstream remainingTimeStream;
|
||||
remainingTimeStream << std::setw(2) << std::setfill('0') << minutes << ":"
|
||||
<< std::setw(2) << std::setfill('0') << seconds << " m";
|
||||
std::string elapsedTimeString = remainingTimeStream.str();
|
||||
timeoutRemainingWidget->setText(Wt::WString("Remaining time before logout is {1}").arg(elapsedTimeString));
|
||||
};
|
||||
timeoutRemainingTimer->timeout().connect(timeoutRemainingRefresh);
|
||||
timeoutRemainingRefresh();
|
||||
timeoutRemainingTimer->start();
|
||||
}
|
||||
|
||||
void App::itemChanged(Wt::WCheckBox *item, Wt::WContainerWidget *dropDownContainer, Wt::WPushButton *openButton, std::unordered_set<std::string> *saveItems) {
|
||||
saveItems->clear();
|
||||
bool unselect = (item->text() == "All" && item->isChecked());
|
||||
@@ -1093,6 +1143,7 @@ void App::showSearch(Wt::Json::Object broadcast) {
|
||||
}
|
||||
|
||||
void App::openInbox() {
|
||||
setActivity();
|
||||
currentConversationWith_ = "";
|
||||
contentContainer_->clear();
|
||||
contentContainer_->addNew<Wt::WText>("<h2>Inbox</h2>");
|
||||
@@ -1128,6 +1179,8 @@ void App::incomingBroadcast() {
|
||||
removeUserFromSearch(broadcast);
|
||||
} else if (broadcast["type"] == "history") {
|
||||
showHistory(broadcast);
|
||||
} else if (broadcast["type"] == "timedout") {
|
||||
connectionTimedOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1136,6 +1189,7 @@ void App::startChat() {
|
||||
createMenu();
|
||||
contentContainer_->clear();
|
||||
contentContainer_->addNew<Wt::WText>(Wt::WString::tr("introduction"), Wt::TextFormat::UnsafeXHTML);
|
||||
setLoggedIn();
|
||||
}
|
||||
|
||||
void App::createUserListContainer(Wt::WHBoxLayout *layout) {
|
||||
|
||||
@@ -198,6 +198,9 @@ private:
|
||||
void removeUserFromSearch(Wt::Json::Object broadcast);
|
||||
void requestHistory();
|
||||
void showHistory(Wt::Json::Object broadcast);
|
||||
void connectionTimedOut();
|
||||
void addLoginTimeView();
|
||||
void addTimeoutView();
|
||||
};
|
||||
|
||||
#endif // APP_H
|
||||
|
||||
@@ -59,7 +59,6 @@ void Broadcast::disconnect(Client *client) {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Wt::Json::Object Broadcast::reSetUser(std::string oldSessionId, std::string newSessionId) {
|
||||
@@ -140,6 +139,10 @@ bool Broadcast::nameIsFree(std::string userNameToCheck) {
|
||||
}
|
||||
|
||||
void Broadcast::run() {
|
||||
Wt::Json::Object timedoutBroadcast {
|
||||
{"type", "timedout"},
|
||||
{"data", "dummy"}
|
||||
};
|
||||
for (;;) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
if (stop_) {
|
||||
@@ -149,6 +152,7 @@ void Broadcast::run() {
|
||||
for (auto &connection: connections_) {
|
||||
if (connection->client()->activitiesTimedOut()) {
|
||||
disconnect(connection->client());
|
||||
addMessageToSessionBroadcast(connection->sessionId(), timedoutBroadcast);
|
||||
continue;
|
||||
}
|
||||
if (connection->getBroadcasts().size() == 0) {
|
||||
@@ -602,7 +606,12 @@ void Client::setActivity() {
|
||||
|
||||
bool Client::activitiesTimedOut() {
|
||||
auto timeDifference = Wt::WDateTime::currentDateTime().secsTo(lastActivity_);
|
||||
return timeDifference > 1800;
|
||||
return timeDifference > timeoutSeconds;
|
||||
}
|
||||
|
||||
int Client::currentlyLoggedInSeconds() {
|
||||
auto currentDateTime = Wt::WDateTime::currentDateTime();
|
||||
return loginTimeStamp_.secsTo(currentDateTime);
|
||||
}
|
||||
|
||||
Wt::Json::Object Client::json() {
|
||||
@@ -615,6 +624,16 @@ Wt::Json::Object Client::json() {
|
||||
};
|
||||
}
|
||||
|
||||
int Client::remainingSecondsToTimeout(){
|
||||
auto timeDifference = lastActivity_.secsTo(Wt::WDateTime::currentDateTime());
|
||||
return timeoutSeconds - timeDifference;
|
||||
}
|
||||
|
||||
void Client::setLoggedIn() {
|
||||
loginTimeStamp_ = Wt::WDateTime::currentDateTime();
|
||||
lastActivity_ = loginTimeStamp_;
|
||||
}
|
||||
|
||||
Broadcast::Message::Message(std::string fromSessionId_, Wt::WString message_):
|
||||
fromSessionId(fromSessionId_),
|
||||
sendType("text"),
|
||||
|
||||
@@ -32,10 +32,17 @@ public:
|
||||
std::unordered_map<std::string, std::vector<ConversationItem> > conversations;
|
||||
void setActivity();
|
||||
bool activitiesTimedOut();
|
||||
int currentlyLoggedInSeconds();
|
||||
virtual void incomingBroadcast() { std::cout << "incoming" << std::endl;};
|
||||
Wt::Json::Object json();
|
||||
int remainingSecondsToTimeout();
|
||||
protected:
|
||||
void setLoggedIn();
|
||||
void setLoggedOut();
|
||||
private:
|
||||
const int timeoutSeconds {1800};
|
||||
Wt::WDateTime lastActivity_;
|
||||
Wt::WDateTime loginTimeStamp_;
|
||||
};
|
||||
|
||||
class Broadcast {
|
||||
|
||||
Reference in New Issue
Block a user