Serve static HTML game page

This commit is contained in:
2024-11-03 20:14:03 +01:00
parent 144ac314f7
commit ff7ad42e32
6 changed files with 97 additions and 7 deletions

View File

@@ -1,11 +1,13 @@
"""Main alfagok API application."""
import logging
from datetime import date
from typing import Union
from fastapi import FastAPI
from pydantic import FilePath
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pydantic import DirectoryPath, FilePath
from pydantic_settings import BaseSettings
@@ -19,11 +21,17 @@ class Settings(BaseSettings):
# Date of first game so we can calculate the game ID we're on
start_date: date
static_dir: DirectoryPath = 'static'
template_dir: DirectoryPath = 'templates'
debug: bool = False
app = FastAPI()
settings = Settings()
app.mount('/static', StaticFiles(directory=settings.static_dir), name='static')
templates = Jinja2Templates(directory=settings.template_dir)
with open(settings.word_list, 'r', encoding='utf-8') as word_file:
# Load the game words
@@ -53,10 +61,11 @@ def is_valid_dictionary_word(word: str) -> bool:
return f'{word}\n' in dictionary
@app.get("/")
def read_root():
"""Ohai."""
return {"Hello": "World"}
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
"""Generate the main HTML page of the game."""
language = 'nl'
return templates.TemplateResponse(request=request, name='index.html', context={'language': language})
@app.get('/api/game')

View File

@@ -0,0 +1,10 @@
var clip = new Clipboard('.copy');
clip.on("success", function(e) {
document.getElementById('copyresults').innerHTML = '<p style="font-size:var(--small);opacity:50%">Copied! Share your results with friends.</p>';
e.clearSelection();
});
clip.on("error", function() {
document.getElementById('copyresults').innerHTML = '<p style="font-size:var(--small);opacity:50%">Error. Please copy manually...</p>';
});

View File

@@ -0,0 +1,23 @@
/* Original from alphaguess.com */
function go() {
window.timerID = window.setInterval(timer, 0);
}
function timer(){
var nextgame = document.getElementById('nextgame');
var now = new Date();
var midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate()+1, 0, 0, 0);
var diff = Math.floor((midnight - now)/1000);
var hoursRemain = Math.floor(diff/(60*60));
var minutesRemain = Math.floor((diff-hoursRemain*60*60)/60);
var secondsRemain = Math.floor(diff%60);
nextgame.innerHTML = '<span class="nextgame">'+addZero(hoursRemain)+':'+addZero(minutesRemain)+':'+addZero(secondsRemain)+' left</span>';
}
function addZero(num){
if(num <=9) return '0'+num;
else return num;
}
go();

View File

@@ -0,0 +1,4 @@
body {
background-color: #333;
color: #FFF;
}

View File

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="{{ language }}">
<head>
<title>alfagok</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/static/game.css">
</head>
<body>
<a href="/" v-cloak class="title">alphaguess</a> <span class="puzzleno">puzzle #{{numberOfDaysSinceStart}} • <span id="nextgame"></span></span>
<div v-cloak v-if="beforeGuesses.length || afterGuesses.length"><br></div>
<div v-cloak class="instructions" v-else>
<p>Guess the word of the day. Each guess reveals where the word sits alphabetically.</p>
</div>
<center>
<div>
<div v-if="winTime" class="win">
<h3><b>You got it! 🎉</b></h3>
<p>Today's word was <b>{{guessValue}}</b>.</p>
<div id="stats">
<div id="results">
<p><b>🧩 Puzzle #{{numberOfDaysSinceStart}}</b></p>
<p>🤔 {{guesses.length}} guesses</p>
<p>⏱️ {{getFormattedTime(winTime - startTime)}}</p>
<p>🔗 <span style="color:var(--blue)">alphaguess.com</span></p>
</div>
</div>
<div id="copyresults"></div>
<button class="copy" data-clipboard-target="#results">
Tap to copy and share ❤️
</button>
</div>
</center>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.12/clipboard.min.js" rel=preload></script>
<script src="/static/copy.js"></script>
<script src="/static/countdown.js"></script>
<script src="/static/game.js"></script>
</body>
</html>