Skip to content

Commit

Permalink
Building frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
epifab committed Mar 3, 2024
1 parent 64aa560 commit 581e99b
Show file tree
Hide file tree
Showing 21 changed files with 241 additions and 512 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ jobs:
node-version: 18
- name: Build
run: |
sbt test sdk/fullLinkJS
sbt sdk/fullLinkJS
cp modules/sdk/target/scala-3.3.1/sdk-opt/main.js modules/sdk/src/main/typescript/index.js
cd modules/sdk/src/main/typescript
npm install
find model -name "*-ti.ts" -type f -delete
`npm bin`/ts-interface-builder model/*.ts
npm link
cd ../../../../../frontend
npm install
Expand All @@ -36,7 +34,7 @@ jobs:
uses: actions/upload-pages-artifact@v3
with:
name: github-pages
path: artifact
path: frontend/dist

deploy:
needs: build
Expand Down
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,6 @@ lazy val backend = (project in file("modules/backend"))
fork := true
)

lazy val root = (project in file(".")).aggregate(domain.jvm, backend)
lazy val root = (project in file("."))
.aggregate(domain.jvm, backend)
.settings(name := "bastoni")
1 change: 1 addition & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

# production
/build
/dist

# misc
.DS_Store
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/App.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
html, body {
margin: 0 !important;
padding: 0 !important;
overflow: hidden;
}

body {
background: black;
color: white;
font-family: 'Open Sans', sans-serif;
}
Expand Down
86 changes: 22 additions & 64 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,39 @@
import React, {useEffect, useState} from 'react';
import {useEffect, useState} from 'react';
import './App.css';
import {fetchAuthToken} from "bastoni/authClient";
import {GameClientBuilder} from "bastoni/gameClient";
import {authenticateMessage, connectMessage, joinTableMessage, OutboxMessage} from "bastoni/model/outboxMessage";
import Card from "./components/Card";
import {OutboxMessage, pongMessage} from "bastoni/model/outboxMessage";
import {GameRoom} from "./components/GameRoom";
import {GameType} from "bastoni/model/gameType"
import {CardStyle} from "./view/CardStyle";
import {Stage} from "@pixi/react";
import {playAgainstComputer} from "bastoni"
import {Room, RoomId} from "bastoni/model/room"
import {CardSuit, CardRank} from "bastoni/model/card"
import {Room} from "bastoni/model/room"
import {InboxMessage} from "bastoni/model/inboxMessage"

async function connect() {
const roomId: RoomId = 'ab24cf47-505a-4794-85a6-2866749eb4f5';
const playerName = 'John Doe';
const authToken = await fetchAuthToken(playerName, 'localhost:9000', false);
return new GameClientBuilder()
.onReady((client) => client.send(authenticateMessage(authToken)))
.onAuthenticated((user, client) => client.send(connectMessage))
.onConnected((room, client) => client.send(joinTableMessage))
.onPlayerJoinedTable((event) => console.log(`${event.user.name} joined the room`))
.onPlayerLeftTable((event) => console.log(`${event.user.name} left the room`))
.build(roomId);
}
// async function connect() {
// const roomId: RoomId = 'ab24cf47-505a-4794-85a6-2866749eb4f5';
// const playerName = 'John Doe';
// const authToken = await fetchAuthToken(playerName, 'localhost:9000', false);
// return new GameClientBuilder()
// .onReady((client) => client.send(authenticateMessage(authToken)))
// .onAuthenticated((user, client) => client.send(connectMessage))
// .onConnected((room, client) => client.send(joinTableMessage))
// .onPlayerJoinedTable((event) => console.log(`${event.user.name} joined the room`))
// .onPlayerLeftTable((event) => console.log(`${event.user.name} left the room`))
// .build(roomId);
// }


export function App() {
const [room, setRoom] = useState<Room | undefined>(undefined)
const [controller, setController] = useState<(message: OutboxMessage) => void>((message: OutboxMessage) => {
})

useEffect(() => {
const cleanup: () => void = playAgainstComputer(
'Me',
GameType.Briscola,
(message: InboxMessage, room: Room) => {
(message: InboxMessage, room?: Room) => {
console.log(message)
console.log(room)
setRoom(room)
},
(sendMessage: (message: OutboxMessage) => void) => setController(sendMessage)
(sendMessage: (message: OutboxMessage) => void) => sendMessage(pongMessage)
)
console.info("Game loaded")
return () => {
Expand All @@ -56,45 +50,9 @@ export function App() {
// })

return (
<Stage options={{antialias: true, autoDensity: false, resolution: 1}} width={window.innerWidth}
height={window.innerHeight}>
<Card
card={{
rank: CardRank.Tre,
suit: CardSuit.Bastoni,
ref: 3
}}
width={200}
topLeft={{x: 0, y: 0}}
style={CardStyle.Napoletane}
/>
<Card
card={{
rank: CardRank.Asso,
suit: CardSuit.Spade,
ref: 3
}}
width={200}
topLeft={{x: 900, y: 500}}
style={CardStyle.Napoletane}
rotation={{deg: 2}}
/>
<Card
card={{ref: 2}}
width={200}
topLeft={{x: 100, y: 200}}
style={CardStyle.Napoletane}
/>
</Stage>
// <div className="App">
// <header className="App-header">
// <img src={logo} className="App-logo" alt="logo"/>
// <p>
// Edit <code>src/App.tsx</code> and save to reload.
// </p>
//
// </header>
// </div>
<>
{room ? <GameRoom room={room} /> : <p>loading</p>}
</>
);
}

Expand Down
9 changes: 5 additions & 4 deletions frontend/src/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import {Sprite} from "@pixi/react";
import CardLayout from "../view/CardLayout";
import {isVisible} from "bastoni/model/card";
import napoletane from "../view/cards/napoletane/resources";
import piacentine from "../view/cards/piacentine/resources";
import napoletane from "../view/cards/napoletane";
import piacentine from "../view/cards/piacentine";
import retro from "../view/cards/retro.tsx";
import {CardStyle} from "../view/CardStyle";
import {useEffect, useState} from "react";
import {Texture} from "pixi.js";
// import {DropShadowFilter} from '@pixi/filter-drop-shadow';

export default function Card(layout: CardLayout) {

const [card, setCard] = useState<Texture>(null);
const [card, setCard] = useState<Texture | undefined>(undefined);
const svgs = layout.style === CardStyle.Piacentine ? piacentine : napoletane;

useEffect(() => {
async function loadCard() {
const uri = isVisible(layout.card) ? svgs[layout.card.suit][layout.card.rank] : './cards/retro.svg';
const uri = isVisible(layout.card) ? svgs[layout.card.suit][layout.card.rank] : retro;
setCard(await Texture.fromURL(uri));
}

Expand Down
5 changes: 0 additions & 5 deletions frontend/src/components/Deck.tsx

This file was deleted.

52 changes: 52 additions & 0 deletions frontend/src/components/GameRoom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {Room} from "bastoni/model/room"
import {CardSuit, CardRank} from "bastoni/model/card"
import {Stage, Text} from "@pixi/react";
import Card from "./Card.tsx";
import {CardStyle} from "../view/CardStyle.ts";
import {TextStyle} from "pixi.js";

interface RoomProps {
room: Room
}

export function GameRoom({room}: RoomProps) {
return (
<Stage options={{antialias: true, autoDensity: false, resolution: 1}}
width={window.innerWidth}
height={window.innerHeight}
>
<Text
text={room.players[room.me]?.name}
style={new TextStyle({fill: 0xFFFFFF, fontSize: 40})}
/>

<Card
card={{
rank: CardRank.Tre,
suit: CardSuit.Bastoni,
ref: 3
}}
width={200}
topLeft={{x: 0, y: 0}}
style={CardStyle.Napoletane}
/>
<Card
card={{
rank: CardRank.Asso,
suit: CardSuit.Spade,
ref: 3
}}
width={200}
topLeft={{x: 900, y: 500}}
style={CardStyle.Napoletane}
rotation={{deg: 2}}
/>
<Card
card={{ref: 2}}
width={200}
topLeft={{x: 100, y: 200}}
style={CardStyle.Napoletane}
/>
</Stage>
)
}
2 changes: 1 addition & 1 deletion frontend/src/view/RoomLayout.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Room} from "bastoni/model/room";
import CardLayout from "./CardLayout";
import {CardStyle} from "./CardStyle";
import {isActing, PlayerState} from "bastoni/model/player";
import {isActing} from "bastoni/model/player";

export default class RoomLayout {
deck: CardLayout[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ const cardsRecord: Record<CardSuit, Record<CardRank, string>> = {
[CardRank.Re]: './cards/napoletane/spade/10.svg',
},
[CardSuit.Bastoni]: {
[CardRank.Asso]: './cards/napoletane/bastoni.01.svg',
[CardRank.Due]: './cards/napoletane/bastoni.02.svg',
[CardRank.Tre]: './cards/napoletane/bastoni.03.svg',
[CardRank.Quattro]: './cards/napoletane/bastoni.04.svg',
[CardRank.Cinque]: './cards/napoletane/bastoni.05.svg',
[CardRank.Sei]: './cards/napoletane/bastoni.06.svg',
[CardRank.Sette]: './cards/napoletane/bastoni.07.svg',
[CardRank.Fante]: './cards/napoletane/bastoni.08.svg',
[CardRank.Cavallo]: './cards/napoletane/bastoni.09.svg',
[CardRank.Re]: './cards/napoletane/bastoni.10.svg',
[CardRank.Asso]: './cards/napoletane/bastoni/01.svg',
[CardRank.Due]: './cards/napoletane/bastoni/02.svg',
[CardRank.Tre]: './cards/napoletane/bastoni/03.svg',
[CardRank.Quattro]: './cards/napoletane/bastoni/04.svg',
[CardRank.Cinque]: './cards/napoletane/bastoni/05.svg',
[CardRank.Sei]: './cards/napoletane/bastoni/06.svg',
[CardRank.Sette]: './cards/napoletane/bastoni/07.svg',
[CardRank.Fante]: './cards/napoletane/bastoni/08.svg',
[CardRank.Cavallo]: './cards/napoletane/bastoni/09.svg',
[CardRank.Re]: './cards/napoletane/bastoni/10.svg',
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ const cardsRecord: Record<CardSuit, Record<CardRank, string>> = {
[CardRank.Re]: './cards/piacentine/spade/10.svg',
},
[CardSuit.Bastoni]: {
[CardRank.Asso]: './cards/piacentine/bastoni.01.svg',
[CardRank.Due]: './cards/piacentine/bastoni.02.svg',
[CardRank.Tre]: './cards/piacentine/bastoni.03.svg',
[CardRank.Quattro]: './cards/piacentine/bastoni.04.svg',
[CardRank.Cinque]: './cards/piacentine/bastoni.05.svg',
[CardRank.Sei]: './cards/piacentine/bastoni.06.svg',
[CardRank.Sette]: './cards/piacentine/bastoni.07.svg',
[CardRank.Fante]: './cards/piacentine/bastoni.08.svg',
[CardRank.Cavallo]: './cards/piacentine/bastoni.09.svg',
[CardRank.Re]: './cards/piacentine/bastoni.10.svg',
[CardRank.Asso]: './cards/piacentine/bastoni/01.svg',
[CardRank.Due]: './cards/piacentine/bastoni/02.svg',
[CardRank.Tre]: './cards/piacentine/bastoni/03.svg',
[CardRank.Quattro]: './cards/piacentine/bastoni/04.svg',
[CardRank.Cinque]: './cards/piacentine/bastoni/05.svg',
[CardRank.Sei]: './cards/piacentine/bastoni/06.svg',
[CardRank.Sette]: './cards/piacentine/bastoni/07.svg',
[CardRank.Fante]: './cards/piacentine/bastoni/08.svg',
[CardRank.Cavallo]: './cards/piacentine/bastoni/09.svg',
[CardRank.Re]: './cards/piacentine/bastoni/10.svg',
}
}

Expand Down
3 changes: 3 additions & 0 deletions frontend/src/view/cards/retro.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const retro = './cards/retro.svg'

export default retro
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import bastoni.domain.model.*
import bastoni.domain.model.Command.*
import bastoni.domain.model.Event.*
import bastoni.domain.view.{FromPlayer, ToPlayer}
import bastoni.domain.view.FromPlayer.GameCommand
import cats.effect.{Resource, Sync}
import cats.effect.syntax.all.*
import cats.effect.Sync
import cats.syntax.all.*
import cats.Monad
import org.typelevel.log4cats.Logger
Expand All @@ -20,7 +18,21 @@ trait GamePublisher[F[_]]:
def publish(me: User, roomId: RoomId)(input: fs2.Stream[F, FromPlayer]): fs2.Stream[F, Unit]
def publish1(me: User, roomId: RoomId)(input: FromPlayer): F[Unit]

trait GameController[F[_]] extends GameSubscriber[F] with GamePublisher[F]
trait GameController[F[_]] extends GameSubscriber[F] with GamePublisher[F]:
def connectPlayer(me: User, roomId: RoomId): fs2.Stream[F, (ToPlayer, Option[RoomPlayerView])] =
subscribe(me, roomId)
.takeThrough {
case ToPlayer.Disconnected(_) => false
case _ => true
}
.zipWithScan1(Option.empty[RoomPlayerView]) {
case (_, ToPlayer.Connected(room)) => Some(room)
case (_, ToPlayer.Disconnected(_)) => None
case (room, ToPlayer.Request(request)) => room.map(_.withRequest(request))
case (room, ToPlayer.GameEvent(event)) => room.map(_.update(event))
case (room, ToPlayer.Authenticated(_)) => room
case (room, ToPlayer.Ping) => room
}

object GameController:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class IntegrationSpec extends AsyncIOFreeSpec:
delayDuration =
if realSpeed then Delay.default
else {
case Delay.ActionTimeout => 100.millis
case Delay.ActionTimeout => 2.hours
case _ => 2.millis
}
)
Expand Down
Loading

0 comments on commit 581e99b

Please sign in to comment.