@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.
@@ -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
- }