diff --git a/Sources/SAPCAI/Foundation/Extensions/SimpleTypeExtension.swift b/Sources/SAPCAI/Foundation/Extensions/SimpleTypeExtension.swift index bb39abd..67d66cd 100644 --- a/Sources/SAPCAI/Foundation/Extensions/SimpleTypeExtension.swift +++ b/Sources/SAPCAI/Foundation/Extensions/SimpleTypeExtension.swift @@ -67,6 +67,14 @@ extension String { return nil } } + + func toTelURLString() -> String { + if lowercased().hasPrefix("tel:") { + return replacingOccurrences(of: " ", with: "", options: .literal) + } else { + return "tel:" + replacingOccurrences(of: " ", with: "", options: .literal) + } + } } // MARK: - URL Extension diff --git a/Sources/SAPCAI/Foundation/Model/MessageData.swift b/Sources/SAPCAI/Foundation/Model/MessageData.swift index 65ea427..166090b 100644 --- a/Sources/SAPCAI/Foundation/Model/MessageData.swift +++ b/Sources/SAPCAI/Foundation/Model/MessageData.swift @@ -141,6 +141,12 @@ public protocol ValueData { var rawValue: String? { get } } +extension ValueData { + var isClickable: Bool { + type == .link || type == .email || type == .phoneNumber + } +} + /// Enumeration for possible postback types public enum PostbackDataType: String { /// text diff --git a/Sources/SAPCAI/UI/Common/SwiftUI/ButtonView.swift b/Sources/SAPCAI/UI/Common/SwiftUI/ButtonView.swift index 6ac9c91..d2ce3cd 100644 --- a/Sources/SAPCAI/UI/Common/SwiftUI/ButtonView.swift +++ b/Sources/SAPCAI/UI/Common/SwiftUI/ButtonView.swift @@ -22,7 +22,7 @@ struct ButtonView: View { URLNavigation(isUrlSheetPresented: self.$viewModel.urlOpenerData.isLinkModalPresented).performURLNavigation(value: self.button.value) } else if self.button.dataType == .phoneNumber { // link navigation feature code - self.viewModel.urlOpenerData.url = optimizePrefix(for: button.value) + self.viewModel.urlOpenerData.url = button.value.toTelURLString() URLNavigation(isUrlSheetPresented: self.$viewModel.urlOpenerData.isLinkModalPresented).performURLNavigation(value: self.viewModel.urlOpenerData.url) } else { self.viewModel.postMessage(type: self.type, postbackData: self.button) @@ -51,14 +51,6 @@ struct ButtonView: View { } }) } - - func optimizePrefix(for phoneNumber: String) -> String { - if phoneNumber.lowercased().hasPrefix("tel:") { - return phoneNumber.filter { !$0.isWhitespace } - } else { - return "tel:" + phoneNumber - } - } } #if DEBUG diff --git a/Sources/SAPCAI/UI/Common/SwiftUI/CardSectionsView.swift b/Sources/SAPCAI/UI/Common/SwiftUI/CardSectionsView.swift index ec87c7e..751a4d8 100644 --- a/Sources/SAPCAI/UI/Common/SwiftUI/CardSectionsView.swift +++ b/Sources/SAPCAI/UI/Common/SwiftUI/CardSectionsView.swift @@ -40,7 +40,7 @@ extension CardSectionsView { var body: some View { var urlVal = secAttribute.value! if secAttribute.type == .phoneNumber { - urlVal = "tel:" + secAttribute.value! + urlVal = secAttribute.value!.toTelURLString() } if secAttribute.type == .email { urlVal = "mailto:" + secAttribute.value! @@ -55,14 +55,7 @@ extension CardSectionsView { } Spacer() if secAttribute.value != nil { - if secAttribute.type == .text { - Text(secAttribute.value!) - .font(.body) - .foregroundColor(self.themeManager.color(for: .primary1)) - .lineLimit(1) - .padding([.top, .bottom], 10) - .padding([.trailing], 16) - } else { + if secAttribute.isClickable { Button(action: { self.viewModel.urlOpenerData.url = urlVal URLNavigation(isUrlSheetPresented: self.$viewModel.urlOpenerData.isLinkModalPresented).performURLNavigation(value: urlVal) @@ -73,6 +66,13 @@ extension CardSectionsView { .padding([.top, .bottom], 10) .padding([.trailing], 16) }) + } else { + Text(secAttribute.value!) + .font(.body) + .foregroundColor(self.themeManager.color(for: .primary1)) + .lineLimit(1) + .padding([.top, .bottom], 10) + .padding([.trailing], 16) } } } @@ -86,7 +86,7 @@ extension CardSectionsView { var body: some View { var urlVal = secAttribute.value! if secAttribute.type == .phoneNumber { - urlVal = "tel:" + secAttribute.value! + urlVal = secAttribute.value!.toTelURLString() } if secAttribute.type == .email { urlVal = "mailto:" + secAttribute.value! @@ -102,16 +102,7 @@ extension CardSectionsView { .padding([.trailing], 16) } if secAttribute.value != nil { - if secAttribute.type == .text { - Text(secAttribute.value!) - .font(.body) - .foregroundColor(self.themeManager.color(for: .primary1)) - .padding([.leading], 16) - .padding([.trailing], 16) - .padding([.bottom], 10) - .lineLimit(2) - .fixedSize(horizontal: false, vertical: true) - } else { + if secAttribute.isClickable { Button(action: { self.viewModel.urlOpenerData.url = urlVal URLNavigation(isUrlSheetPresented: self.$viewModel.urlOpenerData.isLinkModalPresented).performURLNavigation(value: urlVal) @@ -124,6 +115,15 @@ extension CardSectionsView { .lineLimit(2) .fixedSize(horizontal: false, vertical: true) }) + } else { + Text(secAttribute.value!) + .font(.body) + .foregroundColor(self.themeManager.color(for: .primary1)) + .padding([.leading], 16) + .padding([.trailing], 16) + .padding([.bottom], 10) + .lineLimit(2) + .fixedSize(horizontal: false, vertical: true) } } } @@ -133,6 +133,7 @@ extension CardSectionsView { struct CardSectionsView_Previews: PreviewProvider { static var previews: some View { - CardSectionsView(section: UIModelDataSection("title", [UIModelDataValue(value: "val1", dataType: nil, rawValue: nil, label: nil, valueState: nil)])) + CardSectionsView(section: PreviewData.cardSectionData) + .environmentObject(ThemeManager.shared) } } diff --git a/Sources/SAPCAI/UI/PreviewData.swift b/Sources/SAPCAI/UI/PreviewData.swift index c00adb4..fc9f401 100644 --- a/Sources/SAPCAI/UI/PreviewData.swift +++ b/Sources/SAPCAI/UI/PreviewData.swift @@ -58,6 +58,27 @@ viewModel.addMessages(contentsOf: [responseData]) return viewModel } + + static var cardSectionData: UIModelDataSection { + func makeDataValue(label: String? = nil, value: String? = nil, dataType: String? = nil) -> UIModelDataValue { + UIModelDataValue(value: value, dataType: dataType, rawValue: nil, label: label, valueState: nil) + } + return UIModelDataSection("title", [makeDataValue(label: "text", + value: "Just text", + dataType: "text"), + makeDataValue(label: "link address", + value: "https://www.sap.com", + dataType: "link"), + makeDataValue(label: "email address", + value: "example@sap.com", + dataType: "email"), + makeDataValue(label: "tel", + value: "+1 23 388913 23 ", + dataType: "phonenumber"), + makeDataValue(label: "real address", + value: "1234, CA, USA", + dataType: "address")]) + } } #endif diff --git a/Tests/SAPCAITests/Foundation/Extensions/SimpleTypeExtensionTests.swift b/Tests/SAPCAITests/Foundation/Extensions/SimpleTypeExtensionTests.swift new file mode 100644 index 0000000..bbc7cb0 --- /dev/null +++ b/Tests/SAPCAITests/Foundation/Extensions/SimpleTypeExtensionTests.swift @@ -0,0 +1,13 @@ +@testable import SAPCAI +import XCTest + +final class SimpleTypeExtensionTests: XCTestCase { + /// String Extension + func testStringtoTelString() { + var telString = "tel: +86 13463637643 " + XCTAssertEqual(telString.toTelURLString(), "tel:+8613463637643") + + telString = " +1 650 44 79 539 " + XCTAssertEqual(telString.toTelURLString(), "tel:+16504479539") + } +}