fix(ui): correct mirrored chat empty-state + clipped IP placeholder; add readiness-check skill; privacy page nav/meta
- app/session/[id].tsx: chat empty-state rendered mirrored on Android (inverted FlatList) — now an untransformed overlay - app/connection/add.tsx: shortened clipped host placeholder - .agents/skills/readiness-check: production-readiness gate (Play+F-Droid published, app+site health) - docs/privacy: back-nav + canonical/theme-color/description meta Verified: tsc clean, CUA smoke green (run 26814702062) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -165,7 +165,7 @@ export default function AddConnectionScreen() {
|
||||
<View style={styles.ipRow}>
|
||||
<TextInput
|
||||
style={[styles.input, styles.ipInput, isDark && styles.inputDark]}
|
||||
placeholder="192.168.1.100 or my-mac.ts.net"
|
||||
placeholder="192.168.1.100"
|
||||
placeholderTextColor={isDark ? "#666666" : "#999999"}
|
||||
value={ip}
|
||||
onChangeText={setIp}
|
||||
|
||||
@@ -516,14 +516,16 @@ export default function SessionScreen() {
|
||||
</View>
|
||||
) : null
|
||||
}
|
||||
ListEmptyComponent={
|
||||
<View style={s.emptyInverted}>
|
||||
<Ionicons name="chatbubble-outline" size={48} color={isDark ? "#444444" : "#cccccc"} />
|
||||
<Text style={[s.emptyText, isDark && s.metaDark]}>Start a conversation</Text>
|
||||
<Text style={[s.emptyHint, isDark && s.metaDark]}>Type / for commands</Text>
|
||||
</View>
|
||||
}
|
||||
/>
|
||||
{/* Empty state rendered OUTSIDE the inverted list to avoid the
|
||||
inverted transform mirroring its text/icon (see #ui-mirror). */}
|
||||
{messageData.length === 0 && (
|
||||
<View style={s.emptyOverlay} pointerEvents="none">
|
||||
<Ionicons name="chatbubble-outline" size={48} color={isDark ? "#444444" : "#cccccc"} />
|
||||
<Text style={[s.emptyText, isDark && s.metaDark]}>Start a conversation</Text>
|
||||
<Text style={[s.emptyHint, isDark && s.metaDark]}>Type / for commands</Text>
|
||||
</View>
|
||||
)}
|
||||
{showScrollButton && (
|
||||
<TouchableOpacity style={[s.scrollBtn, isDark && s.scrollBtnDark]} onPress={() => scrollToBottom(true)}>
|
||||
<Ionicons name="chevron-down" size={24} color={isDark ? "#ffffff" : "#0a0a0a"} />
|
||||
@@ -690,13 +692,13 @@ const s = StyleSheet.create({
|
||||
},
|
||||
loadingMoreText: { fontSize: 13, color: "#999999" },
|
||||
|
||||
// Empty (inverted list flips content, so use transform to un-flip)
|
||||
emptyInverted: {
|
||||
flex: 1,
|
||||
// Empty state overlay — sits on top of the (empty) inverted list, untransformed,
|
||||
// so its text/icon render upright and un-mirrored on Android.
|
||||
emptyOverlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingVertical: 64,
|
||||
transform: [{ scaleY: -1 }],
|
||||
},
|
||||
|
||||
// Empty
|
||||
|
||||
Reference in New Issue
Block a user