diff --git a/.eslintrc.json b/.eslintrc.json
index 5d1307c..8661b65 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -19,7 +19,7 @@
"computed-property-spacing": ["error", "never"],
"consistent-return": "error",
"consistent-this": "off",
- "curly": "error",
+ "curly": "off",
"default-case": "error",
"dot-location": ["error", "property"],
"dot-notation": "error",
diff --git a/src/auth.js b/src/auth.js
new file mode 100644
index 0000000..f92b0fa
--- /dev/null
+++ b/src/auth.js
@@ -0,0 +1,66 @@
+window.logout = function logout() {
+ firebase.auth().signOut();
+};
+function login(providerName) {
+ var provider;
+ if (providerName === 'fb') {
+ provider = new firebase.auth.FacebookAuthProvider();
+ } else if (providerName === 'twitter') {
+ provider = new firebase.auth.TwitterAuthProvider();
+ } else if (providerName === 'google') {
+ provider = new firebase.auth.GoogleAuthProvider();
+ provider.addScope('https://www.googleapis.com/auth/userinfo.profile');
+ } else {
+ provider = new firebase.auth.GithubAuthProvider();
+ }
+
+ return firebase
+ .auth()
+ .signInWithPopup(provider)
+ .then(function(result) {
+ return;
+ // Save this user in the store
+ firebase
+ .database()
+ .ref('users/' + result.user.uid)
+ .update({
+ displayName: result.user.displayName,
+ email: result.user.email,
+ photoURL: result.user.providerData[0].photoURL,
+ signedUpOn: Date.now()
+ })
+ .then(function() {
+ // Port items in localstorage to user account
+ if (window.localStorage.prototyp) {
+ var items = JSON.parse(window.localStorage.prototyp);
+ var newItemKey;
+ items.forEach(function(localItem) {
+ itemService.fetchItem(localItem.id).then(function(item) {
+ newItemKey = firebase.database().ref('pens').push().key;
+ item.createdBy = result.user.uid;
+ delete item.uid;
+ firebase.database().ref('pens/' + newItemKey).set(item);
+ firebase
+ .database()
+ .ref('users/' + result.user.uid)
+ .child('items')
+ .child(newItemKey)
+ .set(true);
+ });
+ });
+ delete localStorage.prototyp;
+ }
+ });
+ })
+ .catch(function(error) {
+ // Handle Errors here.
+ var errorCode = error.code;
+ var errorMessage = error.message;
+ // The email of the user's account used.
+ var email = error.email;
+ // The firebase.auth.AuthCredential type that was used.
+ var credential = error.credential;
+ console.log(error);
+ });
+}
+window.login = login;
diff --git a/src/db.js b/src/db.js
index 1afd0a9..d8e3a0d 100644
--- a/src/db.js
+++ b/src/db.js
@@ -86,7 +86,7 @@
// Not critical right now.
}
- async function setUserLastSeenVersion(user, version) {
+ async function setUserLastSeenVersion(version) {
if (window.IS_EXTENSION) {
chrome.storage.sync.set(
{
@@ -99,17 +99,22 @@
// Settings the lastSeenVersion in localStorage also because next time we need
// to fetch it irrespective of the user being logged in or out
local.set({ lastSeenVersion: version });
- if (user) {
+ if (window.user) {
const remoteDb = await getDb();
- remoteDb.doc(`users/${user.uid}`).update({ lastSeenVersion: version });
+ remoteDb
+ .doc(`users/${window.user.uid}`)
+ .update({ lastSeenVersion: version });
}
}
async function getUser(userId) {
const remoteDb = await getDb();
return remoteDb.doc(`users/${userId}`).get().then(doc => {
+ if (!doc.exists)
+ return remoteDb.doc(`users/${userId}`).set({}, { merge: true });
const user = doc.data();
Object.assign(window.user, user);
+ return user;
});
}
diff --git a/src/index.html b/src/index.html
index eb21056..52b5ef4 100644
--- a/src/index.html
+++ b/src/index.html
@@ -73,8 +73,14 @@
Open
-
-
+
+ Login/Signup
+
+
+ Logout
+
+
+
@@ -318,6 +324,10 @@
+
+
@@ -591,6 +601,7 @@
+
diff --git a/src/itemService.js b/src/itemService.js
index 053fcea..9d0828a 100644
--- a/src/itemService.js
+++ b/src/itemService.js
@@ -7,13 +7,16 @@
});
},
async getUserItemIds() {
- if (window.user && window.user.items) {
+ if (window.user) {
return new Promise(resolve => {
- resolve(window.user.items);
+ resolve(window.user.items || {});
});
}
var remoteDb = await window.db.getDb();
return remoteDb.doc(`users/${window.user.uid}`).get().then(doc => {
+ if (!doc.exists) {
+ return {};
+ }
return doc.data().items;
});
},
@@ -51,6 +54,9 @@
},
async setItem(id, item) {
+ if (!window.user) {
+ return new Promise(resolve => resolve());
+ }
var remoteDb = await window.db.getDb();
console.log(`Starting to save item ${id}`);
item.createdBy = window.user.uid;
@@ -130,7 +136,7 @@
},
async setItemForUser(itemId) {
- if (window.IS_EXTENSION) {
+ if (window.IS_EXTENSION || !window.user) {
return window.db.local.get(
{
items: {}
@@ -152,6 +158,8 @@
})
.then(arg => {
console.log(`Item ${itemId} set for user`, arg);
+ window.user.items = window.user.items || {};
+ window.user.items[itemId] = true;
})
.catch(error => console.log(error));
},
diff --git a/src/script.js b/src/script.js
index a9357ab..d4e1ca1 100644
--- a/src/script.js
+++ b/src/script.js
@@ -7,7 +7,8 @@ onboardModal, settingsModal, notificationsBtn, onboardShowInTabOptionBtn, editor
onboardDontShowInTabOptionBtn, TextareaAutoComplete, savedItemCountEl, indentationSizeValueEl,
runBtn, searchInput, consoleEl, consoleLogEl, logCountEl, fontStyleTag, fontStyleTemplate,
customEditorFontInput, cssSettingsModal, cssSettingsBtn, acssSettingsTextarea,
-globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
+globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal, headerAvatarImg,
+loginModal
*/
/* eslint-disable no-extra-semi */
(function(alertsService, itemService) {
@@ -490,7 +491,7 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
var d = deferred();
savedItems = savedItems || {};
var items = [];
- if (!window.IS_EXTENSION) {
+ if (!window.IS_EXTENSION && window.user) {
items = await itemService.getAllItems();
if (shouldSaveGlobally) {
@@ -667,6 +668,7 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
settingsModal.classList.remove('is-modal-visible');
cssSettingsModal.classList.remove('is-modal-visible');
keyboardShortcutsModal.classList.remove('is-modal-visible');
+ loginModal.classList.remove('is-modal-visible');
toggleSavedItemsPane(false);
document.dispatchEvent(new Event('overlaysClosed'));
}
@@ -1094,7 +1096,8 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
}
function createPreviewFile(html, css, js) {
- const shouldInlineJs = !window.webkitRequestFileSystem;
+ const shouldInlineJs =
+ !window.webkitRequestFileSystem || !window.IS_EXTENSION;
var contents = getCompleteHtml(html, css, shouldInlineJs ? js : null);
var blob = new Blob([contents], { type: 'text/plain;charset=UTF-8' });
var blobjs = new Blob([js], { type: 'text/plain;charset=UTF-8' });
@@ -1707,21 +1710,26 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
utils.log(settingName, el.type === 'checkbox' ? el.checked : el.value);
prefs[settingName] = el.type === 'checkbox' ? el.checked : el.value;
obj[settingName] = prefs[settingName];
+
+ // In case of !extension, we save in localstorage so that it gets fetched
+ // faster on future loads.
db.sync.set(obj, function() {
alertsService.add('Setting saved');
});
- window.db.getDb().then(remoteDb => {
- remoteDb
- .collection('users')
- .doc(window.user.uid)
- .update({
- [`settings.${settingName}`]: prefs[settingName]
- })
- .then(arg => {
- console.log(`Setting "${settingName}" for user`, arg);
- })
- .catch(error => console.log(error));
- });
+ if (!window.IS_EXTENSION) {
+ window.db.getDb().then(remoteDb => {
+ remoteDb
+ .collection('users')
+ .doc(window.user.uid)
+ .update({
+ [`settings.${settingName}`]: prefs[settingName]
+ })
+ .then(arg => {
+ console.log(`Setting "${settingName}" for user`, arg);
+ })
+ .catch(error => console.log(error));
+ });
+ }
trackEvent('ui', 'updatePref-' + settingName, prefs[settingName]);
}
@@ -2011,7 +2019,17 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
e.preventDefault();
};
- scope.login = function(e) {
+ scope.updateProfileUi = () => {
+ if (window.user) {
+ document.body.classList.add('is-logged-in');
+ headerAvatarImg.src = window.user.photoURL;
+ } else {
+ document.body.classList.remove('is-logged-in');
+ headerAvatarImg.src = '';
+ }
+ };
+
+ scope.login = e => {
firebase.auth().signInAnonymously().then().catch(function(error) {
// Handle Errors here.
utils.log(error);
@@ -2021,6 +2039,8 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
e.preventDefault();
}
};
+ scope.login = window.login;
+ scope.logout = window.logout;
function init() {
var config = {
@@ -2034,17 +2054,23 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
firebase.initializeApp(config);
firebase.auth().onAuthStateChanged(function(user) {
+ scope.closeAllOverlays();
if (user) {
utils.log('You are -> ', user);
+ alertsService.add('You are now logged in!');
scope.user = window.user = user;
- window.db.getUser(user.uid).then(() => {
- Object.assign(prefs, user.settings);
- updateSettingsInUi();
- scope.updateSetting();
+ window.db.getUser(user.uid).then(customUser => {
+ if (customUser) {
+ Object.assign(prefs, user.settings);
+ updateSettingsInUi();
+ scope.updateSetting();
+ }
});
} else {
+ delete window.user;
// User is signed out.
}
+ scope.updateProfileUi();
});
var lastCode;
@@ -2073,7 +2099,7 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
) {
hasSeenNotifications = true;
notificationsBtn.classList.remove('has-new');
- window.db.setUserLastSeenVersion(window.user.uid, version);
+ window.db.setUserLastSeenVersion(version);
}
trackEvent('ui', 'notificationButtonClick', version);
return false;
@@ -2382,9 +2408,11 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
if (lastCode.id) {
// Ignore for remote db
db.local.get(lastCode.id, function(itemResult) {
- utils.log('Load item ', lastCode.id);
- currentItem = itemResult[lastCode.id];
- refreshEditor();
+ if (itemResult[lastCode.id]) {
+ utils.log('Load item ', lastCode.id);
+ currentItem = itemResult[lastCode.id];
+ refreshEditor();
+ }
});
} else {
utils.log('Load last unsaved item', lastCode);
@@ -2409,7 +2437,7 @@ globalConsoleContainerEl, externalLibrarySearchInput, keyboardShortcutsModal
trackEvent('ui', 'onboardModalSeen', version);
document.cookie = 'onboarded=1';
}
- window.db.setUserLastSeenVersion(window.user, version);
+ window.db.setUserLastSeenVersion(version);
// set some initial preferences on closing the onboard modal
// Old onboarding.
// utils.once(document, 'overlaysClosed', function() {});
diff --git a/src/style.css b/src/style.css
index 94f89ab..8f429a6 100644
--- a/src/style.css
+++ b/src/style.css
@@ -959,6 +959,11 @@ transition: 0.25s ease;
display: inline-block;
}
+body.is-logged-in .hide-on-login,
+body:not(.is-logged-in) .hide-on-logout {
+ display: none;
+}
+
/* Codemirror themes basic bg styles. This is here so that there is no big FOUC
while the theme CSS file is loading */
.cm-s-paraiso-dark.CodeMirror { background: #2f1e2e; color: #b9b6b0; }