mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-05 22:36:34 +00:00
Add profile editor, member invite and status banners (#4)
* feat(healthchat): add profile editor, member invite and status banners Native 13-field profile editor with diff-only saves and avatar upload through the HealthChat API (replaces the upstream display-name editor), email invitation for approved accounts, and non-dismissible account status banners in settings and the member directory. * fix(healthchat): satisfy detekt and konsist rules Konsist presenter helper shape, no '=' in state parameter docs, present-tense invite callback, and complete renderer KDoc.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-compose-library")
|
||||
id("kotlin-parcelize")
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -16,7 +17,7 @@ android {
|
||||
dependencies {
|
||||
api(libs.kotlinx.collections.immutable)
|
||||
implementation(libs.coroutines.core)
|
||||
implementation(projects.libraries.architecture)
|
||||
api(projects.libraries.architecture)
|
||||
implementation(projects.libraries.designsystem)
|
||||
api(projects.libraries.matrix.api)
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Novaloop AG
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.healthchat.api
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
/**
|
||||
* Renders the HealthChat account status banners ("account under review", "profile incomplete").
|
||||
*
|
||||
* Both states resolve server-side (approval, completed profile), so the banners are
|
||||
* deliberately not dismissible. When nothing needs attention, nothing is rendered.
|
||||
*/
|
||||
fun interface HealthChatAccountStatusRenderer {
|
||||
/**
|
||||
* @param onCompleteProfileClick called when the user taps the banner action to complete their profile.
|
||||
* @param includePendingApproval false when the host screen already shows its own
|
||||
* pending-approval banner (e.g. the member directory with the verbatim server message).
|
||||
* @param modifier the modifier to apply to the banner.
|
||||
*/
|
||||
@Composable
|
||||
fun Render(
|
||||
onCompleteProfileClick: () -> Unit,
|
||||
includePendingApproval: Boolean,
|
||||
modifier: Modifier,
|
||||
)
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Novaloop AG
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.healthchat.api
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||
import io.element.android.libraries.architecture.NodeInputs
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* Entry point into the fork-owned HealthChat flow (profile editor, member invitation).
|
||||
*/
|
||||
fun interface HealthChatEntryPoint : FeatureEntryPoint {
|
||||
data class Params(
|
||||
val initialTarget: InitialTarget,
|
||||
) : NodeInputs
|
||||
|
||||
sealed interface InitialTarget : Parcelable {
|
||||
@Parcelize
|
||||
data object EditOwnProfile : InitialTarget
|
||||
|
||||
@Parcelize
|
||||
data object Invite : InitialTarget
|
||||
}
|
||||
|
||||
interface Callback : Plugin {
|
||||
fun onDone()
|
||||
}
|
||||
|
||||
fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
params: Params,
|
||||
callback: Callback,
|
||||
): Node
|
||||
}
|
||||
@@ -37,4 +37,46 @@
|
||||
<string name="healthchat_a11y_refresh">Aktualisieren</string>
|
||||
<string name="healthchat_a11y_edit_profile">Profil bearbeiten</string>
|
||||
<string name="healthchat_a11y_invite_member">Neues Mitglied einladen</string>
|
||||
<string name="healthchat_field_name">Anzeigename</string>
|
||||
<string name="healthchat_field_title">Titel</string>
|
||||
<string name="healthchat_field_title_placeholder">z.B. Dr. med.</string>
|
||||
<string name="healthchat_field_first_name">Vorname</string>
|
||||
<string name="healthchat_field_last_name">Nachname</string>
|
||||
<string name="healthchat_field_specialty_placeholder">z.B. Allgemeinmedizin</string>
|
||||
<string name="healthchat_field_practice_name_placeholder">z.B. Praxis Muster</string>
|
||||
<string name="healthchat_field_city">Ort</string>
|
||||
<string name="healthchat_field_city_placeholder">z.B. Zürich</string>
|
||||
<string name="healthchat_field_business_email_placeholder">praxis@beispiel.ch</string>
|
||||
<string name="healthchat_field_business_tel_placeholder">+41 44 123 45 67</string>
|
||||
<!-- Swiss German: "Strasse" (no ß) is correct for this product. -->
|
||||
<string name="healthchat_field_street" tools:ignore="Typos">Strasse</string>
|
||||
<string name="healthchat_field_house_number">Nr.</string>
|
||||
<string name="healthchat_field_postal_code">PLZ</string>
|
||||
<string name="healthchat_field_website_placeholder">https://praxis-muster.ch</string>
|
||||
<string name="healthchat_screen_edit_profile_title">Profil bearbeiten</string>
|
||||
<string name="healthchat_screen_edit_profile_section_personal">Persönliche Angaben</string>
|
||||
<string name="healthchat_screen_edit_profile_section_professional">Berufliche Angaben</string>
|
||||
<string name="healthchat_screen_edit_profile_section_contact">Kontaktdaten</string>
|
||||
<string name="healthchat_screen_edit_profile_section_address">Praxisadresse</string>
|
||||
<string name="healthchat_screen_edit_profile_saving">Profil wird gespeichert…</string>
|
||||
<string name="healthchat_screen_edit_profile_error_title">Profil konnte nicht gespeichert werden</string>
|
||||
<string name="healthchat_screen_edit_profile_load_error">Das Profil konnte nicht geladen werden.</string>
|
||||
<string name="healthchat_screen_edit_profile_recommended">Für ein vollständiges Profil empfohlen</string>
|
||||
<string name="healthchat_error_field_required">Dieses Feld ist erforderlich</string>
|
||||
<string name="healthchat_error_invalid_email">Bitte eine gültige E-Mail-Adresse eingeben</string>
|
||||
<string name="healthchat_error_invalid_url">Bitte eine gültige URL eingeben (z.B. https://praxis-muster.ch)</string>
|
||||
<string name="healthchat_error_note_too_short">Die persönliche Nachricht muss mindestens 10 Zeichen lang sein</string>
|
||||
<string name="healthchat_error_avatar_too_large">Das Bild darf höchstens 2 MB gross sein.</string>
|
||||
<string name="healthchat_banner_incomplete_title">Profil unvollständig</string>
|
||||
<string name="healthchat_banner_incomplete_description">Bitte vervollständigen Sie Ihr Profil, damit andere Mitglieder Sie finden können. Fehlende Angaben: %1$s</string>
|
||||
<string name="healthchat_banner_incomplete_action">Profil vervollständigen</string>
|
||||
<string name="healthchat_screen_invite_title">Mitglied einladen</string>
|
||||
<string name="healthchat_screen_invite_description">Laden Sie neue Mitglieder zu HealthChat ein, indem Sie deren E-Mail-Adresse und eine persönliche Nachricht eingeben.</string>
|
||||
<string name="healthchat_screen_invite_email_label">E-Mail-Adresse</string>
|
||||
<string name="healthchat_screen_invite_email_placeholder">beispiel@domain.ch</string>
|
||||
<string name="healthchat_screen_invite_note_label">Persönliche Nachricht</string>
|
||||
<string name="healthchat_screen_invite_note_placeholder">Schreiben Sie eine persönliche Nachricht an das neue Mitglied…</string>
|
||||
<string name="healthchat_screen_invite_note_counter">%1$d/10 Zeichen</string>
|
||||
<string name="healthchat_screen_invite_send">Einladung senden</string>
|
||||
<string name="healthchat_screen_invite_sending">Einladung wird gesendet…</string>
|
||||
</resources>
|
||||
|
||||
@@ -38,4 +38,45 @@
|
||||
<string name="healthchat_a11y_refresh">Actualiser</string>
|
||||
<string name="healthchat_a11y_edit_profile">Modifier le profil</string>
|
||||
<string name="healthchat_a11y_invite_member">Inviter un nouveau membre</string>
|
||||
<string name="healthchat_field_name">Nom affiché</string>
|
||||
<string name="healthchat_field_title">Titre</string>
|
||||
<string name="healthchat_field_title_placeholder">p. ex. Dr méd.</string>
|
||||
<string name="healthchat_field_first_name">Prénom</string>
|
||||
<string name="healthchat_field_last_name">Nom</string>
|
||||
<string name="healthchat_field_specialty_placeholder">p. ex. médecine générale</string>
|
||||
<string name="healthchat_field_practice_name_placeholder">p. ex. Praxis Muster</string>
|
||||
<string name="healthchat_field_city">Ville</string>
|
||||
<string name="healthchat_field_city_placeholder">p. ex. Zurich</string>
|
||||
<string name="healthchat_field_business_email_placeholder">cabinet@exemple.ch</string>
|
||||
<string name="healthchat_field_business_tel_placeholder">+41 44 123 45 67</string>
|
||||
<string name="healthchat_field_street">Rue</string>
|
||||
<string name="healthchat_field_house_number">N°</string>
|
||||
<string name="healthchat_field_postal_code">NPA</string>
|
||||
<string name="healthchat_field_website_placeholder">https://praxis-muster.ch</string>
|
||||
<string name="healthchat_screen_edit_profile_title">Modifier le profil</string>
|
||||
<string name="healthchat_screen_edit_profile_section_personal">Informations personnelles</string>
|
||||
<string name="healthchat_screen_edit_profile_section_professional">Informations professionnelles</string>
|
||||
<string name="healthchat_screen_edit_profile_section_contact">Coordonnées</string>
|
||||
<string name="healthchat_screen_edit_profile_section_address">Adresse du cabinet</string>
|
||||
<string name="healthchat_screen_edit_profile_saving">Enregistrement du profil…</string>
|
||||
<string name="healthchat_screen_edit_profile_error_title">Impossible d’enregistrer le profil</string>
|
||||
<string name="healthchat_screen_edit_profile_load_error">Le profil n’a pas pu être chargé.</string>
|
||||
<string name="healthchat_screen_edit_profile_recommended">Recommandé pour un profil complet</string>
|
||||
<string name="healthchat_error_field_required">Ce champ est obligatoire</string>
|
||||
<string name="healthchat_error_invalid_email">Veuillez saisir une adresse e-mail valide</string>
|
||||
<string name="healthchat_error_invalid_url">Veuillez saisir une URL valide (p. ex. https://praxis-muster.ch)</string>
|
||||
<string name="healthchat_error_note_too_short">Le message personnel doit contenir au moins 10 caractères</string>
|
||||
<string name="healthchat_error_avatar_too_large">L’image ne doit pas dépasser 2 Mo.</string>
|
||||
<string name="healthchat_banner_incomplete_title">Profil incomplet</string>
|
||||
<string name="healthchat_banner_incomplete_description">Veuillez compléter votre profil pour que les autres membres puissent vous trouver. Informations manquantes : %1$s</string>
|
||||
<string name="healthchat_banner_incomplete_action">Compléter le profil</string>
|
||||
<string name="healthchat_screen_invite_title">Inviter un membre</string>
|
||||
<string name="healthchat_screen_invite_description">Invitez de nouveaux membres sur HealthChat en saisissant leur adresse e-mail et un message personnel.</string>
|
||||
<string name="healthchat_screen_invite_email_label">Adresse e-mail</string>
|
||||
<string name="healthchat_screen_invite_email_placeholder">exemple@domaine.ch</string>
|
||||
<string name="healthchat_screen_invite_note_label">Message personnel</string>
|
||||
<string name="healthchat_screen_invite_note_placeholder">Écrivez un message personnel au nouveau membre…</string>
|
||||
<string name="healthchat_screen_invite_note_counter">%1$d/10 caractères</string>
|
||||
<string name="healthchat_screen_invite_send">Envoyer l’invitation</string>
|
||||
<string name="healthchat_screen_invite_sending">Envoi de l’invitation…</string>
|
||||
</resources>
|
||||
|
||||
@@ -38,4 +38,45 @@
|
||||
<string name="healthchat_a11y_refresh">Aggiorna</string>
|
||||
<string name="healthchat_a11y_edit_profile">Modifica profilo</string>
|
||||
<string name="healthchat_a11y_invite_member">Invita un nuovo membro</string>
|
||||
<string name="healthchat_field_name">Nome visualizzato</string>
|
||||
<string name="healthchat_field_title">Titolo</string>
|
||||
<string name="healthchat_field_title_placeholder">ad es. Dr. med.</string>
|
||||
<string name="healthchat_field_first_name">Nome</string>
|
||||
<string name="healthchat_field_last_name">Cognome</string>
|
||||
<string name="healthchat_field_specialty_placeholder">ad es. medicina generale</string>
|
||||
<string name="healthchat_field_practice_name_placeholder">ad es. Praxis Muster</string>
|
||||
<string name="healthchat_field_city">Città</string>
|
||||
<string name="healthchat_field_city_placeholder">ad es. Zurigo</string>
|
||||
<string name="healthchat_field_business_email_placeholder">studio@esempio.ch</string>
|
||||
<string name="healthchat_field_business_tel_placeholder">+41 44 123 45 67</string>
|
||||
<string name="healthchat_field_street">Via</string>
|
||||
<string name="healthchat_field_house_number">N.</string>
|
||||
<string name="healthchat_field_postal_code">CAP</string>
|
||||
<string name="healthchat_field_website_placeholder">https://praxis-muster.ch</string>
|
||||
<string name="healthchat_screen_edit_profile_title">Modifica profilo</string>
|
||||
<string name="healthchat_screen_edit_profile_section_personal">Dati personali</string>
|
||||
<string name="healthchat_screen_edit_profile_section_professional">Dati professionali</string>
|
||||
<string name="healthchat_screen_edit_profile_section_contact">Contatti</string>
|
||||
<string name="healthchat_screen_edit_profile_section_address">Indirizzo dello studio</string>
|
||||
<string name="healthchat_screen_edit_profile_saving">Salvataggio del profilo…</string>
|
||||
<string name="healthchat_screen_edit_profile_error_title">Impossibile salvare il profilo</string>
|
||||
<string name="healthchat_screen_edit_profile_load_error">Impossibile caricare il profilo.</string>
|
||||
<string name="healthchat_screen_edit_profile_recommended">Consigliato per un profilo completo</string>
|
||||
<string name="healthchat_error_field_required">Questo campo è obbligatorio</string>
|
||||
<string name="healthchat_error_invalid_email">Inserisci un indirizzo e-mail valido</string>
|
||||
<string name="healthchat_error_invalid_url">Inserisci un URL valido (ad es. https://praxis-muster.ch)</string>
|
||||
<string name="healthchat_error_note_too_short">Il messaggio personale deve contenere almeno 10 caratteri</string>
|
||||
<string name="healthchat_error_avatar_too_large">L’immagine non deve superare i 2 MB.</string>
|
||||
<string name="healthchat_banner_incomplete_title">Profilo incompleto</string>
|
||||
<string name="healthchat_banner_incomplete_description">Completa il tuo profilo affinché gli altri membri possano trovarti. Dati mancanti: %1$s</string>
|
||||
<string name="healthchat_banner_incomplete_action">Completa il profilo</string>
|
||||
<string name="healthchat_screen_invite_title">Invita un membro</string>
|
||||
<string name="healthchat_screen_invite_description">Invita nuovi membri su HealthChat inserendo il loro indirizzo e-mail e un messaggio personale.</string>
|
||||
<string name="healthchat_screen_invite_email_label">Indirizzo e-mail</string>
|
||||
<string name="healthchat_screen_invite_email_placeholder">esempio@dominio.ch</string>
|
||||
<string name="healthchat_screen_invite_note_label">Messaggio personale</string>
|
||||
<string name="healthchat_screen_invite_note_placeholder">Scrivi un messaggio personale al nuovo membro…</string>
|
||||
<string name="healthchat_screen_invite_note_counter">%1$d/10 caratteri</string>
|
||||
<string name="healthchat_screen_invite_send">Invia invito</string>
|
||||
<string name="healthchat_screen_invite_sending">Invio dell’invito…</string>
|
||||
</resources>
|
||||
|
||||
@@ -38,4 +38,45 @@
|
||||
<string name="healthchat_a11y_refresh">Refresh</string>
|
||||
<string name="healthchat_a11y_edit_profile">Edit profile</string>
|
||||
<string name="healthchat_a11y_invite_member">Invite a new member</string>
|
||||
<string name="healthchat_field_name">Display name</string>
|
||||
<string name="healthchat_field_title">Title</string>
|
||||
<string name="healthchat_field_title_placeholder">e.g. Dr. med.</string>
|
||||
<string name="healthchat_field_first_name">First name</string>
|
||||
<string name="healthchat_field_last_name">Last name</string>
|
||||
<string name="healthchat_field_specialty_placeholder">e.g. general medicine</string>
|
||||
<string name="healthchat_field_practice_name_placeholder">e.g. Praxis Muster</string>
|
||||
<string name="healthchat_field_city">City</string>
|
||||
<string name="healthchat_field_city_placeholder">e.g. Zurich</string>
|
||||
<string name="healthchat_field_business_email_placeholder">praxis@example.ch</string>
|
||||
<string name="healthchat_field_business_tel_placeholder">+41 44 123 45 67</string>
|
||||
<string name="healthchat_field_street">Street</string>
|
||||
<string name="healthchat_field_house_number">No.</string>
|
||||
<string name="healthchat_field_postal_code">Postal code</string>
|
||||
<string name="healthchat_field_website_placeholder">https://praxis-muster.ch</string>
|
||||
<string name="healthchat_screen_edit_profile_title">Edit profile</string>
|
||||
<string name="healthchat_screen_edit_profile_section_personal">Personal details</string>
|
||||
<string name="healthchat_screen_edit_profile_section_professional">Professional details</string>
|
||||
<string name="healthchat_screen_edit_profile_section_contact">Contact details</string>
|
||||
<string name="healthchat_screen_edit_profile_section_address">Practice address</string>
|
||||
<string name="healthchat_screen_edit_profile_saving">Saving profile…</string>
|
||||
<string name="healthchat_screen_edit_profile_error_title">Couldn’t save the profile</string>
|
||||
<string name="healthchat_screen_edit_profile_load_error">The profile couldn’t be loaded.</string>
|
||||
<string name="healthchat_screen_edit_profile_recommended">Recommended for a complete profile</string>
|
||||
<string name="healthchat_error_field_required">This field is required</string>
|
||||
<string name="healthchat_error_invalid_email">Please enter a valid email address</string>
|
||||
<string name="healthchat_error_invalid_url">Please enter a valid URL (e.g. https://praxis-muster.ch)</string>
|
||||
<string name="healthchat_error_note_too_short">The personal message must be at least 10 characters long</string>
|
||||
<string name="healthchat_error_avatar_too_large">The image must not exceed 2 MB.</string>
|
||||
<string name="healthchat_banner_incomplete_title">Profile incomplete</string>
|
||||
<string name="healthchat_banner_incomplete_description">Please complete your profile so other members can find you. Missing details: %1$s</string>
|
||||
<string name="healthchat_banner_incomplete_action">Complete profile</string>
|
||||
<string name="healthchat_screen_invite_title">Invite a member</string>
|
||||
<string name="healthchat_screen_invite_description">Invite new members to HealthChat by entering their email address and a personal message.</string>
|
||||
<string name="healthchat_screen_invite_email_label">Email address</string>
|
||||
<string name="healthchat_screen_invite_email_placeholder">example@domain.ch</string>
|
||||
<string name="healthchat_screen_invite_note_label">Personal message</string>
|
||||
<string name="healthchat_screen_invite_note_placeholder">Write a personal message to the new member…</string>
|
||||
<string name="healthchat_screen_invite_note_counter">%1$d/10 characters</string>
|
||||
<string name="healthchat_screen_invite_send">Send invitation</string>
|
||||
<string name="healthchat_screen_invite_sending">Sending invitation…</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user