Set up a database and serve character sheets from it #277

Merged
savanni merged 7 commits from visions-database into main 2024-11-30 23:56:21 +00:00
12 changed files with 50 additions and 13 deletions
Showing only changes of commit d8ea2aac40 - Show all commits

View File

@ -118,7 +118,7 @@ impl Core {
state.tabletop.background_image = Some(asset.clone());
state.tabletop.clone()
};
self.publish(Message::UpdateTabletop(tabletop));
self.publish(Message::UpdateTabletop(tabletop)).await;
Ok(())
}

View File

@ -148,7 +148,7 @@ pub async fn handle_connect_websocket(
pub async fn handle_set_background_image(core: Core, image_name: String) -> impl Reply {
handler(async move {
let _ = core.set_background_image(AssetId::from(image_name));
let _ = core.set_background_image(AssetId::from(image_name)).await;
Ok(Response::builder()
.header("Access-Control-Allow-Origin", "*")
@ -166,6 +166,8 @@ pub async fn handle_get_charsheet(core: Core, charid: String) -> impl Reply {
match sheet {
Some(sheet) => Ok(Response::builder()
.header("Access-Control-Allow-Origin", "*")
.header("Content-Type", "application/json")
.body(serde_json::to_vec(&sheet).unwrap())
.unwrap()),
None => Ok(Response::builder()

View File

@ -3,5 +3,7 @@ version: '3'
tasks:
dev:
cmds:
- cd ../visions-types && task build
- npm install
- npm run start

View File

@ -33,7 +33,7 @@
"version": "0.0.1",
"license": "ISC",
"dependencies": {
"typescript": "^5.6.3"
"typescript": "^5.7.2"
}
},
"node_modules/@adobe/css-tools": {

View File

@ -12,6 +12,16 @@ interface AppProps {
client: Client;
}
const CandelaCharsheet = ({ client }: { client: Client }) => {
let [sheet, setSheet] = useState(undefined);
useEffect(
() => { client.charsheet("db7a2585-5dcf-4909-8743-2741111f8b9a").then((c) => setSheet(c)); },
[client, setSheet]
);
return sheet ? <Candela.CharsheetElement sheet={sheet} /> : <div> </div>
}
const App = ({ client }: AppProps) => {
console.log("rendering app");
const [websocketUrl, setWebsocketUrl] = useState<string | undefined>(undefined);
@ -32,7 +42,7 @@ const App = ({ client }: AppProps) => {
},
{
path: "/candela",
element: <Candela.CharsheetElement />
element: <CandelaCharsheet client={client} />
},
{
path: "/design",

View File

@ -44,4 +44,10 @@ export class Client {
url.pathname = `/api/v1/tabletop/bg_image`;
return fetch(url, { method: 'PUT', headers: [['Content-Type', 'application/json']], body: JSON.stringify(name) });
}
async charsheet(id: string) {
const url = new URL(this.base);
url.pathname = `/api/v1/charsheet/${id}`;
return fetch(url).then((response) => response.json());
}
}

View File

@ -88,7 +88,7 @@ const AbilitiesElement = ({ role, role_abilities, specialty, specialty_abilities
);
}
const CharsheetElement_ = ({ sheet }: CharsheetProps) => {
export const CharsheetElement = ({ sheet }: CharsheetProps) => {
return (<div>
<div className="charsheet__header">
<div> Candela Obscura </div>
@ -115,6 +115,7 @@ const CharsheetElement_ = ({ sheet }: CharsheetProps) => {
</div>);
}
/*
export const CharsheetElement = () => {
const sheet = {
type_: 'Candela',
@ -160,3 +161,4 @@ export const CharsheetElement = () => {
return <CharsheetElement_ sheet={sheet} />
}
*/

View File

@ -66,7 +66,7 @@ const ActionGroupElement = ({ group }: ActionGroupElementProps) => {
}
const CharsheetPanelElement_ = ({ sheet }: CharsheetPanelProps) => {
export const CharsheetPanelElement = ({ sheet }: CharsheetPanelProps) => {
return (<div className="candela-panel">
<div className="candela-panel__header">
<p> {sheet.name} ({sheet.pronouns}) </p>
@ -88,6 +88,7 @@ const CharsheetPanelElement_ = ({ sheet }: CharsheetPanelProps) => {
</div>);
}
/*
export const CharsheetPanelElement = () => {
const sheet = {
type_: 'Candela',
@ -133,3 +134,4 @@ export const CharsheetPanelElement = () => {
return <CharsheetPanelElement_ sheet={sheet} />
}
*/

View File

@ -1,4 +1,4 @@
import React, { useContext } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import './PlayerView.css';
import { WebsocketContext } from '../../components/WebsocketProvider';
import { Client } from '../../client';
@ -12,13 +12,25 @@ interface PlayerViewProps {
export const PlayerView = ({ client }: PlayerViewProps) => {
const { tabletop } = useContext(WebsocketContext);
const [charsheet, setCharsheet] = useState(undefined);
useEffect(
() => {
client.charsheet("db7a2585-5dcf-4909-8743-2741111f8b9a").then((c) => {
setCharsheet(c)
});
},
[client, setCharsheet]
);
const backgroundColor = tabletop.backgroundColor;
const tabletopColorStyle = `rgb(${backgroundColor.red}, ${backgroundColor.green}, ${backgroundColor.blue})`;
const backgroundUrl = tabletop.backgroundImage ? client.imageUrl(tabletop.backgroundImage) : undefined;
return (<div className="player-view" style={{ backgroundColor: tabletopColorStyle }}>
<div className="player-view__middle-panel"> <TabletopElement backgroundColor={backgroundColor} backgroundUrl={backgroundUrl} /> </div>
<div className="player-view__right-panel"> <Candela.CharsheetPanelElement /> </div>
<div className="player-view__right-panel">
{charsheet ? <Candela.CharsheetPanelElement sheet={charsheet} /> : <div> </div>}</div>
</div>)
}

View File

@ -3,5 +3,6 @@ version: '3'
tasks:
build:
cmds:
- npm install typescript
- typeshare --lang typescript --output-file visions.ts ../server/src
- npx tsc

View File

@ -9,13 +9,13 @@
"version": "0.0.1",
"license": "ISC",
"dependencies": {
"typescript": "^5.6.3"
"typescript": "^5.7.2"
}
},
"node_modules/typescript": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"

View File

@ -9,6 +9,6 @@
"author": "",
"license": "ISC",
"dependencies": {
"typescript": "^5.6.3"
"typescript": "^5.7.2"
}
}