Skip to content

feat: Add vcard - #816

Draft
Elouan1411 wants to merge 35 commits into
mainfrom
old-vcard
Draft

feat: Add vcard#816
Elouan1411 wants to merge 35 commits into
mainfrom
old-vcard

Conversation

@Elouan1411

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings July 16, 2026 11:50
Comment thread Ui/Compose/ContactCard/src/main/AndroidManifest.xml Fixed
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>

@Elouan1411 Elouan1411 Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ContactCard has no network calls, should I still do something?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a reusable Compose contact-card feature with local persistence, QR presentation, and vCard sharing.

Changes:

  • Adds contact-card models and Room schema v9.
  • Adds creation, editing, preview, deletion, QR, and sharing UI.
  • Registers the module and required dependencies/resources.

Reviewed changes

Copilot reviewed 55 out of 55 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
Ui/Compose/ContactCard/src/main/res/xml/contact_card_paths.xml Configures shareable cache paths.
Ui/Compose/ContactCard/src/main/res/values/strings.xml Adds default UI strings.
Ui/Compose/ContactCard/src/main/res/values-sv/strings.xml Adds Swedish translations.
Ui/Compose/ContactCard/src/main/res/values-pt/strings.xml Adds Portuguese translations.
Ui/Compose/ContactCard/src/main/res/values-pl/strings.xml Adds Polish translations.
Ui/Compose/ContactCard/src/main/res/values-nl/strings.xml Adds Dutch translations.
Ui/Compose/ContactCard/src/main/res/values-nb/strings.xml Adds Norwegian translations.
Ui/Compose/ContactCard/src/main/res/values-it/strings.xml Adds Italian translations.
Ui/Compose/ContactCard/src/main/res/values-fr/strings.xml Adds French translations.
Ui/Compose/ContactCard/src/main/res/values-fi/strings.xml Adds Finnish translations.
Ui/Compose/ContactCard/src/main/res/values-es/strings.xml Adds Spanish translations.
Ui/Compose/ContactCard/src/main/res/values-el/strings.xml Adds Greek translations.
Ui/Compose/ContactCard/src/main/res/values-de/strings.xml Adds German translations.
Ui/Compose/ContactCard/src/main/res/values-da/strings.xml Adds Danish translations.
Ui/Compose/ContactCard/src/main/res/drawable/onboarding_vcard.xml Adds onboarding illustration.
Ui/Compose/ContactCard/src/main/res/drawable/ic_x.xml Adds X icon.
Ui/Compose/ContactCard/src/main/res/drawable/ic_pencil.xml Adds edit icon.
Ui/Compose/ContactCard/src/main/res/drawable/ic_linkedin.xml Adds LinkedIn icon.
Ui/Compose/ContactCard/src/main/res/drawable/ic_link.xml Adds link icon.
Ui/Compose/ContactCard/src/main/res/drawable/ic_instagram.xml Adds Instagram icon.
Ui/Compose/ContactCard/src/main/res/drawable/ic_facebook.xml Adds Facebook icon.
Ui/Compose/ContactCard/src/main/res/drawable/ic_bin.xml Adds deletion icon.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/ContactCardViewModel.kt Manages editing and persistence state.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/ContactCardShareExt.kt Creates and shares vCard files.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/ContactCardScreen.kt Coordinates feature screens and actions.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/ContactCardFileProvider.kt Defines the sharing provider.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/SectionCard.kt Adds editor section containers.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/QrCodeHeader.kt Renders vCard QR codes.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/PreviewTopBar.kt Adds preview navigation actions.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/PreviewData.kt Supplies Compose preview data.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/PreviewContent.kt Renders contact-card previews.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/PreviewActionsBottomSheet.kt Adds edit and delete actions.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/OnboardingContent.kt Adds feature onboarding UI.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/LoadingContent.kt Adds loading UI.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/LinksRow.kt Displays link-type icons.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/FieldDivider.kt Adds editor field dividers.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/EditorTopBar.kt Adds save and cancel actions.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/EditorField.kt Defines contact editor fields.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/EditorContent.kt Implements contact-card editing.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/ContactVCardBloc.kt Composes the visual contact card.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/ContactInfoRows.kt Displays contact details.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/ContactCardConstants.kt Defines shared dimensions.
Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/BottomSheetAction.kt Defines bottom-sheet actions.
Ui/Compose/ContactCard/src/main/AndroidManifest.xml Registers the file provider.
Ui/Compose/ContactCard/build.gradle.kts Configures the new module.
settings.gradle.kts Includes the ContactCard module.
Network/build.gradle.kts Exposes OkHttp transitively.
gradle/core.versions.toml Adds dependencies and module alias.
Auth/src/main/kotlin/com/infomaniak/core/auth/room/UserDatabase.kt Adds card conversion and migration.
Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/User.kt Associates cards with users.
Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt Defines card models and vCard output.
Auth/src/main/kotlin/com/infomaniak/core/auth/CredentialManager.kt Removes the duplicated user lookup.
Auth/src/main/kotlin/com/infomaniak/core/auth/BaseCredentialManager.kt Adds shared user access/update APIs.
Auth/schemas/com.infomaniak.core.auth.room.UserDatabase/9.json Records Room schema v9.
Auth/build.gradle.kts Adds Compose UI dependency.

Comment thread Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt Outdated
Comment thread Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt Outdated
Comment thread Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt Outdated
Comment thread Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/User.kt
Comment thread Ui/Compose/ContactCard/build.gradle.kts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 62 out of 62 changed files in this pull request and generated 11 comments.

Comment thread Ui/Compose/ContactCard/build.gradle.kts
Comment thread Ui/Compose/ContactCard/build.gradle.kts
Comment thread Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt Outdated
Comment on lines +48 to +49
@SerializedName("card") @SerialName("card")
val card: Card? = null,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Card did not exist before this PR, is there still an issue?

Comment thread Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 62 out of 62 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (6)

Ui/Compose/ContactCard/build.gradle.kts:18

  • ContactCardScreen, ContactCardViewModel, and the sharing extensions expose Card/User in their public signatures, but Auth is hidden from consumers' compile classpaths as an implementation dependency. An app depending only on this module can therefore fail to compile against those APIs. This dependency must be exposed with api.
    implementation(project(":Auth"))

Ui/Compose/ContactCard/build.gradle.kts:36

  • This adds QRose as a runtime dependency, but LICENSES.md has no QRose entry. The repository requires that file to be updated whenever a runtime dependency is added or removed.
    implementation(core.qrose)

Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/component/EditorContent.kt:71

  • These callbacks and the state write run directly during composition. Composition may be retried or abandoned, which can trigger duplicate database saves or invalid state mutations. Handle requestSave in a LaunchedEffect(requestSave) (or model save as an event outside composition).
    if (requestSave) {
        onSaveHandled()
        if (isValid) onSave() else showValidationError = true

Ui/Compose/ContactCard/src/main/kotlin/com/infomaniak/core/ui/compose/contactcard/ContactCardScreen.kt:230

  • The back button has no accessibility label, so TalkBack announces an unlabeled control. Add a localized “Back” content description rather than treating this interactive icon as decorative.
                        contentDescription = null,

Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/User.kt:49

  • Inserting this defaulted parameter before the existing required login parameter still breaks every positional User(...) call in consuming composite builds: the former login argument is now matched to Card. Preserve source compatibility by appending the optional field after the existing constructor parameters (and regenerate the Room schema).
    @SerializedName("card") @SerialName("card")
    val card: Card? = null,

Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt:64

  • The embedded bytes are always declared as JPEG, but avatarBase64 can come from any successful avatar response, including PNG or WebP. Such a mismatched PHOTO property is ignored by some contact importers. Carry the response media type into vCard generation and emit the corresponding TYPE (or omit the photo when unsupported).
        if (!forQRCode) {
            avatarBase64?.let {
                builder.appendLine("PHOTO;ENCODING=b;TYPE=JPEG:$it")
            }

Comment thread Ui/Compose/ContactCard/src/main/AndroidManifest.xml Outdated
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 63 out of 63 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (3)

Auth/src/main/kotlin/com/infomaniak/core/auth/models/user/Card.kt:69

  • vCard 3.0 folds at 75 UTF-8 octets, but this compares and slices UTF-16 character positions. Non-ASCII names or organizations can therefore produce overlong lines, and slicing can split a surrogate pair, yielding an invalid vCard. Fold the encoded bytes while keeping UTF-8 code points intact.
    private fun StringBuilder.appendVCardLine(content: String) {
        val maxOctets = 75
        if (content.length <= maxOctets) {

Ui/Compose/ContactCard/build.gradle.kts:36

  • qrose is a new runtime dependency, but it is absent from LICENSES.md. Add QRose and its MIT license to the repository license inventory as required for runtime dependency changes.
    implementation(core.qrose)

Ui/Compose/ContactCard/build.gradle.kts:18

  • The module's public APIs expose Card and User types (for example, ContactCardScreen takes (Card) -> Unit), but Auth is hidden as an implementation dependency. A consumer depending only on ContactCard will not receive those types on its compile classpath. Export Auth with api so this independently consumed module has a usable public contract.
    implementation(project(":Auth"))

Comment on lines +61 to +62
open suspend fun updateUser(user: User) {
userDatabase.userDao().update(user)
Comment thread Ui/Compose/ContactCard/build.gradle.kts Outdated
Comment on lines +64 to +65
val mimeType = body.contentType()?.subtype?.uppercase()
val base64 = Base64.encodeToString(body.bytes(), Base64.NO_WRAP)
fun ContactCardScreen(
onBack: () -> Unit,
onShare: (Card) -> Unit,
viewModel: ContactCardViewModel = viewModel(),
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

💡 Need a hand with PR review? Try Gitar by Sonar!

@Elouan1411
Elouan1411 marked this pull request as draft July 23, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants