From f97c89fa36e7131652f136f0c54709d056a79065 Mon Sep 17 00:00:00 2001 From: Supreme2580 Date: Sat, 7 Dec 2024 23:08:00 +0100 Subject: [PATCH 1/4] wip --- .../src/tabs/worlds/WorldsCreationPanel.js | 200 +++++++++++------- 1 file changed, 124 insertions(+), 76 deletions(-) diff --git a/frontend/src/tabs/worlds/WorldsCreationPanel.js b/frontend/src/tabs/worlds/WorldsCreationPanel.js index e26b0814..bfc22a51 100644 --- a/frontend/src/tabs/worlds/WorldsCreationPanel.js +++ b/frontend/src/tabs/worlds/WorldsCreationPanel.js @@ -26,6 +26,13 @@ const WorldsCreationPanel = (props) => { Yrs: 1000 * 60 * 60 * 24 * 365 }; + const [isCompetitionWorld, setIsCompetitionWorld] = useState(true); + + // Competition constants + const COMPETITION_TIMER = 5; // 5 seconds + const COMPETITION_START = new Date('2023-12-06').getTime(); + const COMPETITION_END = new Date('2024-01-01').getTime(); + const createWorldCall = async ( name, width, @@ -183,23 +190,27 @@ const WorldsCreationPanel = (props) => { return; } - // Check if name exists before submitting const nameExists = await checkWorldNameExists(worldName); - console.log('response: ', nameExists); if (nameExists) { return; } if (!checkInputs()) return; + + // Use competition values if toggle is on + const submitTimer = isCompetitionWorld ? COMPETITION_TIMER : timer; + const submitStart = isCompetitionWorld ? COMPETITION_START : start; + const submitEnd = isCompetitionWorld ? COMPETITION_END : end; + if (!devnetMode) { await createWorldCall( worldName, worldWidth, worldHeight, - timer, + submitTimer, palette, - start, - end + submitStart, + submitEnd ); return; } @@ -274,6 +285,19 @@ const WorldsCreationPanel = (props) => { {nameError &&

{nameError}

} +
+
+ setIsCompetitionWorld(e.target.checked)} + /> + +
+

Size

@@ -345,14 +369,22 @@ const WorldsCreationPanel = (props) => {

Timer

- setTimer(Math.round(e.target.value))} - /> -

Seconds between pixels

+ {isCompetitionWorld ? ( +
+ {COMPETITION_TIMER} seconds between pixels +
+ ) : ( + <> + setTimer(Math.round(e.target.value))} + /> +

Seconds between pixels

+ + )}

Palette

@@ -447,83 +479,99 @@ const WorldsCreationPanel = (props) => {

Start

- setStart(new Date(e.target.value).getTime())} - /> -
setStart(new Date().getTime())} - > - Now -
+ {isCompetitionWorld ? ( +
+ {new Date(COMPETITION_START).toLocaleDateString()} +
+ ) : ( + <> + setStart(new Date(e.target.value).getTime())} + /> +
setStart(new Date().getTime())} + > + Now +
+ + )}
-

End  

-
- setEnd(new Date(e.target.value).getTime())} - /> -
+

End

+ {isCompetitionWorld ? ( +
+ {new Date(COMPETITION_END).toLocaleDateString()} +
+ ) : ( +
+ setEnd(new Date(e.target.value).getTime())} + />
- { - let newEnd = start + timeUnits[timeUnit] * e.target.value; - if (newEnd < start + timeUnits[timeUnit]) { - newEnd = start + timeUnits[timeUnit]; - } - setEnd(newEnd); - }} - style={{ width: '13rem' }} - />
{ - let keys = Object.keys(timeUnits); - let index = keys.indexOf(timeUnit); - index++; - if (index >= keys.length) { - index = 0; - } - setTimeUnit(keys[index]); + style={{ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between' }} > -
{timeUnit}
+ { + let newEnd = start + timeUnits[timeUnit] * e.target.value; + if (newEnd < start + timeUnits[timeUnit]) { + newEnd = start + timeUnits[timeUnit]; + } + setEnd(newEnd); + }} + style={{ width: '13rem' }} + /> +
{ + let keys = Object.keys(timeUnits); + let index = keys.indexOf(timeUnit); + index++; + if (index >= keys.length) { + index = 0; + } + setTimeUnit(keys[index]); + }} + > +
{timeUnit}
+
+
+
+ setEnd( + new Date().getTime() + 1000 * 60 * 60 * 24 * 1000000 + ) // "No Limit" + } + > + No End
-
-
- setEnd(new Date().getTime() + 1000 * 60 * 60 * 24 * 1000000) // "No Limit" - } - > - No End
-
+ )}

{validationMessage} From 98590ba6a90692a3d03ffba581dbd9583cb3b79b Mon Sep 17 00:00:00 2001 From: Supreme2580 Date: Sun, 8 Dec 2024 00:20:35 +0100 Subject: [PATCH 2/4] wip --- .../src/tabs/worlds/WorldsCreationPanel.css | 4 ++- .../src/tabs/worlds/WorldsCreationPanel.js | 36 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/frontend/src/tabs/worlds/WorldsCreationPanel.css b/frontend/src/tabs/worlds/WorldsCreationPanel.css index a5b059c9..bbad5d20 100644 --- a/frontend/src/tabs/worlds/WorldsCreationPanel.css +++ b/frontend/src/tabs/worlds/WorldsCreationPanel.css @@ -1,6 +1,6 @@ .WorldsCreationPanel { position: relative; - width: 100%; + width: 530px; padding: 1rem 0.5rem 0.5rem 0.5rem; margin-bottom: 0.3rem; @@ -18,6 +18,8 @@ box-shadow: 0 0 1rem 0.1rem rgba(0, 0, 0, 0.3); border: 0.2rem solid rgba(0, 0, 0, 0.4); + right: 100px; + pointer-events: fill; } diff --git a/frontend/src/tabs/worlds/WorldsCreationPanel.js b/frontend/src/tabs/worlds/WorldsCreationPanel.js index bfc22a51..dcb3b4bc 100644 --- a/frontend/src/tabs/worlds/WorldsCreationPanel.js +++ b/frontend/src/tabs/worlds/WorldsCreationPanel.js @@ -285,19 +285,6 @@ const WorldsCreationPanel = (props) => {

{nameError &&

{nameError}

}
-
-
- setIsCompetitionWorld(e.target.checked)} - /> - -
-

Size

@@ -368,13 +355,15 @@ const WorldsCreationPanel = (props) => {
-

Timer

{isCompetitionWorld ? ( -
- {COMPETITION_TIMER} seconds between pixels -
+ <> +
+ Wait {COMPETITION_TIMER} seconds between pixels +
+ ) : ( <> +

Timer

{
)} +
+
+ setIsCompetitionWorld(e.target.checked)} + /> + +
+

{validationMessage}

From d6380f737ce9a12917beaef4b932b871408cc583 Mon Sep 17 00:00:00 2001 From: Supreme2580 Date: Sun, 8 Dec 2024 01:00:17 +0100 Subject: [PATCH 3/4] integrated config served with go backend --- backend/routes/competition.go | 52 +++++ configs/competition.config.json | 7 + .../src/tabs/worlds/WorldsCreationPanel.js | 190 +++++++++++------- 3 files changed, 175 insertions(+), 74 deletions(-) create mode 100644 backend/routes/competition.go create mode 100644 configs/competition.config.json diff --git a/backend/routes/competition.go b/backend/routes/competition.go new file mode 100644 index 00000000..5646fd7b --- /dev/null +++ b/backend/routes/competition.go @@ -0,0 +1,52 @@ +package routes + +import ( + "encoding/json" + "net/http" + "os" + "path/filepath" + + routeutils "github.com/keep-starknet-strange/art-peace/backend/routes/utils" +) + +type CompetitionConfig struct { + Round3 struct { + Timer int `json:"timer"` + StartTime string `json:"startTime"` + EndTime string `json:"endTime"` + } `json:"round3"` +} + +func InitCompetitionRoutes() { + http.HandleFunc("/get-competition-config", getCompetitionConfig) +} + +func getCompetitionConfig(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + routeutils.WriteErrorJson(w, http.StatusMethodNotAllowed, "Method not allowed") + return + } + + // Read config file + configPath := filepath.Join("configs", "competition.config.json") + configFile, err := os.ReadFile(configPath) + if err != nil { + routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to read competition config") + return + } + + var config CompetitionConfig + if err := json.Unmarshal(configFile, &config); err != nil { + routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to parse competition config") + return + } + + // Convert to JSON and send response + jsonResponse, err := json.Marshal(config) + if err != nil { + routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to create response") + return + } + + routeutils.WriteDataJson(w, string(jsonResponse)) +} diff --git a/configs/competition.config.json b/configs/competition.config.json new file mode 100644 index 00000000..6640afdb --- /dev/null +++ b/configs/competition.config.json @@ -0,0 +1,7 @@ +{ + "round3": { + "timer": 5, + "startTime": "2023-12-06T00:00:00Z", + "endTime": "2024-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/frontend/src/tabs/worlds/WorldsCreationPanel.js b/frontend/src/tabs/worlds/WorldsCreationPanel.js index dcb3b4bc..b9863b6f 100644 --- a/frontend/src/tabs/worlds/WorldsCreationPanel.js +++ b/frontend/src/tabs/worlds/WorldsCreationPanel.js @@ -28,11 +28,6 @@ const WorldsCreationPanel = (props) => { const [isCompetitionWorld, setIsCompetitionWorld] = useState(true); - // Competition constants - const COMPETITION_TIMER = 5; // 5 seconds - const COMPETITION_START = new Date('2023-12-06').getTime(); - const COMPETITION_END = new Date('2024-01-01').getTime(); - const createWorldCall = async ( name, width, @@ -197,10 +192,9 @@ const WorldsCreationPanel = (props) => { if (!checkInputs()) return; - // Use competition values if toggle is on - const submitTimer = isCompetitionWorld ? COMPETITION_TIMER : timer; - const submitStart = isCompetitionWorld ? COMPETITION_START : start; - const submitEnd = isCompetitionWorld ? COMPETITION_END : end; + const submitTimer = isCompetitionWorld ? getCompetitionTimer() : timer; + const submitStart = isCompetitionWorld ? getCompetitionStart() : start; + const submitEnd = isCompetitionWorld ? getCompetitionEnd() : end; if (!devnetMode) { await createWorldCall( @@ -257,6 +251,44 @@ const WorldsCreationPanel = (props) => { } }, [worldName]); + const [competitionConfig, setCompetitionConfig] = useState(null); + const [isLoadingConfig, setIsLoadingConfig] = useState(true); + + // Fetch competition config when component mounts + useEffect(() => { + const fetchCompetitionConfig = async () => { + try { + const response = await fetchWrapper('get-competition-config'); + if (response.data) { + setCompetitionConfig(response.data.round3); + } + } catch (error) { + console.error('Failed to fetch competition config:', error); + } finally { + setIsLoadingConfig(false); + } + }; + + fetchCompetitionConfig(); + }, []); + + // Use competition values from config when available + const getCompetitionTimer = () => { + return competitionConfig?.timer || 5; // Fallback to default + }; + + const getCompetitionStart = () => { + return competitionConfig?.startTime + ? new Date(competitionConfig.startTime).getTime() + : new Date('2023-12-06').getTime(); // Fallback + }; + + const getCompetitionEnd = () => { + return competitionConfig?.endTime + ? new Date(competitionConfig.endTime).getTime() + : new Date('2024-01-01').getTime(); // Fallback + }; + return (

{

- {isCompetitionWorld ? ( - <> -
- Wait {COMPETITION_TIMER} seconds between pixels -
- - ) : ( + {isCompetitionWorld && ( <>

Timer

{
+ {isCompetitionWorld && ( +

+ {isLoadingConfig + ? 'Loading...' + : `${getCompetitionTimer()} seconds between pixels`} +

+ )}
-

Start

{isCompetitionWorld ? ( -
- {new Date(COMPETITION_START).toLocaleDateString()} -
+

+ Start -{' '} + {isLoadingConfig + ? ' Loading...' + : new Date(getCompetitionStart()).toLocaleDateString()} +

) : ( <> +

Start

{ )}
-

End

{isCompetitionWorld ? (
- {new Date(COMPETITION_END).toLocaleDateString()} + End -{' '} + {isLoadingConfig + ? 'Loading...' + : new Date(getCompetitionEnd()).toLocaleDateString()}
) : ( -
- setEnd(new Date(e.target.value).getTime())} - /> -
+ <> +

End

+
+ setEnd(new Date(e.target.value).getTime())} + />
- { - let newEnd = start + timeUnits[timeUnit] * e.target.value; - if (newEnd < start + timeUnits[timeUnit]) { - newEnd = start + timeUnits[timeUnit]; - } - setEnd(newEnd); - }} - style={{ width: '13rem' }} - />
{ - let keys = Object.keys(timeUnits); - let index = keys.indexOf(timeUnit); - index++; - if (index >= keys.length) { - index = 0; - } - setTimeUnit(keys[index]); + style={{ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between' }} > -
{timeUnit}
+ { + let newEnd = + start + timeUnits[timeUnit] * e.target.value; + if (newEnd < start + timeUnits[timeUnit]) { + newEnd = start + timeUnits[timeUnit]; + } + setEnd(newEnd); + }} + style={{ width: '13rem' }} + /> +
{ + let keys = Object.keys(timeUnits); + let index = keys.indexOf(timeUnit); + index++; + if (index >= keys.length) { + index = 0; + } + setTimeUnit(keys[index]); + }} + > +
{timeUnit}
+
+
+
+ setEnd( + new Date().getTime() + 1000 * 60 * 60 * 24 * 1000000 + ) // "No Limit" + } + > + No End
-
-
- setEnd( - new Date().getTime() + 1000 * 60 * 60 * 24 * 1000000 - ) // "No Limit" - } - > - No End
-
+ )}
From a4a2273a2aa27f8bde94f080b623d2a5025503eb Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Mon, 16 Dec 2024 05:36:06 -0600 Subject: [PATCH 4/4] Change config to match other config patterns and future setup for all round configs --- backend/cmd/backend/backend.go | 8 +- backend/cmd/consumer/consumer.go | 8 +- backend/cmd/video-gen/video.go | 8 +- backend/config/rounds.go | 47 ++++ backend/core/backend.go | 4 +- backend/routes/competition.go | 52 ----- backend/routes/rounds.go | 31 +++ backend/routes/routes.go | 1 + configs/competition.config.json | 7 - configs/rounds.config.json | 9 + .../src/tabs/worlds/WorldsCreationPanel.css | 4 +- .../src/tabs/worlds/WorldsCreationPanel.js | 204 ++++++++++-------- 12 files changed, 224 insertions(+), 159 deletions(-) create mode 100644 backend/config/rounds.go delete mode 100644 backend/routes/competition.go create mode 100644 backend/routes/rounds.go delete mode 100644 configs/competition.config.json create mode 100644 configs/rounds.config.json diff --git a/backend/cmd/backend/backend.go b/backend/cmd/backend/backend.go index 1821d2ee..91815afe 100644 --- a/backend/cmd/backend/backend.go +++ b/backend/cmd/backend/backend.go @@ -19,6 +19,7 @@ func isFlagSet(name string) bool { } func main() { + roundsConfigFilename := flag.String("rounds-config", config.DefaultRoundsConfigPath, "Rounds config file") canvasConfigFilename := flag.String("canvas-config", config.DefaultCanvasConfigPath, "Canvas config file") databaseConfigFilename := flag.String("database-config", config.DefaultDatabaseConfigPath, "Database config file") backendConfigFilename := flag.String("backend-config", config.DefaultBackendConfigPath, "Backend config file") @@ -27,6 +28,11 @@ func main() { flag.Parse() + roundsConfig, err := config.LoadRoundsConfig(*roundsConfigFilename) + if err != nil { + panic(err) + } + canvasConfig, err := config.LoadCanvasConfig(*canvasConfigFilename) if err != nil { panic(err) @@ -49,7 +55,7 @@ func main() { databases := core.NewDatabases(databaseConfig) defer databases.Close() - core.ArtPeaceBackend = core.NewBackend(databases, canvasConfig, backendConfig, *admin) + core.ArtPeaceBackend = core.NewBackend(databases, roundsConfig, canvasConfig, backendConfig, *admin) routes.InitRoutes() diff --git a/backend/cmd/consumer/consumer.go b/backend/cmd/consumer/consumer.go index ae8dffe6..5f87e2eb 100644 --- a/backend/cmd/consumer/consumer.go +++ b/backend/cmd/consumer/consumer.go @@ -20,6 +20,7 @@ func isFlagSet(name string) bool { } func main() { + roundsConfigFilename := flag.String("rounds-config", config.DefaultRoundsConfigPath, "Rounds config file") canvasConfigFilename := flag.String("canvas-config", config.DefaultCanvasConfigPath, "Canvas config file") databaseConfigFilename := flag.String("database-config", config.DefaultDatabaseConfigPath, "Database config file") backendConfigFilename := flag.String("backend-config", config.DefaultBackendConfigPath, "Backend config file") @@ -27,6 +28,11 @@ func main() { flag.Parse() + roundsConfig, err := config.LoadRoundsConfig(*roundsConfigFilename) + if err != nil { + panic(err) + } + canvasConfig, err := config.LoadCanvasConfig(*canvasConfigFilename) if err != nil { panic(err) @@ -49,7 +55,7 @@ func main() { databases := core.NewDatabases(databaseConfig) defer databases.Close() - core.ArtPeaceBackend = core.NewBackend(databases, canvasConfig, backendConfig, false) + core.ArtPeaceBackend = core.NewBackend(databases, roundsConfig, canvasConfig, backendConfig, false) routes.InitBaseRoutes() indexer.InitIndexerRoutes() diff --git a/backend/cmd/video-gen/video.go b/backend/cmd/video-gen/video.go index 6620761d..aec5698e 100644 --- a/backend/cmd/video-gen/video.go +++ b/backend/cmd/video-gen/video.go @@ -10,12 +10,18 @@ import ( ) func main() { + roundsConfigFilename := flag.String("rounds-config", config.DefaultRoundsConfigPath, "Rounds config file") canvasConfigFilename := flag.String("canvas-config", config.DefaultCanvasConfigPath, "Canvas config file") databaseConfigFilename := flag.String("database-config", config.DefaultDatabaseConfigPath, "Database config file") backendConfigFilename := flag.String("backend-config", config.DefaultBackendConfigPath, "Backend config file") flag.Parse() + roundsConfig, err := config.LoadRoundsConfig(*roundsConfigFilename) + if err != nil { + panic(err) + } + canvasConfig, err := config.LoadCanvasConfig(*canvasConfigFilename) if err != nil { panic(err) @@ -34,7 +40,7 @@ func main() { databases := core.NewDatabases(databaseConfig) defer databases.Close() - core.ArtPeaceBackend = core.NewBackend(databases, canvasConfig, backendConfig, true) + core.ArtPeaceBackend = core.NewBackend(databases, roundsConfig, canvasConfig, backendConfig, true) routes.InitBaseRoutes() routes.InitCanvasRoutes() diff --git a/backend/config/rounds.go b/backend/config/rounds.go new file mode 100644 index 00000000..b5198d1c --- /dev/null +++ b/backend/config/rounds.go @@ -0,0 +1,47 @@ +package config + +import ( + "encoding/json" + "os" +) + +type Round3 struct { + Width uint `json:"width"` + Height uint `json:"height"` + Timer uint `json:"timer"` + StartTime string `json:"startTime"` + EndTime string `json:"endTime"` +} + +type RoundsConfig struct { + Round3 Round3 `json:"round3"` +} + +var DefaultRoundsConfig = &RoundsConfig{ + Round3: Round3{ + Width: 256, + Height: 192, + Timer: 5, + StartTime: "2024-12-01T00:00:00Z", + EndTime: "2025-01-01T00:00:00Z", + }, +} + +var DefaultRoundsConfigPath = "../configs/rounds.config.json" + +func LoadRoundsConfig(roundsConfigPath string) (*RoundsConfig, error) { + roundsConfig := &RoundsConfig{} + + roundsConfigFile, err := os.Open(roundsConfigPath) + if err != nil { + return nil, err + } + defer roundsConfigFile.Close() + + jsonParser := json.NewDecoder(roundsConfigFile) + if err = jsonParser.Decode(roundsConfig); err != nil { + return nil, err + } + + return roundsConfig, nil +} diff --git a/backend/core/backend.go b/backend/core/backend.go index 62c460db..b580ab41 100644 --- a/backend/core/backend.go +++ b/backend/core/backend.go @@ -15,6 +15,7 @@ type Backend struct { WSConnections []*websocket.Conn WSConnectionsLock sync.Mutex + RoundsConfig *config.RoundsConfig CanvasConfig *config.CanvasConfig BackendConfig *config.BackendConfig @@ -23,9 +24,10 @@ type Backend struct { var ArtPeaceBackend *Backend -func NewBackend(databases *Databases, canvasConfig *config.CanvasConfig, backendConfig *config.BackendConfig, adminMode bool) *Backend { +func NewBackend(databases *Databases, roundsConfig *config.RoundsConfig, canvasConfig *config.CanvasConfig, backendConfig *config.BackendConfig, adminMode bool) *Backend { return &Backend{ Databases: databases, + RoundsConfig: roundsConfig, CanvasConfig: canvasConfig, BackendConfig: backendConfig, AdminMode: adminMode, diff --git a/backend/routes/competition.go b/backend/routes/competition.go deleted file mode 100644 index 5646fd7b..00000000 --- a/backend/routes/competition.go +++ /dev/null @@ -1,52 +0,0 @@ -package routes - -import ( - "encoding/json" - "net/http" - "os" - "path/filepath" - - routeutils "github.com/keep-starknet-strange/art-peace/backend/routes/utils" -) - -type CompetitionConfig struct { - Round3 struct { - Timer int `json:"timer"` - StartTime string `json:"startTime"` - EndTime string `json:"endTime"` - } `json:"round3"` -} - -func InitCompetitionRoutes() { - http.HandleFunc("/get-competition-config", getCompetitionConfig) -} - -func getCompetitionConfig(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodGet { - routeutils.WriteErrorJson(w, http.StatusMethodNotAllowed, "Method not allowed") - return - } - - // Read config file - configPath := filepath.Join("configs", "competition.config.json") - configFile, err := os.ReadFile(configPath) - if err != nil { - routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to read competition config") - return - } - - var config CompetitionConfig - if err := json.Unmarshal(configFile, &config); err != nil { - routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to parse competition config") - return - } - - // Convert to JSON and send response - jsonResponse, err := json.Marshal(config) - if err != nil { - routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to create response") - return - } - - routeutils.WriteDataJson(w, string(jsonResponse)) -} diff --git a/backend/routes/rounds.go b/backend/routes/rounds.go new file mode 100644 index 00000000..53a907b1 --- /dev/null +++ b/backend/routes/rounds.go @@ -0,0 +1,31 @@ +package routes + +import ( + "encoding/json" + "net/http" + + "github.com/keep-starknet-strange/art-peace/backend/core" + routeutils "github.com/keep-starknet-strange/art-peace/backend/routes/utils" +) + +func InitRoundsRoutes() { + http.HandleFunc("/get-rounds-config", getRoundsConfig) +} + +func getRoundsConfig(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + routeutils.WriteErrorJson(w, http.StatusMethodNotAllowed, "Method not allowed") + return + } + + config := core.ArtPeaceBackend.RoundsConfig + + // Marshal the config to JSON + configJson, err := json.Marshal(config) + if err != nil { + routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Error marshalling config to JSON") + return + } + + routeutils.WriteDataJson(w, string(configJson)) +} diff --git a/backend/routes/routes.go b/backend/routes/routes.go index 18aaefb7..ef6c3f6f 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go @@ -28,4 +28,5 @@ func InitRoutes() { InitWorldsRoutes() InitStencilsRoutes() InitStencilsStaticRoutes() + InitRoundsRoutes() } diff --git a/configs/competition.config.json b/configs/competition.config.json deleted file mode 100644 index 6640afdb..00000000 --- a/configs/competition.config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "round3": { - "timer": 5, - "startTime": "2023-12-06T00:00:00Z", - "endTime": "2024-01-01T00:00:00Z" - } -} \ No newline at end of file diff --git a/configs/rounds.config.json b/configs/rounds.config.json new file mode 100644 index 00000000..94f382ba --- /dev/null +++ b/configs/rounds.config.json @@ -0,0 +1,9 @@ +{ + "round3": { + "width": 256, + "height": 192, + "timer": 5, + "startTime": "2024-12-06T00:00:00Z", + "endTime": "2025-01-01T00:00:00Z" + } +} diff --git a/frontend/src/tabs/worlds/WorldsCreationPanel.css b/frontend/src/tabs/worlds/WorldsCreationPanel.css index bbad5d20..a5b059c9 100644 --- a/frontend/src/tabs/worlds/WorldsCreationPanel.css +++ b/frontend/src/tabs/worlds/WorldsCreationPanel.css @@ -1,6 +1,6 @@ .WorldsCreationPanel { position: relative; - width: 530px; + width: 100%; padding: 1rem 0.5rem 0.5rem 0.5rem; margin-bottom: 0.3rem; @@ -18,8 +18,6 @@ box-shadow: 0 0 1rem 0.1rem rgba(0, 0, 0, 0.3); border: 0.2rem solid rgba(0, 0, 0, 0.4); - right: 100px; - pointer-events: fill; } diff --git a/frontend/src/tabs/worlds/WorldsCreationPanel.js b/frontend/src/tabs/worlds/WorldsCreationPanel.js index 04f1817b..eb0aace4 100644 --- a/frontend/src/tabs/worlds/WorldsCreationPanel.js +++ b/frontend/src/tabs/worlds/WorldsCreationPanel.js @@ -194,6 +194,10 @@ const WorldsCreationPanel = (props) => { if (!checkInputs()) return; + const submitWidth = isCompetitionWorld ? getCompetitionWidth() : worldWidth; + const submitHeight = isCompetitionWorld + ? getCompetitionHeight() + : worldHeight; const submitTimer = isCompetitionWorld ? getCompetitionTimer() : timer; const submitStart = isCompetitionWorld ? getCompetitionStart() : start; const submitEnd = isCompetitionWorld ? getCompetitionEnd() : end; @@ -202,8 +206,8 @@ const WorldsCreationPanel = (props) => { await createWorldCall( worldName, worldSlug, - worldWidth, - worldHeight, + submitWidth, + submitHeight, submitTimer, palette, submitStart, @@ -220,12 +224,12 @@ const WorldsCreationPanel = (props) => { host: host, name: toHex(worldName), unique_name: toHex(worldSlug), - width: worldWidth.toString(), - height: worldHeight.toString(), - time_between_pixels: timer.toString(), + width: submitWidth.toString(), + height: submitHeight.toString(), + time_between_pixels: submitTimer.toString(), color_palette: palette.toString(), - start_time: Math.floor(start / 1000).toString(), - end_time: Math.floor(end / 1000).toString() + start_time: Math.floor(submitStart / 1000).toString(), + end_time: Math.floor(submitEnd / 1000).toString() }) }); if (response.result) { @@ -256,41 +260,46 @@ const WorldsCreationPanel = (props) => { }, [worldName]); const [competitionConfig, setCompetitionConfig] = useState(null); - const [isLoadingConfig, setIsLoadingConfig] = useState(true); // Fetch competition config when component mounts useEffect(() => { - const fetchCompetitionConfig = async () => { + const fetchRoundsConfig = async () => { try { - const response = await fetchWrapper('get-competition-config'); + const response = await fetchWrapper('get-rounds-config'); if (response.data) { setCompetitionConfig(response.data.round3); } } catch (error) { console.error('Failed to fetch competition config:', error); - } finally { - setIsLoadingConfig(false); } }; - fetchCompetitionConfig(); + fetchRoundsConfig(); }, []); + const getCompetitionWidth = () => { + return competitionConfig?.width || 128; // Fallback to default + }; + + const getCompetitionHeight = () => { + return competitionConfig?.height || 128; // Fallback to default + }; + // Use competition values from config when available const getCompetitionTimer = () => { - return competitionConfig?.timer || 5; // Fallback to default + return competitionConfig?.timer || 7; // Fallback to default }; const getCompetitionStart = () => { return competitionConfig?.startTime ? new Date(competitionConfig.startTime).getTime() - : new Date('2023-12-06').getTime(); // Fallback + : new Date('2024-12-07T00:00:00Z').getTime(); }; const getCompetitionEnd = () => { return competitionConfig?.endTime ? new Date(competitionConfig.endTime).getTime() - : new Date('2024-01-01').getTime(); // Fallback + : new Date('2025-01-02T00:00:00Z').getTime(); }; return ( @@ -321,77 +330,93 @@ const WorldsCreationPanel = (props) => {
{nameError &&

{nameError}

}
-
-

Size

-
-
+ {isCompetitionWorld ? ( +
+

Size

+

+ {getCompetitionWidth()} x {getCompetitionHeight()} +

+
+ ) : ( +
+

Size

+
- { - if (e.target.value < minWorldSize) { - setWorldWidth(minWorldSize); - } else if (e.target.value > maxWorldSize) { - setWorldWidth(maxWorldSize); - } else { - setWorldWidth(e.target.value); - } +
-

- Width -

-
-

 x 

-
- { - if (e.target.value < minWorldSize) { - setWorldHeight(minWorldSize); - } else if (e.target.value > maxWorldSize) { - setWorldHeight(maxWorldSize); - } else { - setWorldHeight(e.target.value); - } + > + { + if (e.target.value < minWorldSize) { + setWorldWidth(minWorldSize); + } else if (e.target.value > maxWorldSize) { + setWorldWidth(maxWorldSize); + } else { + setWorldWidth(e.target.value); + } + }} + /> +

+ Width +

+
+

 x 

+
-

- Height -

+ > + { + if (e.target.value < minWorldSize) { + setWorldHeight(minWorldSize); + } else if (e.target.value > maxWorldSize) { + setWorldHeight(maxWorldSize); + } else { + setWorldHeight(e.target.value); + } + }} + /> +

+ Height +

+
-
+ )}
- {isCompetitionWorld && ( + {isCompetitionWorld ? ( + <> +

Timer

+

+ {getCompetitionTimer()} seconds between pixels +

+ + ) : ( <>

Timer

{
- {isCompetitionWorld && ( -

- {isLoadingConfig - ? 'Loading...' - : `${getCompetitionTimer()} seconds between pixels`} -

- )}
{isCompetitionWorld ? ( -

- Start -{' '} - {isLoadingConfig - ? ' Loading...' - : new Date(getCompetitionStart()).toLocaleDateString()} -

+ <> +

Start

+

+ {new Date(getCompetitionStart()).toLocaleDateString()} +

+ ) : ( <>

Start

@@ -531,12 +549,12 @@ const WorldsCreationPanel = (props) => {
{isCompetitionWorld ? ( -
- End -{' '} - {isLoadingConfig - ? 'Loading...' - : new Date(getCompetitionEnd()).toLocaleDateString()} -
+ <> +

End

+

+ {new Date(getCompetitionEnd()).toLocaleDateString()} +

+ ) : ( <>

End