@applicaster/zapp-react-native-utils 13.0.0-alpha.7210171818 → 13.0.0-alpha.9270615060
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/appUtils/keyInputHandler/KeyInputHandler.ts +18 -18
- package/package.json +2 -2
- package/reactHooks/player/TVSeekControlller/ISeekController.ts +2 -2
- package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +39 -22
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +25 -56
- package/reactHooks/player/TVSeekControlller/TapSeekController.ts +15 -17
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
export type SeekKeyHandlerListener = {
|
|
3
3
|
onRewindPress: () => boolean;
|
|
4
|
-
|
|
4
|
+
onRewindLongPress: () => boolean;
|
|
5
5
|
onForwardPress: () => boolean;
|
|
6
|
-
|
|
6
|
+
onForwardLongPress: () => boolean;
|
|
7
7
|
onRewindPressOut: () => void;
|
|
8
8
|
onForwardPressOut: () => void;
|
|
9
9
|
}
|
|
@@ -44,13 +44,13 @@ export class KeyInputHandler {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
onRewindLongPress = () => {
|
|
48
|
+
for (const element of this.listeners) {
|
|
49
|
+
if (element.onRewindLongPress()) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
54
|
|
|
55
55
|
onForwardPress = () => {
|
|
56
56
|
for (const element of this.listeners) {
|
|
@@ -60,13 +60,13 @@ export class KeyInputHandler {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
onForwardLongPress = () => {
|
|
64
|
+
for (const element of this.listeners) {
|
|
65
|
+
if (element.onForwardLongPress()) {
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
70
|
|
|
71
71
|
// TODO: Event should be send to listeners who handled down event
|
|
72
72
|
onRewindPressOut = () => {
|
|
@@ -81,8 +81,8 @@ export class KeyInputHandler {
|
|
|
81
81
|
return {
|
|
82
82
|
onForwardPress: this.onForwardPress,
|
|
83
83
|
onRewindPress: this.onRewindPress,
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
onForwardLongPress: this.onForwardLongPress,
|
|
85
|
+
onRewindLongPress: this.onRewindLongPress,
|
|
86
86
|
onForwardPressOut: this.onForwardPressOut,
|
|
87
87
|
onRewindPressOut: this.onRewindPressOut
|
|
88
88
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "13.0.0-alpha.
|
|
3
|
+
"version": "13.0.0-alpha.9270615060",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "13.0.0-alpha.
|
|
31
|
+
"@applicaster/applicaster-types": "13.0.0-alpha.9270615060",
|
|
32
32
|
"buffer": "^5.2.1",
|
|
33
33
|
"camelize": "^1.0.0",
|
|
34
34
|
"create-react-context": "^0.2.3",
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
log_verbose,
|
|
7
7
|
TVSeekController,
|
|
8
8
|
} from "./TVSeekController";
|
|
9
|
-
import { interval, Subscription } from "rxjs";
|
|
10
|
-
import { tap } from "rxjs/operators";
|
|
9
|
+
import { timer, interval, Subscription } from "rxjs";
|
|
10
|
+
import { switchMap, tap } from "rxjs/operators";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Example interface for the configuration needed for long-press seeking.
|
|
@@ -31,7 +31,7 @@ export class LongPressSeekController implements ISeekController {
|
|
|
31
31
|
private config: LongPressConfig
|
|
32
32
|
) {}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
onPressStart(seekType: SEEK_TYPE) {
|
|
35
35
|
this.cleanUpSubscription();
|
|
36
36
|
|
|
37
37
|
log_debug(
|
|
@@ -45,32 +45,49 @@ export class LongPressSeekController implements ISeekController {
|
|
|
45
45
|
this.isLongPressActive = true;
|
|
46
46
|
this.currentSkipAmount = this.config.INITIAL_SKIP_AMOUNT;
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
/**
|
|
49
|
+
* We wait LONG_PRESS_THRESHOLD ms to confirm it's a long press.
|
|
50
|
+
* If it still active, we switch to an interval that emits every TIMER_INTERVAL_MS.
|
|
51
|
+
*/
|
|
52
|
+
const threshold$ = timer(this.config.LONG_PRESS_THRESHOLD).pipe(
|
|
53
|
+
tap(() =>
|
|
54
|
+
log_verbose("LongPressSeekController: Crossed long-press threshold")
|
|
55
|
+
),
|
|
56
|
+
switchMap(() => {
|
|
57
|
+
return interval(this.config.TIMER_INTERVAL_MS).pipe(
|
|
58
|
+
tap(() => {
|
|
59
|
+
this.parent.handleDelayedSeek(
|
|
60
|
+
this.parent.currentSeekType,
|
|
61
|
+
this.currentSkipAmount
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
log_debug(
|
|
65
|
+
`LongPressSeekController: handle delayed seek type: ${seekType} - currentSkipAmount: ${this.currentSkipAmount}.`
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
this.currentSkipAmount = Math.min(
|
|
69
|
+
this.currentSkipAmount + this.config.SKIP_INCREMENT_STEP,
|
|
70
|
+
this.config.MAX_SKIP_PER_TICK
|
|
71
|
+
);
|
|
72
|
+
})
|
|
63
73
|
);
|
|
64
74
|
})
|
|
65
|
-
)
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
this.subscription = threshold$.subscribe({
|
|
66
78
|
complete: () =>
|
|
67
|
-
log_verbose(
|
|
79
|
+
log_verbose(
|
|
80
|
+
"LongPressSeekController: Long press subscription complete"
|
|
81
|
+
),
|
|
68
82
|
error: (err) =>
|
|
69
|
-
log_error(
|
|
83
|
+
log_error(
|
|
84
|
+
"LongPressSeekController: Long press subscription error",
|
|
85
|
+
err
|
|
86
|
+
),
|
|
70
87
|
});
|
|
71
88
|
}
|
|
72
89
|
|
|
73
|
-
|
|
90
|
+
onPressEnd() {
|
|
74
91
|
const pressDuration = Date.now() - this.pressStartTime;
|
|
75
92
|
|
|
76
93
|
if (
|
|
@@ -6,7 +6,6 @@ import { SEEK_TYPE } from "../const";
|
|
|
6
6
|
import { createLogger } from "../../../logger";
|
|
7
7
|
import { Player } from "../../../appUtils/playerManager/player";
|
|
8
8
|
import { SeekKeyHandlerListener } from "../../../appUtils/keyInputHandler/KeyInputHandler";
|
|
9
|
-
import { ISeekController } from "./ISeekController";
|
|
10
9
|
|
|
11
10
|
export const { log_warning, log_debug, log_info, log_error, log_verbose } =
|
|
12
11
|
createLogger({
|
|
@@ -14,11 +13,6 @@ export const { log_warning, log_debug, log_info, log_error, log_verbose } =
|
|
|
14
13
|
subsystem: "TVSeekController",
|
|
15
14
|
});
|
|
16
15
|
|
|
17
|
-
export enum SEEK_STRATEGY {
|
|
18
|
-
TAP_SEEK = "TAP_SEEK",
|
|
19
|
-
AUTO_SEEK = "AUTO_SEEK",
|
|
20
|
-
}
|
|
21
|
-
|
|
22
16
|
export class TVSeekController implements SeekKeyHandlerListener {
|
|
23
17
|
// -- SHARED STATE ACROSS STRATEGIES --
|
|
24
18
|
public currentSeekType: SEEK_TYPE | null = null;
|
|
@@ -26,12 +20,9 @@ export class TVSeekController implements SeekKeyHandlerListener {
|
|
|
26
20
|
private controller: Player;
|
|
27
21
|
private delayedSeekProgressSubject = new BehaviorSubject<number | null>(null);
|
|
28
22
|
|
|
29
|
-
private currentSeekController: ISeekController;
|
|
30
|
-
|
|
31
23
|
// -- STRATEGY INSTANCES --
|
|
32
24
|
private tapSeekController: TapSeekController;
|
|
33
25
|
private longPressSeekController: LongPressSeekController;
|
|
34
|
-
private longPressThresholdTimeout: any | null = null;
|
|
35
26
|
|
|
36
27
|
// Example config for long press
|
|
37
28
|
private config = {
|
|
@@ -52,68 +43,48 @@ export class TVSeekController implements SeekKeyHandlerListener {
|
|
|
52
43
|
);
|
|
53
44
|
}
|
|
54
45
|
|
|
55
|
-
getDelayedSeekProgressObservable
|
|
46
|
+
getDelayedSeekProgressObservable() {
|
|
56
47
|
return this.delayedSeekProgressSubject;
|
|
57
48
|
}
|
|
58
49
|
|
|
59
|
-
setStrategy = (seekStrategy: SEEK_STRATEGY) => {
|
|
60
|
-
switch (seekStrategy) {
|
|
61
|
-
case SEEK_STRATEGY.TAP_SEEK:
|
|
62
|
-
clearTimeout(this.longPressThresholdTimeout);
|
|
63
|
-
this.longPressThresholdTimeout = null;
|
|
64
|
-
this.currentSeekController = this.tapSeekController;
|
|
65
|
-
|
|
66
|
-
break;
|
|
67
|
-
case SEEK_STRATEGY.AUTO_SEEK:
|
|
68
|
-
this.currentSeekController.reset();
|
|
69
|
-
this.currentSeekController = this.longPressSeekController;
|
|
70
|
-
break;
|
|
71
|
-
default:
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
handleStartSeek = (seekType: SEEK_TYPE) => {
|
|
76
|
-
this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
|
|
77
|
-
this.currentSeekController.onStartSeek(seekType);
|
|
78
|
-
log_verbose(`handleStartSeek: TAP seekType: ${seekType}`);
|
|
79
|
-
|
|
80
|
-
this.longPressThresholdTimeout = setTimeout(() => {
|
|
81
|
-
log_verbose(`handleStartSeek: longPressThresholdTimeout: TIMEOUT, START AUTO_SEEK seekType: ${seekType}`);
|
|
82
|
-
this.setStrategy(SEEK_STRATEGY.AUTO_SEEK);
|
|
83
|
-
this.currentSeekController.onStartSeek(seekType);
|
|
84
|
-
}, this.config.LONG_PRESS_THRESHOLD);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
50
|
onForwardPress = (): boolean => {
|
|
88
|
-
this.
|
|
51
|
+
this.tapSeekController.onPressStart(SEEK_TYPE.FORWARD);
|
|
89
52
|
|
|
90
53
|
return true;
|
|
91
54
|
};
|
|
92
55
|
|
|
93
56
|
onRewindPress = (): boolean => {
|
|
94
|
-
this.
|
|
57
|
+
this.tapSeekController.onPressStart(SEEK_TYPE.REWIND);
|
|
95
58
|
|
|
96
59
|
return true;
|
|
97
60
|
};
|
|
98
61
|
|
|
99
|
-
|
|
100
|
-
this.
|
|
101
|
-
this.
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
onRewindPressOut = () => {
|
|
105
|
-
const isAutoSeek = this.currentSeekController === this.longPressSeekController;
|
|
62
|
+
onForwardLongPress = (): boolean => {
|
|
63
|
+
this.longPressSeekController.onPressStart(SEEK_TYPE.FORWARD);
|
|
64
|
+
this.tapSeekController.reset();
|
|
106
65
|
|
|
107
|
-
|
|
66
|
+
return true;
|
|
67
|
+
};
|
|
108
68
|
|
|
109
|
-
|
|
110
|
-
|
|
69
|
+
onRewindLongPress = (): boolean => {
|
|
70
|
+
this.longPressSeekController.onPressStart(SEEK_TYPE.REWIND);
|
|
71
|
+
this.tapSeekController.reset();
|
|
111
72
|
|
|
112
|
-
|
|
113
|
-
|
|
73
|
+
return true;
|
|
74
|
+
};
|
|
114
75
|
|
|
115
|
-
|
|
116
|
-
|
|
76
|
+
onForwardPressOut = () => this.longPressSeekController.onPressEnd();
|
|
77
|
+
onRewindPressOut = () => this.longPressSeekController.onPressEnd();
|
|
78
|
+
|
|
79
|
+
getSeekMethods() {
|
|
80
|
+
return {
|
|
81
|
+
onForwardPress: this.onForwardPress,
|
|
82
|
+
onRewindPress: this.onRewindPress,
|
|
83
|
+
onForwardLongPress: this.onForwardLongPress,
|
|
84
|
+
onRewindLongPress: this.onRewindLongPress,
|
|
85
|
+
onForwardPressOut: this.onForwardPressOut,
|
|
86
|
+
onRewindPressOut: this.onRewindPressOut,
|
|
87
|
+
};
|
|
117
88
|
}
|
|
118
89
|
|
|
119
90
|
// ---------------------------
|
|
@@ -183,8 +154,6 @@ export class TVSeekController implements SeekKeyHandlerListener {
|
|
|
183
154
|
|
|
184
155
|
this.tapSeekController.reset();
|
|
185
156
|
this.longPressSeekController.reset();
|
|
186
|
-
|
|
187
|
-
this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
|
|
188
157
|
}
|
|
189
158
|
|
|
190
159
|
private getPlayer() {
|
|
@@ -12,7 +12,7 @@ export class TapSeekController implements ISeekController {
|
|
|
12
12
|
|
|
13
13
|
constructor(private parent: TVSeekController) {}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
onPressStart(seekType: SEEK_TYPE) {
|
|
16
16
|
log_debug(`TapSeekController: start tap seek type: ${seekType}.`);
|
|
17
17
|
|
|
18
18
|
const prevSeekType = this.parent.currentSeekType;
|
|
@@ -28,7 +28,19 @@ export class TapSeekController implements ISeekController {
|
|
|
28
28
|
this.tapSequenceTimeout = null;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
this.tapSequenceTimeout = setTimeout(() => {
|
|
32
|
+
if (this.parent.delayedSeekOffset !== null) {
|
|
33
|
+
this.parent.seekPlayer(this.parent.delayedSeekOffset);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
log_debug(
|
|
37
|
+
`TapSeekController: Tap sequence timeout fired, delayedSeekOffset: ${this.parent.delayedSeekOffset}.`
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
this.parent.resetAll();
|
|
41
|
+
}, this.ON_PRESS_RESET_DURATION);
|
|
42
|
+
|
|
43
|
+
const clicksBeforePause = 3;
|
|
32
44
|
const skipTime = getSkipTime(this.seekMultiplier);
|
|
33
45
|
|
|
34
46
|
if (this.seekMultiplier > clicksBeforePause) {
|
|
@@ -48,21 +60,7 @@ export class TapSeekController implements ISeekController {
|
|
|
48
60
|
this.seekMultiplier++;
|
|
49
61
|
}
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
this.tapSequenceTimeout = setTimeout(() => {
|
|
53
|
-
if (this.parent.delayedSeekOffset !== null) {
|
|
54
|
-
this.parent.seekPlayer(this.parent.delayedSeekOffset);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
log_debug(
|
|
58
|
-
`TapSeekController: Tap sequence timeout fired, delayedSeekOffset: ${this.parent.delayedSeekOffset}.`
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
this.parent.resetAll();
|
|
62
|
-
}, this.ON_PRESS_RESET_DURATION);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
reset = () => {
|
|
63
|
+
reset() {
|
|
66
64
|
log_debug("TapSeekController: Reset states");
|
|
67
65
|
|
|
68
66
|
this.seekMultiplier = 1;
|