From 796f31aadfeef86bdbc77fb65ab552e07fd8a424 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 11 Apr 2025 12:49:34 -0700 Subject: [PATCH 1/8] openapi: add fields to submission create --- openapi.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openapi.yaml b/openapi.yaml index abb3424..69ea9bb 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1641,12 +1641,25 @@ components: SubmissionTriggerCreate: required: - AssetID + - DisplayName + - Creator + - GameID type: object properties: AssetID: type: integer format: int64 minimum: 0 + DisplayName: + type: string + maxLength: 128 + Creator: + type: string + maxLength: 128 + GameID: + type: integer + format: int32 + minimum: 0 ReleaseInfo: required: - SubmissionID -- 2.49.1 From d24b342738a0f72bec37aa2c80dfb9cbdc2d2c20 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 11 Apr 2025 13:11:46 -0700 Subject: [PATCH 2/8] openapi: generate --- pkg/api/oas_json_gen.go | 55 +++++++++++++++++++++++++++++++-- pkg/api/oas_schemas_gen.go | 35 ++++++++++++++++++++- pkg/api/oas_validators_gen.go | 58 +++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 3 deletions(-) diff --git a/pkg/api/oas_json_gen.go b/pkg/api/oas_json_gen.go index 11defac..5f84a66 100644 --- a/pkg/api/oas_json_gen.go +++ b/pkg/api/oas_json_gen.go @@ -3128,10 +3128,25 @@ func (s *SubmissionTriggerCreate) encodeFields(e *jx.Encoder) { e.FieldStart("AssetID") e.Int64(s.AssetID) } + { + e.FieldStart("DisplayName") + e.Str(s.DisplayName) + } + { + e.FieldStart("Creator") + e.Str(s.Creator) + } + { + e.FieldStart("GameID") + e.Int32(s.GameID) + } } -var jsonFieldsNameOfSubmissionTriggerCreate = [1]string{ +var jsonFieldsNameOfSubmissionTriggerCreate = [4]string{ 0: "AssetID", + 1: "DisplayName", + 2: "Creator", + 3: "GameID", } // Decode decodes SubmissionTriggerCreate from json. @@ -3155,6 +3170,42 @@ func (s *SubmissionTriggerCreate) Decode(d *jx.Decoder) error { }(); err != nil { return errors.Wrap(err, "decode field \"AssetID\"") } + case "DisplayName": + requiredBitSet[0] |= 1 << 1 + if err := func() error { + v, err := d.Str() + s.DisplayName = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"DisplayName\"") + } + case "Creator": + requiredBitSet[0] |= 1 << 2 + if err := func() error { + v, err := d.Str() + s.Creator = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Creator\"") + } + case "GameID": + requiredBitSet[0] |= 1 << 3 + if err := func() error { + v, err := d.Int32() + s.GameID = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"GameID\"") + } default: return d.Skip() } @@ -3165,7 +3216,7 @@ func (s *SubmissionTriggerCreate) Decode(d *jx.Decoder) error { // Validate required fields. var failures []validate.FieldError for i, mask := range [1]uint8{ - 0b00000001, + 0b00001111, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. diff --git a/pkg/api/oas_schemas_gen.go b/pkg/api/oas_schemas_gen.go index 54d2557..31dc5ea 100644 --- a/pkg/api/oas_schemas_gen.go +++ b/pkg/api/oas_schemas_gen.go @@ -1318,7 +1318,10 @@ func (s *Submission) SetStatusID(val int32) { // Ref: #/components/schemas/SubmissionTriggerCreate type SubmissionTriggerCreate struct { - AssetID int64 `json:"AssetID"` + AssetID int64 `json:"AssetID"` + DisplayName string `json:"DisplayName"` + Creator string `json:"Creator"` + GameID int32 `json:"GameID"` } // GetAssetID returns the value of AssetID. @@ -1326,11 +1329,41 @@ func (s *SubmissionTriggerCreate) GetAssetID() int64 { return s.AssetID } +// GetDisplayName returns the value of DisplayName. +func (s *SubmissionTriggerCreate) GetDisplayName() string { + return s.DisplayName +} + +// GetCreator returns the value of Creator. +func (s *SubmissionTriggerCreate) GetCreator() string { + return s.Creator +} + +// GetGameID returns the value of GameID. +func (s *SubmissionTriggerCreate) GetGameID() int32 { + return s.GameID +} + // SetAssetID sets the value of AssetID. func (s *SubmissionTriggerCreate) SetAssetID(val int64) { s.AssetID = val } +// SetDisplayName sets the value of DisplayName. +func (s *SubmissionTriggerCreate) SetDisplayName(val string) { + s.DisplayName = val +} + +// SetCreator sets the value of Creator. +func (s *SubmissionTriggerCreate) SetCreator(val string) { + s.Creator = val +} + +// SetGameID sets the value of GameID. +func (s *SubmissionTriggerCreate) SetGameID(val int32) { + s.GameID = val +} + // Ref: #/components/schemas/Submissions type Submissions struct { Total int64 `json:"Total"` diff --git a/pkg/api/oas_validators_gen.go b/pkg/api/oas_validators_gen.go index 456bf4d..4f60361 100644 --- a/pkg/api/oas_validators_gen.go +++ b/pkg/api/oas_validators_gen.go @@ -1802,6 +1802,64 @@ func (s *SubmissionTriggerCreate) Validate() error { Error: err, }) } + if err := func() error { + if err := (validate.String{ + MinLength: 0, + MinLengthSet: false, + MaxLength: 128, + MaxLengthSet: true, + Email: false, + Hostname: false, + Regex: nil, + }).Validate(string(s.DisplayName)); err != nil { + return errors.Wrap(err, "string") + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "DisplayName", + Error: err, + }) + } + if err := func() error { + if err := (validate.String{ + MinLength: 0, + MinLengthSet: false, + MaxLength: 128, + MaxLengthSet: true, + Email: false, + Hostname: false, + Regex: nil, + }).Validate(string(s.Creator)); err != nil { + return errors.Wrap(err, "string") + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "Creator", + Error: err, + }) + } + if err := func() error { + if err := (validate.Int{ + MinSet: true, + Min: 0, + MaxSet: false, + Max: 0, + MinExclusive: false, + MaxExclusive: false, + MultipleOfSet: false, + MultipleOf: 0, + }).Validate(int64(s.GameID)); err != nil { + return errors.Wrap(err, "int") + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "GameID", + Error: err, + }) + } if len(failures) > 0 { return &validate.Error{Fields: failures} } -- 2.49.1 From 8372665fd305b7c55c84fa0ce74ac8d556c05768 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 11 Apr 2025 13:07:55 -0700 Subject: [PATCH 3/8] submissions: fields plumbing --- pkg/model/nats.go | 3 +++ pkg/service/submissions.go | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/model/nats.go b/pkg/model/nats.go index 91c0453..0d422af 100644 --- a/pkg/model/nats.go +++ b/pkg/model/nats.go @@ -9,6 +9,9 @@ type CreateSubmissionRequest struct { // operation_id is passed back in the response message OperationID int32 ModelID uint64 + DisplayName string + Creator string + GameID uint32 } type CreateMapfixRequest struct { diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go index 5af693f..c1ce44c 100644 --- a/pkg/service/submissions.go +++ b/pkg/service/submissions.go @@ -101,8 +101,11 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio } create_request := model.CreateSubmissionRequest{ - OperationID: operation.ID, - ModelID: ModelID, + OperationID: operation.ID, + ModelID: ModelID, + DisplayName: request.DisplayName, + Creator: request.Creator, + GameID: uint32(request.GameID), } j, err := json.Marshal(create_request) -- 2.49.1 From 8433030562c555315fb1e4d18dc879db06b750ed Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 11 Apr 2025 13:11:11 -0700 Subject: [PATCH 4/8] web: add submission fields --- web/src/app/submit/_game.tsx | 65 ++++++++++++++++++++++++++++++++++++ web/src/app/submit/page.tsx | 14 +++++++- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 web/src/app/submit/_game.tsx diff --git a/web/src/app/submit/_game.tsx b/web/src/app/submit/_game.tsx new file mode 100644 index 0000000..e754601 --- /dev/null +++ b/web/src/app/submit/_game.tsx @@ -0,0 +1,65 @@ +import { FormControl, Select, InputLabel, MenuItem } from "@mui/material"; +import { styled } from '@mui/material/styles'; +import InputBase from '@mui/material/InputBase'; +import React from "react"; +import { SelectChangeEvent } from "@mui/material"; + +// TODO: Properly style everything instead of pasting 🤚 + +type GameSelectionProps = { + game: number; + setGame: React.Dispatch>; +}; + +const BootstrapInput = styled(InputBase)(({ theme }) => ({ + 'label + &': { + marginTop: theme.spacing(3), + }, + '& .MuiInputBase-input': { + backgroundColor: '#0000', + color: '#FFF', + border: '1px solid rgba(175, 175, 175, 0.66)', + fontSize: 16, + padding: '10px 26px 10px 12px', + transition: theme.transitions.create(['border-color', 'box-shadow']), + fontFamily: [ + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + ].join(','), + '&:focus': { + borderRadius: 4, + borderColor: '#80bdff', + boxShadow: '0 0 0 0.2rem rgba(0,123,255,.25)', + }, + }, + })); + +export default function GameSelection({ game, setGame }: GameSelectionProps) { + const handleChange = (event: SelectChangeEvent) => { + setGame(Number(event.target.value)); // TODO: Change later!! there's 100% a proper way of doing this + }; + + return ( + + Game + + + ); +} \ No newline at end of file diff --git a/web/src/app/submit/page.tsx b/web/src/app/submit/page.tsx index a0b09ee..b0a71e9 100644 --- a/web/src/app/submit/page.tsx +++ b/web/src/app/submit/page.tsx @@ -2,19 +2,25 @@ import { Button, TextField } from "@mui/material" +import GameSelection from "./_game"; import SendIcon from '@mui/icons-material/Send'; import Webpage from "@/app/_components/webpage" +import React, { useState } from "react"; import "./(styles)/page.scss" interface SubmissionPayload { AssetID: number; + DisplayName: string; + Creator: string; + GameID: number; } interface IdResponse { OperationID: number; } export default function SubmissionInfoPage() { + const [game, setGame] = useState(1); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); @@ -23,6 +29,9 @@ export default function SubmissionInfoPage() { const formData = new FormData(form); const payload: SubmissionPayload = { + DisplayName: (formData.get("display-name") as string) ?? "unknown", // TEMPORARY! TODO: Change + Creator: (formData.get("creator") as string) ?? "unknown", // TEMPORARY! TODO: Change + GameID: game, AssetID: Number((formData.get("asset-id") as string) ?? "0"), }; @@ -64,7 +73,10 @@ export default function SubmissionInfoPage() {
- + + + +