# Walkthrough - Key Retention, Microphone Permissions, and Map Coordinates Customization

I have successfully resolved the key retention issues, macOS microphone permission hangs, and recently fixed API version errors and microphone indicators. I have also added advanced map customization features.

---

## 1. 🔑 Desktop Key Retention & Obfuscation Fallback ([main.js](file:///Users/jamesarome/Documents/Gravty/main.js))
* **Obfuscation Scheme:** Implemented a custom XOR-base64 obfuscation scheme (`obfuscate` / `deobfuscate`) to serve as the default storage mechanism for keys, completely bypassing `safeStorage` for saving. This eliminates macOS Keychain permissions prompts and potential hangs.
* **Prefixed Keys:** Updated loading to handle prefixed keys: `sec:` for successful `safeStorage` decryption, and `obf:` for the custom obfuscation. This ensures that the decryption handler knows exactly how to decode the values.
* **Backward Compatibility:** Retained compatibility for older keys without a prefix (raw base64 ciphertexts starting with `djEw` or `AQ.`).
* **Recursive Decryptions:** Updated the key decryption helper to recursively handle double-wrapped obfuscations (where raw safeStorage ciphertext is saved inside the custom obfuscation).

---

## 2. 🎙️ Desktop macOS Microphone Permission Hang Fix ([main.js](file:///Users/jamesarome/Documents/Gravty/main.js))
* **Avoid Hanging Prompts:** Modified the `request-microphone-permission` handler. It now queries `systemPreferences.getMediaAccessStatus('microphone')` first. If the status is `'denied'` or `'restricted'`, it returns `false` immediately instead of calling `askForMediaAccess` (which hung macOS when access was already blocked).
* **Dynamically Resolved Logs:** Relocated the hardcoded log output path of `logDebug` from the old conversation directory to the application's native `userData` directory dynamically.

---

## 3. ⚙️ Desktop System Settings Redirection ([App.jsx](file:///Users/jamesarome/Documents/Gravty/src/App.jsx))
* **Modern System Settings Link:** Updated the redirect scheme for macOS to open the modern `x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension` Privacy & Security settings pane.
* **Clear User Steps:** Added a friendly instructions dialog to guide the user on how to enable the microphone under *Privacy & Security -> Microphone* when the macOS settings window launches.

---

## 4. 🔴 Red SVG Microphone Icon ([App.jsx](file:///Users/jamesarome/Documents/Gravty/src/App.jsx))
* **Emoji to SVG Upgrade:** Replaced the plain text emoji `🎙️` (which cannot change color in browsers via CSS) with an inline vector SVG microphone icon.
* **Active Status Color:** Styled the SVG icon to dynamically use `var(--color-error, #ef4444)` (bright red) when the microphone is recording/listening (`isListening` is true), giving the user a clear and obvious recording status indicator.

---

## 5. 🌐 Gemini v1beta Endpoint Restored ([main.js](file:///Users/jamesarome/Documents/Gravty/main.js))
* **v1beta for JSON Output:** Reverted the API endpoint version for `transcribe-audio` and `verify-location-ai` from stable `v1` to `v1beta`. In Google's REST API, the stable `v1` endpoint does not support `responseMimeType` in `generationConfig`, returning a 400 Bad Request. Restoring `v1beta` resolves this error while mapping correctly to current-generation models.
* **Default Model Upgrade:** Mapped default transcription requests to **`gemini-2.5-flash`** to resolve the 404 model retirement error.

---

## 6. 🔒 Chromium Password Autofill Prevention ([App.jsx](file:///Users/jamesarome/Documents/Gravty/src/App.jsx))
* **Autofill Disabling:** Appended `autoComplete="new-password"` to all six API key `<input>` elements (Gemini, OpenAI, Anthropic key fields on both the welcome screen and settings sidebar). This prevents Chromium from automatically filling input fields with old, saved safeStorage ciphertexts (preventing accidental saving of corrupted keys).
* **Validation Filtering:** Added `isValidKey` helper in the UI to reject any loaded key starting with `AQ.`, `djEw`, or `sec:` (old encrypted string signatures), treating them as blank instead of prepopulating garbage.

---

## 7. 🗺️ Custom GPS Overrides & Map Clicking
* **Interactive Map Clicking ([MapComponent.jsx](file:///Users/jamesarome/Documents/Gravty/src/MapComponent.jsx) & [App.jsx](file:///Users/jamesarome/Documents/Gravty/src/App.jsx)):** Added an `onMapClick` callback to the Leaflet maps. The user can now click *anywhere* on the map (e.g., clicking on land to move a pin out of the ocean). Clicking relocates the suggested pin to that exact coordinate on the spot, allowing the user to click "Write EXIF" to save the clicked coordinate.
* **Manual Coordinate Fields ([App.jsx](file:///Users/jamesarome/Documents/Gravty/src/App.jsx)):** Added explicit **Latitude** and **Longitude** text input fields in the "Edit Photo Details" modal, allowing copying/pasting or typing in exact coordinates alongside the Title/Description fields.

---

## 8. 📱 Mobile Speech Recognition Fix ([RoomLoader.jsx](file:///Users/jamesarome/Documents/HomeInventoryMobile/src/components/RoomLoader.jsx))
* **Re-initialization Prevention:** Replaced the closure dependencies of `listeningTarget` inside the `useEffect` hook using a React `useRef` (`listeningTargetRef`). This prevents the `SpeechRecognition` instance from being destroyed and recreated on every single mic click, resolving the bug where dictation could not be stopped.
* **Clean Cleanup:** Added an abort controller `rec.abort()` on component unmount to release native microphone resources cleanly.

---

## 9. 🤖 Android Microphone Permission ([AndroidManifest.xml](file:///Users/jamesarome/Documents/HomeInventoryMobile/android/app/src/main/AndroidManifest.xml))
* **Added Permission:** Appended `<uses-permission android:name="android.permission.RECORD_AUDIO" />` to the native manifest. This enables native recording and speech recognition to work correctly on Android.

---

## 11. 💾 Persistent Home Directory Backup (`main.js`)
* **Mirrored Configuration:** Implemented a secondary configuration mirror (`~/.findplace_backup.json`) in the user's home directory.
* **Automatic Recovery:** If the main application support folder (`~/Library/Application Support/findplace`) is cleared or translocated during an update, the app automatically restores settings, API keys, and license keys from this backup. This prevents license key reactivations on update, avoiding Lemon Squeezy activation limit blockages.

---

## 12. 🧠 AI Prompt Prioritization & Dynamic Re-Verify UI (`App.jsx`)
* **User Hint Overrides:** Modified the AI prompt structure to prioritize the `USER LOCATION HINT` as a ground-truth override over the parent folder context. This resolves incorrect categorizations when folder names are misleading (e.g. Sydney photos inside an Auckland folder).
* **Correction Feedback UI:** Transformed the location hint box dynamically if AI analysis results already exist: the label shifts to `🤖 Location Hint & Correction Feedback (Optional)`, the placeholder shifts to `Enter correct location or feedback to the AI...`, and the action button shifts to `🔄 Re-Verify / Try Again` to clearly direct users on how to refine/correct matches.
* **Help Modal Action Summary:** Cleaned up the action-bar so it is hidden if there is no GPS and no AI analysis. Updated the `❓` help button to manually trigger a glassmorphic modal explaining what each option (Approve, Skip, Edit) does.

---

## 13. 🏠 HomeInventory Desktop App Key Retention & UI Fixes (`main.js`, `App.jsx`, `SettingsPanel.jsx`)
* **XOR-Obfuscation Fallback:** Ported the safeStorage fallback logic to `HomeInventory/main.js`. If Keychain decryption fails due to app updates, the app utilizes deobfuscation to decrypt API keys and license cache, preventing lost keys.
* **Persistent Settings Backup:** Implemented mirrored saving and startup loading/restoring from `~/.homeinventory_backup.json` in the user's home directory.
* **License Activation Sync:** Added an `onLicenseStatusChange` callback to synchronise successful settings-tab activations directly with the parent state in `App.jsx`. This prevents the "Export to Excel" action from re-prompting the user once they have already activated a key on the API/Settings page.
* **Conditional Copyright Footer:** Wrapped the global footer layout in a conditional check so it only renders when the active tab is `'settings'` (API screen).

---

## 14. 🛠️ Build & Verification Results
* **FindPlace App:** Rebuilt and packaged the commercial release successfully for macOS (separate arm64 and x64 DMGs) and Windows (`FindPlace-Trial-Setup-1.0.1.exe`).
* **AI Home Inventory App:** Rebuilt and packaged the commercial release successfully for macOS (separate `arm64` and `x64` DMGs) and Windows (`AI Home Inventory Trial-Setup-1.0.0.exe`). All builds are signed, packaged, and verified.
