Added some usefull informations for users
Fixed bug with auto logout
This commit is contained in:
@@ -177,3 +177,11 @@ main {
|
|||||||
.flag-icon {
|
.flag-icon {
|
||||||
margin: 0.25em 0.5em 0 0;
|
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/WSlider.h>
|
||||||
#include <Wt/WGridLayout.h>
|
#include <Wt/WGridLayout.h>
|
||||||
#include <Wt/WCheckBox.h>
|
#include <Wt/WCheckBox.h>
|
||||||
|
#include <Wt/WTimer.h>
|
||||||
|
|
||||||
App::App(const Wt::WEnvironment &env, Broadcast &server):
|
App::App(const Wt::WEnvironment &env, Broadcast &server):
|
||||||
Wt::WApplication(env),
|
Wt::WApplication(env),
|
||||||
@@ -786,6 +787,8 @@ void App::createMenu() {
|
|||||||
addSearchButton();
|
addSearchButton();
|
||||||
addInboxButton();
|
addInboxButton();
|
||||||
addHistoryButton();
|
addHistoryButton();
|
||||||
|
addLoginTimeView();
|
||||||
|
addTimeoutView();
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::addLeaveButton() {
|
void App::addLeaveButton() {
|
||||||
@@ -833,6 +836,7 @@ void App::addInboxButton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void App::showSearchWindow() {
|
void App::showSearchWindow() {
|
||||||
|
setActivity();
|
||||||
auto contentLayout = resetSearchFields();
|
auto contentLayout = resetSearchFields();
|
||||||
auto userNameField = setupNameSearchField(contentLayout);
|
auto userNameField = setupNameSearchField(contentLayout);
|
||||||
auto ageSearchFields = setupSearchFields(contentLayout);
|
auto ageSearchFields = setupSearchFields(contentLayout);
|
||||||
@@ -975,6 +979,7 @@ void App::removeUserFromSearch(Wt::Json::Object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void App::requestHistory() {
|
void App::requestHistory() {
|
||||||
|
setActivity();
|
||||||
server_.sendHistory(sessionId());
|
server_.sendHistory(sessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1000,6 +1005,51 @@ void App::showHistory(Wt::Json::Object broadcast) {
|
|||||||
triggerUpdate();
|
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) {
|
void App::itemChanged(Wt::WCheckBox *item, Wt::WContainerWidget *dropDownContainer, Wt::WPushButton *openButton, std::unordered_set<std::string> *saveItems) {
|
||||||
saveItems->clear();
|
saveItems->clear();
|
||||||
bool unselect = (item->text() == "All" && item->isChecked());
|
bool unselect = (item->text() == "All" && item->isChecked());
|
||||||
@@ -1093,6 +1143,7 @@ void App::showSearch(Wt::Json::Object broadcast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void App::openInbox() {
|
void App::openInbox() {
|
||||||
|
setActivity();
|
||||||
currentConversationWith_ = "";
|
currentConversationWith_ = "";
|
||||||
contentContainer_->clear();
|
contentContainer_->clear();
|
||||||
contentContainer_->addNew<Wt::WText>("<h2>Inbox</h2>");
|
contentContainer_->addNew<Wt::WText>("<h2>Inbox</h2>");
|
||||||
@@ -1128,6 +1179,8 @@ void App::incomingBroadcast() {
|
|||||||
removeUserFromSearch(broadcast);
|
removeUserFromSearch(broadcast);
|
||||||
} else if (broadcast["type"] == "history") {
|
} else if (broadcast["type"] == "history") {
|
||||||
showHistory(broadcast);
|
showHistory(broadcast);
|
||||||
|
} else if (broadcast["type"] == "timedout") {
|
||||||
|
connectionTimedOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1136,6 +1189,7 @@ void App::startChat() {
|
|||||||
createMenu();
|
createMenu();
|
||||||
contentContainer_->clear();
|
contentContainer_->clear();
|
||||||
contentContainer_->addNew<Wt::WText>(Wt::WString::tr("introduction"), Wt::TextFormat::UnsafeXHTML);
|
contentContainer_->addNew<Wt::WText>(Wt::WString::tr("introduction"), Wt::TextFormat::UnsafeXHTML);
|
||||||
|
setLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::createUserListContainer(Wt::WHBoxLayout *layout) {
|
void App::createUserListContainer(Wt::WHBoxLayout *layout) {
|
||||||
|
|||||||
@@ -198,6 +198,9 @@ private:
|
|||||||
void removeUserFromSearch(Wt::Json::Object broadcast);
|
void removeUserFromSearch(Wt::Json::Object broadcast);
|
||||||
void requestHistory();
|
void requestHistory();
|
||||||
void showHistory(Wt::Json::Object broadcast);
|
void showHistory(Wt::Json::Object broadcast);
|
||||||
|
void connectionTimedOut();
|
||||||
|
void addLoginTimeView();
|
||||||
|
void addTimeoutView();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APP_H
|
#endif // APP_H
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ void Broadcast::disconnect(Client *client) {
|
|||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::reSetUser(std::string oldSessionId, std::string newSessionId) {
|
Wt::Json::Object Broadcast::reSetUser(std::string oldSessionId, std::string newSessionId) {
|
||||||
@@ -140,6 +139,10 @@ bool Broadcast::nameIsFree(std::string userNameToCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Broadcast::run() {
|
void Broadcast::run() {
|
||||||
|
Wt::Json::Object timedoutBroadcast {
|
||||||
|
{"type", "timedout"},
|
||||||
|
{"data", "dummy"}
|
||||||
|
};
|
||||||
for (;;) {
|
for (;;) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
if (stop_) {
|
if (stop_) {
|
||||||
@@ -149,6 +152,7 @@ void Broadcast::run() {
|
|||||||
for (auto &connection: connections_) {
|
for (auto &connection: connections_) {
|
||||||
if (connection->client()->activitiesTimedOut()) {
|
if (connection->client()->activitiesTimedOut()) {
|
||||||
disconnect(connection->client());
|
disconnect(connection->client());
|
||||||
|
addMessageToSessionBroadcast(connection->sessionId(), timedoutBroadcast);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (connection->getBroadcasts().size() == 0) {
|
if (connection->getBroadcasts().size() == 0) {
|
||||||
@@ -602,7 +606,12 @@ void Client::setActivity() {
|
|||||||
|
|
||||||
bool Client::activitiesTimedOut() {
|
bool Client::activitiesTimedOut() {
|
||||||
auto timeDifference = Wt::WDateTime::currentDateTime().secsTo(lastActivity_);
|
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() {
|
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_):
|
Broadcast::Message::Message(std::string fromSessionId_, Wt::WString message_):
|
||||||
fromSessionId(fromSessionId_),
|
fromSessionId(fromSessionId_),
|
||||||
sendType("text"),
|
sendType("text"),
|
||||||
|
|||||||
@@ -32,10 +32,17 @@ public:
|
|||||||
std::unordered_map<std::string, std::vector<ConversationItem> > conversations;
|
std::unordered_map<std::string, std::vector<ConversationItem> > conversations;
|
||||||
void setActivity();
|
void setActivity();
|
||||||
bool activitiesTimedOut();
|
bool activitiesTimedOut();
|
||||||
|
int currentlyLoggedInSeconds();
|
||||||
virtual void incomingBroadcast() { std::cout << "incoming" << std::endl;};
|
virtual void incomingBroadcast() { std::cout << "incoming" << std::endl;};
|
||||||
Wt::Json::Object json();
|
Wt::Json::Object json();
|
||||||
|
int remainingSecondsToTimeout();
|
||||||
|
protected:
|
||||||
|
void setLoggedIn();
|
||||||
|
void setLoggedOut();
|
||||||
private:
|
private:
|
||||||
|
const int timeoutSeconds {1800};
|
||||||
Wt::WDateTime lastActivity_;
|
Wt::WDateTime lastActivity_;
|
||||||
|
Wt::WDateTime loginTimeStamp_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Broadcast {
|
class Broadcast {
|
||||||
|
|||||||
Reference in New Issue
Block a user