Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Unified Customization to EntryWidget #1059

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions GliaWidgets.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@
C0175A2C2A67E2E9001FACDE /* Theme+Gva.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0175A2B2A67E2E9001FACDE /* Theme+Gva.swift */; };
C02248A72AD53DDA00CC4930 /* LiveObservationConfirmation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C02248A62AD53DDA00CC4930 /* LiveObservationConfirmation.swift */; };
C02248AA2AD53E6100CC4930 /* LiveObservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C02248A92AD53E6100CC4930 /* LiveObservation.swift */; };
C034EEED2CAAB525002650B8 /* EntryWidgetStyle.RemoteConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C034EEEC2CAAB525002650B8 /* EntryWidgetStyle.RemoteConfig.swift */; };
C039FA7F2B19EB6E00DFD0E0 /* MediaPickerLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C039FA7E2B19EB6E00DFD0E0 /* MediaPickerLayoutTests.swift */; };
C039FA812B19ECBA00DFD0E0 /* MediaPickerDynamicFontTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C039FA802B19ECBA00DFD0E0 /* MediaPickerDynamicFontTests.swift */; };
C039FA832B19ED7D00DFD0E0 /* MediaPickerVoiceOverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C039FA822B19ED7D00DFD0E0 /* MediaPickerVoiceOverTests.swift */; };
Expand Down Expand Up @@ -846,6 +847,8 @@
C090478C2B7E5C8F003C437C /* FilePreviewStyle.Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C090478B2B7E5C8F003C437C /* FilePreviewStyle.Equatable.swift */; };
C096B40B297EBDE400F0C552 /* VisitorCodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C096B40A297EBDE400F0C552 /* VisitorCodeTests.swift */; };
C0B325E72AC5A8FA006BC430 /* AlertViewController+LiveObservationConfirmation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0B325E62AC5A8FA006BC430 /* AlertViewController+LiveObservationConfirmation.swift */; };
C0C5BB772CAD4278001B2025 /* MediaTypeItemStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C5BB762CAD4259001B2025 /* MediaTypeItemStyle.swift */; };
C0C5BB792CAD42FD001B2025 /* MediaTypeItemStyle.RemoteConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C5BB782CAD42FD001B2025 /* MediaTypeItemStyle.RemoteConfig.swift */; };
C0D2F02C2991219100803B47 /* VideoCallCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D2F02B2991219100803B47 /* VideoCallCoordinator.swift */; };
C0D2F02E2991221900803B47 /* VideoCallCoordinator.DelegateEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D2F02D2991221900803B47 /* VideoCallCoordinator.DelegateEvent.swift */; };
C0D2F0302991229F00803B47 /* VideoCallCoordinator.Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D2F02F2991229F00803B47 /* VideoCallCoordinator.Environment.swift */; };
Expand Down Expand Up @@ -1706,6 +1709,7 @@
C0175A2B2A67E2E9001FACDE /* Theme+Gva.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Theme+Gva.swift"; sourceTree = "<group>"; };
C02248A62AD53DDA00CC4930 /* LiveObservationConfirmation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveObservationConfirmation.swift; sourceTree = "<group>"; };
C02248A92AD53E6100CC4930 /* LiveObservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveObservation.swift; sourceTree = "<group>"; };
C034EEEC2CAAB525002650B8 /* EntryWidgetStyle.RemoteConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryWidgetStyle.RemoteConfig.swift; sourceTree = "<group>"; };
C039FA7E2B19EB6E00DFD0E0 /* MediaPickerLayoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPickerLayoutTests.swift; sourceTree = "<group>"; };
C039FA802B19ECBA00DFD0E0 /* MediaPickerDynamicFontTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPickerDynamicFontTests.swift; sourceTree = "<group>"; };
C039FA822B19ED7D00DFD0E0 /* MediaPickerVoiceOverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPickerVoiceOverTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1877,6 +1881,8 @@
C090478B2B7E5C8F003C437C /* FilePreviewStyle.Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePreviewStyle.Equatable.swift; sourceTree = "<group>"; };
C096B40A297EBDE400F0C552 /* VisitorCodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisitorCodeTests.swift; sourceTree = "<group>"; };
C0B325E62AC5A8FA006BC430 /* AlertViewController+LiveObservationConfirmation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AlertViewController+LiveObservationConfirmation.swift"; sourceTree = "<group>"; };
C0C5BB762CAD4259001B2025 /* MediaTypeItemStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaTypeItemStyle.swift; sourceTree = "<group>"; };
C0C5BB782CAD42FD001B2025 /* MediaTypeItemStyle.RemoteConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaTypeItemStyle.RemoteConfig.swift; sourceTree = "<group>"; };
C0D2F02B2991219100803B47 /* VideoCallCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallCoordinator.swift; sourceTree = "<group>"; };
C0D2F02D2991221900803B47 /* VideoCallCoordinator.DelegateEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallCoordinator.DelegateEvent.swift; sourceTree = "<group>"; };
C0D2F02F2991229F00803B47 /* VideoCallCoordinator.Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoCallCoordinator.Environment.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4985,14 +4991,17 @@
C0F3DE352C69F4A700DE6D7B /* EntryWidget */ = {
isa = PBXGroup;
children = (
C0F7EA372CA1D6D40038019C /* CustomPresentationController.swift */,
C0F3DE362C69F51D00DE6D7B /* EntryWidget.swift */,
C0F7EA392CA1D7050038019C /* EntryWidget.SizeConstraints.swift */,
C0F3DE382C69FC2100DE6D7B /* EntryWidget.Presentation.swift */,
C0F3DE3E2C6E176A00DE6D7B /* EntryWidget.Channel.swift */,
C0F3DE382C69FC2100DE6D7B /* EntryWidget.Presentation.swift */,
C0F7EA392CA1D7050038019C /* EntryWidget.SizeConstraints.swift */,
C0F3DE442C6E3D7C00DE6D7B /* EntryWidgetStyle.swift */,
C034EEEC2CAAB525002650B8 /* EntryWidgetStyle.RemoteConfig.swift */,
C0F3DE3A2C6E0DD900DE6D7B /* EntryWidgetView.swift */,
C0F3DE3C2C6E170600DE6D7B /* EntryWidgetViewModel.swift */,
C0F3DE442C6E3D7C00DE6D7B /* EntryWidgetStyle.swift */,
C0F7EA372CA1D6D40038019C /* CustomPresentationController.swift */,
C0C5BB762CAD4259001B2025 /* MediaTypeItemStyle.swift */,
C0C5BB782CAD42FD001B2025 /* MediaTypeItemStyle.RemoteConfig.swift */,
);
path = EntryWidget;
sourceTree = "<group>";
Expand Down Expand Up @@ -5632,6 +5641,7 @@
9AE9E4B727E1E30500BFE239 /* MockHelpers.swift in Sources */,
C0EC58CE2B02775100E78C70 /* SnackBar+View+Mock.swift in Sources */,
8464297D2A459E7D00943BD6 /* UIViewController+Replaceble.swift in Sources */,
C0C5BB772CAD4278001B2025 /* MediaTypeItemStyle.swift in Sources */,
C09046EA2B7E0F06003C437C /* Theme.VIsitorChatMessageStyle.RemoteConfig.swift in Sources */,
C09046A82B7D08CD003C437C /* WelcomeStyle.SendButton.LoadingStyle.RemoteConfig.swift in Sources */,
1A2DA72625EF892600032611 /* FilePickerController.swift in Sources */,
Expand Down Expand Up @@ -5799,6 +5809,7 @@
84265E64298D7B2900D65842 /* ScreenSharingViewStyle.Accessibility.swift in Sources */,
756B8B202996EFA2001D2BB2 /* Header.Props.swift in Sources */,
AFA2FDFC289082F500428E6D /* OnHoldOverlayStyle.Mock.swift in Sources */,
C034EEED2CAAB525002650B8 /* EntryWidgetStyle.RemoteConfig.swift in Sources */,
C0F3DE432C6E3D2400DE6D7B /* Theme.EntryWidget.swift in Sources */,
C090476E2B7E2546003C437C /* UnreadMessageDividerStyle.Equatable.swift in Sources */,
C09047602B7E2320003C437C /* ChatFileDownloadStyle.RemoteConfig.swift in Sources */,
Expand Down Expand Up @@ -5961,6 +5972,7 @@
3100D92D296E946600DEC9CE /* SecureConversations.ConfirmationViewModel.swift in Sources */,
75D987FC2AF2D9F90016A702 /* SnackBar.Live.swift in Sources */,
3100EEFB293F363100D57F71 /* SecureConversations.WelcomeView.swift in Sources */,
C0C5BB792CAD42FD001B2025 /* MediaTypeItemStyle.RemoteConfig.swift in Sources */,
1A475BBC25DFA10100296D55 /* UnreadMessagesHandler.swift in Sources */,
C09046752B7CFFCB003C437C /* ConfirmationStyle.CheckMessageButtonStyle.Accessibility.swift in Sources */,
845E2F85283FA90200C04D56 /* Theme.Survey.ValidationError.Accessibility.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import UIKit

final class CustomPresentationController: UIPresentationController {
private let height: CGFloat

private let cornerRadius: CGFloat
private let dimmingView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.black.withAlphaComponent(0.13)
Expand All @@ -12,9 +12,11 @@ final class CustomPresentationController: UIPresentationController {
init(
presentedViewController: UIViewController,
presenting presentingViewController: UIViewController?,
height: CGFloat
height: CGFloat,
cornerRadius: CGFloat
) {
self.height = height
self.cornerRadius = cornerRadius
super.init(
presentedViewController: presentedViewController,
presenting: presentingViewController
Expand Down Expand Up @@ -46,7 +48,7 @@ final class CustomPresentationController: UIPresentationController {

override func containerViewWillLayoutSubviews() {
super.containerViewWillLayoutSubviews()
presentedView?.layer.cornerRadius = 24
presentedView?.layer.cornerRadius = cornerRadius
presentedView?.layer.masksToBounds = true
presentedView?.frame = frameOfPresentedViewInContainerView
}
Expand Down
15 changes: 12 additions & 3 deletions GliaWidgets/Sources/EntryWidget/EntryWidget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,15 @@ private extension EntryWidget {
let view = makeView(model: model)
let hostingController = UIHostingController(rootView: view)

hostingController.view.backgroundColor = UIColor.white
switch theme.entryWidget.backgroundColor {
case .fill(let color):
hostingController.view.backgroundColor = color
case .gradient(let colors):
hostingController.view.makeGradientBackground(
colors: colors,
cornerRadius: theme.entryWidget.cornerRadius
)
}

// Due to the more modern sheet presenting approach being
// available starting from iOS 16, we need to handle cases
Expand All @@ -105,7 +113,7 @@ private extension EntryWidget {
}
sheet.detents = [smallDetent]
sheet.prefersScrollingExpandsWhenScrolledToEdge = true
sheet.preferredCornerRadius = 24
sheet.preferredCornerRadius = theme.entryWidget.cornerRadius
} else {
hostingController.modalPresentationStyle = .custom
hostingController.transitioningDelegate = self
Expand Down Expand Up @@ -163,7 +171,8 @@ extension EntryWidget: UIViewControllerTransitioningDelegate {
return CustomPresentationController(
presentedViewController: presented,
presenting: presenting,
height: height
height: height,
cornerRadius: theme.entryWidget.cornerRadius
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import UIKit

extension EntryWidgetStyle {
mutating func apply(
configuration: RemoteConfiguration.EntryWidget?,
assetsBuilder: RemoteConfiguration.AssetsBuilder
) {
applyBackground(configuration: configuration?.background)
applyDivider(configuration: configuration?.mediaTypeItems?.dividerColor)
applyErrorTitle(
configuration: configuration?.errorTitle,
assetsBuilder: assetsBuilder
)
applyErrorMessage(
configuration: configuration?.errorMessage,
assetsBuilder: assetsBuilder
)
errorButton.apply(
configuration: configuration?.errorButton,
assetsBuilder: assetsBuilder
)
mediaTypeItem.apply(
configuration: configuration?.mediaTypeItems?.mediaTypeItem,
assetsBuilder: assetsBuilder
)
}
}

private extension EntryWidgetStyle {
mutating func applyBackground(configuration: RemoteConfiguration.Layer?) {
configuration?.color.unwrap {
switch $0.type {
case .fill:
$0.value
.map { UIColor(hex: $0) }
.first
.unwrap { backgroundColor = .fill(color: $0) }
case .gradient:
let colors = $0.value.convertToCgColors()
backgroundColor = .gradient(colors: colors)
}
}
configuration?.cornerRadius.unwrap {
cornerRadius = $0
}
}

mutating func applyErrorMessage(
configuration: RemoteConfiguration.Text?,
assetsBuilder: RemoteConfiguration.AssetsBuilder
) {
configuration.unwrap {
UIFont.convertToFont(
uiFont: assetsBuilder.fontBuilder($0.font),
textStyle: errorMessageStyle
).unwrap { errorMessageFont = $0 }

$0.foreground?.value
.map { UIColor(hex: $0) }
.first
.unwrap { errorMessageColor = $0 }
}
}

mutating func applyErrorTitle(
configuration: RemoteConfiguration.Text?,
assetsBuilder: RemoteConfiguration.AssetsBuilder
) {
configuration.unwrap {
UIFont.convertToFont(
uiFont: assetsBuilder.fontBuilder($0.font),
textStyle: errorTitleStyle
).unwrap { errorTitleFont = $0 }

$0.foreground?.value
.map { UIColor(hex: $0) }
.first
.unwrap { errorTitleColor = $0 }
}
}

mutating func applyDivider(configuration: RemoteConfiguration.Color?) {
configuration?.value
.map { UIColor(hex: $0) }
.first
.unwrap { dividerColor = $0 }
}
}
113 changes: 61 additions & 52 deletions GliaWidgets/Sources/EntryWidget/EntryWidgetStyle.swift
Original file line number Diff line number Diff line change
@@ -1,71 +1,80 @@
import UIKit

public struct EntryWidgetStyle {
/// Engagement channel style.
public var channel: EntryWidgetChannelStyle
/// The style of a media type item.
public var mediaTypeItem: MediaTypeItemStyle

/// Background color of the view.
public var backgroundColor: UIColor
/// The background color of the view.
public var backgroundColor: ColorType

/// Style of 'powered by' view.
/// The corner radius of the view.
public var cornerRadius: CGFloat

/// The style of 'powered by' view.
public var poweredBy: PoweredByStyle

/// The color of the dragger
public var draggerColor: UIColor
/// The color of the divider.
public var dividerColor: UIColor

/// - Parameters:
/// - channel: Engagement channel style.
/// - backgroundColor: Background color of the view.
/// - poweredBy: Style of 'powered by' view.
/// - draggerColor: The color of the dragger
///
public init(
channel: EntryWidgetChannelStyle,
backgroundColor: UIColor,
poweredBy: PoweredByStyle,
draggerColor: UIColor
) {
self.channel = channel
self.backgroundColor = backgroundColor
self.poweredBy = poweredBy
self.draggerColor = draggerColor
}
}
/// The font for the title of the error message.
public var errorTitleFont: UIFont

/// The text style for the title of the error message.
public var errorTitleStyle: UIFont.TextStyle

public struct EntryWidgetChannelStyle {
/// Font of the headline text.
public var headlineFont: UIFont
/// The color for the title of the error message.
public var errorTitleColor: UIColor

/// Color of the headline text.
public var headlineColor: UIColor
/// The error message string.
public var errorMessageFont: UIFont

/// Font of the subheadline text.
public var subheadlineFont: UIFont
/// The text style for the error message.
public var errorMessageStyle: UIFont.TextStyle

/// Color of the subheadline text.
public var subheadlineColor: UIColor
/// The color for the error message.
public var errorMessageColor: UIColor

/// Color of the icon.
public var iconColor: UIColor
/// The style of the error button.
public var errorButton: ActionButtonStyle

/// - Parameters:
/// - headlineFont: Font of the headline text.
/// - headlineColor: Color of the headline text.
/// - subheadlineFont: Font of the subheadline text.
/// - subheadlineColor: Color of the subheadline text.
/// - iconColor: Color of the icon.
///
/// - mediaTypeItem: The style of a media type item.
/// - backgroundColor: The background color of the view.
/// - cornerRadius: The corner radius of the view.
/// - poweredBy: The style of the 'powered by' view.
/// - dividerColor: The color of the divider.
/// - errorTitleFont: The font for the title of the error message.
/// - errorTitleStyle: The text style for the title of the error message.
/// - errorTitleColor: The color for the title of the error message.
/// - errorMessage: The error message string.
/// - errorMessageStyle: The text style for the error message.
/// - errorMessageColor: The color for the error message.
/// - errorButton: The style of the error button.
public init(
headlineFont: UIFont,
headlineColor: UIColor,
subheadlineFont: UIFont,
subheadlineColor: UIColor,
iconColor: UIColor
mediaTypeItem: MediaTypeItemStyle,
backgroundColor: ColorType,
cornerRadius: CGFloat,
poweredBy: PoweredByStyle,
dividerColor: UIColor,
errorTitleFont: UIFont,
errorTitleStyle: UIFont.TextStyle,
errorTitleColor: UIColor,
errorMessageFont: UIFont,
errorMessageStyle: UIFont.TextStyle,
errorMessageColor: UIColor,
errorButton: ActionButtonStyle
) {
self.headlineFont = headlineFont
self.headlineColor = headlineColor
self.subheadlineFont = subheadlineFont
self.subheadlineColor = subheadlineColor
self.iconColor = iconColor
self.mediaTypeItem = mediaTypeItem
self.backgroundColor = backgroundColor
self.cornerRadius = cornerRadius
self.poweredBy = poweredBy
self.dividerColor = dividerColor
self.errorTitleFont = errorTitleFont
self.errorTitleStyle = errorTitleStyle
self.errorTitleColor = errorTitleColor
self.errorMessageFont = errorMessageFont
self.errorMessageStyle = errorMessageStyle
self.errorMessageColor = errorMessageColor
self.errorButton = errorButton
}
}
Loading
Loading