diff --git a/package-lock.json b/package-lock.json index 5f9b1b51..68b87d25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7109,9 +7109,9 @@ } }, "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", + "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", "dev": true, "bin": { "envinfo": "dist/cli.js" diff --git a/src/background.js b/src/background.js index db754707..6f8be63c 100644 --- a/src/background.js +++ b/src/background.js @@ -2,13 +2,13 @@ // Handles communication between the extension and the content script as well as Firebase interactions import { configSync, setSyncStorageValue } from "./chromeStorage.js"; import { isFirefox, firebaseConfig } from "./config.js"; -import { initializeApp } from "firebase/app"; +import { hasActiveSubscriptionRole } from "./stripe.js"; +import { getApp, getApps, initializeApp } from "firebase/app"; import { getDatabase, ref, child, update, get, remove } from "firebase/database"; // ---------- Initialization/Chrome event listeners ---------- // Check whether a new version was installed async function initExtension() { - // TODO: Change the extension icon if the user is subscribed to Shuffle+ const manifestData = chrome.runtime.getManifest(); if (configSync.previousVersion === null) { console.log(`Extension was installed for the first time (v${manifestData.version})`); @@ -25,10 +25,28 @@ async function initExtension() { await handleExtensionUpdate(manifestData, configSync.previousVersion); } + await checkShufflePlusStatus(); checkLocalStorageCapacity(); } + await initExtension(); +// On every startup, we check the claim roles for the user +async function checkShufflePlusStatus() { + // TODO: If the user has not yet been introduced to Shuffle+, open the introduction page + if (await hasActiveSubscriptionRole()) { + console.log("User has an active Shuffle+ subscription."); + chrome.action.setIcon({ + path: { + "16": chrome.runtime.getURL("icons/icon-16-white.png"), + "32": chrome.runtime.getURL("icons/icon-32-white.png"), + "48": chrome.runtime.getURL("icons/icon-48-white.png"), + "128": chrome.runtime.getURL("icons/icon-128-white.png") + } + }); + } +} + // Make sure we are not using too much local storage async function checkLocalStorageCapacity() { // If over 90% of the storage quota for playlists is used, remove playlists that have not been accessed in a long time @@ -197,7 +215,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { }); // ---------- Firebase ---------- -const app = initializeApp(firebaseConfig); +const app = !getApps().length ? initializeApp(firebaseConfig) : getApp(); const db = getDatabase(app); async function updatePlaylistInfoInDB(playlistId, playlistInfo, overwriteVideos) { diff --git a/src/googleOauth.js b/src/googleOauth.js index 9d282caf..70865f1b 100644 --- a/src/googleOauth.js +++ b/src/googleOauth.js @@ -2,11 +2,11 @@ import { setSyncStorageValue } from "./chromeStorage.js"; import { isFirefox, firebaseConfig } from "./config.js"; import { hasActiveSubscriptionRole } from "./stripe.js"; -import { initializeApp } from "firebase/app"; +import { getApp, getApps, initializeApp } from "firebase/app"; import { getFirestore, doc, getDoc, setDoc, deleteDoc } from "firebase/firestore"; import { getAuth, onAuthStateChanged, GoogleAuthProvider, signInWithCredential } from "firebase/auth"; -const app = initializeApp(firebaseConfig); +const app = !getApps().length ? initializeApp(firebaseConfig) : getApp(); const db = getFirestore(app); const auth = getAuth(app); @@ -24,7 +24,7 @@ export async function getUser(localOnly, allowSelfRevoke, signupIfNull) { console.log("No local user info found."); return null; } else if (googleOauth || (googleOauth == null && signupIfNull)) { - console.log("Attempting to sign up using Google Oauth."); + console.log("Attempting to sign in using Google Oauth (will attempt to sign up if no user exists)."); // This will also refresh the access token if it has expired return await googleLogin(allowSelfRevoke); } else { diff --git a/src/html/shufflePlus.js b/src/html/shufflePlus.js index 83b4212d..9fc15273 100644 --- a/src/html/shufflePlus.js +++ b/src/html/shufflePlus.js @@ -102,8 +102,15 @@ async function setDomElementEventListeners(domElements) { domElements.googleRevokeAccessButtonDiv.classList.remove("hidden"); domElements.manageSubscribtionButtonDiv.classList.remove("hidden"); await setSubscriptionUI(domElements, user); - // TODO: If the user is logged in and subscribed, change the extension icon, e.g.: - chrome.action.setIcon({ path: chrome.runtime.getURL("icons/icon-128-white.png") }); + + chrome.action.setIcon({ + path: { + "16": chrome.runtime.getURL("icons/icon-16-white.png"), + "32": chrome.runtime.getURL("icons/icon-32-white.png"), + "48": chrome.runtime.getURL("icons/icon-48-white.png"), + "128": chrome.runtime.getURL("icons/icon-128-white.png") + } + }); } else { domElements.googleLoginButton.textContent = `Login failed with error: ${user.code ? user.code : "Unknown Error"}`; domElements.googleLoginSuccessDiv.classList.add("hidden"); diff --git a/src/stripe.js b/src/stripe.js index 22f62add..9b88607b 100644 --- a/src/stripe.js +++ b/src/stripe.js @@ -1,11 +1,11 @@ // Contains logic for interacting with Stripe for payment handling import { firebaseConfig } from "./config.js"; import { getUser } from "./googleOauth.js"; -import { initializeApp } from "firebase/app"; +import { getApp, getApps, initializeApp } from "firebase/app"; import { getFirestore, query, collection, where, getDocs, addDoc, onSnapshot, FieldPath } from "firebase/firestore"; import { getAuth } from "firebase/auth"; -const app = initializeApp(firebaseConfig); +const app = !getApps().length ? initializeApp(firebaseConfig) : getApp(); const db = getFirestore(app); // Get products and pricing information from Firestore/Stripe @@ -139,13 +139,14 @@ export async function getSubscriptions(user = null, activeOnly = true) { } // This will return shufflePlus if the user has an active subscription -async function getStripeRole() { - const decodedToken = await getAuth().currentUser.getIdTokenResult(); +async function getStripeRole(user = null) { + user ??= await getUser(false, true, false); + const decodedToken = await getAuth().currentUser?.getIdTokenResult(); return decodedToken.claims?.stripeRole ?? null; } // TODO: Use this, as it is probably faster and cheaper than querying Firestore -export async function hasActiveSubscriptionRole() { - const stripeRole = await getStripeRole(); +export async function hasActiveSubscriptionRole(user = null) { + const stripeRole = await getStripeRole(user); return stripeRole === "shufflePlus"; } diff --git a/static/icons/icon-128-white.png b/static/icons/icon-128-white.png new file mode 100644 index 00000000..0694ea6f Binary files /dev/null and b/static/icons/icon-128-white.png differ diff --git a/static/icons/icon-16-white.png b/static/icons/icon-16-white.png new file mode 100644 index 00000000..8b59ed22 Binary files /dev/null and b/static/icons/icon-16-white.png differ diff --git a/static/icons/icon-32-white.png b/static/icons/icon-32-white.png new file mode 100644 index 00000000..7186be0c Binary files /dev/null and b/static/icons/icon-32-white.png differ diff --git a/static/icons/icon-48-white.png b/static/icons/icon-48-white.png new file mode 100644 index 00000000..ac4407aa Binary files /dev/null and b/static/icons/icon-48-white.png differ