Add SDB Audio Extractor extension with options and popup UI
- Implemented manifest.json for extension configuration - Created options.html and options.js for user settings management - Developed popup.html and popup.js for audio extraction functionality - Added icons for the extension (icon16.png, icon48.png) - Integrated API token and base URL configuration with validation - Implemented audio extraction from YouTube videos with error handling
This commit is contained in:
124
options.js
Normal file
124
options.js
Normal file
@@ -0,0 +1,124 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const form = document.getElementById('options-form');
|
||||
const apiTokenInput = document.getElementById('api-token');
|
||||
const apiBaseUrlInput = document.getElementById('api-base-url');
|
||||
const saveBtn = document.getElementById('save-btn');
|
||||
const testBtn = document.getElementById('test-btn');
|
||||
const status = document.getElementById('status');
|
||||
|
||||
// Load saved settings
|
||||
const result = await chrome.storage.sync.get(['apiToken', 'apiBaseUrl']);
|
||||
if (result.apiToken) {
|
||||
apiTokenInput.value = result.apiToken;
|
||||
}
|
||||
if (result.apiBaseUrl) {
|
||||
apiBaseUrlInput.value = result.apiBaseUrl;
|
||||
} else {
|
||||
apiBaseUrlInput.value = 'http://192-168-100-199.sslip.io';
|
||||
}
|
||||
|
||||
// Save settings
|
||||
form.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const apiToken = apiTokenInput.value.trim();
|
||||
const apiBaseUrl = apiBaseUrlInput.value.trim() || 'http://192-168-100-199.sslip.io';
|
||||
|
||||
if (!apiToken) {
|
||||
showStatus('Please enter an API token', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
saveBtn.disabled = true;
|
||||
saveBtn.textContent = 'Saving...';
|
||||
|
||||
try {
|
||||
await chrome.storage.sync.set({
|
||||
apiToken: apiToken,
|
||||
apiBaseUrl: apiBaseUrl
|
||||
});
|
||||
|
||||
showStatus('Settings saved successfully!', 'success');
|
||||
|
||||
// Auto-test connection after saving
|
||||
setTimeout(testConnection, 1000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error saving settings:', error);
|
||||
showStatus('Failed to save settings', 'error');
|
||||
} finally {
|
||||
saveBtn.disabled = false;
|
||||
saveBtn.textContent = 'Save Settings';
|
||||
}
|
||||
});
|
||||
|
||||
// Test connection
|
||||
testBtn.addEventListener('click', testConnection);
|
||||
|
||||
async function testConnection() {
|
||||
const apiToken = apiTokenInput.value.trim();
|
||||
const apiBaseUrl = apiBaseUrlInput.value.trim() || 'http://192-168-100-199.sslip.io';
|
||||
|
||||
if (!apiToken) {
|
||||
showStatus('Please enter an API token first', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
testBtn.disabled = true;
|
||||
testBtn.textContent = 'Testing...';
|
||||
showStatus('Testing connection...', 'loading');
|
||||
|
||||
try {
|
||||
// Test with health endpoint first
|
||||
const healthResponse = await fetch(`${apiBaseUrl}/api/v1/health`, {
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
if (!healthResponse.ok) {
|
||||
throw new Error(`Health check failed: HTTP ${healthResponse.status}`);
|
||||
}
|
||||
|
||||
// Test authentication with a simple API call
|
||||
const authResponse = await fetch(`${apiBaseUrl}/api/v1/extractions/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiToken}`
|
||||
}
|
||||
});
|
||||
|
||||
if (authResponse.status === 401) {
|
||||
throw new Error('Invalid API token - authentication failed');
|
||||
} else if (authResponse.status === 403) {
|
||||
throw new Error('API token does not have required permissions');
|
||||
} else if (!authResponse.ok) {
|
||||
throw new Error(`API test failed: HTTP ${authResponse.status}`);
|
||||
}
|
||||
|
||||
showStatus('✅ Connection successful! Your settings are working correctly.', 'success');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Connection test error:', error);
|
||||
|
||||
if (error.message.includes('fetch')) {
|
||||
showStatus('❌ Cannot connect to API server. Check if the backend is running and the URL is correct.', 'error');
|
||||
} else {
|
||||
showStatus(`❌ Connection failed: ${error.message}`, 'error');
|
||||
}
|
||||
} finally {
|
||||
testBtn.disabled = false;
|
||||
testBtn.textContent = 'Test Connection';
|
||||
}
|
||||
}
|
||||
|
||||
function showStatus(message, type) {
|
||||
status.textContent = message;
|
||||
status.className = `status ${type}`;
|
||||
status.classList.remove('hidden');
|
||||
|
||||
if (type === 'success') {
|
||||
setTimeout(() => {
|
||||
status.classList.add('hidden');
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user