You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

googleApi.native.js 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // @flow
  2. import { NativeModules } from 'react-native';
  3. let GoogleSignin;
  4. if (NativeModules.RNGoogleSignin) {
  5. GoogleSignin = require('@react-native-community/google-signin').GoogleSignin;
  6. }
  7. import {
  8. API_URL_BROADCAST_STREAMS,
  9. API_URL_LIVE_BROADCASTS
  10. } from './constants';
  11. /**
  12. * Class to encapsulate Google API functionalities and provide a similar
  13. * interface to what WEB has. The methods are different, but the point is that
  14. * the export object is similar so no need for different export logic.
  15. *
  16. * For more detailed documentation of the {@code GoogleSignin} API, please visit
  17. * https://github.com/react-native-community/react-native-google-signin.
  18. */
  19. class GoogleApi {
  20. /**
  21. * Wraps the {@code GoogleSignin.configure} method.
  22. *
  23. * @param {Object} config - The config object to be passed to
  24. * {@code GoogleSignin.configure}.
  25. * @returns {void}
  26. */
  27. configure(config: Object) {
  28. if (GoogleSignin) {
  29. GoogleSignin.configure(config);
  30. }
  31. }
  32. /**
  33. * Retrieves the current tokens.
  34. *
  35. * @returns {Promise}
  36. */
  37. getTokens(): Promise<*> {
  38. return GoogleSignin.getTokens();
  39. }
  40. /**
  41. * Retrieves the available YouTube streams the user can use for live
  42. * streaming.
  43. *
  44. * @param {string} accessToken - The Google auth token.
  45. * @returns {Promise}
  46. */
  47. getYouTubeLiveStreams(accessToken: string): Promise<*> {
  48. return new Promise((resolve, reject) => {
  49. // Fetching the list of available broadcasts first.
  50. this._fetchGoogleEndpoint(accessToken,
  51. API_URL_LIVE_BROADCASTS)
  52. .then(broadcasts => {
  53. // Then fetching all the available live streams that the
  54. // user has access to with the broadcasts we retrieved
  55. // earlier.
  56. this._getLiveStreamsForBroadcasts(
  57. accessToken, broadcasts).then(resolve, reject);
  58. }, reject);
  59. });
  60. }
  61. /**
  62. * Wraps the {@code GoogleSignin.hasPlayServices} method.
  63. *
  64. * @returns {Promise<*>}
  65. */
  66. hasPlayServices() {
  67. if (!GoogleSignin) {
  68. return Promise.reject(new Error('Google SignIn not supported'));
  69. }
  70. return GoogleSignin.hasPlayServices();
  71. }
  72. /**
  73. * Wraps the {@code GoogleSignin.signIn} method.
  74. *
  75. * @returns {Promise<*>}
  76. */
  77. signIn() {
  78. return GoogleSignin.signIn();
  79. }
  80. /**
  81. * Wraps the {@code GoogleSignin.signInSilently} method.
  82. *
  83. * @returns {Promise<*>}
  84. */
  85. signInSilently() {
  86. return GoogleSignin.signInSilently();
  87. }
  88. /**
  89. * Wraps the {@code GoogleSignin.signOut} method.
  90. *
  91. * @returns {Promise<*>}
  92. */
  93. signOut() {
  94. return GoogleSignin.signOut();
  95. }
  96. /**
  97. * Helper method to fetch a Google API endpoint in a generic way.
  98. *
  99. * @private
  100. * @param {string} accessToken - The access token used for the API call.
  101. * @param {string} endpoint - The endpoint to fetch, including the URL
  102. * params if needed.
  103. * @returns {Promise}
  104. */
  105. _fetchGoogleEndpoint(accessToken, endpoint): Promise<*> {
  106. return new Promise((resolve, reject) => {
  107. const headers = {
  108. Authorization: `Bearer ${accessToken}`
  109. };
  110. fetch(endpoint, {
  111. headers
  112. }).then(response => response.json())
  113. .then(responseJSON => {
  114. if (responseJSON.error) {
  115. reject(responseJSON.error.message);
  116. } else {
  117. resolve(responseJSON.items || []);
  118. }
  119. }, reject);
  120. });
  121. }
  122. /**
  123. * Retrieves the available YouTube streams that are available for the
  124. * provided broadcast IDs.
  125. *
  126. * @private
  127. * @param {string} accessToken - The Google access token.
  128. * @param {Array<Object>} broadcasts - The list of broadcasts that we want
  129. * to retrieve streams for.
  130. * @returns {Promise}
  131. */
  132. _getLiveStreamsForBroadcasts(accessToken, broadcasts): Promise<*> {
  133. return new Promise((resolve, reject) => {
  134. const ids = [];
  135. for (const broadcast of broadcasts) {
  136. broadcast.contentDetails
  137. && broadcast.contentDetails.boundStreamId
  138. && ids.push(broadcast.contentDetails.boundStreamId);
  139. }
  140. this._fetchGoogleEndpoint(
  141. accessToken,
  142. `${API_URL_BROADCAST_STREAMS}${ids.join(',')}`)
  143. .then(streams => {
  144. const keys = [];
  145. // We construct an array of keys bind with the broadcast
  146. // name for a nice display.
  147. for (const stream of streams) {
  148. const key = stream.cdn.ingestionInfo.streamName;
  149. let title;
  150. // Finding title from the broadcast with the same
  151. // boundStreamId. If not found (unknown scenario), we
  152. // use the key as title again.
  153. for (const broadcast of broadcasts) {
  154. if (broadcast.contentDetails
  155. && broadcast.contentDetails.boundStreamId
  156. === stream.id) {
  157. title = broadcast.snippet.title;
  158. }
  159. }
  160. keys.push({
  161. key,
  162. title: title || key
  163. });
  164. }
  165. resolve(keys);
  166. }, reject);
  167. });
  168. }
  169. }
  170. export default new GoogleApi();