Skip to content

Instantly share code, notes, and snippets.

@ithinkihaveacat
Created June 27, 2016 02:06
Show Gist options
  • Select an option

  • Save ithinkihaveacat/c7892d9afa8f17d6a19213498cea0e77 to your computer and use it in GitHub Desktop.

Select an option

Save ithinkihaveacat/c7892d9afa8f17d6a19213498cea0e77 to your computer and use it in GitHub Desktop.
More sane version of some of the Google sign in libraries
/**
* Promise'd version of `gapi.load`.
*/
function gapiLoad<T>(s: string): Promise<T> {
return new Promise((resolve, reject) => {
if ("gapi" in window) {
gapi.load(s, () => resolve(gapi[s]));
} else {
reject("window.gapi not found");
}
});
};
/**
* Promise'd version of `gapi.auth2.init`.
*/
function authInit(params?: gapi.auth2.InitParams): Promise<gapi.auth2.GoogleAuth> {
return gapiLoad<any>("auth2").then(auth2 => {
/* Ideally we'd just return `auth2.init(params)` here, but
* instead we need to work around a few bugs and surprises in
* `auth2.init()` and the "Promise" it returns.
*/
return new Promise(resolve => {
auth2.init(params).then(t => {
t.then = null;
resolve(t);
});
});
});
}
// ### BaseComponent
// The `BaseComponent` is a simple EventTarget-like abstract class, useful for expressing
// the dataflow relationship between components.
abstract class BaseComponent<T> {
private listeners: ((event: T) => void)[] = [];
public constructor() {
return this;
}
/**
* Add event listener. When the event is dispatched, `callback` is called,
* with the event as the argument.
*
* @param {function} callback
*/
public addEventListener(callback: ((event: T) => void)) {
this.listeners.push(callback);
}
/**
* Removes event listener.
*
* @param {function} callback
*/
public removeEventListener(callback: ((event: T) => void)) {
this.listeners = this.listeners.filter(l => l !== callback);
}
/**
* Dispatches event. When called, every listener is called in turn,
* with `event` as its sole argument.
*
* @param {object} event
*/
public dispatchEvent(event: T) {
/* console.warn("DISPATCH", typeof this, event); */
this.listeners.forEach(l => l.call(this, event));
}
}
// ### UserComponent
// The `UserComponent` initializes the authentication process, firing events
// as users login and logout.
/**
* Listeners are passed a `gapi.auth2.GoogleUser` object when users login
* or logout, including first load.
*/
class UserComponent extends BaseComponent<gapi.auth2.GoogleUser> {
/**
* @param {HTMLElement} login
* @param {HTMLElement} logout
* @param {string} clientId OAuth Client Id
* @param {string} scope Scopes to request
*/
public constructor(params: {
login: HTMLElement,
logout: HTMLElement,
clientId: string,
scope: string
}) {
super();
authInit({ client_id: params.clientId, scope: params.scope }).then(auth => {
params.login.addEventListener("click", () => auth.signIn());
params.logout.addEventListener("click", () => auth.signOut());
auth.currentUser.listen(this.dispatchEvent.bind(this));
this.dispatchEvent(auth.currentUser.get());
}).catch(e => {
console.error("unable to initialize UserComponent:", e);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment