import { CharacterIdentifier, UpdateBasicInfoRequest, UpdateSkillValueRequest, UpdateAttributeRequest, UpdateMeritsRequest, UpdateItemsRequest } from "../../_proto/cofd_api_pb"; import { CofdSheet } from "../../_proto/cofd_pb"; import * as api from "../api"; import * as ui from "./edit-ui"; // This is the scripting for the edit character page, which submits // changes to the server as the user makes them. (async () => { // Useful for making sure elements actually exist in event handler. type Option = T | null | undefined; const [, , USERNAME, CHARACTER_ID] = window.location.pathname.split('/'); function characterId(): CharacterIdentifier { const id = new CharacterIdentifier(); id.setId(parseInt(CHARACTER_ID)); id.setOwner(USERNAME); return id; } const getTextValue = (selector: string) => document.querySelector(selector)?.value ?? ""; const getIntValue = (selector: string) => parseInt(document.querySelector(selector)?.value ?? "0") function setupAttributes() { const attributeInputs = document.querySelectorAll('#attributes input[type="number"]'); async function attributeHandler(event: Event) { const input = event.target as Option; if (!input) return; console.log("updating attr"); const attribute = input.id; const newValue = parseInt(input.value); const params = new UpdateAttributeRequest(); params.setCharacter(characterId()); params.setAttributeName(attribute); params.setAttributeValue(newValue); let resp = await api.updateAttributeValue(params); console.log("got a response back", resp); } Array.from(attributeInputs).forEach(input => { input.addEventListener('change', attributeHandler); }); } function setupSkills() { const skillInputs = document.querySelectorAll('#skills input[type="number"]'); async function skillValueHandler(event: Event) { const input = event.target as Option; if (!input) return; console.log("updating skill"); const attribute = input.id; const newValue = parseInt(input.value); const params = new UpdateSkillValueRequest(); params.setCharacter(characterId()); params.setSkillName(attribute); params.setSkillValue(newValue); let resp = await api.updateSkillValue(params); console.log("got a response back", resp); } Array.from(skillInputs).forEach(input => { input.addEventListener('change', skillValueHandler); }); } function setupBasicInfo() { async function updateInfo() { const params = new UpdateBasicInfoRequest(); params.setCharacter(characterId()); params.setName(getTextValue("#characterName")); params.setAge(getIntValue("#age")); params.setConcept(getTextValue("#concept")); params.setChronicle(getTextValue("#chronicle")); params.setGender(getTextValue("#gender")); let resp = await api.updateBasicInfo(params); console.log("got a response back", resp); } const inputs = document.querySelectorAll("#basics input"); inputs.forEach(input => { console.log('got an input', input); input.addEventListener('blur', updateInfo); }); } function setupMerits() { async function updateMerits() { let meritElements = document.querySelectorAll('#merits input[class="merit-name"]'); let merits: CofdSheet.Merit[] = Array.from(meritElements).map(input => { const dotsInput = input.parentElement?.querySelector('input[class="merit-dots"]'); let dotsAmount = dotsInput?.value ?? "0"; if (dotsAmount.length == 0) { dotsAmount = "0"; } const merit = new CofdSheet.Merit(); merit.setName(input.value); merit.setDots(parseInt(dotsAmount)); return merit; }); const params = new UpdateMeritsRequest(); params.setCharacter(characterId()); params.setMeritsList(merits); let resp = await api.updateMerits(params); console.log("got a response back", resp); } async function removeMerit(event: Event) { const button = event.target as Option; const meritLine = button?.parentElement; if (meritLine) { document.querySelector("#merit-list")?.removeChild(meritLine); await updateMerits(); } } async function processEvent(event: Event) { console.log('processing merit control event'); const element = event.target as Element; const eventType = element.getAttribute('data-event-type') ?? ''; if (eventType == 'remove-merit') { await removeMerit(event); } else if (eventType == 'add-merit') { const meritList = document.querySelector("#merit-list")!; ui.addMeritLine(meritList); } } const meritControls = document.querySelector("#merit-controls"); meritControls?.addEventListener('click', processEvent); const meritList = document.querySelector("#merit-list"); meritList?.addEventListener('click', processEvent); meritList?.addEventListener('blur', updateMerits); meritList?.addEventListener('change', updateMerits); } function setupItems() { async function updateItems() { let meritElements = document.querySelectorAll('#items input[class="item-name"]'); let items: CofdSheet.Item[] = Array.from(meritElements).map(input => { const item = new CofdSheet.Item(); item.setName(input.value); item.setDescription(""); //TODO add description item.setRules(""); //TODO add rules return item; }); console.log("items are", items); const params = new UpdateItemsRequest(); params.setCharacter(characterId()); params.setItemsList(items); let resp = await api.updateItems(params); console.log("got a response back", resp); } async function removeItem(event: Event) { const button = event.target as Option; const itemLine = button?.parentElement; if (itemLine) { document.querySelector("#item-list")?.removeChild(itemLine); await updateItems(); } } async function processEvent(event: Event) { console.log('processing item control event'); const element = event.target as Element; const eventType = element.getAttribute('data-event-type') ?? ''; if (eventType == 'remove-item') { await removeItem(event); } else if (eventType == 'add-item') { const itemList = document.querySelector("#item-list")!; ui.addItemLine(itemList); } } const meritControls = document.querySelector("#item-controls"); meritControls?.addEventListener('click', processEvent); const meritList = document.querySelector("#item-list"); meritList?.addEventListener('click', processEvent); meritList?.addEventListener('blur', updateItems); meritList?.addEventListener('change', updateItems); } setupAttributes(); setupSkills(); setupBasicInfo(); setupMerits(); setupItems(); })().catch(e => { alert(e); });