websockets
This commit is contained in:
parent
b44e4ed6f9
commit
f0b53b67ce
9 changed files with 268 additions and 28 deletions
|
|
@ -587,17 +587,86 @@ async function checkSession() {
|
|||
return false;
|
||||
}
|
||||
|
||||
let isPolling = false;
|
||||
async function startAutoRefresh() {
|
||||
setInterval(async () => {
|
||||
if (isPolling) return;
|
||||
isPolling = true;
|
||||
let socket = null;
|
||||
let reconnectDelay = 1000;
|
||||
|
||||
function connectWebSocket() {
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const wsUrl = `${protocol}//${window.location.host}/api/ws`;
|
||||
|
||||
console.log('Connecting to WebSocket:', wsUrl);
|
||||
socket = new WebSocket(wsUrl);
|
||||
|
||||
socket.onopen = () => {
|
||||
console.log('WebSocket connected');
|
||||
reconnectDelay = 1000;
|
||||
// Initial fetch to sync state
|
||||
fetchTasks();
|
||||
};
|
||||
|
||||
socket.onmessage = (event) => {
|
||||
try {
|
||||
await fetchTasks();
|
||||
} finally {
|
||||
isPolling = false;
|
||||
const { type, data } = JSON.parse(event.data);
|
||||
console.log('WebSocket event:', type, data);
|
||||
|
||||
switch (type) {
|
||||
case 'TaskCreated':
|
||||
state.tasks.unshift(data);
|
||||
renderApp();
|
||||
showToast('New task created', 'success');
|
||||
break;
|
||||
case 'TaskUpdated':
|
||||
case 'RunFinished':
|
||||
const index = state.tasks.findIndex(t => t.id === data.id);
|
||||
if (index !== -1) {
|
||||
const wasSelected = state.selectedTaskId === data.id;
|
||||
state.tasks[index] = data;
|
||||
if (wasSelected) {
|
||||
// Update selected run if we were following latest
|
||||
const wasFollowingLatest = state.selectedRunId === state.tasks[index].runs?.[1]?.id || !state.selectedRunId;
|
||||
if (wasFollowingLatest && data.runs && data.runs.length > 0) {
|
||||
state.selectedRunId = data.runs[0].id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state.tasks.unshift(data);
|
||||
}
|
||||
renderApp();
|
||||
if (type === 'RunFinished') {
|
||||
showToast(`Task run completed: ${data.goal}`, 'info');
|
||||
}
|
||||
break;
|
||||
case 'RunStarted':
|
||||
const taskIndex = state.tasks.findIndex(t => t.id === data.task_id);
|
||||
if (taskIndex !== -1) {
|
||||
// We don't have the full task update here, but we can update status
|
||||
// For simplicity, we just trigger a fetch or wait for RunFinished
|
||||
// But let's at least show it's running in the UI if selected
|
||||
if (state.tasks[taskIndex].runs) {
|
||||
// Prepend a dummy run or just fetch
|
||||
fetchTasks();
|
||||
}
|
||||
}
|
||||
showToast(`Task started: ${data.goal}`, 'info');
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error handling WebSocket message:', e);
|
||||
}
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
socket.onclose = () => {
|
||||
console.log('WebSocket disconnected. Reconnecting...');
|
||||
setTimeout(() => {
|
||||
reconnectDelay = Math.min(reconnectDelay * 1.5, 30000);
|
||||
connectWebSocket();
|
||||
}, reconnectDelay);
|
||||
};
|
||||
|
||||
socket.onerror = (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
socket.close();
|
||||
};
|
||||
}
|
||||
|
||||
async function showLogin() {
|
||||
|
|
@ -661,7 +730,7 @@ async function initializeApp() {
|
|||
appEl.classList.remove('hidden');
|
||||
loginOverlay.classList.add('hidden');
|
||||
await fetchTasks();
|
||||
startAutoRefresh();
|
||||
connectWebSocket();
|
||||
} else {
|
||||
showLogin();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue