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.

actions.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /* @flow */
  2. import {
  3. SET_GOOGLE_API_PROFILE,
  4. SET_GOOGLE_API_STATE
  5. } from './actionTypes';
  6. import { GOOGLE_API_STATES } from './constants';
  7. import googleApi from './googleApi';
  8. /**
  9. * Retrieves the current calendar events.
  10. *
  11. * @param {number} fetchStartDays - The number of days to go back when fetching.
  12. * @param {number} fetchEndDays - The number of days to fetch.
  13. * @returns {function(Dispatch<*>): Promise<CalendarEntries>}
  14. */
  15. export function getCalendarEntries(
  16. fetchStartDays: ?number, fetchEndDays: ?number) {
  17. return () =>
  18. googleApi.get()
  19. .then(() =>
  20. googleApi._getCalendarEntries(fetchStartDays, fetchEndDays));
  21. }
  22. /**
  23. * Loads Google API.
  24. *
  25. * @param {string} clientId - The client ID to be used with the API library.
  26. * @returns {Function}
  27. */
  28. export function loadGoogleAPI(clientId: string) {
  29. return (dispatch: Dispatch<*>, getState: Function) =>
  30. googleApi.get()
  31. .then(() => {
  32. if (getState()['features/google-api'].googleAPIState
  33. === GOOGLE_API_STATES.NEEDS_LOADING) {
  34. return googleApi.initializeClient(clientId);
  35. }
  36. return Promise.resolve();
  37. })
  38. .then(() => dispatch({
  39. type: SET_GOOGLE_API_STATE,
  40. googleAPIState: GOOGLE_API_STATES.LOADED }))
  41. .then(() => googleApi.isSignedIn())
  42. .then(isSignedIn => {
  43. if (isSignedIn) {
  44. dispatch({
  45. type: SET_GOOGLE_API_STATE,
  46. googleAPIState: GOOGLE_API_STATES.SIGNED_IN });
  47. }
  48. });
  49. }
  50. /**
  51. * Executes a request for a list of all YouTube broadcasts associated with
  52. * user currently signed in to the Google API Client Library.
  53. *
  54. * @returns {function(): (Promise<*>|Promise<any[] | never>)}
  55. */
  56. export function requestAvailableYouTubeBroadcasts() {
  57. return () =>
  58. googleApi.requestAvailableYouTubeBroadcasts()
  59. .then(response => {
  60. // Takes in a list of broadcasts from the YouTube API,
  61. // removes dupes, removes broadcasts that cannot get a stream key,
  62. // and parses the broadcasts into flat objects.
  63. const broadcasts = response.result.items;
  64. const parsedBroadcasts = {};
  65. for (let i = 0; i < broadcasts.length; i++) {
  66. const broadcast = broadcasts[i];
  67. const boundStreamID = broadcast.contentDetails.boundStreamId;
  68. if (boundStreamID && !parsedBroadcasts[boundStreamID]) {
  69. parsedBroadcasts[boundStreamID] = {
  70. boundStreamID,
  71. id: broadcast.id,
  72. status: broadcast.status.lifeCycleStatus,
  73. title: broadcast.snippet.title
  74. };
  75. }
  76. }
  77. return Object.values(parsedBroadcasts);
  78. });
  79. }
  80. /**
  81. * Fetches the stream key for a YouTube broadcast and updates the internal
  82. * state to display the associated stream key as being entered.
  83. *
  84. * @param {string} boundStreamID - The bound stream ID associated with the
  85. * broadcast from which to get the stream key.
  86. * @returns {function(): (Promise<*>|Promise<{
  87. * streamKey: (*|string),
  88. * selectedBoundStreamID: *} | never>)}
  89. */
  90. export function requestLiveStreamsForYouTubeBroadcast(boundStreamID: string) {
  91. return () =>
  92. googleApi.requestLiveStreamsForYouTubeBroadcast(boundStreamID)
  93. .then(response => {
  94. const broadcasts = response.result.items;
  95. const streamName = broadcasts
  96. && broadcasts[0]
  97. && broadcasts[0].cdn.ingestionInfo.streamName;
  98. const streamKey = streamName || '';
  99. return {
  100. streamKey,
  101. selectedBoundStreamID: boundStreamID
  102. };
  103. });
  104. }
  105. /**
  106. * Forces the Google web client application to prompt for a sign in, such as
  107. * when changing account, and will then fetch available YouTube broadcasts.
  108. *
  109. * @returns {function(): (Promise<*>|Promise<{
  110. * streamKey: (*|string),
  111. * selectedBoundStreamID: *} | never>)}
  112. */
  113. export function showAccountSelection() {
  114. return () =>
  115. googleApi.showAccountSelection();
  116. }
  117. /**
  118. * Prompts the participant to sign in to the Google API Client Library.
  119. *
  120. * @returns {function(Dispatch<*>): Promise<string | never>}
  121. */
  122. export function signIn() {
  123. return (dispatch: Dispatch<*>) => googleApi.get()
  124. .then(() => googleApi.signInIfNotSignedIn())
  125. .then(() => dispatch({
  126. type: SET_GOOGLE_API_STATE,
  127. googleAPIState: GOOGLE_API_STATES.SIGNED_IN
  128. }));
  129. }
  130. /**
  131. * Logs out the user.
  132. *
  133. * @returns {function(Dispatch<*>): Promise<string | never>}
  134. */
  135. export function signOut() {
  136. return (dispatch: Dispatch<*>) =>
  137. googleApi.get()
  138. .then(() => googleApi.signOut())
  139. .then(() => {
  140. dispatch({
  141. type: SET_GOOGLE_API_STATE,
  142. googleAPIState: GOOGLE_API_STATES.LOADED
  143. });
  144. dispatch({
  145. type: SET_GOOGLE_API_PROFILE,
  146. profileEmail: ''
  147. });
  148. });
  149. }
  150. /**
  151. * Updates the profile data that is currently used.
  152. *
  153. * @returns {function(Dispatch<*>): Promise<string | never>}
  154. */
  155. export function updateProfile() {
  156. return (dispatch: Dispatch<*>) => googleApi.get()
  157. .then(() => googleApi.signInIfNotSignedIn())
  158. .then(() => dispatch({
  159. type: SET_GOOGLE_API_STATE,
  160. googleAPIState: GOOGLE_API_STATES.SIGNED_IN
  161. }))
  162. .then(() => googleApi.getCurrentUserProfile())
  163. .then(profile => {
  164. dispatch({
  165. type: SET_GOOGLE_API_PROFILE,
  166. profileEmail: profile.getEmail()
  167. });
  168. return profile.getEmail();
  169. });
  170. }