@@ -23,12 +23,17 @@ import androidx.compose.foundation.layout.Arrangement
2323import androidx.compose.foundation.layout.PaddingValues
2424import androidx.compose.foundation.layout.Row
2525import androidx.compose.foundation.layout.Spacer
26+ import androidx.compose.foundation.layout.WindowInsets
27+ import androidx.compose.foundation.layout.WindowInsetsSides
2628import androidx.compose.foundation.layout.defaultMinSize
2729import androidx.compose.foundation.layout.fillMaxHeight
2830import androidx.compose.foundation.layout.fillMaxSize
2931import androidx.compose.foundation.layout.height
32+ import androidx.compose.foundation.layout.only
3033import androidx.compose.foundation.layout.padding
34+ import androidx.compose.foundation.layout.safeDrawing
3135import androidx.compose.foundation.layout.size
36+ import androidx.compose.foundation.layout.windowInsetsPadding
3237import androidx.compose.foundation.lazy.grid.GridCells
3338import androidx.compose.foundation.lazy.grid.GridItemSpan
3439import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
@@ -184,11 +189,21 @@ fun MainScreen() {
184189
185190 Surface (modifier = Modifier .fillMaxSize()) {
186191 Row (modifier = Modifier .fillMaxSize()) {
192+ // NavigationRail already draws its background edge-to-edge (behind the status bar) while
193+ // insetting its own items, so we only need to inset the content area on the remaining sides.
187194 CategoryNavigationRail (
188195 selectedCategory = selectedCategory,
189196 onCategorySelected = { selectedCategory = it },
190197 )
191- Surface (modifier = Modifier .fillMaxSize()) {
198+ Surface (
199+ modifier =
200+ Modifier .fillMaxSize()
201+ .windowInsetsPadding(
202+ WindowInsets .safeDrawing.only(
203+ WindowInsetsSides .Top + WindowInsetsSides .Bottom + WindowInsetsSides .End
204+ )
205+ )
206+ ) {
192207 when (selectedCategory) {
193208 Category .ERRORS -> ErrorsScreen ()
194209 Category .TRACING -> TracingScreen ()
@@ -271,15 +286,25 @@ fun ErrorsScreen() {
271286 ) {
272287 item {
273288 SentryTraced (" crash_from_java" ) {
274- OutlinedButton (onClick = { throw RuntimeException (" Uncaught Exception from Java." ) }) {
289+ OutlinedButton (
290+ onClick = {
291+ tagSampleAction(" crash_from_java" )
292+ throw RuntimeException (" Crash from Java button: uncaught RuntimeException" )
293+ }
294+ ) {
275295 Text (" Crash from Java" , maxLines = 2 , overflow = TextOverflow .Ellipsis )
276296 }
277297 }
278298 }
279299 item {
280300 SentryTraced (" capture_exception" ) {
281301 OutlinedButton (
282- onClick = { Sentry .captureException(Exception (Exception (Exception (" Some exception." )))) },
302+ onClick = {
303+ tagSampleAction(" capture_exception" )
304+ Sentry .captureException(
305+ Exception (Exception (Exception (" Capture Exception button: nested exception" )))
306+ )
307+ },
283308 modifier = Modifier ,
284309 ) {
285310 Text (" Capture Exception" , maxLines = 2 , overflow = TextOverflow .Ellipsis )
@@ -290,11 +315,12 @@ fun ErrorsScreen() {
290315 SentryTraced (" breadcrumb" ) {
291316 OutlinedButton (
292317 onClick = {
293- Sentry .addBreadcrumb(" Breadcrumb" )
318+ tagSampleAction(" breadcrumb" )
319+ Sentry .addBreadcrumb(" Breadcrumb button clicked" )
294320 Sentry .setExtra(" extra" , " extra" )
295321 Sentry .setFingerprint(listOf (" fingerprint" ))
296322 Sentry .setTransaction(" transaction" )
297- Sentry .captureException(Exception (" Some exception with scope. " ))
323+ Sentry .captureException(Exception (" Breadcrumb button: exception with scope data " ))
298324 },
299325 modifier = Modifier ,
300326 ) {
@@ -304,21 +330,39 @@ fun ErrorsScreen() {
304330 }
305331 item {
306332 SentryTraced (" stack_overflow" ) {
307- OutlinedButton (onClick = { stackOverflow() }, modifier = Modifier ) {
333+ OutlinedButton (
334+ onClick = {
335+ tagSampleAction(" stack_overflow" )
336+ stackOverflow()
337+ },
338+ modifier = Modifier ,
339+ ) {
308340 Text (" Stack Overflow" , maxLines = 2 , overflow = TextOverflow .Ellipsis )
309341 }
310342 }
311343 }
312344 item {
313345 SentryTraced (" native_crash" ) {
314- OutlinedButton (onClick = { NativeSample .crash() }, modifier = Modifier ) {
346+ OutlinedButton (
347+ onClick = {
348+ tagSampleAction(" native_crash" )
349+ NativeSample .crash()
350+ },
351+ modifier = Modifier ,
352+ ) {
315353 Text (" Native Crash" , maxLines = 2 , overflow = TextOverflow .Ellipsis )
316354 }
317355 }
318356 }
319357 item {
320358 SentryTraced (" native_capture" ) {
321- OutlinedButton (onClick = { NativeSample .message() }, modifier = Modifier ) {
359+ OutlinedButton (
360+ onClick = {
361+ tagSampleAction(" native_capture" )
362+ NativeSample .message()
363+ },
364+ modifier = Modifier ,
365+ ) {
322366 Text (" Native Capture" , maxLines = 2 , overflow = TextOverflow .Ellipsis )
323367 }
324368 }
@@ -327,6 +371,7 @@ fun ErrorsScreen() {
327371 SentryTraced (" anr" ) {
328372 OutlinedButton (
329373 onClick = {
374+ tagSampleAction(" anr" )
330375 Thread {
331376 synchronized(mutex) {
332377 while (true ) {
@@ -341,7 +386,14 @@ fun ErrorsScreen() {
341386 .start()
342387
343388 Handler (Looper .getMainLooper())
344- .postDelayed({ synchronized(mutex) { throw IllegalStateException () } }, 1000 )
389+ .postDelayed(
390+ {
391+ synchronized(mutex) {
392+ throw IllegalStateException (" ANR button: main thread blocked" )
393+ }
394+ },
395+ 1000 ,
396+ )
345397 },
346398 modifier = Modifier ,
347399 ) {
@@ -353,10 +405,18 @@ fun ErrorsScreen() {
353405 SentryTraced (" native_anr" ) {
354406 OutlinedButton (
355407 onClick = {
408+ tagSampleAction(" native_anr" )
356409 Thread { NativeSample .freezeMysteriously(mutex) }.start()
357410
358411 Handler (Looper .getMainLooper())
359- .postDelayed({ synchronized(mutex) { throw IllegalStateException () } }, 1000 )
412+ .postDelayed(
413+ {
414+ synchronized(mutex) {
415+ throw IllegalStateException (" ANR (native) button: main thread blocked" )
416+ }
417+ },
418+ 1000 ,
419+ )
360420 },
361421 modifier = Modifier ,
362422 ) {
@@ -368,6 +428,7 @@ fun ErrorsScreen() {
368428 SentryTraced (" out_of_memory" ) {
369429 OutlinedButton (
370430 onClick = {
431+ tagSampleAction(" out_of_memory" )
371432 val latch = CountDownLatch (1 )
372433 for (i in 0 until 20 ) {
373434 Thread {
@@ -393,7 +454,13 @@ fun ErrorsScreen() {
393454 }
394455 item {
395456 SentryTraced (" send_message" ) {
396- OutlinedButton (onClick = { Sentry .captureMessage(" Some message." ) }, modifier = Modifier ) {
457+ OutlinedButton (
458+ onClick = {
459+ tagSampleAction(" send_message" )
460+ Sentry .captureMessage(" Send Message button: test message" )
461+ },
462+ modifier = Modifier ,
463+ ) {
397464 Text (" Send Message" , maxLines = 2 , overflow = TextOverflow .Ellipsis )
398465 }
399466 }
@@ -402,11 +469,12 @@ fun ErrorsScreen() {
402469 SentryTraced (" test_timber" ) {
403470 OutlinedButton (
404471 onClick = {
472+ tagSampleAction(" test_timber" )
405473 crashCount.intValue++
406- Timber .i(" Some info here " )
474+ Timber .i(" Test Timber button: info log " )
407475 Timber .e(
408- RuntimeException (" Uncaught Exception from Java. " ),
409- " Something wrong happened ${crashCount.intValue} times" ,
476+ RuntimeException (" Test Timber button: error RuntimeException " ),
477+ " Test Timber button: error logged ${crashCount.intValue} times" ,
410478 )
411479 },
412480 modifier = Modifier ,
@@ -935,3 +1003,8 @@ fun Context.getActivity(): ComponentActivity {
9351003fun stackOverflow () {
9361004 stackOverflow()
9371005}
1006+
1007+ private fun tagSampleAction (action : String ) {
1008+ // Tag every event with the button that triggered it so it can be filtered in Sentry.
1009+ Sentry .setTag(" sample_action" , action)
1010+ }
0 commit comments