2
\$\begingroup\$

I made a hacky version of a chrome extension to compliment a weekly literary/arts publication. The extension helps me curate links from my publication's readers since there's only so much I can curate and read/watch.

Users sign in through google and can share the link of the opened tab to me.

I'm new to programming. Any kind of code review / suggestion would be highly appreciated. I've opened three issues that I see I need to correct on github repo already, please feel free to highlight and open more.

I'm using firebase auth and database for persistent storage.

LOL Chrome Extension Github Repo

Main code of the repo, in which I'd need review is as follows

// LOL-Chrome-Extension/src/js/credentials.js

  let signInBtn = document.querySelector("#sign-in"),
  signOutBtn = document.querySelector("#sign-out"),
  clickBait = document.getElementById('google-sign-in-btn'),
  loader = document.querySelector(".loader"),
  linkShareBtn = document.querySelector(".send-link-btn")

// Wrapper Functions
function crGetSignInStatus(key, cb) {
  chrome.storage.sync.get(key, (status) => {
    cb(status[key])
  })
}

function crStoreSignInStatus(val, cb) {
  chrome.storage.sync.set({
    "signInStatus": val
  }, () => {
    console.log("Signed In? ", val)
  })
}

function toggleBtns(signInStatusVal) {
  if(signInStatusVal) {
    signInBtn.style.display = "none"
    signOutBtn.style.display = "block"

    linkShareBtn.classList.remove("hide");
    linkShareBtn.addEventListener("click", (e) => {

      // Ripple effect

      let scali = document.querySelector(".scali")
      scali.classList.remove("animate");

      let computedStylesScali  = window.getComputedStyle(document.querySelector(".scali"))

      if( !computedStylesScali.width && !computedStylesScali.height  ) {
        let d = Math.max(linkShareBtn.offsetWidth, linkShareBtn.offsetHeight)
        scali.style.height = d
        scali.style.width = d
      }

      let offsetObj = linkShareBtn.getBoundingClientRect(),
       offsetTop = offsetObj.top + document.body.scrollTop,
       offsetLeft = offsetObj.left + document.body.scrollLeft

      let x = e.pageX - offsetLeft - computedStylesScali.width / 2

      let y = e.pageY - offsetTop - computedStylesScali.height / 2

      scali.style.top = y + "px"
      scali.style.left = x + "px"

      scali.classList.add("animate");

      // ripple effect end

      loader.classList.remove("hide");
      console.log(e.target, " was clicked")

      let currentUserId = firebase.auth().currentUser.providerData[0].uid

      chrome.tabs.query({currentWindow: true, active: true}, function(tabs){

       let newLinkRef = firebase.database().ref().child("links").push()
       let newLinkKey = newLinkRef.key

       async function writeLinks() {
         try {
          await Promise.all([
            firebase.database()
              .ref("users/" + currentUserId)
              .child("links")
              .child(newLinkKey).set({
                url: tabs[0].url
              }),

            newLinkRef.set({
              uid: currentUserId,
              url: tabs[0].url
            })
          ])

          loader.classList.add("hide")
         } catch ( error ) {
           console.log(error);
         }
       }

       writeLinks();

      });
    })

  } else {
      signInBtn.style.display = "block"
      signOutBtn.style.display = "none"

      linkShareBtn.classList.add("hide");
      linkShareBtn.removeEventListener("click", () => {
        console.log("click event on share button is removed")
      })
  }
}

class LOL {
  constructor(...args) {
    this.init.bind(this);
  }

  initFirebase() {
    const config = {
      apiKey: "AIzaSyCLh6M0BKhcihuFWioSVn30z1euZsEF79A",
      databaseURL: "https://lol-chrome-extension.firebaseio.com",
      storageBucket: "lol-chrome-extension.appspot.com"
    };

    firebase.initializeApp(config);
  }

  firebaseAuthStateObserver() {
    firebase.auth().onAuthStateChanged( (user) => {
      if(user) {
        let {
          displayName,
          email,
          photoURL,
          uid
        } = user.providerData[0]

      } else {
        // share button disabled
      }
    })
  }

  attachSignInClickEvent() {
    clickBait.addEventListener("click", this.handleSignInOut.bind(this), false)
  }

  startSignIn(interactive) {
    loader.classList.remove("hide")

    chrome.identity.getAuthToken({ interactive: !!interactive}, (token) => {
      if(chrome.runtime.lastError && !interactive) {
        console.error("It wasn't possible to get a token programmatically")
      } else if (chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError);
      } else if (token) {
        let credential = firebase.auth.GoogleAuthProvider.credential(null, token)
        firebase.auth().signInWithCredential(credential)
          .then( (...args) => {

            crStoreSignInStatus(true, () => {})

            // abstract it
            loader.classList.add("hide");

            crGetSignInStatus("signInStatus", toggleBtns)

            const userInfo = args[0];
            const { uid, displayName, email, photoURL } = userInfo.providerData[0];

            console.log("signin userinfo", userInfo)
            this.firebasePostUser({ uid, displayName, email, photoURL })


            // write end
          })
          .catch( (error) => {
            if(error.code === "auth/invalid-credential") {
              chrome.identity.removeCachedAuthToken({ token: token}, () => {
                this.handleSignInOut(interactive)
              })
            }
          })
      }
    })
  }

  handleSignInOut() {
    if(firebase.auth().currentUser) {
      firebase.auth().signOut();
      crStoreSignInStatus(false, () => {})
      crGetSignInStatus("signInStatus", toggleBtns)
    } else {
      this.startSignIn(true);
    }
  }

  firebasePostUser(userInfoObj) {
    const { displayName, email, photoURL, uid } = userInfoObj;

    let userRef = firebase.database().ref("users/" + uid);

    userRef.once('value', (snap) => {
      let exists = (snap.val() !=null );
      console.log(exists);

      if(!exists) {
        userRef.set({
          name: displayName,
          email,
          photoURL,
          createdAt: new Date().getTime()
        })
      }
    })

  }
  init() {
    this.initFirebase()
    this.firebaseAuthStateObserver()
    this.attachSignInClickEvent()
  }
}

window.onload = () => {
  crGetSignInStatus("signInStatus", toggleBtns)
  let lol = new LOL();
  lol.init();
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.