您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

actions.ts 7.3KB

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