Make the inline Event Log collapsible and viewport-bounded (v7)
Two scene-layout tweaks to the inline (third-column) Event Log: - It can now be collapsed to a fixed corner button (✕ in its header) to declutter, and reopened from that button. ScenePhase owns `logOpen` and reflows the grid to two columns while collapsed; EventLog dispatches `collapse`. - The panel now pins at top:3.5rem (matching .dashboard-container's top padding) with max-height calc(100vh - 4.5rem), so its bottom stays on-screen at any scroll position and .log-content scrolls internally — previously the bottom sat ~24px below the fold at the top of the page. Verified across Pi-Rat and Deep views, scroll extremes, and 3-col / 1-col widths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
33
TODO.md
33
TODO.md
@@ -1,27 +1,18 @@
|
||||
## Simple Tasks
|
||||
## Polish
|
||||
|
||||
- [x] **Event log items**. Completing a crew objective should go in the event log
|
||||
- [x] **Personal objectives for pi-rats** Mousing over a personal objective as a pi-rat should not make the cursor change, as it's a non-interactive UI element for them
|
||||
- [x] **PvP challenge tooltips** Update the PvP challenge card selection dropdown tooltips so that they describe the general class of obstacles for the suit rather than the specific challenge for that card. This also goes for the temporary obstacles created by PvP challenges.
|
||||
- [x] **Secret technique tooltips** The tooltip for a played secret technique should include the full secret technique description, since it gets truncated in the main display.
|
||||
- [x] **Character sheet layout** Personal objectives should be on a second column to the right, on screen layouts wide enough to accommodate it
|
||||
- [x] **Event log layout**. The event log should still be collapsable into a corner button to give the player the option to declutter their screen. On screens big enough for three column layouts, since the event log has an internal scrolling area, make sure that the outer panel never extends past the bottom of the screen, so that the bottom of the log stays visible no matter what.
|
||||
- [ ] **Crew roster text illegible on dark mode**. The text on the crew roster bubbles is black-on-dark in dark mode. The roster items probably need some re-styling on both dark and light mode, because their background being barely different from the page background doesn't look great.
|
||||
- [ ] **Enforce End-Scene requirements** Unless dev mode is turned on, enforce that the scene cannot end unless every pi-rat has been challenged at least once or the obstacle list is empty. Leave enforcement of "had a chance to complete objective" to table talk. The Deep should probably see some kind of UI informing them which Pi-Rats have already been challenged. Maybe a checkmark floating outside their bubble to the left with a tooltip on mouseover that explains what it means.
|
||||
- [ ] **Declutter the Hand panel** The hand panel definitely doesn't need the explanatory text, and probably doesn't need the title either, though if there's some low profile, low-noise visual way to communicate "this is your hand", that wouldn't be a bad idea.
|
||||
|
||||
## DevOps/Maintenance
|
||||
|
||||
- [ ] **Logging**: Add some logging to the backend. The Nix service should log to /var/log/pirats.log. The current greatest need is diagnosing server crashes.
|
||||
- [ ] **Logging**: Add some logging to the backend. The Nix service should log to /var/log/pirats.log by default (but be configurable). At very least, stderr should go there, plus important server-side events, like:
|
||||
- [ ] **Purge old finished/inactive games**: Add a periodic task (daily is good enough, but make the interval configurable through an env variable/the nix flake) to purge games that have finished more than two weeks ago, or have had no moves played within the last month. These time windows should also be configurable. Log all purges, including crew names/uuids and how much disk space they recovered.
|
||||
|
||||
## Polish
|
||||
|
||||
- [ ] **Event log layout**. The event log should still be collapsable into a corner button to give the player the option to declutter their screen. On screens big enough for three column layouts, since the event log has an internal scrolling area, make sure that the outer panel never extends past the bottom of the screen, so that the bottom of the log stays visible no matter what.
|
||||
- [ ] **Crew roster text illegible on dark mode**. The text on the crew roster bubbles is black-on-dark in dark mode. The roster items probably need some re-styling on both dark and light mode, because their background being barely different from the page background doesn't look great.
|
||||
- [ ] **Enforce End-Scene requirements** Unless dev mode is turned on, enforce that the scene cannot end unless every pi-rat has been challenged at least once or the obstacle list is empty. Leave enforcement of "had a chance to complete objective" to table talk.
|
||||
|
||||
## Words Words Words
|
||||
|
||||
- [ ] **Suggestions.** Take a pass through all of the suggestions in suggestions.js, rewrite ones that are stiff, awkward, or don't fit the theme/setting as described in the rulebook. Move the suggestion pool from suggestions.js into a backend API endpoint.
|
||||
- [ ] **TLDR rules**. A one page summary sheet of the rulebook, for the impatient
|
||||
|
||||
## Security
|
||||
|
||||
- [ ] **Defensive coding.** While we trust our players, this app is exposed on the open internet. I'd like to take basic precautions like making sure we're safe against SQL injection (SQLModel should handle this?), doing some basic sanitizing of free inputs from players (valid unicode only + generous character limit should be enough), and making sure that every game action API call is specific and constrained enough that it can't just do arbitrary database updates.
|
||||
|
||||
## Words Words Words (Waiting for Fable to come back)
|
||||
|
||||
- [ ] **TLDR rules**. A one page summary sheet of the rulebook, for the impatient
|
||||
- [ ] **Suggestions.** Take a pass through all of the suggestions in suggestions.js, rewrite ones that are stiff, awkward, or don't fit the theme/setting as described in the rulebook. Move the suggestion pool from suggestions.js into a backend API endpoint.
|
||||
|
||||
|
||||
@@ -17,6 +17,34 @@
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
/* When the inline log is collapsed, reclaim its column (3-col layout only). */
|
||||
@media (min-width: 1101px) {
|
||||
.scene-view-layout.log-collapsed {
|
||||
grid-template-columns: 180px minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Corner button that reopens the collapsed inline Event Log. */
|
||||
.log-reopen-btn {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: 1000;
|
||||
padding: 10px 14px;
|
||||
background: color-mix(in srgb, var(--bg-deep) 95%, transparent);
|
||||
border: 1px solid var(--edge);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-deep);
|
||||
color: var(--text);
|
||||
font-weight: bold;
|
||||
font-family: var(--font-heading);
|
||||
cursor: pointer;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.log-reopen-btn:hover {
|
||||
background: color-mix(in srgb, var(--accent) 12%, var(--bg-deep));
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.scene-view-layout {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script>
|
||||
import { tick, onMount } from 'svelte';
|
||||
import { tick, onMount, createEventDispatcher } from 'svelte';
|
||||
import { apiRequest } from '../lib/api';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let state;
|
||||
// Inline mode pins the log open as a column (scene phase) instead of the
|
||||
// floating, collapsible corner panel used in every other phase.
|
||||
@@ -194,7 +196,10 @@
|
||||
{/key}
|
||||
{/if}
|
||||
{#if inline}
|
||||
<div class="log-header">📜 Event Log</div>
|
||||
<div class="log-header">
|
||||
📜 Event Log
|
||||
<button class="log-hide-btn" title="Collapse the event log" on:click={() => dispatch('collapse')}>✕</button>
|
||||
</div>
|
||||
{:else}
|
||||
<button class="toggle-log-btn" on:click={toggleOpen}>
|
||||
{open ? '⬇️ Hide Log' : '📜 Event Log'}
|
||||
@@ -266,14 +271,18 @@
|
||||
.floating-event-log:not(.open) {
|
||||
width: auto;
|
||||
}
|
||||
/* Inline mode: pinned as the scene's third column instead of floating. */
|
||||
/* Inline mode: pinned as the scene's third column instead of floating. The
|
||||
top offset matches .dashboard-container's top padding (clears the fixed
|
||||
corner menu) so the panel doesn't shift as the page scrolls; the height
|
||||
fills to ~1rem above the viewport bottom, so the panel never runs past
|
||||
the screen and its .log-content scrolls internally instead. */
|
||||
.floating-event-log.inline {
|
||||
position: sticky;
|
||||
top: 1rem;
|
||||
top: 3.5rem;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
width: 100%;
|
||||
max-height: calc(100vh - 2rem);
|
||||
max-height: calc(100vh - 4.5rem);
|
||||
}
|
||||
@media (max-width: 1100px) {
|
||||
.floating-event-log.inline {
|
||||
@@ -282,6 +291,7 @@
|
||||
}
|
||||
}
|
||||
.log-header {
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
@@ -289,6 +299,24 @@
|
||||
border-bottom: 1px solid var(--edge-soft);
|
||||
color: var(--text);
|
||||
}
|
||||
.log-hide-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 6px;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
padding: 2px 7px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
.log-hide-btn:hover {
|
||||
background: color-mix(in srgb, var(--text) 12%, transparent);
|
||||
color: var(--text);
|
||||
}
|
||||
.toggle-log-btn {
|
||||
background: transparent;
|
||||
color: var(--text);
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
export let state;
|
||||
|
||||
// The inline Event Log can be collapsed to a corner button to declutter.
|
||||
let logOpen = true;
|
||||
|
||||
$: hand = state.player.hand_cards ? JSON.parse(state.player.hand_cards) : [];
|
||||
$: playerTechs = { J: state.player.tech_jack, Q: state.player.tech_queen, K: state.player.tech_king };
|
||||
$: isDeep = state.player.role === 'deep';
|
||||
@@ -16,7 +19,7 @@
|
||||
$: showChallengeArea = isDeep || openChallenges.length > 0;
|
||||
</script>
|
||||
|
||||
<div class="scene-view-layout" id="scene-layout-container" data-game-id={state.game.id} data-player-id={state.player.id}>
|
||||
<div class="scene-view-layout" class:log-collapsed={!logOpen} id="scene-layout-container" data-game-id={state.game.id} data-player-id={state.player.id}>
|
||||
<!-- LEFT COLUMN: The Crew -->
|
||||
<CrewColumn {state} />
|
||||
|
||||
@@ -60,8 +63,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RIGHT COLUMN: The Event Log -->
|
||||
<!-- RIGHT COLUMN: The Event Log (collapsible to a corner button) -->
|
||||
{#if logOpen}
|
||||
<div class="log-column">
|
||||
<EventLog {state} inline />
|
||||
<EventLog {state} inline on:collapse={() => (logOpen = false)} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if !logOpen}
|
||||
<button class="log-reopen-btn" title="Show the event log" on:click={() => (logOpen = true)}>
|
||||
📜 Event Log
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -6,10 +6,18 @@
|
||||
// - Add a CHANGELOG entry only when a commit changes something players can
|
||||
// see. Skip refactors, tests, and tooling. Keep wording player-facing.
|
||||
|
||||
export const VERSION = 6;
|
||||
export const VERSION = 7;
|
||||
|
||||
// Newest first. Each entry: { version, date: 'YYYY-MM-DD', changes: [string, ...] }.
|
||||
export const CHANGELOG = [
|
||||
{
|
||||
version: 7,
|
||||
date: '2026-06-15',
|
||||
changes: [
|
||||
'During a scene, the Event Log can be collapsed to a corner button to declutter your screen, and reopened from that button.',
|
||||
'In the three-column layout, the Event Log now stays pinned within the screen and scrolls internally, so its newest entries are always visible.',
|
||||
],
|
||||
},
|
||||
{
|
||||
version: 6,
|
||||
date: '2026-06-15',
|
||||
|
||||
Reference in New Issue
Block a user