diff --git a/index.html b/index.html index 6de1647..81b2f59 100644 --- a/index.html +++ b/index.html @@ -23,9 +23,10 @@
Disconnected
diff --git a/public/icons/clipboard-copy.svg b/public/icons/clipboard-copy.svg new file mode 100755 index 0000000..25b9ec7 --- /dev/null +++ b/public/icons/clipboard-copy.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/public/icons/copy-success.svg b/public/icons/copy-success.svg new file mode 100755 index 0000000..d81b72c --- /dev/null +++ b/public/icons/copy-success.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/public/icons/edit.svg b/public/icons/edit.svg new file mode 100755 index 0000000..15bfee2 --- /dev/null +++ b/public/icons/edit.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/public/icons/heart.svg b/public/icons/heart.svg new file mode 100755 index 0000000..611c11e --- /dev/null +++ b/public/icons/heart.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/public/scripts/copy-game-link.js b/public/scripts/copy-game-link.js index 6adcac4..1eaffc9 100644 --- a/public/scripts/copy-game-link.js +++ b/public/scripts/copy-game-link.js @@ -1,13 +1,30 @@ function copyGameLink() { - const gameLinkInput = document.getElementById('game-link'); - if (gameLinkInput) { - navigator.clipboard - .writeText(gameLinkInput.value) - .then(() => { - alert('Game link copied to clipboard!'); - }) - .catch((err) => { - console.error('Failed to copy link: ', err); - }); - } + const gameId = document.querySelector('meta[name="gameId"]').content; + const gameLink = `${window.location.origin}${window.location.pathname}?gameId=${gameId}`; + + navigator.clipboard.writeText(gameLink) + .then(() => { + const copyLinkButton = document.getElementById('copy-link-button'); + const copyLinkText = document.getElementById('copy-link-text'); + const originalIconSrc = '/icons/clipboard-copy.svg'; + const originalTextContent = 'Click to copy game link!'; + + if (window.copyButtonTimeoutId) { + clearTimeout(window.copyButtonTimeoutId); + } + + copyLinkButton.querySelector('img').src = '/icons/copy-success.svg'; + copyLinkText.textContent = 'Game link copied!'; + copyLinkButton.classList.add('copied-state'); + + window.copyButtonTimeoutId = setTimeout(() => { + copyLinkButton.querySelector('img').src = originalIconSrc; + copyLinkText.textContent = originalTextContent; + copyLinkButton.classList.remove('copied-state'); + window.copyButtonTimeoutId = null; + }, 3000); + }) + .catch(err => { + console.error('Failed to copy link: ', err); + }); } diff --git a/public/scripts/display-ws-connection.js b/public/scripts/display-ws-connection.js index 95ab2bc..e173b14 100644 --- a/public/scripts/display-ws-connection.js +++ b/public/scripts/display-ws-connection.js @@ -19,13 +19,6 @@ gameContainer.setAttribute('ws-connect', wsUrl); // Tell HTMX to connect the WebSocket htmx.trigger(gameContainer, ' and connect'); -// Update the game link input -const gameLinkInput = document.getElementById('game-link'); -if (!gameLinkInput) { - console.error('Missing game-link element.'); -} -gameLinkInput.value = - window.location.origin + window.location.pathname + `?gameId=${gameId}`; // Update the WebSocket status indicator const wsStatusDiv = document.getElementById('ws-status'); diff --git a/public/style.css b/public/style.css index b131f99..c39e1c0 100644 --- a/public/style.css +++ b/public/style.css @@ -9,6 +9,9 @@ --color-intersection-hover: rgba(255, 192, 203, 0.3); --color-heart-pink: #FFB6C1; --color-last-move-glow: rgba(255, 255, 0, 0.7); + --color-black: #000; + --color-white: #fff; + --color-success-purple: #e0b0ff; } body { @@ -33,14 +36,13 @@ body { .game-board-grid { position: relative; - width: calc(14 * 30px); /* 14 gaps of 30px between 15 lines */ - height: calc(14 * 30px); /* 14 gaps of 30px between 15 lines */ + width: calc(14 * 30px); + height: calc(14 * 30px); margin-top: 20px; background-color: var(--color-board-bg); border: 2px solid var(--color-board-border); } -/* Grid lines */ .game-board-grid::before { content: ''; position: absolute; @@ -73,7 +75,6 @@ body { background-color: var(--color-intersection-hover); } -/* Heart Stone Styling */ .stone-black-heart, .stone-white-heart { position: relative; width: 24px; @@ -91,7 +92,7 @@ body { width: 12px; height: 20px; border-radius: 50% 50% 0 0; - border: 1px solid var(--color-black); /* Thin black outline - this creates the line through the middle */ + border: 1px solid var(--color-black); box-sizing: border-box; transform: rotate(-45deg); transform-origin: 0 100%; @@ -114,17 +115,65 @@ body { background-color: var(--color-white); } - .last-move { box-shadow: 0 0 5px 3px var(--color-last-move-glow); } + #messages { margin-top: 10px; font-size: 0.9em; color: var(--color-text-dark); } + #player-info { margin-top: 10px; font-weight: bold; color: var(--color-text-dark); } + +#game-link-container { + position: relative; + display: flex; + justify-content: center; + align-items: center; + height: 40px; + margin-top: 20px; +} + +#copy-link-button, +#copy-success-message { + position: absolute; + left: 50%; + transform: translateX(-50%); + display: flex; + justify-content: center; + align-items: center; + top: 0; bottom: 0; + transition: opacity 0.3s ease; + padding: 8px 15px; + border-radius: 5px; + white-space: nowrap; + box-sizing: border-box; +} + +#copy-link-button { + background-color: var(--color-board-border); + color: var(--color-text-dark); + border: none; + cursor: pointer; + gap: 8px; + font-size: 1em; +} + +#copy-link-button:hover { + background-color: var(--color-grid-lines); +} + +#copy-link-button.copied-state { + background-color: var(--color-success-purple); +} + +#copy-link-button img.icon { + width: 20px; + height: 20px; +}