Fixed problems with block; refactored code

This commit is contained in:
Torsten Schulz
2024-02-21 11:08:27 +01:00
parent 19f9595e8b
commit ab8f84f371
5 changed files with 107 additions and 66 deletions

View File

@@ -39,7 +39,7 @@ endif()
if(Boost_FOUND) if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} GraphicsMagick++) target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} GraphicsMagick++ GraphicsMagick)
endif() endif()
include(GNUInstallDirs) include(GNUInstallDirs)

View File

@@ -399,8 +399,8 @@ std::unique_ptr<Wt::WText> App::createInfoText(Wt::Json::Object userData) {
std::unique_ptr<Wt::WPushButton> App::createBlockButton(Wt::Json::Object userData) { std::unique_ptr<Wt::WPushButton> App::createBlockButton(Wt::Json::Object userData) {
auto blockButton = std::make_unique<Wt::WPushButton>((bool)userData["blocked"] ? "Unblock user" : "Block user"); auto blockButton = std::make_unique<Wt::WPushButton>((bool)userData["blocked"] ? "Unblock user" : "Block user");
blockButton->clicked().connect([=, this, &userData]() { blockButton->clicked().connect([=, this]() mutable {
server_.toggleBlockUser(userName, (std::string)userData["name"], userName); server_.toggleBlockUser(userName, (std::string)userData["name"], sessionId());
}); });
return blockButton; return blockButton;
} }
@@ -433,7 +433,11 @@ Wt::WLineEdit* App::createInputLine(Wt::WHBoxLayout* inputLayout) {
Wt::WImage* App::createSendImageButton(Wt::WHBoxLayout* inputLayout) { Wt::WImage* App::createSendImageButton(Wt::WHBoxLayout* inputLayout) {
auto sendImageButton = inputLayout->addNew<Wt::WImage>(Wt::WLink("/image.png")); auto sendImageButton = inputLayout->addNew<Wt::WImage>(Wt::WLink("/image.png"));
sendImageButton->setToolTip("Send an image"); sendImageButton->setToolTip("Send an image");
sendImageButton->clicked().connect([=, this]() { sendImageButton->clicked().connect(this, &App::sendImage);
return sendImageButton;
}
void App::sendImage() {
auto fileDialog = root()->addNew<Wt::WDialog>("Send Image to User"); auto fileDialog = root()->addNew<Wt::WDialog>("Send Image to User");
auto layout = fileDialog->contents()->setLayout(std::make_unique<Wt::WVBoxLayout>()); auto layout = fileDialog->contents()->setLayout(std::make_unique<Wt::WVBoxLayout>());
layout->addNew<Wt::WText>("Please select an immage"); layout->addNew<Wt::WText>("Please select an immage");
@@ -446,26 +450,7 @@ Wt::WImage* App::createSendImageButton(Wt::WHBoxLayout* inputLayout) {
auto buttonsContainer = layout->addNew<Wt::WContainerWidget>(); auto buttonsContainer = layout->addNew<Wt::WContainerWidget>();
auto okButton = buttonsContainer->addNew<Wt::WPushButton>("Send image"); auto okButton = buttonsContainer->addNew<Wt::WPushButton>("Send image");
fileWidget->uploaded().connect([=, this]() mutable { fileWidget->uploaded().connect([=, this]() mutable {
try { imageUploaded(fileWidget, localImage, image, okButton);
Magick::Image originalImage;
originalImage.quiet(true);
originalImage.read(fileWidget->spoolFileName());
*localImage = scaleImage(originalImage, 500);
auto smallImage = scaleImage(originalImage, 100);
Magick::Blob previewBlob;
smallImage.write(&previewBlob);
auto previewBase64 = previewBlob.base64();
auto previewImage = Wt::Utils::base64Decode(previewBase64);
auto imageResource = std::make_shared<Wt::WMemoryResource>(
"image/png",
std::vector<unsigned char>(previewImage.begin(), previewImage.end()));
image->setImageLink(Wt::WLink(imageResource));
image->resize(Wt::WLength(smallImage.columns(), Wt::LengthUnit::Pixel), Wt::WLength(smallImage.rows(), Wt::LengthUnit::Pixel));
okButton->setEnabled(true);
triggerUpdate();
} catch (const std::exception& e) {
std::cerr << "Error processing uploaded image: " << e.what() << std::endl;
}
}); });
fileWidget->changed().connect([=]() { fileWidget->upload(); }); fileWidget->changed().connect([=]() { fileWidget->upload(); });
fileWidget->fileTooLarge().connect([](){ std::cout << "file too big" << std::endl; }); fileWidget->fileTooLarge().connect([](){ std::cout << "file too big" << std::endl; });
@@ -479,8 +464,36 @@ Wt::WImage* App::createSendImageButton(Wt::WHBoxLayout* inputLayout) {
fileDialog->setClosable(true); fileDialog->setClosable(true);
fileDialog->setModal(true); fileDialog->setModal(true);
fileDialog->show(); fileDialog->show();
}); }
return sendImageButton;
void App::imageUploaded(Wt::WFileUpload *fileWidget, std::shared_ptr<Magick::Image> localImage, Wt::WImage *image, Wt::WPushButton *okButton) {
try {
std::list<Magick::Image> originalImages;
Magick::readImages(&originalImages, fileWidget->spoolFileName());
std::list<Magick::Image> coalescedList;
Magick::coalesceImages(&coalescedList, originalImages.begin(), originalImages.end());
Magick::Image coalescedImage;
Magick::Blob coalescedBlob;
Magick::writeImages(coalescedList.begin(), coalescedList.end(), &coalescedBlob);
coalescedImage.read(coalescedBlob);
*localImage = coalescedImage;
Magick::Blob previewBlob;
coalescedImage.write(&previewBlob);
Magick::writeImages(coalescedList.begin(), coalescedList.end(), &previewBlob);
auto previewBase64 = previewBlob.base64();
auto previewImage = Wt::Utils::base64Decode(previewBase64);
std::string imageFormat = coalescedImage.magick();
auto imageResource = std::make_shared<Wt::WMemoryResource>(
"image/" + imageFormat,
std::vector<unsigned char>(previewImage.begin(), previewImage.end()));
image->setImageLink(Wt::WLink(imageResource));
image->resize(Wt::WLength(localImage->columns(), Wt::LengthUnit::Pixel), Wt::WLength(localImage->rows(), Wt::LengthUnit::Pixel));
std::cout << __LINE__ << std::endl;
okButton->setEnabled(true);
triggerUpdate();
} catch (const std::exception& e) {
std::cerr << "Error processing uploaded image: " << e.what() << std::endl;
}
} }
Magick::Image App::scaleImage(const Magick::Image& originalImage, int maxSize) const { Magick::Image App::scaleImage(const Magick::Image& originalImage, int maxSize) const {
@@ -654,8 +667,11 @@ Wt::WWebWidget* App::createImageElement(Wt::Json::Object& line, const std::strin
imageLineItem->addNew<Wt::WText>(outputText)->setStyleClass("output-line"); imageLineItem->addNew<Wt::WText>(outputText)->setStyleClass("output-line");
auto image = imageLineItem->addNew<Wt::WImage>(); auto image = imageLineItem->addNew<Wt::WImage>();
auto imageBlob = Wt::Utils::base64Decode((std::string)imageDescription["imageblobbase64"]); auto imageBlob = Wt::Utils::base64Decode((std::string)imageDescription["imageblobbase64"]);
Magick::Image magickImage;
magickImage.read(imageBlob);
std::string imageFormat = magickImage.magick();
auto imageResource = std::make_shared<Wt::WMemoryResource>( auto imageResource = std::make_shared<Wt::WMemoryResource>(
"image/png", "image/" + imageFormat,
std::vector<unsigned char>(imageBlob.begin(), imageBlob.end())); std::vector<unsigned char>(imageBlob.begin(), imageBlob.end()));
image->setImageLink(Wt::WLink(imageResource)); image->setImageLink(Wt::WLink(imageResource));
image->resize(Wt::WLength((int)imageDescription["width"], Wt::LengthUnit::Pixel), Wt::WLength((int)imageDescription["height"], Wt::LengthUnit::Pixel)); image->resize(Wt::WLength((int)imageDescription["width"], Wt::LengthUnit::Pixel), Wt::WLength((int)imageDescription["height"], Wt::LengthUnit::Pixel));
@@ -749,8 +765,9 @@ void App::updateUserinfo(Wt::Json::Object data) {
auto infoLayoutItem = containerLayout->itemAt(0); auto infoLayoutItem = containerLayout->itemAt(0);
auto infoWidget = (Wt::WContainerWidget*)(infoLayoutItem->widget()); auto infoWidget = (Wt::WContainerWidget*)(infoLayoutItem->widget());
auto infoWidgetLayout = (Wt::WHBoxLayout*)infoWidget->layout(); auto infoWidgetLayout = (Wt::WHBoxLayout*)infoWidget->layout();
auto infoTextWidget = dynamic_cast<Wt::WText*>(infoWidgetLayout->itemAt(0)->widget()); auto infoTextWidget = dynamic_cast<Wt::WText*>(infoWidgetLayout->itemAt(1)->widget());
auto blockButton = dynamic_cast<Wt::WPushButton*>(infoWidgetLayout->itemAt(1)->widget()); auto blockButton = dynamic_cast<Wt::WPushButton*>(infoWidgetLayout->itemAt(2)->widget());
std::cout << Wt::Json::serialize(userData) << std::endl;
try { try {
infoWidget->setStyleClass(Wt::WString("user-conversation-info userlist-gender-{1}").arg((std::string)userData["gender"])); infoWidget->setStyleClass(Wt::WString("user-conversation-info userlist-gender-{1}").arg((std::string)userData["gender"]));
if (infoTextWidget) { if (infoTextWidget) {
@@ -792,15 +809,20 @@ void App::toggleSmileysBar(Wt::WContainerWidget *smileyBar) {
smileyBar->setHidden(!smileyBar->isHidden()); smileyBar->setHidden(!smileyBar->isHidden());
} }
void App::showSystemMessage(Wt::Json::Object broadcast) { void App::systemEvent(Wt::Json::Object broadcast) {
if ((std::string)broadcast["relatedUser"] != currentConversationWith_) { if ((std::string)broadcast["related-user"] != currentConversationWith_) {
return; return;
} }
auto containerLayout = (Wt::WVBoxLayout*)contentContainer_->layout(); auto containerLayout = (Wt::WVBoxLayout*)contentContainer_->layout();
auto outputLayoutItem = containerLayout->itemAt(1); auto infoLayoutItem = containerLayout->itemAt(0);
auto outputContainer = (Wt::WContainerWidget*)outputLayoutItem->widget(); auto infoWidget = (Wt::WContainerWidget*)(infoLayoutItem->widget());
auto outputLine = outputContainer->addNew<Wt::WText>((std::string)broadcast["data"]); auto infoWidgetLayout = (Wt::WHBoxLayout*)infoWidget->layout();
outputLine->setStyleClass("system-message"); auto blockButton = dynamic_cast<Wt::WPushButton*>(infoWidgetLayout->itemAt(2)->widget());
if (broadcast["data"] == "blocked") {
blockButton->setText("Unblock");
} else if (broadcast["data"] == "unblocked") {
blockButton->setText("Block");
}
} }
@@ -1219,7 +1241,7 @@ void App::incomingBroadcast() {
} else if (broadcast["type"] == "userinfo") { } else if (broadcast["type"] == "userinfo") {
updateUserinfo(broadcast); updateUserinfo(broadcast);
} else if (broadcast["type"] == "system") { } else if (broadcast["type"] == "system") {
showSystemMessage(broadcast); systemEvent(broadcast);
} else if (broadcast["type"] == "conversation-start") { } else if (broadcast["type"] == "conversation-start") {
showConversation(broadcast); showConversation(broadcast);
} else if (broadcast["type"] == "search-result") { } else if (broadcast["type"] == "search-result") {

View File

@@ -11,6 +11,7 @@
namespace Magick { namespace Magick {
class Image; class Image;
class Blob;
} }
class App : public Wt::WApplication, public Client { class App : public Wt::WApplication, public Client {
@@ -140,7 +141,7 @@ private:
void updateUserinfo(Wt::Json::Object data); void updateUserinfo(Wt::Json::Object data);
std::unique_ptr<Wt::WContainerWidget> createSmileysBar(Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition); std::unique_ptr<Wt::WContainerWidget> createSmileysBar(Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition);
void toggleSmileysBar(Wt::WContainerWidget *smileyBar); void toggleSmileysBar(Wt::WContainerWidget *smileyBar);
void showSystemMessage(Wt::Json::Object broadcast); void systemEvent(Wt::Json::Object broadcast);
void addStartChatButton(Wt::WGridLayout *contentGrid, Wt::WLineEdit *userName, Wt::WComboBox *country, Wt::WSpinBox *age, Wt::WComboBox *gender); void addStartChatButton(Wt::WGridLayout *contentGrid, Wt::WLineEdit *userName, Wt::WComboBox *country, Wt::WSpinBox *age, Wt::WComboBox *gender);
Wt::WComboBox *addCountrySelection(Wt::WGridLayout *contentGrid); Wt::WComboBox *addCountrySelection(Wt::WGridLayout *contentGrid);
Wt::WSpinBox *addAgeInput(Wt::WGridLayout *contentGrid); Wt::WSpinBox *addAgeInput(Wt::WGridLayout *contentGrid);
@@ -205,6 +206,9 @@ private:
void addLoginTimeView(); void addLoginTimeView();
void addTimeoutView(); void addTimeoutView();
void showPartnerSites(); void showPartnerSites();
void sendImage();
void imageUploaded(Wt::WFileUpload *fileWidget, std::shared_ptr<Magick::Image> localImage, Wt::WImage *image, Wt::WPushButton *okButton);
bool isAnimatedGIF(const Magick::Blob &blob);
}; };
#endif // APP_H #endif // APP_H

View File

@@ -324,7 +324,7 @@ void Broadcast::sendUserInformation(std::string sendToSessionId, std::string use
if (blockings_.find(userName) == blockings_.end()) { if (blockings_.find(userName) == blockings_.end()) {
blockings_[userName] = std::set<std::string>(); blockings_[userName] = std::set<std::string>();
} }
userData["blocked"] = !(blockings_.find(userName) == blockings_.end() || blockings_[userName].find(requestingUserName) == blockings_[userName].end()); userData["blocked"] = (blockings_.find(userName) != blockings_.end() && blockings_[userName].find(requestingUserName) != blockings_[userName].end());
Wt::Json::Object broadcast{ Wt::Json::Object broadcast{
{"type", "userinfo"}, {"type", "userinfo"},
{"data", userData} {"data", userData}
@@ -341,10 +341,9 @@ void Broadcast::toggleBlockUser(std::string blockingUserName, std::string blocke
blockings_[blockedUser].erase(blockingUserName); blockings_[blockedUser].erase(blockingUserName);
sendUnblockDone(blockingUserSessionId, blockedUser); sendUnblockDone(blockingUserSessionId, blockedUser);
} else { } else {
blockings_[blockedUser].insert(blockingUserSessionId); blockings_[blockedUser].insert(blockingUserName);
sendBlockDone(blockingUserSessionId, blockedUser); sendBlockDone(blockingUserSessionId, blockedUser);
} }
sendUserInformation(blockingUserSessionId, blockedUser, blockingUserName);
} }
void Broadcast::requestConversation(std::string sendToSessionId, std::string withUserName, std::string requestingUserName) { void Broadcast::requestConversation(std::string sendToSessionId, std::string withUserName, std::string requestingUserName) {
@@ -524,20 +523,22 @@ void Broadcast::sendBlockedMessage(std::string sessionId, std::string toUserName
} }
void Broadcast::sendBlockDone(std::string sessionId, std::string toUserName) { void Broadcast::sendBlockDone(std::string sessionId, std::string toUserName) {
addMessage(sessionId, toUserName, Message("Conversation is blocked."));
Wt::Json::Object broadcast{ Wt::Json::Object broadcast{
{"type", "system"}, {"type", "system"},
{"related-user", Wt::WString(toUserName)}, {"related-user", Wt::WString(toUserName)},
{"data", "User is blocked."} {"data", "blocked"}
}; };
addMessageToSessionBroadcast(sessionId, broadcast); addMessageToSessionBroadcast(sessionId, broadcast);
} }
void Broadcast::sendUnblockDone(std::string sessionId, std::string toUserName) { void Broadcast::sendUnblockDone(std::string sessionId, std::string toUserName) {
addMessage(sessionId, toUserName, Message("Conversation is unblocked."));
Wt::Json::Object broadcast{ Wt::Json::Object broadcast{
{"type", "system"}, {"type", "system"},
{"related-user", Wt::WString(toUserName)}, {"related-user", Wt::WString(toUserName)},
{"data", "User is unblocked."} {"data", "unblocked"}
}; };
addMessageToSessionBroadcast(sessionId, broadcast); addMessageToSessionBroadcast(sessionId, broadcast);
} }
@@ -671,6 +672,18 @@ Broadcast::Message::Message(std::string fromSessionId_, std::shared_ptr<Magick::
}; };
} }
Broadcast::Message::Message(Wt::WString message_):
systemMessage(true),
sendType("text"),
message (message_) {
auto timestamp = std::time(nullptr);
auto combinedString = std::to_string(timestamp) + "system09715";
Wt::Auth::SHA1HashFunction hashObj;
auto hash = hashObj.compute(combinedString, "salt");
messageId = Wt::WString(hash);
sendTime = Wt::WDateTime::currentDateTime();
}
Wt::Json::Object Broadcast::Message::json() { Wt::Json::Object Broadcast::Message::json() {
auto json = Wt::Json::Object(); auto json = Wt::Json::Object();
json["sender"] = Wt::Json::Value(fromSessionId); json["sender"] = Wt::Json::Value(fromSessionId);

View File

@@ -51,6 +51,8 @@ public:
Message()= default; Message()= default;
Message(std::string fromSessionId_, Wt::WString message_); Message(std::string fromSessionId_, Wt::WString message_);
Message(std::string fromSessionId_, std::shared_ptr<Magick::Image> image_); Message(std::string fromSessionId_, std::shared_ptr<Magick::Image> image_);
Message(Wt::WString message_);
bool systemMessage{false};
std::string fromSessionId; std::string fromSessionId;
std::string sendType; std::string sendType;
Wt::WDateTime sendTime; Wt::WDateTime sendTime;