Add name editing. Add icons for all buttons.

This commit is contained in:
sepia 2025-07-23 16:50:35 -05:00
parent 02d777c364
commit bc45f3a604
13 changed files with 253 additions and 12 deletions

4
public/icons/accept.svg Normal file
View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" />
</svg>

After

Width:  |  Height:  |  Size: 221 B

4
public/icons/decline.svg Normal file
View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>

After

Width:  |  Height:  |  Size: 220 B

4
public/icons/draw.svg Normal file
View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v17.25m0 0c-1.472 0-2.882.265-4.185.75M12 20.25c1.472 0 2.882.265 4.185.75M18.75 4.97A48.416 48.416 0 0 0 12 4.5c-2.291 0-4.545.16-6.75.47m13.5 0c1.01.143 2.01.317 3 .52m-3-.52 2.62 10.726c.122.499-.106 1.028-.589 1.202a5.988 5.988 0 0 1-2.031.352 5.988 5.988 0 0 1-2.031-.352c-.483-.174-.711-.703-.59-1.202L18.75 4.971Zm-16.5.52c.99-.203 1.99-.377 3-.52m0 0 2.62 10.726c.122.499-.106 1.028-.589 1.202a5.989 5.989 0 0 1-2.031.352 5.989 5.989 0 0 1-2.031-.352c-.483-.174-.711-.703-.59-1.202L5.25 4.971Z" />
</svg>

After

Width:  |  Height:  |  Size: 706 B

4
public/icons/resign.svg Normal file
View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 3v1.5M3 21v-6m0 0 2.77-.693a9 9 0 0 1 6.208.682l.108.054a9 9 0 0 0 6.086.71l3.114-.732a48.524 48.524 0 0 1-.005-10.499l-3.11.732a9 9 0 0 1-6.085-.711l-.108-.054a9 9 0 0 0-6.208-.682L3 4.5M3 15V4.5" />
</svg>

After

Width:  |  Height:  |  Size: 399 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="m15 15 6-6m0 0-6-6m6 6H9a6 6 0 0 0 0 12h3" />
</svg>

After

Width:  |  Height:  |  Size: 241 B

4
public/icons/undo.svg Normal file
View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3" />
</svg>

After

Width:  |  Height:  |  Size: 242 B

View file

@ -11,7 +11,7 @@ const playerId = playerIdMeta.content;
const wsUrl = `ws://${window.location.host}/ws?gameId=${gameId}&playerId=${playerId}`;
// Get the game container element
const gameContainer = document.getElementById('game-container');
const gameContainer = document.getElementById('ws-container');
// Set the ws-connect attribute
gameContainer.setAttribute('ws-connect', wsUrl);

View file

@ -0,0 +1,42 @@
document.addEventListener('DOMContentLoaded', () => {
const displayNameSpan = document.getElementById('display-name');
const editIcon = document.getElementById('edit-display-name-icon');
const editControls = document.getElementById('display-name-edit-controls');
const displayNameInput = document.getElementById('display-name-input');
const saveButton = document.getElementById('save-display-name-ws-button');
const cancelButton = document.getElementById('cancel-display-name-button');
// Get playerId from meta tag
const playerIdMeta = document.querySelector('meta[name="playerId"]');
const playerId = playerIdMeta ? playerIdMeta.content : 'UnknownPlayer';
// Initialize display name with player ID
displayNameSpan.textContent = playerId;
function setEditMode(isEditing) {
if (isEditing) {
displayNameSpan.style.display = 'none';
editIcon.style.display = 'none';
editControls.style.display = 'flex';
displayNameInput.value = displayNameSpan.textContent;
displayNameInput.focus();
} else {
displayNameSpan.style.display = 'inline';
editIcon.style.display = 'inline';
editControls.style.display = 'none';
}
}
editIcon.addEventListener('click', () => setEditMode(true));
cancelButton.addEventListener('click', () => setEditMode(false));
saveButton.addEventListener('click', () => {
// The actual sending of the message is handled by hx-trigger and send-ws-messages.js
// We just handle the optimistic UI update here.
const newName = displayNameInput.value.trim();
if (newName && newName !== displayNameSpan.textContent) {
displayNameSpan.textContent = newName; // Optimistically update display
}
setEditMode(false);
});
});

View file

@ -73,5 +73,11 @@ document.addEventListener('htmx:wsConfigSend', function (e) {
type: 'rematch',
action: 'cancel',
};
} else if (e.target.id == 'save-display-name-ws-button') {
const displayNameInput = document.getElementById('display-name-input');
e.detail.parameters = {
type: 'update_display_name',
displayName: displayNameInput ? displayNameInput.value.trim() : '',
};
}
});

View file

@ -273,3 +273,66 @@ button:hover {
#copy-link-button.copied-state {
background-color: var(--color-success);
}
.player-profile-box {
position: absolute;
top: 20px;
right: 20px;
display: flex;
align-items: center;
gap: 10px;
background-color: var(--color-neutral-100);
color: var(--color-on-light);
padding: 8px 12px;
border-radius: 20px;
box-shadow: 0 2px 4px var(--color-shadow);
}
.player-profile-box .edit-icon {
cursor: pointer;
width: 1.4em;
height: 1.4em;
opacity: 0.6;
transition: opacity 0.3s ease;
}
.player-profile-box .edit-icon:hover {
opacity: 1;
}
.player-profile-box #display-name-edit-controls {
display: flex;
gap: 5px;
align-items: center;
}
.player-profile-box #display-name-input {
border: 1px solid var(--color-neutral-300);
border-radius: 5px;
padding: 5px 8px;
font-size: 1em;
width: 120px;
}
.player-profile-box button {
background-color: var(--color-success);
color: var(--color-on-primary);
border: none;
border-radius: 5px;
padding: 5px 10px;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.3s ease;
}
.player-profile-box button:hover {
background-color: var(--color-success-light);
}
.player-profile-box button#cancel-display-name-button {
background-color: var(--color-error);
}
.player-profile-box button#cancel-display-name-button:hover {
background-color: var(--color-error-light);
}