feat: Add ContactCard ViewModel, sharing and header components - #821
feat: Add ContactCard ViewModel, sharing and header components#821Elouan1411 wants to merge 9 commits into
Conversation
a610d66 to
b7b36a8
Compare
b7b36a8 to
c5063f4
Compare
57135d9 to
64dc46e
Compare
There was a problem hiding this comment.
Pull request overview
Adds contact-card state management and Compose preview components.
Changes:
- Adds card loading, editing, saving, and deletion.
- Adds QR-code header with avatar.
- Adds contact details and social-link presentation.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
ContactCardViewModel.kt |
Manages card state and persistence. |
QrCodeHeader.kt |
Renders the vCard QR header. |
LinksRow.kt |
Displays available link types. |
ContactVCardBloc.kt |
Composes the contact-card preview. |
Comments suppressed due to low confidence (1)
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/ContactCardViewModel.kt:115
- Deleting also writes the whole
Usersnapshot from the preview state through Room@Update. Any profile or preference changes persisted after this snapshot was loaded can therefore be reverted when only the card should change. Delete the card through an atomic card-column update rather than replacing the complete row.
val updatedUser = current.user.copy(card = null)
accountUtils.updateUser(updatedUser)
64dc46e to
823feb5
Compare
823feb5 to
6e61152
Compare
6e61152 to
8632764
Compare
8632764 to
6673f3a
Compare
6673f3a to
a47131d
Compare
a47131d to
eb8d274
Compare
|
|
||
| @DrawableRes | ||
| private fun CardLinkType.iconRes(): Int = when (this) { | ||
| CardLinkType.LinkedIn -> R.drawable.ic_linkedin |
There was a problem hiding this comment.
Could be great to directly have this icon in CardLinkType.
| Surface( | ||
| shape = CircleShape, | ||
| color = MaterialTheme.colorScheme.surface, | ||
| modifier = Modifier | ||
| .size(qrSize * 0.24f) | ||
| .clip(CircleShape), | ||
| ) { | ||
| Box( | ||
| modifier = Modifier.padding(3.dp), | ||
| contentAlignment = Alignment.Center, | ||
| ) { | ||
| Avatar( | ||
| avatarType = AvatarType.fromUser(user), | ||
| modifier = Modifier | ||
| .fillMaxSize() | ||
| .clip(CircleShape), | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
| Surface( | |
| shape = CircleShape, | |
| color = MaterialTheme.colorScheme.surface, | |
| modifier = Modifier | |
| .size(qrSize * 0.24f) | |
| .clip(CircleShape), | |
| ) { | |
| Box( | |
| modifier = Modifier.padding(3.dp), | |
| contentAlignment = Alignment.Center, | |
| ) { | |
| Avatar( | |
| avatarType = AvatarType.fromUser(user), | |
| modifier = Modifier | |
| .fillMaxSize() | |
| .clip(CircleShape), | |
| ) | |
| } | |
| } | |
| Surface( | |
| shape = CircleShape, | |
| color = MaterialTheme.colorScheme.surface, | |
| modifier = Modifier | |
| .size(qrSize * 0.24f) | |
| .clip(CircleShape), | |
| ) { | |
| Avatar( | |
| avatarType = AvatarType.fromUser(user), | |
| modifier = Modifier | |
| .padding(3.dp) | |
| .fillMaxSize() | |
| .clip(CircleShape), | |
| ) | |
| } |
| loadUser() | ||
| } | ||
|
|
||
| fun loadUser() { |
There was a problem hiding this comment.
Why this is public ? It seems you only use if in the init { ... }.
| private val _uiState = MutableStateFlow<ContactCardUiState>(ContactCardUiState.Loading) | ||
| val uiState: StateFlow<ContactCardUiState> = _uiState.asStateFlow() | ||
|
|
||
| private var currentUser: User? = null |
There was a problem hiding this comment.
Instead of having a var and checking everywhere if user is null to do an early return, it would be great to just quit the VCard screen. It makes no sense to be on that screen without a user.
| } | ||
|
|
||
| companion object { | ||
| const val USER_ID_KEY = "userId" |
There was a problem hiding this comment.
No need for this to be public.
eb8d274 to
a47131d
Compare
|



No description provided.