From 020dfcda00ca06b9a06e7076eaf8a0164ae1327e Mon Sep 17 00:00:00 2001 From: David Skoland Date: Tue, 10 Feb 2026 23:38:17 +0100 Subject: Refactor playerlist to state-driven rendering with renderPlayerList handlePR and handlePU now only update client.playerlist state, and renderPlayerList handles all DOM rendering from that state. Co-Authored-By: Claude Opus 4.6 --- webAO/dom/renderPlayerList.ts | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 webAO/dom/renderPlayerList.ts (limited to 'webAO/dom/renderPlayerList.ts') diff --git a/webAO/dom/renderPlayerList.ts b/webAO/dom/renderPlayerList.ts new file mode 100644 index 0000000..43dab64 --- /dev/null +++ b/webAO/dom/renderPlayerList.ts @@ -0,0 +1,50 @@ +import { client } from "../client"; +import { AO_HOST } from "../client/aoHost"; + +export function renderPlayerList() { + const list = document.getElementById("client_playerlist") as HTMLTableElement; + list.innerHTML = ""; + + for (const [playerID, player] of client.playerlist) { + const playerRow = list.insertRow(); + playerRow.id = `client_playerlist_entry${playerID}`; + + const imgCell = playerRow.insertCell(0); + imgCell.style.width = "64px"; + const img = document.createElement("img"); + if (player.charId >= 0) { + const char = client.chars[player.charId]; + if (char) { + const iconExt = client.charicon_extensions[0] || ".png"; + img.src = `${AO_HOST}characters/${encodeURI(char.name.toLowerCase())}/char_icon${iconExt}`; + img.alt = char.name; + img.title = char.name; + } + } + imgCell.appendChild(img); + + const charNameCell = playerRow.insertCell(1); + charNameCell.textContent = + player.charId >= 0 ? `[${playerID}] ${player.charName}` : ""; + + const showNameCell = playerRow.insertCell(2); + showNameCell.textContent = player.showName; + + const oocNameCell = playerRow.insertCell(3); + oocNameCell.textContent = player.name; + + const kickCell = playerRow.insertCell(4); + kickCell.style.width = "64px"; + const kick = document.createElement("button"); + kick.innerText = "Kick"; + kick.onclick = () => window.kickPlayer(playerID); + kickCell.appendChild(kick); + + const banCell = playerRow.insertCell(5); + banCell.style.width = "64px"; + const ban = document.createElement("button"); + ban.innerText = "Ban"; + ban.onclick = () => window.banPlayer(playerID); + banCell.appendChild(ban); + } +} -- cgit From 9993c378613b20b6f6f74b324c22c3bfda4c71fc Mon Sep 17 00:00:00 2001 From: David Skoland Date: Tue, 10 Feb 2026 23:59:48 +0100 Subject: Use charName directly for playerlist rendering and add table styling Render char icons and names from the character name string (PU type 1) instead of gating on charId lookup. Add header row and row separators to the playerlist table. Co-Authored-By: Claude Opus 4.6 --- webAO/dom/renderPlayerList.ts | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'webAO/dom/renderPlayerList.ts') diff --git a/webAO/dom/renderPlayerList.ts b/webAO/dom/renderPlayerList.ts index 43dab64..d0f08c6 100644 --- a/webAO/dom/renderPlayerList.ts +++ b/webAO/dom/renderPlayerList.ts @@ -5,27 +5,32 @@ export function renderPlayerList() { const list = document.getElementById("client_playerlist") as HTMLTableElement; list.innerHTML = ""; + const header = list.createTHead().insertRow(); + for (const label of ["Icon", "Character", "Showname", "OOC Name"]) { + const th = document.createElement("th"); + th.textContent = label; + header.appendChild(th); + } + + const body = list.createTBody(); for (const [playerID, player] of client.playerlist) { - const playerRow = list.insertRow(); + const playerRow = body.insertRow(); playerRow.id = `client_playerlist_entry${playerID}`; const imgCell = playerRow.insertCell(0); imgCell.style.width = "64px"; const img = document.createElement("img"); - if (player.charId >= 0) { - const char = client.chars[player.charId]; - if (char) { - const iconExt = client.charicon_extensions[0] || ".png"; - img.src = `${AO_HOST}characters/${encodeURI(char.name.toLowerCase())}/char_icon${iconExt}`; - img.alt = char.name; - img.title = char.name; - } + if (player.charName) { + const iconExt = client.charicon_extensions[0] || ".png"; + img.src = `${AO_HOST}characters/${encodeURI(player.charName.toLowerCase())}/char_icon${iconExt}`; + img.alt = player.charName; + img.title = player.charName; } imgCell.appendChild(img); const charNameCell = playerRow.insertCell(1); charNameCell.textContent = - player.charId >= 0 ? `[${playerID}] ${player.charName}` : ""; + player.charName ? `[${playerID}] ${player.charName}` : ""; const showNameCell = playerRow.insertCell(2); showNameCell.textContent = player.showName; -- cgit From 6314a7e61ad85aaf9313ed2947853e8e1d2aea33 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 11 Feb 2026 00:05:04 +0100 Subject: Add area column to playerlist Co-Authored-By: Claude Opus 4.6 --- webAO/dom/renderPlayerList.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'webAO/dom/renderPlayerList.ts') diff --git a/webAO/dom/renderPlayerList.ts b/webAO/dom/renderPlayerList.ts index d0f08c6..a78851b 100644 --- a/webAO/dom/renderPlayerList.ts +++ b/webAO/dom/renderPlayerList.ts @@ -6,7 +6,7 @@ export function renderPlayerList() { list.innerHTML = ""; const header = list.createTHead().insertRow(); - for (const label of ["Icon", "Character", "Showname", "OOC Name"]) { + for (const label of ["Icon", "Character", "Showname", "OOC Name", "Area"]) { const th = document.createElement("th"); th.textContent = label; header.appendChild(th); @@ -38,14 +38,17 @@ export function renderPlayerList() { const oocNameCell = playerRow.insertCell(3); oocNameCell.textContent = player.name; - const kickCell = playerRow.insertCell(4); + const areaCell = playerRow.insertCell(4); + areaCell.textContent = String(player.area); + + const kickCell = playerRow.insertCell(5); kickCell.style.width = "64px"; const kick = document.createElement("button"); kick.innerText = "Kick"; kick.onclick = () => window.kickPlayer(playerID); kickCell.appendChild(kick); - const banCell = playerRow.insertCell(5); + const banCell = playerRow.insertCell(6); banCell.style.width = "64px"; const ban = document.createElement("button"); ban.innerText = "Ban"; -- cgit From c380112d5f29b68bfa301527405fdf372835900e Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 11 Feb 2026 00:10:05 +0100 Subject: Filter playerlist by area and remove Area column Hide players not in the client's current area. Re-render playerlist on area switch. Remove the now-redundant Area column. Co-Authored-By: Claude Opus 4.6 --- webAO/dom/renderPlayerList.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'webAO/dom/renderPlayerList.ts') diff --git a/webAO/dom/renderPlayerList.ts b/webAO/dom/renderPlayerList.ts index a78851b..a382194 100644 --- a/webAO/dom/renderPlayerList.ts +++ b/webAO/dom/renderPlayerList.ts @@ -6,7 +6,7 @@ export function renderPlayerList() { list.innerHTML = ""; const header = list.createTHead().insertRow(); - for (const label of ["Icon", "Character", "Showname", "OOC Name", "Area"]) { + for (const label of ["Icon", "Character", "Showname", "OOC Name"]) { const th = document.createElement("th"); th.textContent = label; header.appendChild(th); @@ -16,6 +16,7 @@ export function renderPlayerList() { for (const [playerID, player] of client.playerlist) { const playerRow = body.insertRow(); playerRow.id = `client_playerlist_entry${playerID}`; + playerRow.style.display = player.area === client.area ? "" : "none"; const imgCell = playerRow.insertCell(0); imgCell.style.width = "64px"; @@ -38,17 +39,14 @@ export function renderPlayerList() { const oocNameCell = playerRow.insertCell(3); oocNameCell.textContent = player.name; - const areaCell = playerRow.insertCell(4); - areaCell.textContent = String(player.area); - - const kickCell = playerRow.insertCell(5); + const kickCell = playerRow.insertCell(4); kickCell.style.width = "64px"; const kick = document.createElement("button"); kick.innerText = "Kick"; kick.onclick = () => window.kickPlayer(playerID); kickCell.appendChild(kick); - const banCell = playerRow.insertCell(6); + const banCell = playerRow.insertCell(5); banCell.style.width = "64px"; const ban = document.createElement("button"); ban.innerText = "Ban"; -- cgit From 5bb35a981e2f35df7fbf126faa8655ee3b3ca142 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 11 Feb 2026 00:12:51 +0100 Subject: Clamp playerlist char icons to 60x60 pixels Co-Authored-By: Claude Opus 4.6 --- webAO/dom/renderPlayerList.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'webAO/dom/renderPlayerList.ts') diff --git a/webAO/dom/renderPlayerList.ts b/webAO/dom/renderPlayerList.ts index a382194..48354ae 100644 --- a/webAO/dom/renderPlayerList.ts +++ b/webAO/dom/renderPlayerList.ts @@ -21,6 +21,8 @@ export function renderPlayerList() { const imgCell = playerRow.insertCell(0); imgCell.style.width = "64px"; const img = document.createElement("img"); + img.style.maxWidth = "60px"; + img.style.maxHeight = "60px"; if (player.charName) { const iconExt = client.charicon_extensions[0] || ".png"; img.src = `${AO_HOST}characters/${encodeURI(player.charName.toLowerCase())}/char_icon${iconExt}`; -- cgit