Set up a database and serve character sheets from it #277
|
@ -118,7 +118,7 @@ impl Core {
|
||||||
state.tabletop.background_image = Some(asset.clone());
|
state.tabletop.background_image = Some(asset.clone());
|
||||||
state.tabletop.clone()
|
state.tabletop.clone()
|
||||||
};
|
};
|
||||||
self.publish(Message::UpdateTabletop(tabletop));
|
self.publish(Message::UpdateTabletop(tabletop)).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ pub async fn handle_connect_websocket(
|
||||||
|
|
||||||
pub async fn handle_set_background_image(core: Core, image_name: String) -> impl Reply {
|
pub async fn handle_set_background_image(core: Core, image_name: String) -> impl Reply {
|
||||||
handler(async move {
|
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()
|
Ok(Response::builder()
|
||||||
.header("Access-Control-Allow-Origin", "*")
|
.header("Access-Control-Allow-Origin", "*")
|
||||||
|
@ -166,6 +166,8 @@ pub async fn handle_get_charsheet(core: Core, charid: String) -> impl Reply {
|
||||||
|
|
||||||
match sheet {
|
match sheet {
|
||||||
Some(sheet) => Ok(Response::builder()
|
Some(sheet) => Ok(Response::builder()
|
||||||
|
.header("Access-Control-Allow-Origin", "*")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
.body(serde_json::to_vec(&sheet).unwrap())
|
.body(serde_json::to_vec(&sheet).unwrap())
|
||||||
.unwrap()),
|
.unwrap()),
|
||||||
None => Ok(Response::builder()
|
None => Ok(Response::builder()
|
||||||
|
|
|
@ -3,5 +3,7 @@ version: '3'
|
||||||
tasks:
|
tasks:
|
||||||
dev:
|
dev:
|
||||||
cmds:
|
cmds:
|
||||||
|
- cd ../visions-types && task build
|
||||||
|
- npm install
|
||||||
- npm run start
|
- npm run start
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"typescript": "^5.6.3"
|
"typescript": "^5.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@adobe/css-tools": {
|
"node_modules/@adobe/css-tools": {
|
||||||
|
|
|
@ -12,6 +12,16 @@ interface AppProps {
|
||||||
client: Client;
|
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) => {
|
const App = ({ client }: AppProps) => {
|
||||||
console.log("rendering app");
|
console.log("rendering app");
|
||||||
const [websocketUrl, setWebsocketUrl] = useState<string | undefined>(undefined);
|
const [websocketUrl, setWebsocketUrl] = useState<string | undefined>(undefined);
|
||||||
|
@ -32,7 +42,7 @@ const App = ({ client }: AppProps) => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/candela",
|
path: "/candela",
|
||||||
element: <Candela.CharsheetElement />
|
element: <CandelaCharsheet client={client} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/design",
|
path: "/design",
|
||||||
|
|
|
@ -44,4 +44,10 @@ export class Client {
|
||||||
url.pathname = `/api/v1/tabletop/bg_image`;
|
url.pathname = `/api/v1/tabletop/bg_image`;
|
||||||
return fetch(url, { method: 'PUT', headers: [['Content-Type', 'application/json']], body: JSON.stringify(name) });
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ const AbilitiesElement = ({ role, role_abilities, specialty, specialty_abilities
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CharsheetElement_ = ({ sheet }: CharsheetProps) => {
|
export const CharsheetElement = ({ sheet }: CharsheetProps) => {
|
||||||
return (<div>
|
return (<div>
|
||||||
<div className="charsheet__header">
|
<div className="charsheet__header">
|
||||||
<div> Candela Obscura </div>
|
<div> Candela Obscura </div>
|
||||||
|
@ -115,6 +115,7 @@ const CharsheetElement_ = ({ sheet }: CharsheetProps) => {
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
export const CharsheetElement = () => {
|
export const CharsheetElement = () => {
|
||||||
const sheet = {
|
const sheet = {
|
||||||
type_: 'Candela',
|
type_: 'Candela',
|
||||||
|
@ -160,3 +161,4 @@ export const CharsheetElement = () => {
|
||||||
|
|
||||||
return <CharsheetElement_ sheet={sheet} />
|
return <CharsheetElement_ sheet={sheet} />
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -66,7 +66,7 @@ const ActionGroupElement = ({ group }: ActionGroupElementProps) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const CharsheetPanelElement_ = ({ sheet }: CharsheetPanelProps) => {
|
export const CharsheetPanelElement = ({ sheet }: CharsheetPanelProps) => {
|
||||||
return (<div className="candela-panel">
|
return (<div className="candela-panel">
|
||||||
<div className="candela-panel__header">
|
<div className="candela-panel__header">
|
||||||
<p> {sheet.name} ({sheet.pronouns}) </p>
|
<p> {sheet.name} ({sheet.pronouns}) </p>
|
||||||
|
@ -88,6 +88,7 @@ const CharsheetPanelElement_ = ({ sheet }: CharsheetPanelProps) => {
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
export const CharsheetPanelElement = () => {
|
export const CharsheetPanelElement = () => {
|
||||||
const sheet = {
|
const sheet = {
|
||||||
type_: 'Candela',
|
type_: 'Candela',
|
||||||
|
@ -133,3 +134,4 @@ export const CharsheetPanelElement = () => {
|
||||||
|
|
||||||
return <CharsheetPanelElement_ sheet={sheet} />
|
return <CharsheetPanelElement_ sheet={sheet} />
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import './PlayerView.css';
|
import './PlayerView.css';
|
||||||
import { WebsocketContext } from '../../components/WebsocketProvider';
|
import { WebsocketContext } from '../../components/WebsocketProvider';
|
||||||
import { Client } from '../../client';
|
import { Client } from '../../client';
|
||||||
|
@ -12,13 +12,25 @@ interface PlayerViewProps {
|
||||||
export const PlayerView = ({ client }: PlayerViewProps) => {
|
export const PlayerView = ({ client }: PlayerViewProps) => {
|
||||||
const { tabletop } = useContext(WebsocketContext);
|
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 backgroundColor = tabletop.backgroundColor;
|
||||||
const tabletopColorStyle = `rgb(${backgroundColor.red}, ${backgroundColor.green}, ${backgroundColor.blue})`;
|
const tabletopColorStyle = `rgb(${backgroundColor.red}, ${backgroundColor.green}, ${backgroundColor.blue})`;
|
||||||
const backgroundUrl = tabletop.backgroundImage ? client.imageUrl(tabletop.backgroundImage) : undefined;
|
const backgroundUrl = tabletop.backgroundImage ? client.imageUrl(tabletop.backgroundImage) : undefined;
|
||||||
|
|
||||||
return (<div className="player-view" style={{ backgroundColor: tabletopColorStyle }}>
|
return (<div className="player-view" style={{ backgroundColor: tabletopColorStyle }}>
|
||||||
<div className="player-view__middle-panel"> <TabletopElement backgroundColor={backgroundColor} backgroundUrl={backgroundUrl} /> </div>
|
<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>)
|
</div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,6 @@ version: '3'
|
||||||
tasks:
|
tasks:
|
||||||
build:
|
build:
|
||||||
cmds:
|
cmds:
|
||||||
|
- npm install typescript
|
||||||
- typeshare --lang typescript --output-file visions.ts ../server/src
|
- typeshare --lang typescript --output-file visions.ts ../server/src
|
||||||
- npx tsc
|
- npx tsc
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"typescript": "^5.6.3"
|
"typescript": "^5.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.6.3",
|
"version": "5.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
|
||||||
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
|
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"typescript": "^5.6.3"
|
"typescript": "^5.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue