@applicaster/zapp-react-native-utils 13.0.0-alpha.1632352572 → 13.0.0-alpha.1909212433
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/keyCodes/keysByPlatform.js +0 -4
- package/appUtils/playerManager/player.ts +5 -17
- package/appUtils/playerManager/playerNative.ts +1 -2
- package/appUtils/playerManager/usePlayerControllerSetup.tsx +3 -3
- package/manifestUtils/sharedConfiguration/screenPicker/__tests__/utils.test.js +304 -0
- package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +875 -0
- package/manifestUtils/sharedConfiguration/screenPicker/utils.js +130 -0
- package/package.json +2 -2
- package/reactHooks/player/__tests__/useAutoSeek.test.tsx +116 -0
- package/reactHooks/player/__tests__/useTapSeek.test.ts +94 -0
- package/reactHooks/player/const.ts +1 -1
- package/reactHooks/player/index.ts +6 -0
- package/reactHooks/player/useAutoSeek.tsx +87 -0
- package/reactHooks/player/useSeek.tsx +66 -0
- package/reactHooks/player/useTapSeek.tsx +58 -0
- package/appUtils/keyInputHandler/KeyInputHandler.ts +0 -68
- package/reactHooks/player/TVSeekControlller/ISeekController.ts +0 -7
- package/reactHooks/player/TVSeekControlller/LongPressSeekController.ts +0 -109
- package/reactHooks/player/TVSeekControlller/TVSeekController.ts +0 -168
- package/reactHooks/player/TVSeekControlller/TapSeekController.ts +0 -75
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { ISeekController } from "./ISeekController";
|
|
2
|
-
import { SEEK_TYPE } from "../const";
|
|
3
|
-
import {
|
|
4
|
-
log_debug,
|
|
5
|
-
log_error,
|
|
6
|
-
log_verbose,
|
|
7
|
-
TVSeekController,
|
|
8
|
-
} from "./TVSeekController";
|
|
9
|
-
import { interval, Subscription } from "rxjs";
|
|
10
|
-
import { tap } from "rxjs/operators";
|
|
11
|
-
|
|
12
|
-
interface LongPressConfig {
|
|
13
|
-
LONG_PRESS_THRESHOLD: number; // ms
|
|
14
|
-
TIMER_INTERVAL_MS: number; // ms
|
|
15
|
-
SKIP_INCREMENT_STEP: number; // seconds
|
|
16
|
-
MAX_SKIP_PER_TICK: number; // seconds
|
|
17
|
-
INITIAL_SKIP_AMOUNT: number; // e.g., 10s to start
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export class LongPressSeekController implements ISeekController {
|
|
21
|
-
private pressStartTime = 0;
|
|
22
|
-
private isLongPressActive = false;
|
|
23
|
-
private currentSkipAmount = 0;
|
|
24
|
-
private subscription: Subscription | null = null;
|
|
25
|
-
|
|
26
|
-
constructor(
|
|
27
|
-
private parent: TVSeekController,
|
|
28
|
-
private config: LongPressConfig
|
|
29
|
-
) {}
|
|
30
|
-
|
|
31
|
-
onStartSeek(seekType: SEEK_TYPE) {
|
|
32
|
-
this.cleanUpSubscription();
|
|
33
|
-
|
|
34
|
-
log_debug(
|
|
35
|
-
`LongPressSeekController: start long press seek type:${seekType}.`
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
this.parent.currentSeekType = seekType;
|
|
39
|
-
this.parent.pausePlayer();
|
|
40
|
-
|
|
41
|
-
this.pressStartTime = Date.now();
|
|
42
|
-
this.isLongPressActive = true;
|
|
43
|
-
this.currentSkipAmount = this.config.INITIAL_SKIP_AMOUNT;
|
|
44
|
-
|
|
45
|
-
this.subscription = interval(this.config.TIMER_INTERVAL_MS)
|
|
46
|
-
.pipe(
|
|
47
|
-
tap(() => {
|
|
48
|
-
this.parent.handleDelayedSeek(
|
|
49
|
-
this.parent.currentSeekType,
|
|
50
|
-
this.currentSkipAmount
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
log_debug(
|
|
54
|
-
`LongPressSeekController: handle delayed seek type: ${seekType} - currentSkipAmount: ${this.currentSkipAmount}.`
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
this.currentSkipAmount = Math.min(
|
|
58
|
-
this.currentSkipAmount + this.config.SKIP_INCREMENT_STEP,
|
|
59
|
-
this.config.MAX_SKIP_PER_TICK
|
|
60
|
-
);
|
|
61
|
-
})
|
|
62
|
-
)
|
|
63
|
-
.subscribe({
|
|
64
|
-
complete: () =>
|
|
65
|
-
log_verbose(
|
|
66
|
-
"LongPressSeekController: Long press subscription complete"
|
|
67
|
-
),
|
|
68
|
-
error: (err) =>
|
|
69
|
-
log_error(
|
|
70
|
-
"LongPressSeekController: Long press subscription error",
|
|
71
|
-
err
|
|
72
|
-
),
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
onSeekEnd() {
|
|
77
|
-
const pressDuration = Date.now() - this.pressStartTime;
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
this.isLongPressActive &&
|
|
81
|
-
pressDuration > this.config.LONG_PRESS_THRESHOLD
|
|
82
|
-
) {
|
|
83
|
-
const offset = this.parent.delayedSeekOffset;
|
|
84
|
-
|
|
85
|
-
if (offset) {
|
|
86
|
-
log_debug(
|
|
87
|
-
`LongPressSeekController: onPressEnd for LongPressSeekController, seek offset: ${offset}`
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
this.parent.seekPlayer(offset);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
this.parent.resetAll();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
reset() {
|
|
98
|
-
this.isLongPressActive = false;
|
|
99
|
-
this.currentSkipAmount = 0;
|
|
100
|
-
this.cleanUpSubscription();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
private cleanUpSubscription() {
|
|
104
|
-
if (this.subscription) {
|
|
105
|
-
this.subscription.unsubscribe();
|
|
106
|
-
this.subscription = null;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { BehaviorSubject } from "rxjs";
|
|
2
|
-
import { TapSeekController } from "./TapSeekController";
|
|
3
|
-
import { LongPressSeekController } from "./LongPressSeekController";
|
|
4
|
-
import { SEEK_TYPE } from "../const";
|
|
5
|
-
import { createLogger } from "../../../logger";
|
|
6
|
-
import { Player } from "../../../appUtils/playerManager/player";
|
|
7
|
-
import { SeekKeyHandlerListener } from "../../../appUtils/keyInputHandler/KeyInputHandler";
|
|
8
|
-
import { ISeekController } from "./ISeekController";
|
|
9
|
-
|
|
10
|
-
export const { log_warning, log_debug, log_info, log_error, log_verbose } =
|
|
11
|
-
createLogger({
|
|
12
|
-
category: "General",
|
|
13
|
-
subsystem: "TVSeekController",
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export enum SEEK_STRATEGY {
|
|
17
|
-
TAP_SEEK = "TAP_SEEK",
|
|
18
|
-
AUTO_SEEK = "AUTO_SEEK",
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class TVSeekController implements SeekKeyHandlerListener {
|
|
22
|
-
public currentSeekType: SEEK_TYPE | null = null;
|
|
23
|
-
public delayedSeekOffset: number | null = null;
|
|
24
|
-
private readonly playerController: Player;
|
|
25
|
-
private delayedSeekProgressSubject = new BehaviorSubject<number | null>(null);
|
|
26
|
-
|
|
27
|
-
private currentSeekController: ISeekController;
|
|
28
|
-
|
|
29
|
-
private tapSeekController: TapSeekController;
|
|
30
|
-
private longPressSeekController: LongPressSeekController;
|
|
31
|
-
private longPressThresholdTimeout: any | null = null;
|
|
32
|
-
|
|
33
|
-
private config = {
|
|
34
|
-
LONG_PRESS_THRESHOLD: 500,
|
|
35
|
-
TIMER_INTERVAL_MS: 300,
|
|
36
|
-
SKIP_INCREMENT_STEP: 5,
|
|
37
|
-
MAX_SKIP_PER_TICK: 300,
|
|
38
|
-
INITIAL_SKIP_AMOUNT: 10,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
constructor(playerController: Player) {
|
|
42
|
-
this.playerController = playerController;
|
|
43
|
-
this.tapSeekController = new TapSeekController(this);
|
|
44
|
-
|
|
45
|
-
this.longPressSeekController = new LongPressSeekController(
|
|
46
|
-
this,
|
|
47
|
-
this.config
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
getDelayedSeekProgressObservable = () => {
|
|
52
|
-
return this.delayedSeekProgressSubject;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
setStrategy = (seekStrategy: SEEK_STRATEGY) => {
|
|
56
|
-
switch (seekStrategy) {
|
|
57
|
-
case SEEK_STRATEGY.TAP_SEEK:
|
|
58
|
-
clearTimeout(this.longPressThresholdTimeout);
|
|
59
|
-
this.longPressThresholdTimeout = null;
|
|
60
|
-
this.currentSeekController = this.tapSeekController;
|
|
61
|
-
|
|
62
|
-
break;
|
|
63
|
-
case SEEK_STRATEGY.AUTO_SEEK:
|
|
64
|
-
this.currentSeekController.reset();
|
|
65
|
-
this.currentSeekController = this.longPressSeekController;
|
|
66
|
-
break;
|
|
67
|
-
default:
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
handleStartSeek = (seekType: SEEK_TYPE) => {
|
|
72
|
-
this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
|
|
73
|
-
this.currentSeekController.onStartSeek(seekType);
|
|
74
|
-
|
|
75
|
-
this.longPressThresholdTimeout = setTimeout(() => {
|
|
76
|
-
this.setStrategy(SEEK_STRATEGY.AUTO_SEEK);
|
|
77
|
-
this.currentSeekController.onStartSeek(seekType);
|
|
78
|
-
}, this.config.LONG_PRESS_THRESHOLD);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
onForwardPress = (): boolean => {
|
|
82
|
-
this.handleStartSeek(SEEK_TYPE.FORWARD);
|
|
83
|
-
|
|
84
|
-
return true;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
onRewindPress = (): boolean => {
|
|
88
|
-
this.handleStartSeek(SEEK_TYPE.REWIND);
|
|
89
|
-
|
|
90
|
-
return true;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
onSeekEnd = () => {
|
|
94
|
-
this.currentSeekController.onSeekEnd();
|
|
95
|
-
this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
onRewindPressOut = () => {
|
|
99
|
-
this.onSeekEnd();
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
onForwardPressOut = () => {
|
|
103
|
-
this.onSeekEnd();
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
public onVideoProgress = (position: number) => {
|
|
107
|
-
if (this.delayedSeekOffset) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// TODO: If 1 second after seek, send
|
|
112
|
-
|
|
113
|
-
this.delayedSeekProgressSubject.next(position);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
handleDelayedSeek(eventType: SEEK_TYPE, skipTime: number) {
|
|
117
|
-
if (this.delayedSeekOffset === null) {
|
|
118
|
-
this.pausePlayer();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const newOffset = (this.delayedSeekOffset || 0) + skipTime;
|
|
122
|
-
const currentPos = this.playerController.getPosition();
|
|
123
|
-
let targetPos = currentPos;
|
|
124
|
-
|
|
125
|
-
if (eventType === SEEK_TYPE.FORWARD) {
|
|
126
|
-
targetPos = Math.min(
|
|
127
|
-
currentPos + newOffset,
|
|
128
|
-
this.playerController.getSeekableDuration()
|
|
129
|
-
);
|
|
130
|
-
} else {
|
|
131
|
-
targetPos = Math.max(0, currentPos - newOffset);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
this.delayedSeekOffset = newOffset;
|
|
135
|
-
|
|
136
|
-
log_debug(
|
|
137
|
-
`TVSeekController: handleDelayedSeek - targetPos: ${targetPos}, offset: ${newOffset}, skipTime: ${skipTime}`
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
this.delayedSeekProgressSubject.next(targetPos);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
seekPlayer(offset: number) {
|
|
144
|
-
this.playerController[this.currentSeekType](offset);
|
|
145
|
-
this.playerPlay();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
playerPlay() {
|
|
149
|
-
if (this.playerController.isPaused()) {
|
|
150
|
-
this.playerController.play();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
pausePlayer() {
|
|
155
|
-
this.playerController.pause();
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
resetAll() {
|
|
159
|
-
log_debug("TVSeekController: Reset all states");
|
|
160
|
-
this.currentSeekType = null;
|
|
161
|
-
this.delayedSeekOffset = null;
|
|
162
|
-
|
|
163
|
-
this.tapSeekController.reset();
|
|
164
|
-
this.longPressSeekController.reset();
|
|
165
|
-
|
|
166
|
-
this.setStrategy(SEEK_STRATEGY.TAP_SEEK);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { ISeekController } from "./ISeekController";
|
|
2
|
-
import { SEEK_TYPE, MAX_SEEK_TIME, SKIP_TIME_BASE } from "../const";
|
|
3
|
-
import { log_debug, TVSeekController } from "./TVSeekController";
|
|
4
|
-
|
|
5
|
-
const getSkipTime = (multiplier: number) =>
|
|
6
|
-
Math.min(MAX_SEEK_TIME, SKIP_TIME_BASE * multiplier);
|
|
7
|
-
|
|
8
|
-
export class TapSeekController implements ISeekController {
|
|
9
|
-
private tapSequenceTimeout: any | null = null;
|
|
10
|
-
private seekMultiplier = 1;
|
|
11
|
-
private readonly ON_PRESS_RESET_DURATION = 500; // ms
|
|
12
|
-
|
|
13
|
-
constructor(private parent: TVSeekController) {}
|
|
14
|
-
|
|
15
|
-
onStartSeek = (seekType: SEEK_TYPE) => {
|
|
16
|
-
log_debug(`TapSeekController: start tap seek type: ${seekType}.`);
|
|
17
|
-
|
|
18
|
-
const prevSeekType = this.parent.currentSeekType;
|
|
19
|
-
|
|
20
|
-
if (prevSeekType !== seekType) {
|
|
21
|
-
this.reset();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
this.parent.currentSeekType = seekType;
|
|
25
|
-
|
|
26
|
-
if (this.tapSequenceTimeout) {
|
|
27
|
-
clearTimeout(this.tapSequenceTimeout);
|
|
28
|
-
this.tapSequenceTimeout = null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const clicksBeforePause = 0;
|
|
32
|
-
const skipTime = getSkipTime(this.seekMultiplier);
|
|
33
|
-
|
|
34
|
-
if (this.seekMultiplier > clicksBeforePause) {
|
|
35
|
-
log_debug(
|
|
36
|
-
`TapSeekController: handle delayed seek type:${seekType} - skipTime: ${skipTime}.`
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
this.parent.handleDelayedSeek(seekType, skipTime);
|
|
40
|
-
} else {
|
|
41
|
-
log_debug(
|
|
42
|
-
`TapSeekController: handle seek type:${seekType} - skipTime: ${skipTime}.`
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
this.parent.seekPlayer(skipTime);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
this.seekMultiplier++;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
onSeekEnd = () => {
|
|
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 = () => {
|
|
66
|
-
log_debug("TapSeekController: Reset states");
|
|
67
|
-
|
|
68
|
-
this.seekMultiplier = 1;
|
|
69
|
-
|
|
70
|
-
if (this.tapSequenceTimeout) {
|
|
71
|
-
clearTimeout(this.tapSequenceTimeout);
|
|
72
|
-
this.tapSequenceTimeout = null;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|