diff options
author | Florrie <towerofnix@gmail.com> | 2019-03-22 21:03:44 -0300 |
---|---|---|
committer | Florrie <towerofnix@gmail.com> | 2019-03-22 21:03:44 -0300 |
commit | 951499dba4ea173ba4c1f08b956e5d558999da45 (patch) | |
tree | 7adae99d03bf9025063637c6fe7f8ea9eb80e759 /extension | |
parent | 3878c62bb16991ba2dab0bf069b0a67ad53d9106 (diff) |
Popup UI
Diffstat (limited to 'extension')
-rw-r--r-- | extension/background.js | 24 | ||||
-rw-r--r-- | extension/manifest.json | 4 | ||||
-rw-r--r-- | extension/popup/index.html | 23 | ||||
-rw-r--r-- | extension/popup/main.js | 162 | ||||
-rw-r--r-- | extension/popup/style.css | 110 |
5 files changed, 307 insertions, 16 deletions
diff --git a/extension/background.js b/extension/background.js index 020a2be..9b7db26 100644 --- a/extension/background.js +++ b/extension/background.js @@ -26,18 +26,14 @@ port.onDisconnect.addListener(() => { }); browser.runtime.onMessage.addListener(({hostname}) => { - const map = { - 'scratch.mit.edu': ['mantis'], - 'stackoverflow.com': ['bass', 'main'], - 'www.youtube.com': [] - }; - - const mode = map[hostname]; - - if (mode) { - console.log('BGM:', mode); - port.postMessage(mode.map(track => ({track, volume: 100}))); - } else { - console.log('No BGM found for ' + location.hostname); - } + browser.storage.sync.get('siteSettings').then(({siteSettings}) => { + const mode = siteSettings[hostname]; + + if (mode) { + console.log('BGM:', mode); + port.postMessage(mode.map(track => ({track, volume: 100}))); + } else { + console.log('No BGM found for ' + hostname); + } + }); }); diff --git a/extension/manifest.json b/extension/manifest.json index 27cafda..d949ee5 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -7,7 +7,9 @@ "permissions": [ "activeTab", - "nativeMessaging" + "nativeMessaging", + "storage", + "tabs" ], "applications": { diff --git a/extension/popup/index.html b/extension/popup/index.html index e6cf5e5..9ddbec4 100644 --- a/extension/popup/index.html +++ b/extension/popup/index.html @@ -1 +1,22 @@ -<p>Nice.</p> +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Interactive BGM</title> + <link rel="stylesheet" href="style.css"> + </head> + <body> + <div class="screen visible" id="loading-screen"> + <p>Loading...</p> + </div> + <div class="screen" id="main-screen"> + <h1 id="hostname"></h1> + <h2>Tracks</h2> + <ul id="track-list"></ul> + </div> + <div class="screen" id="invalid-host-screen"> + <p>Sorry, this page doesn't appear to have a hostname. We can't configure music here.</p> + </div> + <script src="main.js"></script> + </body> +</html> diff --git a/extension/popup/main.js b/extension/popup/main.js new file mode 100644 index 0000000..ad1475a --- /dev/null +++ b/extension/popup/main.js @@ -0,0 +1,162 @@ +function changeScreen(id) { + for (const screen of document.getElementsByClassName('screen')) { + if (screen.id === id) { + screen.classList.add('visible'); + } else { + screen.classList.remove('visible'); + } + } +} + +function loadTrackList(opts) { + const {hostname, siteSettings} = opts; + const site = siteSettings[hostname] || []; + return browser.storage.sync.get('tracks').then(({tracks = []}) => { + const ul = document.getElementById('track-list'); + while (ul.firstChild) { + ul.removeChild(ul.firstChild); + } + + tracks.sort(); + + for (const track of tracks) { + const li = document.createElement('li'); + ul.appendChild(li); + + li.classList.add('track'); + + const label = document.createElement('label'); + li.appendChild(label); + + const checkbox = document.createElement('input'); + label.appendChild(checkbox); + + checkbox.type = 'checkbox'; + checkbox.checked = site.includes(track); + checkbox.title = `Toggles whether the track "${track}" will play when this site is opened.` + + checkbox.addEventListener('click', () => { + if (checkbox.checked) { + if (!site.includes(track)) { + site.push(track); + } + } else { + if (site.includes(track)) { + site.splice(site.indexOf(track), 1); + } + } + + if (!siteSettings[hostname]) { + siteSettings[hostname] = site; + } + + disableButton.style.display = 'inline-block'; + + browser.storage.sync.set({siteSettings}) + .then(() => browser.runtime.sendMessage({hostname})); + }); + + label.appendChild(document.createTextNode(' ' + track)); + + const deleteButton = document.createElement('button'); + li.appendChild(deleteButton); + + deleteButton.appendChild(document.createTextNode('Delete...')); + deleteButton.title = `Deletes the track from all sites. You will be confirmed first.`; + + deleteButton.addEventListener('click', () => { + if (confirm(`This will delete "${track}" from ALL sites - this cannot be undone. Are you sure?`)) { + changeScreen('loading-screen'); + browser.storage.sync.set({tracks: tracks.filter(t => t !== track)}) + .then(() => loadTrackList(opts)) + .then(() => changeScreen('main-screen')); + } + }); + } + + const actionLi = document.createElement('li'); + ul.appendChild(actionLi); + + actionLi.classList.add('action'); + + const addButton = document.createElement('button'); + actionLi.appendChild(addButton); + + addButton.appendChild(document.createTextNode('Create Track')); + addButton.title = `Creates a new track, which will be an option present in all sites.`; + + let newTrackInput = null; + addButton.addEventListener('click', () => { + if (newTrackInput) { + newTrackInput.focus(); + return; + } + + const li = document.createElement('li'); + li.classList.add('track'); + ul.insertBefore(li, actionLi); + + newTrackInput = document.createElement('input'); + li.appendChild(newTrackInput); + + const saveButton = document.createElement('button'); + li.appendChild(saveButton); + + saveButton.appendChild(document.createTextNode('Save')); + + saveButton.addEventListener('click', () => { + while (li.firstChild) { + li.removeChild(li.firstChild); + } + li.appendChild(document.createTextNode('Saving...')); + + const name = newTrackInput.value.trim(); + if (name.length) { + changeScreen('loading-screen'); + browser.storage.sync.set({tracks: tracks.concat([name])}) + .then(() => loadTrackList(opts)) + .then(() => changeScreen('main-screen')); + } + }); + + newTrackInput.focus(); + }); + + const disableButton = document.createElement('button'); + actionLi.appendChild(disableButton); + + disableButton.appendChild(document.createTextNode('Disable Site')); + disableButton.title = `Removes the entry for this site altogether. It won't change BGM when you open it again.`; + + disableButton.addEventListener('click', () => { + changeScreen('loading-screen'); + delete siteSettings[hostname]; + browser.storage.sync.set({siteSettings}) + .then(() => loadTrackList(opts)) + .then(() => changeScreen('main-screen')); + }); + + if (!(hostname in siteSettings)) { + disableButton.style.display = 'none'; + } + }); +} + +Promise.all([ + browser.tabs.query({active: true, currentWindow: true}) + .then(([tab]) => { + const url = new URL(tab.url); + document.getElementById('hostname').appendChild(document.createTextNode(url.hostname)); + return url.hostname; + }), + browser.storage.sync.get('siteSettings') + .then(({siteSettings = {}}) => siteSettings) +]) + .then(([hostname, siteSettings]) => { + if (hostname) { + return loadTrackList({hostname, siteSettings}) + .then(() => changeScreen('main-screen')); + } else { + changeScreen('invalid-host-screen'); + } + }); diff --git a/extension/popup/style.css b/extension/popup/style.css new file mode 100644 index 0000000..147a94e --- /dev/null +++ b/extension/popup/style.css @@ -0,0 +1,110 @@ +body, html { + width: 100%; + height: 100%; + padding: 0; + margin: 0; + min-width: 300px; + max-width: 400px; +} + +body { + background-color: #EEEEEE; + color: black; + font-family: Helvetica, Arial, sans-serif; +} + +label { + font-weight: 800; +} + +input[type=checkbox] { + width: 13px; + height: 13px; + padding: 0; + margin: 0; + position: relative; + top: 1px; +} + +input, button { + margin-right: 4px; + margin-left: 4px; +} + +ul { + margin: 4px 0; +} + +li { + padding: 3px; +} + +li:nth-child(even) { + background-color: white; +} + +li:nth-child(odd) { + background-color: #DDDDDD; +} + +h1 { + margin: 2px 0; + font-size: 1.2em; + text-align: center; +} + +h2 { + font-size: 0.9em; + margin: 2px 0; + text-align: center; + overflow: hidden; +} + +h2:before, h2:after { + background-color: black; + content: ''; + display: inline-block; + height: 1px; + position: relative; + vertical-align: middle; + width: 50%; +} + +h2:before { + right: 0.5em; + margin-left: -50%; +} + +h2:after { + left: 0.5em; + margin-right: -50%; +} + +.screen { + width: 100%; + height: 100%; + padding: 5px; + box-sizing: border-box; +} + +.screen:not(.visible) { + display: none; +} + +#loading-screen p, #invalid-host-screen { + text-align: center; + font-style: oblique; +} + +#track-list { + list-style: none; + padding-left: 0; +} + +#track-list li.track button { + float: right; +} + +#track-list li.action { + text-align: center; +} |