SkateSpots/android-templates/network_security_config.xml
shakespeare.diy 2e6a20dc2b Citrine: native cleartext config, default-pool write wiring, polished UI (1.3.1)
Completes the local-relay integration so it actually works end-to-end and feels
first-class.

Native (Android):
- android-templates/network_security_config.xml — permits cleartext for
  LOOPBACK ONLY (127.0.0.1 / localhost / ::1); all real traffic stays TLS. This
  is what lets ws://127.0.0.1 (Citrine) connect on API 28+, which otherwise
  silently blocks cleartext.
- scripts/inject-network-security.mjs — idempotently copies the XML into
  res/xml/ and adds android:networkSecurityConfig to <application>, mirroring
  the existing inject-amber-queries pattern so it survives `cap sync`.
- Wired into android:init / android:sync / android:build.

Reads AND writes now reach Citrine app-wide:
- NostrProvider's NPool routers (reqRouter/eventRouter) fold in the active
  Citrine URL via a ref, so every default-pool query hits it first (instant
  local reads) and every useNostrPublish write also lands on-device (backup +
  offline capture). Previously only explicit useSkateRelays paths benefited.
- A dedicated effect refreshes ['nostr'] queries when the local relay comes/goes
  so reads switch over immediately. Fully no-op off-Android (url stays null).

UI/UX (Relays settings CitrineCard):
- Four crisp states — off / searching / live / waiting — with a breathing then
  glowing status pip, benefit chips (Instant reads · Works offline · On-device
  backup) that pop in on connect, a spinning Recheck, an actionable install CTA,
  and a persistent encryption-reassurance note.
- Graceful first-run: shows "searching" until the first probe settles (via new
  useCitrine.settled), never flashing the orange "not detected" state.

Tailwind: added status-breathe / status-live / pop-in keyframes+animations.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-08 19:11:51 +07:00

35 lines
1.6 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!--
Android network security config for SkateSpots.
WHY THIS EXISTS
───────────────
Android API 28+ defaults cleartextTrafficPermitted to FALSE. The optional
local Citrine relay (github.com/greenart7c3/Citrine) listens on a plaintext
loopback WebSocket (ws://127.0.0.1 / ws://localhost). Without a cleartext
allow-entry the OS silently refuses that socket, so the in-app "Local Relay"
probe can never turn green even when Citrine is running.
SCOPE — deliberately minimal:
• Cleartext is permitted ONLY for loopback addresses (127.0.0.1, ::1,
localhost). Nothing else.
• The base config keeps cleartextTrafficPermitted="false", so ALL real
network traffic (wss:// relays, https:// APIs, Blossom, etc.) stays
encrypted and is unaffected. This is strictly narrower than flipping the
global usesCleartextTraffic flag.
Kept as the source of truth in android-templates/ and copied into
android/app/src/main/res/xml/ on every build by
scripts/inject-network-security.mjs (idempotent).
-->
<network-security-config>
<!-- Everything not explicitly listed below: no cleartext, encrypted only. -->
<base-config cleartextTrafficPermitted="false" />
<!-- Loopback only: the on-device Citrine relay. -->
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">127.0.0.1</domain>
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">::1</domain>
</domain-config>
</network-security-config>