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

Feature/mbx 0000 snackbar new way #269

Merged
merged 11 commits into from
Oct 5, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final class PresentationDisplayUseCase {
private var model: InAppFormData?
private var factory: ViewFactoryProtocol?
private var tracker: InAppMessagesTrackerProtocol

init(tracker: InAppMessagesTrackerProtocol) {
self.tracker = tracker
}
Expand All @@ -26,10 +26,12 @@ final class PresentationDisplayUseCase {
changeType(model: model.content)

guard let window = presentationStrategy?.getWindow() else {
Logger.common(message: "In-app modal window creating failed")
Logger.common(message: "In-app window creating failed")
return
}

Logger.common(message: "PresentationDisplayUseCase window: \(window)")

guard let factory = self.factory else {
Logger.common(message: "Factory does not exists.", level: .error, category: .general)
return
Expand All @@ -46,6 +48,11 @@ final class PresentationDisplayUseCase {
}

presentedVC = viewController

if let image = model.imagesDict[model.firstImageValue] {
presentationStrategy?.setupWindowFrame(model: model.content, imageSize: image.size)
}

presentationStrategy?.present(id: model.inAppId, in: window, using: viewController)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UIKit
import MindboxLogger

final class ModalPresentationStrategy: PresentationStrategyProtocol {
var inappWindow: UIWindow?
var window: UIWindow?

func getWindow() -> UIWindow? {
return makeInAppMessageWindow()
Expand All @@ -28,15 +28,19 @@ final class ModalPresentationStrategy: PresentationStrategyProtocol {
Logger.common(message: "In-app modal presentation dismissed", level: .debug, category: .inAppMessages)
}

func setupWindowFrame(model: MindboxFormVariant, imageSize: CGSize) {
// Not need to setup.
}

private func makeInAppMessageWindow() -> UIWindow? {
let window: UIWindow?
if #available(iOS 13.0, *) {
window = iOS13PlusWindow
} else {
window = UIWindow(frame: UIScreen.main.bounds)
}
self.inappWindow = window
window?.windowLevel = UIWindow.Level.normal
self.window = window
window?.windowLevel = .normal + 3
window?.isHidden = false
return window
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
import UIKit

protocol PresentationStrategyProtocol {
var window: UIWindow? { get set }

func getWindow() -> UIWindow?
func present(id: String, in window: UIWindow, using viewController: UIViewController)
func dismiss(viewController: UIViewController)
func setupWindowFrame(model: MindboxFormVariant, imageSize: CGSize)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,112 @@ import UIKit
import MindboxLogger

final class SnackbarPresentationStrategy: PresentationStrategyProtocol {
func getWindow() -> UIWindow? {
return UIApplication.shared.windows.first(where: { $0.isKeyWindow })

enum Constants {
static let oneThirdScreenHeight: CGFloat = UIScreen.main.bounds.height / 3.0
}

var window: UIWindow?

func getWindow() -> UIWindow? {
let window: UIWindow
let screenBounds = UIScreen.main.bounds
let windowFrame = CGRect(x: 0, y: 0, width: screenBounds.width, height: screenBounds.height)
Logger.common(message: "SnackbarPresentationStrategy getWindow started.")
if #available(iOS 13, *) {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
window = UIWindow(windowScene: windowScene)
} else {
window = UIWindow(frame: UIScreen.main.bounds)
}
} else {
window = UIWindow(frame: UIScreen.main.bounds)
}

window.frame = windowFrame
window.backgroundColor = .clear
window.windowLevel = .normal + 3
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.normal + 3
Ты хоть бы вынес куда нибудь эту цифру

let viewController = UIViewController()
window.rootViewController = viewController
viewController.view.frame = windowFrame
window.isHidden = false
self.window = window
return window
}

func present(id: String, in window: UIWindow, using viewController: UIViewController) {
window.rootViewController?.addChild(viewController)
window.rootViewController?.view.addSubview(viewController.view)
Logger.common(message: "In-app with id \(id) presented", level: .info, category: .inAppMessages)
if var topController = window.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}

viewController.view.frame = topController.view.frame
topController.addChild(viewController)
topController.view.addSubview(viewController.view)

viewController.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
viewController.view.topAnchor.constraint(equalTo: topController.view.topAnchor),
viewController.view.bottomAnchor.constraint(equalTo: topController.view.bottomAnchor),
viewController.view.leadingAnchor.constraint(equalTo: topController.view.leadingAnchor),
viewController.view.trailingAnchor.constraint(equalTo: topController.view.trailingAnchor)
])

viewController.didMove(toParent: topController)
Logger.common(message: "In-app snackbar with id \(id) presented", level: .info, category: .inAppMessages)
} else {
Logger.common(message: "Unable to get top controller. Abort.", level: .error, category: .inAppMessages)
}
}

func dismiss(viewController: UIViewController) {
viewController.view.removeFromSuperview()
viewController.removeFromParent()
Logger.common(message: "InApp presentation dismissed", level: .debug, category: .inAppMessages)
Logger.common(message: "In-app snackbar presentation dismissed", level: .debug, category: .inAppMessages)
}

func setupWindowFrame(model: MindboxFormVariant, imageSize: CGSize) {
switch model {
case .snackbar(let snackbarFormVariant):
if let gravity = snackbarFormVariant.content.position.gravity?.vertical {
let leftOffset = snackbarFormVariant.content.position.margin.left
let rightOffset = snackbarFormVariant.content.position.margin.right
let width = UIScreen.main.bounds.width - leftOffset - rightOffset
let heightMultiplier = width / imageSize.width
let imageHeight = imageSize.height * heightMultiplier
let finalHeight = (imageHeight < Constants.oneThirdScreenHeight) ? imageHeight : Constants.oneThirdScreenHeight
let safeAreaInset = getSafeAreaInset(gravity: gravity)
let y = getYPosition(gravity: gravity, finalHeight: finalHeight, safeAreaInset: safeAreaInset)
self.window?.frame = CGRect(x: leftOffset, y: y, width: width, height: finalHeight)
}
default:
break
}
}
}

private extension SnackbarPresentationStrategy {
func getSafeAreaInset(gravity: GravityVerticalType) -> CGFloat {
var safeAreaInset: CGFloat = 0
if #available(iOS 11, *) {
if gravity == .bottom {
safeAreaInset = window?.safeAreaInsets.bottom ?? 0
} else if gravity == .top {
safeAreaInset = window?.safeAreaInsets.top ?? 0
}
}

return safeAreaInset
}

func getYPosition(gravity: GravityVerticalType, finalHeight: CGFloat, safeAreaInset: CGFloat) -> CGFloat {
var y = UIScreen.main.bounds.height - finalHeight
if gravity == .bottom {
y = UIScreen.main.bounds.height - finalHeight - safeAreaInset
} else if gravity == .top {
y = safeAreaInset
}

return y
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import UIKit
import MindboxLogger

final class InAppImageOnlyView: UIView {
var onClose: (() -> Void)?
Expand All @@ -29,9 +30,12 @@ final class InAppImageOnlyView: UIView {

func customInit() {
guard let image = image else {
Logger.common(message: "[Error]: \(#function) at line \(#line) of \(#file)", level: .error)
return
}

Logger.common(message: "InAppImageOnlyView custom init started.")

imageView.contentMode = .scaleAspectFill
imageView.image = image

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@
//

import UIKit
import MindboxLogger

class ImageLayerFactory: LayerFactory {
func create(from image: UIImage, layer: ContentBackgroundLayer, in view: UIView, with controller: GestureHandler) -> UIView? {
if case .image(let imageContentBackgroundLayer) = layer {
let inAppView = InAppImageOnlyView(image: image, action: imageContentBackgroundLayer.action)
let imageTapGestureRecognizer = UITapGestureRecognizer(target: controller, action: #selector(controller.imageTapped(_:)))
inAppView.addGestureRecognizer(imageTapGestureRecognizer)

Logger.common(message: "ImageLayerFactory return uiView.")
return inAppView
}


Logger.common(message: "ImageLayerFactory return nil.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а почему это common а не варнинг какой нибудь?

return nil
}

Expand All @@ -39,5 +41,6 @@ class ImageLayerFactory: LayerFactory {
view.leadingAnchor.constraint(equalTo: parentView.leadingAnchor),
view.trailingAnchor.constraint(equalTo: parentView.trailingAnchor)
])
Logger.common(message: "ImageLayerFactory setupConstraintsSnackbar finished.")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ final class ModalViewController: UIViewController, InappViewControllerProtocol,

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
elements.forEach({
$0.removeFromSuperview()
})

setupElements()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import UIKit
import MindboxLogger

class SnackbarView: UIView {

Expand Down Expand Up @@ -39,7 +40,7 @@ class SnackbarView: UIView {
self.onClose = onClose
self.animationTime = animationTime
super.init(frame: .zero)

Logger.common(message: "SnackbarView inited.")
setupPanGesture()
}

Expand Down Expand Up @@ -72,6 +73,7 @@ class SnackbarView: UIView {
if ((swipeDirection == .up && translation.y < 0) || (swipeDirection == .down && translation.y > 0)) &&
abs(translation.y) > threshold {
animateHide(completion: onClose, animated: true)

} else {
UIView.animate(withDuration: animationTime) {
self.transform = .identity
Expand Down Expand Up @@ -113,6 +115,7 @@ class SnackbarView: UIView {
}

required init?(coder: NSCoder) {
Logger.common(message: "SnackbarView init(coder:) has not been implemented.")
fatalError("init(coder:) has not been implemented")
}
}
Loading