Identity change: handle click on "learn more"

This commit is contained in:
Benoit Marty
2024-10-08 09:35:18 +02:00
parent 67140fe165
commit 57e45aa834
4 changed files with 34 additions and 17 deletions

View File

@@ -9,4 +9,5 @@ package io.element.android.appconfig
object LearnMoreConfig {
const val SECURE_BACKUP_URL: String = "https://element.io/help#encryption5"
const val IDENTITY_CHANGE_URL: String = "https://element.io/help#encryption18"
}

View File

@@ -27,13 +27,14 @@ import com.bumble.appyx.core.plugin.plugins
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.messages.impl.attachments.Attachment
import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents
import io.element.android.features.messages.impl.timeline.TimelineEvents
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.libraries.androidutils.system.openUrlInExternalApp
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
import io.element.android.libraries.androidutils.system.toast
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs
@@ -122,7 +123,8 @@ class MessagesNode @AssistedInject constructor(
}
private fun onLinkClick(
context: Context,
activity: Activity,
darkTheme: Boolean,
url: String,
eventSink: (TimelineEvents) -> Unit,
) {
@@ -133,11 +135,11 @@ class MessagesNode @AssistedInject constructor(
callbacks.forEach { it.onUserDataClick(permalink.userId) }
}
is PermalinkData.RoomLink -> {
handleRoomLinkClick(context, permalink, eventSink)
handleRoomLinkClick(activity, permalink, eventSink)
}
is PermalinkData.FallbackLink,
is PermalinkData.RoomEmailInviteLink -> {
context.openUrlInExternalApp(url)
activity.openUrlInChromeCustomTab(null, darkTheme, url)
}
}
}
@@ -195,6 +197,7 @@ class MessagesNode @AssistedInject constructor(
@Composable
override fun View(modifier: Modifier) {
val activity = LocalContext.current as Activity
val isDark = ElementTheme.isLightTheme.not()
CompositionLocalProvider(
LocalTimelineItemPresenterFactories provides timelineItemPresenterFactories,
) {
@@ -212,7 +215,7 @@ class MessagesNode @AssistedInject constructor(
onEventClick = this::onEventClick,
onPreviewAttachments = this::onPreviewAttachments,
onUserDataClick = this::onUserDataClick,
onLinkClick = { onLinkClick(activity, it, state.timelineState.eventSink) },
onLinkClick = { url -> onLinkClick(activity, isDark, url, state.timelineState.eventSink) },
onSendLocationClick = this::onSendLocationClick,
onCreatePollClick = this::onCreatePollClick,
onJoinCallClick = this::onJoinCallClick,

View File

@@ -417,6 +417,7 @@ private fun MessagesViewContent(
MessagesViewComposerBottomSheetContents(
subcomposing = subcomposing,
state = state,
onLinkClick = onLinkClick,
)
},
sheetContentKey = sheetResizeContentKey.intValue,
@@ -430,6 +431,7 @@ private fun MessagesViewContent(
private fun MessagesViewComposerBottomSheetContents(
subcomposing: Boolean,
state: MessagesState,
onLinkClick: (String) -> Unit,
) {
if (state.userEventPermissions.canSendMessage) {
Column(modifier = Modifier.fillMaxWidth()) {
@@ -453,7 +455,10 @@ private fun MessagesViewComposerBottomSheetContents(
// Do not show the identity change if user is composing a Rich message or is seeing suggestion(s).
if (state.composerState.suggestions.isEmpty() &&
state.composerState.textEditorState is TextEditorState.Markdown) {
IdentityChangeStateView(state.identityChangeState)
IdentityChangeStateView(
state = state.identityChangeState,
onLinkClick = onLinkClick,
)
}
MessageComposerView(
state = state.composerState,

View File

@@ -10,11 +10,13 @@ package io.element.android.features.messages.impl.crypto.identity
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.appconfig.LearnMoreConfig
import io.element.android.libraries.designsystem.atomic.molecules.ComposerAlertMolecule
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -26,6 +28,7 @@ import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun IdentityChangeStateView(
state: IdentityChangeState,
onLinkClick: (String) -> Unit,
modifier: Modifier = Modifier,
) {
// Pick the first identity change to PinViolation
@@ -38,27 +41,31 @@ fun IdentityChangeStateView(
modifier = modifier,
avatar = identityChange.roomMember.getAvatarData(AvatarSize.ComposerAlert),
content = buildAnnotatedString {
val coloredPart = stringResource(CommonStrings.action_learn_more)
val learnMoreStr = stringResource(CommonStrings.action_learn_more)
val fullText = stringResource(
CommonStrings.crypto_identity_change_pin_violation,
id = CommonStrings.crypto_identity_change_pin_violation,
identityChange.roomMember.disambiguatedDisplayName,
coloredPart,
learnMoreStr,
)
val startIndex = fullText.indexOf(coloredPart)
val learnMoreStartIndex = fullText.indexOf(learnMoreStr)
append(fullText)
addStyle(
style = SpanStyle(
textDecoration = TextDecoration.Underline,
fontWeight = FontWeight.Bold,
),
start = startIndex,
end = startIndex + coloredPart.length,
start = learnMoreStartIndex,
end = learnMoreStartIndex + learnMoreStr.length,
)
addStringAnnotation(
tag = "LEARN_MORE",
annotation = "TODO",
start = startIndex,
end = startIndex + coloredPart.length
addLink(
url = LinkAnnotation.Url(
url = LearnMoreConfig.IDENTITY_CHANGE_URL,
linkInteractionListener = { t ->
onLinkClick(LearnMoreConfig.IDENTITY_CHANGE_URL)
}
),
start = learnMoreStartIndex,
end = learnMoreStartIndex + learnMoreStr.length,
)
},
onSubmitClick = { state.eventSink(IdentityChangeEvent.Submit(identityChange.roomMember.userId)) },
@@ -74,5 +81,6 @@ internal fun IdentityChangeStateViewPreview(
) = ElementPreview {
IdentityChangeStateView(
state = state,
onLinkClick = {},
)
}