WIP on reimplementing edit character script with typescript

This commit is contained in:
jeff 2021-01-04 22:36:21 +00:00
parent 06262e6ad3
commit af01a56907
8 changed files with 142 additions and 74 deletions

View File

@ -6,15 +6,6 @@ use std::ops::Deref;
pub mod cofd; pub mod cofd;
const CRATE_NAME: &'static str = env!("CARGO_BIN_NAME");
/// Convert an incoming protobuf content-type to the equivalent type
/// name produced by std::any::type_name(). Currently does NOT work
/// with nested types due to how prost generates the module names.
fn convert_to_rust_name(proto_type: &str) -> String {
format!("{}::{}", CRATE_NAME, proto_type.replace(".", "::"))
}
/// A struct wrapping a protobuf that allows it to be used as binary /// A struct wrapping a protobuf that allows it to be used as binary
/// data submitted via POST using fetch API. Can automatically be /// data submitted via POST using fetch API. Can automatically be
/// dereferenced into its wrapped type. /// dereferenced into its wrapped type.
@ -40,21 +31,10 @@ where
.map(|ct| ct.top() == "application" && ct.sub() == "x-protobuf") .map(|ct| ct.top() == "application" && ct.sub() == "x-protobuf")
.unwrap_or(false); .unwrap_or(false);
let message_type: Option<String> = content_type.and_then(|ct| {
ct.params()
.find(|&(name, _)| name == "messageType")
.map(|(_, message_type)| convert_to_rust_name(message_type))
});
if !is_protobuf { if !is_protobuf {
return Outcome::Failure((Status::new(422, "invalid protobuf"), Error::InvalidInput)); return Outcome::Failure((Status::new(422, "invalid protobuf"), Error::InvalidInput));
} }
if message_type.as_ref().map(String::as_str) != Some(std::any::type_name::<T>()) {
println!("message type is {:?}", message_type);
return Outcome::Forward(data);
}
let bytes: Vec<u8> = match data.open(2.mebibytes()).stream_to_vec().await { let bytes: Vec<u8> = match data.open(2.mebibytes()).stream_to_vec().await {
Ok(read_bytes) => read_bytes, Ok(read_bytes) => read_bytes,
Err(e) => return Outcome::Failure((Status::new(422, "invalid protobuf"), e.into())), Err(e) => return Outcome::Failure((Status::new(422, "invalid protobuf"), e.into())),

View File

@ -85,8 +85,11 @@
</style> </style>
<script src="https://cdn.jsdelivr.net/npm/protobufjs@6.10.2/dist/protobuf.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/protobufjs@6.10.2/dist/protobuf.min.js"></script>
<script defer type="text/javascript" src="/scripts/api.js"></script> {# <script defer type="text/javascript" src="/scripts/api.js"></script> #}
<script defer type="text/javascript" src="/scripts/characters/edit.js"></script> {# <script defer type="text/javascript" src="/scripts/characters/edit.js"></script> #}
{# Webpack Templating for API script #}
<%= htmlWebpackPlugin.tags.bodyTags %>
<h1>Core Sheet</h1> <h1>Core Sheet</h1>
<div> <div>
<h1>Name: <input type="text" value="{{name}}" /></h1> <h1>Name: <input type="text" value="{{name}}" /></h1>

View File

@ -2,12 +2,12 @@
//TODO start refactoring these into a separate script, and make API calls //TODO start refactoring these into a separate script, and make API calls
//take all necessary info (e.g. username and character ID, plus other stuff) //take all necessary info (e.g. username and character ID, plus other stuff)
//as object params. //as object params.
const root = await protobuf.load("/protos/cofd_api.proto"); //const root = await protobuf.load("/protos/cofd_api.proto");
const [, , USERNAME, CHARACTER_ID] = window.location.pathname.split('/'); const [, , USERNAME, CHARACTER_ID] = window.location.pathname.split('/');
const api = makeAPI(root); //const api = makeAPI(root);
console.log("api is", api); //console.log("api is", api);
function setupAttributes() { function setupAttributes() {
const attributeInputs = document.querySelectorAll('#attributes input[type="number"]'); const attributeInputs = document.querySelectorAll('#attributes input[type="number"]');

15
static/scripts/src/api.ts Normal file
View File

@ -0,0 +1,15 @@
import { UpdateSkillValueRequest } from "../_proto/cofd_api_pb";
const PROTOBUF_CONTENT_TYPE = { 'Content-Type': 'application/x-protobuf' };
export async function updateSkillValue(params: UpdateSkillValueRequest) {
let resp = await fetch('/api/rpc/cofd/update_skill_value', {
method: 'POST',
headers: { ...PROTOBUF_CONTENT_TYPE },
body: params.serializeBinary()
}).then(async resp => {
console.log("resp is", await resp.text());
}).catch(async err => {
console.log("err is", err.text());
});
}

View File

@ -0,0 +1,63 @@
import { UpdateSkillValueRequest } from "../../_proto/cofd_api_pb";
import * as api from "../api";
(async () => {
//TODO start refactoring these into a separate script, and make API calls
//take all necessary info (e.g. username and character ID, plus other stuff)
//as object params.
//const root = await protobuf.load("/protos/cofd_api.proto");
const [, , USERNAME, CHARACTER_ID] = window.location.pathname.split('/');
//const api = makeAPI(root);
//console.log("api is", api);
function setupAttributes() {
// const attributeInputs = document.querySelectorAll('#skills input[type="number"]');
// async function skillValueHandler(event: Event) {
// const input = event.target as HTMLInputElement;
// console.log("updating attr");
// const attribute = input.id;
// const newValue = parseInt(input.value);
// const params = new UpdateSkillValueRequest();
// params.setCharacterUsername(USERNAME);
// params.setCharacterId(parseInt(CHARACTER_ID));
// params.setSkillName(attribute);
// params.setSkillValue(newValue);
// await api.updateSkillValue(params);
// }
// Array.from(attributeInputs).forEach(input => {
// input.addEventListener('change', skillValueHandler);
// });
}
function setupSkills() {
const skillInputs = document.querySelectorAll('#skills input[type="number"]');
async function skillValueHandler(event: Event) {
const input = event.target as HTMLInputElement;
console.log("updating attr");
const attribute = input.id;
const newValue = parseInt(input.value);
const params = new UpdateSkillValueRequest();
params.setCharacterUsername(USERNAME);
params.setCharacterId(parseInt(CHARACTER_ID));
params.setSkillName(attribute);
params.setSkillValue(newValue);
await api.updateSkillValue(params);
}
Array.from(skillInputs).forEach(input => {
input.addEventListener('change', skillValueHandler);
});
}
setupAttributes();
setupSkills();
})().catch(e => {
alert(e);
});

View File

@ -1,8 +1,10 @@
import * as api from "./api";
import { grpc } from "@improbable-eng/grpc-web"; import { grpc } from "@improbable-eng/grpc-web";
import { CofdApi } from "../_proto/cofd_api_pb_service"; import { CofdApi } from "../_proto/cofd_api_pb_service";
import { UpdateSkillValueRequest } from "../_proto/cofd_api_pb"; import { UpdateSkillValueRequest } from "../_proto/cofd_api_pb";
import { CofdSheet } from "../_proto/cofd_pb"; import { CofdSheet } from "../_proto/cofd_pb";
console.log(api.updateSkillValue);
let x = new UpdateSkillValueRequest(); let x = new UpdateSkillValueRequest();
x.setCharacterId(1); x.setCharacterId(1);
x.setCharacterUsername("guy"); x.setCharacterUsername("guy");

View File

@ -9,7 +9,9 @@
"strictNullChecks": true, "strictNullChecks": true,
"stripInternal": true, "stripInternal": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noEmitOnError": true "noEmitOnError": true,
"lib": [
"dom"
]
} }
} }

View File

@ -10,6 +10,8 @@ function packPage(page, chunks) {
return new HtmlWebpackPlugin({ return new HtmlWebpackPlugin({
template: `${root}/src/templates/${page}`, template: `${root}/src/templates/${page}`,
filename: `${root}/static/templates/${page}`, filename: `${root}/static/templates/${page}`,
publicPath: '/scripts/dist',
scriptLoading: 'defer',
chunks: chunks, chunks: chunks,
inject: false, inject: false,
minify: false minify: false
@ -19,6 +21,7 @@ function packPage(page, chunks) {
module.exports = { module.exports = {
entry: { entry: {
index: "./src/index.ts", index: "./src/index.ts",
edit_character: "./src/characters/edit.ts",
blah: "./src/blah.ts", blah: "./src/blah.ts",
}, },
optimization: { optimization: {
@ -53,7 +56,7 @@ module.exports = {
packPage('error.html.tera'), packPage('error.html.tera'),
packPage('index.html.tera'), packPage('index.html.tera'),
packPage('registration.html.tera'), packPage('registration.html.tera'),
packPage('characters/edit_character.html.tera'), packPage('characters/edit_character.html.tera', ['edit_character']),
packPage('characters/edit_character_macros.html.tera'), packPage('characters/edit_character_macros.html.tera'),
packPage('characters/new_character.html.tera'), packPage('characters/new_character.html.tera'),
packPage('characters/view_character.html.tera') packPage('characters/view_character.html.tera')