diff --git a/docs/tile-grid-plan.md b/docs/tile-grid-plan.md index 768d0153..d3711c80 100644 --- a/docs/tile-grid-plan.md +++ b/docs/tile-grid-plan.md @@ -401,8 +401,8 @@ the harness/model request; see "As built") ### Persistence -Decided: per device (per browser), restored on reload, and by the Tiles toggle -(decision 11). Stored in localStorage key `codeman:tile-grid`, never on the +Decided: per device (per browser), restored on reload when it was open, and by +the Tiles toggle however it was closed (decision 11). Stored in localStorage key `codeman:tile-grid`, never on the server: ```json @@ -1129,9 +1129,11 @@ exits green. Use the browser runner for those files and read the file count. last setting was, if there was no setting before take the working ones, that ones needs input and then the most recent ones in order"). The layout (cells and holes, tile count, divider sizes, focus, a zoom the user chose) - is saved per browser on every change and comes back exactly from the toggle - and a reload, however the grid closed; it is never filled to the remembered - count nor trimmed to the window. A session gone since frees its cell for the + is saved per browser on every change and comes back exactly from the toggle, + however the grid closed, and from a reload when the grid was open (a grid + closed before the reload stays remembered for the toggle; the page shows the + single view); it is never filled to the remembered count nor trimmed to the + window. A session gone since frees its cell for the ranking; with none left, the grid opens from the ranking (`rankTileSessions`: working, then needing input, then most recent), which also fills every place the grid fills on its own (a count picked in the menu, a freed cell, an open diff --git a/docs/wiki/Tile-Grid.md b/docs/wiki/Tile-Grid.md index cbb5b2ad..cfe56135 100644 --- a/docs/wiki/Tile-Grid.md +++ b/docs/wiki/Tile-Grid.md @@ -98,8 +98,8 @@ keeps the focus. A moved tile takes the size of the place it lands in: column widths and row heights stay where you dragged the dividers. Tiles do not move while one is zoomed. Where everything is, -the empty slot included, is saved with the grid and comes back on reload and when you turn -the grid off and on. +the empty slot included, is saved with the grid and comes back when you turn the grid off +and on, and on a page reload while the grid is open. Closing a tile leaves its place empty when the grid keeps its shape (six tiles to five), and a new tile takes the first empty place. When the number of tiles changes the grid's shape (four @@ -135,7 +135,9 @@ same. Narrowing the window below the desktop width also returns to the single vi The grid is saved in this browser every time you change it (moving, resizing, adding or removing a tile, changing the count, focusing or zooming a tile), and never sent to the server. However you leave it (the Tiles button, another tab, Home, a link, closing its last -tile or session), the Tiles button and a page reload bring it back as it was. A session +tile or session), the Tiles button brings it back as it was. A page reload brings it back +when the grid was open; after you left it, a reload shows the single view and the Tiles +button still brings the grid back. A session that was closed in the meantime frees its place for another one, picked the way a new grid picks them; the place stays empty only when no other session is left. Right after a page reload the page does not know yet which sessions are waiting for your answer, so that pick diff --git a/src/web/public/tile-grid.js b/src/web/public/tile-grid.js index 090b3061..f761367c 100644 --- a/src/web/public/tile-grid.js +++ b/src/web/public/tile-grid.js @@ -29,8 +29,8 @@ const TILE_GRID_FONT_KEY = 'codeman-tile-font-size'; // how many tiles the user's own last change left (a session that went away by // itself does not lower it). Session ids and layout only, never content. // Written on every change while the grid is open; `open: false` keeps it for -// the Tiles toggle, which brings it back exactly; restored on reload inside -// handleInit. Never sent to the server. +// the Tiles toggle, which brings it back exactly; a grid stored open is +// restored on reload inside handleInit. Never sent to the server. const TILE_GRID_STORAGE_KEY = 'codeman:tile-grid'; // The count last picked in the Tiles button's right-click menu (2, 4 or 6; // owner decision 10), per device: what a click opens when there is no stored @@ -432,8 +432,8 @@ Object.assign(CodemanApp.prototype, { * queued loads dropped), the main terminal unparked. * * `keepStored` (every caller) keeps the grid as it was, holes, count, sizes, - * focus and zoom, for the Tiles toggle and the next reload to bring back; - * false would forget it. `reselect` shows the focused session in the single + * focus and zoom, closed, for the Tiles toggle to bring back (a reload + * restores only a grid stored open); false would forget it. `reselect` shows the focused session in the single * view through a forced reload; pass false when the caller selects * something itself. `animate` (the Tiles toggle only, owner answer 4) * leaves a still copy of the tiles over the stage until the single view has diff --git a/test/tile-grid-layout-memory.test.ts b/test/tile-grid-layout-memory.test.ts index 3d3ebf6e..d554c6ff 100644 --- a/test/tile-grid-layout-memory.test.ts +++ b/test/tile-grid-layout-memory.test.ts @@ -7,13 +7,14 @@ * - Saved on every change (`codeman:tile-grid` in localStorage, never the * server): which session sits in which cell, holes included, the tile count, * the divider sizes, the focused tile and a zoom the user chose. - * - The Tiles toggle and a page reload bring back exactly that, however the - * grid was closed: the toggle, a tab that is not tiled, a followed link - * (`leaveTiles`, or `#session=` on load), Home, the window narrowing past the - * desktop gate, the last tile removed, "Open group as tiles", closing a - * session, killing them all. It is never filled to the remembered count and - * never trimmed to the window (a too-small window shows the focused tile - * until it fits, the arrangement kept). + * - The Tiles toggle brings back exactly that, however the grid was closed: + * the toggle, a tab that is not tiled, a followed link (`leaveTiles`, or + * `#session=` on load), Home, the window narrowing past the desktop gate, + * the last tile removed, "Open group as tiles", closing a session, killing + * them all. A page reload brings it back only when the grid was open (a + * closed one stays remembered for the toggle). It is never filled to the + * remembered count and never trimmed to the window (a too-small window + * shows the focused tile until it fits, the arrangement kept). * - A session that no longer exists frees its cell, and the ranking fills it * (the hole a user left stays a hole); with none of the stored sessions left * the grid opens from the ranking, as with nothing stored. @@ -255,7 +256,7 @@ describe('saved on every change', () => { }); }); -describe('the Tiles toggle and a reload bring back exactly what was arranged', () => { +describe('the Tiles toggle (and a reload while it is open) brings back exactly what was arranged', () => { it('off and on: the cells and the hole, the count, the divider sizes, the focus and the zoom', async () => { const app = layoutApp(); await arrange(app); @@ -291,6 +292,23 @@ describe('the Tiles toggle and a reload bring back exactly what was arranged', ( expect(layoutOf(next)).toEqual(before); }); + it('a reload after the grid was closed: the single view, and the Tiles toggle brings it back exactly', async () => { + const app = layoutApp(); + await arrange(app); + const before = layoutOf(app); + app.toggleTileGrid(); + section.children = []; + FakeTile.all = []; + const next = layoutApp(); + // The reload leaves it closed (handleInit then selects the single view)... + expect(next._restoreTileGrid()).toBe(false); + expect(next._tilesOwnTerminal()).toBe(false); + expect(stored()).toMatchObject({ open: false, ids: ARRANGED_CELLS }); + // ...and remembered: the toggle puts it back as it was. + next.toggleTileGrid(); + expect(layoutOf(next)).toEqual(before); + }); + it('never trimmed to a smaller window: the focused tile shows alone, and the arrangement is kept for a wider one', async () => { const app = layoutApp(); app.openTileGrid(SIX, { focusedId: 's-c' });