diff --git a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift index 37f7ac96..6f5d88b6 100644 --- a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift +++ b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift @@ -25,59 +25,120 @@ import UIKit open class AlertFactory { - open class func alert(title: String? = nil, - message: String? = nil, - tint: UIColor = .systemBlue, - actions: [AlertAction]) -> AlertDescriptor { + public var localizationProvider: AlertLocalizationProvider - return AlertDescriptor(title: title, - message: message, - style: .alert, - tintColor: tint, - actions: actions) + public init(localizationProvider: AlertLocalizationProvider = DefaultAlertLocalizationProvider()) { + self.localizationProvider = localizationProvider } - open class func sheetAlert(title: String? = nil, - message: String? = nil, - tint: UIColor = .systemBlue, - actions: [AlertAction]) -> AlertDescriptor { + /// Provides general alert description. + /// - Parameters: + /// - title: A text string used as the title of the alert. + /// - message: A text string used as the message of the alert. + /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue. + /// - actions: An array of actions of the alert. + /// - Returns: Alert descriptor, which can be used to present alert view. + open func alert(title: String? = nil, + message: String? = nil, + tint: UIColor = .systemBlue, + actions: [AlertAction]) -> AlertDescriptor { - return AlertDescriptor(title: title, - message: message, - style: .actionSheet, - tintColor: tint, - actions: actions) + AlertDescriptor(title: title, + message: message, + tintColor: tint, + actions: actions) } - open class func okAlert(title: String? = nil, + /// Provides general sheet alert description. + /// - Parameters: + /// - title: A text string used as the title of the sheet alert. + /// - message: A text string used as the message of the sheet alert. + /// - tint: A color used as a tint color of the sheet alert. Default color is UIColor.systemBlue. + /// - actions: An array of actions of the sheet alert. + /// - Returns: Alert descriptor, which can be used to present sheet alert view. + open func sheetAlert(title: String? = nil, + message: String? = nil, + tint: UIColor = .systemBlue, + actions: [AlertAction]) -> AlertDescriptor { + + AlertDescriptor(title: title, + message: message, + style: .actionSheet, + tintColor: tint, + actions: actions) + } + + /// Provides ok type alert description. + /// - Parameters: + /// - title: A text string used as the title of the alert. + /// - message: A text string used as the message of the alert. + /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue. + /// - Returns: Alert descriptor, which can be used to present alert view. + open func okAlert(title: String? = nil, + message: String? = nil, + tint: UIColor = .systemBlue) -> AlertDescriptor { + + AlertDescriptor(title: title, + message: message, + tintColor: tint, + actions: [.simpleAction(localizationProvider.okTitle)]) + } + + /// Provides retry type alert description. + /// - Parameters: + /// - title: A text string used as the title of the alert. + /// - message: A text string used as the message of the alert. + /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue. + /// - retryAction: A closure called by tapping on the retry button of the alert. + /// - Returns: Alert descriptor, which can be used to present alert view. + open func retryAlert(title: String? = nil, + message: String? = nil, + tint: UIColor = .systemBlue, + retryAction: VoidClosure? = nil) -> AlertDescriptor { + + AlertDescriptor(title: title, + message: message, + tintColor: tint, + actions: [ + .cancelAction(localizationProvider.cancelTitle), + .init(title: localizationProvider.retryTitle, action: retryAction) + ]) + } + + /// Provides dialogue type alert description. Dialogue type alert containes to buttons: Yes and No. + /// - Parameters: + /// - title: A text string used as the title of the alert. + /// - message: A text string used as the message of the alert. + /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue. + /// - yesAction: A closure called by tapping on the yes button of the alert. + /// - noAction: A closure called by tapping on the no button of the alert. + /// - Returns: Alert descriptor, which can be used to present alert view. + open func dialogueAlert(title: String? = nil, message: String? = nil, - tint: UIColor = .systemBlue) -> AlertDescriptor { - AlertDescriptor(title: title, - message: message, - style: .alert, - tintColor: tint, - actions: [.okAction]) - } + tint: UIColor = .systemBlue, + yesAction: VoidClosure? = nil, + noAction: VoidClosure? = nil) -> AlertDescriptor { - open class func retryAlert(title: String? = nil, - message: String? = nil, - cancelTitle: String = "Cancel", - tint: UIColor = .systemBlue, - retryAction: VoidClosure? = nil) -> AlertDescriptor { AlertDescriptor(title: title, message: message, tintColor: tint, - actions: [.cancelAction(cancelTitle), - AlertAction(title: "Retry", action: retryAction)]) + actions: [ + .init(title: localizationProvider.yesTitle, style: .destructive, action: yesAction), + .init(title: localizationProvider.noTitle, action: noAction) + ]) } } +// MARK: - AlertAction + Helpers + private extension AlertAction { - static var okAction: AlertAction { - AlertAction(title: "Ok", action: {}) + static func simpleAction(_ title: String, + style: UIAlertAction.Style = .default) -> AlertAction { + + AlertAction(title: title, style: style, action: nil) } - static func cancelAction(_ title: String = "Cancel") -> AlertAction { - AlertAction(title: title, style: .cancel, action: {}) + static func cancelAction(_ title: String) -> AlertAction { + .simpleAction(title, style: .cancel) } } diff --git a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift index 789c778a..4a718c09 100644 --- a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift +++ b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2021 Touch Instinct +// Copyright (c) 2022 Touch Instinct // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the Software), to deal diff --git a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift index 2327e244..6af75ec1 100644 --- a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift +++ b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2021 Touch Instinct +// Copyright (c) 2022 Touch Instinct // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the Software), to deal @@ -25,6 +25,12 @@ import SwiftUI @available(iOS 13.0, *) public extension View { + + /// Presents an alert with a description on a context when a given condition is true. + /// - Parameters: + /// - isPresented: A binding to a Boolean value that determines whether to present the alert. When the user presses or taps one of the alert’s actions, the system sets this value to false and dismisses. + /// - context: The view that will show the alert + /// - alert: Descriptor of the alert. func alert(isPresented: Binding, on context: PresentationContext, alert: AlertDescriptor) -> some View { @@ -38,6 +44,12 @@ public extension View { return self } + /// Presents an alert with a description on a context with custom configuration of the alert when a given condition is true. + /// - Parameters: + /// - isPresented: A binding to a Boolean value that determines whether to present the alert. When the user presses or taps one of the alert’s actions, the system sets this value to false and dismisses. + /// - context: The view that will show the alert + /// - descriptor: Descriptor of the alert. + /// - alertViewFactory: A closure called to configure custom alert. func alert(isPresented: Binding, on context: PresentationContext, alertDescriptor descriptor: AlertDescriptor, diff --git a/TIUIElements/Sources/Alerts/Models/AlertAction.swift b/TIUIElements/Sources/Alerts/Models/AlertAction.swift index 229d3f0a..c90b8996 100644 --- a/TIUIElements/Sources/Alerts/Models/AlertAction.swift +++ b/TIUIElements/Sources/Alerts/Models/AlertAction.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2021 Touch Instinct +// Copyright (c) 2022 Touch Instinct // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the Software), to deal diff --git a/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift b/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift index cd07687c..2efb8190 100644 --- a/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift +++ b/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2021 Touch Instinct +// Copyright (c) 2022 Touch Instinct // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the Software), to deal diff --git a/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift b/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift new file mode 100644 index 00000000..a1a7084c --- /dev/null +++ b/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift @@ -0,0 +1,53 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +/// Provide default localization for alerts' buttons +open class DefaultAlertLocalizationProvider: AlertLocalizationProvider { + + public private(set) var bundle: Bundle + + public init(bundle: Bundle = .main) { + self.bundle = bundle + } + + open var okTitle: String { + bundle.localizedString(forKey: "common_ok", value: "Ок", table: nil) + } + + open var cancelTitle: String { + bundle.localizedString(forKey: "common_cancel", value: "Отмена", table: nil) + } + + open var retryTitle: String { + bundle.localizedString(forKey: "common_retry", value: "Повторить", table: nil) + } + + open var yesTitle: String { + bundle.localizedString(forKey: "common_yes", value: "Да", table: nil) + } + + open var noTitle: String { + bundle.localizedString(forKey: "common_no", value: "Нет", table: nil) + } +} diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift b/TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift new file mode 100644 index 00000000..98795b27 --- /dev/null +++ b/TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift @@ -0,0 +1,29 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public protocol AlertLocalizationProvider { + var okTitle: String { get } + var cancelTitle: String { get } + var retryTitle: String { get } + var yesTitle: String { get } + var noTitle: String { get } +}