improve ux, moved functionality for better ui experience on app and extension.

This commit is contained in:
Bryan Van Deusen
2026-01-26 11:38:51 -05:00
parent 74b1ecf2cf
commit 2a0e37a73d
12 changed files with 369 additions and 78 deletions
+34 -4
View File
@@ -6,18 +6,41 @@
let discordToken = null;
let discordTokenCapturedAt = null;
// Track initialization state
let initialized = false;
/**
* Ensure extension is initialized
*/
async function ensureInitialized() {
if (!initialized) {
console.log('Initializing extension...');
try {
await api.init();
await loadDiscordToken();
initialized = true;
console.log('Extension initialized successfully');
} catch (error) {
console.error('Failed to initialize extension:', error);
throw error;
}
}
}
// Initialize API on startup
browser.runtime.onInstalled.addListener(async () => {
console.log('GallerySubscriber extension installed');
await api.init();
await loadDiscordToken();
await ensureInitialized();
});
browser.runtime.onStartup.addListener(async () => {
await api.init();
await loadDiscordToken();
console.log('GallerySubscriber extension startup');
await ensureInitialized();
});
// Also initialize immediately in case background wakes up from idle
ensureInitialized().catch(err => console.error('Initial init failed:', err));
/**
* Load Discord token from storage
*/
@@ -88,6 +111,13 @@ browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
* @returns {Promise<object>} - Response data
*/
async function handleMessage(message) {
console.log('Handling message:', message.type);
// Ensure initialized for operations that need it
if (['EXPORT_COOKIES', 'EXPORT_ALL_COOKIES', 'GET_PLATFORM_STATUS', 'TEST_CONNECTION'].includes(message.type)) {
await ensureInitialized();
}
switch (message.type) {
case 'EXPORT_COOKIES':
return await exportCookies(message.platform);
+6
View File
@@ -302,6 +302,12 @@ body {
color: var(--alert-warning-text);
}
.alert-error {
background: var(--status-error-bg);
border: 1px solid var(--status-error-border);
color: var(--status-error-text);
}
.status-message {
padding: 10px 12px;
border-radius: 6px;
+86 -17
View File
@@ -3,38 +3,107 @@
*/
document.addEventListener('DOMContentLoaded', async () => {
await init();
try {
await init();
} catch (error) {
console.error('Popup init error:', error);
// Show error in UI
document.getElementById('setup-required').classList.remove('hidden');
const alertDiv = document.querySelector('#setup-required .alert');
if (alertDiv) {
alertDiv.innerHTML = `<strong>Error</strong><p>${error.message}</p>`;
alertDiv.className = 'alert alert-error';
}
}
});
// Rate limit connection tests (max once per 2 minutes)
const CONNECTION_TEST_INTERVAL = 2 * 60 * 1000; // 2 minutes
/**
* Initialize the popup
*/
async function init() {
// Check configuration
const config = await browser.runtime.sendMessage({ type: 'GET_CONFIG' });
console.log('Popup initializing...');
if (!config.apiUrl || !config.apiKey) {
// Check configuration (this is fast - just reads from storage)
let config;
try {
config = await browser.runtime.sendMessage({ type: 'GET_CONFIG' });
console.log('Got config:', config);
} catch (error) {
console.error('Failed to get config:', error);
throw new Error(`Failed to communicate with background script: ${error.message}`);
}
if (!config || !config.apiUrl || !config.apiKey) {
console.log('Config missing, showing setup');
showSetupRequired();
return;
}
// Test connection
const connectionStatus = await browser.runtime.sendMessage({ type: 'TEST_CONNECTION' });
updateConnectionIndicator(connectionStatus.connected);
// Show main content
// Show main content IMMEDIATELY - don't wait for connection test or platform status
document.getElementById('setup-required').classList.add('hidden');
document.getElementById('main-content').classList.remove('hidden');
if (!connectionStatus.connected) {
showError(`Cannot connect to backend: ${connectionStatus.error}`);
}
// Load platform status
await loadPlatformStatus();
// Setup event listeners
// Setup event listeners right away
setupEventListeners();
// Show loading state for platforms
const platformsContainer = document.getElementById('platforms-list');
platformsContainer.innerHTML = '<div style="text-align: center; padding: 20px; color: var(--text-secondary);">Loading platforms...</div>';
// Now do background tasks in parallel (non-blocking)
// Check if we should test connection (rate limited)
testConnectionIfNeeded();
// Load platform status (this can take time)
loadPlatformStatus().catch(error => {
console.error('Failed to load platform status:', error);
showError(`Failed to load platforms: ${error.message}`);
});
}
/**
* Test connection only if enough time has passed since last test
*/
async function testConnectionIfNeeded() {
try {
// Check last test time from storage
const stored = await browser.storage.local.get(['lastConnectionTest', 'lastConnectionStatus']);
const now = Date.now();
const lastTest = stored.lastConnectionTest || 0;
// Use cached status if recent
if (now - lastTest < CONNECTION_TEST_INTERVAL && stored.lastConnectionStatus !== undefined) {
console.log('Using cached connection status');
updateConnectionIndicator(stored.lastConnectionStatus);
if (!stored.lastConnectionStatus) {
showError('Cannot connect to backend (cached status)');
}
return;
}
// Test connection in background
console.log('Testing connection...');
const connectionStatus = await browser.runtime.sendMessage({ type: 'TEST_CONNECTION' });
console.log('Connection status:', connectionStatus);
// Cache the result
await browser.storage.local.set({
lastConnectionTest: now,
lastConnectionStatus: connectionStatus.connected
});
updateConnectionIndicator(connectionStatus.connected);
if (!connectionStatus.connected) {
showError(`Cannot connect to backend: ${connectionStatus.error}`);
}
} catch (error) {
console.error('Failed to test connection:', error);
updateConnectionIndicator(false);
}
}
/**