AzureCommunicationUI/sdk/AzureCommunicationUICalling/Sources/Presentation/SwiftUI/Calling/CallingViewComponent/CaptionsRtt/CaptionsAndRttLandscapeView.swift (112 lines of code) (raw):

// // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // import SwiftUI import FluentUI internal struct CaptionsAndRttLandscapeView<Content: View>: View { // MARK: - Properties // Bindings @Binding var isAutoCommitted: Bool // Drawer Configuration let title: String? let endIcon: CompositeIcon? let endIconAction: (() -> Void)? let showTextBox: Bool let textBoxHint: String? let commitAction: ((_ message: String, _ isFinal: Bool?) -> Void)? // Content let content: Content // Internal States @State private var text: String = "" @State private var keyboardHeight: CGFloat = 0 // MARK: - Initializer init( title: String? = nil, endIcon: CompositeIcon? = nil, endIconAction: (() -> Void)? = nil, showTextBox: Bool = false, textBoxHint: String? = nil, isAutoCommitted: Binding<Bool> = .constant(false), commitAction: ((_ message: String, _ isFinal: Bool?) -> Void)? = nil, @ViewBuilder content: () -> Content ) { self._isAutoCommitted = isAutoCommitted self.title = title self.endIcon = endIcon self.endIconAction = endIconAction self.showTextBox = showTextBox self.textBoxHint = textBoxHint self.commitAction = commitAction self.content = content() } // MARK: - Body var body: some View { drawerView.onChange(of: isAutoCommitted) { shouldClear in if shouldClear { clearText() } } } // MARK: - Drawer View private var drawerView: some View { VStack { Spacer() VStack { // Title and Icons titleView // Content content // Text Editor (if applicable) if showTextBox { textEditor .frame(height: DrawerConstants.textBoxHeight) .padding([.leading, .trailing], 10) } // Bottom Padding to Push Content Off-Screen Spacer().frame(height: DrawerConstants.textBoxPaddingBottom) } .frame(maxWidth: .infinity, alignment: .bottom) .background(Color(StyleProvider.color.drawerColor)) .clipShape(RoundedCorner(radius: 3, corners: [.topLeft, .bottomLeft])) .padding(.leading, 2) .shadow(radius: 3) .hideKeyboardOnTap() // Dismiss keyboard when tapping outside } } // MARK: - Title View private var titleView: some View { VStack { HStack(spacing: 8) { Spacer() // End Icon (if any) if let icon = endIcon { Icon(name: icon, size: DrawerListConstants.iconSize) .foregroundColor(Color(StyleProvider.color.drawerIconDark)) .onTapGesture { endIconAction?() } } } .padding([.leading, .trailing], 10) .padding(.top, 15) }.overlay( Text(title ?? "") .font(.headline) .foregroundColor(.primary) .accessibilityAddTraits(.isHeader) .padding(.top, 15), alignment: .center ) } // MARK: - Text Editor private var textEditor: some View { CustomTextField( text: $text, placeholder: textBoxHint ?? "", onCommit: { commitAction?(text, true) DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { text = "" } }, onChange: { newText in commitAction?(newText, false) } ) .frame(height: DrawerConstants.textBoxHeight) .frame(maxWidth: .infinity) .onChange(of: isAutoCommitted) { shouldClear in if shouldClear { clearText() } } } // MARK: - Helper Functions /// Clears the text in the text editor and resets auto-commit state. private func clearText() { DispatchQueue.main.async { text = "" isAutoCommitted = false } } }