diff --git a/build.sh b/build.sh index df3636f..4472992 100644 --- a/build.sh +++ b/build.sh @@ -3,3 +3,4 @@ bin2cpp --file=client/footer.html --output=server/src/generated bin2cpp --file=client/header.html --output=server/src/generated bin2cpp --file=client/style.css --output=server/src/generated +bin2cpp --file=client/script.js --output=server/src/generated diff --git a/client/header.html b/client/header.html index e444d8a..4226cd9 100644 --- a/client/header.html +++ b/client/header.html @@ -4,6 +4,7 @@ posts +
diff --git a/client/script.js b/client/script.js new file mode 100644 index 0000000..17357f5 --- /dev/null +++ b/client/script.js @@ -0,0 +1,15 @@ +function like(id) { + + const usernameBox = document.getElementById('username'); + const passwordBox = document.getElementById('password'); + + const formData = new FormData(); + formData.append('username', usernameBox.value); + formData.append('password', passwordBox.value); + formData.append('post', id); + + fetch('/like', { + method: 'POST', + body: formData + }); +} diff --git a/client/style.css b/client/style.css index 700e94b..ae2e853 100644 --- a/client/style.css +++ b/client/style.css @@ -55,6 +55,11 @@ img { box-sizing: border-box; } +.post-buttons { + display: flex; + gap: 5px; +} + @media (max-width: 600px) { input, textarea, button { font-size: 16px; diff --git a/server/meson.build b/server/meson.build index 681b576..56d98f7 100644 --- a/server/meson.build +++ b/server/meson.build @@ -7,6 +7,7 @@ sources = [ 'src/generated/header.cpp', 'src/generated/footer.cpp', 'src/generated/style.cpp', + 'src/generated/script.cpp', # bcrypt 'src/bcrypt/bcrypt.cpp', diff --git a/server/src/db.cpp b/server/src/db.cpp index c3b78aa..b4566bf 100644 --- a/server/src/db.cpp +++ b/server/src/db.cpp @@ -154,6 +154,22 @@ void Database::addPost(const Post& post) { sqlite3_finalize(stmt); } +void Database::addLike(uint64_t postId, uint64_t userId) { + std::stringstream sql; + sql << R"( + UPDATE posts + SET likes = likes + 1 + WHERE id = + )"; + sql << postId << ";"; + std::string sqlstr = sql.str(); + + char* errmsg = nullptr; + if (sqlite3_exec(db, sqlstr.c_str(), nullptr, nullptr, &errmsg) != SQLITE_OK) { + throw std::runtime_error("sqlite3 error: " + std::string(errmsg)); + } +} + diff --git a/server/src/db.h b/server/src/db.h index a4460d2..71f0187 100644 --- a/server/src/db.h +++ b/server/src/db.h @@ -32,6 +32,7 @@ class Database { std::vector getUserPosts(uint64_t userId); std::vector getTopPosts(uint64_t amount); void addPost(const Post& post); + void addLike(uint64_t postId, uint64_t userId); std::optional getUser(uint64_t id); std::optional getUserByName(const std::string& name); diff --git a/server/src/main.cpp b/server/src/main.cpp index e3a035e..85d8667 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -14,15 +15,18 @@ #include "generated/header.h" #include "generated/footer.h" #include "generated/style.h" +#include "generated/script.h" int main() { const bin2cpp::File& headerfile = bin2cpp::getHeaderHtmlFile(); const bin2cpp::File& footerfile = bin2cpp::getFooterHtmlFile(); const bin2cpp::File& stylefile = bin2cpp::getStyleCssFile(); + const bin2cpp::File& scriptfile = bin2cpp::getScriptJsFile(); std::string header{headerfile.getBuffer(), headerfile.getSize()}; std::string footer{footerfile.getBuffer(), footerfile.getSize()}; std::string style{stylefile.getBuffer(), stylefile.getSize()}; + std::string script{scriptfile.getBuffer(), scriptfile.getSize()}; Database database{"chookchat.db"}; @@ -34,6 +38,10 @@ int main() { response.set_content(style, "text/css"); }); + svr.Get("/script.js", [&script](const httplib::Request& request, httplib::Response& response) { + response.set_content(script, "text/css"); + }); + svr.Get("/", [&header, &footer, &database, &data_mutex](const httplib::Request& request, httplib::Response& response) { std::stringstream ss; @@ -57,7 +65,7 @@ int main() { } }); - svr.Post("/make_post", [&header, &footer, &database, &data_mutex](const httplib::Request& request, httplib::Response& response) { + svr.Post("/make_post", [&database, &data_mutex](const httplib::Request& request, httplib::Response& response) { std::string username = request.get_param_value("username"); std::string password = request.get_param_value("password"); @@ -90,11 +98,26 @@ int main() { database.addPost(Post(post, userId)); response.set_redirect("/"); } catch (const std::runtime_error& e) { - response.set_content("

there was an error :( it is: " +std::string(e.what()) + "

", "text/html"); + response.set_content("

there was an error :( it is: " + std::string(e.what()) + "

", "text/html"); } }); + svr.Post("/like", [&database, &data_mutex](const httplib::Request& request, httplib::Response& response) { + std::string username = request.get_param_value("username"); + std::string password = request.get_param_value("password"); + std::string post = request.get_param_value("post"); + + std::lock_guard lock(data_mutex); + + try { + uint64_t postNum = std::stoull(post); + database.addLike(postNum, 0); + } catch (const std::runtime_error& e) { + response.set_content("

there was an error :( it is: " + std::string(e.what()) + "

", "text/html"); + } + }); + svr.listen("0.0.0.0", 8080); } diff --git a/server/src/post.cpp b/server/src/post.cpp index 3e59a5a..8f6319b 100644 --- a/server/src/post.cpp +++ b/server/src/post.cpp @@ -53,8 +53,8 @@ std::string Post::genHtml() const { ss << ""; ss << "
"; - ss << ""; - ss << ""; + ss << ""; + ss << ""; ss << "
"; return ss.str();