diff options
| -rwxr-xr-x | backend/server.py | 9 | ||||
| -rw-r--r-- | src/components/Tile.vue | 10 | ||||
| -rw-r--r-- | src/components/TileInfoModal.vue | 10 | ||||
| -rw-r--r-- | src/tol.ts | 2 | ||||
| -rw-r--r-- | src/util.ts | 5 |
5 files changed, 32 insertions, 4 deletions
diff --git a/backend/server.py b/backend/server.py index c1e5538..c8567ab 100755 --- a/backend/server.py +++ b/backend/server.py @@ -30,6 +30,7 @@ dbCon.load_extension('./data/spellfix') def lookupNodes(names): nodeObjs = {} cur = dbCon.cursor() + # Get node info query = "SELECT name, children, parent, tips, p_support FROM nodes WHERE" \ " name IN ({})".format(",".join(["?"] * len(names))) for row in cur.execute(query, names): @@ -39,6 +40,7 @@ def lookupNodes(names): "parent": None if row[2] == "" else row[2], "tips": row[3], "pSupport": True if row[4] == 1 else False, + "commonName": None, } # Check for image file match = re.fullmatch(r"\[(.+) \+ (.+)]", name) @@ -50,6 +52,13 @@ def lookupNodes(names): nodeObj["imgName"] = getNodeImg(match.group(2)) # Add node object nodeObjs[name] = nodeObj + # Get preferred-name info + query = "SELECT name, alt_name FROM names WHERE pref_alt = 1 AND" \ + " name IN ({})".format(",".join(["?"] * len(names))) + for row in cur.execute(query, names): + [name, altName] = row + nodeObjs[name]["commonName"] = altName + # return nodeObjs def getNodeImg(name): cur = dbCon.cursor() diff --git a/src/components/Tile.vue b/src/components/Tile.vue index 744adc3..f656b09 100644 --- a/src/components/Tile.vue +++ b/src/components/Tile.vue @@ -5,6 +5,7 @@ import {LayoutNode} from '../layout'; import type {LayoutOptions} from '../layout'; import type {TolMap} from '../tol'; import {TolNode} from '../tol'; +import {capitalizeWords} from '../util'; // Displays one, or a hierarchy of, tree-of-life nodes, as a 'tile' export default defineComponent({ @@ -42,6 +43,9 @@ export default defineComponent({ return (this.layoutNode.showHeader && this.layoutNode.sepSweptArea == null) || (this.layoutNode.sepSweptArea != null && this.layoutNode.sepSweptArea.sweptLeft); }, + displayName(): string { + return capitalizeWords(this.tolNode.commonName || this.layoutNode.name); + }, // Style related nonleafBgColor(): string { let colorArray = this.uiOpts.nonleafBgColors; @@ -316,7 +320,7 @@ export default defineComponent({ <div v-if="isLeaf" :style="leafStyles" class="w-full h-full flex flex-col overflow-hidden" :class="{'hover:cursor-pointer': isExpandableLeaf}" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" @mousedown="onMouseDown" @mouseup="onMouseUp"> - <h1 :style="leafHeaderStyles" class="capitalize">{{layoutNode.name}}</h1> + <h1 :style="leafHeaderStyles">{{displayName}}</h1> <info-icon :style="[infoIconStyles, {marginTop: 'auto'}]" class="self-end text-white/10 hover:text-white hover:cursor-pointer" @click.stop="onInfoIconClick" @mousedown.stop @mouseup.stop/> @@ -324,7 +328,7 @@ export default defineComponent({ <div v-else :style="nonleafStyles" class="w-full h-full" ref="nonleaf"> <div v-if="showNonleafHeader" :style="nonleafHeaderStyles" class="flex hover:cursor-pointer" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" @mousedown="onMouseDown" @mouseup="onMouseUp"> - <h1 :style="nonleafHeaderTextStyles" class="grow capitalize">{{layoutNode.name}}</h1> + <h1 :style="nonleafHeaderTextStyles" class="grow">{{displayName}}</h1> <info-icon :style="infoIconStyles" class="text-white/10 hover:text-white hover:cursor-pointer" @click.stop="onInfoIconClick" @mousedown.stop @mouseup.stop/> </div> @@ -333,7 +337,7 @@ export default defineComponent({ <div v-if="layoutNode?.sepSweptArea?.sweptLeft === false" :style="nonleafHeaderStyles" class="flex hover:cursor-pointer" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave" @mousedown="onMouseDown" @mouseup="onMouseUp"> - <h1 :style="nonleafHeaderTextStyles" class="grow capitalize">{{layoutNode.name}}</h1> + <h1 :style="nonleafHeaderTextStyles" class="grow">{{displayName}}</h1> <info-icon :style="infoIconStyles" class="text-white/10 hover:text-white hover:cursor-pointer" @click.stop="onInfoIconClick" @mousedown.stop @mouseup.stop/> </div> diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue index 7cd75b7..275dd08 100644 --- a/src/components/TileInfoModal.vue +++ b/src/components/TileInfoModal.vue @@ -4,6 +4,7 @@ import CloseIcon from './icon/CloseIcon.vue'; import {LayoutNode} from '../layout'; import type {TolMap} from '../tol'; import {TolNode} from '../tol'; +import {capitalizeWords} from '../util'; // Displays information about a tree-of-life node export default defineComponent({ @@ -23,6 +24,13 @@ export default defineComponent({ tolNode(): TolNode { return this.tolMap.get(this.node.name)!; }, + displayName(): string { + if (this.tolNode.commonName == null){ + return capitalizeWords(this.node.name); + } else { + return `${capitalizeWords(this.tolNode.commonName)} (aka ${capitalizeWords(this.node.name)})`; + } + }, imgStyles(): Record<string,string> { return { backgroundImage: this.tolNode.imgName != null ? @@ -71,7 +79,7 @@ export default defineComponent({ bg-stone-50 rounded-md shadow shadow-black"> <close-icon @click.stop="onCloseClick" ref="closeIcon" class="block absolute top-2 right-2 w-6 h-6 hover:cursor-pointer"/> - <h1 class="text-center text-xl font-bold mb-2 capitalize">{{node.name}}</h1> + <h1 class="text-center text-xl font-bold mb-2">{{displayName}}</h1> <hr class="mb-4 border-stone-400"/> <div class="flex"> <div> @@ -11,11 +11,13 @@ export class TolNode { tips: number; pSupport: boolean; imgName: null | string; + commonName: null | string; constructor(children: string[] = [], parent = null, tips = 0, pSupport = false){ this.children = children; this.parent = parent; this.tips = tips; this.pSupport = pSupport; this.imgName = null; + this.commonName = null; } } diff --git a/src/util.ts b/src/util.ts index a698d23..78b7870 100644 --- a/src/util.ts +++ b/src/util.ts @@ -97,3 +97,8 @@ export function randWeightedChoice(weights: number[]): number | null { } return null; } +// Returns a string with words first-letter capitalised +export function capitalizeWords(str: string){ + return str.replace(/\b\w/g, x => x.toUpperCase()); + // '\b' matches word boundary, '\w' is like [a-zA-Z0-9_], +} |
