@buoy-gg/images 7.0.28 → 7.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/components/ImagesModal.js +2 -1
- package/lib/commonjs/components/ImagesModal.js.map +1 -1
- package/lib/module/components/ImagesModal.js +2 -1
- package/lib/module/components/ImagesModal.js.map +1 -1
- package/package.json +5 -6
- package/src/capture/actions.ts +0 -215
- package/src/capture/install.ts +0 -40
- package/src/capture/installExpoImage.ts +0 -115
- package/src/capture/installRnImage.tsx +0 -133
- package/src/capture/overrides.ts +0 -332
- package/src/capture/savings.ts +0 -204
- package/src/capture/shared.ts +0 -387
- package/src/components/ImageDetail.tsx +0 -466
- package/src/components/ImageDetailFooter.tsx +0 -271
- package/src/components/ImageRow.tsx +0 -148
- package/src/components/ImagesHeader.tsx +0 -77
- package/src/components/ImagesIcon.tsx +0 -9
- package/src/components/ImagesListFooter.tsx +0 -194
- package/src/components/ImagesModal.tsx +0 -265
- package/src/components/ImagesRoot.tsx +0 -18
- package/src/components/InsightsBar.tsx +0 -51
- package/src/export.ts +0 -100
- package/src/format.ts +0 -85
- package/src/hooks/useImageRecords.ts +0 -24
- package/src/index.tsx +0 -120
- package/src/preset.tsx +0 -35
- package/src/register.ts +0 -17
- package/src/remote.ts +0 -42
- package/src/state.ts +0 -103
- package/src/store/imageEventStore.ts +0 -236
- package/src/store/insights.ts +0 -66
- package/src/sync/__tests__/imagesSyncAdapter.test.ts +0 -114
- package/src/sync/imagesSyncAdapter.ts +0 -312
- package/src/types.ts +0 -155
|
@@ -1,466 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ImageDetail — full record view: preview, source, load timeline, dimensions
|
|
3
|
-
* with the oversize verdict + estimated decoded/wasted memory, cache verdict,
|
|
4
|
-
* and error details (including HTTP status/headers when the platform provides
|
|
5
|
-
* them). Cache actions live here too (expo-image global clears).
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { useState, type ReactNode } from "react";
|
|
9
|
-
import {
|
|
10
|
-
Image,
|
|
11
|
-
ScrollView,
|
|
12
|
-
StyleSheet,
|
|
13
|
-
Text,
|
|
14
|
-
TextInput,
|
|
15
|
-
TouchableOpacity,
|
|
16
|
-
View,
|
|
17
|
-
} from "react-native";
|
|
18
|
-
import { macOSColors, night } from "@buoy-gg/shared-ui";
|
|
19
|
-
import { clearOverride, setOverride } from "../capture/overrides";
|
|
20
|
-
import { proveSavings } from "../capture/savings";
|
|
21
|
-
import type { SavingsResult } from "../capture/savings";
|
|
22
|
-
import { remoteImagesDispatch } from "../remote";
|
|
23
|
-
import {
|
|
24
|
-
effectivePixelRatio,
|
|
25
|
-
estDecodedBytes,
|
|
26
|
-
estWastedBytes,
|
|
27
|
-
neededPixels,
|
|
28
|
-
} from "../store/imageEventStore";
|
|
29
|
-
import { cacheBadge, formatBytes, formatMs, sizeVerdict } from "../format";
|
|
30
|
-
import type { ImageRecord } from "../types";
|
|
31
|
-
|
|
32
|
-
interface ImageDetailProps {
|
|
33
|
-
record: ImageRecord;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function Section({ title, children }: { title: string; children: ReactNode }) {
|
|
37
|
-
return (
|
|
38
|
-
<View style={styles.section}>
|
|
39
|
-
<Text style={styles.sectionTitle}>{title}</Text>
|
|
40
|
-
<View style={styles.sectionBody}>{children}</View>
|
|
41
|
-
</View>
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function Row({ label, value, color }: { label: string; value: string; color?: string }) {
|
|
46
|
-
return (
|
|
47
|
-
<View style={styles.kvRow}>
|
|
48
|
-
<Text style={styles.kvLabel}>{label}</Text>
|
|
49
|
-
<Text style={[styles.kvValue, color ? { color } : null]} selectable>
|
|
50
|
-
{value}
|
|
51
|
-
</Text>
|
|
52
|
-
</View>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** expo-image global cache clears (no-ops if expo-image is absent). */
|
|
57
|
-
function clearExpoCache(kind: "memory" | "disk"): void {
|
|
58
|
-
// Mirror mode: the caches live on the synced device.
|
|
59
|
-
const remote = remoteImagesDispatch();
|
|
60
|
-
if (remote) {
|
|
61
|
-
void remote("clearExpoCaches", {
|
|
62
|
-
memory: kind === "memory",
|
|
63
|
-
disk: kind === "disk",
|
|
64
|
-
});
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
try {
|
|
68
|
-
const expo = require("expo-image");
|
|
69
|
-
if (kind === "memory") void expo.Image.clearMemoryCache();
|
|
70
|
-
else void expo.Image.clearDiskCache();
|
|
71
|
-
} catch {
|
|
72
|
-
// expo-image not installed
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Free-text source swap: test another URL/format/CDN param on the live view. */
|
|
77
|
-
function SwapUrlSection({ record }: { record: ImageRecord }) {
|
|
78
|
-
const [url, setUrl] = useState(record.uri);
|
|
79
|
-
const trimmed = url.trim();
|
|
80
|
-
const canApply = record.mounted && trimmed.length > 0 && trimmed !== record.uri;
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<Section title="SWAP SOURCE URL">
|
|
84
|
-
<TextInput
|
|
85
|
-
style={styles.urlInput}
|
|
86
|
-
value={url}
|
|
87
|
-
onChangeText={setUrl}
|
|
88
|
-
placeholder="https://…"
|
|
89
|
-
placeholderTextColor={night.color.placeholder}
|
|
90
|
-
autoCapitalize="none"
|
|
91
|
-
autoCorrect={false}
|
|
92
|
-
multiline
|
|
93
|
-
/>
|
|
94
|
-
<View style={styles.actionsRow}>
|
|
95
|
-
<TouchableOpacity
|
|
96
|
-
style={[styles.actionButton, !canApply && styles.actionDisabled]}
|
|
97
|
-
disabled={!canApply}
|
|
98
|
-
onPress={() =>
|
|
99
|
-
setOverride(record.id, {
|
|
100
|
-
source: { type: "url", uri: trimmed },
|
|
101
|
-
label: "URL swapped",
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
>
|
|
105
|
-
<Text style={styles.actionText}>Apply</Text>
|
|
106
|
-
</TouchableOpacity>
|
|
107
|
-
<TouchableOpacity
|
|
108
|
-
style={styles.actionButton}
|
|
109
|
-
onPress={() => setUrl(record.uri)}
|
|
110
|
-
>
|
|
111
|
-
<Text style={styles.actionText}>Reset field</Text>
|
|
112
|
-
</TouchableOpacity>
|
|
113
|
-
</View>
|
|
114
|
-
</Section>
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Real, on-device savings proof: re-encode at displayed size as WebP via
|
|
120
|
-
* expo-image-manipulator, report actual bytes, offer an in-place preview.
|
|
121
|
-
*/
|
|
122
|
-
function SavingsSection({ record }: { record: ImageRecord }) {
|
|
123
|
-
const [busy, setBusy] = useState(false);
|
|
124
|
-
const [result, setResult] = useState<SavingsResult | null>(null);
|
|
125
|
-
|
|
126
|
-
const run = () => {
|
|
127
|
-
setBusy(true);
|
|
128
|
-
proveSavings(record)
|
|
129
|
-
.then(setResult)
|
|
130
|
-
.catch((error) => setResult({ ok: false, message: String(error?.message ?? error) }))
|
|
131
|
-
.finally(() => setBusy(false));
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
return (
|
|
135
|
-
<Section title="PROVE SAVINGS (re-encode on device)">
|
|
136
|
-
{result == null ? (
|
|
137
|
-
<View style={styles.actionsRow}>
|
|
138
|
-
<TouchableOpacity style={styles.actionButton} onPress={run} disabled={busy}>
|
|
139
|
-
<Text style={styles.actionText}>
|
|
140
|
-
{busy ? "Re-encoding…" : "Re-encode at displayed size (WebP)"}
|
|
141
|
-
</Text>
|
|
142
|
-
</TouchableOpacity>
|
|
143
|
-
</View>
|
|
144
|
-
) : (
|
|
145
|
-
<>
|
|
146
|
-
<Row
|
|
147
|
-
label="Result"
|
|
148
|
-
value={result.message || (result.ok ? "done" : "failed")}
|
|
149
|
-
color={result.ok ? macOSColors.semantic.success : macOSColors.semantic.error}
|
|
150
|
-
/>
|
|
151
|
-
{result.originalBytes != null ? (
|
|
152
|
-
<Row
|
|
153
|
-
label="Original"
|
|
154
|
-
value={`${formatBytes(result.originalBytes)} (${result.originalBytesSource})`}
|
|
155
|
-
/>
|
|
156
|
-
) : null}
|
|
157
|
-
{result.optimizedBytes != null ? (
|
|
158
|
-
<Row
|
|
159
|
-
label="Optimized"
|
|
160
|
-
value={`${formatBytes(result.optimizedBytes)} — ${result.optimizedDims?.width}×${result.optimizedDims?.height} WebP`}
|
|
161
|
-
color={macOSColors.semantic.success}
|
|
162
|
-
/>
|
|
163
|
-
) : null}
|
|
164
|
-
{result.savedBytes != null ? (
|
|
165
|
-
<Row
|
|
166
|
-
label="Saved"
|
|
167
|
-
value={`${formatBytes(result.savedBytes)} (${result.savedPct}%)`}
|
|
168
|
-
color={macOSColors.semantic.success}
|
|
169
|
-
/>
|
|
170
|
-
) : null}
|
|
171
|
-
<View style={styles.actionsRow}>
|
|
172
|
-
{result.ok && result.optimizedUri && record.mounted ? (
|
|
173
|
-
<TouchableOpacity
|
|
174
|
-
style={styles.actionButton}
|
|
175
|
-
onPress={() =>
|
|
176
|
-
setOverride(record.id, {
|
|
177
|
-
source: { type: "url", uri: result.optimizedUri! },
|
|
178
|
-
label: "Optimized preview",
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
>
|
|
182
|
-
<Text style={styles.actionText}>Preview in place</Text>
|
|
183
|
-
</TouchableOpacity>
|
|
184
|
-
) : null}
|
|
185
|
-
<TouchableOpacity style={styles.actionButton} onPress={run} disabled={busy}>
|
|
186
|
-
<Text style={styles.actionText}>{busy ? "Re-encoding…" : "Re-run"}</Text>
|
|
187
|
-
</TouchableOpacity>
|
|
188
|
-
</View>
|
|
189
|
-
</>
|
|
190
|
-
)}
|
|
191
|
-
</Section>
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export function ImageDetail({ record }: ImageDetailProps) {
|
|
196
|
-
const verdict = sizeVerdict(record);
|
|
197
|
-
const cache = cacheBadge(record);
|
|
198
|
-
const needed = neededPixels(record);
|
|
199
|
-
const decoded = estDecodedBytes(record);
|
|
200
|
-
const wasted = estWastedBytes(record);
|
|
201
|
-
|
|
202
|
-
return (
|
|
203
|
-
<ScrollView style={styles.container} contentContainerStyle={styles.content}>
|
|
204
|
-
{record.overrideLabel ? (
|
|
205
|
-
<View style={styles.overrideBanner}>
|
|
206
|
-
<Text style={styles.overrideText}>
|
|
207
|
-
Simulation active: {record.overrideLabel} — stats below describe the
|
|
208
|
-
override, not the original source.
|
|
209
|
-
</Text>
|
|
210
|
-
<TouchableOpacity onPress={() => clearOverride(record.id)}>
|
|
211
|
-
<Text style={styles.overrideRestore}>RESTORE</Text>
|
|
212
|
-
</TouchableOpacity>
|
|
213
|
-
</View>
|
|
214
|
-
) : null}
|
|
215
|
-
|
|
216
|
-
{record.uri && record.sourceKind !== "data" ? (
|
|
217
|
-
<View style={styles.previewBox}>
|
|
218
|
-
<Image
|
|
219
|
-
testID="buoy-internal-images-preview"
|
|
220
|
-
source={{ uri: record.uri }}
|
|
221
|
-
style={styles.preview}
|
|
222
|
-
resizeMode="contain"
|
|
223
|
-
/>
|
|
224
|
-
</View>
|
|
225
|
-
) : null}
|
|
226
|
-
|
|
227
|
-
<Section title="SOURCE">
|
|
228
|
-
<Row label="URI" value={record.uri || "(none)"} />
|
|
229
|
-
<Row label="Kind" value={record.sourceKind} />
|
|
230
|
-
<Row label="Library" value={record.lib === "expo" ? "expo-image" : "RN <Image>"} />
|
|
231
|
-
{record.hasAltText === false ? (
|
|
232
|
-
<Row
|
|
233
|
-
label="Alt text"
|
|
234
|
-
value="missing — add alt/accessibilityLabel"
|
|
235
|
-
color={macOSColors.semantic.warning}
|
|
236
|
-
/>
|
|
237
|
-
) : null}
|
|
238
|
-
{record.mediaType != null ? <Row label="Media type" value={String(record.mediaType)} /> : null}
|
|
239
|
-
{record.isAnimated != null ? (
|
|
240
|
-
<Row label="Animated" value={record.isAnimated ? "yes" : "no"} />
|
|
241
|
-
) : null}
|
|
242
|
-
</Section>
|
|
243
|
-
|
|
244
|
-
<Section title="LOAD">
|
|
245
|
-
<Row
|
|
246
|
-
label="Status"
|
|
247
|
-
value={record.status}
|
|
248
|
-
color={
|
|
249
|
-
record.status === "error"
|
|
250
|
-
? macOSColors.semantic.error
|
|
251
|
-
: record.status === "loaded"
|
|
252
|
-
? macOSColors.semantic.success
|
|
253
|
-
: macOSColors.semantic.warning
|
|
254
|
-
}
|
|
255
|
-
/>
|
|
256
|
-
<Row label="Duration" value={formatMs(record.durationMs)} />
|
|
257
|
-
{record.displayedAt && record.loadedAt ? (
|
|
258
|
-
<Row
|
|
259
|
-
label="Decode → display"
|
|
260
|
-
value={formatMs(Math.max(0, record.displayedAt - record.loadedAt))}
|
|
261
|
-
/>
|
|
262
|
-
) : null}
|
|
263
|
-
<Row label="Cache" value={`${cache.label}`} color={cache.color} />
|
|
264
|
-
{record.cacheVerdictSource ? (
|
|
265
|
-
<Row
|
|
266
|
-
label="Cache source"
|
|
267
|
-
value={
|
|
268
|
-
record.cacheVerdictSource === "event"
|
|
269
|
-
? "reported by expo-image onLoad"
|
|
270
|
-
: "Image.queryCache after load"
|
|
271
|
-
}
|
|
272
|
-
/>
|
|
273
|
-
) : null}
|
|
274
|
-
{record.progressSeen ? (
|
|
275
|
-
<Row
|
|
276
|
-
label="Downloaded"
|
|
277
|
-
value={
|
|
278
|
-
record.bytesTotal
|
|
279
|
-
? `${formatBytes(record.bytesLoaded ?? 0)} / ${formatBytes(record.bytesTotal)}`
|
|
280
|
-
: "network transfer observed"
|
|
281
|
-
}
|
|
282
|
-
/>
|
|
283
|
-
) : null}
|
|
284
|
-
<Row label="Load cycles" value={String(record.loadCount)} />
|
|
285
|
-
<Row label="Still mounted" value={record.mounted ? "yes" : "no"} />
|
|
286
|
-
</Section>
|
|
287
|
-
|
|
288
|
-
<Section title="DIMENSIONS">
|
|
289
|
-
{record.intrinsic ? (
|
|
290
|
-
<Row
|
|
291
|
-
label="Decoded"
|
|
292
|
-
value={`${record.intrinsic.width}×${record.intrinsic.height} px`}
|
|
293
|
-
/>
|
|
294
|
-
) : (
|
|
295
|
-
<Row label="Decoded" value="unknown" />
|
|
296
|
-
)}
|
|
297
|
-
{record.layout ? (
|
|
298
|
-
<Row
|
|
299
|
-
label="Displayed"
|
|
300
|
-
value={`${Math.round(record.layout.width)}×${Math.round(record.layout.height)} dp (needs ${
|
|
301
|
-
needed ? `${needed.width}×${needed.height}` : "?"
|
|
302
|
-
} px @${Math.round(effectivePixelRatio() * 100) / 100}x)`}
|
|
303
|
-
/>
|
|
304
|
-
) : (
|
|
305
|
-
<Row label="Displayed" value="no layout yet" />
|
|
306
|
-
)}
|
|
307
|
-
{verdict.label ? <Row label="Verdict" value={verdict.label} color={verdict.color} /> : null}
|
|
308
|
-
{decoded > 0 ? <Row label="Est. decoded memory" value={formatBytes(decoded)} /> : null}
|
|
309
|
-
{wasted > 0 ? (
|
|
310
|
-
<Row
|
|
311
|
-
label="Est. wasted"
|
|
312
|
-
value={`${formatBytes(wasted)} — resize the source to ${
|
|
313
|
-
needed ? `${needed.width}×${needed.height}` : "the displayed size"
|
|
314
|
-
}`}
|
|
315
|
-
color={macOSColors.semantic.warning}
|
|
316
|
-
/>
|
|
317
|
-
) : null}
|
|
318
|
-
{(record.layoutShifts ?? 0) > 0 ? (
|
|
319
|
-
<Row
|
|
320
|
-
label="Layout shifts"
|
|
321
|
-
value={`${record.layoutShifts} — box resized after load; reserve explicit width/height`}
|
|
322
|
-
color={macOSColors.semantic.warning}
|
|
323
|
-
/>
|
|
324
|
-
) : null}
|
|
325
|
-
</Section>
|
|
326
|
-
|
|
327
|
-
{record.sourceKind === "network" || record.sourceKind === "asset" ? (
|
|
328
|
-
<SavingsSection key={`savings-${record.id}`} record={record} />
|
|
329
|
-
) : null}
|
|
330
|
-
|
|
331
|
-
{record.status === "error" ? (
|
|
332
|
-
<Section title="ERROR">
|
|
333
|
-
<Row label="Message" value={record.error ?? "unknown"} color={macOSColors.semantic.error} />
|
|
334
|
-
{record.errorCode != null ? <Row label="HTTP status" value={String(record.errorCode)} /> : null}
|
|
335
|
-
{record.errorHeaders
|
|
336
|
-
? Object.entries(record.errorHeaders).map(([k, v]) => (
|
|
337
|
-
<Row key={k} label={k} value={String(v)} />
|
|
338
|
-
))
|
|
339
|
-
: null}
|
|
340
|
-
</Section>
|
|
341
|
-
) : null}
|
|
342
|
-
|
|
343
|
-
{record.sourceKind === "network" && record.mounted ? (
|
|
344
|
-
<SwapUrlSection key={record.id} record={record} />
|
|
345
|
-
) : null}
|
|
346
|
-
|
|
347
|
-
{record.lib === "expo" ? (
|
|
348
|
-
<Section title="CACHE ACTIONS (expo-image, global)">
|
|
349
|
-
<View style={styles.actionsRow}>
|
|
350
|
-
<TouchableOpacity style={styles.actionButton} onPress={() => clearExpoCache("memory")}>
|
|
351
|
-
<Text style={styles.actionText}>Clear memory cache</Text>
|
|
352
|
-
</TouchableOpacity>
|
|
353
|
-
<TouchableOpacity style={styles.actionButton} onPress={() => clearExpoCache("disk")}>
|
|
354
|
-
<Text style={styles.actionText}>Clear disk cache</Text>
|
|
355
|
-
</TouchableOpacity>
|
|
356
|
-
</View>
|
|
357
|
-
</Section>
|
|
358
|
-
) : null}
|
|
359
|
-
</ScrollView>
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const styles = StyleSheet.create({
|
|
364
|
-
container: {
|
|
365
|
-
flex: 1,
|
|
366
|
-
},
|
|
367
|
-
content: {
|
|
368
|
-
padding: 12,
|
|
369
|
-
gap: 12,
|
|
370
|
-
},
|
|
371
|
-
previewBox: {
|
|
372
|
-
height: 140,
|
|
373
|
-
borderRadius: 8,
|
|
374
|
-
backgroundColor: night.color.bg,
|
|
375
|
-
overflow: "hidden",
|
|
376
|
-
},
|
|
377
|
-
preview: {
|
|
378
|
-
width: "100%",
|
|
379
|
-
height: "100%",
|
|
380
|
-
},
|
|
381
|
-
section: {
|
|
382
|
-
gap: 6,
|
|
383
|
-
},
|
|
384
|
-
sectionTitle: {
|
|
385
|
-
color: night.color.textTertiary,
|
|
386
|
-
fontSize: 10,
|
|
387
|
-
fontWeight: "700",
|
|
388
|
-
letterSpacing: 0.8,
|
|
389
|
-
},
|
|
390
|
-
sectionBody: {
|
|
391
|
-
backgroundColor: night.color.surface,
|
|
392
|
-
borderRadius: 8,
|
|
393
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
394
|
-
borderColor: night.color.border,
|
|
395
|
-
paddingHorizontal: 10,
|
|
396
|
-
paddingVertical: 4,
|
|
397
|
-
},
|
|
398
|
-
kvRow: {
|
|
399
|
-
flexDirection: "row",
|
|
400
|
-
paddingVertical: 5,
|
|
401
|
-
gap: 12,
|
|
402
|
-
},
|
|
403
|
-
kvLabel: {
|
|
404
|
-
color: night.color.textSecondary,
|
|
405
|
-
fontSize: 11,
|
|
406
|
-
width: 110,
|
|
407
|
-
},
|
|
408
|
-
kvValue: {
|
|
409
|
-
color: night.color.text,
|
|
410
|
-
fontSize: 11,
|
|
411
|
-
flex: 1,
|
|
412
|
-
},
|
|
413
|
-
actionsRow: {
|
|
414
|
-
flexDirection: "row",
|
|
415
|
-
gap: 8,
|
|
416
|
-
paddingVertical: 8,
|
|
417
|
-
},
|
|
418
|
-
actionButton: {
|
|
419
|
-
backgroundColor: night.color.surfaceElevated,
|
|
420
|
-
borderRadius: 6,
|
|
421
|
-
paddingHorizontal: 10,
|
|
422
|
-
paddingVertical: 6,
|
|
423
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
424
|
-
borderColor: night.color.border,
|
|
425
|
-
},
|
|
426
|
-
actionText: {
|
|
427
|
-
color: night.color.text,
|
|
428
|
-
fontSize: 11,
|
|
429
|
-
fontWeight: "600",
|
|
430
|
-
},
|
|
431
|
-
actionDisabled: {
|
|
432
|
-
opacity: 0.4,
|
|
433
|
-
},
|
|
434
|
-
urlInput: {
|
|
435
|
-
color: night.color.text,
|
|
436
|
-
fontSize: 11,
|
|
437
|
-
fontFamily: "monospace",
|
|
438
|
-
backgroundColor: night.color.surfaceElevated,
|
|
439
|
-
borderRadius: 6,
|
|
440
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
441
|
-
borderColor: night.color.border,
|
|
442
|
-
paddingHorizontal: 8,
|
|
443
|
-
paddingVertical: 6,
|
|
444
|
-
marginTop: 8,
|
|
445
|
-
},
|
|
446
|
-
overrideBanner: {
|
|
447
|
-
flexDirection: "row",
|
|
448
|
-
alignItems: "center",
|
|
449
|
-
gap: 10,
|
|
450
|
-
padding: 10,
|
|
451
|
-
borderRadius: 8,
|
|
452
|
-
backgroundColor: night.color.warningSoft,
|
|
453
|
-
},
|
|
454
|
-
overrideText: {
|
|
455
|
-
flex: 1,
|
|
456
|
-
color: night.color.warning,
|
|
457
|
-
fontSize: 11,
|
|
458
|
-
lineHeight: 15,
|
|
459
|
-
},
|
|
460
|
-
overrideRestore: {
|
|
461
|
-
color: night.color.warning,
|
|
462
|
-
fontSize: 11,
|
|
463
|
-
fontWeight: "700",
|
|
464
|
-
letterSpacing: 0.5,
|
|
465
|
-
},
|
|
466
|
-
});
|