Skip to content
Source
Sign inSign up
Open History to see the last commit

mobile-showcase.config.ts

232 lines7.1 KB

1import {
2 MOBILE_DEFAULT_THEME_ID,
3 MOBILE_THEME_IDS,
4 type MobileThemeId,
5} from "@t3tools/shared/themePalettes";
6​
7import { SHOWCASE_SCENES, type ShowcaseScene } from "./mobile-showcase-environment.ts";
8​
9export { SHOWCASE_SCENES };
10export type { ShowcaseScene };
11​
12export type ShowcaseAppearance = "light" | "dark";
13​
14export const SHOWCASE_THEMES = MOBILE_THEME_IDS;
15const DEFAULT_SHOWCASE_THEME = MOBILE_DEFAULT_THEME_ID;
16export type ShowcaseTheme = MobileThemeId;
17​
18export interface ShowcaseStoreAssetSpec {
19 readonly store: "apple" | "google-play";
20 readonly directory: string;
21 readonly width: number;
22 readonly height: number;
23 readonly minimumUploadCount: number;
24 readonly maximumUploadCount: number;
25 readonly maximumFileSizeBytes?: number;
27​
28export interface ShowcaseIosDevice {
29 readonly id: string;
30 readonly platform: "ios";
31 readonly simulator: string;
32 readonly simulatorDeviceType?: string;
33 readonly appearance: ShowcaseAppearance;
34 readonly theme: ShowcaseTheme;
35 readonly orientation?: "portrait" | "landscape";
36 readonly fold?: "closed" | "open";
37 readonly scenes: ReadonlyArray<ShowcaseScene>;
38 readonly storeAsset: ShowcaseStoreAssetSpec;
40​
41export interface ShowcaseAndroidDevice {
42 readonly id: string;
43 readonly platform: "android";
44 readonly avd: string;
45 readonly appearance: ShowcaseAppearance;
46 readonly theme: ShowcaseTheme;
47 readonly abi?: "arm64-v8a" | "x86_64" | "x86" | "armeabi-v7a";
48 readonly scenes: ReadonlyArray<ShowcaseScene>;
49 readonly viewport?: {
50 readonly width: number;
51 readonly height: number;
52 readonly density?: number;
53 };
54 readonly storeAsset: ShowcaseStoreAssetSpec;
56​
57export type ShowcaseDevice = ShowcaseIosDevice | ShowcaseAndroidDevice;
58​
59export interface ShowcaseConfig {
60 readonly outputDirectory: string;
61 readonly metroPort: number;
62 readonly settleDelayMs: number;
63 readonly devices: ReadonlyArray<ShowcaseDevice>;
65​
66const ANDROID_ABIS = ["arm64-v8a", "x86_64", "x86", "armeabi-v7a"] as const;
67​
68function resolveShowcaseAndroidAbi(
69 value: string | undefined,
70): NonNullable<ShowcaseAndroidDevice["abi"]> {
71 if (!value) return "arm64-v8a";
72 if (ANDROID_ABIS.some((abi) => abi === value)) {
73 return value as NonNullable<ShowcaseAndroidDevice["abi"]>;
74 }
75 throw new Error(
76 `Unsupported T3_SHOWCASE_ANDROID_ABI '${value}'. Use ${ANDROID_ABIS.join(", ")}.`,
77 );
79​
80const config: ShowcaseConfig = {
81 outputDirectory: "artifacts/app-store/screenshots",
82 // A dedicated port prevents captures from attaching to another dev server's bundle.
83 metroPort: 8199,
84 settleDelayMs: 2_500,
85 devices: [
86 {
87 id: "iphone-6.9",
88 platform: "ios",
89 simulator: "T3 Showcase iPhone 17 Pro Max",
90 simulatorDeviceType: "com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro-Max",
91 appearance: "dark",
92 theme: DEFAULT_SHOWCASE_THEME,
93 scenes: ["thread", "terminal", "review", "threads", "environments", "agent-activity"],
94 storeAsset: {
95 store: "apple",
96 directory: "apple/iphone-6.9",
97 width: 1320,
98 height: 2868,
99 minimumUploadCount: 1,
100 maximumUploadCount: 10,
101 },
102 },
103 {
104 id: "iphone-6.5",
105 platform: "ios",
106 simulator: "T3 Showcase iPhone 14 Plus",
107 simulatorDeviceType: "com.apple.CoreSimulator.SimDeviceType.iPhone-14-Plus",
108 appearance: "dark",
109 theme: DEFAULT_SHOWCASE_THEME,
110 scenes: ["thread", "terminal", "review", "threads", "environments", "agent-activity"],
111 storeAsset: {
112 store: "apple",
113 directory: "apple/iphone-6.5",
114 width: 1284,
115 height: 2778,
116 minimumUploadCount: 1,
117 maximumUploadCount: 10,
118 },
119 },
120 ...(["closed", "open"] as const).map((fold): ShowcaseIosDevice => ({
121 id: `iphone-duo-${fold}`,
122 platform: "ios",
123 simulator: `T3 Showcase iPhone Duo ${fold}`,
124 simulatorDeviceType: "com.apple.CoreSimulator.SimDeviceType.iPhone-Duo",
125 appearance: "dark",
126 theme: DEFAULT_SHOWCASE_THEME,
127 orientation: fold === "closed" ? "portrait" : "landscape",
128 fold,
129 // Both poses share one ten-image App Store slot.
130 scenes: ["thread", "terminal", "review", "threads", "environments"],
131 storeAsset: {
132 store: "apple",
133 directory: `apple/iphone-duo-${fold}`,
134 width: fold === "closed" ? 1398 : 2853,
135 height: fold === "closed" ? 2034 : 2007,
136 minimumUploadCount: 1,
137 maximumUploadCount: 5,
138 },
139 })),
140 {
141 id: "ipad-13",
142 platform: "ios",
143 simulator: "iPad Pro 13-inch (M5)",
144 simulatorDeviceType: "com.apple.CoreSimulator.SimDeviceType.iPad-Pro-13-inch-M5-16GB",
145 appearance: "dark",
146 theme: DEFAULT_SHOWCASE_THEME,
147 orientation: "landscape",
148 // Lock screens ignore app rotation; headless landscape captures would be sideways.
149 scenes: ["thread", "terminal", "review", "threads", "environments"],
150 storeAsset: {
151 store: "apple",
152 directory: "apple/ipad-13",
153 width: 2752,
154 height: 2064,
155 minimumUploadCount: 1,
156 maximumUploadCount: 10,
157 },
158 },
159 {
160 id: "pixel",
161 platform: "android",
162 avd: "Pixel_10_Pro",
163 // Apple Silicon defaults to ARM64; Blacksmith Linux CI overrides to x86_64 for KVM.
164 abi: resolveShowcaseAndroidAbi(process.env.T3_SHOWCASE_ANDROID_ABI),
165 appearance: "dark",
166 theme: DEFAULT_SHOWCASE_THEME,
167 viewport: {
168 width: 1080,
169 height: 1920,
170 density: 420,
171 },
172 scenes: ["thread", "terminal", "review", "threads", "environments", "agent-activity"],
173 storeAsset: {
174 store: "google-play",
175 directory: "google-play/phone",
176 width: 1080,
177 height: 1920,
178 minimumUploadCount: 2,
179 maximumUploadCount: 8,
180 maximumFileSizeBytes: 8 * 1024 * 1024,
181 },
182 },
183 {
184 id: "android-tablet-7",
185 platform: "android",
186 avd: "Pixel_10_Pro",
187 abi: resolveShowcaseAndroidAbi(process.env.T3_SHOWCASE_ANDROID_ABI),
188 appearance: "dark",
189 theme: DEFAULT_SHOWCASE_THEME,
190 viewport: {
191 width: 1080,
192 height: 1920,
193 density: 288,
194 },
195 scenes: ["thread", "terminal", "review", "threads", "environments", "agent-activity"],
196 storeAsset: {
197 store: "google-play",
198 directory: "google-play/tablet-7",
199 width: 1080,
200 height: 1920,
201 minimumUploadCount: 4,
202 maximumUploadCount: 8,
203 maximumFileSizeBytes: 8 * 1024 * 1024,
204 },
205 },
206 {
207 id: "android-tablet-10",
208 platform: "android",
209 avd: "Pixel_10_Pro",
210 abi: resolveShowcaseAndroidAbi(process.env.T3_SHOWCASE_ANDROID_ABI),
211 appearance: "dark",
212 theme: DEFAULT_SHOWCASE_THEME,
213 viewport: {
214 width: 1440,
215 height: 2560,
216 density: 288,
217 },
218 scenes: ["thread", "terminal", "review", "threads", "environments", "agent-activity"],
219 storeAsset: {
220 store: "google-play",
221 directory: "google-play/tablet-10",
222 width: 1440,
223 height: 2560,
224 minimumUploadCount: 4,
225 maximumUploadCount: 8,
226 maximumFileSizeBytes: 8 * 1024 * 1024,
227 },
228 },
229 ],
230};
231​
232export default config;