Fix ws and docker run script
This commit is contained in:
parent
f61b30e3cc
commit
60321b19c5
|
@ -49,6 +49,7 @@ jobs:
|
||||||
uses: akkuman/gitea-release-action@v1
|
uses: akkuman/gitea-release-action@v1
|
||||||
with:
|
with:
|
||||||
name: Focus ${{ steps.tagName.outputs.tag }}
|
name: Focus ${{ steps.tagName.outputs.tag }}
|
||||||
|
prerelease: true
|
||||||
files: |-
|
files: |-
|
||||||
frontend/src-tauri/target/release/focus
|
frontend/src-tauri/target/release/focus
|
||||||
frontend/src-tauri/target/release/bundle/deb/*.deb
|
frontend/src-tauri/target/release/bundle/deb/*.deb
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
PUBLIC_BACKEND_URL=${PUBLIC_BACKEND_URL:-http://localhost:3000}
|
PUBLIC_BACKEND_URL=${PUBLIC_BACKEND_URL:-http://localhost:3000}
|
||||||
|
PUBLIC_BACKEND_WSURL=${PUBLIC_BACKEND_WSURL:-${PUBLIC_BACKEND_URL/http:/ws:}}
|
||||||
|
PUBLIC_BACKEND_WSURL=${PUBLIC_BACKEND_WSURL/https:/wss:}
|
||||||
|
|
||||||
find /usr/share/nginx/html -type f -exec sed -i "s|http://localhost:3000|$PUBLIC_BACKEND_URL|g" {} +
|
find /usr/share/nginx/html -type f -exec sed -i "s|http://localhost:3000|$PUBLIC_BACKEND_URL|g" {} +
|
||||||
|
find /usr/share/nginx/html -type f -exec sed -i "s|ws://localhost:3000|$PUBLIC_BACKEND_WSURL|g" {} +
|
||||||
|
|
||||||
nginx -g 'daemon off;'
|
nginx -g 'daemon off;'
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
import Project, { projects } from '$lib/types/Project';
|
|
||||||
import { hasPendingRequests } from '$lib/utils/api';
|
|
||||||
import { toastWarning } from '$lib/utils/toasts';
|
|
||||||
import { get } from 'svelte/store';
|
|
||||||
|
|
||||||
let socket: WebSocket;
|
|
||||||
|
|
||||||
export function connectWebSocket() {
|
|
||||||
socket = new WebSocket('ws://localhost:3000/api/v1/ws');
|
|
||||||
|
|
||||||
socket.onopen = () => {
|
|
||||||
console.log('WebSocket connected');
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onclose = () => {
|
|
||||||
console.log('WebSocket disconnected');
|
|
||||||
toastWarning(
|
|
||||||
'WebSocket disconnected',
|
|
||||||
'You may experience sync issues. You can try to reload the page.'
|
|
||||||
);
|
|
||||||
|
|
||||||
const reconnectTimer = setTimeout(() => {
|
|
||||||
connectWebSocket();
|
|
||||||
clearTimeout(reconnectTimer);
|
|
||||||
}, 5000);
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onerror = (err) => {
|
|
||||||
console.error('WebSocket error:', err);
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.onmessage = async (event) => {
|
|
||||||
const parsed = JSON.parse(event.data);
|
|
||||||
while (hasPendingRequests()) {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
||||||
}
|
|
||||||
applyMessage(parsed);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyMessage(data: any) {
|
|
||||||
switch (data.object) {
|
|
||||||
case 'project':
|
|
||||||
applyProject(data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log('Unknown object:', data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyProject(data: any) {
|
|
||||||
switch (data.action) {
|
|
||||||
case 'create':
|
|
||||||
if (get(projects).find((p) => p.id === data.id)) break;
|
|
||||||
case 'update':
|
|
||||||
Project.parse(data.value);
|
|
||||||
break;
|
|
||||||
case 'delete':
|
|
||||||
projects.set(get(projects).filter((p) => p.id !== data.id));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -46,7 +46,7 @@
|
||||||
<div id="branding">
|
<div id="branding">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<span id="title">Focus.</span>
|
<span id="title">Focus.</span>
|
||||||
<span id="version">v0.0.1</span>
|
<span id="version">v0.3.2</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="views">
|
<div id="views">
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
import Project, { projects } from '$lib/types/Project';
|
||||||
|
import { hasPendingRequests } from '$lib/utils/api';
|
||||||
|
import { toastAlert, toastWarning } from '$lib/utils/toasts';
|
||||||
|
import { get } from 'svelte/store';
|
||||||
|
|
||||||
|
export default class WebSocketManager {
|
||||||
|
_socket: WebSocket | null;
|
||||||
|
_queue: any[];
|
||||||
|
_reconnectAttempts: number;
|
||||||
|
_maxReconnectAttempts: number;
|
||||||
|
_hasBeenConnected: boolean;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._socket = null;
|
||||||
|
this._queue = [];
|
||||||
|
this._reconnectAttempts = 0;
|
||||||
|
this._maxReconnectAttempts = 5;
|
||||||
|
this._hasBeenConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
if (
|
||||||
|
this._socket &&
|
||||||
|
(this._socket.readyState === WebSocket.OPEN ||
|
||||||
|
this._socket.readyState === WebSocket.CONNECTING)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._socket = new WebSocket('ws://localhost:3000/api/v1/ws');
|
||||||
|
|
||||||
|
this._socket.onopen = () => {
|
||||||
|
this._reconnectAttempts = 0;
|
||||||
|
this._hasBeenConnected = true;
|
||||||
|
console.log('WebSocket connected');
|
||||||
|
};
|
||||||
|
|
||||||
|
this._socket.onclose = () => {
|
||||||
|
console.log('WebSocket disconnected');
|
||||||
|
|
||||||
|
if (this._reconnectAttempts < this._maxReconnectAttempts) {
|
||||||
|
toastWarning(
|
||||||
|
'WebSocket disconnected',
|
||||||
|
`You may experience sync issues. Trying to reconnect... (${this._reconnectAttempts + 1}/${
|
||||||
|
this._maxReconnectAttempts
|
||||||
|
})`
|
||||||
|
);
|
||||||
|
this._reconnectAttempts++;
|
||||||
|
setTimeout(() => {
|
||||||
|
this._socket?.close();
|
||||||
|
this.connect();
|
||||||
|
}, 5000);
|
||||||
|
} else {
|
||||||
|
toastAlert('Failed to connect to WebSocket', 'Please refresh the page to try again.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this._socket.onerror = (err) => {
|
||||||
|
console.warn('WebSocket error:', err);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._socket.onmessage = async (event) => {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
while (hasPendingRequests()) {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||||
|
}
|
||||||
|
applyMessage(data);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyMessage(data: any) {
|
||||||
|
switch (data.object) {
|
||||||
|
case 'project':
|
||||||
|
applyProject(data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('Unknown object:', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyProject(data: any) {
|
||||||
|
switch (data.action) {
|
||||||
|
case 'create':
|
||||||
|
if (get(projects).find((p) => p.id === data.id)) break;
|
||||||
|
case 'update':
|
||||||
|
Project.parse(data.value);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
projects.set(get(projects).filter((p) => p.id !== data.id));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,17 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import projectsApi from '$lib/api/projectsApi';
|
import projectsApi from '$lib/api/projectsApi';
|
||||||
import { connectWebSocket } from '$lib/api/websocket';
|
|
||||||
import Project, { projects } from '$lib/types/Project';
|
import Project, { projects } from '$lib/types/Project';
|
||||||
|
import WebSocketManager from '$lib/utils/webSocketManager';
|
||||||
import { SvelteToast } from '@zerodevx/svelte-toast';
|
import { SvelteToast } from '@zerodevx/svelte-toast';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import SelectProject from '../lib/components/projects/SelectProject.svelte';
|
import SelectProject from '../lib/components/projects/SelectProject.svelte';
|
||||||
|
|
||||||
|
const wsManager = new WebSocketManager();
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await projectsApi.getAll();
|
await projectsApi.getAll();
|
||||||
|
wsManager.connect();
|
||||||
});
|
});
|
||||||
|
|
||||||
connectWebSocket();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|
Loading…
Reference in New Issue