| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 | 
							- import { GOOGLE_API_SCOPES, DISCOVERY_DOCS } from './constants';
 - 
 - const GOOGLE_API_CLIENT_LIBRARY_URL = 'https://apis.google.com/js/api.js';
 - 
 - /**
 -  * A promise for dynamically loading the Google API Client Library.
 -  *
 -  * @private
 -  * @type {Promise}
 -  */
 - let googleClientLoadPromise;
 - 
 - /**
 -  * A singleton for loading and interacting with the Google API.
 -  */
 - const googleApi = {
 -     /**
 -      * Obtains Google API Client Library, loading the library dynamically if
 -      * needed.
 -      *
 -      * @returns {Promise}
 -      */
 -     get() {
 -         const globalGoogleApi = this._getGoogleApiClient();
 - 
 -         if (!globalGoogleApi) {
 -             return this.load();
 -         }
 - 
 -         return Promise.resolve(globalGoogleApi);
 -     },
 - 
 -     /**
 -      * Gets the profile for the user signed in to the Google API Client Library.
 -      *
 -      * @returns {Promise}
 -      */
 -     getCurrentUserProfile() {
 -         return this.get()
 -             .then(() => this.isSignedIn())
 -             .then(isSignedIn => {
 -                 if (!isSignedIn) {
 -                     return null;
 -                 }
 - 
 -                 return this._getGoogleApiClient()
 -                     .auth2.getAuthInstance()
 -                     .currentUser.get()
 -                     .getBasicProfile();
 -             });
 -     },
 - 
 -     /**
 -      * Sets the Google Web Client ID used for authenticating with Google and
 -      * making Google API requests.
 -      *
 -      * @param {string} clientId - The client ID to be used with the API library.
 -      * @returns {Promise}
 -      */
 -     initializeClient(clientId) {
 -         return this.get()
 -             .then(api => new Promise((resolve, reject) => {
 -                 // setTimeout is used as a workaround for api.client.init not
 -                 // resolving consistently when the Google API Client Library is
 -                 // loaded asynchronously. See:
 -                 // github.com/google/google-api-javascript-client/issues/399
 -                 setTimeout(() => {
 -                     api.client.init({
 -                         clientId,
 -                         discoveryDocs: DISCOVERY_DOCS,
 -                         scope: GOOGLE_API_SCOPES.join(' ')
 -                     })
 -                     .then(resolve)
 -                     .catch(reject);
 -                 }, 500);
 -             }));
 -     },
 - 
 -     /**
 -      * Checks whether a user is currently authenticated with Google through an
 -      * initialized Google API Client Library.
 -      *
 -      * @returns {Promise}
 -      */
 -     isSignedIn() {
 -         return this.get()
 -             .then(api => Boolean(api
 -                 && api.auth2
 -                 && api.auth2.getAuthInstance
 -                 && api.auth2.getAuthInstance()
 -                 && api.auth2.getAuthInstance().isSignedIn
 -                 && api.auth2.getAuthInstance().isSignedIn.get()));
 -     },
 - 
 -     /**
 -      * Generates a script tag and downloads the Google API Client Library.
 -      *
 -      * @returns {Promise}
 -      */
 -     load() {
 -         if (googleClientLoadPromise) {
 -             return googleClientLoadPromise;
 -         }
 - 
 -         googleClientLoadPromise = new Promise((resolve, reject) => {
 -             const scriptTag = document.createElement('script');
 - 
 -             scriptTag.async = true;
 -             scriptTag.addEventListener('error', () => {
 -                 scriptTag.remove();
 - 
 -                 googleClientLoadPromise = null;
 - 
 -                 reject();
 -             });
 -             scriptTag.addEventListener('load', resolve);
 -             scriptTag.type = 'text/javascript';
 - 
 -             scriptTag.src = GOOGLE_API_CLIENT_LIBRARY_URL;
 - 
 -             document.head.appendChild(scriptTag);
 -         })
 -             .then(() => new Promise((resolve, reject) =>
 -                 this._getGoogleApiClient().load('client:auth2', {
 -                     callback: resolve,
 -                     onerror: reject
 -                 })))
 -             .then(() => this._getGoogleApiClient());
 - 
 -         return googleClientLoadPromise;
 -     },
 - 
 -     /**
 -      * Executes a request for a list of all YouTube broadcasts associated with
 -      * user currently signed in to the Google API Client Library.
 -      *
 -      * @returns {Promise}
 -      */
 -     requestAvailableYouTubeBroadcasts() {
 -         const url = this._getURLForLiveBroadcasts();
 - 
 -         return this.get()
 -             .then(api => api.client.request(url));
 -     },
 - 
 -     /**
 -      * Executes a request to get all live streams associated with a broadcast
 -      * in YouTube.
 -      *
 -      * @param {string} boundStreamID - The bound stream ID associated with a
 -      * broadcast in YouTube.
 -      * @returns {Promise}
 -      */
 -     requestLiveStreamsForYouTubeBroadcast(boundStreamID) {
 -         const url = this._getURLForLiveStreams(boundStreamID);
 - 
 -         return this.get()
 -             .then(api => api.client.request(url));
 -     },
 - 
 -     /**
 -      * Prompts the participant to sign in to the Google API Client Library, even
 -      * if already signed in.
 -      *
 -      * @returns {Promise}
 -      */
 -     showAccountSelection() {
 -         return this.get()
 -             .then(api => api.auth2.getAuthInstance().signIn());
 -     },
 - 
 -     /**
 -      * Prompts the participant to sign in to the Google API Client Library, if
 -      * not already signed in.
 -      *
 -      * @returns {Promise}
 -      */
 -     signInIfNotSignedIn() {
 -         return this.get()
 -             .then(() => this.isSignedIn())
 -             .then(isSignedIn => {
 -                 if (!isSignedIn) {
 -                     return this.showAccountSelection();
 -                 }
 -             });
 -     },
 - 
 -     /**
 -      * Sign out from the Google API Client Library.
 -      *
 -      * @returns {Promise}
 -      */
 -     signOut() {
 -         return this.get()
 -             .then(api =>
 -                 api.auth2
 -                 && api.auth2.getAuthInstance
 -                 && api.auth2.getAuthInstance()
 -                 && api.auth2.getAuthInstance().signOut());
 -     },
 - 
 -     /**
 -      * Parses the google calendar entries to a known format.
 -      *
 -      * @param {Object} entry - The google calendar entry.
 -      * @returns {{
 -      *  calendarId: string,
 -      *  description: string,
 -      *  endDate: string,
 -      *  id: string,
 -      *  location: string,
 -      *  startDate: string,
 -      *  title: string}}
 -      * @private
 -      */
 -     _convertCalendarEntry(entry) {
 -         return {
 -             calendarId: entry.calendarId,
 -             description: entry.description,
 -             endDate: entry.end.dateTime,
 -             id: entry.id,
 -             location: entry.location,
 -             startDate: entry.start.dateTime,
 -             title: entry.summary
 -         };
 -     },
 - 
 -     /**
 -      * Retrieves calendar entries from all available calendars.
 -      *
 -      * @param {number} fetchStartDays - The number of days to go back
 -      * when fetching.
 -      * @param {number} fetchEndDays - The number of days to fetch.
 -      * @returns {Promise<CalendarEntry>}
 -      * @private
 -      */
 -     _getCalendarEntries(fetchStartDays, fetchEndDays) {
 -         return this.get()
 -             .then(() => this.isSignedIn())
 -             .then(isSignedIn => {
 -                 if (!isSignedIn) {
 -                     return null;
 -                 }
 - 
 -                 // user can edit the events, so we want only those that
 -                 // can be edited
 -                 return this._getGoogleApiClient()
 -                     .client.calendar.calendarList.list();
 -             })
 -             .then(calendarList => {
 - 
 -                 // no result, maybe not signed in
 -                 if (!calendarList) {
 -                     return Promise.resolve();
 -                 }
 - 
 -                 const calendarIds
 -                     = calendarList.result.items.map(en => {
 -                         return {
 -                             id: en.id,
 -                             accessRole: en.accessRole
 -                         };
 -                     });
 -                 const promises = calendarIds.map(({ id, accessRole }) => {
 -                     const startDate = new Date();
 -                     const endDate = new Date();
 - 
 -                     startDate.setDate(startDate.getDate() + fetchStartDays);
 -                     endDate.setDate(endDate.getDate() + fetchEndDays);
 - 
 -                     // retrieve the events and adds to the result the calendarId
 -                     return this._getGoogleApiClient()
 -                         .client.calendar.events.list({
 -                             'calendarId': id,
 -                             'timeMin': startDate.toISOString(),
 -                             'timeMax': endDate.toISOString(),
 -                             'showDeleted': false,
 -                             'singleEvents': true,
 -                             'orderBy': 'startTime'
 -                         })
 -                         .then(result => result.result.items
 -                             .map(item => {
 -                                 const resultItem = { ...item };
 - 
 -                                 // add the calendarId only for the events
 -                                 // we can edit
 -                                 if (accessRole === 'writer'
 -                                     || accessRole === 'owner') {
 -                                     resultItem.calendarId = id;
 -                                 }
 - 
 -                                 return resultItem;
 -                             }));
 -                 });
 - 
 -                 return Promise.all(promises)
 -                     .then(results => [].concat(...results))
 -                     .then(entries =>
 -                         entries.map(e => this._convertCalendarEntry(e)));
 -             });
 -     },
 - 
 -     /* eslint-disable max-params */
 -     /**
 -      * Updates the calendar event and adds a location and text.
 -      *
 -      * @param {string} id - The event id to update.
 -      * @param {string} calendarId - The calendar id to use.
 -      * @param {string} location - The location to add to the event.
 -      * @param {string} text - The description text to set/append.
 -      * @returns {Promise<T | never>}
 -      * @private
 -      */
 -     _updateCalendarEntry(id, calendarId, location, text) {
 -         return this.get()
 -             .then(() => this.isSignedIn())
 -             .then(isSignedIn => {
 -                 if (!isSignedIn) {
 -                     return null;
 -                 }
 - 
 -                 return this._getGoogleApiClient()
 -                     .client.calendar.events.get({
 -                         'calendarId': calendarId,
 -                         'eventId': id
 -                     }).then(event => {
 -                         let newDescription = text;
 - 
 -                         if (event.result.description) {
 -                             newDescription = `${event.result.description}\n\n${
 -                                 text}`;
 -                         }
 - 
 -                         return this._getGoogleApiClient()
 -                             .client.calendar.events.patch({
 -                                 'calendarId': calendarId,
 -                                 'eventId': id,
 -                                 'description': newDescription,
 -                                 'location': location
 -                             });
 -                     });
 - 
 -             });
 -     },
 -     /* eslint-enable max-params */
 - 
 -     /**
 -      * Returns the global Google API Client Library object. Direct use of this
 -      * method is discouraged; instead use the {@link get} method.
 -      *
 -      * @private
 -      * @returns {Object|undefined}
 -      */
 -     _getGoogleApiClient() {
 -         return window.gapi;
 -     },
 - 
 -     /**
 -      * Returns the URL to the Google API endpoint for retrieving the currently
 -      * signed in user's YouTube broadcasts.
 -      *
 -      * @private
 -      * @returns {string}
 -      */
 -     _getURLForLiveBroadcasts() {
 -         return [
 -             'https://content.googleapis.com/youtube/v3/liveBroadcasts',
 -             '?broadcastType=all',
 -             '&mine=true&part=id%2Csnippet%2CcontentDetails%2Cstatus'
 -         ].join('');
 -     },
 - 
 -     /**
 -      * Returns the URL to the Google API endpoint for retrieving the live
 -      * streams associated with a YouTube broadcast's bound stream.
 -      *
 -      * @param {string} boundStreamID - The bound stream ID associated with a
 -      * broadcast in YouTube.
 -      * @returns {string}
 -      */
 -     _getURLForLiveStreams(boundStreamID) {
 -         return [
 -             'https://content.googleapis.com/youtube/v3/liveStreams',
 -             '?part=id%2Csnippet%2Ccdn%2Cstatus',
 -             `&id=${boundStreamID}`
 -         ].join('');
 -     }
 - };
 - 
 - export default googleApi;
 
 
  |