This commit is contained in:
Torsten Schulz
2024-01-26 08:31:10 +01:00
parent 2a673b50ef
commit fc21a7e772
5 changed files with 1771 additions and 0 deletions

150
src/app.h Normal file
View File

@@ -0,0 +1,150 @@
#ifndef APP_H
#define APP_H
#include <Wt/WApplication.h>
#include <Wt/WEnvironment.h>
#include "broadcast.h"
#include "curl/curl.h"
#include <libxml2/libxml/tree.h>
#include <libxml2/libxml/xpath.h>
namespace Magick {
class Image;
}
class App : public Wt::WApplication, public Client {
public:
App(const Wt::WEnvironment& env, Broadcast& server);
private:
std::unordered_map<std::string, std::string> genders_ {
{"F", "Female"},
{"M", "Male"},
{"P", "Pair"},
{"TF", "Transgender (M->F)"},
{"TM", "Transgender (F->M)"}
};
std::vector<std::string> notAllowedNickPhrases_ {
"whore",
"hitler",
"nazi",
"admin"
};
struct Smiley {
std::string code;
std::string tooltip;
Smiley()=default;
Smiley(std::string code_, std::string tooltip_): code(code_), tooltip(tooltip_) {};
};
std::unordered_map<std::string, Smiley> smileys_ {
{":)", Smiley("1F642", "Smile")},
{":D", Smiley("1F600", "Laugh")},
{":(", Smiley("1F641", "Sad")},
{";)", Smiley("1F609", "Twinkle")},
{":p", Smiley("1F60B", "Tongue")},
{";p", Smiley("1F61C", "Twinkle tongue")},
{":'(", Smiley("1F622", "Cry")}
};
Wt::WString smileyPlaceholder_ = "&#x{1};";
const Wt::WEnvironment &env_;
Broadcast &server_;
Wt::WContainerWidget *menuContainer_;
Wt::WContainerWidget *userListContainer_;
Wt::WContainerWidget *contentContainer_;
Wt::JSignal<std::string, std::string> updateLocationSignal_;
std::string responseData_{""};
Wt::WPushButton *inbox_;
std::vector<std::string> searchResults_;
std::string currentConversationWith_{""};
bool inboxOpen_{false};
int messageCursorPosition_{-1};
std::unique_ptr<Wt::WSound> messageReceived_;
void initApp();
Wt::WVBoxLayout *createVerticalLayout();
Wt::WHBoxLayout *createActionLayout(Wt::WVBoxLayout *verticalContainer);
void createUserListContainer(Wt::WHBoxLayout *layout);
void createContentContainer(Wt::WHBoxLayout *layout);
void createHeadContainer(Wt::WVBoxLayout *layout);
void createMenuContainer(Wt::WVBoxLayout *layout);
void showLogin();
void incomingBroadcast();
void startChat();
void updateLocation();
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *output) {
size_t totalSize = size * nmemb;
output->append(reinterpret_cast<const char *>(contents), totalSize);
return totalSize;
};
void populateCountryComboBox(Wt::WComboBox *countryWidget);
void handleLogin(Wt::WLineEdit *userName, Wt::WComboBox *countryWidget, Wt::WSpinBox *ageWidget, Wt::WComboBox *genderWidget);
void populateGenderComboBox(Wt::WComboBox *genderWidget);
std::string getGenderShortByGender(std::string gender);
void updateUserlist(Wt::Json::Array userList);
std::vector<Wt::Json::Object> sortUserList(Wt::Json::Array unsortedUserList);
void createMenu();
void addLeaveButton();
void logout();
void addIdentifier();
void addSearchButton();
void addInboxButton();
void executeSearch();
void openInbox();
bool isNickAllowed(const std::string &nick);
bool compareJsonObjects(const Wt::Json::Object &obj1, const Wt::Json::Object &obj2);
void requestConversation(std::string conversationWith);
void showConversation(Wt::Json::Object data);
void sendMessage(Wt::WLineEdit *inputLine);
void renderConversation(Wt::Json::Object conversation);
void showUnreadMessages(Wt::Json::Object data);
void showOpenInbox(Wt::Json::Object data);
void updateUserinfo(Wt::Json::Object data);
std::unique_ptr<Wt::WContainerWidget> createSmileysBar(Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition);
void toggleSmileysBar(Wt::WContainerWidget *smileyBar);
void showSystemMessage(Wt::Json::Object broadcast);
void addStartChatButton(Wt::WGridLayout *contentGrid, Wt::WLineEdit *userName, Wt::WComboBox *country, Wt::WSpinBox *age, Wt::WComboBox *gender);
Wt::WComboBox *addCountrySelection(Wt::WGridLayout *contentGrid);
Wt::WSpinBox *addAgeInput(Wt::WGridLayout *contentGrid);
Wt::WLineEdit *addUsernameInput(Wt::WGridLayout *contentGrid);
Wt::WComboBox *addGenderSelection(Wt::WGridLayout *contentGrid);
void createLoginContainer();
void connectToServer();
void setUserData(const std::string &nick, Wt::WComboBox *countryWidget, Wt::WSpinBox *ageWidget, Wt::WComboBox *genderWidget);
void validateAge(Wt::WSpinBox *ageWidget);
bool isGenderSelected(Wt::WComboBox *genderWidget);
void validateGender(Wt::WComboBox *genderWidget);
bool isNameAlreadyInUse(const std::string &nick);
bool isInvalidName(const std::string &nick);
void validateName(const std::string &nick);
std::string extractTrimmedUserName(Wt::WLineEdit *userName);
Wt::WPushButton *createSendButton(Wt::WHBoxLayout *inputLayout, Wt::WLineEdit *inputLine);
Wt::WContainerWidget *createSmileyBar(Wt::WContainerWidget *parent, Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition);
Wt::WContainerWidget *createSmileyButton(Wt::WHBoxLayout *inputLayout, Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition);
Wt::WImage *createSendImageButton(Wt::WHBoxLayout *inputLayout);
Wt::WLineEdit *createInputLine(Wt::WHBoxLayout *inputLayout);
Wt::WContainerWidget *createInputContainer(Wt::WVBoxLayout *layout);
std::unique_ptr<Wt::WText> createInfoText(Wt::Json::Object userData);
Wt::WContainerWidget *createInfoWidget(Wt::WVBoxLayout *layout, Wt::Json::Object userData);
void setupConversationUI(Wt::Json::Object userData);
bool shouldShowConversation(Wt::Json::Object userData);
Wt::Json::Object extractUserData(Wt::Json::Object data);
std::unique_ptr<Wt::WPushButton> createBlockButton(Wt::Json::Object userData);
std::string replaceSmileys(std::string outputText);
void renderChatLine(Wt::Json::Object &line, Wt::Json::Object conversation, Wt::WContainerWidget *outputContainer);
std::string getChatLineWriter(Wt::Json::Object &line, Wt::Json::Object conversation);
void renderChatLines(Wt::Json::Object conversation, Wt::WContainerWidget *outputContainer);
void updateOutputContainer(Wt::Json::Object conversation);
void handleException(const std::exception &e);
void processXmlNode(xmlNodePtr node);
void parseXmlDocument(xmlDocPtr doc);
void processCurlResponse();
void performCurlRequest(CURL *curl);
void setCurlOptions(CURL *curl, const std::string &apiUrl);
std::string buildApiUrl(const std::string &userIP);
std::string getUserIP();
Magick::Image scaleImage(const Magick::Image &originalImage, int maxSize) const;
Wt::WWebWidget *createImageElement(Wt::Json::Object &line, const std::string &writer, Wt::WContainerWidget *outputContainer);
Wt::WWebWidget *createTextElement(const std::string &writer, const std::string &text, Wt::WContainerWidget *outputContainer);
void createImprintContainer(Wt::WVBoxLayout *containerLayout);
};
#endif // APP_H