@applicaster/zapp-react-dom-app 12.0.0-alpha.4462655310 → 12.0.0-alpha.4484269996
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/App/InteractionManager/index.tsx +546 -552
- package/index.js +5 -6
- package/main.css +2 -2
- package/package.json +6 -6
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
5
|
+
|
|
4
6
|
import {
|
|
5
7
|
QUICK_BRICK_EVENTS,
|
|
6
8
|
sendQuickBrickEvent,
|
|
@@ -35,9 +37,9 @@ import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
|
|
|
35
37
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
36
38
|
import { confirmationDialogStore } from "@applicaster/zapp-react-native-ui-components/Contexts/ConfirmDialogState";
|
|
37
39
|
import {
|
|
38
|
-
isVizioPlatform,
|
|
39
|
-
isSamsungPlatform,
|
|
40
40
|
isLgPlatform,
|
|
41
|
+
isSamsungPlatform,
|
|
42
|
+
isVizioPlatform,
|
|
41
43
|
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
42
44
|
|
|
43
45
|
import { OnScreenKeyboard } from "@applicaster/zapp-react-dom-ui-components/Components/OnScreenKeyboard";
|
|
@@ -72,590 +74,555 @@ type KeyCode = { code: string; keyCode: number | string };
|
|
|
72
74
|
export const alertConfirmationMesage =
|
|
73
75
|
"Are you sure you want to exit application?";
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
onScrollListener: (event: MouseEvent) => void;
|
|
81
|
-
|
|
82
|
-
longKeyPressTimeout: any | null;
|
|
83
|
-
longPressActive: boolean;
|
|
84
|
-
timeout: any | null;
|
|
85
|
-
sequenceTimeout: NodeJS.Timeout | null; // timeoutID
|
|
86
|
-
userSequence: number[] = [];
|
|
87
|
-
confirmDialog: any;
|
|
88
|
-
isDismissing = false;
|
|
89
|
-
|
|
90
|
-
constructor(props) {
|
|
91
|
-
super(props);
|
|
77
|
+
class InteractionManagerClass extends React.Component<Props, State> {
|
|
78
|
+
onKeyDownListener: (keyCode: KeyCode) => void;
|
|
79
|
+
onMouseDownListener: (event: MouseEvent) => void;
|
|
80
|
+
onMouseMoveListener: (event: MouseEvent) => void;
|
|
81
|
+
onScrollListener: (event: MouseEvent) => void;
|
|
92
82
|
|
|
93
|
-
|
|
83
|
+
longKeyPressTimeout: any | null;
|
|
84
|
+
longPressActive: boolean;
|
|
85
|
+
timeout: any | null;
|
|
86
|
+
sequenceTimeout: NodeJS.Timeout | null; // timeoutID
|
|
87
|
+
userSequence: number[] = [];
|
|
88
|
+
confirmDialog: any;
|
|
89
|
+
isDismissing = false;
|
|
94
90
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
keyboardInput: "",
|
|
98
|
-
};
|
|
91
|
+
constructor(props) {
|
|
92
|
+
super(props);
|
|
99
93
|
|
|
100
|
-
|
|
101
|
-
fn: this.onMouseMove,
|
|
102
|
-
context: this,
|
|
103
|
-
});
|
|
94
|
+
this.onKeyDownListener = this.onKeyDown.bind(this);
|
|
104
95
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
});
|
|
96
|
+
this.state = {
|
|
97
|
+
isKeyboardVisible: false,
|
|
98
|
+
keyboardInput: "",
|
|
99
|
+
};
|
|
110
100
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
101
|
+
this.onMouseMoveListener = debounce({
|
|
102
|
+
fn: this.onMouseMove,
|
|
103
|
+
context: this,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
this.onScrollListener = debounce({
|
|
107
|
+
fn: this.onScroll,
|
|
108
|
+
wait: 100,
|
|
109
|
+
context: this,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
this.onMouseDownListener = debounce({
|
|
113
|
+
fn: this.onMouseDown,
|
|
114
|
+
context: this,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
this.longKeyPressTimeout = null;
|
|
118
|
+
this.longPressActive = false;
|
|
119
|
+
this.confirmDialog = confirmationDialogStore.getState();
|
|
120
|
+
this.resetHudTimeout = this.resetHudTimeout.bind(this);
|
|
121
|
+
this.cursorVisibilityChange = this.cursorVisibilityChange.bind(this);
|
|
122
|
+
this.onKeyDown = this.onKeyDown.bind(this);
|
|
123
|
+
this.onKeyUp = this.onKeyUp.bind(this);
|
|
124
|
+
this.onMouseMove = this.onMouseMove.bind(this);
|
|
125
|
+
this.onScroll = this.onScroll.bind(this);
|
|
126
|
+
this.onMouseDown = this.onMouseDown.bind(this);
|
|
127
|
+
this.onKeyboardStateChange = this.onKeyboardStateChange.bind(this);
|
|
128
|
+
this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
|
|
129
|
+
this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
|
|
130
|
+
this.performExit = this.performExit.bind(this);
|
|
131
|
+
this.handleInputFocus = this.handleInputFocus.bind(this);
|
|
132
|
+
this.handleInputBlur = this.handleInputBlur.bind(this);
|
|
133
|
+
this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
|
|
134
|
+
this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
|
|
135
|
+
|
|
136
|
+
this.confirmDialog.setConfirmAction(this.performExit);
|
|
137
|
+
this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
|
|
138
|
+
}
|
|
115
139
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.cursorVisibilityChange = this.cursorVisibilityChange.bind(this);
|
|
121
|
-
this.onKeyDown = this.onKeyDown.bind(this);
|
|
122
|
-
this.onKeyUp = this.onKeyUp.bind(this);
|
|
123
|
-
this.onMouseMove = this.onMouseMove.bind(this);
|
|
124
|
-
this.onScroll = this.onScroll.bind(this);
|
|
125
|
-
this.onMouseDown = this.onMouseDown.bind(this);
|
|
126
|
-
this.onKeyboardStateChange = this.onKeyboardStateChange.bind(this);
|
|
127
|
-
this.onConfirmDialogOpen = this.onConfirmDialogOpen.bind(this);
|
|
128
|
-
this.onConfirmDialogClose = this.onConfirmDialogClose.bind(this);
|
|
129
|
-
this.performExit = this.performExit.bind(this);
|
|
130
|
-
this.handleInputFocus = this.handleInputFocus.bind(this);
|
|
131
|
-
this.handleInputBlur = this.handleInputBlur.bind(this);
|
|
132
|
-
this.handleKeyboardInput = this.handleKeyboardInput.bind(this);
|
|
133
|
-
this.handleKeyboardDismiss = this.handleKeyboardDismiss.bind(this);
|
|
134
|
-
|
|
135
|
-
this.confirmDialog.setConfirmAction(this.performExit);
|
|
136
|
-
this.confirmDialog.setCancelAction(this.onConfirmDialogClose);
|
|
137
|
-
}
|
|
140
|
+
componentDidMount() {
|
|
141
|
+
window.addEventListener("keydown", this.onKeyDownListener);
|
|
142
|
+
window.addEventListener("keyup", this.onKeyUp);
|
|
143
|
+
window.addEventListener("mousemove", this.onMouseMoveListener);
|
|
138
144
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
window.addEventListener("mousemove", this.onMouseMoveListener);
|
|
145
|
+
document.addEventListener("wheel", this.onScrollListener, {
|
|
146
|
+
passive: true,
|
|
147
|
+
});
|
|
143
148
|
|
|
144
|
-
|
|
145
|
-
passive: true,
|
|
146
|
-
});
|
|
149
|
+
document.addEventListener("mousedown", this.onMouseDownListener);
|
|
147
150
|
|
|
148
|
-
|
|
151
|
+
document.addEventListener(
|
|
152
|
+
"keyboardStateChange",
|
|
153
|
+
this.onKeyboardStateChange,
|
|
154
|
+
false
|
|
155
|
+
);
|
|
149
156
|
|
|
150
|
-
|
|
151
|
-
"keyboardStateChange",
|
|
152
|
-
this.onKeyboardStateChange,
|
|
153
|
-
false
|
|
154
|
-
);
|
|
157
|
+
document.addEventListener("focusin", this.handleInputFocus);
|
|
155
158
|
|
|
156
|
-
|
|
159
|
+
document.addEventListener(
|
|
160
|
+
"cursorStateChange",
|
|
161
|
+
this.cursorVisibilityChange,
|
|
162
|
+
false
|
|
163
|
+
);
|
|
164
|
+
}
|
|
157
165
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
);
|
|
163
|
-
}
|
|
166
|
+
componentWillUnmount() {
|
|
167
|
+
window.removeEventListener("keydown", this.onKeyDownListener);
|
|
168
|
+
window.removeEventListener("keyup", this.onKeyUp);
|
|
169
|
+
document.removeEventListener("wheel", this.onScrollListener);
|
|
164
170
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
171
|
+
document.removeEventListener(
|
|
172
|
+
"cursorStateChange",
|
|
173
|
+
this.cursorVisibilityChange
|
|
174
|
+
);
|
|
169
175
|
|
|
170
|
-
|
|
171
|
-
"cursorStateChange",
|
|
172
|
-
this.cursorVisibilityChange
|
|
173
|
-
);
|
|
176
|
+
document.removeEventListener("focusin", this.handleInputFocus);
|
|
174
177
|
|
|
175
|
-
|
|
178
|
+
document.removeEventListener("mousedown", this.onMouseDownListener);
|
|
176
179
|
|
|
177
|
-
|
|
180
|
+
if (this.timeout) {
|
|
181
|
+
this.clearTimeout();
|
|
182
|
+
}
|
|
178
183
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
184
|
+
this.isDismissing = false;
|
|
185
|
+
}
|
|
182
186
|
|
|
183
|
-
|
|
187
|
+
performExit() {
|
|
188
|
+
if (isSamsungPlatform()) {
|
|
189
|
+
this.onConfirmDialogClose();
|
|
190
|
+
sendQuickBrickEvent(QUICK_BRICK_EVENTS.MOVE_APP_TO_BACKGROUND);
|
|
184
191
|
}
|
|
185
192
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (isLgPlatform()) {
|
|
193
|
-
// webOS recommend to use this method when implemention a custom exit
|
|
194
|
-
globalAny.close();
|
|
195
|
-
}
|
|
193
|
+
if (isLgPlatform()) {
|
|
194
|
+
// webOS recommend to use this method when implemention a custom exit
|
|
195
|
+
globalAny.close();
|
|
196
|
+
}
|
|
196
197
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
198
|
+
if (isVizioPlatform()) {
|
|
199
|
+
window?.VIZIO?.exitApplication();
|
|
200
200
|
}
|
|
201
|
+
}
|
|
201
202
|
|
|
202
|
-
|
|
203
|
-
|
|
203
|
+
handleWebOsBack() {
|
|
204
|
+
const systemBack = globalAny?.webOS?.platformBack;
|
|
204
205
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
206
|
+
if (systemBack) {
|
|
207
|
+
systemBack();
|
|
208
|
+
} else {
|
|
209
|
+
/**
|
|
210
|
+
* In case webOS failed to show the exit pop-up, we show a regular promtp as fallback
|
|
211
|
+
*/
|
|
212
|
+
showConfirmationDialog({
|
|
213
|
+
title: "",
|
|
214
|
+
message: alertConfirmationMesage,
|
|
215
|
+
confirmCompletion: this.performExit,
|
|
216
|
+
});
|
|
217
217
|
}
|
|
218
|
+
}
|
|
218
219
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
} else if (isLgPlatform()) {
|
|
242
|
-
this.handleWebOsBack();
|
|
220
|
+
/**
|
|
221
|
+
* This methods sends the app to background in whatever way is appropriate for each platform
|
|
222
|
+
* In the case of Tizen it shows a custom dialog on confirm it exits the app
|
|
223
|
+
* WebOS behavior depends on the SDK version, WebOS 4 would pull up the launcher menu
|
|
224
|
+
* following versions would show a native exit prompt
|
|
225
|
+
*/
|
|
226
|
+
platformBack() {
|
|
227
|
+
try {
|
|
228
|
+
// TODO: temporary hack until this code is refactored
|
|
229
|
+
if (isSamsungPlatform() || isVizioPlatform()) {
|
|
230
|
+
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
231
|
+
|
|
232
|
+
if (isDialogVisible) {
|
|
233
|
+
this.onConfirmDialogClose();
|
|
234
|
+
} else {
|
|
235
|
+
showConfirmationDialog({
|
|
236
|
+
title: "",
|
|
237
|
+
message: alertConfirmationMesage,
|
|
238
|
+
confirmCompletion: this.performExit,
|
|
239
|
+
cancelCompletion: this.onConfirmDialogClose,
|
|
240
|
+
});
|
|
243
241
|
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
console.warn("Failed to execute platformBack", e);
|
|
242
|
+
} else if (isLgPlatform()) {
|
|
243
|
+
this.handleWebOsBack();
|
|
247
244
|
}
|
|
245
|
+
} catch (e) {
|
|
246
|
+
// eslint-disable-next-line no-console
|
|
247
|
+
console.warn("Failed to execute platformBack", e);
|
|
248
248
|
}
|
|
249
|
+
}
|
|
249
250
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
cursorVisibilityChange(event) {
|
|
252
|
+
const visible = event.detail.visibility;
|
|
253
|
+
const { setDisplayState, displayState } = this.props;
|
|
253
254
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
255
|
+
if (visible && displayState === DISPLAY_STATES.PLAYER) {
|
|
256
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
257
|
+
this.resetHudTimeout();
|
|
258
258
|
}
|
|
259
|
+
}
|
|
259
260
|
|
|
260
|
-
|
|
261
|
-
|
|
261
|
+
onMouseMove() {
|
|
262
|
+
const { setDisplayState, displayState } = this.props;
|
|
262
263
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
264
|
+
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
265
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
266
|
+
this.resetHudTimeout();
|
|
267
267
|
}
|
|
268
|
+
}
|
|
268
269
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
isHomeScreen() {
|
|
271
|
+
const { navigator } = this.props;
|
|
272
|
+
const { rivers } = this.props;
|
|
272
273
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
274
|
+
const homeId = R.compose(
|
|
275
|
+
R.prop("id"),
|
|
276
|
+
R.find(R.prop("home")),
|
|
277
|
+
R.values
|
|
278
|
+
)(rivers);
|
|
278
279
|
|
|
279
|
-
|
|
280
|
+
const homePath = `/river/${homeId}`;
|
|
280
281
|
|
|
281
|
-
|
|
282
|
-
|
|
282
|
+
return homePath === navigator.currentRoute;
|
|
283
|
+
}
|
|
283
284
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
285
|
+
goToHome() {
|
|
286
|
+
const { navigator } = this.props;
|
|
287
|
+
const { rivers } = this.props;
|
|
288
|
+
const homeRiver = R.find(R.propEq("home", true), R.values(rivers));
|
|
288
289
|
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
navigator.replace(homeRiver);
|
|
291
|
+
}
|
|
291
292
|
|
|
292
|
-
|
|
293
|
-
|
|
293
|
+
resetHudTimeout() {
|
|
294
|
+
const { resetHudTimer = noop } = this.props;
|
|
294
295
|
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
resetHudTimer?.();
|
|
297
|
+
}
|
|
297
298
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
299
|
+
clearTimeout() {
|
|
300
|
+
if (this.timeout) {
|
|
301
|
+
clearTimeout(this.timeout);
|
|
302
|
+
this.timeout = null;
|
|
303
303
|
}
|
|
304
|
+
}
|
|
304
305
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
306
|
+
clearLongPressTimeout() {
|
|
307
|
+
if (this.longKeyPressTimeout) {
|
|
308
|
+
clearTimeout(this.longKeyPressTimeout);
|
|
309
|
+
this.longKeyPressTimeout = null;
|
|
310
310
|
}
|
|
311
|
+
}
|
|
311
312
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
313
|
+
/**
|
|
314
|
+
* If the keySupportsLongPress this method is called on longpress of key
|
|
315
|
+
* Register your longpress handlers here, and make sure to add it to list of supported keys
|
|
316
|
+
*/
|
|
317
|
+
onLongPress(event) {
|
|
318
|
+
this.longPressActive = true;
|
|
319
|
+
// Legacy way of determining whether controls are being displayed
|
|
320
|
+
// Or if the player is in a playback state.
|
|
321
|
+
const { displayState } = this.props;
|
|
322
|
+
const playerState = displayState === DISPLAY_STATES.PLAYER;
|
|
323
|
+
const hudState = displayState === DISPLAY_STATES.HUD;
|
|
324
|
+
const playbackState = playerState || hudState;
|
|
325
|
+
|
|
326
|
+
switch (event.code) {
|
|
327
|
+
case KEYS.Back.code:
|
|
328
|
+
// If you longpress the back button we probably want to exit
|
|
329
|
+
this.platformBack();
|
|
329
330
|
|
|
330
|
-
|
|
331
|
+
break;
|
|
331
332
|
|
|
332
|
-
|
|
333
|
-
|
|
333
|
+
case KEYS.Enter.code:
|
|
334
|
+
focusManager.longPress();
|
|
334
335
|
|
|
335
|
-
|
|
336
|
+
break;
|
|
336
337
|
|
|
337
|
-
|
|
338
|
-
|
|
338
|
+
case KEYS.Forward.code:
|
|
339
|
+
playbackState && this.props.seekMethods.onForwardLongPress();
|
|
339
340
|
|
|
340
|
-
|
|
341
|
+
break;
|
|
341
342
|
|
|
342
|
-
|
|
343
|
-
|
|
343
|
+
case KEYS.Rewind.code:
|
|
344
|
+
playbackState && this.props.seekMethods.onRewindLongPress();
|
|
344
345
|
|
|
345
|
-
|
|
346
|
+
break;
|
|
346
347
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
348
|
+
default:
|
|
349
|
+
break;
|
|
350
350
|
}
|
|
351
|
+
}
|
|
351
352
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
353
|
+
/**
|
|
354
|
+
* If the keySupportsLongPress this method is called on keyup of a longpress key
|
|
355
|
+
* If you need to handle the release or keyup of a longpress key register the handler here
|
|
356
|
+
*/
|
|
357
|
+
onLongPressRelease(event) {
|
|
358
|
+
this.longPressActive = false;
|
|
359
|
+
this.resetHudTimeout();
|
|
359
360
|
|
|
360
|
-
|
|
361
|
+
focusManager.pressOut();
|
|
361
362
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
363
|
+
switch (event.code) {
|
|
364
|
+
case KEYS.Forward.code:
|
|
365
|
+
this.props.seekMethods.onForwardPressOut();
|
|
365
366
|
|
|
366
|
-
|
|
367
|
+
break;
|
|
367
368
|
|
|
368
|
-
|
|
369
|
-
|
|
369
|
+
case KEYS.Rewind.code:
|
|
370
|
+
this.props.seekMethods.onForwardPressOut();
|
|
370
371
|
|
|
371
|
-
|
|
372
|
+
break;
|
|
372
373
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
374
|
+
default:
|
|
375
|
+
break;
|
|
376
376
|
}
|
|
377
|
+
}
|
|
377
378
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
379
|
+
/**
|
|
380
|
+
* Resets the sequence of keys we captured.
|
|
381
|
+
* Clear ensures that we don't interpret regular interactions
|
|
382
|
+
* as a sequence used to unlock certain features
|
|
383
|
+
*/
|
|
384
|
+
resetSequenceTimeout() {
|
|
385
|
+
const SEQUENCE_ENTRY_TIME = 1900;
|
|
386
|
+
|
|
387
|
+
if (this.sequenceTimeout) {
|
|
388
|
+
// Start timer over
|
|
389
|
+
clearTimeout(this.sequenceTimeout);
|
|
390
|
+
}
|
|
385
391
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
392
|
+
this.sequenceTimeout = setTimeout(() => {
|
|
393
|
+
// User needs to complete sequence before SEQUENCE_ENTRY_TIME
|
|
394
|
+
// or we set userSequence, and prev sequenceTimeout to empty values
|
|
395
|
+
this.sequenceTimeout = null;
|
|
396
|
+
this.userSequence = [];
|
|
397
|
+
}, SEQUENCE_ENTRY_TIME);
|
|
398
|
+
}
|
|
390
399
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
400
|
+
/**
|
|
401
|
+
* If a certain sequence of keys are pressed we enable special menus or settings
|
|
402
|
+
* Each supported sequence can be stored as a constant
|
|
403
|
+
*/
|
|
404
|
+
checkSequence(key) {
|
|
405
|
+
const SINK_SEQUENCE = [
|
|
406
|
+
KEYS.ArrowUp.keyCode,
|
|
407
|
+
KEYS.ArrowUp.keyCode,
|
|
408
|
+
KEYS.ArrowDown.keyCode,
|
|
409
|
+
KEYS.ArrowDown.keyCode,
|
|
410
|
+
KEYS.ArrowLeft.keyCode,
|
|
411
|
+
KEYS.ArrowRight.keyCode,
|
|
412
|
+
KEYS.ArrowLeft.keyCode,
|
|
413
|
+
KEYS.ArrowRight.keyCode,
|
|
414
|
+
];
|
|
415
|
+
|
|
416
|
+
this.resetSequenceTimeout();
|
|
417
|
+
this.userSequence.push(key);
|
|
418
|
+
|
|
419
|
+
// Remember [1,2,3] !== [1,2,3] in js, so string comparison is better
|
|
420
|
+
const shouldAddSink =
|
|
421
|
+
this.userSequence.toString() === SINK_SEQUENCE.toString();
|
|
422
|
+
|
|
423
|
+
if (shouldAddSink) {
|
|
424
|
+
this.props.xray.addRemoteSink({});
|
|
397
425
|
}
|
|
426
|
+
}
|
|
398
427
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
KEYS.ArrowUp.keyCode,
|
|
407
|
-
KEYS.ArrowDown.keyCode,
|
|
408
|
-
KEYS.ArrowDown.keyCode,
|
|
409
|
-
KEYS.ArrowLeft.keyCode,
|
|
410
|
-
KEYS.ArrowRight.keyCode,
|
|
411
|
-
KEYS.ArrowLeft.keyCode,
|
|
412
|
-
KEYS.ArrowRight.keyCode,
|
|
413
|
-
];
|
|
414
|
-
|
|
415
|
-
this.resetSequenceTimeout();
|
|
416
|
-
this.userSequence.push(key);
|
|
417
|
-
|
|
418
|
-
// Remember [1,2,3] !== [1,2,3] in js, so string comparison is better
|
|
419
|
-
const shouldAddSink =
|
|
420
|
-
this.userSequence.toString() === SINK_SEQUENCE.toString();
|
|
421
|
-
|
|
422
|
-
if (shouldAddSink) {
|
|
423
|
-
this.props.xray.addRemoteSink({});
|
|
424
|
-
}
|
|
425
|
-
}
|
|
428
|
+
/**
|
|
429
|
+
* Determines whether the key supports or handles longpress
|
|
430
|
+
* At the moment the only keys that support are the ones defined in
|
|
431
|
+
* supportedEvents array. This logic just prevents us from registering timeouts for every key
|
|
432
|
+
*/
|
|
433
|
+
keySupportsLongPress(event): boolean {
|
|
434
|
+
const supportedEvents = [KEYS.Back, KEYS.Enter, KEYS.Rewind, KEYS.Forward];
|
|
426
435
|
|
|
427
|
-
|
|
428
|
-
* Determines whether the key supports or handles longpress
|
|
429
|
-
* At the moment the only keys that support are the ones defined in
|
|
430
|
-
* supportedEvents array. This logic just prevents us from registering timeouts for every key
|
|
431
|
-
*/
|
|
432
|
-
keySupportsLongPress(event): boolean {
|
|
433
|
-
const supportedEvents = [
|
|
434
|
-
KEYS.Back,
|
|
435
|
-
KEYS.Enter,
|
|
436
|
-
KEYS.Rewind,
|
|
437
|
-
KEYS.Forward,
|
|
438
|
-
];
|
|
439
|
-
|
|
440
|
-
const eventMatcher = R.compose(R.prop("matches"), keyCode)(event);
|
|
436
|
+
const eventMatcher = R.compose(R.prop("matches"), keyCode)(event);
|
|
441
437
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
438
|
+
const supportsLongPress = R.compose(
|
|
439
|
+
R.any(R.equals(true)),
|
|
440
|
+
R.map(eventMatcher)
|
|
441
|
+
)(supportedEvents);
|
|
446
442
|
|
|
447
|
-
|
|
448
|
-
|
|
443
|
+
return supportsLongPress;
|
|
444
|
+
}
|
|
449
445
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
}
|
|
446
|
+
onKeyUp(event: KeyboardEvent) {
|
|
447
|
+
// If this is a supported longpress key we need to clear the timeout and handle release of key
|
|
448
|
+
// This logic is handled by onLongPressRelease
|
|
449
|
+
if (this.keySupportsLongPress(event)) {
|
|
450
|
+
if (this.longPressActive) {
|
|
451
|
+
this.onLongPressRelease(event);
|
|
452
|
+
} else {
|
|
453
|
+
this.clearLongPressTimeout();
|
|
459
454
|
}
|
|
460
455
|
}
|
|
456
|
+
}
|
|
461
457
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
458
|
+
onKeyDown(event) {
|
|
459
|
+
const { displayState, setDisplayState, navigator } = this.props;
|
|
460
|
+
const { isKeyboardVisible } = this.state;
|
|
465
461
|
|
|
466
|
-
|
|
462
|
+
const { isDialogVisible } = confirmationDialogStore.getState();
|
|
467
463
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
464
|
+
// If this is a supported longpress key we need to set the timeout and handle the longpress
|
|
465
|
+
if (this.keySupportsLongPress(event)) {
|
|
466
|
+
this.longKeyPressTimeout = setTimeout(() => {
|
|
467
|
+
this.onLongPress(event);
|
|
468
|
+
}, LONG_KEY_PRESS_TIMEOUT);
|
|
469
|
+
}
|
|
474
470
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
471
|
+
if (isKeyboardVisible && shouldUseOnScreenKeyboard()) {
|
|
472
|
+
if (keyCode(event).matchesAny("Escape", "Back")) {
|
|
473
|
+
event.preventDefault();
|
|
474
|
+
event.stopPropagation();
|
|
475
|
+
this.handleKeyboardDismiss();
|
|
480
476
|
|
|
481
|
-
|
|
482
|
-
}
|
|
477
|
+
return;
|
|
483
478
|
}
|
|
479
|
+
}
|
|
484
480
|
|
|
481
|
+
/**
|
|
482
|
+
When the player is displayed, we listen to Native Play / Pause / Stop
|
|
483
|
+
buttons. Any other key press will display the transport controls
|
|
484
|
+
*/
|
|
485
|
+
if (
|
|
486
|
+
displayState === DISPLAY_STATES.PLAYER ||
|
|
487
|
+
displayState === DISPLAY_STATES.HUD
|
|
488
|
+
) {
|
|
485
489
|
/**
|
|
486
|
-
|
|
487
|
-
buttons. Any other key press will display the transport controls
|
|
490
|
+
registering native keys for playback
|
|
488
491
|
*/
|
|
489
|
-
if (
|
|
490
|
-
|
|
491
|
-
displayState === DISPLAY_STATES.HUD
|
|
492
|
-
) {
|
|
493
|
-
/**
|
|
494
|
-
registering native keys for playback
|
|
495
|
-
*/
|
|
496
|
-
if (keyCode(event).matches(KEYS.TogglePlayPause)) {
|
|
497
|
-
const { playing } = playerManager.getState() || {};
|
|
498
|
-
|
|
499
|
-
if (!playing) {
|
|
500
|
-
return playerManager.togglePlayPause();
|
|
501
|
-
}
|
|
502
|
-
}
|
|
492
|
+
if (keyCode(event).matches(KEYS.TogglePlayPause)) {
|
|
493
|
+
const { playing } = playerManager.getState() || {};
|
|
503
494
|
|
|
504
|
-
if (
|
|
505
|
-
return playerManager.
|
|
495
|
+
if (!playing) {
|
|
496
|
+
return playerManager.togglePlayPause();
|
|
506
497
|
}
|
|
498
|
+
}
|
|
507
499
|
|
|
508
|
-
|
|
509
|
-
|
|
500
|
+
if (keyCode(event).matches(KEYS.Play)) {
|
|
501
|
+
return playerManager.play();
|
|
502
|
+
}
|
|
510
503
|
|
|
511
|
-
|
|
512
|
-
|
|
504
|
+
if (keyCode(event).matches(KEYS.Pause)) {
|
|
505
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
513
506
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
navigator.goBack();
|
|
507
|
+
return playerManager.pause();
|
|
508
|
+
}
|
|
517
509
|
|
|
518
|
-
|
|
519
|
-
|
|
510
|
+
if (keyCode(event).matches(KEYS.Stop)) {
|
|
511
|
+
setDisplayState(DISPLAY_STATES.DEFAULT);
|
|
512
|
+
navigator.goBack();
|
|
520
513
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
this.props.seekMethods.onForwardPress();
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
524
516
|
|
|
525
|
-
|
|
526
|
-
|
|
517
|
+
if (keyCode(event).matches(KEYS.Forward)) {
|
|
518
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
519
|
+
this.props.seekMethods.onForwardPress();
|
|
527
520
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
this.props.seekMethods.onRewindPress();
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
531
523
|
|
|
532
|
-
|
|
533
|
-
|
|
524
|
+
if (keyCode(event).matches(KEYS.Rewind)) {
|
|
525
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
526
|
+
this.props.seekMethods.onRewindPress();
|
|
527
|
+
|
|
528
|
+
return;
|
|
534
529
|
}
|
|
530
|
+
}
|
|
535
531
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
532
|
+
/**
|
|
533
|
+
When pressing backspace or the Native "Back" button:
|
|
534
|
+
if on the transport controls: we show the player
|
|
535
|
+
if on the player : we show the UI
|
|
536
|
+
if on the UI : we exit the app
|
|
537
|
+
*/
|
|
542
538
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
539
|
+
if (
|
|
540
|
+
keyCode(event).matchesAny(
|
|
541
|
+
KEYS.Back,
|
|
542
|
+
KEYS.Escape,
|
|
543
|
+
KEYS.EscapeDevice,
|
|
544
|
+
KEYS.Backspace
|
|
545
|
+
)
|
|
546
|
+
) {
|
|
547
|
+
switch (displayState) {
|
|
548
|
+
case DISPLAY_STATES.DEFAULT:
|
|
549
|
+
case DISPLAY_STATES.PLAYER:
|
|
550
|
+
if (isDialogVisible) {
|
|
551
|
+
this.onConfirmDialogClose();
|
|
552
|
+
} else if (navigator.canGoBack()) {
|
|
553
|
+
navigator.goBack();
|
|
554
|
+
} else if (this.isHomeScreen()) {
|
|
555
|
+
this.platformBack();
|
|
556
|
+
} else if (navigator.currentRoute.includes("hook")) {
|
|
557
|
+
// If code reaches this block navigator cant go back, it is not home,
|
|
558
|
+
// and this is a login plugin that was pushed on top of the home
|
|
559
|
+
// Treat it like a home screen and run platformBack()
|
|
560
|
+
const entryData = navigator?.data?.entry;
|
|
561
|
+
const isHookInHomescreen = entryData?.payload?.home;
|
|
562
|
+
|
|
563
|
+
const isHookFlowBlocker =
|
|
564
|
+
entryData?.hookPlugin?.module?.isFlowBlocker();
|
|
565
|
+
|
|
566
|
+
if (isHookInHomescreen && isHookFlowBlocker) {
|
|
559
567
|
this.platformBack();
|
|
560
|
-
} else if (navigator.currentRoute.includes("hook")) {
|
|
561
|
-
// If code reaches this block navigator cant go back, it is not home,
|
|
562
|
-
// and this is a login plugin that was pushed on top of the home
|
|
563
|
-
// Treat it like a home screen and run platformBack()
|
|
564
|
-
const entryData = navigator?.data?.entry;
|
|
565
|
-
const isHookInHomescreen = entryData?.payload?.home;
|
|
566
|
-
|
|
567
|
-
const isHookFlowBlocker =
|
|
568
|
-
entryData?.hookPlugin?.module?.isFlowBlocker();
|
|
569
|
-
|
|
570
|
-
if (isHookInHomescreen && isHookFlowBlocker) {
|
|
571
|
-
this.platformBack();
|
|
572
|
-
} else {
|
|
573
|
-
navigator.goBack(false, true);
|
|
574
|
-
}
|
|
575
568
|
} else {
|
|
576
|
-
|
|
569
|
+
navigator.goBack(false, true);
|
|
577
570
|
}
|
|
571
|
+
} else {
|
|
572
|
+
this.goToHome();
|
|
573
|
+
}
|
|
578
574
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
}
|
|
575
|
+
break;
|
|
576
|
+
case DISPLAY_STATES.HUD:
|
|
577
|
+
// IF transport controls are open, close them instead of closing player
|
|
578
|
+
setDisplayState(DISPLAY_STATES.PLAYER);
|
|
579
|
+
break;
|
|
580
|
+
default:
|
|
581
|
+
setDisplayState(DISPLAY_STATES.PLAYER);
|
|
582
|
+
break;
|
|
588
583
|
}
|
|
584
|
+
}
|
|
589
585
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
return true;
|
|
586
|
+
if (keyCode(event).matches(KEYS.Enter)) {
|
|
587
|
+
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
588
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
589
|
+
} else {
|
|
590
|
+
focusManager.press();
|
|
598
591
|
}
|
|
599
592
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
this.performExit();
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
603
595
|
|
|
604
|
-
|
|
605
|
-
|
|
596
|
+
if (keyCode(event).matches(KEYS.Exit)) {
|
|
597
|
+
if (isSamsungPlatform() || shouldUseOnScreenKeyboard()) {
|
|
598
|
+
this.performExit();
|
|
606
599
|
|
|
607
|
-
|
|
600
|
+
return;
|
|
608
601
|
}
|
|
609
602
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
!this.state.isKeyboardVisible
|
|
613
|
-
) {
|
|
614
|
-
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
615
|
-
setDisplayState(DISPLAY_STATES.HUD);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
this.checkSequence(event.keyCode);
|
|
619
|
-
|
|
620
|
-
const direction = keyCode(event).direction();
|
|
621
|
-
|
|
622
|
-
if (!isDialogVisible || !["up", "down"].includes(direction.value)) {
|
|
623
|
-
focusManager.moveFocus(direction);
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
if (!isDialogVisible) {
|
|
627
|
-
// run focus recovery on user interaction attempt
|
|
628
|
-
// probably we failed to set initial focus for some reason
|
|
629
|
-
focusManager.recoverFocus();
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
if (
|
|
633
|
-
displayState === DISPLAY_STATES.PLAYER ||
|
|
634
|
-
displayState === DISPLAY_STATES.HUD
|
|
635
|
-
) {
|
|
636
|
-
this.resetHudTimeout();
|
|
637
|
-
}
|
|
603
|
+
this.platformBack();
|
|
604
|
+
}
|
|
638
605
|
|
|
639
|
-
|
|
606
|
+
if (
|
|
607
|
+
keyCode(event).matchesAny(...ARROW_KEYS) &&
|
|
608
|
+
!this.state.isKeyboardVisible
|
|
609
|
+
) {
|
|
610
|
+
if (displayState === DISPLAY_STATES.PLAYER) {
|
|
611
|
+
setDisplayState(DISPLAY_STATES.HUD);
|
|
640
612
|
}
|
|
641
|
-
}
|
|
642
613
|
|
|
643
|
-
|
|
644
|
-
const { displayState } = this.props;
|
|
614
|
+
this.checkSequence(event.keyCode);
|
|
645
615
|
|
|
646
|
-
const
|
|
616
|
+
const direction = keyCode(event).direction();
|
|
647
617
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
isVertical: true,
|
|
652
|
-
value: "",
|
|
653
|
-
};
|
|
618
|
+
if (!isDialogVisible || !["up", "down"].includes(direction.value)) {
|
|
619
|
+
focusManager.moveFocus(direction);
|
|
620
|
+
}
|
|
654
621
|
|
|
655
|
-
if (
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
622
|
+
if (!isDialogVisible) {
|
|
623
|
+
// run focus recovery on user interaction attempt
|
|
624
|
+
// probably we failed to set initial focus for some reason
|
|
625
|
+
focusManager.recoverFocus();
|
|
659
626
|
}
|
|
660
627
|
|
|
661
628
|
if (
|
|
@@ -663,112 +630,139 @@ export function withInteractionManager(Component: React.FC) {
|
|
|
663
630
|
displayState === DISPLAY_STATES.HUD
|
|
664
631
|
) {
|
|
665
632
|
this.resetHudTimeout();
|
|
666
|
-
} else {
|
|
667
|
-
focusManager.moveFocus(DIRECTION);
|
|
668
633
|
}
|
|
634
|
+
|
|
635
|
+
return true;
|
|
669
636
|
}
|
|
637
|
+
}
|
|
670
638
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
const { displayState } = this.props;
|
|
639
|
+
onScroll(event) {
|
|
640
|
+
const { displayState } = this.props;
|
|
674
641
|
|
|
675
|
-
|
|
676
|
-
button === 1 && // number 1 represents press on the scroll wheel
|
|
677
|
-
(displayState === DISPLAY_STATES.PLAYER ||
|
|
678
|
-
displayState === DISPLAY_STATES.HUD)
|
|
679
|
-
) {
|
|
680
|
-
this.resetHudTimeout();
|
|
681
|
-
}
|
|
682
|
-
}
|
|
642
|
+
const deltaY = event?.deltaY;
|
|
683
643
|
|
|
684
|
-
|
|
685
|
-
|
|
644
|
+
const DIRECTION = {
|
|
645
|
+
axis: "y",
|
|
646
|
+
isHorizontal: false,
|
|
647
|
+
isVertical: true,
|
|
648
|
+
value: "",
|
|
649
|
+
};
|
|
650
|
+
|
|
651
|
+
if (deltaY > 0) {
|
|
652
|
+
DIRECTION.value = isLgPlatform() ? "down" : "up";
|
|
653
|
+
} else if (deltaY < 0) {
|
|
654
|
+
DIRECTION.value = isLgPlatform() ? "up" : "down";
|
|
686
655
|
}
|
|
687
656
|
|
|
688
|
-
|
|
689
|
-
|
|
657
|
+
if (
|
|
658
|
+
displayState === DISPLAY_STATES.PLAYER ||
|
|
659
|
+
displayState === DISPLAY_STATES.HUD
|
|
660
|
+
) {
|
|
661
|
+
this.resetHudTimeout();
|
|
662
|
+
} else {
|
|
663
|
+
focusManager.moveFocus(DIRECTION);
|
|
690
664
|
}
|
|
665
|
+
}
|
|
691
666
|
|
|
692
|
-
|
|
693
|
-
|
|
667
|
+
onMouseDown(event) {
|
|
668
|
+
const { button } = event;
|
|
669
|
+
const { displayState } = this.props;
|
|
694
670
|
|
|
695
|
-
|
|
696
|
-
|
|
671
|
+
if (
|
|
672
|
+
button === 1 && // number 1 represents press on the scroll wheel
|
|
673
|
+
(displayState === DISPLAY_STATES.PLAYER ||
|
|
674
|
+
displayState === DISPLAY_STATES.HUD)
|
|
675
|
+
) {
|
|
676
|
+
this.resetHudTimeout();
|
|
697
677
|
}
|
|
678
|
+
}
|
|
698
679
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
680
|
+
onKeyboardStateChange(event) {
|
|
681
|
+
this.setState({ isKeyboardVisible: event.visibility });
|
|
682
|
+
}
|
|
702
683
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
684
|
+
onConfirmDialogOpen() {
|
|
685
|
+
this.confirmDialog.showDialog();
|
|
686
|
+
}
|
|
706
687
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
isKeyboardVisible: true,
|
|
710
|
-
keyboardInput: (target as HTMLInputElement).value || "",
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
};
|
|
688
|
+
onConfirmDialogClose() {
|
|
689
|
+
this.confirmDialog.hideDialog();
|
|
714
690
|
|
|
715
|
-
|
|
716
|
-
|
|
691
|
+
// restore initial focus after closing dialog
|
|
692
|
+
focusManager.setInitialFocus();
|
|
693
|
+
}
|
|
717
694
|
|
|
718
|
-
|
|
695
|
+
handleInputFocus = (event: FocusEvent) => {
|
|
696
|
+
if (!shouldUseOnScreenKeyboard()) return;
|
|
697
|
+
const target = event.target as HTMLElement;
|
|
719
698
|
|
|
720
|
-
|
|
721
|
-
|
|
699
|
+
if (this.isDismissing) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
722
702
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
this.setState({ isKeyboardVisible: false });
|
|
729
|
-
}
|
|
730
|
-
}
|
|
703
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
|
|
704
|
+
this.setState({
|
|
705
|
+
isKeyboardVisible: true,
|
|
706
|
+
keyboardInput: (target as HTMLInputElement).value || "",
|
|
707
|
+
});
|
|
731
708
|
}
|
|
709
|
+
};
|
|
732
710
|
|
|
733
|
-
|
|
734
|
-
|
|
711
|
+
handleInputBlur(event: FocusEvent) {
|
|
712
|
+
if (!shouldUseOnScreenKeyboard()) return;
|
|
735
713
|
|
|
736
|
-
|
|
737
|
-
{
|
|
738
|
-
isKeyboardVisible: false,
|
|
739
|
-
keyboardInput: "",
|
|
740
|
-
},
|
|
741
|
-
() => {
|
|
742
|
-
this.isDismissing = false;
|
|
743
|
-
}
|
|
744
|
-
);
|
|
745
|
-
};
|
|
714
|
+
const target = event.target as HTMLElement;
|
|
746
715
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
}
|
|
716
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
|
|
717
|
+
const relatedTarget = event.relatedTarget as HTMLElement;
|
|
750
718
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
onInput={this.handleKeyboardInput}
|
|
759
|
-
onDismiss={this.handleKeyboardDismiss}
|
|
760
|
-
/>
|
|
761
|
-
)}
|
|
762
|
-
</>
|
|
763
|
-
);
|
|
719
|
+
if (
|
|
720
|
+
!relatedTarget ||
|
|
721
|
+
(relatedTarget.tagName !== "INPUT" &&
|
|
722
|
+
relatedTarget.tagName !== "TEXTAREA")
|
|
723
|
+
) {
|
|
724
|
+
this.setState({ isKeyboardVisible: false });
|
|
725
|
+
}
|
|
764
726
|
}
|
|
765
727
|
}
|
|
766
728
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
729
|
+
handleKeyboardDismiss = () => {
|
|
730
|
+
this.isDismissing = true;
|
|
731
|
+
|
|
732
|
+
this.setState(
|
|
733
|
+
{
|
|
734
|
+
isKeyboardVisible: false,
|
|
735
|
+
keyboardInput: "",
|
|
736
|
+
},
|
|
737
|
+
() => {
|
|
738
|
+
this.isDismissing = false;
|
|
739
|
+
}
|
|
740
|
+
);
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
handleKeyboardInput(value: string) {
|
|
744
|
+
this.setState({ keyboardInput: value });
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
render() {
|
|
748
|
+
return (
|
|
749
|
+
(shouldUseOnScreenKeyboard() && this.state.isKeyboardVisible && (
|
|
750
|
+
<OnScreenKeyboard
|
|
751
|
+
initialValue={this.state.keyboardInput}
|
|
752
|
+
onInput={this.handleKeyboardInput}
|
|
753
|
+
onDismiss={this.handleKeyboardDismiss}
|
|
754
|
+
/>
|
|
755
|
+
)) ||
|
|
756
|
+
null
|
|
757
|
+
);
|
|
758
|
+
}
|
|
774
759
|
}
|
|
760
|
+
|
|
761
|
+
export const InteractionManager = R.compose(
|
|
762
|
+
withNavigator,
|
|
763
|
+
withUseSeek,
|
|
764
|
+
withXray,
|
|
765
|
+
connectToStore(R.pick(["rivers"])),
|
|
766
|
+
PlayerContentContext.withConsumer,
|
|
767
|
+
DisplayStateContext.withConsumer
|
|
768
|
+
)(InteractionManagerClass);
|
package/index.js
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
/// <reference types="@applicaster/applicaster-types" />
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
-
import {
|
|
3
|
+
import { useHistory, useLocation } from "react-router-dom";
|
|
4
4
|
|
|
5
5
|
import { createQuickBrickApp } from "@applicaster/quick-brick-core";
|
|
6
6
|
import * as QuickBrickManager from "@applicaster/zapp-react-native-bridge/QuickBrick";
|
|
7
7
|
import * as Contexts from "@applicaster/zapp-react-native-ui-components/Contexts";
|
|
8
8
|
import { OfflineHandler } from "@applicaster/zapp-react-native-ui-components/Components/OfflineHandler";
|
|
9
9
|
import { getXray } from "@applicaster/zapp-react-native-utils/logger";
|
|
10
|
-
|
|
11
|
-
const { withXray } = getXray();
|
|
12
|
-
|
|
13
10
|
import { ZappDomRouter } from "./App/Router";
|
|
14
11
|
import { Layout } from "./App/Layout";
|
|
15
12
|
import { SplashLoader } from "./App/Loader/SplashLoader";
|
|
16
13
|
import { appLoader } from "./App/Loader";
|
|
17
14
|
|
|
18
|
-
import {
|
|
15
|
+
import { InteractionManager } from "./App/InteractionManager";
|
|
19
16
|
import "./main.css";
|
|
20
17
|
|
|
18
|
+
const { withXray } = getXray();
|
|
19
|
+
|
|
21
20
|
const contextProviders = R.map(R.prop("withProvider"), R.values(Contexts));
|
|
22
21
|
|
|
23
22
|
// Add DOM specific providers
|
|
@@ -33,7 +32,7 @@ export const ZappApp = createQuickBrickApp({
|
|
|
33
32
|
QuickBrickManager,
|
|
34
33
|
Layout,
|
|
35
34
|
OfflineHandler,
|
|
36
|
-
InteractionManager
|
|
35
|
+
InteractionManager,
|
|
37
36
|
appLoader,
|
|
38
37
|
SplashLoader,
|
|
39
38
|
ContextProviders: contextProviders,
|
package/main.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-dom-app",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.4484269996",
|
|
4
4
|
"description": "Zapp App Component for Applicaster's Quick Brick React Native App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/applicaster/zapp-react-dom-app#readme",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@applicaster/zapp-react-dom-ui-components": "12.0.0-alpha.
|
|
26
|
-
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.
|
|
27
|
-
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.
|
|
28
|
-
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.
|
|
29
|
-
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.
|
|
25
|
+
"@applicaster/zapp-react-dom-ui-components": "12.0.0-alpha.4484269996",
|
|
26
|
+
"@applicaster/zapp-react-native-bridge": "12.0.0-alpha.4484269996",
|
|
27
|
+
"@applicaster/zapp-react-native-redux": "12.0.0-alpha.4484269996",
|
|
28
|
+
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.4484269996",
|
|
29
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.4484269996",
|
|
30
30
|
"abortcontroller-polyfill": "^1.7.5",
|
|
31
31
|
"history": "^4.7.2",
|
|
32
32
|
"react-router-dom": "^5.1.2",
|