@@ -43,43 +43,53 @@ fun Avatar(
4343 var isFocused = remember { mutableStateOf(false ) }
4444 val focusManager = LocalFocusManager .current
4545
46- // Determine the modifier based on whether the avatar is focusable
47- val outerModifier =
48- Modifier .then(
49- if (isFocusable) {
50- Modifier .padding(4 .dp)
51- } else Modifier ) // Add padding if focusable
52- .size((size * 1.5f ).dp)
53- .clip(CircleShape )
54- .background(if (isFocused.value) MaterialTheme .colorScheme.surface else Color .Transparent )
55- .onFocusChanged { focusState -> isFocused.value = focusState.isFocused }
56- .then(if (isFocusable) Modifier .focusable() else Modifier ) // Conditionally add focusable
57- .clickable(
58- interactionSource = remember { MutableInteractionSource () },
59- indication = ripple(bounded = true ),
60- onClick = {
61- action?.invoke()
62- focusManager.clearFocus() // Clear focus after clicking
63- })
64-
65- // Outer Box for the larger focusable and clickable area
66- Box (contentAlignment = Alignment .Center , modifier = outerModifier) {
67- // Inner Box to hold the avatar content (Icon or AsyncImage)
68- Box (contentAlignment = Alignment .Center , modifier = Modifier .size(size.dp).clip(CircleShape )) {
69- if (profile?.UserProfile ?.ProfilePicURL != null ) {
70- AsyncImage (
71- model = profile.UserProfile .ProfilePicURL ,
72- modifier = Modifier .size(size.dp).clip(CircleShape ),
73- contentDescription = null )
74- } else {
75- Icon (
76- imageVector = Icons .Default .Person ,
77- contentDescription = stringResource(R .string.settings_title),
78- modifier =
79- Modifier .size((size * 0.8f ).dp)
80- .clip(CircleShape ) // Icon size slightly smaller than the Box
46+ // Outer Box for the larger focusable and clickable area
47+ Box (
48+ contentAlignment = Alignment .Center ,
49+ modifier = Modifier
50+ .padding(4 .dp)
51+ .size((size * 1.5f ).dp) // Focusable area is larger than the avatar
52+ .clip(CircleShape ) // Ensure both the focus and click area are circular
53+ .background(
54+ if (isFocused.value) MaterialTheme .colorScheme.surface
55+ else Color .Transparent ,
56+ )
57+ .onFocusChanged { focusState ->
58+ isFocused.value = focusState.isFocused
59+ }
60+ .focusable() // Make this outer Box focusable (after onFocusChanged)
61+ .clickable(
62+ interactionSource = remember { MutableInteractionSource () },
63+ indication = ripple(bounded = true ), // Apply ripple effect inside circular bounds
64+ onClick = {
65+ action?.invoke()
66+ focusManager.clearFocus() // Clear focus after clicking the avatar
67+ }
8168 )
82- }
83- }
69+ ) {
70+ // Inner Box to hold the avatar content (Icon or AsyncImage)
71+ Box (
72+ contentAlignment = Alignment .Center ,
73+ modifier = Modifier
74+ .size(size.dp)
75+ .clip(CircleShape )
76+ ) {
77+ // Always display the default icon as a background layer
78+ Icon (
79+ imageVector = Icons .Default .Person ,
80+ contentDescription = stringResource(R .string.settings_title),
81+ modifier =
82+ Modifier .size((size * 0.8f ).dp)
83+ .clip(CircleShape ) // Icon size slightly smaller than the Box
84+ )
85+
86+ // Overlay the profile picture if available
87+ profile?.UserProfile ?.ProfilePicURL ?.let { url ->
88+ AsyncImage (
89+ model = url,
90+ modifier = Modifier .size(size.dp).clip(CircleShape ),
91+ contentDescription = null )
92+ }
93+ }
8494 }
8595}
0 commit comments