@applicaster/quick-brick-native-apple 6.1.2 → 6.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apple/QuickBrickApple.podspec.json +2 -2
- package/apple/tvos/ReactNativeModulesExportstvOS.m +7 -0
- package/apple/tvos/Views/FocusableView/FocusableView+FocusGuide.swift +60 -0
- package/apple/tvos/Views/FocusableView/FocusableView.swift +85 -0
- package/apple/tvos/Views/FocusableView/FocusableViewModule.swift +8 -1
- package/apple/tvos/Views/ParallaxView/ParallaxView.swift +3 -3
- package/apple/universal/ReactNative/OfflineAssetsBridge.swift +1 -1
- package/apple/universal/ReactNative/ReactNativeCommunicationModule.swift +1 -3
- package/apple/universal/ReactNative/ReactNativeManager.swift +0 -4
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "QuickBrickApple",
|
|
3
|
-
"version": "6.1
|
|
3
|
+
"version": "6.2.1",
|
|
4
4
|
"platforms": {
|
|
5
5
|
"ios": "14.0",
|
|
6
6
|
"tvos": "14.0"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"authors": "Applicaster LTD.",
|
|
17
17
|
"source": {
|
|
18
18
|
"git": "https://github.com/applicaster/Zapp-Frameworks.git",
|
|
19
|
-
"tag": "@@applicaster/quick-brick-native-apple/6.1
|
|
19
|
+
"tag": "@@applicaster/quick-brick-native-apple/6.2.1"
|
|
20
20
|
},
|
|
21
21
|
"requires_arc": true,
|
|
22
22
|
"source_files": "universal/**/*.{m,swift}",
|
|
@@ -40,6 +40,13 @@ RCT_EXPORT_VIEW_PROPERTY(onViewPress, RCTBubblingEventBlock)
|
|
|
40
40
|
RCT_EXPORT_VIEW_PROPERTY(onViewFocus, RCTBubblingEventBlock)
|
|
41
41
|
RCT_EXPORT_VIEW_PROPERTY(onViewBlur, RCTBubblingEventBlock)
|
|
42
42
|
RCT_EXPORT_VIEW_PROPERTY(focusable, BOOL);
|
|
43
|
+
|
|
44
|
+
//TODO: We need only in cases where we can not focus with focusable group
|
|
45
|
+
RCT_EXPORT_VIEW_PROPERTY(nextTvosFocusLeft, NSNumber)
|
|
46
|
+
RCT_EXPORT_VIEW_PROPERTY(nextTvosFocusRight, NSNumber)
|
|
47
|
+
RCT_EXPORT_VIEW_PROPERTY(nextTvosFocusUp, NSNumber)
|
|
48
|
+
RCT_EXPORT_VIEW_PROPERTY(nextTvosFocusDown, NSNumber)
|
|
49
|
+
|
|
43
50
|
@end
|
|
44
51
|
#endif
|
|
45
52
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//
|
|
2
|
+
// FocusableView+FocusGuide.swift
|
|
3
|
+
// QuickBrickApple
|
|
4
|
+
//
|
|
5
|
+
// Created by Anton Kononenko on 6/27/23.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
class FocusGuideDebugView: UIView {
|
|
11
|
+
init(focusGuide: UIFocusGuide) {
|
|
12
|
+
super.init(frame: focusGuide.layoutFrame)
|
|
13
|
+
backgroundColor = UIColor.green.withAlphaComponent(0.15)
|
|
14
|
+
layer.borderColor = UIColor.green.withAlphaComponent(0.3).cgColor
|
|
15
|
+
layer.borderWidth = 1
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
required init?(coder _: NSCoder) {
|
|
19
|
+
nil
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
extension FocusableView {
|
|
24
|
+
@discardableResult
|
|
25
|
+
func addFocusGuide(from origin: UIView, to destination: UIView, direction: UIRectEdge, debugMode: Bool = false) -> UIFocusGuide {
|
|
26
|
+
addFocusGuide(from: origin, to: [destination], direction: direction, debugMode: debugMode)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@discardableResult
|
|
30
|
+
func addFocusGuide(from origin: UIView, to destinations: [UIView], direction: UIRectEdge, debugMode: Bool = false) -> UIFocusGuide {
|
|
31
|
+
let focusGuide = UIFocusGuide()
|
|
32
|
+
addLayoutGuide(focusGuide)
|
|
33
|
+
focusGuide.preferredFocusEnvironments = destinations
|
|
34
|
+
focusGuide.widthAnchor.constraint(equalTo: origin.widthAnchor).isActive = true
|
|
35
|
+
focusGuide.heightAnchor.constraint(equalTo: origin.heightAnchor).isActive = true
|
|
36
|
+
|
|
37
|
+
switch direction {
|
|
38
|
+
case .bottom:
|
|
39
|
+
focusGuide.topAnchor.constraint(equalTo: origin.bottomAnchor).isActive = true
|
|
40
|
+
focusGuide.leftAnchor.constraint(equalTo: origin.leftAnchor).isActive = true
|
|
41
|
+
case .top:
|
|
42
|
+
focusGuide.bottomAnchor.constraint(equalTo: origin.topAnchor).isActive = true
|
|
43
|
+
focusGuide.leftAnchor.constraint(equalTo: origin.leftAnchor).isActive = true
|
|
44
|
+
case .left:
|
|
45
|
+
focusGuide.topAnchor.constraint(equalTo: origin.topAnchor).isActive = true
|
|
46
|
+
focusGuide.rightAnchor.constraint(equalTo: origin.leftAnchor).isActive = true
|
|
47
|
+
case .right:
|
|
48
|
+
focusGuide.topAnchor.constraint(equalTo: origin.topAnchor).isActive = true
|
|
49
|
+
focusGuide.leftAnchor.constraint(equalTo: origin.rightAnchor).isActive = true
|
|
50
|
+
default:
|
|
51
|
+
break
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if debugMode {
|
|
55
|
+
addSubview(FocusGuideDebugView(focusGuide: focusGuide))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return focusGuide
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -12,6 +12,8 @@ import UIKit
|
|
|
12
12
|
|
|
13
13
|
/// RCTTVView subclass that has api how to conects to FocusableGroup
|
|
14
14
|
public class FocusableView: ParallaxView {
|
|
15
|
+
weak var module: FocusableViewModule?
|
|
16
|
+
|
|
15
17
|
@objc public var onViewFocus: RCTBubblingEventBlock?
|
|
16
18
|
@objc public var onViewPress: RCTBubblingEventBlock?
|
|
17
19
|
@objc public var onViewBlur: RCTBubblingEventBlock?
|
|
@@ -45,12 +47,95 @@ public class FocusableView: ParallaxView {
|
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
|
|
50
|
+
var isFocusLayoutConfigured = false
|
|
51
|
+
override public func layoutSubviews() {
|
|
52
|
+
super.layoutSubviews()
|
|
53
|
+
|
|
54
|
+
if isFocusLayoutConfigured == false {
|
|
55
|
+
configureFocusLayout()
|
|
56
|
+
isFocusLayoutConfigured = true
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// TODO: Example of solution for future with groupId and focuse id
|
|
61
|
+
// func hintLeftFocusId() {
|
|
62
|
+
// if let onFocusLeft = dictFromReactNative,
|
|
63
|
+
// let groupId = onFocusLeft["groupId"],
|
|
64
|
+
// let id = onFocusLeft["id"],
|
|
65
|
+
// let view = FocusableGroupManager.item(byGroupId: groupId,
|
|
66
|
+
// andItemId: id) {
|
|
67
|
+
// _ = addFocusGuide(from: self,
|
|
68
|
+
// to: view,
|
|
69
|
+
// direction: .left,
|
|
70
|
+
// debugMode: true)
|
|
71
|
+
// }
|
|
72
|
+
// }
|
|
73
|
+
|
|
74
|
+
func addFocusGuideIfNeeded(tag: NSNumber?,
|
|
75
|
+
direction: UIRectEdge) {
|
|
76
|
+
if let tag,
|
|
77
|
+
let view = module?.viewForTag(tag: tag) {
|
|
78
|
+
_ = addFocusGuide(from: self,
|
|
79
|
+
to: view,
|
|
80
|
+
direction: direction,
|
|
81
|
+
debugMode: false)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func configureFocusLayout() {
|
|
86
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusLeft, direction: .left)
|
|
87
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusRight, direction: .right)
|
|
88
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusUp, direction: .top)
|
|
89
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusDown, direction: .bottom)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@objc public var nextTvosFocusLeft: NSNumber? {
|
|
93
|
+
didSet {
|
|
94
|
+
// This check needed in case refs assigned on later phase, after view ready
|
|
95
|
+
if nextTvosFocusLeft != oldValue,
|
|
96
|
+
isFocusLayoutConfigured {
|
|
97
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusLeft, direction: .left)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@objc public var nextTvosFocusRight: NSNumber? {
|
|
103
|
+
didSet {
|
|
104
|
+
// This check needed in case refs assigned on later phase, after view ready
|
|
105
|
+
if nextTvosFocusRight != oldValue,
|
|
106
|
+
isFocusLayoutConfigured {
|
|
107
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusRight, direction: .right)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@objc public var nextTvosFocusUp: NSNumber? {
|
|
113
|
+
didSet {
|
|
114
|
+
// This check needed in case refs assigned on later phase, after view ready
|
|
115
|
+
if nextTvosFocusUp != oldValue,
|
|
116
|
+
isFocusLayoutConfigured {
|
|
117
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusUp, direction: .top)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@objc public var nextTvosFocusDown: NSNumber? {
|
|
123
|
+
didSet {
|
|
124
|
+
// This check needed in case refs assigned on later phase, after view ready
|
|
125
|
+
if nextTvosFocusDown != oldValue,
|
|
126
|
+
isFocusLayoutConfigured {
|
|
127
|
+
addFocusGuideIfNeeded(tag: nextTvosFocusDown, direction: .bottom)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
48
132
|
/// Define if this view is preffered tv focused View
|
|
49
133
|
@objc public var forceFocus: Bool = false {
|
|
50
134
|
didSet {
|
|
51
135
|
guard forceFocus else {
|
|
52
136
|
return
|
|
53
137
|
}
|
|
138
|
+
|
|
54
139
|
DispatchQueue.main.async { [weak self] in
|
|
55
140
|
FocusableGroupManager.updateFocus(self?.groupId,
|
|
56
141
|
itemId: self?.itemId,
|
|
@@ -26,6 +26,13 @@ public class FocusableViewModule: RCTViewManager {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
override public func view() -> UIView? {
|
|
29
|
-
FocusableView()
|
|
29
|
+
let view = FocusableView()
|
|
30
|
+
view.module = self
|
|
31
|
+
|
|
32
|
+
return view
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public func viewForTag<T: UIView>(tag: NSNumber) -> T? {
|
|
36
|
+
bridge.uiManager.view(forReactTag: tag) as? T
|
|
30
37
|
}
|
|
31
38
|
}
|
|
@@ -73,7 +73,7 @@ open class ParallaxView: RCTView, ParallaxableView {
|
|
|
73
73
|
override open func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
|
|
74
74
|
if !isPressActionDisabled {
|
|
75
75
|
parallaxViewActions.animatePressIn?(self, presses, event, { [unowned self] in
|
|
76
|
-
|
|
76
|
+
delegate?.parallaxViewWillSelected(self)
|
|
77
77
|
|
|
78
78
|
})
|
|
79
79
|
|
|
@@ -84,7 +84,7 @@ open class ParallaxView: RCTView, ParallaxableView {
|
|
|
84
84
|
override open func pressesCancelled(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
|
|
85
85
|
if !isPressActionDisabled {
|
|
86
86
|
parallaxViewActions.animatePressOut?(self, presses, event, { [unowned self] in
|
|
87
|
-
|
|
87
|
+
delegate?.parallaxViewDidSelected(self)
|
|
88
88
|
})
|
|
89
89
|
|
|
90
90
|
super.pressesCancelled(presses, with: event)
|
|
@@ -94,7 +94,7 @@ open class ParallaxView: RCTView, ParallaxableView {
|
|
|
94
94
|
override open func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
|
|
95
95
|
if !isPressActionDisabled {
|
|
96
96
|
parallaxViewActions.animatePressOut?(self, presses, event, { [unowned self] in
|
|
97
|
-
|
|
97
|
+
delegate?.parallaxViewDidSelected(self)
|
|
98
98
|
})
|
|
99
99
|
|
|
100
100
|
super.pressesEnded(presses, with: event)
|
|
@@ -84,7 +84,7 @@ class OfflineAssetsBridge: NSObject, RCTBridgeModule {
|
|
|
84
84
|
|
|
85
85
|
dispatchGroup.notify(queue: .main) { [unowned self] in
|
|
86
86
|
var responseObj: [String: Bool] = [:]
|
|
87
|
-
|
|
87
|
+
tasks.forEach { responseObj[$0.saveTo.absoluteString] = $0.state == .completed }
|
|
88
88
|
resolver(responseObj)
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -85,8 +85,6 @@ enum Events: String {
|
|
|
85
85
|
func setPrefersHomeIndicatorAutoHidden(_ payload: [String: Any])
|
|
86
86
|
|
|
87
87
|
func forceAppReload()
|
|
88
|
-
|
|
89
|
-
func forceAppReloadLanguageSwitch()
|
|
90
88
|
}
|
|
91
89
|
|
|
92
90
|
@objc(QuickBrickCommunicationModule)
|
|
@@ -171,7 +169,7 @@ class ReactNativeCommunicationModule: NSObject, RCTBridgeModule {
|
|
|
171
169
|
ReactNativeCommunicationModuleError.unableToSaveToLocalStorage, nil)
|
|
172
170
|
}
|
|
173
171
|
|
|
174
|
-
delegateManager.
|
|
172
|
+
delegateManager.forceAppReload()
|
|
175
173
|
}
|
|
176
174
|
}
|
|
177
175
|
}
|
|
@@ -223,8 +223,4 @@ extension ReactNativeManager: QuickBrickManagerDelegate {
|
|
|
223
223
|
public func forceAppReload() {
|
|
224
224
|
EventsBus.post(EventsBus.Event(type: EventsBusType(.forceAppReload)))
|
|
225
225
|
}
|
|
226
|
-
|
|
227
|
-
public func forceAppReloadLanguageSwitch() {
|
|
228
|
-
EventsBus.post(EventsBus.Event(type: EventsBusType(.forceAppReloadLanguageSwitch)))
|
|
229
|
-
}
|
|
230
226
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-native-apple",
|
|
3
|
-
"version": "6.1
|
|
3
|
+
"version": "6.2.1",
|
|
4
4
|
"description": "iOS and tvOS native code for QuickBrick applications. This package is used to provide native logic for QuickBrick",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1"
|