Skip to content

Commit b4eaba5

Browse files
committed
Added internet connection checks
1 parent eb68ace commit b4eaba5

8 files changed

Lines changed: 337 additions & 6 deletions

File tree

changelog.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
11
# Changelog
22
**All dates are in YYYY/MM/DD (Year-Month-Day)**
33

4-
## [1.5.1] - 2025-01-02
4+
## [1.5.2] - 2025-06-07
5+
6+
### Added
7+
- **Internet Connectivity Monitoring**: Comprehensive online/offline detection system to ensure proper app functionality
8+
- Real-time connectivity checking with Google ping using 5-second timeout HTTPS requests
9+
- Visual connectivity indicator that appears when offline with slide-down animation
10+
- Smart retry system: automatic checks every 10 seconds when online, auto-retry every 30 seconds when offline
11+
- Manual "Retry Connection" button with loading states for immediate connectivity testing
12+
- Red banner notification system with clear "No Internet Connection" messaging
13+
- **Enhanced User Experience**: Proactive connectivity management for transcription reliability
14+
- Prevents failed transcription attempts by ensuring internet availability upfront
15+
- Real-time status updates through event-driven IPC communication
16+
- Responsive UI feedback with smooth animations and hover effects
17+
- App lifecycle integration - starts connectivity checking on launch, stops on quit
18+
19+
### Technical
20+
- **Backend Connectivity System**: Added comprehensive internet checking infrastructure in main.js
21+
- `checkInternetConnectivity()` function with Google ping and timeout handling
22+
- `handleConnectivityChange()` for state management and renderer notifications
23+
- `startConnectivityChecking()` and `startConnectivityRetryInterval()` for automated monitoring
24+
- New IPC handlers: `retry-connectivity-check` and `get-connectivity-status`
25+
- **Frontend Integration**: Extended app.js with connectivity management
26+
- `setupConnectivityManagement()` method for event handling and UI updates
27+
- `handleConnectivityChange()` for dynamic indicator visibility control
28+
- Manual retry functionality with loading state management
29+
- **UI Components**: Added connectivity indicator to index.html with professional styling
30+
- Red gradient banner with Wi-Fi icon and retry button
31+
- CSS animations and responsive design in styles.css
32+
- Loading spinner for manual retry operations
33+
- **IPC Communication**: Enhanced preload.js with connectivity API exposure
34+
- `retryConnectivityCheck` and `getConnectivityStatus` methods
35+
- `onConnectivityStatus` event listener for real-time updates
36+
37+
## [1.5.1] - 2025-06-07
538

639
### Added
740
- **Platform-Specific UI Optimization**: Enhanced interface for Windows and Linux users

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "autocaption",
3-
"version": "1.5.1",
3+
"version": "1.5.2",
44
"description": "Automatic caption generation app using OpenAI Whisper",
55
"main": "src/main.js",
66
"scripts": {

src/app.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class AutoCaptionApp {
1616
this.setupApiKeyLoadListener();
1717
this.setupThemeSystem();
1818
this.setupPlatformDetection();
19+
this.setupConnectivityManagement();
1920
this.loadSettings();
2021
this.checkOnboardingStatus();
2122
}
@@ -61,6 +62,14 @@ class AutoCaptionApp {
6162
this.openSettings();
6263
});
6364
}
65+
66+
// Listen for connectivity status changes
67+
if (window.electronAPI && window.electronAPI.onConnectivityStatus) {
68+
window.electronAPI.onConnectivityStatus((event, status) => {
69+
console.log('[DEBUG] Connectivity status changed:', status.isOnline);
70+
this.handleConnectivityChange(status.isOnline);
71+
});
72+
}
6473
}
6574

6675
setupThemeSystem() {
@@ -90,6 +99,65 @@ class AutoCaptionApp {
9099
}
91100
}
92101

102+
async setupConnectivityManagement() {
103+
// Set up retry button
104+
const retryBtn = document.getElementById('retry-connection-btn');
105+
const retryText = document.getElementById('retry-connection-text');
106+
const retrySpinner = document.getElementById('retry-connection-spinner');
107+
108+
if (retryBtn) {
109+
retryBtn.addEventListener('click', async () => {
110+
console.log('[DEBUG] Manual connectivity retry requested');
111+
112+
// Show loading state
113+
retryText.style.display = 'none';
114+
retrySpinner.style.display = 'inline-block';
115+
retryBtn.disabled = true;
116+
117+
try {
118+
const result = await window.electronAPI.retryConnectivityCheck();
119+
console.log('[DEBUG] Connectivity retry result:', result);
120+
121+
if (result.success && result.isOnline) {
122+
// Connection restored, indicator will be hidden by connectivity change handler
123+
this.handleConnectivityChange(true);
124+
}
125+
} catch (error) {
126+
console.error('Error during connectivity retry:', error);
127+
} finally {
128+
// Reset button state
129+
retryText.style.display = 'inline';
130+
retrySpinner.style.display = 'none';
131+
retryBtn.disabled = false;
132+
}
133+
});
134+
}
135+
136+
// Check initial connectivity status
137+
try {
138+
const result = await window.electronAPI.getConnectivityStatus();
139+
if (result.success) {
140+
this.handleConnectivityChange(result.isOnline);
141+
}
142+
} catch (error) {
143+
console.error('Error getting initial connectivity status:', error);
144+
}
145+
}
146+
147+
handleConnectivityChange(isOnline) {
148+
const connectivityIndicator = document.getElementById('connectivity-indicator');
149+
150+
if (isOnline) {
151+
// Hide connectivity indicator when online
152+
connectivityIndicator.style.display = 'none';
153+
console.log('[DEBUG] Internet connection restored');
154+
} else {
155+
// Show connectivity indicator when offline
156+
connectivityIndicator.style.display = 'block';
157+
console.log('[DEBUG] Internet connection lost');
158+
}
159+
}
160+
93161
handleTitleBarVisibility(platform) {
94162
const titleBar = document.querySelector('.title-bar');
95163
const container = document.querySelector('.container');

src/index.html

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,21 @@ <h4>Quick Start:</h4>
228228
<h1>AutoCaption</h1>
229229
<p>Generate professional captions for your videos.</p>
230230
</div>
231+
232+
<!-- Connectivity Indicator -->
233+
<div id="connectivity-indicator" class="connectivity-indicator" style="display: none;">
234+
<div class="connectivity-content">
235+
<div class="connectivity-icon">🌐</div>
236+
<div class="connectivity-text">
237+
<h3>No Internet Connection</h3>
238+
<p>Please check your internet connection to use AutoCaption's AI transcription features.</p>
239+
</div>
240+
<button id="retry-connection-btn" class="btn btn-primary">
241+
<span id="retry-connection-text">🔄 Retry Connection</span>
242+
<div id="retry-connection-spinner" class="spinner" style="display: none;"></div>
243+
</button>
244+
</div>
245+
</div>
231246
</header>
232247

233248
<main>
@@ -291,7 +306,7 @@ <h3>🔄 Updates</h3>
291306
<div class="setting-group">
292307
<h3>ℹ️ About</h3>
293308
<div class="setting-item">
294-
<p><strong>Version:</strong> 1.5.1</p>
309+
<p><strong>Version:</strong> 1.5.2</p>
295310
<p><strong>Made with ❤️ by Jay</strong></p>
296311
<p>Using OpenAI Whisper for AI-powered transcription</p>
297312
</div>

src/main.js

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,115 @@ const OpenAI = require('openai');
66
const https = require('https');
77
const ffmpeg = require('fluent-ffmpeg');
88

9+
// Internet connectivity checking
10+
let isOnline = true;
11+
let connectivityCheckInterval;
12+
let connectivityRetryInterval;
13+
const CONNECTIVITY_CHECK_INTERVAL = 10000; // 10 seconds
14+
const CONNECTIVITY_RETRY_INTERVAL = 30000; // 30 seconds when offline
15+
const CONNECTIVITY_TIMEOUT = 5000; // 5 seconds timeout
16+
17+
// Check internet connectivity by trying to reach Google
18+
function checkInternetConnectivity() {
19+
return new Promise((resolve) => {
20+
const request = https.request({
21+
hostname: 'google.com',
22+
port: 443,
23+
path: '/',
24+
method: 'HEAD',
25+
timeout: CONNECTIVITY_TIMEOUT
26+
}, (res) => {
27+
resolve(true);
28+
});
29+
30+
request.on('error', () => {
31+
resolve(false);
32+
});
33+
34+
request.on('timeout', () => {
35+
request.destroy();
36+
resolve(false);
37+
});
38+
39+
request.setTimeout(CONNECTIVITY_TIMEOUT);
40+
request.end();
41+
});
42+
}
43+
44+
// Handle connectivity state changes
45+
async function handleConnectivityChange(online) {
46+
const wasOnline = isOnline;
47+
isOnline = online;
48+
49+
logger.info(`Connectivity status changed: ${online ? 'online' : 'offline'}`);
50+
51+
if (mainWindow) {
52+
mainWindow.webContents.send('connectivity-status', { isOnline: online });
53+
}
54+
55+
// If we just went offline, start more frequent retry checking
56+
if (wasOnline && !online) {
57+
logger.info('Device went offline, starting retry interval');
58+
startConnectivityRetryInterval();
59+
}
60+
// If we just came back online, stop retry checking and resume normal checking
61+
else if (!wasOnline && online) {
62+
logger.info('Device came back online, stopping retry interval');
63+
stopConnectivityRetryInterval();
64+
}
65+
}
66+
67+
// Start normal connectivity checking (every 10 seconds)
68+
function startConnectivityChecking() {
69+
logger.info('Starting connectivity checking');
70+
71+
// Initial check
72+
checkInternetConnectivity().then(handleConnectivityChange);
73+
74+
// Set up regular checking
75+
connectivityCheckInterval = setInterval(async () => {
76+
if (isOnline) { // Only do regular checks when we think we're online
77+
const online = await checkInternetConnectivity();
78+
if (online !== isOnline) {
79+
await handleConnectivityChange(online);
80+
}
81+
}
82+
}, CONNECTIVITY_CHECK_INTERVAL);
83+
}
84+
85+
// Start aggressive retry checking (every 30 seconds when offline)
86+
function startConnectivityRetryInterval() {
87+
if (connectivityRetryInterval) {
88+
clearInterval(connectivityRetryInterval);
89+
}
90+
91+
connectivityRetryInterval = setInterval(async () => {
92+
logger.debug('Retry connectivity check (offline state)');
93+
const online = await checkInternetConnectivity();
94+
if (online !== isOnline) {
95+
await handleConnectivityChange(online);
96+
}
97+
}, CONNECTIVITY_RETRY_INTERVAL);
98+
}
99+
100+
// Stop retry checking
101+
function stopConnectivityRetryInterval() {
102+
if (connectivityRetryInterval) {
103+
clearInterval(connectivityRetryInterval);
104+
connectivityRetryInterval = null;
105+
}
106+
}
107+
108+
// Stop all connectivity checking
109+
function stopConnectivityChecking() {
110+
logger.info('Stopping connectivity checking');
111+
if (connectivityCheckInterval) {
112+
clearInterval(connectivityCheckInterval);
113+
connectivityCheckInterval = null;
114+
}
115+
stopConnectivityRetryInterval();
116+
}
117+
9118
// Debug logging setup
10119
const debugLogsDir = path.join(app.getPath('userData'), 'logs');
11120
const debugLogFile = path.join(debugLogsDir, 'debug.log');
@@ -107,7 +216,7 @@ let openai;
107216
let updateCheckInterval;
108217

109218
// Current app version
110-
const CURRENT_VERSION = '1.5.1';
219+
const CURRENT_VERSION = '1.5.2';
111220
const UPDATE_CHECK_URL = 'https://raw.githubusercontent.com/jay-bman725/AutoCaption/refs/heads/main/version';
112221
const CHANGELOG_URL = 'https://raw.githubusercontent.com/jay-bman725/AutoCaption/refs/heads/main/changelog.md';
113222

@@ -435,6 +544,9 @@ async function createWindow() {
435544
// Start automatic update checking
436545
await startAutoUpdateCheck();
437546

547+
// Start connectivity checking
548+
startConnectivityChecking();
549+
438550
logger.info('Showing main window');
439551
mainWindow.show();
440552
});
@@ -515,6 +627,7 @@ app.whenReady().then(async () => {
515627
app.on('window-all-closed', () => {
516628
logger.info('All windows closed');
517629
stopAutoUpdateCheck();
630+
stopConnectivityChecking();
518631
if (process.platform !== 'darwin') {
519632
logger.info('Quitting application');
520633
app.quit();
@@ -829,6 +942,30 @@ ipcMain.handle('get-platform', async () => {
829942
}
830943
});
831944

945+
// Connectivity management
946+
ipcMain.handle('retry-connectivity-check', async () => {
947+
try {
948+
logger.info('Manual connectivity retry requested');
949+
const online = await checkInternetConnectivity();
950+
if (online !== isOnline) {
951+
await handleConnectivityChange(online);
952+
}
953+
return { success: true, isOnline: online };
954+
} catch (error) {
955+
logger.error('Error during manual connectivity retry:', error);
956+
return { success: false, error: error.message };
957+
}
958+
});
959+
960+
ipcMain.handle('get-connectivity-status', async () => {
961+
try {
962+
return { success: true, isOnline };
963+
} catch (error) {
964+
logger.error('Error getting connectivity status:', error);
965+
return { success: false, error: error.message };
966+
}
967+
});
968+
832969
// Onboarding IPC handlers
833970
ipcMain.handle('get-onboarding-status', async () => {
834971
try {

src/preload.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,12 @@ contextBridge.exposeInMainWorld('electronAPI', {
4545
getOnboardingStatus: () => ipcRenderer.invoke('get-onboarding-status'),
4646
completeOnboardingStep: (stepName) => ipcRenderer.invoke('complete-onboarding-step', stepName),
4747
completeOnboarding: () => ipcRenderer.invoke('complete-onboarding'),
48-
skipOnboarding: () => ipcRenderer.invoke('skip-onboarding')
48+
skipOnboarding: () => ipcRenderer.invoke('skip-onboarding'),
49+
50+
// Connectivity management
51+
retryConnectivityCheck: () => ipcRenderer.invoke('retry-connectivity-check'),
52+
getConnectivityStatus: () => ipcRenderer.invoke('get-connectivity-status'),
53+
54+
// Listen for connectivity status changes
55+
onConnectivityStatus: (callback) => ipcRenderer.on('connectivity-status', callback)
4956
});

0 commit comments

Comments
 (0)