#!/bin/bash # # CloserApp — IME/keyboard-handling scanner (Pass J pre-check) # # WHY: the app is edge-to-edge (WindowCompat, decorFitsSystemWindows=false) with # windowSoftInputMode=adjustResize. Under edge-to-edge the window does NOT physically resize, so any # screen with a text field must reserve keyboard space via WindowInsets — `imePadding()` or # `safeDrawingPadding()` — or the soft keyboard overlays the fields and they can't be typed into. # This scanner caught DateReflectionScreen shipping without it ("you can't type in Date Reflection"). # # It flags every file containing a text field (OutlinedTextField / BasicTextField / TextField) that does # NOT itself call imePadding()/safeDrawingPadding(). Reusable *components* that are always hosted inside an # IME-handling screen are allowlisted below (verify the host still handles IME before adding one). # # ⛔ CLAUDE: keep this runnable from the project root; update the allowlist ONLY after confirming the # component's host screens handle IME. Exit code is non-zero if any non-allowlisted file is missing. # # Usage: ./scripts/ime-scan.sh set -euo pipefail PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" UI_DIR="$PROJECT_ROOT/app/src/main/java/app/closer/ui" # Components whose IME handling is provided by their host screen (verified). Basenames only. ALLOWLIST=( "QuestionAnswerInput.kt" # hosted by QuestionThreadScreen (imePadding) + LocalQuestionContent (safeDrawingPadding) "QuestionDiscussionThread.kt" # hosted by QuestionThreadScreen (imePadding) ) is_allowlisted() { local base="$1" for a in "${ALLOWLIST[@]}"; do [[ "$base" == "$a" ]] && return 0; done return 1 } fail=0 printf '=== IME/keyboard-handling scan (text-input screens) ===\n\n' # Files with any text-input composable. mapfile -t files < <(grep -rlE "OutlinedTextField\(|BasicTextField\(| TextField\(" "$UI_DIR" 2>/dev/null | sort) for f in "${files[@]}"; do base="$(basename "$f")" rel="${f#"$PROJECT_ROOT"/}" if grep -qE "imePadding|safeDrawingPadding" "$f"; then printf ' OK %s\n' "$rel" elif is_allowlisted "$base"; then printf ' OK(host) %s (component; host handles IME)\n' "$rel" else printf ' ** MISSING IME ** %s\n' "$rel" fail=1 fi done echo if [[ "$fail" -ne 0 ]]; then echo "FAIL: one or more text-input screens lack imePadding()/safeDrawingPadding()." echo "Add IME handling to the scrollable content Column (see e.g. ConversationScreen.kt), or allowlist" echo "the file here ONLY if it is a component whose host screen already handles IME." exit 1 fi echo "PASS: every text-input screen handles the keyboard."