about summary refs log tree commit diff
path: root/modules/expo-bluesky-swiss-army/ios/Visibility/VisiblityView.swift
blob: fd99ee49386a0d8d262ab84b37d3e2559a027197 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import ExpoModulesCore

class VisibilityView: ExpoView {
  var enabled = false {
    didSet {
      if enabled {
        VisibilityViewManager.shared.removeView(self)
      }
    }
  }

  private let onChangeStatus = EventDispatcher()
  private var isCurrentlyActiveView = false

  required init(appContext: AppContext? = nil) {
    super.init(appContext: appContext)
  }

  public override func willMove(toWindow newWindow: UIWindow?) {
    super.willMove(toWindow: newWindow)

    if !self.enabled {
      return
    }

    if newWindow == nil {
      VisibilityViewManager.shared.removeView(self)
    } else {
      VisibilityViewManager.shared.addView(self)
    }
  }

  func setIsCurrentlyActive(isActive: Bool) {
    if isCurrentlyActiveView == isActive {
      return
    }
    self.isCurrentlyActiveView = isActive
    self.onChangeStatus([
      "isActive": isActive
    ])
  }
}

// 🚨 DANGER 🚨
// These functions need to be called from the main thread. Xcode will warn you if you call one of them
// off the main thread, so pay attention!
extension UIView {
  func getPositionOnScreen() -> CGRect? {
    if let window = self.window {
      return self.convert(self.bounds, to: window)
    }
    return nil
  }

  func isViewableEnough() -> Bool {
    guard let window = self.window else {
      return false
    }

    let viewFrameOnScreen = self.convert(self.bounds, to: window)
    let screenBounds = window.bounds
    let intersection = viewFrameOnScreen.intersection(screenBounds)

    let viewHeight = viewFrameOnScreen.height
    let intersectionHeight = intersection.height

    return intersectionHeight >= 0.5 * viewHeight
  }
}