Commit c2d1a2156d

c2d1a2156d18f83775faac47e21565e25f8d638f

parent: 869d0abff4

Verified · cmc

cmc <hello@cleberg.net> · 2026-10-16 19:32 UTC

App Store header and screenshots from 1.14.1

AppStore/ follows orgstar's ios/AppStore layout. header.html renders the
21:9 and 16:9 product page headers: three iPhones over the app's indigo
(#4338ca), as on krz.sh/apps/gitbay. Screenshots are light mode, taken by
the checkpoint tests as cmc on the iPhone 18 Pro Max and iPad Pro 13-inch
(M5) simulators; the 6.3" set is resized from the 6.9" one.

testScreenshotCheckpoint now captures the MR detail at its header, before
scrolling to the diff row. testIPadScreenshotCheckpoint opens the first
dashboard item so the split view's detail is not the empty placeholder.

Layout: unified · split

AppStore/header-16x9.png added

Binary file not shown.

AppStore/header-21x9.png added

Binary file not shown.

AppStore/header.html added +42
@@ -0,0 +1,42 @@
1<!doctype html>
2<!-- Product page header, after the krz.sh hero: three iPhones fanned over the app's indigo (#4338ca).
3 header.html renders the 21:9 header (3840x1646), header.html#wide the 16:9 one (5244x2950),
4 with headless Chromium, then the alpha channel is removed:
5 Chromium --headless --hide-scrollbars --force-device-scale-factor=1 --window-size=3840,1646 --screenshot=header-21x9.png header.html
6 Chromium --headless --hide-scrollbars --force-device-scale-factor=1 --window-size=5244,2950 --screenshot=header-16x9.png "file://$PWD/header.html#wide"
7 magick header-21x9.png -alpha off PNG24:header-21x9.png -->
8<html>
9<head>
10<meta charset="utf-8">
11<style>
12 :root { --u: 1px; --top: 180px; }
13 * { box-sizing: border-box; }
14 html, body { margin: 0; width: 3840px; height: 1646px; overflow: hidden; }
15 body {
16 position: relative;
17 background:
18 radial-gradient(ellipse 55% 75% at 50% 30%, #6d64e8 0%, #4338ca 35%, #272080 70%, #120f3d 100%);
19 }
20 .iphone {
21 position: absolute; left: 50%; top: var(--top);
22 width: calc(860 * var(--u)); height: calc(1868 * var(--u));
23 padding: calc(24 * var(--u)); border-radius: calc(140 * var(--u)); background: #0c0c12;
24 box-shadow: 0 calc(50 * var(--u)) calc(120 * var(--u)) rgba(0, 0, 0, 0.5);
25 }
26 .iphone img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; border-radius: calc(116 * var(--u)); }
27 .center { transform: translateX(-50%); z-index: 2; }
28 .left { transform: translate(calc(-50% - 760 * var(--u)), calc(120 * var(--u))) rotate(-8deg); }
29 .right { transform: translate(calc(-50% + 760 * var(--u)), calc(120 * var(--u))) rotate(8deg); }
30
31 /* 16:9, 5244x2950. */
32 html.wide { --u: 1.6px; --top: 420px; }
33 html.wide, .wide body { width: 5244px; height: 2950px; }
34</style>
35<script>if (location.hash === "#wide") document.documentElement.className = "wide";</script>
36</head>
37<body>
38 <div class="iphone left"><img src="screenshots/iphone-6.9/02-repo.png"></div>
39 <div class="iphone right"><img src="screenshots/iphone-6.9/03-mr-list.png"></div>
40 <div class="iphone center"><img src="screenshots/iphone-6.9/01-dashboard.png"></div>
41</body>
42</html>
AppStore/icon-64.png added

Binary file not shown.

AppStore/screenshots/ipad/01-dashboard.png added

Binary file not shown.

AppStore/screenshots/ipad/02-explore.png added

Binary file not shown.

AppStore/screenshots/ipad/03-repo.png added

Binary file not shown.

AppStore/screenshots/ipad/04-feed.png added

Binary file not shown.

AppStore/screenshots/ipad/05-profile.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/01-dashboard.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/02-repo.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/03-mr-list.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/04-mr-detail.png added

Binary file not shown.

AppStore/screenshots/iphone-6.3/05-diff.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/01-dashboard.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/02-repo.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/03-mr-list.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/04-mr-detail.png added

Binary file not shown.

AppStore/screenshots/iphone-6.9/05-diff.png added

Binary file not shown.

gitbayUITests/LiveSmokeUITests.swift +14 −3
@@ -1156,11 +1156,14 @@ extension LiveSmokeUITests {
1156 snap("mr-list") 1156 snap("mr-list")
1157 1157
1158 mrNumber.tap() 1158 mrNumber.tap()
1159 // The detail opens at its header; the diff row sits below the 1159 // Captured at its header, before scrolling down to the diff row.
1160 // fold and a List does not build rows it has not shown. 1160 XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 15), "MR detail did not open")
1161 snap("mr-detail")
1162
1163 // The diff row sits below the fold and a List does not build rows
1164 // it has not shown.
1161 let diffRow = app.staticTexts["Diff"].firstMatch 1165 let diffRow = app.staticTexts["Diff"].firstMatch
1162 XCTAssertTrue(scrollTo(diffRow), "MR detail has no diff row") 1166 XCTAssertTrue(scrollTo(diffRow), "MR detail has no diff row")
1163 snap("mr-detail")
1164 1167
1165 diffRow.tap() 1168 diffRow.tap()
1166 XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 15)) 1169 XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 15))
@@ -1553,6 +1556,14 @@ extension LiveSmokeUITests {
1553 /// deferred. Tabs and a list row work on both. 1556 /// deferred. Tabs and a list row work on both.
1554 func testIPadScreenshotCheckpoint() throws { 1557 func testIPadScreenshotCheckpoint() throws {
1555 signInIfNeeded() 1558 signInIfNeeded()
1559 // The split view's detail is empty until a row is chosen; open the
1560 // first issue or merge request so the shot is not half placeholder.
1561 let item = app.staticTexts
1562 .matching(NSPredicate(format: "label MATCHES '.+/.+[#!][0-9]+'")).firstMatch
1563 XCTAssertTrue(item.waitForExistence(timeout: 20), "dashboard listed no items")
1564 item.tap()
1565 XCTAssertTrue(waitForDisappearance(app.staticTexts["Nothing selected"].firstMatch, timeout: 15),
1566 "dashboard detail did not open")
1556 snap("dashboard") 1567 snap("dashboard")
1557 1568
1558 selectTab("Explore") 1569 selectTab("Explore")