diff options
-rw-r--r-- | public/common/client.js | 42 | ||||
-rw-r--r-- | public/common/grid.css | 281 |
2 files changed, 186 insertions, 137 deletions
diff --git a/public/common/client.js b/public/common/client.js index cf23ee4..01b6c05 100644 --- a/public/common/client.js +++ b/public/common/client.js @@ -116,6 +116,22 @@ function stop_blinker() { window.addEventListener("focus", stop_blinker); function load_chat() { + let chat_window = document.createElement("div"); + chat_window.id = "chat_window"; + chat_window.innerHTML = ` + <div id="chat_header">Chat</div> + <div id="chat_text"></div> + <form id="chat_form" action=""><input id="chat_input" autocomplete="off"></form> + `; + document.querySelector("body").appendChild(chat_window); + + let chat_button = document.createElement("div"); + chat_button.id = "chat_button"; + chat_button.className = "icon_button"; + chat_button.innerHTML = '<img src="/images/chat-bubble.svg">'; + chat_button.addEventListener("click", toggle_chat); + document.querySelector("header").insertBefore(chat_button, document.getElementById("prompt")); + chat_key = "chat/" + param_game_id; chat_text = document.getElementById("chat_text"); chat_last_day = null; @@ -202,14 +218,14 @@ function init_client(roles) { socket.on('connect', () => { console.log("CONNECTED"); - document.getElementById("grid_top").classList.remove('disconnected'); + document.querySelector("header").classList.remove('disconnected'); socket.emit('getchat', chat_log); // only send new messages when we reconnect! }); socket.on('disconnect', () => { console.log("DISCONNECTED"); document.getElementById("prompt").textContent = "Disconnected from server!"; - document.getElementById("grid_top").classList.add('disconnected'); + document.querySelector("header").classList.add('disconnected'); }); socket.on('roles', (me, players) => { @@ -298,12 +314,12 @@ let old_active = null; function on_update_bar() { document.getElementById("prompt").textContent = game.prompt; if (game.actions) { - document.getElementById("grid_top").classList.add("your_turn"); + document.querySelector("header").classList.add("your_turn"); if (!is_your_turn || old_active !== game.active) start_blinker("YOUR TURN"); is_your_turn = true; } else { - document.getElementById("grid_top").classList.remove("your_turn"); + document.querySelector("header").classList.remove("your_turn"); is_your_turn = false; } old_active = game.active; @@ -370,7 +386,7 @@ function toggle_chat() { } function zoom_map() { - let grid = document.getElementById("grid_center"); + let grid = document.querySelector("main"); let mapwrap = document.getElementById("mapwrap"); let map = document.getElementById("map"); map.style.transform = null; @@ -411,16 +427,24 @@ function init_shift_zoom() { } function toggle_log() { - document.getElementById("grid_window").classList.toggle("hide_log"); + document.querySelector("aside").classList.toggle("hide"); zoom_map(); } -function show_action_button(sel, action, use_label = false) { - let button = document.querySelector(sel); +function action_button(action, label) { + let id = action + "_button"; + let button = document.getElementById(id); + if (!button) { + button = document.createElement("button"); + button.id = id; + button.textContent = label; + button.addEventListener("click", evt => send_action(action)); + document.getElementById("actions").appendChild(button); + } if (game.actions && action in game.actions) { button.classList.remove("hide"); if (game.actions[action]) { - if (use_label) + if (label === undefined) button.textContent = game.actions[action]; button.disabled = false; } else { diff --git a/public/common/grid.css b/public/common/grid.css index 61edd18..47bc6b1 100644 --- a/public/common/grid.css +++ b/public/common/grid.css @@ -13,130 +13,110 @@ html, button, input, select { font-family: "Source Serif", "Circled Numbers", "Dingbats", "Noto Emoji", "Georgia", serif; } -#log { +#log, #turn_info { font-family: "Source Serif SmText", "Circled Numbers", "Dingbats", "Noto Emoji", "Georgia", serif; } -body:not(.shift) .debug { +.hide { display: none; } -html, body, div { - margin: 0; - padding: 0; +body:not(.shift) .debug { + display: none; } -html { - overflow: clip; +body.Observer .resign { + display: none; } -#status { - position:absolute; - z-index: 100; - left: 0; - bottom: 0; - background-color: white; - padding: 0 1ex; +button { + font-size: 1rem; + margin: 0; + padding: 1px 12px; + background-color: gainsboro; +} +button:disabled { + color: gray; + border: 2px solid gainsboro; + outline: 1px solid gray; +} +button:enabled { + border: 2px outset white; + outline: 1px solid black; +} +button:enabled:active:hover { + border: 2px inset white; + padding: 2px 11px 0px 13px; } -#grid_window { +/* MAIN GRID */ + +body { + margin: 0; + padding: 0; display: grid; + overflow: clip; grid-template-columns: 1fr min-content; - grid-template-rows: min-content min-content 1fr; - gap: 0px; + grid-template-rows: min-content 1fr; width: 100vw; height: 100vh; } -#grid_window.hide_log #grid_role { - display: none; +header { + grid-column: 1/3; + grid-row: 1; + display: flex; + align-items: center; + border-bottom: 1px solid black; } -#grid_window.hide_log #log { - display: none; + +header.disconnected { + background-color: red !important; +} + +header.your_turn { + background-color: orange; } -#grid_center { +main { grid-column: 1; - grid-row: 2/4; + grid-row: 2; overflow: auto; scrollbar-width: none; } -#grid_role { +aside { grid-column: 2; grid-row: 2; - border-left: 1px solid black; - width: 209px; -} - -.role_name { - padding-top: 3px; - padding-bottom: 3px; - padding-left: 5px; - padding-right: 5px; - border-bottom: 1px solid black; -} - -.role_vp { - float: right; -} - -.role_user { - font-style: italic; - text-align: right; + display: grid; overflow: clip; - text-overflow: "..."; - white-space: nowrap; -} - -.role .role_name::before { content: "\25cb "; opacity: 0.6; } -.role.present .role_name::before { content: "\25cf "; opacity: 0.6; } - -.role_info { - border-bottom: 1px solid black; - overflow: clip; /* clip dropshadow from filter:grayscale() stacking context */ + grid-template-rows: min-content 1fr; + width: 209px; + border-left: 1px solid black; } -#turn_info { - padding: 8px 0px 8px 8px; - border-bottom: 1px solid black; - white-space: pre-line; - font-style: italic; - font-size: 12px; - line-height: 18px; - font-family: "Source Serif SmText"; +#roles { + grid-column: 1; + grid-row: 1; } #log { - grid-column: 2; - grid-row: 3; - border-left: 1px solid black; + grid-column: 1; + grid-row: 2; overflow-y: scroll; scrollbar-width: thin; - padding: 12px 0; - font-size: 12px; - line-height: 18px; - white-space: pre-wrap; } -#log > * { - padding-left: 20px; - padding-right: 4px; - text-indent: -12px; - min-height: 9px; +footer { + position:absolute; + z-index: 100; + left: 0; + bottom: 0; + background-color: white; + padding: 0 1ex; } -#grid_top { - grid-column: 1/3; - grid-row: 1; - display: flex; - align-items: center; - border-bottom: 1px solid black; -} - -#grid_top.disconnected { - background-color: red !important; -} +/* MENU */ .menu { user-select: none; @@ -176,32 +156,27 @@ html { color: white; } -body.Observer .menu .resign { - display: none; -} +/* TOOL BAR */ -.image_button { +.icon_button { user-select: none; } -.image_button img { +.icon_button img { display: block; height: 35px; padding: 5px; } -.image_button:hover { +.icon_button:hover { background-color: black; color: white; } -.image_button:hover img { +.icon_button:hover img { filter: invert(100%); } -#grid_top button { +header button { margin: 0 10px; } -#grid_top .hide { - display: none; -} #prompt { margin: 0 50px; @@ -209,6 +184,79 @@ body.Observer .menu .resign { flex-grow: 1; } +/* ROLES */ + +.role_name { + border-bottom: 1px solid black; + padding-top: 3px; + padding-bottom: 3px; + padding-left: 5px; + padding-right: 5px; +} + +.role_info, .card_info, #turn_info { + border-bottom: 1px solid black; + overflow: clip; /* clip dropshadow from filter:grayscale() stacking context */ +} + +.role_vp { + float: right; +} + +.role_user { + font-style: italic; + text-align: right; + overflow: clip; + text-overflow: "..."; + white-space: nowrap; +} + +.role .role_name::before { content: "\25cb "; opacity: 0.6; } +.role.present .role_name::before { content: "\25cf "; opacity: 0.6; } + +#turn_info { + padding: 8px 0px 8px 8px; + white-space: pre-line; + font-style: italic; + font-size: 12px; + line-height: 18px; +} + +/* LOG */ + +#log { + padding: 12px 0; + font-size: 12px; + line-height: 18px; + white-space: pre-wrap; +} + +#log > * { + padding-left: 20px; + padding-right: 4px; + text-indent: -12px; + min-height: 9px; +} + +/* MAP */ + +#mapwrap { + position: relative; + margin: 0 auto; +} + +#mapwrap.fit { + max-width: 100%; +} + +#map { + position: absolute; + isolation: isolate; + transform-origin: 0 0; +} + +/* CARDS */ + .hand { margin: 15px; display: flex; @@ -225,12 +273,15 @@ body.Observer .menu .resign { box-shadow: 1px 1px 5px rgba(0,0,0,0.5); display: none; } + .card.show { display: block; } + .card.enabled { cursor: pointer; } + .card.disabled { filter: grayscale(100%); } @@ -243,44 +294,12 @@ body.Observer .menu .resign { box-shadow: 1px 1px 5px rgba(0,0,0,0.5); } -#mapwrap { - margin: 0 auto; -} - -#mapwrap.fit { - max-width: 100%; -} - -#map { - isolation:isolate; - transform-origin: 0 0; -} - -button { - font-size: 1rem; - margin: 0; - padding: 1px 12px; - background-color: gainsboro; -} -button:disabled { - color: gray; - border: 2px solid gainsboro; - outline: 1px solid gray; -} -button:enabled { - border: 2px outset white; - outline: 1px solid black; -} -button:enabled:active:hover { - border: 2px inset white; - padding: 2px 11px 0px 13px; -} - /* CHAT WINDOW */ #chat_button.new { filter: invert(100%); } + #chat_window { position: absolute; left: 10px; @@ -294,15 +313,18 @@ button:enabled:active:hover { display: grid; grid-template-rows: min-content 1fr min-content; } + #chat_window.show { visibility: visible; } + #chat_header { cursor: move; background-color: gainsboro; border-bottom: 1px solid black; padding: 5px 10px; } + #chat_text { font-size: 16px; line-height: 24px; @@ -310,15 +332,18 @@ button:enabled:active:hover { padding: 0px 5px; overflow-y: scroll; } + #chat_text .date { font-weight: bold; } + #chat_form { display: block; margin: 0; padding: 0; border-top: 1px solid black; } + #chat_input { box-sizing: border-box; width: 100%; |