Public: anyone can read this; the crew can change it.

Your apps, one line each: the studio home's rows and its empty state #522

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/69-your-apps-one-line-each-the-studio-home → main 1 commit fork

  • Merged. scout/69-your-apps-one-line-each-the-studio-home was merged into main as ec5e8b4.

Review

Sign in to review this change.
4 files changed +42 −6
src/web/studio/home.ts +8 −2
@@ -64,7 +64,11 @@ async function shelf(
6464 icon: "rocket",
6565 title: "No apps yet",
6666 note: "Make one, tell the crew what it is, and watch it come up.",
67 action: btn("New app", { href: "/apps/new", variant: "primary" }),
67 action: html`${btn("New app", {
68 href: "/apps/new",
69 variant: "primary",
70 })}
71 ${btn("Repositories", { href: "/?mode=dev" })}`,
6872 })
6973 : listCard(appRows, {
7074 head: html`${icon("rocket")}
@@ -239,7 +243,9 @@ export function studioDoor(ctx: Ctx): Response {
239243 <span class="app-tile-body">
240244 <span class="app-tile-name">${repo.name}</span>
241245 ${repo.description !== ""
242 ? html`<span class="app-tile-desc truncate"
246 ? html`<span
247 class="app-tile-desc truncate"
248 title="${repo.description}"
243249 >${repo.description}</span
244250 >`
245251 : null}
src/web/studio/shelf.ts +7 −3
@@ -265,9 +265,13 @@ export async function shelfRows(
265265 lead: dot(tone),
266266 title,
267267 titleAttr: repo.description || repo.name,
268 meta: html`${repo.description
269 ? html`${repo.description} · `
270 : null}${happening}`,
268 meta: html`<span class="shelf-meta"
269 >${repo.description
270 ? html`<span class="shelf-desc">${repo.description}</span>`
271 : null}<span class="shelf-facts"
272 >${repo.description ? "· " : null}${happening}</span
273 ></span
274 >`,
271275 trail: raw(
272276 `\n <span class="badge" data-tone="${tone}">${escapeHtml(live.word)}</span>`,
273277 ),
src/web/studio/style.ts +5
@@ -67,6 +67,9 @@ const rows = part(/* css */ `
6767 .studio-list li svg { vertical-align: -3px; }
6868 .studio-who { font-weight: 600; }
6969 .studio-word { font-family: var(--mono); font-size: 11.5px; opacity: .8; white-space: nowrap; }
70 .shelf-meta { display: flex; gap: 0 4px; min-width: 0; }
71 .shelf-desc { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
72 .shelf-facts { flex: 0 0 auto; max-width: 100%; }
7073 .row-meta .studio-word { font-family: inherit; font-size: inherit; opacity: 1; font-weight: 560; }
7174 .studio-list li[data-word="working"] .studio-word { color: var(--accent); opacity: 1; }
7275 .studio-list li[data-word="look"] .studio-word { color: var(--merged); opacity: 1; }
@@ -106,6 +109,8 @@ const phone = part(/* css */ `
106109 .studio-list li > :nth-child(n+3) { grid-column: 2; }
107110 .studio-word { white-space: normal; }
108111 .studio .row-meta, .studio-list .row-meta { white-space: normal; overflow-wrap: anywhere; }
112 .shelf-meta { flex-wrap: wrap; }
113 .shelf-desc { flex: 1 1 100%; }
109114 .studio-tell textarea, .studio-tell .input { font-size: 16px; }
110115 }
111116 `);
test/studio.test.ts +22 −1
@@ -213,10 +213,30 @@ describe("the studio", () => {
213213 // The bytes the home rendered before the row moved into its own
214214 // module, escaped so no formatter can reflow them.
215215 expect(shelfRow).toBe(
216 '<li>\n <a href="/alice/notes" class="row"\n \n data-nav tabindex="-1"><span class="row-lead"><span\n class="dot"\n \n ></span></span>\n <span class="row-main">\n <span\n class="row-title"\n title="a place for notes"\n >notes</span\n >\n <span class="row-meta">a place for notes · <span class="muted">quiet — tell the crew something</span></span>\n </span>\n <span class="row-trail">\n <span class="badge" data-tone="default">not running</span></span></a>\n </li>',
216 '<li>\n <a href="/alice/notes" class="row"\n \n data-nav tabindex="-1"><span class="row-lead"><span\n class="dot"\n \n ></span></span>\n <span class="row-main">\n <span\n class="row-title"\n title="a place for notes"\n >notes</span\n >\n <span class="row-meta"><span class="shelf-meta"\n ><span class="shelf-desc">a place for notes</span><span class="shelf-facts"\n >· <span class="muted">quiet — tell the crew something</span></span\n ></span\n ></span>\n </span>\n <span class="row-trail">\n <span class="badge" data-tone="default">not running</span></span></a>\n </li>',
217217 );
218218 });
219219
220 test("a 400-character description is one clamped line on the row, whole in its title, and the facts keep their own span (#69)", async () => {
221 const long = "paragraph ".repeat(40).trim();
222 expect(long.length).toBeGreaterThanOrEqual(399);
223 app.db.run("UPDATE repo SET description = ?1 WHERE id = ?2", [long, repo.id]);
224 try {
225 const home = await (await get("/")).text();
226 const at = home.indexOf('href="/alice/notes"');
227 const shelfRow = home.slice(home.lastIndexOf("<li>", at), home.indexOf("</li>", at));
228 expect(shelfRow).toContain(`title="${long}"`);
229 expect(shelfRow).toContain(`<span class="shelf-desc">${long}</span>`);
230 expect(shelfRow).toContain('class="shelf-facts"');
231 // The facts sit outside the description, so it cannot push them out.
232 expect(shelfRow.indexOf('class="shelf-facts"')).toBeGreaterThan(
233 shelfRow.indexOf("</span>", shelfRow.indexOf('class="shelf-desc"')),
234 );
235 } finally {
236 app.db.run("UPDATE repo SET description = ?1 WHERE id = ?2", ["a place for notes", repo.id]);
237 }
238 });
239
220240 test("an app's home is the app in the studio, and the code in dev", async () => {
221241 const studio = await (await get("/alice/notes")).text();
222242 expect(studio).toContain("Tell the crew");
@@ -1547,6 +1567,7 @@ describe("the studio", () => {
15471567 const erinHome = await (await erinGet("/")).text();
15481568 expect(erinHome).toContain("No apps yet");
15491569 expect(erinHome).toContain('href="/apps/new"');
1570 expect(erinHome).toContain('href="/?mode=dev"');
15501571 expect(erinHome).not.toContain('href="/alice/lighthouse"');
15511572 expect(erinHome).not.toContain("tell the crew something");
15521573

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs