diff --git a/frontend/src/routes/settings/+page.svelte b/frontend/src/routes/settings/+page.svelte index 4f58c4c5..be00f65d 100644 --- a/frontend/src/routes/settings/+page.svelte +++ b/frontend/src/routes/settings/+page.svelte @@ -11,7 +11,7 @@ // Ensure settings are properly loaded on component mount onMount(async () => { try { - const response = await fetch('/api/settings'); + const response = await HuntarrUtils.fetchWithTimeout('/api/settings'); if (response.ok) { const data = await response.json(); settings.set(ensureNumericValues(data)); @@ -23,7 +23,7 @@ async function loadSettings() { try { - const response = await fetch('/api/settings'); + const response = await HuntarrUtils.fetchWithTimeout('/api/settings'); if (response.ok) { const data = await response.json(); // Ensure all numeric values are properly handled @@ -73,7 +73,7 @@ try { const settingsValue = $settings; - const response = await fetch('/api/settings', { + const response = await HuntarrUtils.fetchWithTimeout('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/frontend/static/js/apps.js b/frontend/static/js/apps.js index 5294d27e..907278f5 100644 --- a/frontend/static/js/apps.js +++ b/frontend/static/js/apps.js @@ -223,7 +223,7 @@ const appsModule = { appPanel.innerHTML = '
Loading settings...
'; // Fetch settings for this app - fetch(`/api/settings/${app}`) + HuntarrUtils.fetchWithTimeout(`/api/settings/${app}`) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); @@ -588,7 +588,7 @@ const appsModule = { // Send settings to the server console.log(`Sending ${appType} settings to server...`); - fetch(`/api/settings/${appType}`, { + HuntarrUtils.fetchWithTimeout(`/api/settings/${appType}`, { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/frontend/static/js/apps/eros.js b/frontend/static/js/apps/eros.js index 6331a07f..b89946b7 100644 --- a/frontend/static/js/apps/eros.js +++ b/frontend/static/js/apps/eros.js @@ -164,7 +164,7 @@ function getErosVersion() { */ function refreshErosStatusAndVersion() { // Try to get current connection status from the server - fetch('/api/eros/status') + HuntarrUtils.fetchWithTimeout('/api/eros/status') .then(response => response.json()) .then(data => { const panel = document.getElementById('erosSettings'); diff --git a/frontend/static/js/community-resources.js b/frontend/static/js/community-resources.js index 3495f55c..199b1ab3 100644 --- a/frontend/static/js/community-resources.js +++ b/frontend/static/js/community-resources.js @@ -27,7 +27,7 @@ function initCommunityResourcesVisibility() { } // Fetch general settings to determine visibility - fetch('/api/settings/general') + HuntarrUtils.fetchWithTimeout('/api/settings/general') .then(response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); diff --git a/frontend/static/js/direct-reset.js b/frontend/static/js/direct-reset.js index c87fda06..94dfcb0c 100644 --- a/frontend/static/js/direct-reset.js +++ b/frontend/static/js/direct-reset.js @@ -53,7 +53,7 @@ window.lastStatefulHoursValue = null; window.justCompletedStatefulReset = true; // Make direct API call - fetch('/api/stateful/reset', { + HuntarrUtils.fetchWithTimeout('/api/stateful/reset', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/frontend/static/js/history.js b/frontend/static/js/history.js index 830d0041..4404c668 100644 --- a/frontend/static/js/history.js +++ b/frontend/static/js/history.js @@ -177,7 +177,7 @@ const historyModule = { url += `&search=${encodeURIComponent(this.searchQuery)}`; } - fetch(url) + HuntarrUtils.fetchWithTimeout(url) .then(response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); @@ -201,7 +201,7 @@ const historyModule = { clearHistory: function() { this.setLoading(true); - fetch(`/api/history/${this.currentApp}`, { + HuntarrUtils.fetchWithTimeout(`/api/history/${this.currentApp}`, { method: 'DELETE', }) .then(response => { diff --git a/frontend/static/js/hourly-cap.js b/frontend/static/js/hourly-cap.js index f210c58a..048265fc 100644 --- a/frontend/static/js/hourly-cap.js +++ b/frontend/static/js/hourly-cap.js @@ -15,7 +15,7 @@ document.addEventListener('DOMContentLoaded', function() { * Load hourly API cap data from the server */ function loadHourlyCapData() { - fetch('/api/hourly-caps') + HuntarrUtils.fetchWithTimeout('/api/hourly-caps') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); diff --git a/frontend/static/js/new-main.js b/frontend/static/js/new-main.js index 80e65582..0540a48a 100644 --- a/frontend/static/js/new-main.js +++ b/frontend/static/js/new-main.js @@ -30,7 +30,7 @@ let huntarrUI = { suppressUnsavedChangesCheck: false, // Flag to suppress unsaved changes dialog // Logo URL - logoUrl: '/static/logo/256.png', + logoUrl: './static/logo/256.png', // Element references elements: {}, @@ -869,7 +869,7 @@ let huntarrUI = { try { // Append the app type to the URL - const eventSource = new EventSource(`/logs?app=${appType}`); + const eventSource = new EventSource(`./logs?app=${appType}`); eventSource.onopen = () => { this.elements.logConnectionStatus.textContent = 'Connected'; diff --git a/frontend/static/js/new-user.js b/frontend/static/js/new-user.js index 0adbd5d4..33340b8a 100644 --- a/frontend/static/js/new-user.js +++ b/frontend/static/js/new-user.js @@ -82,7 +82,7 @@ return; } - fetch('/api/user/change-username', { + HuntarrUtils.fetchWithTimeout('/api/user/change-username', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -133,7 +133,7 @@ return; } - fetch('/api/user/change-password', { + HuntarrUtils.fetchWithTimeout('/api/user/change-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -161,7 +161,7 @@ // 2FA setup handler function handleEnableTwoFactor() { - fetch('/api/user/2fa/setup', { method: 'POST' }) + HuntarrUtils.fetchWithTimeout('/api/user/2fa/setup', { method: 'POST' }) .then(response => response.json()) .then(data => { if (data.success) { @@ -200,7 +200,7 @@ return; } - fetch('/api/user/2fa/verify', { + HuntarrUtils.fetchWithTimeout('/api/user/2fa/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: code }) @@ -240,7 +240,7 @@ return; } - fetch('/api/user/2fa/disable', { + HuntarrUtils.fetchWithTimeout('/api/user/2fa/disable', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -293,7 +293,7 @@ // Function to fetch user information function fetchUserInfo() { - fetch('/api/user/info') + HuntarrUtils.fetchWithTimeout('/api/user/info') .then(response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); diff --git a/frontend/static/js/reset-stateful.js b/frontend/static/js/reset-stateful.js index e999184d..95385d0f 100644 --- a/frontend/static/js/reset-stateful.js +++ b/frontend/static/js/reset-stateful.js @@ -51,7 +51,7 @@ this.innerHTML = ' Resetting...'; // Make API call - fetch('/api/stateful/reset', { + HuntarrUtils.fetchWithTimeout('/api/stateful/reset', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/frontend/static/js/scheduling.js b/frontend/static/js/scheduling.js index 483ce7bf..81548266 100644 --- a/frontend/static/js/scheduling.js +++ b/frontend/static/js/scheduling.js @@ -161,7 +161,7 @@ async function fetchAppInstances() { const listUrl = `/api/scheduling/list?nocache=${cacheBuster}`; console.debug(`Loading app instances from ${listUrl}`); - const response = await fetch(listUrl); + const response = await HuntarrUtils.fetchWithTimeout(listUrl); if (response.ok) { const data = await response.json(); @@ -320,7 +320,7 @@ function loadSchedules() { console.debug('Loading schedules from server'); // DEBUG level per user preference // Make API call to get schedules - fetch('/api/scheduler/load') + HuntarrUtils.fetchWithTimeout('/api/scheduler/load') .then(response => { if (!response.ok) { throw new Error('Failed to load schedules'); @@ -463,7 +463,7 @@ function saveSchedules() { console.debug('Saving processed schedules:', schedulesCopy); // Make API call to save schedules - fetch('/api/scheduler/save', { + HuntarrUtils.fetchWithTimeout('/api/scheduler/save', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/frontend/static/js/settings_forms.js b/frontend/static/js/settings_forms.js index 9c094658..8e9b61cb 100644 --- a/frontend/static/js/settings_forms.js +++ b/frontend/static/js/settings_forms.js @@ -908,7 +908,7 @@ const SettingsForms = { const resetStrikesBtn = container.querySelector('#reset_swaparr_strikes'); const statusContainer = container.querySelector('#swaparr_status'); - fetch('/api/swaparr/status') + HuntarrUtils.fetchWithTimeout('/api/swaparr/status') .then(response => response.json()) .then(data => { let statusHTML = ''; @@ -944,7 +944,7 @@ const SettingsForms = { if (confirm('Are you sure you want to reset all Swaparr strikes? This will clear the strike history for all apps.')) { statusContainer.innerHTML = '

Resetting strikes...

'; - fetch('/api/swaparr/reset', { + HuntarrUtils.fetchWithTimeout('/api/swaparr/reset', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -957,7 +957,7 @@ const SettingsForms = { statusContainer.innerHTML = `

Success: ${data.message}

`; // Reload status after a short delay setTimeout(() => { - fetch('/api/swaparr/status') + HuntarrUtils.fetchWithTimeout('/api/swaparr/status') .then(response => response.json()) .then(data => { let statusHTML = ''; @@ -1473,7 +1473,7 @@ const SettingsForms = { } } - fetch('/api/stateful/info', { + HuntarrUtils.fetchWithTimeout('/api/stateful/info', { cache: 'no-cache', headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', @@ -1550,7 +1550,7 @@ const SettingsForms = { // Helper function to fetch data silently without updating UI function fetchStatefulInfoSilently() { - fetch('/api/stateful/info', { + HuntarrUtils.fetchWithTimeout('/api/stateful/info', { cache: 'no-cache', headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', @@ -1665,7 +1665,7 @@ const SettingsForms = { button.disabled = true; // Make the API request - fetch(`/api/${appType}/test-connection`, { + HuntarrUtils.fetchWithTimeout(`/api/${appType}/test-connection`, { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -1950,7 +1950,7 @@ const SettingsForms = { } // Make the API request - fetch(`/api/${app}/test-connection`, { + HuntarrUtils.fetchWithTimeout(`/api/${app}/test-connection`, { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/frontend/static/js/stats-reset.js b/frontend/static/js/stats-reset.js index 21f9907d..662f0dc1 100644 --- a/frontend/static/js/stats-reset.js +++ b/frontend/static/js/stats-reset.js @@ -61,7 +61,7 @@ function resetStatsAPI(appType = null) { const requestBody = appType ? { app_type: appType } : {}; // Use the public endpoint that doesn't require authentication - return fetch('/api/stats/reset_public', { + return HuntarrUtils.fetchWithTimeout('/api/stats/reset_public', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/frontend/static/js/theme-preload.js b/frontend/static/js/theme-preload.js index 92befe1c..01e33ed3 100644 --- a/frontend/static/js/theme-preload.js +++ b/frontend/static/js/theme-preload.js @@ -1,6 +1,6 @@ (function() { // Store logo URL consistently across the app - use local path instead of GitHub - const LOGO_URL = '/static/logo/256.png'; + const LOGO_URL = './static/logo/256.png'; // Create and preload image with local path const preloadImg = new Image(); @@ -56,8 +56,8 @@ img.onerror = function() { // Fallback if local path fails console.warn('Logo failed to load, trying alternate source'); - if (this.src !== '/logo/256.png') { - this.src = '/logo/256.png'; + if (this.src !== './logo/256.png') { + this.src = './logo/256.png'; } }; } diff --git a/frontend/static/js/user.js b/frontend/static/js/user.js index 8670b971..5e21431a 100644 --- a/frontend/static/js/user.js +++ b/frontend/static/js/user.js @@ -14,7 +14,7 @@ document.addEventListener('DOMContentLoaded', function() { // Function to load user information function loadUserInfo() { - fetch('/api/user/info') + HuntarrUtils.fetchWithTimeout('/api/user/info') .then(response => response.json()) .then(data => { if (data.username) { @@ -27,7 +27,7 @@ document.addEventListener('DOMContentLoaded', function() { // Function to check 2FA status function check2FAStatus() { - fetch('/api/user/2fa-status') + HuntarrUtils.fetchWithTimeout('/api/user/2fa-status') .then(response => response.json()) .then(data => { const enable2FACheckbox = document.getElementById('enable2FA'); diff --git a/frontend/templates/base.html b/frontend/templates/base.html index c971f1aa..38d96e93 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -4,24 +4,28 @@ My App - + + + + + {% include 'components/scripts.html' %} - - - - - - - + + + + + + + - - - - - + + + + + \ No newline at end of file diff --git a/frontend/templates/components/cleanuperr_section.html b/frontend/templates/components/cleanuperr_section.html index d2e76434..c2e693ea 100644 --- a/frontend/templates/components/cleanuperr_section.html +++ b/frontend/templates/components/cleanuperr_section.html @@ -12,7 +12,7 @@

Cleanuperr by Flaminel

@@ -392,7 +392,7 @@ // Load GitHub star count for Cleanuperr function loadCleanuperrStarCount() { - fetch('https://api.github.com/repos/flmorg/cleanuperr') + HuntarrUtils.fetchWithTimeout('https://api.github.com/repos/flmorg/cleanuperr') .then(response => { if (!response.ok) { // Handle rate limiting or other errors diff --git a/frontend/templates/components/head.html b/frontend/templates/components/head.html index 90d8f43a..7136bfaf 100644 --- a/frontend/templates/components/head.html +++ b/frontend/templates/components/head.html @@ -1,21 +1,16 @@ - + - - - - + + - - - - - + + + + + - - - - - - - - - + + + + + + + + + - - + +
- +

Sonarr

@@ -367,7 +367,7 @@
- +

Radarr

@@ -399,7 +399,7 @@
- +

Lidarr

@@ -431,7 +431,7 @@
- +

Readarr

@@ -463,7 +463,7 @@
- +

Whisparr

@@ -495,7 +495,7 @@
- +

Whisparr V3

@@ -1772,7 +1772,7 @@ document.addEventListener('DOMContentLoaded', function() { // Fetch sponsors from the API async function fetchSponsors() { try { - const response = await fetch('/api/github_sponsors'); + const response = await HuntarrUtils.fetchWithTimeout('/api/github_sponsors'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } diff --git a/frontend/templates/components/scripts.html b/frontend/templates/components/scripts.html index 1c41331e..9d2134d6 100644 --- a/frontend/templates/components/scripts.html +++ b/frontend/templates/components/scripts.html @@ -1,8 +1,8 @@ - - - - - - - + + + + + + + diff --git a/frontend/templates/components/sidebar.html b/frontend/templates/components/sidebar.html index d43d27d7..788e1f59 100644 --- a/frontend/templates/components/sidebar.html +++ b/frontend/templates/components/sidebar.html @@ -1,8 +1,8 @@