@applicaster/quick-brick-native-apple 6.15.2 → 6.15.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "QuickBrickApple",
3
- "version": "6.15.2",
3
+ "version": "6.15.3",
4
4
  "platforms": {
5
5
  "ios": "16.0",
6
6
  "tvos": "16.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.15.2"
19
+ "tag": "@@applicaster/quick-brick-native-apple/6.15.3"
20
20
  },
21
21
  "requires_arc": true,
22
22
  "source_files": "universal/**/*.{m,swift}",
@@ -11,8 +11,8 @@ import Foundation
11
11
  import React
12
12
 
13
13
  protocol FocusableGroupManagerUpdater {
14
- var focusableGroupRegistrationUpdates: PassthroughSubject<FocusableGroupView, Never> { get }
15
- var focusableItemDidUpdatePreferredFocus: PassthroughSubject<FocusableView, Never> { get }
14
+ var focusableGroupRegistrationUpdates: AnyPublisher<FocusableGroupView, Never> { get }
15
+ var focusableItemDidUpdatePreferredFocus: AnyPublisher<FocusableView, Never> { get }
16
16
  }
17
17
 
18
18
  /// Class control focusable group view with focusable items
@@ -62,14 +62,17 @@ class FocusableGroupManager {
62
62
 
63
63
  func registerItem(_ item: FocusableView) async -> Bool {
64
64
  let success = await itemStorage.registerItem(item)
65
+
66
+ // IMPORTANT: Handle edge case where group was registered BEFORE items
67
+ // PassthroughSubject doesn't replay events to new subscribers, so items
68
+ // that subscribe after group registration would miss the update.
69
+ // Performance is handled by efficient compactMap filter in FocusableGroupView
65
70
  if success,
66
- let groupId = await item.groupId {
67
- if let itemGroup = await getGroup(by: groupId) {
68
- // Handler in case group was registerd later then items
69
- // TODO: Check this it gives a lot of calls, need to be optimized
70
- updateService.sendFocusableGroupRegisteredUpdate(itemGroup)
71
- }
71
+ let groupId = await item.groupId,
72
+ let itemGroup = await getGroup(by: groupId) {
73
+ updateService.sendFocusableGroupRegisteredUpdate(itemGroup)
72
74
  }
75
+
73
76
  return success
74
77
  }
75
78
 
@@ -156,11 +159,11 @@ class FocusableGroupManager {
156
159
  }
157
160
 
158
161
  extension FocusableGroupManager: FocusableGroupManagerUpdater {
159
- var focusableItemDidUpdatePreferredFocus: PassthroughSubject<FocusableView, Never> {
162
+ var focusableItemDidUpdatePreferredFocus: AnyPublisher<FocusableView, Never> {
160
163
  updateService.focusableItemDidUpdatePreferredFocus
161
164
  }
162
165
 
163
- var focusableGroupRegistrationUpdates: PassthroughSubject<FocusableGroupView, Never> {
166
+ var focusableGroupRegistrationUpdates: AnyPublisher<FocusableGroupView, Never> {
164
167
  updateService.focusableGroupRegistrationUpdates
165
168
  }
166
169
  }
@@ -6,6 +6,7 @@
6
6
  //
7
7
 
8
8
  import Combine
9
+ import Foundation
9
10
 
10
11
  struct FocusableGroupUpdateEvent {
11
12
  let groupId: String
@@ -13,14 +14,22 @@ struct FocusableGroupUpdateEvent {
13
14
  }
14
15
 
15
16
  class UpdateService {
16
- let focusableGroupRegistrationUpdates = PassthroughSubject<FocusableGroupView, Never>()
17
- let focusableItemDidUpdatePreferredFocus = PassthroughSubject<FocusableView, Never>()
17
+ private let _focusableGroupRegistrationUpdates = PassthroughSubject<FocusableGroupView, Never>()
18
+ private let _focusableItemDidUpdatePreferredFocus = PassthroughSubject<FocusableView, Never>()
19
+
20
+ lazy var focusableGroupRegistrationUpdates: AnyPublisher<FocusableGroupView, Never> = _focusableGroupRegistrationUpdates
21
+ .receive(on: DispatchQueue.main)
22
+ .eraseToAnyPublisher()
23
+
24
+ lazy var focusableItemDidUpdatePreferredFocus: AnyPublisher<FocusableView, Never> = _focusableItemDidUpdatePreferredFocus
25
+ .receive(on: DispatchQueue.main)
26
+ .eraseToAnyPublisher()
18
27
 
19
28
  func sendFocusableGroupRegisteredUpdate(_ focusableGroupView: FocusableGroupView) {
20
- focusableGroupRegistrationUpdates.send(focusableGroupView)
29
+ _focusableGroupRegistrationUpdates.send(focusableGroupView)
21
30
  }
22
31
 
23
32
  func sendFocusableItemDidUpdatePreferredFocus(_ focusableView: FocusableView) {
24
- focusableItemDidUpdatePreferredFocus.send(focusableView)
33
+ _focusableItemDidUpdatePreferredFocus.send(focusableView)
25
34
  }
26
35
  }
@@ -131,16 +131,22 @@ public class FocusableGroupView: RCTTVView {
131
131
  groupFocusGuide.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
132
132
 
133
133
  manager.focusableItemDidUpdatePreferredFocus
134
- .filter { self.groupId != nil && $0.groupId == self.itemId }
134
+ .compactMap { [weak self] focusableView -> FocusableView? in
135
+ guard let self,
136
+ groupId != nil,
137
+ focusableView.groupId == self.itemId
138
+ else {
139
+ return nil
140
+ }
141
+ return focusableView
142
+ }
135
143
  .sink { [weak self] focusableView in
136
144
  guard let self else { return }
137
- guard focusableView.preferredFocus == false else {
138
- userPreferredFocusEnvironments = [focusableView]
139
- return
140
- }
141
145
 
142
- if let currentPreferred = userPreferredFocusEnvironments?.first as? FocusableView,
143
- currentPreferred == focusableView {
146
+ if focusableView.preferredFocus {
147
+ userPreferredFocusEnvironments = [focusableView]
148
+ } else if let currentPreferred = userPreferredFocusEnvironments?.first as? FocusableView,
149
+ currentPreferred == focusableView {
144
150
  userPreferredFocusEnvironments = nil
145
151
  }
146
152
  }.store(in: &cancellables)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/quick-brick-native-apple",
3
- "version": "6.15.2",
3
+ "version": "6.15.3",
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"