@jwplayer/jwplayer-react-native 1.3.2 → 1.4.0

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/README.md CHANGED
@@ -357,6 +357,29 @@ Follow this step to set up advertising with IMA or DAI:
357
357
 
358
358
  1. In the **Podfile** `ext{}`, add `$RNJWPlayerUseGoogleIMA = true`. This setting will add `GoogleAds-IMA-iOS-SDK` to the pod.
359
359
 
360
+ #### Using a Local iOS SDK
361
+
362
+ To test with a specific version of JWPlayerKit (e.g. a pre-release build provided by JW Player support):
363
+
364
+ 1. Acquire the `JWPlayerKit.xcframework` asset.
365
+ 2. Copy it to `ios/frameworks/JWPlayerKit.xcframework` in this repo (this path is gitignored).
366
+ 3. Add `$RNJWPlayerUseLocalSDK = true` to your **Podfile**.
367
+ 4. Run `pod install`.
368
+
369
+ To switch back to the published CocoaPod, remove or comment out the `$RNJWPlayerUseLocalSDK` line and run `pod install` again.
370
+
371
+ #### Using Local Android AARs
372
+
373
+ To test with a specific version of the JW Player Android SDK (e.g. a pre-release build provided by JW Player support):
374
+
375
+ 1. Acquire the AAR files and copy them to `android/libs/` in this repo (this path is gitignored):
376
+ - `jwplayer-core.aar`, `jwplayer-common.aar`, `jwplayer-chromecast.aar`
377
+ - `jwplayer-ima.aar` (if using IMA)
378
+ 2. Set `useLocalAARs = true` in `android/build.gradle`.
379
+ 3. Rebuild the app.
380
+
381
+ To switch back to Maven, set `useLocalAARs = false` and rebuild.
382
+
360
383
  <br /><br />
361
384
 
362
385
  ### Background Audio
@@ -12,7 +12,12 @@ Pod::Spec.new do |s|
12
12
  s.platform = :ios, "15.0"
13
13
  s.source = { :git => "https://github.com/jwplayer/jwplayer-react-native.git", :tag => "v#{s.version}" }
14
14
  s.source_files = "ios/RNJWPlayer/*.{h,m,swift}"
15
- s.dependency 'JWPlayerKit', '4.25.0'
15
+ if defined?($RNJWPlayerUseLocalSDK)
16
+ Pod::UI.puts "RNJWPlayer: using local JWPlayerKit.xcframework"
17
+ s.vendored_frameworks = 'ios/frameworks/JWPlayerKit.xcframework'
18
+ else
19
+ s.dependency 'JWPlayerKit', '4.25.2'
20
+ end
16
21
  s.dependency 'React-Core'
17
22
  s.static_framework = true
18
23
  s.info_plist = {
@@ -95,7 +95,8 @@ allprojects {
95
95
  }
96
96
  }
97
97
 
98
- def jwPlayerVersion = "4.24.0"
98
+ def jwPlayerVersion = "4.24.1"
99
+ def useLocalAARs = false // Set to false to revert to Maven dependencies
99
100
  def exoplayerVersion = "2.18.7" // Deprecated. Use Media3 when targeting JW SDK > 4.16.0
100
101
  def media3ExoVersion = "1.4.1"
101
102
 
@@ -103,20 +104,28 @@ dependencies {
103
104
  implementation 'com.facebook.react:react-native:+'
104
105
  implementation 'com.google.code.gson:gson:2.9.0'
105
106
 
106
- // JWPlayer SDK Core (always required)
107
- implementation "com.jwplayer:jwplayer-core:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
108
- implementation "com.jwplayer:jwplayer-common:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
109
- implementation "com.jwplayer:jwplayer-chromecast:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
110
-
111
- // Optional: IMA Ads support
112
- if (useIMA) {
113
- implementation "com.jwplayer:jwplayer-ima:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
114
- implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.36.0'
115
- implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
116
- // Core library desugaring (required for IMA SDK 3.37.0+)
117
- // Using version 2.1.5 as recommended by IMA SDK documentation:
118
- // https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/get-started
119
- coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
107
+ if (useLocalAARs) {
108
+ // Local AARs for debugging (built from android-sdk with diagnostic logging)
109
+ implementation fileTree(dir: 'libs', include: ['jwplayer-core.aar', 'jwplayer-common.aar', 'jwplayer-chromecast.aar'])
110
+ if (useIMA) {
111
+ implementation fileTree(dir: 'libs', include: ['jwplayer-ima.aar'])
112
+ implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.36.0'
113
+ implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
114
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
115
+ }
116
+ } else {
117
+ // JWPlayer SDK Core from Maven (always required)
118
+ implementation "com.jwplayer:jwplayer-core:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
119
+ implementation "com.jwplayer:jwplayer-common:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
120
+ implementation "com.jwplayer:jwplayer-chromecast:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
121
+
122
+ // Optional: IMA Ads support
123
+ if (useIMA) {
124
+ implementation "com.jwplayer:jwplayer-ima:${safeExtGet('jwPlayerVersion', jwPlayerVersion)}"
125
+ implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.36.0'
126
+ implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
127
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
128
+ }
120
129
  }
121
130
 
122
131
  // Cast dependencies
@@ -243,6 +243,9 @@ public class RNJWPlayerView extends RelativeLayout implements
243
243
  // Add completion handler field
244
244
  PlaylistItemDecision itemUpdatePromise = null;
245
245
 
246
+ // Flag to prevent race conditions during player destruction
247
+ private volatile boolean isDestroying = false;
248
+
246
249
  private void doBindService() {
247
250
  if (mMediaServiceController != null) {
248
251
  if (!isBackgroundAudioServiceRunning()) {
@@ -380,7 +383,22 @@ public class RNJWPlayerView extends RelativeLayout implements
380
383
  // }
381
384
 
382
385
  public void destroyPlayer() {
383
- if (mPlayer != null) {
386
+ if (mPlayer != null && !isDestroying) {
387
+ isDestroying = true;
388
+
389
+ // Disable touch events immediately to prevent race conditions
390
+ if (mPlayerView != null) {
391
+ Handler mainHandler = new Handler(Looper.getMainLooper());
392
+ mainHandler.post(() -> {
393
+ if (mPlayerView != null) {
394
+ mPlayerView.setClickable(false);
395
+ mPlayerView.setFocusable(false);
396
+ mPlayerView.setEnabled(false);
397
+ mPlayerView.setOnTouchListener(null);
398
+ }
399
+ });
400
+ }
401
+
384
402
  unRegisterReceiver();
385
403
 
386
404
  // If we are casting we need to break the cast session as there is no simple
@@ -480,6 +498,8 @@ public class RNJWPlayerView extends RelativeLayout implements
480
498
  audioManager = null;
481
499
 
482
500
  doUnbindService();
501
+
502
+ isDestroying = false; // Reset flag for potential reuse
483
503
  }
484
504
  }
485
505
 
@@ -1,5 +1,7 @@
1
1
  package com.jwplayer.rnjwplayer;
2
2
 
3
+ import android.util.Log;
4
+
3
5
  import com.facebook.react.bridge.ReactApplicationContext;
4
6
  import com.facebook.react.bridge.ReadableMap;
5
7
  import com.facebook.react.common.MapBuilder;
@@ -43,7 +45,14 @@ public class RNJWPlayerViewManager extends SimpleViewManager<RNJWPlayerView> {
43
45
  if (view == null || view.mPlayerView == null) {
44
46
  return;
45
47
  }
46
- view.mPlayerView.getPlayer().setControls(controls);
48
+ // Add null check for getPlayer() to prevent crashes
49
+ try {
50
+ if (view.mPlayerView.getPlayer() != null) {
51
+ view.mPlayerView.getPlayer().setControls(controls);
52
+ }
53
+ } catch (Exception e) {
54
+ Log.w(TAG, "Error setting controls: " + e.getMessage());
55
+ }
47
56
  }
48
57
 
49
58
  /**
@@ -58,8 +67,15 @@ public class RNJWPlayerViewManager extends SimpleViewManager<RNJWPlayerView> {
58
67
  if (view == null || view.mPlayerView == null) {
59
68
  return;
60
69
  }
61
- view.mPlayerView.getPlayer().stop();
62
- view.setConfig(config);
70
+ // Add null check for getPlayer() to prevent crashes
71
+ try {
72
+ if (view.mPlayerView.getPlayer() != null) {
73
+ view.mPlayerView.getPlayer().stop();
74
+ }
75
+ view.setConfig(config);
76
+ } catch (Exception e) {
77
+ Log.w(TAG, "Error recreating player: " + e.getMessage());
78
+ }
63
79
  }
64
80
 
65
81
  public Map getExportedCustomBubblingEventTypeConstants() {
@@ -12,12 +12,12 @@ import JWPlayerKit
12
12
  extension RCTConvert {
13
13
 
14
14
  static func JWAdClient(_ value: String) -> JWAdClient {
15
- switch value {
15
+ switch value.lowercased() {
16
16
  case "vast":
17
17
  return .JWPlayer
18
- case "ima":
18
+ case "ima", "googima":
19
19
  return .GoogleIMA
20
- case "ima_dai":
20
+ case "ima_dai", "googimadai":
21
21
  return .GoogleIMADAI
22
22
  default:
23
23
  return .unknown
@@ -47,6 +47,7 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
47
47
  var isCasting: Bool = false
48
48
  var availableDevices: [AnyObject]!
49
49
  var onBeforeNextPlaylistItemCompletion: ((JWPlayerItem?) -> ())?
50
+ var pendingConfigAfterPlaylistItemCallback: [String: Any]?
50
51
 
51
52
  @objc var onBuffer: RCTDirectEventBlock?
52
53
  @objc var onUpdateBuffer: RCTDirectEventBlock?
@@ -234,6 +235,16 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
234
235
  }
235
236
 
236
237
  @objc func setConfig(_ config: [String: Any]) {
238
+ // Defer config changes while a playlist item callback is pending resolution.
239
+ // React Native re-renders can trigger setConfig during the window between
240
+ // onBeforeNextPlaylistItem firing and resolveNextPlaylistItem being called.
241
+ // Reconfiguring the player during this window crashes the SDK.
242
+ if onBeforeNextPlaylistItemCompletion != nil {
243
+ print("Warning: setConfig deferred — playlist item callback pending resolution")
244
+ pendingConfigAfterPlaylistItemCallback = config
245
+ return
246
+ }
247
+
237
248
  if (playerFailed) {
238
249
  playerFailed = false
239
250
  setNewConfig(config: config)
@@ -764,6 +775,11 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
764
775
  print("Error serializing playlist item: \(error)")
765
776
  self.onBeforeNextPlaylistItemCompletion?(item) // Call completion handler directly on error
766
777
  self.onBeforeNextPlaylistItemCompletion = nil
778
+ // Apply any deferred config change
779
+ if let pendingConfig = self.pendingConfigAfterPlaylistItemCallback {
780
+ self.pendingConfigAfterPlaylistItemCallback = nil
781
+ self.setConfig(pendingConfig)
782
+ }
767
783
  }
768
784
  } else {
769
785
  print("No onBeforeNextPlaylistItem handler set, calling completion directly")
@@ -1067,8 +1083,7 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
1067
1083
  for adItem in adsItem.compactMap({ $0 as? [String: Any] }) {
1068
1084
  if let offsetString = adItem["offset"] as? String,
1069
1085
  let tag = adItem["tag"] as? String,
1070
- let encodedString = tag.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed),
1071
- let tagURL = URL(string: encodedString),
1086
+ let tagURL = URL(string: tag) ?? URL(string: tag.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""),
1072
1087
  let offset = JWAdOffset.from(string: offsetString) {
1073
1088
  let adBreakBuilder = JWAdBreakBuilder()
1074
1089
  adBreakBuilder.offset(offset)
@@ -1140,7 +1155,7 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
1140
1155
  var advertisingConfig: JWAdvertisingConfig?
1141
1156
 
1142
1157
  var jwAdClient = JWAdClient.unknown
1143
- if let adClientString = ads["adClient"] as? String {
1158
+ if let adClientString = ads["adClient"] as? String ?? ads["client"] as? String {
1144
1159
  jwAdClient = RCTConvert.JWAdClient(adClientString)
1145
1160
  }
1146
1161
 
@@ -1255,10 +1270,16 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
1255
1270
  }
1256
1271
 
1257
1272
  func dismissPlayerViewController() {
1258
- if (playerViewController != nil) {
1259
- playerViewController.player.pause() // hack for stop not always stopping on unmount
1260
- playerViewController.player.stop()
1261
- playerViewController.enableLockScreenControls = false
1273
+ guard playerViewController != nil else { return }
1274
+
1275
+ // Ensure UI operations happen on main thread to prevent crashes
1276
+ // when deinit is called from a background thread during unmount
1277
+ let cleanup = { [self] in
1278
+ guard let pvc = self.playerViewController else { return }
1279
+
1280
+ pvc.player.pause() // hack for stop not always stopping on unmount
1281
+ pvc.player.stop()
1282
+ pvc.enableLockScreenControls = false
1262
1283
 
1263
1284
  // hack for stop not always stopping on unmount
1264
1285
  let configBuilder:JWPlayerConfigurationBuilder! = JWPlayerConfigurationBuilder()
@@ -1266,19 +1287,24 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
1266
1287
 
1267
1288
  do {
1268
1289
  let configuration: JWPlayerConfiguration = try configBuilder.build()
1269
- playerViewController.player.configurePlayer(with: configuration)
1290
+ pvc.player.configurePlayer(with: configuration)
1270
1291
  } catch {
1271
1292
  print(error)
1272
1293
  }
1273
1294
 
1274
-
1275
- playerViewController.parentView = nil
1276
- playerViewController.setVisibility(.hidden, for:[.pictureInPictureButton])
1277
- playerViewController.view.removeFromSuperview()
1278
- playerViewController.removeFromParent()
1279
- playerViewController.willMove(toParent: nil)
1280
- playerViewController.removeDelegates()
1281
- playerViewController = nil
1295
+ pvc.parentView = nil
1296
+ pvc.setVisibility(.hidden, for:[.pictureInPictureButton])
1297
+ pvc.view.removeFromSuperview()
1298
+ pvc.removeFromParent()
1299
+ pvc.willMove(toParent: nil)
1300
+ pvc.removeDelegates()
1301
+ self.playerViewController = nil
1302
+ }
1303
+
1304
+ if Thread.isMainThread {
1305
+ cleanup()
1306
+ } else {
1307
+ DispatchQueue.main.sync(execute: cleanup)
1282
1308
  }
1283
1309
  }
1284
1310
 
@@ -1330,10 +1356,21 @@ class RNJWPlayerView: UIView, JWPlayerDelegate, JWPlayerStateDelegate,
1330
1356
  }
1331
1357
 
1332
1358
  func removePlayerView() {
1333
- if (playerView != nil) {
1334
- playerView.player.stop()
1335
- playerView.removeFromSuperview()
1336
- playerView = nil
1359
+ guard playerView != nil else { return }
1360
+
1361
+ // Ensure UI operations happen on main thread to prevent crashes
1362
+ // when deinit is called from a background thread during unmount
1363
+ let cleanup = { [self] in
1364
+ guard let pv = self.playerView else { return }
1365
+ pv.player.stop()
1366
+ pv.removeFromSuperview()
1367
+ self.playerView = nil
1368
+ }
1369
+
1370
+ if Thread.isMainThread {
1371
+ cleanup()
1372
+ } else {
1373
+ DispatchQueue.main.sync(execute: cleanup)
1337
1374
  }
1338
1375
  }
1339
1376
 
@@ -234,13 +234,34 @@ class RNJWPlayerViewManager: RCTViewManager {
234
234
  }
235
235
 
236
236
  if let completion = view.onBeforeNextPlaylistItemCompletion {
237
+ guard let itemDict = playlistItem as? [String: Any] else {
238
+ print("Error: resolveNextPlaylistItem received invalid playlist item data")
239
+ completion(nil)
240
+ view.onBeforeNextPlaylistItemCompletion = nil
241
+ return
242
+ }
237
243
  do {
238
- let item = try view.getPlayerItem(item: playlistItem as! [String: Any])
239
- completion(item)
244
+ let item = try view.getPlayerItem(item: itemDict)
245
+ // Ensure completion runs on the main thread — the SDK performs
246
+ // UI updates (view hierarchy changes) when loading the next item.
247
+ DispatchQueue.main.async {
248
+ completion(item)
249
+ view.onBeforeNextPlaylistItemCompletion = nil
250
+
251
+ // Apply any config change that was deferred while the callback was pending
252
+ if let pendingConfig = view.pendingConfigAfterPlaylistItemCallback {
253
+ view.pendingConfigAfterPlaylistItemCallback = nil
254
+ view.setConfig(pendingConfig)
255
+ }
256
+ }
240
257
  } catch {
241
258
  print("Error creating JWPlayerItem: \(error)")
259
+ view.onBeforeNextPlaylistItemCompletion = nil
260
+ if let pendingConfig = view.pendingConfigAfterPlaylistItemCallback {
261
+ view.pendingConfigAfterPlaylistItemCallback = nil
262
+ view.setConfig(pendingConfig)
263
+ }
242
264
  }
243
- view.onBeforeNextPlaylistItemCompletion = nil
244
265
  } else {
245
266
  print("Warning: resolveNextPlaylistItem called but no completion handler was set OR completion handler was already called")
246
267
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jwplayer/jwplayer-react-native",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "description": "React-native Android/iOS plugin for JWPlayer SDK (https://www.jwplayer.com/)",
5
5
  "main": "index.js",
6
6
  "types": "./index.d.ts",
@@ -1,2 +0,0 @@
1
- # SDK Team
2
- * @jwplayer/team_sdks
@@ -1,48 +0,0 @@
1
- ---
2
- name: Bug report
3
- about: Create a report to help us improve
4
- title: "[BUG]"
5
- labels: "needs-grooming"
6
- assignees: '@jwplayer/team_sdks'
7
-
8
- ---
9
-
10
- **Describe the bug**
11
- A clear and concise description of what the bug is.
12
-
13
- **To Reproduce**
14
- Use the `Example` application as reference material and a starting place to reproduce any bugs.
15
-
16
- ***Steps to reproduce the behavior:***
17
- 1. Provide thorough
18
- 2. And complete
19
- 3. Steps for reproduction
20
- 4. That are reliably reproducible
21
-
22
- **Expected behavior**
23
- A clear and concise description of what you expected to happen.
24
-
25
- **Screenshots / Visual evidence**
26
- If applicable, add screenshots or recordings to help explain your problem. (Required if reproduction is not 100% reliable)
27
-
28
- **Desktop (please complete the following information):**
29
- If you are having a build issue, we would like to know about your machine.
30
- - Result of `npx react-native info`
31
-
32
- **Device(s) affected**
33
- - Device: [e.g. iPhone6]
34
- - OS: [e.g. iOS8.1]
35
- - Version [e.g. 22]
36
-
37
- **Additional context**
38
- Add any other context about the problem here.
39
-
40
- **JWP Ticketing**
41
- To expedite resolution and maintain confidentiality, submit a JWP [request](https://support.jwplayer.com/hc/en-us/requests/new) in addition to this new `Issue`. A JWP request offers the following benefits:
42
- * Associates the `Issue` with your company
43
- * Permits securely share sensitive information related to the bug, request, or question
44
- * Enhances JWP's ability to track progress and provide timely updates
45
- * Enables you to track and manage multiple issues through a single platform
46
-
47
- | ℹ️ While `Issues` are valuable for open-source collaboration, a JWP request ensures that you will receive clear timelines and efficient support. |
48
- |:---|
@@ -1,30 +0,0 @@
1
- ---
2
- name: Feature request
3
- about: Suggest an idea for this project
4
- title: "[FEAT]"
5
- labels: 'needs-grooming'
6
- assignees: '@jwplayer/team_sdks'
7
-
8
- ---
9
-
10
- **Is your feature request related to a problem? Please describe.**
11
- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
-
13
- **Describe the solution you'd like**
14
- A clear and concise description of what you want to happen.
15
-
16
- **Describe alternatives you've considered**
17
- A clear and concise description of any alternative solutions or features you've considered.
18
-
19
- **Additional context**
20
- Add any other context or screenshots about the feature request here.
21
-
22
- **JWP Ticketing**
23
- To expedite resolution and maintain confidentiality, submit a JWP [request](https://support.jwplayer.com/hc/en-us/requests/new) in addition to this new `Issue`. A JWP request offers the following benefits:
24
- * Associates the `Issue` with your company
25
- * Permits securely share sensitive information related to the bug, request, or question
26
- * Enhances JWP's ability to track progress and provide timely updates
27
- * Enables you to track and manage multiple issues through a single platform
28
-
29
- | ℹ️ While `Issues` are valuable for open-source collaboration, a JWP request ensures that you will receive clear timelines and efficient support. |
30
- |:---|
@@ -1,26 +0,0 @@
1
- ---
2
- name: Implementation
3
- about: Request an implementation of a native feature or upgrade of SDK
4
- title: "[IMPLEMENT]"
5
- labels: 'needs-grooming'
6
- assignees: '@jwplayer/team_sdks'
7
-
8
- ---
9
-
10
- **What needs to be implemented**
11
-
12
- **How should it be implemented**
13
-
14
- **Acceptance Criteria**
15
-
16
- **Additional context**
17
-
18
- **JWP Ticketing**
19
- To expedite resolution and maintain confidentiality, submit a JWP [request](https://support.jwplayer.com/hc/en-us/requests/new) in addition to this new `Issue`. A JWP request offers the following benefits:
20
- * Associates the `Issue` with your company
21
- * Permits securely share sensitive information related to the bug, request, or question
22
- * Enhances JWP's ability to track progress and provide timely updates
23
- * Enables you to track and manage multiple issues through a single platform
24
-
25
- | ℹ️ While `Issues` are valuable for open-source collaboration, a JWP request ensures that you will receive clear timelines and efficient support. |
26
- |:---|
@@ -1,21 +0,0 @@
1
- ---
2
- name: Question
3
- about: Ask a question about the project or product
4
- title: "[ASK]"
5
- labels: 'needs-grooming'
6
- assignees: '@jwplayer/team_sdks'
7
-
8
- ---
9
-
10
- **What isn't clear?**
11
- What information are we not providing that you think we should?
12
-
13
- **JWP Ticketing**
14
- To expedite resolution and maintain confidentiality, submit a JWP [request](https://support.jwplayer.com/hc/en-us/requests/new) in addition to this new `Issue`. A JWP request offers the following benefits:
15
- * Associates the `Issue` with your company
16
- * Permits securely share sensitive information related to the bug, request, or question
17
- * Enhances JWP's ability to track progress and provide timely updates
18
- * Enables you to track and manage multiple issues through a single platform
19
-
20
- | ℹ️ While `Issues` are valuable for open-source collaboration, a JWP request ensures that you will receive clear timelines and efficient support. |
21
- |:---|
@@ -1,15 +0,0 @@
1
- ### What does this Pull Request do?
2
-
3
-
4
- ### Why is this Pull Request needed?
5
-
6
-
7
- ### Are there any points in the code the reviewer needs to double check?
8
-
9
-
10
- ### Are there any Pull Requests open in other repos which need to be merged with this?
11
-
12
-
13
- #### Addresses Issue(s):
14
-
15
- [GitHub Issue](https://github.com/jwplayer/jwplayer-react-native/issues/###)
@@ -1,128 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- We as members, contributors, and leaders pledge to make participation in our
6
- community a harassment-free experience for everyone, regardless of age, body
7
- size, visible or invisible disability, ethnicity, sex characteristics, gender
8
- identity and expression, level of experience, education, socio-economic status,
9
- nationality, personal appearance, race, religion, or sexual identity
10
- and orientation.
11
-
12
- We pledge to act and interact in ways that contribute to an open, welcoming,
13
- diverse, inclusive, and healthy community.
14
-
15
- ## Our Standards
16
-
17
- Examples of behavior that contributes to a positive environment for our
18
- community include:
19
-
20
- * Demonstrating empathy and kindness toward other people
21
- * Being respectful of differing opinions, viewpoints, and experiences
22
- * Giving and gracefully accepting constructive feedback
23
- * Accepting responsibility and apologizing to those affected by our mistakes,
24
- and learning from the experience
25
- * Focusing on what is best not just for us as individuals, but for the
26
- overall community
27
-
28
- Examples of unacceptable behavior include:
29
-
30
- * The use of sexualized language or imagery, and sexual attention or
31
- advances of any kind
32
- * Trolling, insulting or derogatory comments, and personal or political attacks
33
- * Public or private harassment
34
- * Publishing others' private information, such as a physical or email
35
- address, without their explicit permission
36
- * Other conduct which could reasonably be considered inappropriate in a
37
- professional setting
38
-
39
- ## Enforcement Responsibilities
40
-
41
- Community leaders are responsible for clarifying and enforcing our standards of
42
- acceptable behavior and will take appropriate and fair corrective action in
43
- response to any behavior that they deem inappropriate, threatening, offensive,
44
- or harmful.
45
-
46
- Community leaders have the right and responsibility to remove, edit, or reject
47
- comments, commits, code, wiki edits, issues, and other contributions that are
48
- not aligned to this Code of Conduct, and will communicate reasons for moderation
49
- decisions when appropriate.
50
-
51
- ## Scope
52
-
53
- This Code of Conduct applies within all community spaces, and also applies when
54
- an individual is officially representing the community in public spaces.
55
- Examples of representing our community include using an official e-mail address,
56
- posting via an official social media account, or acting as an appointed
57
- representative at an online or offline event.
58
-
59
- ## Enforcement
60
-
61
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
- reported to the community leaders responsible for enforcement at
63
- conduct@jwplayer.com.
64
- All complaints will be reviewed and investigated promptly and fairly.
65
-
66
- All community leaders are obligated to respect the privacy and security of the
67
- reporter of any incident.
68
-
69
- ## Enforcement Guidelines
70
-
71
- Community leaders will follow these Community Impact Guidelines in determining
72
- the consequences for any action they deem in violation of this Code of Conduct:
73
-
74
- ### 1. Correction
75
-
76
- **Community Impact**: Use of inappropriate language or other behavior deemed
77
- unprofessional or unwelcome in the community.
78
-
79
- **Consequence**: A private, written warning from community leaders, providing
80
- clarity around the nature of the violation and an explanation of why the
81
- behavior was inappropriate. A public apology may be requested.
82
-
83
- ### 2. Warning
84
-
85
- **Community Impact**: A violation through a single incident or series
86
- of actions.
87
-
88
- **Consequence**: A warning with consequences for continued behavior. No
89
- interaction with the people involved, including unsolicited interaction with
90
- those enforcing the Code of Conduct, for a specified period of time. This
91
- includes avoiding interactions in community spaces as well as external channels
92
- like social media. Violating these terms may lead to a temporary or
93
- permanent ban.
94
-
95
- ### 3. Temporary Ban
96
-
97
- **Community Impact**: A serious violation of community standards, including
98
- sustained inappropriate behavior.
99
-
100
- **Consequence**: A temporary ban from any sort of interaction or public
101
- communication with the community for a specified period of time. No public or
102
- private interaction with the people involved, including unsolicited interaction
103
- with those enforcing the Code of Conduct, is allowed during this period.
104
- Violating these terms may lead to a permanent ban.
105
-
106
- ### 4. Permanent Ban
107
-
108
- **Community Impact**: Demonstrating a pattern of violation of community
109
- standards, including sustained inappropriate behavior, harassment of an
110
- individual, or aggression toward or disparagement of classes of individuals.
111
-
112
- **Consequence**: A permanent ban from any sort of public interaction within
113
- the community.
114
-
115
- ## Attribution
116
-
117
- This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118
- version 2.0, available at
119
- https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120
-
121
- Community Impact Guidelines were inspired by [Mozilla's code of conduct
122
- enforcement ladder](https://github.com/mozilla/diversity).
123
-
124
- [homepage]: https://www.contributor-covenant.org
125
-
126
- For answers to common questions about this code of conduct, see the FAQ at
127
- https://www.contributor-covenant.org/faq. Translations are available at
128
- https://www.contributor-covenant.org/translations.