@tivio/sdk-react 2.3.4 → 2.4.2-alpha

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -1,6 +1,25 @@
1
1
  # @tivio/sdk-react
2
2
 
3
3
  ## Changelog
4
+ * UNRELEASED
5
+ * patch: fix peerDependency declaration for react, react-dom
6
+ * major: TivioProvider requires deviceCapabilities
7
+ * major: TivioProvider requires currency
8
+ * minor: add voucher support (see usePurchaseSubscription and useTransactionPayment hooks)
9
+ * minor: device limit support
10
+ * minor: drm (Widevine, PlayReady) support
11
+ * minor: watermarking support
12
+ * minor: add useSearch hook
13
+ * patch: price on video is 0 when purchased
14
+ * v2.4.2
15
+ * patch: added back changelog
16
+ * v2.4.1
17
+ * patch: improved doc about player wrapper
18
+ * v2.4.0
19
+ * patch: improved Player wrapper types
20
+ * minor: added Tivio DOM events `tivio_key_input_handling_change`, `tivio_context_switch` and `tivio_request_goto`
21
+ * patch: added support for remote code on browsers that do not implement [indexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)
22
+ * patch: added support for browsers that do not implement [indexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)
4
23
  * v2.3.4
5
24
  * patch: fix of usePurchaseSubscription not reactive
6
25
  * v2.3.3
@@ -20,7 +39,7 @@
20
39
  * v2.1.5
21
40
  * patch fix of `useVideosInSection` hook (fetching video's monetizations)
22
41
  * v2.1.4
23
- * patch: fix re-rendering of `useAd` during non-skippable ads (requires core-react@2.1.9)
42
+ * patch: fix re-rendering of `useAd` during non-skippable ads (requires core-react-dom@2.1.9)
24
43
  * v2.1.3
25
44
  * patch: fix changelog
26
45
  * v2.1.2
@@ -52,16 +71,14 @@
52
71
  * v1.3.4
53
72
  * ...
54
73
 
55
- ## Installation
56
74
 
57
- Check/install peer dependencies
58
- ``` sh
59
- npm install --save mobx@6.0.4 styled-components@5.2.1 firebase@8.2.3 react@17.0.2 react-dom@17.0.2
60
- ```
75
+ ## Installation
61
76
 
62
- Install SDK itself
63
- ``` sh
64
- npm install --save @tivio/sdk-react
77
+ Install @tivio/sdk-react along with its peer dependencies
78
+ ```sh
79
+ npm i react@17 react-dom@17 @tivio/sdk-react
80
+ # or
81
+ yarn add react@17 react-dom@17 @tivio/sdk-react
65
82
  ```
66
83
 
67
84
  ## Initialization
@@ -71,13 +88,13 @@ Put Tivio Provider at the top level of your application:
71
88
  ``` javascript
72
89
  import { TivioProvider } from '@tivio/sdk-react'
73
90
 
74
- const tivioConf = {
91
+ const config = {
75
92
  secret: 'XXXXXXXXXX',
76
93
  }
77
94
 
78
95
  function App({children}) {
79
96
  return (
80
- <TivioProvider conf={tivioConf}>
97
+ <TivioProvider conf={config}>
81
98
  {children}
82
99
  </TivioProvider>
83
100
  )
@@ -89,7 +106,7 @@ function App({children}) {
89
106
  ``` javascript
90
107
  import { TivioProvider, setUser } from '@tivio/sdk-react'
91
108
 
92
- const tivioConf = {
109
+ const config = {
93
110
  secret: 'XXXXXXXXXX',
94
111
  }
95
112
 
@@ -97,7 +114,7 @@ setUser('user-id', { some: 'payload' })
97
114
 
98
115
  function App({children}) {
99
116
  return (
100
- <TivioProvider conf={tivioConf}>
117
+ <TivioProvider conf={config}>
101
118
  {children}
102
119
  </TivioProvider>
103
120
  )
@@ -106,7 +123,7 @@ function App({children}) {
106
123
  ## Tivio widget
107
124
 
108
125
  Tivio widget is the main Tivio component which shows the widget and provides access to its channels, sections and videos.
109
- Usage is very simple (be sure to set `id` to the widget ID you have configured in Tivio Studio):
126
+ Usage is very simple (be sure to set `id` to the widget ID you have configured in [Tivio Studio](https://studio.tiv.io/)):
110
127
 
111
128
  ``` javascript
112
129
  import { TivioWidget } from '@tivio/sdk-react'
@@ -135,48 +152,146 @@ function Screen() {
135
152
  )
136
153
  }
137
154
  ```
155
+
138
156
  ## Player wrapper
139
157
 
140
- Player wrapper is the way how you can enhance your video player with Tivio features (e.g. inserting of ads).
158
+ Player wrapper is the way how you can enhance your video player with Tivio features, such Tivio Ads. In order to start using Tivio player wrapper, wrap your player methods with PlayerWrapper, start using PlayerWrapper's methods instead of them to control your playback and start sending player events to Tivio PlayerWrapper.
159
+
160
+ ### Wrap your player methods with Tivio player wrapper
141
161
 
142
162
  ``` javascript
143
- import { useTivioData } from '@tivio/sdk-react'
163
+ import { useTivioReadyData } from '@tivio/sdk-react'
144
164
 
145
165
  function CustomPlayer() {
146
- const tivio = useTivioData()
147
- const [isPlaying, setIsPlaying] = useState()
166
+ const tivioData = useTivioReadyData()
148
167
 
149
168
  useEffect(() => {
150
- (async () => {
151
- if (tivio.getPlayerWrapper) {
152
- const playerWrapper = await tivio.getPlayerWrapper(
153
- { playerWrapperId: 'default' }
154
- )
155
-
156
- playerWrapper.register({
157
- play: () => {
158
- setIsPlaying(true)
159
- // start playback using your player here
160
- },
161
- pause: () => {
162
- setIsPlaying(false)
163
- // pause playback using your player here
164
- },
165
- seekTo: (ms: number) => {
166
- // seek using your player here
167
- },
168
- setSource: (videoSource: InputSource) => {
169
- // play videoSource using your player here
170
- },
171
- })
172
- }
173
- })()
174
- }, [])
175
-
176
- return (<div>Example is {isPlaying ? null : 'not '}playing.</div>)
169
+ if (tivioData) {
170
+ // If your app uses multiple player instances, use different Tivio player wrapper for each
171
+ // distinguished by playerWrapperId
172
+ const playerWrapper = tivio.getPlayerWrapper({ playerWrapperId: 'PLAYER_1' })
173
+
174
+ // Pass your player methods to Tivio player wrapper
175
+ playerWrapper.register({
176
+ play: () => {
177
+ // Un-pause your player
178
+ },
179
+ pause: () => {
180
+ // Pause your player
181
+ },
182
+ seekTo: (ms: number) => {
183
+ // Seek to position in milliseconds using your player
184
+ },
185
+ setSource: (videoSource: InputSource) => {
186
+ // Send this video source to your player to load it
187
+ },
188
+ })
189
+ }
190
+ }, [tivioData])
191
+ }
192
+ ```
193
+
194
+ ### Start using Tivio player wrapper methods to control playback
195
+
196
+ ``` javascript
197
+ // Channel source metadata, such as channel name, epg start and epg end are necessary
198
+ // for TV ad segment detection and application of ad strategies
199
+ const source = new ChannelSource(
200
+ 'https://channel_prima_hd.m3u8',
201
+ {
202
+ // here put any additional metadata, for your use.
203
+ // This object will not be touched by Tivio
204
+ },
205
+ // channel name
206
+ // can also be prima hd, prima_hd, prima, Prima, PRIMA, etc.
207
+ // we will normalize it to snake case and add '_hd' if necessary
208
+ 'Prima HD',
209
+ // program name
210
+ 'Dr. House',
211
+ // description (optional)
212
+ 'Episode about Dr. House being awesome',
213
+ // EPG start
214
+ new Date('2021-12-10T12:00:00'),
215
+ // EPG end
216
+ new Date('2021-12-10T13:40:00'),
217
+ )
218
+
219
+ // Send source to player
220
+ playerWrapper.onSourceChanged(source)
221
+
222
+ // Un-pause player
223
+ playerWrapper.play()
224
+
225
+ // Pause player
226
+ playerWrapper.pause()
177
227
  }
178
228
  ```
179
229
 
230
+ ### Start reporting player events to Tivio
231
+
232
+ ``` javascript
233
+ // Report that source is playing
234
+ playerWrapper.onStateChanged('playing')
235
+
236
+ // Report that source is paused
237
+ playerWrapper.onStateChanged('paused')
238
+
239
+ // Report that source stopped playing
240
+ playerWrapper.onPlaybackEnded()
241
+ playerWrapper.onStateChanged('idle')
242
+
243
+ // Report video progress
244
+ playerWrapper.onTimeChanged(ms)
245
+ }
246
+ ```
247
+
248
+ ### Start reporting playback-related errors to Tivio
249
+
250
+ ``` javascript
251
+ // Report that video failed to load (e.g. due to a wrong URI)
252
+ playerWrapper.onLoadError(new Error('video failed to load'))
253
+
254
+ // Report that video failed during playback (e.g. due to bad connection, corrupted chunks of stream video etc.)
255
+ // This type of error may be auto-recoverable
256
+ playerWrapper.onError(new Error('playback error'))
257
+ }
258
+ ```
259
+
260
+ ## Tivio DOM events
261
+
262
+ `TivioWidget` triggers these events on `window.document`.
263
+
264
+ 1. To instruct the parent app to navigate to and focus a specific TivioWidget (e.g. after going back from a Tivio screen)
265
+
266
+ ```typescript
267
+ document.addEventListener("tivio_request_goto", e => {
268
+ e.detail.widgetId; // string - Tivio widget ID to go navigate to in UI
269
+ });
270
+ ```
271
+ 2. To notify the parent app about context switch, i.e. where is the user located or what is he focusing
272
+
273
+ ```typescript
274
+ document.addEventListener("tivio_context_switch", e => {
275
+ e.detail.context; // 'tivio' | 'parent' - where is the user located? - in Tivio or in parent app
276
+
277
+ // For context Tivio there are additional fields
278
+ e.detail.context; // 'tivio'
279
+ e.detail.contextLocation; // 'route' | 'overlay' | 'widget' - where in Tivio is the user located?
280
+ // - on a Tivio route, in parent app but looking at a full screen Tivio overlay,
281
+ // or in parent app and focus is on a Tivio widget
282
+
283
+ // For context Tivio contextLocation 'widget' there is an additional field of widget ID
284
+ e.detail.widgetId; // string - which Tivio widget is focused right now
285
+ });
286
+ ```
287
+ 3. To notify the parent app about whether it should be handling key input from RC (TV remote) or not. When inputHandler is 'tivio', the parent app should stop reacting to key input, when inputHandler is 'parent' the parent app should start reacting again.
288
+
289
+ ```typescript
290
+ document.addEventListener("tivio_key_input_handling_change", e => {
291
+ e.detail.inputHandler; // 'tivio' | 'parent' - who should be handling RC input? - Tivio or parent app
292
+ });
293
+ ```
294
+
180
295
  ## Data hooks
181
296
 
182
297
  If you don't want to use TivioWidget, you can implement your own UI using React data hooks.
@@ -3,11 +3,17 @@
3
3
  * nangu.TV, a.s PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4
4
  */
5
5
  import React, { FunctionComponentElement } from 'react';
6
+ import type { PlayerWrapper } from '../types/customPlayer.types';
6
7
  export declare type PlayerProviderProps = {
7
8
  children: React.ReactNode;
8
9
  playerWrapperId?: string;
9
10
  };
10
- export declare type Player = any;
11
- export declare const PlayerContext: React.Context<any>;
11
+ /**
12
+ * value
13
+ * - undefined - you are trying to access this context but are not inside <PlayerContext /> that is a bug
14
+ * - null - we are waiting for remote code
15
+ * - Player - player is ready
16
+ */
17
+ export declare const PlayerContext: React.Context<PlayerWrapper | null | undefined>;
12
18
  export declare const PlayerProvider: ({ children, playerWrapperId, }: PlayerProviderProps) => FunctionComponentElement<PlayerProviderProps>;
13
19
  export declare function withPlayerContext(id: string): <P>(WrappedComponent: React.ComponentType<P>) => (props: P) => JSX.Element;
@@ -9,7 +9,7 @@ export declare type TivioProviderProps = {
9
9
  /**
10
10
  * This prop must be set only once and not change value afterwards
11
11
  */
12
- conf?: Config;
12
+ conf: Config;
13
13
  children: React.ReactNode;
14
14
  };
15
15
  declare const TivioContext: React.Context<RemoteBundleState | null>;
@@ -2,7 +2,9 @@ export * from './useUser';
2
2
  export * from './useTaggedVideos';
3
3
  export * from './useScreens';
4
4
  export * from './useScreen';
5
+ export * from './useSearch';
5
6
  export * from './useItemsInRow';
7
+ export * from './useCancelSubscription';
6
8
  export * from './useTransactionPayment';
7
9
  export * from './usePurchaseSubscription';
8
10
  export * from './contentHooks';
@@ -11,4 +13,8 @@ export * from './useOrganizationSubscriptions';
11
13
  export * from './usePurchasesWithVideos';
12
14
  export * from './useFreePurchase';
13
15
  export * from './useRowsInScreen';
16
+ export * from './useVoucher';
14
17
  export * from './useTivio';
18
+ export * from './useOverlay';
19
+ export * from './useWatchWithoutAds';
20
+ export * from './useLastVideoByWidgetId';
@@ -0,0 +1,2 @@
1
+ import { UseCancelSubscription } from '@tivio/common';
2
+ export declare const useCancelSubscription: UseCancelSubscription;
@@ -0,0 +1,2 @@
1
+ import { Video } from '@tivio/common';
2
+ export declare function useLastVideoByWidgetId(widgetId: string): Video | null;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Displays overlay to purchase "watch without ads mode" if available.
3
+ * This overlay can be hidden by pressing BACK button on RC.
4
+ */
5
+ export declare const useOverlayToPurchaseWatchWithoutAds: () => {
6
+ showOverlay: () => void;
7
+ };
8
+ interface Callbacks {
9
+ onShow: () => void;
10
+ onHide: () => void;
11
+ }
12
+ export declare const useRegisterOverlayCallbacks: (callbacks: Callbacks) => void;
13
+ export {};
@@ -1,3 +1,4 @@
1
1
  import { QerkoTransaction } from '@tivio/common';
2
- declare const usePurchaseSubscription: (monetizationId: string) => QerkoTransaction;
2
+ import { Voucher } from './useTransactionPayment';
3
+ declare const usePurchaseSubscription: (monetizationId: string, voucher?: Voucher | undefined) => QerkoTransaction;
3
4
  export { usePurchaseSubscription, };
@@ -0,0 +1,8 @@
1
+ import { ALGOLIA_INDEX_NAME, UseSearch } from '@tivio/common';
2
+ /**
3
+ * Full text search that returns entities based on search query.
4
+ * @param indexName - index that search would be performed on ('videos', 'tags', etc.)
5
+ * @param options - pagination options
6
+ */
7
+ export declare const useSearch: UseSearch;
8
+ export { ALGOLIA_INDEX_NAME };
@@ -1,3 +1,10 @@
1
1
  import { QerkoTransaction } from '@tivio/common';
2
- declare const useTransactionPayment: (videoId: string, monetizationId: string) => QerkoTransaction;
2
+ declare type Voucher = {
3
+ /**
4
+ * Voucher expiration date as a Date object or timestamp in ms.
5
+ */
6
+ expirationDate: Date | number;
7
+ };
8
+ declare const useTransactionPayment: (videoId: string, monetizationId: string, voucher?: Voucher | undefined) => QerkoTransaction;
3
9
  export { useTransactionPayment, };
10
+ export type { Voucher, };
@@ -0,0 +1,12 @@
1
+ declare type Voucher = {
2
+ activate: () => void;
3
+ isUsed: boolean;
4
+ isExpired: boolean;
5
+ status: 'NEW' | 'USED';
6
+ };
7
+ declare const useVoucher: (voucherId: string) => {
8
+ activate: (() => void) | null;
9
+ voucher: Voucher | null;
10
+ error: Error | null;
11
+ };
12
+ export { useVoucher, };
@@ -0,0 +1,5 @@
1
+ export declare const useCanPurchaseWatchWithoutAds: () => boolean;
2
+ export declare const useWatchWithoutAds: () => {
3
+ canPurchaseWatchWithoutAds: boolean;
4
+ showOverlay: () => void;
5
+ };
package/dist/config.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2021, nangu.TV, a.s. All rights reserved.
3
3
  * nangu.TV, a.s PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4
4
  */
5
- import { Config as ExternalConfig, InternalConfig } from './types/bundle.types';
5
+ import type { Config as ExternalConfig, InternalConfig } from './types/bundle.types';
6
6
  export declare const defaultConf: {
7
7
  secret: null;
8
8
  resolverUrl: string;
@@ -14,4 +14,4 @@ export declare const defaultConf: {
14
14
  error: string | null;
15
15
  }>;
16
16
  };
17
- export declare const createInternalConf: (conf: ExternalConfig | null) => InternalConfig;
17
+ export declare const createInternalConf: (conf: ExternalConfig) => InternalConfig;
package/dist/index.d.ts CHANGED
@@ -21,3 +21,5 @@ export { TivioComponents } from './types/bundle.types';
21
21
  export { TivioAuth } from './types/bundle.types';
22
22
  export { TivioGetters } from './types/bundle.types';
23
23
  export { TivioSubscriptions } from './types/bundle.types';
24
+ export { PlayerCapability } from './types/bundle.types';
25
+ export { Currency } from './types/bundle.types';