fix css + verify and format

pull/77/head
Vivien DUFOUR 1 year ago
parent c68344dab0
commit d858cc3113

@ -1,7 +1,7 @@
import "../../style/ball.css"
import BallSvg from "../../assets/icon/ball.svg?react"
import {Ball} from "../../tactic/CourtObjects";
import { Ball } from "../../tactic/CourtObjects"
export interface CourtBallProps {
onMoved: (rect: DOMRect) => void
@ -10,8 +10,5 @@ export interface CourtBallProps {
}
export function BallPiece() {
return (
<BallSvg className={"ball"}/>
)
return <BallSvg className={"ball"} />
}

@ -3,8 +3,8 @@ import {RefObject} from "react"
import CourtPlayer from "./CourtPlayer"
import { Player } from "../../tactic/Player"
import {CourtObject} from "../../tactic/CourtObjects";
import {CourtBall} from "./CourtBall";
import { CourtObject } from "../../tactic/CourtObjects"
import { CourtBall } from "./CourtBall"
export interface BasketCourtProps {
players: Player[]
@ -15,7 +15,7 @@ export interface BasketCourtProps {
onBallRemove: () => void
onBallMoved: (ball: DOMRect) => void,
onBallMoved: (ball: DOMRect) => void
courtImage: string
courtRef: RefObject<HTMLDivElement>
@ -31,7 +31,6 @@ export function BasketCourt({
courtImage,
courtRef,
}: BasketCourtProps) {
return (
<div
id="court-container"
@ -51,19 +50,19 @@ export function BasketCourt({
)
})}
{objects.map(object => {
{objects.map((object) => {
if (object.type == "ball") {
return <CourtBall
return (
<CourtBall
onMoved={onBallMoved}
ball={object}
onRemove={onBallRemove}
key="ball"
/>
)
}
throw new Error("unknown court object", object.type)
})}
</div>
)
}

@ -1,7 +1,6 @@
import React, {useRef} from "react";
import Draggable from "react-draggable";
import {BallPiece, CourtBallProps} from "./BallPiece";
import React, { useRef } from "react"
import Draggable from "react-draggable"
import { BallPiece, CourtBallProps } from "./BallPiece"
export function CourtBall({ onMoved, ball, onRemove }: CourtBallProps) {
const pieceRef = useRef<HTMLDivElement>(null)
@ -12,9 +11,9 @@ export function CourtBall({onMoved, ball, onRemove}: CourtBallProps) {
return (
<Draggable
onStop={() => onMoved(pieceRef.current!.getBoundingClientRect())}
nodeRef={pieceRef}
>
<div className={"ball-div"}
nodeRef={pieceRef}>
<div
className={"ball-div"}
ref={pieceRef}
tabIndex={0}
onKeyUp={(e) => {
@ -24,8 +23,7 @@ export function CourtBall({onMoved, ball, onRemove}: CourtBallProps) {
position: "absolute",
left: `${x * 100}%`,
top: `${y * 100}%`,
}}
>
}}>
<BallPiece />
</div>
</Draggable>

@ -68,13 +68,20 @@ export default function CourtPlayer({
if (e.key == "Delete") onRemove()
}}>
<div className="player-selection-tab">
{hasBall && (<Draggable nodeRef={ballPiece}
onStop={() => onBallDrop(ballPiece.current!.getBoundingClientRect())}
{hasBall && (
<Draggable
nodeRef={ballPiece}
onStop={() =>
onBallDrop(
ballPiece.current!.getBoundingClientRect(),
)
}
position={{ x: 0, y: 0 }}>
<div ref={ballPiece}>
<BallPiece />
</div>
</Draggable>)}
</Draggable>
)}
</div>
<PlayerPiece
team={player.team}

@ -8,9 +8,7 @@
width: 20px;
height: 20px;
cursor: pointer;
tabIndex: 0;
}
.ball-div:focus-within {
}

@ -32,6 +32,8 @@
#racks {
display: flex;
justify-content: space-between;
align-items: center;
height: 25px;
}
.title-input {
@ -46,6 +48,10 @@
#allies-rack {
width: 125px;
min-width: 125px;
display: flex;
flex-direction: row;
align-items: flex-end;
justify-content: flex-start;
}
#opponent-rack {
@ -111,5 +117,3 @@
.save-state-guest {
color: gray;
}

@ -1,13 +1,10 @@
export type CourtObject = { type: "ball" } & Ball
export interface Ball {
/**
* The ball is a "ball" court object
*/
readonly type: "ball",
readonly type: "ball"
/**
* Percentage of the player's position to the bottom (0 means top, 1 means bottom, 0.5 means middle)

@ -1,5 +1,5 @@
import { Player } from "./Player"
import {CourtObject} from "./CourtObjects";
import { CourtObject } from "./CourtObjects"
export interface Tactic {
id: number

@ -1,4 +1,11 @@
import {CSSProperties, Dispatch, SetStateAction, useCallback, useRef, useState,} from "react"
import {
CSSProperties,
Dispatch,
SetStateAction,
useCallback,
useRef,
useState,
} from "react"
import "../style/editor.css"
import TitleInput from "../components/TitleInput"
import { BasketCourt } from "../components/editor/BasketCourt"
@ -7,23 +14,23 @@ import plainCourt from "../assets/court/full_court.svg"
import halfCourt from "../assets/court/half_court.svg"
import { BallPiece } from "../components/editor/BallPiece"
import { Rack } from "../components/Rack"
import { PlayerPiece } from "../components/editor/PlayerPiece"
import {BallPiece, CourtBall} from "../components/editor/BallPiece";
import { Player } from "../tactic/Player"
import { Tactic, TacticContent } from "../tactic/Tactic"
import { fetchAPI } from "../Fetcher"
import { Team } from "../tactic/Team"
import { calculateRatio } from "../Utils"
import SavingState, {
SaveState,
SaveStates,
} from "../components/editor/SavingState"
import {CourtObject} from "../tactic/CourtObjects";
import {Simulate} from "react-dom/test-utils";
const ERROR_STYLE: CSSProperties = {
@ -57,12 +64,14 @@ interface RackedPlayer {
type RackedCourtObject = { key: "ball" }
export default function Editor({
id,
name,
courtType,
content,
}: EditorProps) {
const isInGuestMode = id == -1
const storage_content = localStorage.getItem(GUEST_MODE_CONTENT_STORAGE_KEY)
@ -101,7 +110,8 @@ export default function Editor({
(r) => r.ok,
)
}}
courtType={courtType}/>
courtType={courtType}
/>
)
}
@ -111,7 +121,6 @@ function EditorView({
onNameChange,
courtType,
}: EditorViewProps) {
const isInGuestMode = id == -1
const [titleStyle, setTitleStyle] = useState<CSSProperties>({})
@ -128,12 +137,14 @@ function EditorView({
getRackPlayers(Team.Opponents, content.players),
)
const [objects, setObjects] = useState<RackedCourtObject[]>(isBallOnCourt(content) ? [] : [{key: "ball"}])
const [objects, setObjects] = useState<RackedCourtObject[]>(
isBallOnCourt(content) ? [] : [{ key: "ball" }],
)
const courtDivContentRef = useRef<HTMLDivElement>(null)
const canDetach = (bounds: DOMRect) => {
const isBoundsOnCourt = (bounds: DOMRect) => {
const courtBounds = courtDivContentRef.current!.getBoundingClientRect()
// check if refBounds overlaps courtBounds
@ -145,8 +156,6 @@ function EditorView({
)
}
const onPieceDetach = (ref: HTMLDivElement, element: RackedPlayer) => {
const refBounds = ref.getBoundingClientRect()
const courtBounds = courtDivContentRef.current!.getBoundingClientRect()
@ -171,7 +180,10 @@ function EditorView({
})
}
const onObjectDetach = (ref: HTMLDivElement, rackedObject: RackedCourtObject) => {
const onObjectDetach = (
ref: HTMLDivElement,
rackedObject: RackedCourtObject,
) => {
const refBounds = ref.getBoundingClientRect()
const courtBounds = courtDivContentRef.current!.getBoundingClientRect()
@ -181,23 +193,27 @@ function EditorView({
switch (rackedObject.key) {
case "ball":
const ballObj = content.objects.findIndex(o => o.type == "ball")
const playerCollidedIdx = getPlayerCollided(refBounds, content.players)
const ballObj = content.objects.findIndex(
(o) => o.type == "ball",
)
const playerCollidedIdx = getPlayerCollided(
refBounds,
content.players,
)
if (playerCollidedIdx != -1) {
onBallDropOnPlayer(playerCollidedIdx)
setContent((content) => {
return {
...content,
objects : content.objects.toSpliced(ballObj, 1)
objects: content.objects.toSpliced(ballObj, 1),
}
})
return
}
else {
} else {
courtObject = {
type: "ball",
rightRatio: x,
bottomRatio: y
bottomRatio: y,
}
}
break
@ -207,20 +223,22 @@ function EditorView({
}
setContent((content) => {
return ({
return {
...content,
objects: [
...content.objects,
courtObject,
]
})
objects: [...content.objects, courtObject],
}
})
}
const getPlayerCollided = (bounds: DOMRect, players: Player[]): number | -1 => {
const getPlayerCollided = (
bounds: DOMRect,
players: Player[],
): number | -1 => {
for (let i = 0; i < players.length; i++) {
const player = players[i]
const playerBounds = document.getElementById(player.id)!.getBoundingClientRect()
const playerBounds = document
.getElementById(player.id)!
.getBoundingClientRect()
const doesOverlap = !(
bounds.top > playerBounds.bottom ||
bounds.right < playerBounds.left ||
@ -234,33 +252,50 @@ function EditorView({
return -1
}
const onBallDropOnPlayer = (playerCollidedIdx: number) => {
setContent((content) => {
const ballObj = content.objects.findIndex(o => o.type == "ball")
const ballObj = content.objects.findIndex((o) => o.type == "ball")
let player = content.players.at(playerCollidedIdx) as Player
return {
...content,
players: content.players.toSpliced(playerCollidedIdx, 1, {...player, hasBall: true}),
objects : content.objects.toSpliced(ballObj, 1)
players: content.players.toSpliced(playerCollidedIdx, 1, {
...player,
hasBall: true,
}),
objects: content.objects.toSpliced(ballObj, 1),
}
})
}
const onBallDrop = (refBounds: DOMRect) => {
if (!isBoundsOnCourt(refBounds)) {
setContent((content) => {
const ballObj = content.objects.findIndex(
(o) => o.type == "ball",
)
return {
...content,
objects: content.objects.toSpliced(ballObj, 1),
}
})
setObjects([{ key: "ball" }])
}
const playerCollidedIdx = getPlayerCollided(refBounds, content.players)
if (playerCollidedIdx != -1) {
setContent((content) => {
return {
...content,
players: content.players.map((player) => ({...player, hasBall: false})),
players: content.players.map((player) => ({
...player,
hasBall: false,
})),
}
})
onBallDropOnPlayer(playerCollidedIdx)
return
}
if(content.objects.findIndex(o => o.type == "ball") != -1) {
if (content.objects.findIndex((o) => o.type == "ball") != -1) {
return
}
@ -271,17 +306,17 @@ function EditorView({
courtObject = {
type: "ball",
rightRatio: x,
bottomRatio: y
bottomRatio: y,
}
setContent((content) => {
return {
...content,
players: content.players.map((player) => ({...player, hasBall: false})),
objects: [
...content.objects,
courtObject,
]
players: content.players.map((player) => ({
...player,
hasBall: false,
})),
objects: [...content.objects, courtObject],
}
})
}
@ -313,7 +348,9 @@ function EditorView({
id="allies-rack"
objects={allies}
onChange={setAllies}
canDetach={div => canDetach(div.getBoundingClientRect())}
canDetach={(div) =>
isBoundsOnCourt(div.getBoundingClientRect())
}
onElementDetached={onPieceDetach}
render={({ team, key }) => (
<PlayerPiece
@ -325,18 +362,24 @@ function EditorView({
)}
/>
<Rack id={"objects"}
<Rack
id={"objects"}
objects={objects}
onChange={setObjects}
canDetach={div => canDetach(div.getBoundingClientRect())}
canDetach={(div) =>
isBoundsOnCourt(div.getBoundingClientRect())
}
onElementDetached={onObjectDetach}
render={renderCourtObject}/>
render={renderCourtObject}
/>
<Rack
id="opponent-rack"
objects={opponents}
onChange={setOpponents}
canDetach={div => canDetach(div.getBoundingClientRect())}
canDetach={(div) =>
isBoundsOnCourt(div.getBoundingClientRect())
}
onElementDetached={onPieceDetach}
render={({ team, key }) => (
<PlayerPiece
@ -376,9 +419,7 @@ function EditorView({
player,
false,
),
objects: [
...content.objects,
]
objects: [...content.objects],
}))
let setter
switch (player.team) {
@ -402,10 +443,15 @@ function EditorView({
}}
onBallRemove={() => {
setContent((content) => {
const ballObj = content.objects.findIndex(o => o.type == "ball")
const ballObj = content.objects.findIndex(
(o) => o.type == "ball",
)
return {
...content,
objects: content.objects.toSpliced(ballObj, 1)
objects: content.objects.toSpliced(
ballObj,
1,
),
}
})
setObjects([{ key: "ball" }])
@ -419,10 +465,10 @@ function EditorView({
}
function isBallOnCourt(content: TacticContent) {
if(content.players.findIndex(p => p.hasBall) != -1) {
if (content.players.findIndex((p) => p.hasBall) != -1) {
return true
}
return content.objects.findIndex(o => o.type == "ball") != -1
return content.objects.findIndex((o) => o.type == "ball") != -1
}
function renderCourtObject(courtObject: RackedCourtObject) {

Loading…
Cancel
Save