🐛 Debug Panel

Wbudowany panel do debugowania requestów w aplikacji.

Szybki start

import rip.nerd.kitsunenet.debug.KNETDebugPanel

// Włącz debug panel (tylko w DEBUG)
if (BuildConfig.DEBUG) {
    KNETDebugPanel.install(application)
}

// Panel pokazuje się przez shake gesture
// lub programowo:
KNETDebugPanel.show()

Integracja z klientem

val debugInterceptor = KNETDebugPanel.interceptor()

val client = KNETClient.builder()
    .apply {
        if (BuildConfig.DEBUG) {
            addInterceptor(debugInterceptor)
        }
    }
    .build()

// Teraz wszystkie requesty są widoczne w panelu

Funkcje panelu

📋 Lista requestów

Wszystkie wykonane requesty z czasem i statusem

🔍 Szczegóły

Headers, body, timing dla każdego requestu

🔄 Replay

Ponowne wykonanie requestu

📤 Export

Export do cURL, Postman, HAR

🔎 Search

Wyszukiwanie po URL, statusie, body

📊 Stats

Statystyki sukcesu, latencji, błędów

Konfiguracja

KNETDebugPanel.configure {
    // Aktywacja
    shakeToOpen = true
    notificationEnabled = true  // Persistent notification

    // Limity
    maxRequests = 500
    maxBodySize = 100_000

    // Retencja
    clearOnAppRestart = false

    // UI
    theme = DebugPanelTheme.DARK
    position = DebugPanelPosition.BOTTOM_SHEET
}

Programmatic access

// Pobierz wszystkie requesty
val requests = KNETDebugPanel.getRequests()

requests.forEach { entry ->
    println("${entry.request.method} ${entry.request.url}")
    println("Status: ${entry.response?.statusCode}")
    println("Time: ${entry.durationMs}ms")
}

// Wyczyść
KNETDebugPanel.clear()

// Export
val har = KNETDebugPanel.exportToHAR()
val curl = KNETDebugPanel.exportToCurl()
val postman = KNETDebugPanel.exportToPostman("My Collection")

Floating button

// Pływający przycisk debug
KNETDebugPanel.showFloatingButton(activity)

// Lub w Activity
class DebugActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        if (BuildConfig.DEBUG) {
            KNETDebugPanel.attachTo(this)
        }
    }
}

Custom UI

// Jeśli chcesz własny UI
@Composable
fun MyDebugPanel() {
    val requests by KNETDebugPanel.requestsFlow.collectAsState()

    LazyColumn {
        items(requests) { entry ->
            RequestItem(entry)
        }
    }
}

@Composable
fun RequestItem(entry: DebugEntry) {
    Card(Modifier.padding(8.dp)) {
        Column(Modifier.padding(16.dp)) {
            Row {
                StatusBadge(entry.response?.statusCode ?: 0)
                Spacer(Modifier.width(8.dp))
                Text(entry.request.method)
                Spacer(Modifier.width(8.dp))
                Text(
                    entry.request.url.substringAfter("://").take(40),
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
            }
            Text("${entry.durationMs}ms", style = MaterialTheme.typography.caption)
        }
    }
}

Network Flipper integration

// Integracja z Facebook Flipper
if (BuildConfig.DEBUG) {
    val networkPlugin = NetworkFlipperPlugin()

    val client = KNETClient.builder()
        .addInterceptor(FlipperOkhttpInterceptor(networkPlugin))
        .build()

    AndroidFlipperClient.getInstance(context).apply {
        addPlugin(networkPlugin)
        start()
    }
}

Bezpieczeństwo

⚠️ Tylko dla DEBUG!

Debug Panel nigdy nie powinien być włączony w production - może ujawnić sensitive data.

// Zawsze sprawdzaj BuildConfig
if (BuildConfig.DEBUG) {
    KNETDebugPanel.install(application)
}

// Lub użyj proguard do usunięcia w release:
// -assumenosideeffects class rip.nerd.kitsunenet.debug.** { *; }

📚 Zobacz też