flags implementation
Some checks failed
build / build (push) Successful in 29s
release-tag / release-image (push) Has been cancelled

This commit is contained in:
Tijl 2024-08-26 16:46:28 +02:00
parent d246f5e270
commit a71595596a
Signed by: tijl
GPG Key ID: DAE24BFCD722F053
9 changed files with 133 additions and 25 deletions

View File

@ -17,6 +17,51 @@ import (
)
func answerHandler(c *fiber.Ctx) error {
gameId, err := uuid.Parse(c.Cookies("app_flags_game_session"))
if err != nil {
return err
}
answer := c.FormValue("answer")
gameSession, err := db.Queries.GetFlagsGame(context.TODO(), gameId)
if err != nil {
return err
}
err, countries := filterCountriesByTags(gameSession.Tags)
if err != nil {
return err
}
shuffledCountries := shuffleSlice(countries, gameSession.GameSeed.UUID.String())
correctAnswer := shuffledCountries[gameSession.QuestionCurrent-1]
if answer == correctAnswer {
db.Queries.UpdateFlagsGame(context.TODO(), queries.UpdateFlagsGameParams{
GameID: gameId,
QuestionCurrent: gameSession.QuestionCurrent + 1,
})
db.Queries.UpsertGameAnswer(context.TODO(), queries.UpsertGameAnswerParams{
GameID: gameId,
Question: gameSession.QuestionCurrent,
Errors: 0,
})
} else {
db.Queries.UpsertGameAnswer(context.TODO(), queries.UpsertGameAnswerParams{
GameID: gameId,
Question: gameSession.QuestionCurrent,
Errors: 1,
})
}
err = db.Queries.UpdateQuestionCorrect(context.TODO(), gameId)
if err != nil {
return err
}
return questionHandler(c, NewGameUUID{})
}
@ -44,8 +89,7 @@ func questionHandler(c *fiber.Ctx, newGame NewGameUUID) error {
}
if (gameSession.QuestionAmount != 0) && (gameSession.QuestionAmount+1 == gameSession.QuestionCurrent) {
// TODO: game is over
return c.SendString("game is over")
return gameEndHandler(c)
}
err, countries := filterCountriesByTags(gameSession.Tags)
@ -53,6 +97,10 @@ func questionHandler(c *fiber.Ctx, newGame NewGameUUID) error {
return err
}
if int(gameSession.QuestionCurrent) == len(countries) {
return gameEndHandler(c)
}
shuffledCountries := shuffleSlice(countries, gameSession.GameSeed.UUID.String())
shuffledAnswers := shuffleSlice(countries, gameSession.GameSeed.UUID.String()+string(gameSession.QuestionCurrent))
shuffledAnswers = shuffledAnswers[0:4] // 4 random aswers
@ -74,9 +122,13 @@ func questionHandler(c *fiber.Ctx, newGame NewGameUUID) error {
data["Title"] = "tmp"
data["Answers"] = shuffledAnswers
data["Flag"] = flag
data["Errors"] = gameSession.QuestionsErrors
return c.Render("apps/flags/question", data, "layouts/base")
}
func getGameData() {
}
func startNewGameHandler(c *fiber.Ctx) error {
values := c.Request().PostArgs().PeekMulti("tags")
var selectedTags []string
@ -108,13 +160,29 @@ func startNewGameHandler(c *fiber.Ctx) error {
c.Cookie(&fiber.Cookie{
Name: "app_flags_game_session",
Value: row.GameID.String(),
Secure: true,
//Secure: true,
})
return questionHandler(c, NewGameUUID{used: true, UUID: row.GameID})
}
func stopGameHandler(c *fiber.Ctx) error {
func gameEndHandler(c *fiber.Ctx) error {
gameId, err := uuid.Parse(c.Cookies("app_flags_game_session"))
if err != nil {
return err
}
gameSession, err := db.Queries.GetFlagsGame(context.TODO(), gameId)
if err != nil {
return err
}
data := *web.Common(c)
data["Title"] = "tmp"
data["Errors"] = gameSession.QuestionsErrors
return c.Render("apps/flags/end", data, "layouts/base")
}
func stopGameHandler(c *fiber.Ctx) error { // exit game
utils.ClearCookie(c, "app_flags_game_session")
return EntryPageHandler(c)
}

View File

@ -80,8 +80,8 @@ func Setup() {
case "start":
return startNewGameHandler(c)
case "answer":
return c.SendString("wip")
case "cancel":
return answerHandler(c)
case "exit":
return stopGameHandler(c)
}

View File

@ -13,9 +13,16 @@ WHERE game_id = $2;
-- name: UpdateQuestionCorrect :exec
UPDATE app_flags_games
SET questions_correct = (
SELECT COUNT(*)
SET questions_errors = (
SELECT COALESCE(SUM(errors), 0)
FROM app_flags_games_answers
WHERE game_id $1 AND correct = TRUE
WHERE app_flags_games_answers.game_id = app_flags_games.game_id
)
WHERE game_id = $1;
WHERE app_flags_games.game_id = $1;
-- name: UpsertGameAnswer :exec
INSERT INTO app_flags_games_answers (game_id, question, errors)
VALUES ($1, $2, $3)
ON CONFLICT (game_id, question)
DO UPDATE SET errors = app_flags_games_answers.errors + EXCLUDED.errors;

View File

@ -38,7 +38,7 @@ func (q *Queries) CreateFlagsGame(ctx context.Context, arg CreateFlagsGameParams
}
const getFlagsGame = `-- name: GetFlagsGame :one
SELECT game_id, game_seed, uid, tags, question_amount, question_current, question_correct, created_at, last_activity FROM app_flags_games WHERE game_id = $1 LIMIT 1
SELECT game_id, game_seed, uid, tags, question_amount, question_current, questions_errors, created_at, last_activity FROM app_flags_games WHERE game_id = $1 LIMIT 1
`
func (q *Queries) GetFlagsGame(ctx context.Context, gameID uuid.UUID) (AppFlagsGame, error) {
@ -51,7 +51,7 @@ func (q *Queries) GetFlagsGame(ctx context.Context, gameID uuid.UUID) (AppFlagsG
pq.Array(&i.Tags),
&i.QuestionAmount,
&i.QuestionCurrent,
&i.QuestionCorrect,
&i.QuestionsErrors,
&i.CreatedAt,
&i.LastActivity,
)
@ -76,15 +76,33 @@ func (q *Queries) UpdateFlagsGame(ctx context.Context, arg UpdateFlagsGameParams
const updateQuestionCorrect = `-- name: UpdateQuestionCorrect :exec
UPDATE app_flags_games
SET questions_correct = (
SELECT COUNT(*)
SET questions_errors = (
SELECT COALESCE(SUM(errors), 0)
FROM app_flags_games_answers
WHERE game_id $1 AND correct = TRUE
WHERE app_flags_games_answers.game_id = app_flags_games.game_id
)
WHERE game_id = $1
WHERE app_flags_games.game_id = $1
`
func (q *Queries) UpdateQuestionCorrect(ctx context.Context, dollar_1 interface{}) error {
_, err := q.db.ExecContext(ctx, updateQuestionCorrect, dollar_1)
func (q *Queries) UpdateQuestionCorrect(ctx context.Context, gameID uuid.UUID) error {
_, err := q.db.ExecContext(ctx, updateQuestionCorrect, gameID)
return err
}
const upsertGameAnswer = `-- name: UpsertGameAnswer :exec
INSERT INTO app_flags_games_answers (game_id, question, errors)
VALUES ($1, $2, $3)
ON CONFLICT (game_id, question)
DO UPDATE SET errors = app_flags_games_answers.errors + EXCLUDED.errors
`
type UpsertGameAnswerParams struct {
GameID uuid.UUID
Question int32
Errors int32
}
func (q *Queries) UpsertGameAnswer(ctx context.Context, arg UpsertGameAnswerParams) error {
_, err := q.db.ExecContext(ctx, upsertGameAnswer, arg.GameID, arg.Question, arg.Errors)
return err
}

View File

@ -18,7 +18,7 @@ type AppFlagsGame struct {
Tags []string
QuestionAmount int32
QuestionCurrent int32
QuestionCorrect int32
QuestionsErrors int32
CreatedAt time.Time
LastActivity time.Time
}

View File

@ -5,7 +5,7 @@ CREATE TABLE app_flags_games (
tags VARCHAR[] NOT NULL,
question_amount INT NOT NULL,
question_current INT DEFAULT 1 NOT NULL,
question_correct INT DEFAULT 0 NOT NULL,
questions_errors INT DEFAULT 0 NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
FOREIGN KEY (uid) REFERENCES users (uid)

View File

@ -0,0 +1,13 @@
<div>
<div>
Errors: {{.Errors}}
</div>
<div>game is over</div>
<form method="post" hx-boost="true">
<input class="hidden" name="type" value="exit" />
<button type="submit" class="btn">exit</button>
</form>
</div>

View File

@ -2,6 +2,10 @@
<div>
<div>
Errors: {{.Errors}}
</div>
<div class="flex justify-center p-4 mt-4">
<span style="font-size: 105px;">{{.Flag}}</span>
</div>
@ -17,7 +21,7 @@
</div>
<form hx-boost="true" method="post">
<input class="hidden" name="type" value="cancel" />
<input class="hidden" name="type" value="exit" />
<button type="submit" class="btn hover:btn-error">Stop</button>
</form>

View File

@ -55,7 +55,6 @@
<span class="text-base">{{.T.about}}</span>
</a>
</li>
<!--
<li class="flex-none">
<details class="dropdown">
<summary><a class="flex gap-4">
@ -92,7 +91,6 @@
</ul>
</details>
</li>
-->
<li>
{{if .SignedIn}}
<a class='flex gap-4 {{if eq .Path "/account"}}active{{end}}' href="/account">