Update message composer design for unencrypted rooms (#4361)

* Update message composer design for unencrypted rooms.
* Move the encryption banner to the composer toolbar.
This commit is contained in:
Stefan Ceriu
2025-07-28 19:21:13 +03:00
committed by GitHub
parent 64978986f2
commit 82c7dfe28d
20 changed files with 61 additions and 67 deletions
@@ -28,7 +28,7 @@ struct PillViewOnBubble_Previews: PreviewProvider, TestablePreview {
mockMessage
.offset(y: -1)
.frame(maxWidth: .infinity, alignment: .leading)
.messageComposerStyle(isEncrypted: false)
.messageComposerStyle()
SendButton { }
}
@@ -69,7 +69,7 @@ struct MediaUploadPreviewScreen: View {
captionWarningButton
}
}
.messageComposerStyle(isEncrypted: context.viewState.isRoomEncrypted)
.messageComposerStyle()
SendButton {
context.send(viewAction: .send)
@@ -42,10 +42,25 @@ struct ComposerToolbar: View {
}
}
.readFrame($frame)
.safeAreaInset(edge: .top) {
if !context.viewState.isRoomEncrypted {
Label {
Text(L10n.commonNotEncrypted)
.font(.compound.bodySM)
.foregroundStyle(.compound.textSecondary)
} icon: {
CompoundIcon(\.lockOff, size: .xSmall, relativeTo: .compound.bodyMD)
.foregroundStyle(.compound.iconInfoPrimary)
}
.padding(4.0)
}
}
.overlay(alignment: .bottom) {
if verticalSizeClass != .compact, !context.composerExpanded {
suggestionView
.offset(y: -frame.height)
ZStack {
if verticalSizeClass != .compact, !context.composerExpanded {
suggestionView
.offset(y: -frame.height)
}
}
}
.disabled(!context.viewState.canSend)
@@ -162,8 +177,7 @@ struct ComposerToolbar: View {
placeholder: placeholder,
composerFormattingEnabled: context.composerFormattingEnabled,
showResizeGrabber: context.composerFormattingEnabled,
isExpanded: $context.composerExpanded,
isEncrypted: context.viewState.isRoomEncrypted) {
isExpanded: $context.composerExpanded) {
sendMessage()
} editAction: {
context.send(viewAction: .editLastMessage)
@@ -236,11 +250,7 @@ struct ComposerToolbar: View {
}
private var composerPlaceholder: String {
if context.viewState.isRoomEncrypted {
return L10n.richTextEditorComposerPlaceholder
} else {
return L10n.richTextEditorComposerUnencryptedPlaceholder
}
L10n.richTextEditorComposerPlaceholder
}
private var composerView: WysiwygComposerView {
@@ -24,7 +24,6 @@ struct MessageComposer: View {
let composerFormattingEnabled: Bool
let showResizeGrabber: Bool
@Binding var isExpanded: Bool
let isEncrypted: Bool
let sendAction: () -> Void
let editAction: () -> Void
@@ -42,7 +41,7 @@ struct MessageComposer: View {
}
composerTextField
.messageComposerStyle(header: header, isEncrypted: isEncrypted)
.messageComposerStyle(header: header)
// Explicitly disable all animations to fix weirdness with the header immediately
// appearing whilst the text field and keyboard are still animating up to it.
.animation(.noAnimation, value: mode)
@@ -200,8 +199,8 @@ private struct MessageComposerHeaderLabelStyle: LabelStyle {
// MARK: - Style
extension View {
func messageComposerStyle(header: some View = EmptyView(), isEncrypted: Bool) -> some View {
modifier(MessageComposerStyleModifier(header: header, isEncrypted: isEncrypted))
func messageComposerStyle(header: some View = EmptyView()) -> some View {
modifier(MessageComposerStyleModifier(header: header))
}
}
@@ -209,20 +208,14 @@ private struct MessageComposerStyleModifier<Header: View>: ViewModifier {
private let composerShape = RoundedRectangle(cornerRadius: 21, style: .circular)
let header: Header
let isEncrypted: Bool
func body(content: Content) -> some View {
VStack(alignment: .leading, spacing: -6) {
header
HStack(alignment: .top, spacing: 6) {
icon
.scaledOffset(y: 2)
content
.tint(.compound.iconAccentTertiary)
}
.padding(.vertical, 10)
content
.tint(.compound.iconAccentTertiary)
.padding(.vertical, 10)
}
.padding(.horizontal, 12.0)
.clipShape(composerShape)
@@ -235,14 +228,6 @@ private struct MessageComposerStyleModifier<Header: View>: ViewModifier {
}
}
}
@ViewBuilder
private var icon: some View {
if !isEncrypted {
CompoundIcon(\.lockOff, size: .xSmall, relativeTo: .compound.bodyMD)
.foregroundStyle(.compound.iconInfoPrimary)
}
}
}
// MARK: - Previews
@@ -294,7 +279,7 @@ struct MessageComposer_Previews: PreviewProvider, TestablePreview {
static func messageComposer(_ content: NSAttributedString = .init(string: ""),
mode: ComposerMode = .default,
placeholder: String = L10n.richTextEditorComposerEncryptedPlaceholder) -> MessageComposer {
placeholder: String = L10n.richTextEditorComposerPlaceholder) -> MessageComposer {
let viewModel = WysiwygComposerViewModel(minHeight: 22,
maxExpandedHeight: 250)
viewModel.setMarkdownContent(content.string)
@@ -314,7 +299,6 @@ struct MessageComposer_Previews: PreviewProvider, TestablePreview {
composerFormattingEnabled: false,
showResizeGrabber: false,
isExpanded: .constant(false),
isEncrypted: false,
sendAction: { },
editAction: { },
pasteAction: { _ in },