import { CharacterIdentifier, UpdateBasicInfoRequest, UpdateSkillValueRequest, UpdateAttributeRequest, UpdateMeritsRequest } from "../../_proto/cofd_api_pb"; import { CofdSheet } from "../../_proto/cofd_pb"; import * as api from "../api"; // 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("#basicInfo 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(); } } function addMeritLine() { const meritName = document.createElement('input'); meritName.type = 'text'; meritName.value = ''; meritName.classList.add('merit-name'); const meritDots = document.createElement('input'); meritDots.type = 'number'; meritDots.min = '0'; meritDots.value = '0'; meritDots.classList.add('merit-dots'); const removeButton = document.createElement('button'); removeButton.innerText = "X"; removeButton.setAttribute('data-event-type', 'remove-merit'); const dots = document.createElement('span'); dots.innerText = 'Dots'; const merit = document.createElement('div'); merit.classList.add('merit'); merit.appendChild(meritName); merit.appendChild(meritDots); merit.appendChild(dots); merit.appendChild(removeButton); document.querySelector("#merit-list")?.appendChild(merit); } async function processControlEvent(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') { addMeritLine(); } } const meritControls = document.querySelector("#merit-controls"); meritControls?.addEventListener('click', processControlEvent); const meritList = document.querySelector("#merit-list"); meritList?.addEventListener('click', processControlEvent); meritList?.addEventListener('blur', updateMerits); meritList?.addEventListener('change', updateMerits); } setupAttributes(); setupSkills(); setupBasicInfo(); setupMerits(); })().catch(e => { alert(e); });