diff --git a/resources/migrations/20250312151928-create-players.up.sql b/resources/migrations/20250312151928-create-players.up.sql index 2884edf..452e068 100644 --- a/resources/migrations/20250312151928-create-players.up.sql +++ b/resources/migrations/20250312151928-create-players.up.sql @@ -1,6 +1,7 @@ CREATE TABLE IF NOT EXISTS player ( id INTEGER PRIMARY KEY, - score INTEGER NOT NULL, + game_score INTEGER NOT NULL, + round_score INTEGER NOT NULL, name text NOT NULL, game_code text NOT NULL, play_order integer NOT NULL, diff --git a/src/com/biffweb/my_project.clj b/src/com/biffweb/my_project.clj index 36ccf21..73114f3 100644 --- a/src/com/biffweb/my_project.clj +++ b/src/com/biffweb/my_project.clj @@ -9,6 +9,7 @@ [com.biffweb.my-project.app :as app] [com.biffweb.my-project.auth-module :as auth-module] [rum.core :as rum] + [honey.sql :as sql] [com.biffweb.my-project.email :as email] [com.biffweb.my-project.home :as home] [com.biffweb.my-project.middleware :as mid] diff --git a/src/com/biffweb/my_project/app.clj b/src/com/biffweb/my_project/app.clj index 3a50aea..bac1cef 100644 --- a/src/com/biffweb/my_project/app.clj +++ b/src/com/biffweb/my_project/app.clj @@ -46,13 +46,14 @@ (jdbc/execute! ds (sql/format {:insert-into :player :values (for [[p o] (partition 2 (interleave players player-order))] - {:score 0 + {:game_score 0 + :round_score 0 :name p :play_order o :game_code code})})) {:status 200 - :headers {"HX-redirect" (str/join "/" ["" "game" code "display"])} + :headers {"HX-Redirect" (str/join "/" ["" "game" code "display"])} :session {:id id}})))) (defn display-game [{:keys [session params path-params] @@ -69,53 +70,57 @@ :from :game :where [:= :code code]})) current-player (:game/current_player game)] + (println code game) - (ui/page - {} - [:div - [:nav - [:ul [:li [:strong "Score the pigs"]]] - [:ul [:li (biff/form {:id "reset" - :hx-get "/reset"} - [:button.secondary "Reset"])]]] - [:h4 (:game/id game)] + (if-not (and code game) + {:status 200 + :headers {"HX-Redirect" "/?err=no-code"}} + (ui/page + {} + [:div + [:nav + [:ul [:li [:strong "Score the pigs"]]] + [:ul [:li (biff/form {:id "reset" + :hx-get "/reset"} + [:button.secondary "Reset"])]]] + [:h4 (:game/id game)] - (let [player-elements-swap-str (->> players - (map (fn [{:player/keys [id play_order]}] - (str "#player" id "-" play_order))) - (str/join ",") - (str "multi:"))] - [:div - [:h4 "Game code is " (:game/code game)] - [:table - [:thead - [:tr - [:th {:scope "col"} "Player"] - [:th {:scope "col"} "Score"]]] + (let [player-elements-swap-str (->> players + (map (fn [{:player/keys [id play_order]}] + (str "#player" id "-" play_order))) + (str/join ",") + (str "multi:"))] + [:div + [:h4 "Game code is " (:game/code game)] + [:table + [:thead + [:tr + [:th {:scope "col"} "Player"] + [:th {:scope "col"} "Total Score"]]] - (into [:tbody - {:hx-ext "ws,multi-swap" - :ws-connect (str "/game/" (:game/code game) "/connect") - :hx-swap player-elements-swap-str}] - (for [p players - :let [{:player/keys [id play_order score]} p]] + (into [:tbody + {:hx-ext "ws,multi-swap" + :ws-connect (str "/game/" (:game/code game) "/connect") + :hx-swap player-elements-swap-str}] + (for [p players + :let [{:player/keys [id play_order game_score]} p]] - [:tr - [:th {:scope "row"} [:div - (:player/name p) - (when (= (:player/play_order p) current-player) - [:span.pico-background-jade-600 - {:style {:text-align "center" - :padding "4px 8px" - :width "8px" - :margin-left "20px" - :border-radius "5px" - :align-items "center"}} "now playing"])]] + [:tr + [:th {:scope "row"} [:div + (:player/name p) + (when (= (:player/play_order p) current-player) + [:span.pico-background-jade-600 + {:style {:text-align "center" + :padding "4px 8px" + :width "8px" + :margin-left "20px" + :border-radius "5px" + :align-items "center"}} + "now playing"])]] - [:td [:div - {:id (str "player" id "-" play_order)} - - score]]]))]])]))) + [:td [:div + {:id (str "player" id "-" play_order "-game-score")} + game_score]]]))]])])))) (defn connect-ws [{:keys [session params] :example/keys [chat-clients ds] :as ctx}] @@ -191,9 +196,36 @@ [:button {:type "submit"} "Score pigs"] [:button.contrast {:type "submit"} "Pigs are touching! (Lose all points)"])]))) +(def game-code-input-attrs + {:name "game-code", + :hx-target "this" + :hx-swap "outerHTML" + :placeholder "game code", + :type "text"}) + +(defn route-to-game-view + [{:keys [session params] + :example/keys [ds] + :as _ctx}] + (let [code (:game-code params) + view-type (:view-type params) + game (delay (jdbc/execute-one! ds (sql/format {:select :* :from :game :where [:= :code code]})))] + (cond + (not (and code @game)) + (error-style "Couldn't find that game.") + + (= view-type "show-scoreboard") + {:status 200 + :headers {"HX-Redirect" (str/join "/" ["/game" code "display"])}} + + (= view-type "show-game-remote") + {:status 200 + :headers {"HX-Redirect" (str/join "/" ["/game" code "control"])}}))) + (defn app [{:keys [session params] :example/keys [ds] :as _ctx}] + (pp/pprint session) (let [id (:id session)] (ui/page @@ -209,22 +241,49 @@ [:section [:button {:_ "on click toggle the *display of #new-game-form"} "New game"]] - [:div - [:label - "Existing game? Enter the code here:" + (biff/form + {:hx-post "/game/create" + :style {:display :none} + :hx-swap "afterend" + :id ::new-game-form} + [:div + [:textarea#players {:type "textarea" :rows "8" :name "players"}] + [:fieldset + [:legend "Game options:"] + [:label + [:input {:type "checkbox", :name "random-player-order", :checked ""}] + "Random player order"] + ;; [:label + ;; [:input {:type "checkbox", :name "french", :checked ""}] + ;; "French"] + ] + [:button {:type "submit"} "Start"]]) + + (biff/form + {:id ::display-existing-game + :hx-post "/game/route-to-view" + :hx-swap "afterend"} + [:fieldset.grid [:input - {:name "game-code", - :placeholder "game code", - :type "text" - :_ "on keyup - set #control-existing-game@href to '/game/' + my.value + '/control' - then - set #display-existing-game@href to '/game/' + my.value + '/display' "}]] - [:div {:role "group"} - [:a {:id ::display-existing-game - :type "button"} "Show scoreboard"] - [:a.secondary {:id ::control-existing-game - :type "button"} "Start game control"]]]]))) + {:hidden :true + :name ::view-type + :value ::show-scoreboard}] + [:input game-code-input-attrs] + + [:input {:type :submit :value "Show scoreboard"}]]) + + (biff/form + {:id ::control-existing-game + :hx-post "/game/route-to-view" + :hx-swap "afterend"} + [:fieldset.grid + [:input + {:hidden :true + :name ::view-type + :value ::show-game-remote}] + [:input game-code-input-attrs] + + [:input.secondary {:type :submit :value "Control an existing game"}]])]))) (def about-page (ui/page @@ -243,6 +302,7 @@ ["" {:get app}] ["game/" ["create" {:post create-game}] + ["route-to-view" {:post route-to-game-view}] [":code" ["/display" {:get display-game}] ["/control" {:get control-view}]