From 217cc4ad84b47bd661f5a6e9d05eecefe62663f5 Mon Sep 17 00:00:00 2001 From: Guusvanmeerveld Date: Wed, 4 Aug 2021 17:32:36 +0200 Subject: [PATCH] New options page --- package.json | 2 +- src/background.js | 27 ------- src/builder/builders.js | 4 +- src/builder/index.js | 20 +---- src/builder/options.js | 25 ++++++ src/builder/watch.js | 6 ++ src/events.js | 45 +++++++++++ src/login.js | 5 +- src/manifest.json | 2 +- src/pages/account.html | 71 +++++++++++++++++ src/pages/options.html | 25 ++++-- src/pages/scripts/accounts.js | 105 ++++++++++++++++++++++++-- src/pages/scripts/add-account.js | 40 ++++++++++ src/pages/scripts/constants.js | 1 + src/pages/scripts/dark-mode-button.js | 18 +++++ src/pages/scripts/dark-mode.js | 23 +----- src/save.js | 77 ------------------- src/stylesheets/account.sass | 18 +++++ src/stylesheets/dark-mode-button.sass | 0 src/stylesheets/dark-mode.sass | 32 +++++++- src/stylesheets/globals.sass | 2 + src/stylesheets/options.sass | 26 +++++++ src/stylesheets/popup.sass | 14 ---- 23 files changed, 413 insertions(+), 175 deletions(-) delete mode 100644 src/background.js create mode 100644 src/builder/options.js create mode 100644 src/events.js create mode 100644 src/pages/scripts/add-account.js create mode 100644 src/pages/scripts/dark-mode-button.js delete mode 100644 src/save.js create mode 100644 src/stylesheets/account.sass create mode 100644 src/stylesheets/dark-mode-button.sass create mode 100644 src/stylesheets/globals.sass diff --git a/package.json b/package.json index 040a758..c7aa38f 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "sass": "^1.36.0" }, "scripts": { - "dev": "node src/builder/watch", + "dev": "node src/builder && node src/builder/watch", "build": "node src/builder", "prettify": "prettier --write src" }, diff --git a/src/background.js b/src/background.js deleted file mode 100644 index 1b8f987..0000000 --- a/src/background.js +++ /dev/null @@ -1,27 +0,0 @@ -// Runs when the extensions is updated -const updated = (tabId, changeInfo, tab) => { - if (changeInfo.status == 'complete' && tab.active) { - chrome.tabs.executeScript(tab.ib, { - file: 'login.js', - }); - } -}; - -// Run when extensions is installed -const installed = () => { - window.open('@pages/options.html', '_blank'); - - chrome.storage.sync.get('accounts', (accounts) => { - chrome.storage.sync.set({ - enabled: true, - accounts: accounts || [], - }); - }); - - chrome.browserAction.setBadgeText({ - text: 'ON', - }); -}; - -chrome.tabs.onUpdated.addListener(updated); -chrome.runtime.onInstalled.addListener(installed); diff --git a/src/builder/builders.js b/src/builder/builders.js index b1b6ddb..3b7a17d 100644 --- a/src/builder/builders.js +++ b/src/builder/builders.js @@ -57,7 +57,6 @@ const fileBuilder = async (file, outPath, fileType) => { file = file.replace(sassExtension, '.min.css'); } - const path = file.split('/'); const fileName = path[path.length - 1]; @@ -106,13 +105,12 @@ const replaceFileContents = (data) => { Object.keys(config.paths).forEach((key) => { data = data.replace(new RegExp(key, 'g'), '/' + config.paths[key]); }); - } data = data.replace(new RegExp(sassExtension, 'g'), '.min.css'); if (process.env.TARGET_BROWSER != 'chrome') { - data = data.replace(new RegExp('chrome.', 'g'), 'browser.') + data = data.replace(new RegExp('chrome.', 'g'), 'browser.'); } return data; diff --git a/src/builder/index.js b/src/builder/index.js index 3e262aa..2cb5701 100644 --- a/src/builder/index.js +++ b/src/builder/index.js @@ -1,31 +1,15 @@ const { join } = require('path'); -const { program } = require('commander'); - const config = require(join(process.cwd(), 'builder.config.js')); -const validBrowsers = ['chrome', 'firefox', 'edge'] - const srcDir = join(process.cwd(), config.root); const distDir = join(process.cwd(), config.out); const { builder } = require('./builders'); -program - .option(`-t, --target <${validBrowsers.join(' | ')}>`, 'set the target browser') - -program.parse(process.argv); - -const options = program.opts(); - -const target = options.target.toLowerCase() || 'chrome' - -if (!validBrowsers.includes(target)) { - console.log('Error: invalid target browser, please specify one of the following: ' + validBrowsers.join(', ')); - process.exit(); -} +const { target } = require('./options'); -process.env.TARGET_BROWSER = target; +target(); if (config.interpreter) { config.interpreter.forEach((interpreter) => { diff --git a/src/builder/options.js b/src/builder/options.js new file mode 100644 index 0000000..73ec4bb --- /dev/null +++ b/src/builder/options.js @@ -0,0 +1,25 @@ +const { program } = require('commander'); + +const validBrowsers = ['chrome', 'firefox', 'edge']; + +const target = () => { + program.option(`-t, --target <${validBrowsers.join(' | ')}>`, 'set the target browser'); + + program.parse(process.argv); + + const options = program.opts(); + + const target = (options.target || 'chrome').toLowerCase(); + + if (!validBrowsers.includes(target)) { + console.log( + 'error: invalid target browser, please specify one of the following: ' + + validBrowsers.join(', ') + ); + process.exit(); + } + + process.env.TARGET_BROWSER = target; +}; + +module.exports = { target }; diff --git a/src/builder/watch.js b/src/builder/watch.js index 14dcca2..6a6cb05 100644 --- a/src/builder/watch.js +++ b/src/builder/watch.js @@ -12,8 +12,14 @@ const watcher = chokidar.watch(srcDir, { persistent: true, }); +const { target } = require('./options'); + +target(); + // Check for changes in the src directory watcher.on('change', async (path) => { + console.clear(); + const relativePath = path.replace(srcDir + '/', ''); const splittedPath = relativePath.split('/'); diff --git a/src/events.js b/src/events.js new file mode 100644 index 0000000..a22c99d --- /dev/null +++ b/src/events.js @@ -0,0 +1,45 @@ +/** + * Runs when the extensions is updated + * @param {string} tabId + * @param {*} changeInfo + * @param {*} tab + */ +const updated = (tabId, changeInfo, tab) => { + if (changeInfo.status == 'complete' && tab.active) { + chrome.tabs.executeScript(tab.ib, { + file: 'login.js', + }); + } +}; + +/** + * Run when extensions is installed + */ +const installed = () => { + window.open('@pages/options.html', '_blank'); + + getAccounts((accounts) => { + chrome.storage.sync.set( + { + enabled: true, + accounts: accounts || [], + }, + () => getAccounts(console.log) + ); + }); + + chrome.browserAction.setBadgeText({ + text: 'ON', + }); +}; + +/** + * Get the all the accounts that are currently added + * @param {() => void} callback + */ +const getAccounts = (callback) => { + chrome.storage.sync.get('accounts', ({ accounts }) => callback(accounts)); +}; + +chrome.tabs.onUpdated.addListener(updated); +chrome.runtime.onInstalled.addListener(installed); diff --git a/src/login.js b/src/login.js index 2ee9f78..0049da1 100644 --- a/src/login.js +++ b/src/login.js @@ -1,8 +1,7 @@ const $ = document.querySelector.bind(document); -const getSettings = (callback) => { - chrome.storage.sync.get(['school', 'number', 'password'], callback); -}; +const getSettings = (callback) => + chrome.storage.sync.get('accounts', ({ current, accounts }) => callback(accounts[current])); const login = () => { getSettings(async ({ school, number, password }) => { diff --git a/src/manifest.json b/src/manifest.json index 408e32c..6fb804c 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -6,7 +6,7 @@ "options_page": "@pages/options.html", "homepage_url": "http://mb-o.nl/autologin", "background": { - "scripts": ["/background.js"], + "scripts": ["/events.js"], "persistent": true }, "browser_action": { diff --git a/src/pages/account.html b/src/pages/account.html index e69de29..1872186 100644 --- a/src/pages/account.html +++ b/src/pages/account.html @@ -0,0 +1,71 @@ + + + + + + + + Account toevoegen | Magister Auto-Login + + + + + + + + + + + + +
+
+

Account toe voegen

+ + +
+ + +
+ + + +
+ + + + +
+
+ + + + + + diff --git a/src/pages/options.html b/src/pages/options.html index c2d8422..6ff9265 100644 --- a/src/pages/options.html +++ b/src/pages/options.html @@ -1,21 +1,30 @@ - Options | Magister Auto-Login + + + + + Opties | Magister Auto-Login + - - + + + - +
+ + +
@@ -23,7 +32,12 @@

Magister Auto Login

- Gemaakt door Martijn Oosterhuis & Guus van Meerveld + Gemaakt door Martijn Oosterhuis & + Guus van Meerveld

Accounts

@@ -31,6 +45,7 @@
+ diff --git a/src/pages/scripts/accounts.js b/src/pages/scripts/accounts.js index 66add83..b981fe6 100644 --- a/src/pages/scripts/accounts.js +++ b/src/pages/scripts/accounts.js @@ -1,8 +1,103 @@ -const getAccounts = (accounts) => { - if (accounts.length == 0) { - $('.accounts').innerHTML = 'Je hebt nog geen accounts.'; - return; +const removeAccount = ({ school, username }, onFinished) => { + chrome.storage.sync.get('accounts', ({ accounts }) => { + const newAccounts = accounts.filter( + (account) => !(account.username == username && account.school == school) + ); + + chrome.storage.sync.set({ accounts: newAccounts }, onFinished); + }); +}; + +const makePrimaryAccount = (username, onFinished) => { + chrome.storage.sync.set({ primaryAccount: username }, onFinished); +} + +const createAccountElement = ({ username, school }, primaryAccount) => { + const _account = create('div'); + + _account.id = username; + _account.classList.add('account'); + _account.classList.add('bg-secondary'); + + /** + * Display username + */ + const _name = create('h1'); + + _name.innerHTML = username || 'Onbekend'; + + /** + * Display school + */ + const _school = create('h3'); + + _school.innerHTML = school || 'Geen school'; + + if (primaryAccount != username) { + /** + * A button to remove the account + */ + const _removeButton = create('a'); + + _removeButton.innerHTML = 'Verwijder'; + _removeButton.classList.add('remove-button'); + + _removeButton.addEventListener('click', (e) => { + e.preventDefault(); + + removeAccount({ username, school }, () => location.reload()); + }); + + /** + * Display wether this is the primary account + */ + const _primaryAccount = create('a'); + + _primaryAccount.innerHTML = 'Maak hoofd account'; + _primaryAccount.classList.add('make-primary-account'); + + _primaryAccount.addEventListener('click', (e) => { + e.preventDefault(); + + makePrimaryAccount(username, () => location.reload()); + }) + + _account.appendChild(_primaryAccount); + _account.appendChild(_removeButton); + } else { + + } + + _account.appendChild(_name); + _account.appendChild(_school); + + $('.accounts').appendChild(_account); +}; + +const getSettings = ({ accounts, primaryAccount }) => { + const _addAccountLink = create('a'); + + _addAccountLink.classList.add('button'); + _addAccountLink.href = '@pages/account.html'; + + if (!accounts.length) { + /** + * Display message saying no accounts are added + */ + const _noAccounts = create('p'); + + _noAccounts.innerHTML = 'Je hebt nog geen accounts.'; + + _addAccountLink.innerHTML = 'Voeg er een toe'; + + $('.accounts').appendChild(_noAccounts); + } else { + accounts.forEach((account) => createAccountElement(account, primaryAccount)); + + _addAccountLink.innerHTML = 'Voeg er nog een toe'; } + + $('.accounts').appendChild(_addAccountLink); }; -const accounts = chrome.storage.sync.get('accounts', getAccounts); +const accounts = chrome.storage.sync.get(['accounts', 'primaryAccount'], getSettings); diff --git a/src/pages/scripts/add-account.js b/src/pages/scripts/add-account.js new file mode 100644 index 0000000..0b07b8c --- /dev/null +++ b/src/pages/scripts/add-account.js @@ -0,0 +1,40 @@ +$('#newAccountForm').addEventListener('submit', (e) => { + e.preventDefault(); + + chrome.storage.sync.get('accounts', ({ accounts }) => { + const school = $('#school').value; + const username = $('#username').value; + + if (accounts.find((account) => account.username == username && account.school == school)) { + const _errorMessage = create('p'); + + _errorMessage.innerHTML = 'Account bestaat al.'; + _errorMessage.classList.add('error-message'); + + $('#message').innerHTML = ''; + + $('#message').appendChild(_errorMessage); + + return; + } + + const newAccount = { + school, + username, + password: $('#password').value, + }; + + if (accounts.length == 0 || $('#primaryAccount').checked) { + chrome.storage.sync.set({ primaryAccount: username }); + } + + chrome.storage.sync.set( + { + accounts: [...accounts, newAccount], + }, + () => { + location.href = '@pages/options.html'; + } + ); + }); +}); diff --git a/src/pages/scripts/constants.js b/src/pages/scripts/constants.js index 0ed4b25..1df8781 100644 --- a/src/pages/scripts/constants.js +++ b/src/pages/scripts/constants.js @@ -1 +1,2 @@ const $ = document.querySelector.bind(document); +const create = document.createElement.bind(document); diff --git a/src/pages/scripts/dark-mode-button.js b/src/pages/scripts/dark-mode-button.js new file mode 100644 index 0000000..e73476e --- /dev/null +++ b/src/pages/scripts/dark-mode-button.js @@ -0,0 +1,18 @@ +const toggleDarkMode = () => { + const checked = $('.dark-mode').checked; + + chrome.storage.sync.set({ + 'dark-mode': checked, + }); + + $('#dark-mode-stylesheet').disabled = !checked; +}; + +const initDarkMode = () => + chrome.storage.sync.get('dark-mode', ({ 'dark-mode': usingDarkMode }) => { + $('.dark-mode').checked = usingDarkMode; + }); + +$('.dark-mode').addEventListener('click', toggleDarkMode); + +initDarkMode(); diff --git a/src/pages/scripts/dark-mode.js b/src/pages/scripts/dark-mode.js index 656ffbc..6c08fcd 100644 --- a/src/pages/scripts/dark-mode.js +++ b/src/pages/scripts/dark-mode.js @@ -1,19 +1,4 @@ -const toggleDarkMode = () => { - const checked = $('.dark-mode').checked; - - chrome.storage.sync.set({ - 'dark-mode': checked, - }); - - $('#dark-mode-stylesheet').disabled = !checked; -}; - -const initDarkMode = () => - chrome.storage.sync.get('dark-mode', (usingDarkMode) => { - $('#dark-mode-stylesheet').disabled = !usingDarkMode; - $('.dark-mode').checked = usingDarkMode; - }); - -$('.dark-mode').addEventListener('click', toggleDarkMode); - -initDarkMode(); +chrome.storage.sync.get( + 'dark-mode', + ({ 'dark-mode': usingDarkMode }) => ($('#dark-mode-stylesheet').disabled = !usingDarkMode) +); diff --git a/src/save.js b/src/save.js deleted file mode 100644 index 8614b6e..0000000 --- a/src/save.js +++ /dev/null @@ -1,77 +0,0 @@ -d('save').addEventListener('click', save); - -qAll('.login').forEach((s) => { - s.addEventListener('keydown', (e) => { - if (e.key == 'Enter') { - if (e.target.id == 'school') { - d('number').focus(); - } - if (e.target.id == 'number') { - d('password').focus(); - } - if (e.target.id == 'password') { - save(); - } - } - }); -}); - -function save() { - var school = d('school').value; - var number = d('number').value; - var password = d('password').value; - - try { - chrome.storage.sync.set({ - school: school, - number: number, - password: password, - }); - - d('save').innerHTML = 'Opgeslagen!'; - } catch (e) { - d('save').innerHTML = 'Fout'; - d('save').className = 'btn btn-danger float-right'; - console.error(e); - } -} - -function onLoad() { - chrome.storage.sync.get(['school', 'number', 'password'], function (result) { - if (result.school !== undefined) { - d('school').value = result.school; - } - - if (result.number !== undefined) { - d('number').value = result.number; - } - - if (result.password !== undefined) { - d('password').value = 'lolleukgeprobeerd'; - } - }); - - chrome.storage.sync.get(['enabled'], function (result) { - d('switch').checked = result.enabled; - }); - - chrome.storage.sync.get(['darkmode'], function (result) { - d('dark-mode').checked = result.darkmode; - d('dark-link').disabled = !d('dark-mode').checked; - }); - - d('switch').addEventListener('click', toggle); -} - -function toggle() { - var checked = d('switch').checked; - chrome.storage.sync.set({ - enabled: checked, - }); - - chrome.browserAction.setBadgeText({ - text: checked ? 'ON' : 'OFF', - }); -} - -onLoad(); diff --git a/src/stylesheets/account.sass b/src/stylesheets/account.sass new file mode 100644 index 0000000..e630aaf --- /dev/null +++ b/src/stylesheets/account.sass @@ -0,0 +1,18 @@ +.wrapper + min-height: 100vh + + display: flex + align-items: center + justify-content: center + + .form + width: 100% + +.header + text-align: center + +.error-message + color: red + +.primary-account + margin-right: 1rem diff --git a/src/stylesheets/dark-mode-button.sass b/src/stylesheets/dark-mode-button.sass new file mode 100644 index 0000000..e69de29 diff --git a/src/stylesheets/dark-mode.sass b/src/stylesheets/dark-mode.sass index cbba64e..dbc3bad 100644 --- a/src/stylesheets/dark-mode.sass +++ b/src/stylesheets/dark-mode.sass @@ -1,3 +1,31 @@ +$text: #c5c5c5 +$bg-primary: #282a2d +$bg-secondary: #2d2f31 + +$borders: #373a3d + body - background-color: #282a2d - color: #c5c5c5 + background-color: $bg-primary + color: $text + +input[type='color'], +input[type='date'], +input[type='datetime'], +input[type='datetime-local'], +input[type='email'], +input[type='month'], +input[type='number'], +input[type='password'], +input[type='search'], +input[type='tel'], +input[type='text'], +input[type='url'], +input[type='week'], +input:not([type]), +textarea, +select + border-color: $borders + color: $text + +.bg-secondary + background-color: $bg-secondary diff --git a/src/stylesheets/globals.sass b/src/stylesheets/globals.sass new file mode 100644 index 0000000..e3f57e0 --- /dev/null +++ b/src/stylesheets/globals.sass @@ -0,0 +1,2 @@ +.bg-secondary + background-color: #f3f3f3 diff --git a/src/stylesheets/options.sass b/src/stylesheets/options.sass index 0e65ff3..a4529ca 100644 --- a/src/stylesheets/options.sass +++ b/src/stylesheets/options.sass @@ -1,4 +1,30 @@ .header + margin-top: 7.5rem margin-bottom: 5rem text-align: center + +.account + border-radius: 5px + padding: 2rem + + margin-bottom: 2rem + + position: relative + + a + position: absolute + cursor: pointer + + .remove-button + right: 2rem + bottom: 2rem + + .make-primary-account + right: 2rem + top: 2rem + +.dark-mode-switch + position: absolute + right: 2rem + top: 2rem diff --git a/src/stylesheets/popup.sass b/src/stylesheets/popup.sass index de08363..8b13789 100644 --- a/src/stylesheets/popup.sass +++ b/src/stylesheets/popup.sass @@ -1,15 +1 @@ -body - min-width: 20rem - min-height: 24rem -.darkcheck - position: absolute - margin: 7px - right: 0px - -.enable - position: absolute - bottom: 0 - left: 0 - margin-bottom: 10px - margin-left: 20px