« get me outta code hell

Upload/delete tracks - interactive-bgm - Browser extension that adds background music based on the site you're browsing
about summary refs log tree commit diff
path: root/extension
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2019-03-23 12:05:04 -0300
committerFlorrie <towerofnix@gmail.com>2019-03-23 12:05:04 -0300
commit213ef476d5aa27e3590754da52ff1e8c0b48cc38 (patch)
treef87f5ad7e20a9b6d7ba4c5ea38b6e4639f92b57e /extension
parent29e9b65926ee3062f7490e247dd7971e9de23a52 (diff)
Upload/delete tracks
Diffstat (limited to 'extension')
-rw-r--r--extension/background.js83
-rw-r--r--extension/interactive-bgm.js121
-rw-r--r--extension/manifest.json1
-rw-r--r--extension/popup/main.js58
4 files changed, 193 insertions, 70 deletions
diff --git a/extension/background.js b/extension/background.js
index eedbb73..c450c9d 100644
--- a/extension/background.js
+++ b/extension/background.js
@@ -2,44 +2,69 @@ console.log('Start');
 
 const port = browser.runtime.connectNative('interactive_bgm');
 
-browser.browserAction.onClicked.addListener(() => {
-    console.log('Hello??');
-    // port.postMessage('[{"track": "mantis", "volume": 100}]\n');
-});
-
-console.log('Hi', port);
-
 port.postMessage('[{"track": "mantis", "volume": 100}]\n');
 
 port.onMessage.addListener(msg => {
     console.log('Nyoom', msg);
 });
 
-/*
-setTimeout(() => {
-    port.disconnect();
-}, 4000);
-*/
-
 port.onDisconnect.addListener(() => {
     console.log('Disconnected');
 });
 
-browser.runtime.onMessage.addListener(({hostname}) => {
-    browser.storage.sync.get(['siteSettings', 'disableEverywhere'])
-        .then(({siteSettings, disableEverywhere}) => {
-            if (disableEverywhere) {
-                port.postMessage([]);
-                return;
-            }
-
-            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);
-            }
+const uploadCallbacks = {};
+const deleteCallbacks = {};
+
+port.onMessage.addListener(({type, trackName}) => {
+    if (type === 'uploadFinished') {
+        if (uploadCallbacks[trackName]) {
+            uploadCallbacks[trackName]();
+        }
+    } else if (type === 'deleteFinished') {
+        if (deleteCallbacks[trackName]) {
+            deleteCallbacks[trackName]();
+        }
+    }
+});
+
+const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
+
+browser.runtime.onMessage.addListener(async ({hostname, type, base64, trackName}, sender, sendResponse) => {
+    if (hostname) {
+        browser.storage.sync.get(['siteSettings', 'disableEverywhere'])
+            .then(({siteSettings, disableEverywhere}) => {
+                if (disableEverywhere) {
+                    port.postMessage([]);
+                    return;
+                }
+
+                const mode = siteSettings[hostname];
+
+                if (mode) {
+                    port.postMessage(mode.map(track => ({track, volume: 100})));
+                }
+            });
+    } else if (type === 'uploadTrack' && trackName && base64) {
+        port.postMessage({type: 'uploadTrack', trackName, base64});
+        return new Promise(resolve => {
+            uploadCallbacks[trackName] = resolve;
+        }).then(() => {
+            browser.notifications.create({
+                type: 'basic',
+                title: 'Save Complete',
+                message: `Successfully saved track "${trackName}".`
+            });
+        });
+    } else if (type === 'deleteTrack' && trackName) {
+        port.postMessage({type: 'deleteTrack', trackName});
+        return new Promise(resolve => {
+            deleteCallbacks[trackName] = resolve;
+        }).then(() => {
+            browser.notifications.create({
+                type: 'basic',
+                title: 'Delete Complete',
+                message: `Successfully deleted track "${trackName}".`
+            });
         });
+    }
 });
diff --git a/extension/interactive-bgm.js b/extension/interactive-bgm.js
index 032dc19..1d29d06 100644
--- a/extension/interactive-bgm.js
+++ b/extension/interactive-bgm.js
@@ -1,3 +1,124 @@
 window.addEventListener('focus', () => {
     browser.runtime.sendMessage({hostname: location.hostname});
 });
+
+let hasShownCreateTrack = false;
+
+browser.runtime.onMessage.addListener(({createTrack}) => {
+    if (createTrack) {
+        if (hasShownCreateTrack) {
+            return;
+        }
+
+        hasShownCreateTrack = true;
+
+        const container = document.createElement('div')
+        document.body.appendChild(container);
+
+        Object.assign(container.style, {
+            all: 'initial',
+            position: 'fixed',
+            left: '0',
+            top: '0',
+            width: '100%',
+            height: '100%',
+            padding: '10px',
+            boxSizing: 'border-box',
+            zIndex: '99999999999',
+            display: 'flex',
+            justifyContent: 'center',
+            alignItems: 'center',
+            lineHeight: '2em',
+            fontFamily: 'Helvetica, Arial, sans-serif',
+            backgroundColor: 'rgba(105, 105, 105, 0.5)'
+        });
+
+        const div = document.createElement('div');
+        container.appendChild(div);
+
+        Object.assign(div.style, {
+            width: '50%',
+            height: '50%',
+            padding: '10px',
+            boxSizing: 'border-box',
+            backgroundColor: '#EEEEEE',
+            border: '2px solid black',
+            borderRadius: '4px',
+            boxShadow: '0 0 8px rgba(0, 0, 0, 0.5)',
+            zIndex: '99999999999',
+            minHeight: '120px',
+            minWidth: '200px'
+        });
+
+        const h1 = document.createElement('div');
+        div.appendChild(h1);
+
+        h1.appendChild(document.createTextNode('Create Track'));
+
+        Object.assign(h1.style, {
+            textAlign: 'center',
+            fontWeight: '800',
+            marginBottom: '8px'
+        });
+
+        const form = document.createElement('form');
+        div.appendChild(form);
+
+        const nameLabel = document.createElement('nameLabel');
+        form.appendChild(nameLabel);
+
+        nameLabel.appendChild(document.createTextNode('Name: '));
+
+        const nameInput = document.createElement('input');
+        nameLabel.appendChild(nameInput);
+
+        nameInput.type = 'text';
+        nameInput.required = true;
+
+        form.appendChild(document.createElement('br'));
+
+        const fileLabel = document.createElement('label');
+        form.appendChild(fileLabel);
+
+        fileLabel.appendChild(document.createTextNode('File: '));
+
+        const fileInput = document.createElement('input');
+        fileLabel.appendChild(fileInput);
+
+        fileInput.type = 'file';
+        fileInput.required = true;
+
+        form.appendChild(document.createElement('br'));
+
+        const submitInput = document.createElement('input');
+        form.appendChild(submitInput);
+
+        submitInput.type = 'submit';
+        submitInput.value = 'Save';
+
+        form.addEventListener('submit', event => {
+            event.preventDefault();
+
+            const trackName = nameInput.value;
+
+            const reader = new FileReader();
+            reader.onload = () => {
+                browser.storage.sync.get('tracks').then(({tracks}) => {
+                    browser.storage.sync.set({tracks: tracks.concat([trackName])});
+                });
+
+                const base64 = reader.result.split(',')[1];
+                const mime = reader.result.split(',')[0].split(';')[0];
+
+                browser.runtime.sendMessage({type: 'uploadTrack', base64, trackName}).then(() => {
+                    document.body.removeChild(container);
+                });
+            };
+
+            reader.readAsDataURL(fileInput.files[0]);
+
+            submitInput.value = 'Saving...';
+            submitInput.disabled = true;
+        });
+    }
+});
diff --git a/extension/manifest.json b/extension/manifest.json
index 2562fc9..7dbf537 100644
--- a/extension/manifest.json
+++ b/extension/manifest.json
@@ -8,6 +8,7 @@
     "permissions": [
         "activeTab",
         "nativeMessaging",
+        "notifications",
         "storage",
         "tabs"
     ],
diff --git a/extension/popup/main.js b/extension/popup/main.js
index 6175e36..06aca18 100644
--- a/extension/popup/main.js
+++ b/extension/popup/main.js
@@ -9,7 +9,7 @@ function changeScreen(id) {
 }
 
 function loadTrackList(opts) {
-    const {hostname, siteSettings} = opts;
+    const {tab, hostname, siteSettings} = opts;
     const site = siteSettings[hostname] || [];
     return browser.storage.sync.get('tracks').then(({tracks = []}) => {
         const ul = document.getElementById('track-list');
@@ -67,9 +67,17 @@ function loadTrackList(opts) {
             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'));
+                    tracks = tracks.filter(t => t !== track);
+                    for (const site of Object.values(siteSettings)) {
+                        while (site.includes(track)) {
+                            site.splice(site.indexOf(track, 1));
+                        }
+                    }
+                    Promise.all([
+                        browser.runtime.sendMessage({type: 'deleteTrack', trackName: track}),
+                        browser.storage.sync.set({tracks, siteSettings})
+                            .then(() => loadTrackList(opts))
+                    ]).then(() => changeScreen('main-screen'));
                 }
             });
         }
@@ -85,41 +93,9 @@ function loadTrackList(opts) {
         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();
+            browser.tabs.sendMessage(tab.id, {createTrack: true});
+            window.close();
         });
 
         const disableButton = document.createElement('button');
@@ -161,14 +137,14 @@ Promise.all([
                 .then(() => browser.runtime.sendMessage({hostname}));
         });
 
-        return hostname;
+        return {tab, hostname};
     })(),
     browser.storage.sync.get('siteSettings')
         .then(({siteSettings = {}}) => siteSettings)
 ])
-    .then(([hostname, siteSettings]) => {
+    .then(([{tab, hostname}, siteSettings]) => {
         if (hostname) {
-            return loadTrackList({hostname, siteSettings})
+            return loadTrackList({tab, hostname, siteSettings})
                 .then(() => changeScreen('main-screen'));
         } else {
             changeScreen('invalid-host-screen');