From 28d6f62b74f1029735402660cc913755a8d297dc Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Fri, 23 Dec 2022 13:10:00 +0000 Subject: [PATCH] mobile: better layout for feature/preference items (#1631) * mobile: better layout for feature/preference items * refactor --- .../app/views/chat/item/CIChatFeatureView.kt | 2 +- .../app/views/chat/item/CIEventView.kt | 10 ++--- .../chat/item/CIFeaturePreferenceView.kt | 44 +++++++++++-------- .../app/views/chat/item/ChatItemView.kt | 5 ++- .../ChatItem/CIFeaturePreferenceView.swift | 33 +++++++++----- 5 files changed, 55 insertions(+), 39 deletions(-) diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIChatFeatureView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIChatFeatureView.kt index 7f64869e68..347dde80fc 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIChatFeatureView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIChatFeatureView.kt @@ -23,7 +23,7 @@ fun CIChatFeatureView( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp) ) { - Icon(icon ?: feature.iconFilled, feature.text, Modifier.size(15.dp), tint = iconColor) + Icon(icon ?: feature.iconFilled, feature.text, Modifier.size(18.dp), tint = iconColor) Text( chatEventText(chatItem), Modifier, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIEventView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIEventView.kt index 24e15c8026..5b37c402b7 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIEventView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIEventView.kt @@ -32,7 +32,7 @@ fun CIEventView(ci: ChatItem) { if (memberDisplayName != null) { chatEventTextView( buildAnnotatedString { - withChatEventStyle(this, memberDisplayName) + withStyle(chatEventStyle) { append(memberDisplayName) } append(" ") }.plus(chatEventText(ci)) ) @@ -43,15 +43,11 @@ fun CIEventView(ci: ChatItem) { } } -fun withChatEventStyle(builder: AnnotatedString.Builder, text: String) { - return builder.withStyle(SpanStyle(fontSize = 12.sp, fontWeight = FontWeight.Light, color = HighOrLowlight)) { append(text) } -} +val chatEventStyle = SpanStyle(fontSize = 12.sp, fontWeight = FontWeight.Light, color = HighOrLowlight) fun chatEventText(ci: ChatItem): AnnotatedString = buildAnnotatedString { - withChatEventStyle(this, ci.content.text) - append(" ") - withChatEventStyle(this, ci.timestampText) + withStyle(chatEventStyle) { append(ci.content.text + " " + ci.timestampText) } } @Preview(showBackground = true) diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIFeaturePreferenceView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIFeaturePreferenceView.kt index a10ded313f..4d2f51f1b1 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIFeaturePreferenceView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/CIFeaturePreferenceView.kt @@ -1,5 +1,7 @@ package chat.simplex.app.views.chat.item +import android.content.ActivityNotFoundException +import android.util.Log import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.material.* @@ -9,19 +11,22 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.app.R +import chat.simplex.app.TAG import chat.simplex.app.model.* import chat.simplex.app.ui.theme.HighOrLowlight import chat.simplex.app.ui.theme.SimpleButton +import chat.simplex.app.views.helpers.generalGetString @Composable fun CIFeaturePreferenceView( chatItem: ChatItem, - chatInfo: ChatInfo, + contact: Contact?, feature: ChatFeature, allowed: FeatureAllowed, acceptFeature: (Contact, ChatFeature) -> Unit @@ -31,24 +36,25 @@ fun CIFeaturePreferenceView( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp) ) { - Icon(feature.icon, feature.text, Modifier.size(15.dp), tint = HighOrLowlight) - Text(chatItem.content.text, fontSize = 12.sp, fontWeight = FontWeight.Light, color = HighOrLowlight) - if (chatInfo is ChatInfo.Direct && allowed != FeatureAllowed.NO) { - val ct = chatInfo.contact - if (ct.allowsFeature(feature) && !ct.userAllowsFeature(feature)) { - Text(stringResource(R.string.accept), modifier = Modifier.clickable { acceptFeature(ct, feature) }, - fontSize = 12.sp, color = MaterialTheme.colors.primary) + Icon(feature.icon, feature.text, Modifier.size(18.dp), tint = HighOrLowlight) + if (contact != null && allowed != FeatureAllowed.NO && contact.allowsFeature(feature) && !contact.userAllowsFeature(feature)) { + val acceptStyle = SpanStyle(color = MaterialTheme.colors.primary, fontSize = 12.sp) + val annotatedText = buildAnnotatedString { + withStyle(chatEventStyle) { append(chatItem.content.text + " ") } + withAnnotation(tag = "Accept", annotation = "Accept") { + withStyle(acceptStyle) { append(generalGetString(R.string.accept) + " ") } + } + withStyle(chatEventStyle) { append(chatItem.timestampText) } } + fun accept(offset: Int): Boolean = annotatedText.getStringAnnotations(tag = "Accept", start = offset, end = offset).isNotEmpty() + ClickableText( + annotatedText, + onClick = { if (accept(it)) { acceptFeature(contact, feature) } }, + shouldConsumeEvent = ::accept + ) + } else { + Text(chatItem.content.text + " " + chatItem.timestampText, + fontSize = 12.sp, fontWeight = FontWeight.Light, color = HighOrLowlight) } - Text(chatItem.timestampText, fontSize = 12.sp, fontWeight = FontWeight.Light, color = HighOrLowlight) -// buildAnnotatedString { -// withChatEventStyle(this, chatItem.content.text) -// append(" ") -// withChatEventStyle(this, chatItem.timestampText) -// }, -// Modifier, -// // this is important. Otherwise, aligning will be bad because annotated string has a Span with size 12.sp -// fontSize = 12.sp -// ) } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt index b62c4f6d18..3ae8acc2c9 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/item/ChatItemView.kt @@ -226,7 +226,10 @@ fun ChatItemView( is CIContent.SndConnEventContent -> CIEventView(cItem) is CIContent.RcvChatFeature -> CIChatFeatureView(cItem, c.feature, c.enabled.iconColor) is CIContent.SndChatFeature -> CIChatFeatureView(cItem, c.feature, c.enabled.iconColor) - is CIContent.RcvChatPreference -> CIFeaturePreferenceView(cItem, cInfo, c.feature, c.allowed, acceptFeature) + is CIContent.RcvChatPreference -> { + val ct = if (cInfo is ChatInfo.Direct) cInfo.contact else null + CIFeaturePreferenceView(cItem, ct, c.feature, c.allowed, acceptFeature) + } is CIContent.SndChatPreference -> CIChatFeatureView(cItem, c.feature, HighOrLowlight, icon = c.feature.icon,) is CIContent.RcvGroupFeature -> CIChatFeatureView(cItem, c.groupFeature, c.preference.enable.iconColor) is CIContent.SndGroupFeature -> CIChatFeatureView(cItem, c.groupFeature, c.preference.enable.iconColor) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift index 7443a843ee..0f92bf2fca 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift @@ -17,28 +17,39 @@ struct CIFeaturePreferenceView: View { var param: Int? var body: some View { - HStack(alignment: .bottom, spacing: 4) { + HStack(alignment: .center, spacing: 4) { Image(systemName: feature.icon) .foregroundColor(.secondary) .scaleEffect(feature.iconScale) - Text(CIContent.preferenceText(feature, allowed, param)) - .font(.caption) - .foregroundColor(.secondary) - .fontWeight(.light) if let ct = chat.chatInfo.contact, allowed != .no && ct.allowsFeature(feature) && !ct.userAllowsFeature(feature) { - Button("Accept") { allowFeatureToContact(ct, feature) } - .font(.caption) + featurePreferenceView(accept: true) + .onTapGesture { + allowFeatureToContact(ct, feature) + } + } else { + featurePreferenceView() } - chatItem.timestampText - .font(.caption) - .foregroundColor(Color.secondary) - .fontWeight(.light) } .padding(.leading, 6) .padding(.bottom, 6) .textSelection(.disabled) } + + private func featurePreferenceView(accept: Bool = false) -> some View { + var r = Text(CIContent.preferenceText(feature, allowed, param) + " ") + .fontWeight(.light) + .foregroundColor(.secondary) + if accept { + r = r + Text("Accept" + " ") + .fontWeight(.medium) + .foregroundColor(.accentColor) + } + r = r + chatItem.timestampText + .fontWeight(.light) + .foregroundColor(.secondary) + return r.font(.caption) + } } func allowFeatureToContact(_ contact: Contact, _ feature: ChatFeature) {