@playkit-js/rapt 0.4.10-canary.0-878cdb7

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.
@@ -0,0 +1,14 @@
1
+ export function createElement(
2
+ type: string,
3
+ id?: string,
4
+ initialClasses?: string
5
+ ): HTMLElement {
6
+ const newElement = document.createElement(type);
7
+ if (id) {
8
+ newElement.setAttribute("id", id);
9
+ }
10
+ if (initialClasses) {
11
+ newElement.setAttribute("class", initialClasses);
12
+ }
13
+ return newElement;
14
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Simple (Event)Dispatcher class
3
+ * Inspiered by https://medium.com/@LeoAref/simple-event-dispatcher-implementation-using-javascript-36d0eadf5a11
4
+ */
5
+
6
+ export interface KivEvent {
7
+ type: string;
8
+ payload?: any;
9
+ }
10
+ export class Dispatcher {
11
+ events: any;
12
+
13
+ constructor() {
14
+ this.events = {};
15
+ }
16
+
17
+ addListener(type: string, callback: (data?: any) => any) {
18
+ // Create the event if not exists
19
+ if (this.events[type] === undefined) {
20
+ this.events[type] = {
21
+ listeners: []
22
+ };
23
+ }
24
+ this.events[type].listeners.push(callback);
25
+ }
26
+
27
+ removeListener(type: string, callback: (data?: any) => any) {
28
+ // Check if this event not exists
29
+ if (this.events[type] === undefined) {
30
+ return false;
31
+ }
32
+ this.events[type].listeners = this.events[type].listeners.filter(
33
+ (listener: string) => {
34
+ return listener.toString() !== callback.toString();
35
+ }
36
+ );
37
+ }
38
+
39
+ dispatch(event: KivEvent) {
40
+ // If event doesn't have a listener - don't do anything
41
+ if (this.events[event.type] === undefined) {
42
+ return false;
43
+ }
44
+ this.events[event.type].listeners.forEach((listener: any) => {
45
+ if (event.payload) {
46
+ listener({ type: event.type, payload: event.payload });
47
+ } else {
48
+ listener({ type: event.type });
49
+ }
50
+ });
51
+ }
52
+ }
@@ -0,0 +1,6 @@
1
+ export const KipEvent = {
2
+ API_ERROR: "apiError",
3
+ MISSING_FIRST_NODE: "missingFirstNode",
4
+ FIRST_PLAY_ERROR: "firstPlayError",
5
+ RAPT_DATA_LOAD_ERROR: "raptDataLoadError"
6
+ };
@@ -0,0 +1,209 @@
1
+ import { log } from "../helpers/logger";
2
+
3
+ const get = (
4
+ obj: Record<string, any>,
5
+ path: string,
6
+ defaultValue: any
7
+ ): any => {
8
+ function stringToPath(path: string) {
9
+ const output = [];
10
+ path.split(".").forEach((item) => {
11
+ item.split(/\[([^}]+)\]/g).forEach((key) => {
12
+ if (key.length > 0) {
13
+ output.push(key);
14
+ }
15
+ });
16
+ });
17
+ return output;
18
+ }
19
+ const pathArray = stringToPath(path);
20
+ let current = obj;
21
+ for (let i = 0; i < pathArray.length; i++) {
22
+ if (!current[pathArray[i]]) return defaultValue;
23
+ current = current[pathArray[i]];
24
+ }
25
+ return current;
26
+ };
27
+
28
+ const addSettings = (newData) => {
29
+ return {
30
+ settings: {
31
+ startNodeId: get(newData, "pathData.startNodeId", ""),
32
+ stageWidth: 720,
33
+ stageHeight: 405,
34
+ },
35
+ };
36
+ };
37
+
38
+ const addVersion = () => {
39
+ return {
40
+ version: "1.0.0-rc.4",
41
+ };
42
+ };
43
+
44
+ const makeNodesAndHotspots = (newData) => {
45
+ const nodes = [];
46
+ const hotspots = [];
47
+ const cues = [];
48
+ get(newData, "nodes", []).forEach((node) => {
49
+ let onEnded = [
50
+ {
51
+ type: "project:stop",
52
+ payload: {},
53
+ },
54
+ ];
55
+
56
+ const prefetchNodeIds = [];
57
+ const duration = get(node, "pathData.msDuration", 0);
58
+ get(node, "interactions", []).forEach((interaction) => {
59
+ const behavior = get(interaction, "data.behavior", {});
60
+ if (interaction.type === "@@core/postPlay") {
61
+ if (behavior.type === "GoToNode") {
62
+ prefetchNodeIds.push(behavior.nodeId);
63
+ onEnded = [
64
+ {
65
+ type: "project:jump",
66
+ payload: {
67
+ destination: behavior.nodeId,
68
+ startFrom: behavior.startTime ? behavior.startTime / 1000 : 0,
69
+ },
70
+ },
71
+ ];
72
+ }
73
+ if (behavior.type === "Loop") {
74
+ onEnded = [
75
+ {
76
+ type: "project:jump",
77
+ payload: {
78
+ destination: node.id,
79
+ },
80
+ },
81
+ ];
82
+ }
83
+ } else if (interaction.type === "@@core/cue") {
84
+ cues.push({
85
+ at: interaction.startTime / 1000 / duration,
86
+ customData: get(interaction, "data.customData", ""),
87
+ id: interaction.id,
88
+ nodeId: node.id,
89
+ });
90
+ } else if (interaction.type === "@@core/hotspot") {
91
+ const data = get(interaction, "data", {});
92
+ const label = get(data, "text.label", "");
93
+ const hotspot: any = {
94
+ id: interaction.id,
95
+ name: label,
96
+ nodeId: node.id,
97
+ label,
98
+ showAt: interaction.startTime ? interaction.startTime / duration : 0,
99
+ hideAt: interaction.endTime ? interaction.endTime / duration : 0,
100
+ style: data.styles || {},
101
+ position: data.position ? convertPosition(data.position) : {},
102
+ customData: get(interaction, "pathData.customData", null),
103
+ onClick: [],
104
+ };
105
+ if (behavior.type === "Pause") {
106
+ hotspot.onClick = [
107
+ {
108
+ type: "player:pause",
109
+ payload: {},
110
+ },
111
+ ];
112
+ } else if (behavior.type === "GoToNode") {
113
+ prefetchNodeIds.push(behavior.nodeId);
114
+ hotspot.onClick = [
115
+ {
116
+ type: "project:jump",
117
+ payload: {
118
+ destination: behavior.nodeId,
119
+ startFrom: behavior.startTime ? behavior.startTime / 1000 : 0,
120
+ },
121
+ },
122
+ ];
123
+ } else if (behavior.type === "GoToUrl") {
124
+ hotspot.onClick = [
125
+ {
126
+ type: "player:pause",
127
+ payload: {},
128
+ },
129
+ {
130
+ type: "browser:open",
131
+ payload: {
132
+ href: behavior.url,
133
+ },
134
+ },
135
+ ];
136
+ } else if (behavior.type === "GoToTime") {
137
+ hotspot.clickSeek = behavior.time / 1000;
138
+ }
139
+ hotspots.push(hotspot);
140
+ }
141
+ });
142
+ nodes.push({
143
+ id: node.id,
144
+ xref: null,
145
+ name: node.name,
146
+ customData: get(node, "pathData.customData", null),
147
+ entryId: node.entryId,
148
+ onEnded,
149
+ prefetchNodeIds,
150
+ startFrom: node.startTime / 1000,
151
+ });
152
+ });
153
+ return [nodes, hotspots, cues];
154
+ };
155
+
156
+ const convertPosition = (position) => {
157
+ const newPosition = { ...position };
158
+ newPosition.width = 720 * position.width;
159
+ newPosition.height = 405 * position.height;
160
+ newPosition.top = 405 * position.top;
161
+ newPosition.left = 720 * position.left;
162
+ return newPosition;
163
+ };
164
+
165
+ const addFonts = (newData) => {
166
+ return {
167
+ fonts: get(newData, "pathData.fonts", []),
168
+ };
169
+ };
170
+
171
+ const addSkins = (newData) => {
172
+ const result = {};
173
+ get(newData, "pathData.skins", []).forEach((skin) => {
174
+ result[skin.id] = skin;
175
+ });
176
+ return {
177
+ __skins: result,
178
+ };
179
+ };
180
+
181
+ const addAcconunt = (newData) => {
182
+ return {
183
+ account: {
184
+ id: get(newData, "account.id", ""),
185
+ },
186
+ };
187
+ };
188
+
189
+ const convertApiResponce = (newData) => {
190
+ try {
191
+ log("log", "Converting Vegiterians ", "Original Data:", newData);
192
+ const [nodes, hotspots, cues] = makeNodesAndHotspots(newData);
193
+ const result = {
194
+ ...addVersion(),
195
+ ...addSettings(newData),
196
+ ...addFonts(newData),
197
+ ...addSkins(newData),
198
+ ...addAcconunt(newData),
199
+ nodes,
200
+ hotspots,
201
+ cues,
202
+ };
203
+ return result;
204
+ } catch (e) {
205
+ console.error("Failed to convert data", e, newData);
206
+ }
207
+ };
208
+
209
+ export default convertApiResponce;
@@ -0,0 +1,23 @@
1
+ export function getInternetExplorerVersion()
2
+ {
3
+ var rv = -1;
4
+ if (navigator.appName == 'Microsoft Internet Explorer')
5
+ {
6
+ var ua = navigator.userAgent;
7
+ var re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})");
8
+ if (re.exec(ua) != null)
9
+ rv = parseFloat( RegExp.$1 );
10
+ }
11
+ else if (navigator.appName == 'Netscape')
12
+ {
13
+ var ua = navigator.userAgent;
14
+ var re = new RegExp("Trident/.*rv:([0-9]{1,}[\\.0-9]{0,})");
15
+ if (re.exec(ua) != null)
16
+ rv = parseFloat( RegExp.$1 );
17
+ }
18
+ return rv;
19
+ }
20
+
21
+ export function isWindows7(){
22
+ return navigator.userAgent.indexOf("Windows NT 6.1") != -1;
23
+ }
@@ -0,0 +1,9 @@
1
+ let isEnabled = false;
2
+ export function enable() {
3
+ isEnabled = true;
4
+ }
5
+ export function log(level: 'log' | 'warn' | 'error', context: string, message: string, ...optionalParams: any[]) {
6
+ if (isEnabled) {
7
+ console[level](`KIV [${level}] ${context ? `[${context}]` : ''} : ${message}`, ...optionalParams);
8
+ }
9
+ }
@@ -0,0 +1,152 @@
1
+ export class PlaybackPreset {
2
+ preset: (props: any) => any;
3
+ presetWithPlayButton: (props: any) => any;
4
+ // TODO - when we have more time - switch to TSX
5
+ constructor(
6
+ h: any,
7
+ c: any,
8
+ fullscreenCallback: () => void,
9
+ private raptData: any,
10
+ private deviceModel: string | undefined
11
+ ) {
12
+ let customSeekbarContainer: any;
13
+ let customLeftContainer: any;
14
+ let customRightContainer: any;
15
+
16
+
17
+ let showFullscreenClass = "show-fullscreen";
18
+ if (this.deviceModel === "iPhone" || raptData.showFullscreen === false) {
19
+ showFullscreenClass = "hide-fullscreen";
20
+ }
21
+
22
+ // switch showScrubber
23
+ if (raptData.showScrubber) {
24
+ customSeekbarContainer = function(props: any) {
25
+ return h(c.SeekBarPlaybackContainer, {
26
+ showFramePreview: false,
27
+ showTimeBubble: false,
28
+ player: props.player,
29
+ playerContainer: props.playerContainer
30
+ });
31
+ };
32
+ } else {
33
+ customSeekbarContainer = function(props: any) {
34
+ return null;
35
+ };
36
+ }
37
+
38
+
39
+ customLeftContainer = function(props: any) {
40
+ return h(
41
+ "div",
42
+ { className: "playkit-left-controls"},
43
+ h(c.PlayPauseControl, { player: props.player }),
44
+ h(c.RewindControl, { player: props.player, step: 10 })
45
+ );
46
+ };
47
+ if (this.raptData.showTimers) {
48
+ customRightContainer = function(props: any) {
49
+ return h(
50
+ "div",
51
+ { className: "playkit-right-controls" },
52
+ h(c.TimeDisplayPlaybackContainer, { format: "current / total" }),
53
+ h(c.VolumeControl, { player: props.player }),
54
+ h(c.LanguageControl, { player: props.player }),
55
+ h(customFullScreenButton)
56
+ );
57
+ };
58
+ }else{
59
+ customRightContainer = function(props: any) {
60
+ return h(
61
+ "div",
62
+ { className: "playkit-right-controls" },
63
+ h(c.VolumeControl, { player: props.player }),
64
+ h(c.LanguageControl, { player: props.player }),
65
+ h(customFullScreenButton)
66
+ );
67
+ };
68
+ }
69
+
70
+ const customControllers = function(props: any) {
71
+ return h(
72
+ c.BottomBar,
73
+ null,
74
+ customSeekbarContainer(props),
75
+ customLeftContainer(props),
76
+ customRightContainer(props)
77
+ );
78
+ };
79
+
80
+ // define the app fullscreen button
81
+ let customFullScreenButton;
82
+
83
+ if (this.deviceModel === "iPhone" || this.raptData.showFullscreen === false) {
84
+ // do not render the fullscreen button - return null as the button
85
+ customFullScreenButton = function() {
86
+ return null;
87
+ };
88
+ } else {
89
+ customFullScreenButton = function() {
90
+ return h(
91
+ "div",
92
+ {
93
+ className:
94
+ "playkit-control-button-container playkit-control-fullscreen"
95
+ },
96
+ h(
97
+ "button",
98
+ {
99
+ tabIndex: "0",
100
+ "aria-label": "controls.fullscreen",
101
+ className: "playkit-control-button",
102
+ onClick: () => {
103
+ fullscreenCallback();
104
+ }
105
+ },
106
+ h("icon", {
107
+ className: "playkit-icon playkit-icon-maximize",
108
+ style: "transform: rotate(90deg)"
109
+ }),
110
+ h("icon", {
111
+ className: "playkit-icon playkit-icon-minimize",
112
+ style: "transform: rotate(90deg)"
113
+ })
114
+ )
115
+ );
116
+ };
117
+ }
118
+ this.presetWithPlayButton = function(props: any) {
119
+ //if U change this change the other preset
120
+ return h(
121
+ "div", null ,
122
+ h(c.KeyboardControl, { player: props.player, config: props.config }),
123
+ h(c.Loading, { player: props.player }),
124
+ h(
125
+ "div",
126
+ { className: "playkit-player-gui " + showFullscreenClass, id: "player-gui" },
127
+ h(c.OverlayPortal, null),
128
+ h(c.UnmuteIndication, { player: props.player }),
129
+ h(c.OverlayAction, { player: props.player }),
130
+ customControllers(props)
131
+ ),
132
+ h(c.PrePlaybackPlayOverlay, { player: props.player })
133
+ );
134
+ };
135
+ this.preset = function(props: any) {
136
+ //if U change this change the other preset
137
+ return h(
138
+ "div", null,
139
+ h(c.KeyboardControl, { player: props.player, config: props.config }),
140
+ h(c.Loading, { player: props.player }),
141
+ h(
142
+ "div",
143
+ { className: "playkit-player-gui " + showFullscreenClass, id: "player-gui" },
144
+ h(c.OverlayPortal, null),
145
+ h(c.UnmuteIndication, { player: props.player }),
146
+ h(c.OverlayAction, { player: props.player }),
147
+ customControllers(props)
148
+ )
149
+ );
150
+ };
151
+ }
152
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "downlevelIteration": true,
5
+ "target": "ES5",
6
+ "lib": ["es2015", "es2017", "dom"],
7
+ "sourceMap": true,
8
+ "outDir": "./dist/",
9
+ "noImplicitAny": false
10
+ },
11
+ "exclude": ["node_modules"],
12
+ "include": ["src/*"]
13
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var LiveReloadPlugin = require('webpack-livereload-plugin');
3
+
4
+ const webpack = require("webpack");
5
+ const PROD = process.env.NODE_ENV === "production";
6
+ const packageData = require("./package.json");
7
+
8
+ let plugins = [
9
+ new webpack.DefinePlugin({
10
+ __VERSION__: JSON.stringify(packageData.version),
11
+ __NAME__: JSON.stringify(packageData.name)
12
+ })
13
+ ];
14
+
15
+ if (!PROD) {
16
+ plugins.push(new LiveReloadPlugin());
17
+ }
18
+
19
+ module.exports = {
20
+ mode: PROD ? "production" : "development",
21
+ devServer: {
22
+ port: 9000
23
+ },
24
+ entry: {
25
+ PathKalturaPlayer: ["./src/Kip.ts"]
26
+ },
27
+ output: {
28
+ path: __dirname + "/dist",
29
+ filename: `playkit-kaltura-interactive-player.js`,
30
+ libraryTarget: 'umd',
31
+ // `library` determines the name of the global variable
32
+ library: '[name]',
33
+ umdNamedDefine: true
34
+ },
35
+ devtool: "source-map",
36
+ plugins: plugins,
37
+ module: {
38
+ rules: [
39
+ {
40
+ test: /\.tsx?$/,
41
+ use: [
42
+ {
43
+ loader: "ts-loader"
44
+ }
45
+ ],
46
+ exclude: [/node_modules/]
47
+ },
48
+ {
49
+ test: /\.scss$/,
50
+ use: [
51
+ "style-loader", // creates style nodes from JS strings
52
+ "css-loader", // translates CSS into CommonJS
53
+ "sass-loader" // compiles Sass to CSS, using Node Sass by default
54
+ ]
55
+ }
56
+ ]
57
+ },
58
+ resolve: {
59
+ extensions: [".tsx", ".ts", ".js"]
60
+ }
61
+ };