From af557ffc6e09464892d61110ce20fb82a5ca34d0 Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Mon, 16 Jan 2023 20:26:52 +0300 Subject: [PATCH] basic notifications impl for back-end --- db/migrations/20_notifications.sql | 15 +++++++++++++++ src/crystal-gauntlet.cr | 1 + src/endpoints/levels/rateLevel.cr | 14 +++++++++++++- src/lib/notifications.cr | 17 +++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 db/migrations/20_notifications.sql create mode 100644 src/lib/notifications.cr diff --git a/db/migrations/20_notifications.sql b/db/migrations/20_notifications.sql new file mode 100644 index 0000000..c83939c --- /dev/null +++ b/db/migrations/20_notifications.sql @@ -0,0 +1,15 @@ +-- +migrate up +CREATE TABLE notifications ( + id SERIAL PRIMARY KEY, + + account_id INTEGER NOT NULL references accounts(id), + type TEXT NOT NULL, + target INTEGER, -- represents whatever is affected; for SQL querying assistance. INTEGER because it's always an ID, might be tweaked in the future + details TEXT NOT NULL, -- a JSON of various things relevant to displaying the notification + + created_at TEXT NOT NULL DEFAULT (STRFTIME('%Y-%m-%d %H:%M:%f', 'now')), + read_at TEXT +); + +-- +migrate down +DROP TABLE notifications; \ No newline at end of file diff --git a/src/crystal-gauntlet.cr b/src/crystal-gauntlet.cr index 1c5cc91..76823cc 100644 --- a/src/crystal-gauntlet.cr +++ b/src/crystal-gauntlet.cr @@ -26,6 +26,7 @@ require "./lib/creator_points" require "./lib/versions" require "./lib/ips" require "./lib/ranks" +require "./lib/notifications" require "./patch-exe.cr" diff --git a/src/endpoints/levels/rateLevel.cr b/src/endpoints/levels/rateLevel.cr index 00ab8bd..7bd876a 100644 --- a/src/endpoints/levels/rateLevel.cr +++ b/src/endpoints/levels/rateLevel.cr @@ -105,7 +105,19 @@ CrystalGauntlet.endpoints["/suggestGJStars20.php"] = ->(context : HTTP::Server:: return "-2" end - DATABASE.exec "update levels set stars = ?, featured = ?, difficulty = ? where id = ?", params["stars"].to_i, params["feature"].to_i, (stars_to_difficulty(params["stars"].to_i) || LevelDifficulty::Easy).to_i, params["levelID"].to_i + level_id = params["levelID"].to_i + stars = params["stars"].to_i + difficulty = stars_to_difficulty(params["stars"].to_i) || LevelDifficulty::Easy + + author_account_id = DATABASE.query_one("select users.account_id from levels left join users on users.id = levels.user_id where levels.id = ?", level_id, as: {Int32?}) + if author_account_id + notif_type = params["feature"] == "1" ? "authored_level_featured" : "authored_level_rated" + + Notifications.clear_previous_notifications(author_account_id, notif_type, level_id) + Notifications.send_notification(author_account_id, notif_type, level_id, {"stars" => stars.to_i64, "difficulty" => difficulty.to_i64}) + end + + DATABASE.exec "update levels set stars = ?, featured = ?, difficulty = ? where id = ?", stars, params["feature"].to_i, difficulty.to_i, level_id "1" } diff --git a/src/lib/notifications.cr b/src/lib/notifications.cr new file mode 100644 index 0000000..785ecd0 --- /dev/null +++ b/src/lib/notifications.cr @@ -0,0 +1,17 @@ +require "json" + +include CrystalGauntlet + +module CrystalGauntlet::Notifications + extend self + + alias NotificationValue = Hash(String, String | Int64 | Bool | Float64 | Nil) + + def clear_previous_notifications(account_id : Int32, type : String, target : Int32) + DATABASE.exec("delete from notifications where account_id = ? and type = ? and target = ?", account_id, type, target) + end + + def send_notification(account_id : Int32, type : String, target : Int32?, details : NotificationValue? = nil) + DATABASE.exec("insert into notifications (id, account_id, type, target, details) values (?, ?, ?, ?, ?)", IDs.get_next_id("notifications"), account_id, type, target, details.try &.to_json || "{}") + end +end