@apexnative/navigation 1.0.0-alpha.1 → 1.0.0-alpha.2
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/CHANGELOG.md +16 -0
- package/README.md +147 -51
- package/android/CLAUDE.md +10 -4
- package/android/CORE.md +4 -1
- package/android/RECIPES.md +4 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +5 -4
- package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +5 -4
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +7 -6
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +3 -35
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +101 -87
- package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +12 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +12 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +25 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +1 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +4 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +8 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +2 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +2 -1
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +5 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +85 -27
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +5 -4
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +45 -1
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +2 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +4 -6
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +4 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +4 -3
- package/cli/app.js +1 -1
- package/cli/project.js +6 -2
- package/cli/setup/index.js +13 -0
- package/cli/setup/steps/appDelegate.js +66 -11
- package/cli/setup/steps/sceneDelegate.js +108 -0
- package/docs-md/architecture/transitions.md +1 -1
- package/docs-md/guides/deep-links.md +15 -33
- package/docs-md/start/installation.md +1 -0
- package/ios/Animations/ANNTransitionAnimator.mm +13 -11
- package/ios/Animations/ANNTransitionWait.mm +6 -7
- package/ios/Animations/Elements/ANNElementFinder.h +57 -0
- package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
- package/ios/Animations/Elements/ANNElementTransition.h +7 -5
- package/ios/Animations/Elements/ANNElementTransition.mm +17 -19
- package/ios/Animations/Elements/ANNSharedElementFlight.h +13 -8
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +59 -24
- package/ios/CLAUDE.md +10 -2
- package/ios/CORE.md +3 -2
- package/ios/Contract/ANNCommandAnswer.h +4 -3
- package/ios/Contract/ANNCommandAnswer.mm +12 -2
- package/ios/Contract/ANNCommandRunner.h +2 -2
- package/ios/Contract/ANNCommandRunner.mm +1 -1
- package/ios/Contract/ANNErrorTexts.h +6 -2
- package/ios/Contract/ANNErrorTexts.mm +18 -10
- package/ios/Core/ANNDeepLinkQueue.h +20 -1
- package/ios/Core/ANNDeepLinkQueue.mm +107 -12
- package/ios/Core/ANNErrorHandler.h +8 -3
- package/ios/Core/ANNErrorHandler.mm +17 -1
- package/ios/Core/ANNEventContract.h +246 -0
- package/ios/Core/ANNEventContract.mm +225 -0
- package/ios/Core/ANNEventEmitter.h +5 -1
- package/ios/Core/ANNEventEmitter.mm +117 -80
- package/ios/Core/ANNHinge.mm +6 -4
- package/ios/Core/ANNSceneDelegate.mm +25 -15
- package/ios/Core/ANNSystemUI.h +3 -2
- package/ios/Core/ANNSystemUI.mm +7 -0
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +6 -4
- package/ios/Layouts/Modal/ANNModalCoordinator.mm +1 -1
- package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
- package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
- package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
- package/ios/Layouts/Root/ANNRootCoordinator.mm +12 -3
- package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
- package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
- package/ios/Layouts/Screen/ANNComponentViewController.mm +28 -7
- package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
- package/ios/Layouts/Screen/ANNScreenInsets.mm +6 -4
- package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -6
- package/ios/Layouts/SplitView/ANNSplitViewController.mm +4 -7
- package/ios/Options/ANNSheetOptions.h +4 -1
- package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
- package/ios/RECIPES.md +2 -1
- package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
- package/ios/TurboModules/ANNTurboModule.mm +5 -2
- package/lib/module/ARCHITECTURE.md +7 -4
- package/lib/module/api/app/createNavigation.js +2 -0
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/linking/dispatchedLinks.js +23 -0
- package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
- package/lib/module/interfaces/contract/errors.json +275 -0
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
- package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
- package/lib/typescript/interfaces/Events.d.ts +9 -0
- package/lib/typescript/interfaces/Events.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +17 -13
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/modals.d.ts +15 -11
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/sideMenu.d.ts +7 -6
- package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +4 -3
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ARCHITECTURE.md +7 -4
- package/src/api/app/createNavigation.ts +2 -0
- package/src/api/linking/dispatchedLinks.ts +18 -0
- package/src/interfaces/Events.ts +10 -0
- package/src/interfaces/contract/errors.json +275 -0
- package/src/interfaces/options/animations.ts +17 -13
- package/src/interfaces/options/modals.ts +15 -11
- package/src/interfaces/options/sideMenu.ts +7 -6
- package/src/interfaces/options/system.ts +4 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "ANNEventEmitter.h"
|
|
2
2
|
#import "ANNAssert.h"
|
|
3
|
+
#import "ANNEventContract.h"
|
|
3
4
|
#import "ANNReloadCoordinator.h"
|
|
4
5
|
#import "ANNTurboEventEmitter.h"
|
|
5
6
|
#import <React/RCTUtils.h>
|
|
@@ -24,8 +25,6 @@ static NSString *ANNComponentTypeName(ANNReactComponentType componentType) {
|
|
|
24
25
|
static BOOL ANNAppLaunchedPending;
|
|
25
26
|
static NSUInteger ANNAppLaunchedBundle;
|
|
26
27
|
|
|
27
|
-
static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
28
|
-
|
|
29
28
|
@implementation ANNEventEmitter
|
|
30
29
|
|
|
31
30
|
- (instancetype)init {
|
|
@@ -42,12 +41,11 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
42
41
|
// The generation is checked where the event goes out, on the main queue: an event sent from another queue just
|
|
43
42
|
// before a reload is dropped too.
|
|
44
43
|
- (void)sendEvent:(NSString *)name body:(NSDictionary<NSString *, id> *)body {
|
|
45
|
-
NSString *eventName = [@"ANN." stringByAppendingString:name];
|
|
46
44
|
RCTExecuteOnMainQueue(^{
|
|
47
45
|
if (!self.isCurrent) {
|
|
48
46
|
return;
|
|
49
47
|
}
|
|
50
|
-
[ANNTurboEventEmitter.current sendIfListened:
|
|
48
|
+
[ANNTurboEventEmitter.current sendIfListened:name body:body];
|
|
51
49
|
});
|
|
52
50
|
}
|
|
53
51
|
|
|
@@ -62,7 +60,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
62
60
|
return;
|
|
63
61
|
}
|
|
64
62
|
ANNAppLaunchedPending = NO;
|
|
65
|
-
[eventEmitter sendIfListened:
|
|
63
|
+
[eventEmitter sendIfListened:ANNEventContract.AppLaunched.event body:nil];
|
|
66
64
|
}
|
|
67
65
|
|
|
68
66
|
+ (void)eventEmitterListensToAppLaunched:(ANNTurboEventEmitter *)eventEmitter {
|
|
@@ -71,7 +69,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
71
69
|
return;
|
|
72
70
|
}
|
|
73
71
|
ANNAppLaunchedPending = NO;
|
|
74
|
-
[eventEmitter sendIfListened:
|
|
72
|
+
[eventEmitter sendIfListened:ANNEventContract.AppLaunched.event body:nil];
|
|
75
73
|
}
|
|
76
74
|
|
|
77
75
|
// Only an `AppLaunched` of the module's own JavaScript or an older one: the module is made while its bundle runs,
|
|
@@ -87,11 +85,12 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
87
85
|
- (void)sendCommandCompleted:(NSString *)commandName
|
|
88
86
|
commandId:(NSString *)commandId
|
|
89
87
|
completionTime:(double)completionTime {
|
|
90
|
-
|
|
88
|
+
const auto &keys = ANNEventContract.CommandCompleted;
|
|
89
|
+
[self sendEvent:keys.event
|
|
91
90
|
body:@{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
keys.commandName : commandName,
|
|
92
|
+
keys.commandId : commandId,
|
|
93
|
+
keys.completionTime : @(completionTime),
|
|
95
94
|
}];
|
|
96
95
|
}
|
|
97
96
|
|
|
@@ -100,7 +99,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
100
99
|
- (void)sendComponentWillAppear:(NSString *)componentId
|
|
101
100
|
componentName:(NSString *)componentName
|
|
102
101
|
componentType:(ANNReactComponentType)componentType {
|
|
103
|
-
[self sendComponentEvent
|
|
102
|
+
[self sendComponentEvent:ANNEventContract.ComponentWillAppear.event
|
|
104
103
|
componentId:componentId
|
|
105
104
|
componentName:componentName
|
|
106
105
|
componentType:componentType];
|
|
@@ -109,7 +108,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
109
108
|
- (void)sendComponentDidAppear:(NSString *)componentId
|
|
110
109
|
componentName:(NSString *)componentName
|
|
111
110
|
componentType:(ANNReactComponentType)componentType {
|
|
112
|
-
[self sendComponentEvent
|
|
111
|
+
[self sendComponentEvent:ANNEventContract.ComponentDidAppear.event
|
|
113
112
|
componentId:componentId
|
|
114
113
|
componentName:componentName
|
|
115
114
|
componentType:componentType];
|
|
@@ -118,21 +117,23 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
118
117
|
- (void)sendComponentDidDisappear:(NSString *)componentId
|
|
119
118
|
componentName:(NSString *)componentName
|
|
120
119
|
componentType:(ANNReactComponentType)componentType {
|
|
121
|
-
[self sendComponentEvent
|
|
120
|
+
[self sendComponentEvent:ANNEventContract.ComponentDidDisappear.event
|
|
122
121
|
componentId:componentId
|
|
123
122
|
componentName:componentName
|
|
124
123
|
componentType:componentType];
|
|
125
124
|
}
|
|
126
125
|
|
|
126
|
+
// The three appearance events have the same keys.
|
|
127
127
|
- (void)sendComponentEvent:(NSString *)name
|
|
128
128
|
componentId:(NSString *)componentId
|
|
129
129
|
componentName:(NSString *)componentName
|
|
130
130
|
componentType:(ANNReactComponentType)componentType {
|
|
131
|
+
const auto &keys = ANNEventContract.ComponentDidAppear;
|
|
131
132
|
[self sendEvent:name
|
|
132
133
|
body:@{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
keys.componentId : componentId ?: @"",
|
|
135
|
+
keys.componentName : componentName ?: @"",
|
|
136
|
+
keys.componentType : ANNComponentTypeName(componentType),
|
|
136
137
|
}];
|
|
137
138
|
}
|
|
138
139
|
|
|
@@ -143,58 +144,76 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
143
144
|
- (void)sendOnNavigationButtonPressed:(NSString *)componentId
|
|
144
145
|
buttonId:(NSString *)buttonId
|
|
145
146
|
selected:(NSNumber *)selected {
|
|
147
|
+
const auto &keys = ANNEventContract.NavigationButtonPressed;
|
|
146
148
|
NSMutableDictionary *body =
|
|
147
|
-
[@{
|
|
149
|
+
[@{keys.componentId : componentId ?: @"", keys.buttonId : buttonId ?: @""} mutableCopy];
|
|
148
150
|
if (selected) {
|
|
149
|
-
body[
|
|
151
|
+
body[keys.selected] = @(selected.boolValue);
|
|
150
152
|
}
|
|
151
|
-
[self sendEvent
|
|
153
|
+
[self sendEvent:keys.event body:body];
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
- (void)sendScreenPopped:(NSString *)componentId {
|
|
155
|
-
|
|
157
|
+
const auto &keys = ANNEventContract.ScreenPopped;
|
|
158
|
+
[self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
- (void)sendNavigationStateChanged:(NSString *)screenId name:(NSString *)name tab:(NSNumber *)tab {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
+
const auto &keys = ANNEventContract.NavigationStateChanged;
|
|
163
|
+
const auto &screenKeys = ANNEventContract.NavigationStateChangedScreen;
|
|
164
|
+
id screen = screenId ? @{screenKeys.id : screenId, screenKeys.name : name ?: @""}
|
|
165
|
+
: (id)NSNull.null;
|
|
166
|
+
[self sendEvent:keys.event body:@{keys.screen : screen, keys.tab : tab ?: (id)NSNull.null}];
|
|
162
167
|
}
|
|
163
168
|
|
|
164
169
|
- (void)sendScreenInsetsChanged:(NSString *)componentId
|
|
165
170
|
insets:(NSDictionary<NSString *, NSNumber *> *)insets {
|
|
171
|
+
const auto &keys = ANNEventContract.ScreenInsetsChanged;
|
|
166
172
|
NSMutableDictionary *body = [insets mutableCopy] ?: [NSMutableDictionary new];
|
|
167
|
-
body[
|
|
168
|
-
[self sendEvent
|
|
173
|
+
body[keys.componentId] = componentId;
|
|
174
|
+
[self sendEvent:keys.event body:body];
|
|
169
175
|
}
|
|
170
176
|
|
|
171
177
|
- (void)sendScreenRegionsChanged:(NSString *)componentId
|
|
172
178
|
regions:(NSDictionary<NSString *, NSArray *> *)regions {
|
|
179
|
+
const auto &keys = ANNEventContract.ScreenRegionsChanged;
|
|
173
180
|
NSMutableDictionary *body = [regions mutableCopy] ?: [NSMutableDictionary new];
|
|
174
|
-
body[
|
|
175
|
-
[self sendEvent
|
|
181
|
+
body[keys.componentId] = componentId;
|
|
182
|
+
[self sendEvent:keys.event body:body];
|
|
176
183
|
}
|
|
177
184
|
|
|
178
185
|
- (void)sendSlotDestroyed:(NSString *)componentId {
|
|
179
|
-
|
|
186
|
+
const auto &keys = ANNEventContract.SlotDestroyed;
|
|
187
|
+
[self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
- (void)sendDeepLinkDispatched:(NSURL *)url {
|
|
191
|
+
const auto &keys = ANNEventContract.DeepLinkDispatched;
|
|
192
|
+
[self sendEvent:keys.event body:@{keys.url : url.absoluteString ?: @""}];
|
|
180
193
|
}
|
|
181
194
|
|
|
182
195
|
- (void)sendTitleRenamed:(NSString *)componentId text:(NSString *)text {
|
|
183
|
-
|
|
184
|
-
|
|
196
|
+
const auto &keys = ANNEventContract.TitleRenamed;
|
|
197
|
+
[self sendEvent:keys.event
|
|
198
|
+
body:@{keys.componentId : componentId ?: @"", keys.text : text ?: @""}];
|
|
185
199
|
}
|
|
186
200
|
|
|
187
201
|
- (void)sendKeyCommandPressed:(NSString *)componentId keyCommandId:(NSString *)keyCommandId {
|
|
188
|
-
|
|
189
|
-
|
|
202
|
+
const auto &keys = ANNEventContract.KeyCommandPressed;
|
|
203
|
+
[self sendEvent:keys.event
|
|
204
|
+
body:@{
|
|
205
|
+
keys.componentId : componentId ?: @"",
|
|
206
|
+
keys.keyCommandId : keyCommandId ?: @"",
|
|
207
|
+
}];
|
|
190
208
|
}
|
|
191
209
|
|
|
192
210
|
- (void)sendPreviewCompleted:(NSString *)componentId
|
|
193
211
|
previewComponentId:(NSString *)previewComponentId {
|
|
194
|
-
|
|
212
|
+
const auto &keys = ANNEventContract.PreviewCompleted;
|
|
213
|
+
[self sendEvent:keys.event
|
|
195
214
|
body:@{
|
|
196
|
-
|
|
197
|
-
|
|
215
|
+
keys.componentId : componentId ?: @"",
|
|
216
|
+
keys.previewComponentId : previewComponentId ?: @"",
|
|
198
217
|
}];
|
|
199
218
|
}
|
|
200
219
|
|
|
@@ -203,21 +222,24 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
203
222
|
- (void)sendModalDismissed:(NSString *)componentId
|
|
204
223
|
componentName:(NSString *)componentName
|
|
205
224
|
modalsDismissed:(NSUInteger)modalsDismissed {
|
|
206
|
-
|
|
225
|
+
const auto &keys = ANNEventContract.ModalDismissed;
|
|
226
|
+
[self sendEvent:keys.event
|
|
207
227
|
body:@{
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
228
|
+
keys.componentId : componentId ?: @"",
|
|
229
|
+
keys.componentName : componentName ?: @"",
|
|
230
|
+
keys.modalsDismissed : @(modalsDismissed),
|
|
211
231
|
}];
|
|
212
232
|
}
|
|
213
233
|
|
|
214
234
|
- (void)sendModalAttemptedToDismiss:(NSString *)componentId {
|
|
215
|
-
|
|
235
|
+
const auto &keys = ANNEventContract.ModalAttemptedToDismiss;
|
|
236
|
+
[self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
|
|
216
237
|
}
|
|
217
238
|
|
|
218
239
|
- (void)sendSheetDetentChanged:(NSString *)componentId detent:(id)detent {
|
|
219
|
-
|
|
220
|
-
|
|
240
|
+
const auto &keys = ANNEventContract.SheetDetentChanged;
|
|
241
|
+
[self sendEvent:keys.event
|
|
242
|
+
body:@{keys.componentId : componentId ?: @"", keys.detent : detent ?: @""}];
|
|
221
243
|
}
|
|
222
244
|
|
|
223
245
|
#pragma mark - Search
|
|
@@ -227,82 +249,94 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
227
249
|
isFocused:(BOOL)isFocused
|
|
228
250
|
scope:(NSString *)scope
|
|
229
251
|
tokens:(NSArray<NSString *> *)tokens {
|
|
252
|
+
const auto &keys = ANNEventContract.SearchBarUpdated;
|
|
230
253
|
NSMutableDictionary *body = [@{
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
254
|
+
keys.componentId : componentId ?: @"",
|
|
255
|
+
keys.text : text ?: @"",
|
|
256
|
+
keys.isFocused : @(isFocused),
|
|
234
257
|
} mutableCopy];
|
|
235
|
-
body[
|
|
236
|
-
body[
|
|
237
|
-
[self sendEvent
|
|
258
|
+
body[keys.scope] = scope;
|
|
259
|
+
body[keys.tokens] = tokens;
|
|
260
|
+
[self sendEvent:keys.event body:body];
|
|
238
261
|
}
|
|
239
262
|
|
|
240
263
|
- (void)sendOnSearchBarSubmitted:(NSString *)componentId
|
|
241
264
|
text:(NSString *)text
|
|
242
265
|
scope:(NSString *)scope
|
|
243
266
|
tokens:(NSArray<NSString *> *)tokens {
|
|
267
|
+
const auto &keys = ANNEventContract.SearchBarSubmitted;
|
|
244
268
|
NSMutableDictionary *body =
|
|
245
|
-
[@{
|
|
246
|
-
body[
|
|
247
|
-
body[
|
|
248
|
-
[self sendEvent
|
|
269
|
+
[@{keys.componentId : componentId ?: @"", keys.text : text ?: @""} mutableCopy];
|
|
270
|
+
body[keys.scope] = scope;
|
|
271
|
+
body[keys.tokens] = tokens;
|
|
272
|
+
[self sendEvent:keys.event body:body];
|
|
249
273
|
}
|
|
250
274
|
|
|
251
275
|
- (void)sendOnSearchBarCancelPressed:(NSString *)componentId {
|
|
252
|
-
|
|
276
|
+
const auto &keys = ANNEventContract.SearchBarCancelPressed;
|
|
277
|
+
[self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
|
|
253
278
|
}
|
|
254
279
|
|
|
255
280
|
- (void)sendOnSearchSuggestionPicked:(NSString *)componentId suggestionId:(NSString *)suggestionId {
|
|
256
|
-
|
|
257
|
-
|
|
281
|
+
const auto &keys = ANNEventContract.SearchSuggestionPicked;
|
|
282
|
+
[self sendEvent:keys.event
|
|
283
|
+
body:@{
|
|
284
|
+
keys.componentId : componentId ?: @"",
|
|
285
|
+
keys.suggestionId : suggestionId ?: @"",
|
|
286
|
+
}];
|
|
258
287
|
}
|
|
259
288
|
|
|
260
289
|
#pragma mark - Split view, pair, hinge
|
|
261
290
|
|
|
262
291
|
- (void)sendSplitViewColumnsStacked:(NSString *)componentId stacked:(BOOL)stacked {
|
|
263
|
-
|
|
264
|
-
|
|
292
|
+
const auto &keys = ANNEventContract.SplitViewColumnsStacked;
|
|
293
|
+
[self sendEvent:keys.event
|
|
294
|
+
body:@{keys.componentId : componentId ?: @"", keys.stacked : @(stacked)}];
|
|
265
295
|
}
|
|
266
296
|
|
|
267
297
|
- (void)sendSplitViewDisplayModeChanged:(NSString *)componentId
|
|
268
298
|
displayMode:(NSString *)displayMode
|
|
269
299
|
inspectorVisible:(NSNumber *)inspectorVisible {
|
|
300
|
+
const auto &keys = ANNEventContract.SplitViewDisplayModeChanged;
|
|
270
301
|
NSMutableDictionary *body = [@{
|
|
271
|
-
|
|
272
|
-
|
|
302
|
+
keys.componentId : componentId ?: @"",
|
|
303
|
+
keys.displayMode : displayMode ?: @"automatic",
|
|
273
304
|
} mutableCopy];
|
|
274
|
-
body[
|
|
275
|
-
[self sendEvent
|
|
305
|
+
body[keys.inspectorVisible] = inspectorVisible;
|
|
306
|
+
[self sendEvent:keys.event body:body];
|
|
276
307
|
}
|
|
277
308
|
|
|
278
309
|
- (void)sendArrangementChanged:(NSString *)componentId state:(NSDictionary<NSString *, id> *)state {
|
|
310
|
+
const auto &keys = ANNEventContract.ArrangementChanged;
|
|
279
311
|
NSMutableDictionary *body = [state mutableCopy] ?: [NSMutableDictionary new];
|
|
280
|
-
body[
|
|
281
|
-
[self sendEvent
|
|
312
|
+
body[keys.componentId] = componentId;
|
|
313
|
+
[self sendEvent:keys.event body:body];
|
|
282
314
|
}
|
|
283
315
|
|
|
284
316
|
- (void)sendHingeChanged:(NSDictionary<NSString *, id> *)value {
|
|
285
|
-
[self sendEvent
|
|
317
|
+
[self sendEvent:ANNEventContract.HingeChanged.event body:value ?: @{}];
|
|
286
318
|
}
|
|
287
319
|
|
|
288
320
|
#pragma mark - Native screens, tabs
|
|
289
321
|
|
|
290
322
|
- (void)sendNativeScreenCall:(NSDictionary<NSString *, id> *)call {
|
|
291
|
-
[self sendEvent
|
|
323
|
+
[self sendEvent:ANNEventContract.NativeScreenCall.event body:call];
|
|
292
324
|
}
|
|
293
325
|
|
|
294
326
|
- (void)sendNativeScreenReleased:(NSString *)componentId {
|
|
295
|
-
|
|
327
|
+
const auto &keys = ANNEventContract.NativeScreenReleased;
|
|
328
|
+
[self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
|
|
296
329
|
}
|
|
297
330
|
|
|
298
331
|
- (void)sendBottomTabSelected:(NSUInteger)selectedTabIndex
|
|
299
332
|
unselectedTabIndex:(NSUInteger)unselectedTabIndex
|
|
300
333
|
bottomTabsId:(NSString *)bottomTabsId {
|
|
301
|
-
|
|
334
|
+
const auto &keys = ANNEventContract.BottomTabSelected;
|
|
335
|
+
[self sendEvent:keys.event
|
|
302
336
|
body:@{
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
337
|
+
keys.selectedTabIndex : @(selectedTabIndex),
|
|
338
|
+
keys.unselectedTabIndex : @(unselectedTabIndex),
|
|
339
|
+
keys.bottomTabsId : bottomTabsId ?: @"",
|
|
306
340
|
}];
|
|
307
341
|
}
|
|
308
342
|
|
|
@@ -310,28 +344,31 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
|
|
|
310
344
|
bottomTabsId:(NSString *)bottomTabsId
|
|
311
345
|
screenId:(NSString *)screenId
|
|
312
346
|
wasSelected:(BOOL)wasSelected {
|
|
347
|
+
const auto &keys = ANNEventContract.BottomTabPressed;
|
|
313
348
|
NSMutableDictionary *body = [@{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
349
|
+
keys.tabIndex : @(tabIndex),
|
|
350
|
+
keys.bottomTabsId : bottomTabsId ?: @"",
|
|
351
|
+
keys.wasSelected : @(wasSelected),
|
|
317
352
|
} mutableCopy];
|
|
318
|
-
body[
|
|
319
|
-
[self sendEvent
|
|
353
|
+
body[keys.screenId] = screenId;
|
|
354
|
+
[self sendEvent:keys.event body:body];
|
|
320
355
|
}
|
|
321
356
|
|
|
322
357
|
- (void)sendBottomTabLongPressed:(NSUInteger)selectedTabIndex
|
|
323
358
|
bottomTabsId:(NSString *)bottomTabsId {
|
|
324
|
-
|
|
359
|
+
const auto &keys = ANNEventContract.BottomTabLongPressed;
|
|
360
|
+
[self sendEvent:keys.event
|
|
325
361
|
body:@{
|
|
326
|
-
|
|
327
|
-
|
|
362
|
+
keys.selectedTabIndex : @(selectedTabIndex),
|
|
363
|
+
keys.bottomTabsId : bottomTabsId ?: @"",
|
|
328
364
|
}];
|
|
329
365
|
}
|
|
330
366
|
|
|
331
367
|
- (void)sendBottomAccessoryPlacementChanged:(NSString *)componentId
|
|
332
368
|
placement:(NSString *)placement {
|
|
333
|
-
|
|
334
|
-
|
|
369
|
+
const auto &keys = ANNEventContract.BottomAccessoryPlacementChanged;
|
|
370
|
+
[self sendEvent:keys.event
|
|
371
|
+
body:@{keys.componentId : componentId ?: @"", keys.placement : placement ?: @""}];
|
|
335
372
|
}
|
|
336
373
|
|
|
337
374
|
@end
|
package/ios/Core/ANNHinge.mm
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "ANNHinge.h"
|
|
2
2
|
#import "ANNAssert.h"
|
|
3
|
+
#import "ANNEventContract.h"
|
|
3
4
|
#import "ANNUtils.h"
|
|
4
5
|
|
|
5
6
|
NSNotificationName const ANNHingeDidChangeNotification = @"ANNHingeDidChange";
|
|
@@ -34,11 +35,12 @@ static NSDictionary<NSString *, id> *ANNHingeValue(UIHinge *hinge) API_AVAILABLE
|
|
|
34
35
|
if (!hinge) {
|
|
35
36
|
return @{};
|
|
36
37
|
}
|
|
38
|
+
const auto &keys = ANNEventContract.HingeChanged;
|
|
37
39
|
NSString *state = ANNHingeStateName(hinge.status);
|
|
38
40
|
if (hinge.status == UIHingeStatusUnknown) {
|
|
39
|
-
return @{
|
|
41
|
+
return @{keys.state : state};
|
|
40
42
|
}
|
|
41
|
-
return @{
|
|
43
|
+
return @{keys.state : state, keys.angle : @(round(hinge.angle * 1800 / M_PI) / 10)};
|
|
42
44
|
}
|
|
43
45
|
#endif
|
|
44
46
|
|
|
@@ -94,13 +96,13 @@ static NSDictionary<NSString *, id> *ANNHingeValue(UIHinge *hinge) API_AVAILABLE
|
|
|
94
96
|
if ([ANNLastHinge isEqualToDictionary:value]) {
|
|
95
97
|
return;
|
|
96
98
|
}
|
|
97
|
-
previousState = ANNLastHinge[
|
|
99
|
+
previousState = ANNLastHinge[ANNEventContract.HingeChanged.state];
|
|
98
100
|
ANNLastHinge = value;
|
|
99
101
|
}
|
|
100
102
|
if (ANNHingeUpdatesEnabled) {
|
|
101
103
|
[ANNHingeEventEmitter sendHingeChanged:value];
|
|
102
104
|
}
|
|
103
|
-
id state = value[
|
|
105
|
+
id state = value[ANNEventContract.HingeChanged.state];
|
|
104
106
|
if (previousState != state && ![previousState isEqual:state]) {
|
|
105
107
|
[NSNotificationCenter.defaultCenter postNotificationName:ANNHingeDidChangeNotification
|
|
106
108
|
object:nil];
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#import "ANNSceneDelegate.h"
|
|
2
|
+
#import "ANNDeepLinkQueue.h"
|
|
2
3
|
#import "ApexNavigation.h"
|
|
3
|
-
#import <React/RCTLinkingManager.h>
|
|
4
4
|
|
|
5
5
|
// On the scene life cycle UIKit stops calling the app delegate's URL, user activity and foreground/background
|
|
6
|
-
// methods. The scene forwards them, so AppDelegate overrides (and the deep links of ANNDeepLinkQueue) keep working
|
|
6
|
+
// methods. The scene forwards them, so AppDelegate overrides (and the deep links of ANNDeepLinkQueue) keep working; the
|
|
7
|
+
// links keep their scene, through which React Native 0.88 and newer take them.
|
|
7
8
|
@implementation ANNSceneDelegate
|
|
8
9
|
|
|
9
10
|
- (void)scene:(UIScene *)scene
|
|
@@ -15,21 +16,21 @@
|
|
|
15
16
|
self.window = [ApexNavigation attachToWindowScene:(UIWindowScene *)scene];
|
|
16
17
|
|
|
17
18
|
for (UIOpenURLContext *context in connectionOptions.URLContexts) {
|
|
18
|
-
[self ann_openURLContext:context];
|
|
19
|
+
[self ann_openURLContext:context ofScene:scene];
|
|
19
20
|
}
|
|
20
21
|
for (NSUserActivity *activity in connectionOptions.userActivities) {
|
|
21
|
-
[self ann_continueUserActivity:activity];
|
|
22
|
+
[self ann_continueUserActivity:activity ofScene:scene];
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
|
|
26
27
|
for (UIOpenURLContext *context in URLContexts) {
|
|
27
|
-
[self ann_openURLContext:context];
|
|
28
|
+
[self ann_openURLContext:context ofScene:scene];
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity {
|
|
32
|
-
[self ann_continueUserActivity:userActivity];
|
|
33
|
+
[self ann_continueUserActivity:userActivity ofScene:scene];
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
- (void)sceneDidBecomeActive:(UIScene *)scene {
|
|
@@ -62,7 +63,7 @@
|
|
|
62
63
|
|
|
63
64
|
#pragma mark - private
|
|
64
65
|
|
|
65
|
-
- (void)ann_openURLContext:(UIOpenURLContext *)context {
|
|
66
|
+
- (void)ann_openURLContext:(UIOpenURLContext *)context ofScene:(UIScene *)scene {
|
|
66
67
|
UIApplication *application = UIApplication.sharedApplication;
|
|
67
68
|
id<UIApplicationDelegate> appDelegate = application.delegate;
|
|
68
69
|
if ([appDelegate respondsToSelector:@selector(application:openURL:options:)]) {
|
|
@@ -70,22 +71,31 @@
|
|
|
70
71
|
options[UIApplicationOpenURLOptionsSourceApplicationKey] = context.options.sourceApplication;
|
|
71
72
|
options[UIApplicationOpenURLOptionsAnnotationKey] = context.options.annotation;
|
|
72
73
|
options[UIApplicationOpenURLOptionsOpenInPlaceKey] = @(context.options.openInPlace);
|
|
73
|
-
[
|
|
74
|
+
[ANNDeepLinkQueue forwardURLContext:context
|
|
75
|
+
ofScene:scene
|
|
76
|
+
through:^{
|
|
77
|
+
[appDelegate application:application openURL:context.URL options:options];
|
|
78
|
+
}];
|
|
74
79
|
} else {
|
|
75
|
-
[
|
|
80
|
+
[ANNDeepLinkQueue openURLContext:context ofScene:scene];
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
|
|
79
|
-
- (void)ann_continueUserActivity:(NSUserActivity *)activity {
|
|
84
|
+
- (void)ann_continueUserActivity:(NSUserActivity *)activity ofScene:(UIScene *)scene {
|
|
80
85
|
UIApplication *application = UIApplication.sharedApplication;
|
|
81
86
|
id<UIApplicationDelegate> appDelegate = application.delegate;
|
|
82
87
|
if ([appDelegate respondsToSelector:@selector(application:continueUserActivity:restorationHandler:)]) {
|
|
83
|
-
[
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
[ANNDeepLinkQueue forwardUserActivity:activity
|
|
89
|
+
ofScene:scene
|
|
90
|
+
through:^{
|
|
91
|
+
[appDelegate application:application
|
|
92
|
+
continueUserActivity:activity
|
|
93
|
+
restorationHandler:^(
|
|
94
|
+
NSArray<id<UIUserActivityRestoring>> *restorableObjects){
|
|
95
|
+
}];
|
|
96
|
+
}];
|
|
87
97
|
} else if ([activity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
|
88
|
-
[
|
|
98
|
+
[ANNDeepLinkQueue openUserActivity:activity ofScene:scene];
|
|
89
99
|
}
|
|
90
100
|
}
|
|
91
101
|
|
package/ios/Core/ANNSystemUI.h
CHANGED
|
@@ -36,8 +36,9 @@ typedef NS_ENUM(NSInteger, ANNSystemUIQuestion) {
|
|
|
36
36
|
/// The owner adds the asks UIKit doesn't make — a merge, a side menu at rest, an overlay, a root replaced, the bar of a
|
|
37
37
|
/// stack shown or hidden, the orientation after an appearance — and makes them once per turn of the main queue: a
|
|
38
38
|
/// trigger marks groups, the marks of a turn are coalesced, and at its end UIKit is asked again for each marked group
|
|
39
|
-
/// in the main window and every overlay window.
|
|
40
|
-
///
|
|
39
|
+
/// in the main window and every overlay window. Each ask of the status bar also lays out the screens' blurs under it
|
|
40
|
+
/// (`statusBar.blur`), then and on the next turn. It keeps no values but the last status bar of each window, which
|
|
41
|
+
/// only chooses whether a change of the style animates. Never a wait. Main queue.
|
|
41
42
|
@interface ANNSystemUI : NSObject
|
|
42
43
|
|
|
43
44
|
- (instancetype)init NS_UNAVAILABLE;
|
package/ios/Core/ANNSystemUI.mm
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "ANNSystemUI.h"
|
|
2
2
|
#import "ANNAssert.h"
|
|
3
|
+
#import "ANNComponentPresenter.h"
|
|
3
4
|
#import "ANNComponentViewController.h"
|
|
4
5
|
#import "ANNDefaultOptions.h"
|
|
5
6
|
#import "ANNOverlayCoordinator.h"
|
|
@@ -280,6 +281,12 @@ static NSArray<UIViewController *> *ANNChainOf(UIWindow *window) {
|
|
|
280
281
|
ask();
|
|
281
282
|
}
|
|
282
283
|
}
|
|
284
|
+
// The status bar hidden or shown moves no view where the safe area stays (a device with a notch): the blurs under
|
|
285
|
+
// it take its frame now, and once more on the next turn of the main queue, in case UIKit settles it after the ask.
|
|
286
|
+
[ANNComponentPresenter statusBarDidChange];
|
|
287
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
288
|
+
[ANNComponentPresenter statusBarDidChange];
|
|
289
|
+
});
|
|
283
290
|
}
|
|
284
291
|
|
|
285
292
|
// A controller that is no node of the layout (React Native's `<Modal>`, an alert, the splash) animates as UIKit's
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
#import "ANNArrangementState.h"
|
|
6
6
|
#import "ANNComponentViewController.h"
|
|
7
|
+
#import "ANNEventContract.h"
|
|
7
8
|
#import "ANNExternalViewController.h"
|
|
8
9
|
#import "ANNShownScreens.h"
|
|
9
10
|
#import "ANNUtils.h"
|
|
@@ -130,11 +131,12 @@ static BOOL ANNKeepsState(UIViewController *screen) {
|
|
|
130
131
|
|
|
131
132
|
static NSDictionary<NSString *, id> *ANNStateOf(NSString *placement, NSString *layout, BOOL front,
|
|
132
133
|
BOOL hidden) {
|
|
134
|
+
const auto &keys = ANNEventContract.ArrangementChanged;
|
|
133
135
|
return @{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
keys.placement : placement,
|
|
137
|
+
keys.layout : layout,
|
|
138
|
+
keys.front : @(front),
|
|
139
|
+
keys.hidden : @(hidden),
|
|
138
140
|
};
|
|
139
141
|
}
|
|
140
142
|
|
|
@@ -407,7 +407,7 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
407
407
|
ANNNavigationOptions *resolved = [root resolveOptionsWithDefault];
|
|
408
408
|
ANNModalPresentation *presentation =
|
|
409
409
|
[[ANNModalPresentation alloc] initWithOptions:resolved animated:modal.animatedOverride];
|
|
410
|
-
NSString *problem = [presentation
|
|
410
|
+
NSString *problem = [presentation fitToPresenting:presenting windowRoot:windowRoot];
|
|
411
411
|
if (problem) {
|
|
412
412
|
[self failShowOf:modal reason:problem];
|
|
413
413
|
done();
|
|
@@ -20,7 +20,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
20
20
|
|
|
21
21
|
/// `modalPresentationStyle`: one to one; unset is UIKit's automatic style; an unknown string full screen.
|
|
22
22
|
@property(nonatomic, readonly) UIModalPresentationStyle style;
|
|
23
|
-
/// `modalTransitionStyle`: `coverVertical` unless one of the others is given
|
|
23
|
+
/// `modalTransitionStyle`: `coverVertical` unless one of the others is given; `partialCurl` only where UIKit curls
|
|
24
|
+
/// (`fitToPresenting:windowRoot:`).
|
|
24
25
|
@property(nonatomic, readonly) UIModalTransitionStyle transitionStyle;
|
|
25
26
|
/// The present is animated: `enter.enabled` is not `false`.
|
|
26
27
|
@property(nonatomic, readonly) BOOL animated;
|
|
@@ -47,10 +48,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
47
48
|
animation:(nullable ANNModalAnimationOptions *)animation
|
|
48
49
|
under:(nullable UIViewController *)under;
|
|
49
50
|
|
|
50
|
-
///
|
|
51
|
-
///
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
/// Fits the show to `presenting`, before `prepare:…`: `partialCurl` stays only for a full-screen modal over a
|
|
52
|
+
/// controller that fills the screen (`presenting` is `windowRoot`, the main window's root, or a full-screen modal);
|
|
53
|
+
/// otherwise `transitionStyle` becomes `coverVertical`. Returns why UIKit can't make the show (`presenting` was shown
|
|
54
|
+
/// with `partialCurl`), as the reason of the rejection; nil when it can.
|
|
55
|
+
- (nullable NSString *)fitToPresenting:(UIViewController *)presenting
|
|
56
|
+
windowRoot:(nullable UIViewController *)windowRoot;
|
|
54
57
|
|
|
55
58
|
/// Before `presentViewController:`: the style and the transition, the presentation's delegate, the popover kept a
|
|
56
59
|
/// popover (`adaptive: false`), the sheet, the size, the popover's source on `presentingLayout`, the hold, the
|