layout +backend
This commit is contained in:
parent
189af45397
commit
bef591dfe0
9 changed files with 439 additions and 31 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -19,3 +19,6 @@ Thumbs.db
|
|||
# Vite
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
# Backend
|
||||
backend/static
|
||||
|
|
38
backend/go.mod
Normal file
38
backend/go.mod
Normal file
|
@ -0,0 +1,38 @@
|
|||
module stream-score
|
||||
|
||||
go 1.23.3
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/cors v1.7.3
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.12.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.7 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
||||
github.com/goccy/go-json v0.10.4 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
golang.org/x/arch v0.12.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
95
backend/go.sum
Normal file
95
backend/go.sum
Normal file
|
@ -0,0 +1,95 @@
|
|||
github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk=
|
||||
github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
|
||||
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
|
||||
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
|
||||
github.com/gin-contrib/cors v1.7.3 h1:hV+a5xp8hwJoTw7OY+a70FsL8JkVVFTXw9EcfrYUdns=
|
||||
github.com/gin-contrib/cors v1.7.3/go.mod h1:M3bcKZhxzsvI+rlRSkkxHyljJt1ESd93COUvemZ79j4=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
|
||||
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
|
||||
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
|
||||
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
39
backend/main.go
Normal file
39
backend/main.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
Engine := gin.Default()
|
||||
Engine.Use(cors.Default())
|
||||
|
||||
sapp := Engine.Group("/_app")
|
||||
sapp.Static("/", "./static/_app")
|
||||
|
||||
static := Engine.Group("/static")
|
||||
static.Static("/", "./static/static")
|
||||
|
||||
Engine.StaticFile("/", "./static/index.html")
|
||||
Engine.StaticFile("/favicon.png", "./static/favicon.png")
|
||||
|
||||
Engine.ForwardedByClientIP = true
|
||||
Engine.SetTrustedProxies([]string{"127.0.0.1"})
|
||||
|
||||
api := Engine.Group("/api")
|
||||
|
||||
api.GET("/sse", SSEHandler)
|
||||
api.GET("/status", GetStatus)
|
||||
api.POST("/status", SetStatus)
|
||||
|
||||
port := os.Getenv("PORT")
|
||||
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
}
|
||||
|
||||
Engine.Run(":" + port)
|
||||
}
|
87
backend/sse_stream.go
Normal file
87
backend/sse_stream.go
Normal file
|
@ -0,0 +1,87 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Data interface{} `json:"data"`
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
Channel chan Message `json:"clients"`
|
||||
}
|
||||
|
||||
var (
|
||||
clients = make(map[*Client]bool)
|
||||
clientsMutex sync.Mutex
|
||||
broadcast = make(chan Message)
|
||||
)
|
||||
|
||||
func SSEHandler(c *gin.Context) {
|
||||
client := &Client{
|
||||
Channel: make(chan Message),
|
||||
}
|
||||
|
||||
log.Printf("events: %+v", client)
|
||||
|
||||
AddClient(client)
|
||||
|
||||
defer unregisterClient(client)
|
||||
|
||||
log.Printf("Client %s connected", client)
|
||||
|
||||
c.Writer.Header().Set("Content-Type", "text/event-stream")
|
||||
c.Writer.Header().Set("Cache-Control", "no-cache")
|
||||
c.Writer.Header().Set("Connection", "keep-alive")
|
||||
c.Writer.Header().Set("Transfer-Encoding", "chunked")
|
||||
|
||||
for {
|
||||
select {
|
||||
case msg := <-client.Channel:
|
||||
fmt.Fprintf(c.Writer, "data: %s\n\n", msg.Data)
|
||||
c.Writer.Flush()
|
||||
case <-c.Writer.CloseNotify():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AddClient(client *Client) {
|
||||
clientsMutex.Lock()
|
||||
clients[client] = true
|
||||
clientsMutex.Unlock()
|
||||
}
|
||||
|
||||
func unregisterClient(client *Client) {
|
||||
clientsMutex.Lock()
|
||||
delete(clients, client)
|
||||
close(client.Channel)
|
||||
clientsMutex.Unlock()
|
||||
}
|
||||
|
||||
func SendMsg(c *gin.Context) {
|
||||
var msg Message
|
||||
c.ShouldBind(&msg)
|
||||
msg.Id = time.Now().Format(time.RFC3339)
|
||||
broadcast <- msg
|
||||
c.JSON(http.StatusOK, gin.H{"status": "sent"})
|
||||
}
|
||||
|
||||
func handleMessages() {
|
||||
for {
|
||||
msg := <-broadcast
|
||||
clientsMutex.Lock()
|
||||
for client := range clients {
|
||||
client.Channel <- msg
|
||||
}
|
||||
clientsMutex.Unlock()
|
||||
}
|
||||
}
|
83
backend/status.go
Normal file
83
backend/status.go
Normal file
|
@ -0,0 +1,83 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Status struct {
|
||||
Surfers []Surfer `json:"surfers"`
|
||||
Round Info `json:"round"`
|
||||
Count int `json:"surfersCount"`
|
||||
}
|
||||
|
||||
type Surfer struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
Priority string `json:"priority"`
|
||||
Score int `json:"score"`
|
||||
Delete bool `json:"delete"`
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Round string `json:"round"`
|
||||
Heat int `json:"heat"`
|
||||
Category string `json:"category"`
|
||||
Time int `json:"time"`
|
||||
}
|
||||
|
||||
var status Status
|
||||
|
||||
func initStatus() interface{} {
|
||||
return Status{
|
||||
Surfers: []Surfer{
|
||||
{
|
||||
Name: "",
|
||||
Color: "lightgray",
|
||||
Priority: "",
|
||||
Score: 0,
|
||||
},
|
||||
},
|
||||
Round: Info{
|
||||
Round: "",
|
||||
Heat: 1,
|
||||
Category: "",
|
||||
Time: 0,
|
||||
},
|
||||
Count: 1,
|
||||
}
|
||||
}
|
||||
|
||||
func GetStatus(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, status)
|
||||
|
||||
log.Printf("get status: %+v", status)
|
||||
}
|
||||
|
||||
func SetStatus(c *gin.Context) {
|
||||
var stat = Status{}
|
||||
|
||||
body, _ := io.ReadAll(c.Request.Body)
|
||||
log.Printf("set status body: %s", string(body))
|
||||
c.Request.Body = io.NopCloser(bytes.NewReader(body))
|
||||
|
||||
err := c.ShouldBindJSON(&stat)
|
||||
log.Printf("set status: %+v - err: %+v", stat, err)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": http.StatusOK,
|
||||
"message": stat,
|
||||
})
|
||||
|
||||
var msg = Message{
|
||||
Data: stat,
|
||||
}
|
||||
|
||||
broadcast <- msg
|
||||
|
||||
status = stat
|
||||
}
|
BIN
backend/stream-score
Executable file
BIN
backend/stream-score
Executable file
Binary file not shown.
|
@ -4,15 +4,19 @@
|
|||
import { rounds } from "$lib/stores/rounds.js";
|
||||
import { categories } from "$lib/stores/categories.js";
|
||||
|
||||
// let wWidth = $state(window.innerWidth);
|
||||
// let wHeight = $state(window.innerHeight);
|
||||
|
||||
let timer;
|
||||
|
||||
let surfers = $state([]);
|
||||
let start = $state(false);
|
||||
|
||||
let info = $state({
|
||||
cat: "U12 M",
|
||||
category: "U12 M",
|
||||
round: "Qualifying",
|
||||
heat: "1",
|
||||
time: 0,
|
||||
});
|
||||
let mins = $state(0);
|
||||
let secs = $state(0);
|
||||
|
@ -44,16 +48,31 @@
|
|||
console.log("ResetLocalCache");
|
||||
window.sessionStorage.clear();
|
||||
surfers = [
|
||||
{ id: 1, name: "", score: 0, colore: "black", delete: false },
|
||||
{ id: 2, name: "", score: 0, colore: "black", delete: false },
|
||||
{
|
||||
id: 1,
|
||||
name: "",
|
||||
score: 0,
|
||||
color: "lightgray",
|
||||
priority: 0,
|
||||
delete: false,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "",
|
||||
score: 0,
|
||||
color: "lightgray",
|
||||
priority: 0,
|
||||
delete: false,
|
||||
},
|
||||
];
|
||||
start = false;
|
||||
info = {
|
||||
cat: "U12 M",
|
||||
category: "U12 M",
|
||||
round: "Qualifying",
|
||||
heat: "1",
|
||||
time: 0,
|
||||
};
|
||||
mins = 0;
|
||||
mins = info.time;
|
||||
secs = 0;
|
||||
round_name = false;
|
||||
console.log(`reset store: ${JSON.stringify(surfers)}`);
|
||||
|
@ -68,8 +87,10 @@
|
|||
function StartHeat() {
|
||||
console.log("StartHeat");
|
||||
start = true;
|
||||
mins = info.time;
|
||||
secs = 0;
|
||||
SaveToLocalCahe();
|
||||
timer = setInterval(Timer, 100);
|
||||
timer = setInterval(Timer, 1000);
|
||||
}
|
||||
|
||||
function pad(n) {
|
||||
|
@ -110,6 +131,7 @@
|
|||
name: "",
|
||||
score: 0,
|
||||
rank: 0,
|
||||
color: "lightgray",
|
||||
delete: true,
|
||||
};
|
||||
surfers.push(newSurfer);
|
||||
|
@ -123,8 +145,28 @@
|
|||
SaveToLocalCahe();
|
||||
}
|
||||
}
|
||||
|
||||
async function SendStatus() {
|
||||
if (dev) {
|
||||
return;
|
||||
}
|
||||
const res = await fetch(`/api/status`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
surfers: surfers,
|
||||
info: info,
|
||||
start: start,
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
console.log(`SendPriority: ${JSON.stringify(info)}`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- <svelte:window bind:innerWidth={wWidth} bind:innerHeight={wHeight} /> -->
|
||||
|
||||
<div class="body">
|
||||
<div id="score-container">
|
||||
<div class="info-box">
|
||||
|
@ -134,7 +176,7 @@
|
|||
{/if}
|
||||
</div>
|
||||
<div class="Cat">
|
||||
<small><span id="round">{info.cat}</span></small>
|
||||
<small><span id="round">{info.category}</span></small>
|
||||
</div>
|
||||
<div class="Round">
|
||||
<small><span id="round">{info.round}</span></small>
|
||||
|
@ -149,8 +191,8 @@
|
|||
<div class="score-box">
|
||||
<div
|
||||
class="color"
|
||||
style="background-color: {surfer.colore};"
|
||||
id="color-{surfer.colore}">
|
||||
style="background-color: {surfer.color};"
|
||||
id="color-{surfer.color}">
|
||||
</div>
|
||||
<div class="surfer">{surfer.name}</div>
|
||||
{#if surfer.score != 0}
|
||||
|
@ -177,8 +219,9 @@
|
|||
{/if}
|
||||
|
||||
<div class="input-group mb-1">
|
||||
<span class="input-group-text">tempo</span>
|
||||
<span class="input-group-text">time</span>
|
||||
<input
|
||||
disabled={start}
|
||||
type="text"
|
||||
class="form-control time"
|
||||
name="time"
|
||||
|
@ -186,13 +229,17 @@
|
|||
pattern="^[0-9][0-9]$"
|
||||
maxlength="2"
|
||||
size="2"
|
||||
bind:value={mins} />
|
||||
onchange={() => {
|
||||
secs = 0;
|
||||
mins = info.time;
|
||||
}}
|
||||
bind:value={info.time} />
|
||||
<span class="input-group-text">category</span>
|
||||
<select
|
||||
class="form-select"
|
||||
name="category"
|
||||
aria-label="Category"
|
||||
bind:value={info.cat}>
|
||||
bind:value={info.category}>
|
||||
{#each $categories as cat}
|
||||
<option value={cat.title}>{cat.title}</option>
|
||||
{/each}
|
||||
|
@ -237,15 +284,17 @@
|
|||
<ul>
|
||||
{#each surfers as surfer, id}
|
||||
<li>
|
||||
<div class="input-group">
|
||||
<div
|
||||
class="d-grid gap-2 d-md-flex justify-content-md-center mb-2">
|
||||
<!-- <div class="input-group"> -->
|
||||
<!-- <span class="input-group-text">colore</span> -->
|
||||
<select
|
||||
class="form-select"
|
||||
class="form-select w-25"
|
||||
name="color"
|
||||
aria-label="Color"
|
||||
size="1"
|
||||
bind:value={surfer.colore}
|
||||
style="background-color: {surfer.colore};">
|
||||
bind:value={surfer.color}
|
||||
style="background-color: {surfer.color};">
|
||||
{#each $colors as col}
|
||||
<option
|
||||
value={col}
|
||||
|
@ -254,17 +303,17 @@
|
|||
>{col}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<span class="input-group-text">nome</span>
|
||||
<span class="badge bg-secondary">nome</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
name="nome-{id}"
|
||||
bind:value={surfer.name} />
|
||||
|
||||
<span class="input-group-text">score</span>
|
||||
<span class="badge bg-secondary">score</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
class="form-control w-25"
|
||||
name="score-{id}"
|
||||
bind:value={surfer.score} />
|
||||
</div>
|
||||
|
@ -294,18 +343,21 @@
|
|||
class="btn btn-danger w-50"
|
||||
onclick={ResetLocalCache}>Reset</button>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
<!-- <div class="d-grid gap-2 d-md-flex justify-content-md-center mt-2">
|
||||
<button class="justify-content-md-center"
|
||||
>{wWidth} - {wHeight}</button>
|
||||
</div> -->
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.body {
|
||||
background-color: #dfffdf;
|
||||
background-color: lightgreen;
|
||||
color: black;
|
||||
font-family: Arial, sans-serif;
|
||||
min-height: 1024px;
|
||||
min-width: 768px;
|
||||
min-height: 895px;
|
||||
min-width: 1024px;
|
||||
}
|
||||
.info-box {
|
||||
display: grid;
|
||||
|
@ -313,7 +365,8 @@
|
|||
left: 6px;
|
||||
width: 254px;
|
||||
padding-left: 6px;
|
||||
background: rgba(50, 50, 50, 0.7);
|
||||
padding-right: 4px;
|
||||
background: rgba(40, 40, 40, 0.8);
|
||||
color: white;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr 1fr;
|
||||
|
@ -333,7 +386,7 @@
|
|||
padding-right: 6px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
background: rgba(50, 50, 50, 0.7);
|
||||
background: rgba(40, 40, 40, 0.8);
|
||||
color: white;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
@ -349,7 +402,7 @@
|
|||
font-size: 14px;
|
||||
justify-self: start;
|
||||
align-self: center;
|
||||
margin-left: 30px;
|
||||
margin-left: 28px;
|
||||
#font-weight: bold;
|
||||
}
|
||||
.Round {
|
||||
|
@ -357,7 +410,7 @@
|
|||
font-size: 14px;
|
||||
justify-self: start;
|
||||
align-self: center;
|
||||
margin-left: 30px;
|
||||
margin-left: 28px;
|
||||
#font-weight: bold;
|
||||
}
|
||||
.Heat {
|
||||
|
@ -365,7 +418,7 @@
|
|||
font-size: 14px;
|
||||
justify-self: start;
|
||||
align-self: center;
|
||||
margin-left: 30px;
|
||||
margin-left: 28px;
|
||||
#font-weight: bold;
|
||||
}
|
||||
.surfer {
|
||||
|
@ -403,7 +456,7 @@
|
|||
margin-right: 2px;
|
||||
}
|
||||
.form-box {
|
||||
width: 500px;
|
||||
width: 700px;
|
||||
background: rgba(50, 50, 50, 0.7);
|
||||
color: white;
|
||||
margin-left: 550px;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import adapter from '@sveltejs/adapter-auto';
|
||||
//import adapter from '@sveltejs/adapter-auto';
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
|
@ -6,7 +7,16 @@ const config = {
|
|||
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
||||
adapter: adapter()
|
||||
adapter: adapter(
|
||||
{
|
||||
pages: 'backend/static',
|
||||
assets: 'backend/static',
|
||||
fallback: 'index.html',
|
||||
precompress: true,
|
||||
strict: true
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue