From f4a47e8d4b30c550a7a4b6b05e407b2f4d04b4f0 Mon Sep 17 00:00:00 2001 From: Benjamin Sherriff Date: Wed, 11 Oct 2023 15:06:41 -0400 Subject: [PATCH] Updated spells modal --- service/src/db/spells/types.rs | 43 +------------- ui/src/app/spells/page.tsx | 19 +++++++ ui/src/components/SpellModal.tsx | 97 +++++++++++++++++--------------- 3 files changed, 73 insertions(+), 86 deletions(-) diff --git a/service/src/db/spells/types.rs b/service/src/db/spells/types.rs index 72492cc..9c9d9a2 100644 --- a/service/src/db/spells/types.rs +++ b/service/src/db/spells/types.rs @@ -177,54 +177,13 @@ pub struct Range { #[derive(Debug, Serialize, Deserialize)] pub struct Area { #[serde(rename = "type")] - pub area_type: AreaType, + pub area_type: String, #[serde(skip_serializing_if = "Option::is_none")] pub value: Option, #[serde(skip_serializing_if = "Option::is_none")] pub unit: Option } -#[derive(Debug, Serialize, Deserialize)] -pub enum AreaType { - #[serde(rename = "cone")] - Cone, - #[serde(rename = "cube")] - Cube, - #[serde(rename = "cylinder")] - Cylinder, - #[serde(rename = "line")] - Line, - #[serde(rename = "sphere")] - Sphere -} - -// impl AreaType { -// pub fn to_string(&self) -> String { -// match self { -// AreaType::Cone => "cone".to_string(), -// AreaType::Cube => "cube".to_string(), -// AreaType::Cylinder => "cylinder".to_string(), -// AreaType::Line => "line".to_string(), -// AreaType::Sphere => "sphere".to_string() -// } -// } -// } - -// impl FromStr for AreaType { -// type Err = (); - -// fn from_str(s: &str) -> Result { -// match s { -// "cone" => Ok(AreaType::Cone), -// "cube" => Ok(AreaType::Cube), -// "cylinder" => Ok(AreaType::Cylinder), -// "line" => Ok(AreaType::Line), -// "sphere" => Ok(AreaType::Sphere), -// _ => Err(()) -// } -// } -// } - #[derive(Debug, Serialize, Deserialize)] pub struct Duration { #[serde(rename = "type")] diff --git a/ui/src/app/spells/page.tsx b/ui/src/app/spells/page.tsx index ec80cea..ae12099 100644 --- a/ui/src/app/spells/page.tsx +++ b/ui/src/app/spells/page.tsx @@ -22,6 +22,16 @@ export default function Page() { const [activeSpell, setActiveSpell] = useState(undefined); const [isOpen, setIsOpen] = useState(false); const [searchName, setSearchName] = useState(''); + const [includeCantrips, setIncludeCantrips] = useState(true); + const [includeLevel1, setIncludeLevel1] = useState(true); + const [includeLevel2, setIncludeLevel2] = useState(true); + const [includeLevel3, setIncludeLevel3] = useState(true); + const [includeLevel4, setIncludeLevel4] = useState(true); + const [includeLevel5, setIncludeLevel5] = useState(true); + const [includeLevel6, setIncludeLevel6] = useState(true); + const [includeLevel7, setIncludeLevel7] = useState(true); + const [includeLevel8, setIncludeLevel8] = useState(true); + const [includeLevel9, setIncludeLevel9] = useState(true); useEffect(() => { getSpells({ levels: [0] }).then((s) => setCantrips(s.data)); @@ -54,6 +64,15 @@ export default function Page() { }} />
+ s.name.toLowerCase().includes(searchName.toLowerCase()))} + onClick={(spell) => { + setActiveSpell(spell); + setIsOpen(true); + }} + /> +
{activeSpell && setIsOpen(false)} />} ); diff --git a/ui/src/components/SpellModal.tsx b/ui/src/components/SpellModal.tsx index 23e402b..2c28f2a 100644 --- a/ui/src/components/SpellModal.tsx +++ b/ui/src/components/SpellModal.tsx @@ -50,7 +50,7 @@ export default function SpellModal({ spell, isOpen, onClose }: SpellModalProps) {spell.classes.map((c) => ( - {capitalize(c)} + {parseText(c, true)} ))} @@ -86,65 +86,74 @@ export default function SpellModal({ spell, isOpen, onClose }: SpellModalProps) ); } -function SpellDescription({ spell }: { spell: Spell }) { - function parseText(text: string) { - const regex = /{@(.*?) (.*?)}/g; - const matches = text.matchAll(regex); - const result = []; - let lastIndex = 0; - for (const match of matches) { - const [full, type, name] = match; - result.push(text.slice(lastIndex, match.index)); - if (match.index !== undefined) { +function parseText(text: string, capitalizeFirst?: boolean) { + const regex = /{@(.*?) (.*?)}/g; + const matches = text.matchAll(regex); + const result = []; + let lastIndex = 0; + for (const match of matches) { + const [full, type, name] = match; + result.push(text.slice(lastIndex, match.index)); + if (match.index !== undefined) { + if (type == 'dice') { result.push( handleLink(type, name)} className='link'> {name} ); - lastIndex = match.index + full.length; + } else if (type == 'scaledice') { + // scaledice format is {@scaledice 1d6|1-9|1d6|}. Parse this out into dice, levels, and dice again. + const [dice, levels] = name.split('|'); + result.push( + handleLink('dice', dice)} className='link'> + {dice} + + ); + } else if (type == 'bold') { + result.push({name}); + } else if (type == 'subclass') { + const [className, subclassName] = name.split('|'); + result.push( + + {capitalize(className)} ({capitalize(subclassName)}) + + ); + } else { + result.push({capitalizeFirst ? capitalize(name) : name}); } + lastIndex = match.index + full.length; } - result.push(text.slice(lastIndex)); - return result; } + result.push(text.slice(lastIndex)); + return result; +} - function handleLink(type: string, name: string) { - if (type == 'spell') { - console.log(`Link to spell: ${name}`); - } else if (type == 'dice' || type == 'damage') { - const rolls = rollDice(name); - notifications.show({ - title: `Rolling ${name}`, - message: `${rolls.join(' + ')} = ${rolls.reduce((a, b) => a + b, 0)}`, - color: 'blue', - autoClose: 5000, - withCloseButton: false - }); - } else { - console.error(`Unknown link type: ${type}`); - } +function handleLink(type: string, name: string) { + if (type == 'spell') { + console.log(`Link to spell: ${name}`); + } else if (type == 'dice') { + const rolls = rollDice(name); + notifications.show({ + title: `Rolling ${name}`, + message: `${rolls.join(' + ')} = ${rolls.reduce((a, b) => a + b, 0)}`, + color: 'blue', + autoClose: 5000, + withCloseButton: false + }); + } else if (type == 'scaledice') { + console.log(`Link to scaledice: ${name}`); + } else { + console.error(`Unknown link type: ${type}`); } +} + +function SpellDescription({ spell }: { spell: Spell }) { return ( <> {spell.description && ( <> {spell.description.entries.map((e) => ( - // typeof e === 'string' ? ( - //

{parseText(e)}

- // ) : ( - // <> - // {e.list ? ( - //
    - // {e.list.map((text) => ( - //
  • {parseText(text)}
  • - // ))} - //
- // ) : ( - // <> - // )} - // - // ) <> {e.text &&

{parseText(e.text)}

} {e.list && (