@applicaster/zapp-react-native-utils 16.0.0-rc.100 → 16.0.0-rc.101
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/playerManager/__tests__/playerNative.test.ts +76 -0
- package/appUtils/playerManager/__tests__/playerNativeCommand.test.ts +62 -0
- package/appUtils/playerManager/const.ts +13 -0
- package/appUtils/playerManager/player.ts +10 -0
- package/appUtils/playerManager/playerNative.ts +22 -0
- package/appUtils/playerManager/playerNativeCommand.ts +3 -6
- package/package.json +2 -2
|
@@ -36,3 +36,79 @@ describe("PlayerNative.isAudioItem", () => {
|
|
|
36
36
|
expect(playerWithEntry(null).isAudioItem()).toBe(false);
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
|
+
|
|
40
|
+
describe("PlayerNative.command", () => {
|
|
41
|
+
it("invokes native function with playerId on iOS platform", () => {
|
|
42
|
+
const player = new PlayerNative({
|
|
43
|
+
entry: null,
|
|
44
|
+
player: { current: {} } as any,
|
|
45
|
+
playerId: "test-player",
|
|
46
|
+
playerPluginId: "QuickBrickPlayerPlugin",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const commandSpy = jest.fn();
|
|
50
|
+
|
|
51
|
+
jest.spyOn(player, "getPlayerModule").mockReturnValue({
|
|
52
|
+
command: commandSpy,
|
|
53
|
+
} as any);
|
|
54
|
+
|
|
55
|
+
player.command("setPlayerControls", { transport: ["play"] });
|
|
56
|
+
|
|
57
|
+
expect(commandSpy).toHaveBeenCalledWith(
|
|
58
|
+
"setPlayerControls",
|
|
59
|
+
"test-player",
|
|
60
|
+
{
|
|
61
|
+
transport: ["play"],
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("invokes native function with view tag on Android when method exists", () => {
|
|
67
|
+
const reactUtils = require("../../../reactUtils");
|
|
68
|
+
jest.spyOn(reactUtils, "isApplePlatform").mockReturnValue(false);
|
|
69
|
+
|
|
70
|
+
const player = new PlayerNative({
|
|
71
|
+
entry: null,
|
|
72
|
+
player: { current: {} } as any,
|
|
73
|
+
playerId: "test-player",
|
|
74
|
+
playerPluginId: "QuickBrickPlayerPlugin",
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const commandSpy = jest.fn();
|
|
78
|
+
|
|
79
|
+
jest.spyOn(player, "getPlayerModule").mockReturnValue({
|
|
80
|
+
command: commandSpy,
|
|
81
|
+
} as any);
|
|
82
|
+
|
|
83
|
+
jest.spyOn(player, "getComponentNode").mockReturnValue(12345 as any);
|
|
84
|
+
|
|
85
|
+
player.command("setPlayerControls", { transport: ["play"] });
|
|
86
|
+
|
|
87
|
+
expect(commandSpy).toHaveBeenCalledWith(12345, "setPlayerControls", {
|
|
88
|
+
transport: ["play"],
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
(reactUtils.isApplePlatform as jest.Mock).mockRestore();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("handles when native module does not have command method on Android", () => {
|
|
95
|
+
const reactUtils = require("../../../reactUtils");
|
|
96
|
+
jest.spyOn(reactUtils, "isApplePlatform").mockReturnValue(false);
|
|
97
|
+
|
|
98
|
+
const player = new PlayerNative({
|
|
99
|
+
entry: null,
|
|
100
|
+
player: { current: {} } as any,
|
|
101
|
+
playerId: "test-player",
|
|
102
|
+
playerPluginId: "KalturaPlayerPlugin",
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
jest.spyOn(player, "getPlayerModule").mockReturnValue({} as any);
|
|
106
|
+
jest.spyOn(player, "getComponentNode").mockReturnValue(12345 as any);
|
|
107
|
+
|
|
108
|
+
expect(() => {
|
|
109
|
+
player.command("setPlayerControls", { transport: ["play"] });
|
|
110
|
+
}).not.toThrow();
|
|
111
|
+
|
|
112
|
+
(reactUtils.isApplePlatform as jest.Mock).mockRestore();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { NativeModules } from "react-native";
|
|
2
|
+
import {
|
|
3
|
+
PlayerNativeCommandTypes,
|
|
4
|
+
PlayerNativeSendCommand,
|
|
5
|
+
} from "../playerNativeCommand";
|
|
6
|
+
|
|
7
|
+
describe("PlayerNativeSendCommand", () => {
|
|
8
|
+
const reactUtils = require("../../../reactUtils");
|
|
9
|
+
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
jest.restoreAllMocks();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("calls NativeModules.PlayerModule.command on Apple platform with playerId", () => {
|
|
15
|
+
jest.spyOn(reactUtils, "isApplePlatform").mockReturnValue(true);
|
|
16
|
+
|
|
17
|
+
NativeModules.PlayerModule = {
|
|
18
|
+
command: jest.fn(),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
PlayerNativeSendCommand(
|
|
22
|
+
PlayerNativeCommandTypes.setPlayerControls,
|
|
23
|
+
"player-123",
|
|
24
|
+
{ transport: ["play"] }
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
expect(NativeModules.PlayerModule.command).toHaveBeenCalledWith(
|
|
28
|
+
"setPlayerControls",
|
|
29
|
+
"player-123",
|
|
30
|
+
{ transport: ["play"] }
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("does not call NativeModules.PlayerModule.command on non-Apple platform", () => {
|
|
35
|
+
jest.spyOn(reactUtils, "isApplePlatform").mockReturnValue(false);
|
|
36
|
+
|
|
37
|
+
NativeModules.PlayerModule = {
|
|
38
|
+
command: jest.fn(),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
PlayerNativeSendCommand(
|
|
42
|
+
PlayerNativeCommandTypes.setPlayerControls,
|
|
43
|
+
"player-123",
|
|
44
|
+
{ transport: ["play"] }
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
expect(NativeModules.PlayerModule.command).not.toHaveBeenCalled();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("does nothing when playerId or command is missing", () => {
|
|
51
|
+
jest.spyOn(reactUtils, "isApplePlatform").mockReturnValue(true);
|
|
52
|
+
|
|
53
|
+
NativeModules.PlayerModule = {
|
|
54
|
+
command: jest.fn(),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
PlayerNativeSendCommand("", "player-123");
|
|
58
|
+
PlayerNativeSendCommand("setPlayerControls", "");
|
|
59
|
+
|
|
60
|
+
expect(NativeModules.PlayerModule.command).not.toHaveBeenCalled();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -59,6 +59,19 @@ export enum SharedPlayerCallBacksKeys {
|
|
|
59
59
|
// PIP
|
|
60
60
|
OnPlayerDetached = "onPlayerDetached",
|
|
61
61
|
OnPlayerAttached = "onPlayerAttached",
|
|
62
|
+
|
|
63
|
+
OnRemoteCommand = "onRemoteCommand",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Ids native sends in onRemoteCommand (lock screen / Control Center / CarPlay buttons)
|
|
67
|
+
export enum RemoteCommand {
|
|
68
|
+
Play = "play",
|
|
69
|
+
Pause = "pause",
|
|
70
|
+
Stop = "stop",
|
|
71
|
+
NextTrack = "nextTrack",
|
|
72
|
+
PreviousTrack = "previousTrack",
|
|
73
|
+
SkipForward = "skipForward",
|
|
74
|
+
SkipBackward = "skipBackward",
|
|
62
75
|
}
|
|
63
76
|
|
|
64
77
|
export enum PlayerRole {
|
|
@@ -746,6 +746,13 @@ export class Player {
|
|
|
746
746
|
});
|
|
747
747
|
};
|
|
748
748
|
|
|
749
|
+
onRemoteCommand = (event: QuickBrickPlayer.RemoteCommandEvent) => {
|
|
750
|
+
this.invokeListenersUpdate({
|
|
751
|
+
callbackName: SharedPlayerCallBacksKeys.OnRemoteCommand,
|
|
752
|
+
event,
|
|
753
|
+
});
|
|
754
|
+
};
|
|
755
|
+
|
|
749
756
|
getTracksState = (): QuickBrickPlayer.TracksState =>
|
|
750
757
|
this.playerState.trackState;
|
|
751
758
|
|
|
@@ -823,6 +830,8 @@ export class Player {
|
|
|
823
830
|
// PIP
|
|
824
831
|
onPlayerDetached: this.onPlayerDetached,
|
|
825
832
|
onPlayerAttached: this.onPlayerAttached,
|
|
833
|
+
|
|
834
|
+
onRemoteCommand: this.onRemoteCommand,
|
|
826
835
|
});
|
|
827
836
|
|
|
828
837
|
play = () => {};
|
|
@@ -832,6 +841,7 @@ export class Player {
|
|
|
832
841
|
setPlaybackRate = (_rate) => {};
|
|
833
842
|
startSleepTimer = (_timestamp) => {};
|
|
834
843
|
cancelSleepTimer = () => {};
|
|
844
|
+
command = (_command: string, _userInfo?: Record<string, any>) => {};
|
|
835
845
|
|
|
836
846
|
getPluginConfiguration = () => null;
|
|
837
847
|
appStateChange = (_appState, _previousAppState) => {};
|
|
@@ -6,6 +6,7 @@ import { findNodeHandle } from "react-native";
|
|
|
6
6
|
import { PlayerRole } from "./const";
|
|
7
7
|
import { toBooleanWithDefaultFalse } from "../../booleanUtils";
|
|
8
8
|
import { RNPlayerManager } from "./nativePlayerManager";
|
|
9
|
+
import { isApplePlatform } from "../../reactUtils";
|
|
9
10
|
|
|
10
11
|
const logger = createLogger({
|
|
11
12
|
category: "PlayerNativeController",
|
|
@@ -27,6 +28,7 @@ interface PlayerMethods {
|
|
|
27
28
|
appStateChange?: (appState: string, previousAppState: string) => void;
|
|
28
29
|
closeNativePlayer?: () => void;
|
|
29
30
|
togglePlayPause?: () => void;
|
|
31
|
+
command?: (command: string, userInfo?: Record<string, any>) => void;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
type PlayerComponent = ReactComponent<PlayerRefProps> & PlayerMethods;
|
|
@@ -52,6 +54,7 @@ const PlayerModuleFuncNames = {
|
|
|
52
54
|
startSleepTimer: "startSleepTimer",
|
|
53
55
|
cancelSleepTimer: "cancelSleepTimer",
|
|
54
56
|
getSleepTimerEnd: "getSleepTimerEnd",
|
|
57
|
+
command: "command",
|
|
55
58
|
};
|
|
56
59
|
|
|
57
60
|
export class PlayerNative extends Player {
|
|
@@ -206,6 +209,25 @@ export class PlayerNative extends Player {
|
|
|
206
209
|
}
|
|
207
210
|
};
|
|
208
211
|
|
|
212
|
+
command = (command: string, userInfo?: Record<string, any>) => {
|
|
213
|
+
if (isApplePlatform()) {
|
|
214
|
+
const module = this.getPlayerModule();
|
|
215
|
+
module?.command?.(command, this.playerId, userInfo);
|
|
216
|
+
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (
|
|
221
|
+
!this.invokeNativeFunction(
|
|
222
|
+
PlayerModuleFuncNames.command,
|
|
223
|
+
command,
|
|
224
|
+
userInfo
|
|
225
|
+
)
|
|
226
|
+
) {
|
|
227
|
+
this.currentPlayerComponent()?.command?.(command, userInfo);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
209
231
|
disableBufferAnimation = (): boolean => false;
|
|
210
232
|
|
|
211
233
|
selectTrack = (
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { isApplePlatform } from "../../reactUtils";
|
|
2
2
|
import { NativeModules } from "react-native";
|
|
3
3
|
|
|
4
|
-
const NativePlayerModule = isApplePlatform()
|
|
5
|
-
? NativeModules.PlayerModule
|
|
6
|
-
: NativeModules.QuickBrickDefaultPlayerModule;
|
|
7
|
-
|
|
8
4
|
const PlayerNativeCommandTypes = {
|
|
9
5
|
pause: "pause",
|
|
10
6
|
clearPlayerData: "clearPlayerData",
|
|
11
7
|
removeViewByNativeId: "removeViewByNativeId",
|
|
8
|
+
setPlayerControls: "setPlayerControls",
|
|
12
9
|
};
|
|
13
10
|
|
|
14
11
|
const PlayerNativeSendCommand = (
|
|
@@ -16,8 +13,8 @@ const PlayerNativeSendCommand = (
|
|
|
16
13
|
playerId: string,
|
|
17
14
|
userInfo?: Record<string, any>
|
|
18
15
|
) => {
|
|
19
|
-
if (playerId && command) {
|
|
20
|
-
|
|
16
|
+
if (isApplePlatform() && playerId && command) {
|
|
17
|
+
NativeModules.PlayerModule?.command?.(command, playerId, userInfo);
|
|
21
18
|
}
|
|
22
19
|
};
|
|
23
20
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-utils",
|
|
3
|
-
"version": "16.0.0-rc.
|
|
3
|
+
"version": "16.0.0-rc.101",
|
|
4
4
|
"description": "Applicaster Zapp React Native utilities package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@applicaster/applicaster-types": "16.0.0-rc.
|
|
30
|
+
"@applicaster/applicaster-types": "16.0.0-rc.101",
|
|
31
31
|
"buffer": "^5.2.1",
|
|
32
32
|
"camelize": "^1.0.0",
|
|
33
33
|
"dayjs": "^1.11.10",
|