feat: modernize UI with Astro+Svelte and optimize Docker build
- Migrated frontend to Astro + Svelte 5 for cyberpunk aesthetic - Switched to Bun for faster frontend builds - Implemented multi-stage Docker build for smaller image size - Refactored backend to serve static assets and proxy API requests - Added recovery mode for manual file management
This commit is contained in:
parent
985a05858a
commit
aa94920650
62 changed files with 6589 additions and 18 deletions
297
browser-extension/browser-extension-0.4.2/extension/popup.js
Normal file
297
browser-extension/browser-extension-0.4.2/extension/popup.js
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
Loaded into popup index.html
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
let browserType = getBrowser();
|
||||
|
||||
// boilerplate to dedect browser type api
|
||||
function getBrowser() {
|
||||
if (typeof chrome !== 'undefined') {
|
||||
if (typeof browser !== 'undefined') {
|
||||
return browser;
|
||||
} else {
|
||||
return chrome;
|
||||
}
|
||||
} else {
|
||||
console.log('failed to detect browser');
|
||||
throw 'browser detection error';
|
||||
}
|
||||
}
|
||||
|
||||
async function sendMessage(message) {
|
||||
let { success, value } = await browserType.runtime.sendMessage(message);
|
||||
if (!success) {
|
||||
throw value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
let errorOut = document.getElementById('error-out');
|
||||
function setError(message) {
|
||||
errorOut.style.display = 'initial';
|
||||
errorOut.innerText = message;
|
||||
}
|
||||
|
||||
function clearError() {
|
||||
errorOut.style.display = 'none';
|
||||
}
|
||||
|
||||
function clearTempLocalStorage() {
|
||||
browserType.storage.local.remove('popupApiKey');
|
||||
browserType.storage.local.remove('popupFullUrl');
|
||||
}
|
||||
|
||||
// store access details
|
||||
document.getElementById('save-login').addEventListener('click', function () {
|
||||
let url = document.getElementById('full-url').value;
|
||||
if (!url.includes('://')) {
|
||||
url = 'http://' + url;
|
||||
}
|
||||
try {
|
||||
clearError();
|
||||
let parsed = new URL(url);
|
||||
let toStore = {
|
||||
access: {
|
||||
url: `${parsed.protocol}//${parsed.hostname}`,
|
||||
port: parsed.port || (parsed.protocol === 'https:' ? '443' : '80'),
|
||||
apiKey: document.getElementById('api-key').value,
|
||||
},
|
||||
};
|
||||
browserType.storage.local.set(toStore, function () {
|
||||
console.log('Stored connection details: ' + JSON.stringify(toStore));
|
||||
pingBackend();
|
||||
});
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
}
|
||||
});
|
||||
|
||||
// verify connection status
|
||||
document.getElementById('status-icon').addEventListener('click', function () {
|
||||
pingBackend();
|
||||
});
|
||||
|
||||
// send cookie
|
||||
document.getElementById('sendCookies').addEventListener('click', function () {
|
||||
sendCookie();
|
||||
});
|
||||
|
||||
// show cookies
|
||||
document.getElementById('showCookies').addEventListener('click', function () {
|
||||
showCookies();
|
||||
});
|
||||
|
||||
// continuous sync
|
||||
document.getElementById('continuous-sync').addEventListener('click', function () {
|
||||
toggleContinuousSync();
|
||||
});
|
||||
|
||||
// autostart
|
||||
document.getElementById('autostart').addEventListener('click', function () {
|
||||
toggleAutostart();
|
||||
});
|
||||
|
||||
let fullUrlInput = document.getElementById('full-url');
|
||||
fullUrlInput.addEventListener('change', () => {
|
||||
browserType.storage.local.set({
|
||||
popupFullUrl: fullUrlInput.value,
|
||||
});
|
||||
});
|
||||
|
||||
let apiKeyInput = document.getElementById('api-key');
|
||||
apiKeyInput.addEventListener('change', () => {
|
||||
browserType.storage.local.set({
|
||||
popupApiKey: apiKeyInput.value,
|
||||
});
|
||||
});
|
||||
|
||||
function sendCookie() {
|
||||
console.log('popup send cookie');
|
||||
clearError();
|
||||
|
||||
function handleResponse(message) {
|
||||
console.log('handle cookie response: ' + JSON.stringify(message));
|
||||
let validattionMessage = `enabled, last verified ${message.validated_str}`;
|
||||
document.getElementById('sendCookiesStatus').innerText = validattionMessage;
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
console.log(`Error: ${error}`);
|
||||
setError(error);
|
||||
}
|
||||
|
||||
let sending = sendMessage({ type: 'sendCookie' });
|
||||
sending.then(handleResponse, handleError);
|
||||
}
|
||||
|
||||
function showCookies() {
|
||||
console.log('popup show cookies');
|
||||
const textArea = document.getElementById('cookieLinesResponse');
|
||||
|
||||
function handleResponse(message) {
|
||||
textArea.value = message.join('\n');
|
||||
textArea.style.display = 'initial';
|
||||
}
|
||||
function handleError(error) {
|
||||
console.log(`Error: ${error}`);
|
||||
}
|
||||
|
||||
if (textArea.value) {
|
||||
textArea.value = '';
|
||||
textArea.style.display = 'none';
|
||||
document.getElementById('showCookies').textContent = 'Show Cookie';
|
||||
} else {
|
||||
let sending = sendMessage({ type: 'getCookieLines' });
|
||||
sending.then(handleResponse, handleError);
|
||||
document.getElementById('showCookies').textContent = 'Hide Cookie';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleContinuousSync() {
|
||||
const checked = document.getElementById('continuous-sync').checked;
|
||||
let toStore = {
|
||||
continuousSync: {
|
||||
checked: checked,
|
||||
},
|
||||
};
|
||||
browserType.storage.local.set(toStore, function () {
|
||||
console.log('stored option: ' + JSON.stringify(toStore));
|
||||
});
|
||||
sendMessage({ type: 'continuousSync', checked });
|
||||
}
|
||||
|
||||
function toggleAutostart() {
|
||||
let checked = document.getElementById('autostart').checked;
|
||||
let toStore = {
|
||||
autostart: {
|
||||
checked: checked,
|
||||
},
|
||||
};
|
||||
browserType.storage.local.set(toStore, function () {
|
||||
console.log('stored option: ' + JSON.stringify(toStore));
|
||||
});
|
||||
}
|
||||
|
||||
// send ping message to TA backend
|
||||
async function pingBackend() {
|
||||
clearError();
|
||||
clearTempLocalStorage();
|
||||
function handleResponse() {
|
||||
console.log('connection validated');
|
||||
setStatusIcon(true);
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
console.log(`Verify got error: ${error}`);
|
||||
setStatusIcon(false);
|
||||
setError(error);
|
||||
}
|
||||
|
||||
console.log('ping TA server');
|
||||
let sending = sendMessage({ type: 'verify' });
|
||||
sending.then(handleResponse, handleError);
|
||||
}
|
||||
|
||||
// add url to image
|
||||
function addUrl(access) {
|
||||
const url = `${access.url}:${access.port}`;
|
||||
document.getElementById('ta-url').setAttribute('href', url);
|
||||
}
|
||||
|
||||
function setCookieState() {
|
||||
clearError();
|
||||
function handleResponse(message) {
|
||||
console.log(message);
|
||||
if (!message.cookie_enabled) {
|
||||
document.getElementById('sendCookiesStatus').innerText = 'disabled';
|
||||
} else {
|
||||
let validattionMessage = 'enabled';
|
||||
if (message.validated_str) {
|
||||
validattionMessage += `, last verified ${message.validated_str}`;
|
||||
}
|
||||
document.getElementById('sendCookiesStatus').innerText = validattionMessage;
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
console.log(`Error: ${error}`);
|
||||
setError(error);
|
||||
}
|
||||
|
||||
console.log('set cookie state');
|
||||
let sending = sendMessage({ type: 'cookieState' });
|
||||
sending.then(handleResponse, handleError);
|
||||
document.getElementById('sendCookies').checked = true;
|
||||
}
|
||||
|
||||
// change status icon based on connection status
|
||||
function setStatusIcon(connected) {
|
||||
let statusIcon = document.getElementById('status-icon');
|
||||
if (connected) {
|
||||
statusIcon.innerHTML = '☑';
|
||||
statusIcon.style.color = 'green';
|
||||
} else {
|
||||
statusIcon.innerHTML = '☒';
|
||||
statusIcon.style.color = 'red';
|
||||
}
|
||||
}
|
||||
|
||||
// fill in form
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
async function onGot(item) {
|
||||
if (!item.access) {
|
||||
console.log('no access details found');
|
||||
if (item.popupFullUrl != null && fullUrlInput.value === '') {
|
||||
fullUrlInput.value = item.popupFullUrl;
|
||||
}
|
||||
if (item.popupApiKey != null && apiKeyInput.value === '') {
|
||||
apiKeyInput.value = item.popupApiKey;
|
||||
}
|
||||
setStatusIcon(false);
|
||||
return;
|
||||
}
|
||||
let { url, port } = item.access;
|
||||
let fullUrl = url;
|
||||
if (!(url.startsWith('http://') && port === '80')) {
|
||||
fullUrl += `:${port}`;
|
||||
}
|
||||
document.getElementById('full-url').value = fullUrl;
|
||||
document.getElementById('api-key').value = item.access.apiKey;
|
||||
pingBackend();
|
||||
addUrl(item.access);
|
||||
setCookieState();
|
||||
}
|
||||
|
||||
async function setContinuousCookiesOptions(result) {
|
||||
if (!result.continuousSync || result.continuousSync.checked === false) {
|
||||
console.log('continuous cookie sync not set');
|
||||
return;
|
||||
}
|
||||
console.log('set options: ' + JSON.stringify(result));
|
||||
document.getElementById('continuous-sync').checked = true;
|
||||
}
|
||||
|
||||
async function setAutostartOption(result) {
|
||||
console.log(result);
|
||||
if (!result.autostart || result.autostart.checked === false) {
|
||||
console.log('autostart not set');
|
||||
return;
|
||||
}
|
||||
console.log('set options: ' + JSON.stringify(result));
|
||||
document.getElementById('autostart').checked = true;
|
||||
}
|
||||
|
||||
browserType.storage.local.get(['access', 'popupFullUrl', 'popupApiKey'], function (result) {
|
||||
onGot(result);
|
||||
});
|
||||
|
||||
browserType.storage.local.get('continuousSync', function (result) {
|
||||
setContinuousCookiesOptions(result);
|
||||
});
|
||||
|
||||
browserType.storage.local.get('autostart', function (result) {
|
||||
setAutostartOption(result);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue