From 6c7809f853aa910a5f81f6535848af594eb4b947 Mon Sep 17 00:00:00 2001 From: Ashhhleyyy Date: Fri, 23 Feb 2024 15:12:24 +0000 Subject: [PATCH] feat(extension): autofill support --- extension/src/ash.css | 37 +++++++++++++++++ extension/src/background.js | 11 ++++- extension/src/content.js | 37 +++++++++++++++++ extension/src/popup.js | 81 ++++++++++++++++++++++++++++++------- 4 files changed, 151 insertions(+), 15 deletions(-) diff --git a/extension/src/ash.css b/extension/src/ash.css index 0c5b72a..ee452a7 100644 --- a/extension/src/ash.css +++ b/extension/src/ash.css @@ -8,6 +8,8 @@ --error: orange; --accent: #f9027a; --accent-dim: hsl(331, 50%, 49%); + --confirm: #82f1b1; + --warning: #fb7185; } body { @@ -252,3 +254,38 @@ td.code-bad { font-weight: 900; font-size: 2em; } + +.button-container { + position: fixed; + bottom: 0; + left: 0; + display: flex; + flex-direction: row; + width: 100%; + gap: 8px; + padding: 8px; +} + +.button-container .button { + flex: 1; +} + +.button { + border: none; + padding: 8px; + border-radius: 8px; + cursor: pointer; + text-decoration: none; + font-size: initial; + color: black; + transition: filter 200ms ease; + vertical-align: middle; +} + +.button.confirm { + background-color: var(--confirm); +} + +.button.warning { + background-color: var(--warning); +} diff --git a/extension/src/background.js b/extension/src/background.js index c9f20a9..bdd52e5 100644 --- a/extension/src/background.js +++ b/extension/src/background.js @@ -88,10 +88,19 @@ function interceptCode(details) { } } -function handleMessage(message) { +function handleMessage(message, sender) { if (message['type'] === 'link-activity-details') { const { activityId, date, time, name, space } = message; attachActivityDetails(activityId, date, time, name, space); + } else if (message['type'] === 'create-popup') { + const create = message['create']; + create.url += '&tabId=' + sender.tab.id; + browser.windows.create(create); + } else if (message['type'] === 'autofill-code') { + browser.tabs.sendMessage(message['tabId'], { + type: 'autofill-code', + code: message['code'], + }); } else { console.warn('recieved unknown message:', message); } diff --git a/extension/src/content.js b/extension/src/content.js index 462677b..ca2832a 100644 --- a/extension/src/content.js +++ b/extension/src/content.js @@ -8,6 +8,7 @@ console.log('hello'); const time = section.querySelector('.row:nth-child(1) > .col-md-4').innerText; const name = section.querySelector('.row:nth-child(2) > .col-md-4').innerText; const space = section.querySelector('.row:nth-child(4) > .col-md-4').innerText; + browser.runtime.sendMessage({ type: 'link-activity-details', activityId, @@ -16,5 +17,41 @@ console.log('hello'); name, space, }); + + const submitButton = section.querySelector('.selfregistration-changestatus'); + submitButton.addEventListener('click', async function(event) { + const params = new URLSearchParams({ + date, + time, + activity: name, + space, + }); + browser.runtime.sendMessage({ + type: 'create-popup', + create: { + url: browser.runtime.getURL('src/popup.html') + '#' + params.toString(), + width: 360, + height: 480, + type: 'popup', + }, + }); + }); } })(); + +function autofillCode(code) { + const input = document.querySelector('#notie-input-field'); + if (input.value === '') { + input.value = code; + } +} + +function handleMessage(message) { + if (message['type'] === 'autofill-code') { + console.log('i am autofill', message); + const { code } = message; + autofillCode(code); + } +} + +browser.runtime.onMessage.addListener(handleMessage); diff --git a/extension/src/popup.js b/extension/src/popup.js index 9676c9b..af404ef 100644 --- a/extension/src/popup.js +++ b/extension/src/popup.js @@ -40,10 +40,39 @@ details.innerHTML += '
'; details.innerHTML += dataRow('Location', activity.space).innerHTML; root.appendChild(details); + activity.codes.sort(code => -code.score); root.appendChild(codeTable(activity.codes)); return root; } + function simpleButton(text, clickHandler, type) { + const button = document.createElement('button'); + button.onclick = clickHandler; + button.classList.add('button'); + button.classList.add(type); + button.innerText = text; + return button; + } + + function submitButtons(code, tabId) { + const buttonContainer = document.createElement('div'); + buttonContainer.classList.add('button-container'); + const cancelButton = simpleButton('Cancel', function() { + window.close(); + }, 'warning'); + const submitButton = simpleButton(`Autofill ${code}`, function () { + browser.runtime.sendMessage({ + type: 'autofill-code', + code, + tabId, + }); + window.close(); + }, 'confirm'); + buttonContainer.appendChild(cancelButton); + buttonContainer.appendChild(submitButton); + return buttonContainer; + } + function message(message, error = false) { const ele = document.createElement('p'); if (error) { @@ -57,21 +86,45 @@ root.appendChild(ele); } - const res = await fetch(SERVER_URL + '/api/codes').catch((e) => { - message(`Something went wrong: ` + e); - console.error(e); - }); - if (!res.ok) { - message('Server returned error code ' + res.status + ': ' + res.statusText, true); - return; - } - const { activities } = await res.json(); - if (activities.length === 0) { - message('No codes are available right now :/'); - } else { - activities.sort(activity => activity.time); - for (const activity of activities) { + if (window.location.hash.length >= 2) { + const query = window.location.hash.substring(1); + const queryParams = new URLSearchParams(query); + const res = await fetch(SERVER_URL + '/api/codes/query?' + query).catch((e) => { + message(`Something went wrong: ${e}`); + console.error(e); + }); + if (!res.ok) { + message('Server returned error code ' + res.status + ': ' + res.statusText, true); + return; + } + const activity = await res.json(); + if (activity.codes.length === 0) { + message('No codes are available right now :/'); + } else { root.appendChild(activityEle(activity)); + + const topCode = activity.codes[0]; + if (topCode.score >= -1) { + root.appendChild(submitButtons(topCode.code, parseInt(queryParams.get('tabId')))); + } + } + } else { + const res = await fetch(SERVER_URL + '/api/codes').catch((e) => { + message(`Something went wrong: ${e}`); + console.error(e); + }); + if (!res.ok) { + message('Server returned error code ' + res.status + ': ' + res.statusText, true); + return; + } + const { activities } = await res.json(); + if (activities.length === 0) { + message('No codes are available right now :/'); + } else { + activities.sort(activity => activity.time); + for (const activity of activities) { + root.appendChild(activityEle(activity)); + } } } })();