updates
This commit is contained in:
22
frontend-web/src/App.tsx
Normal file
22
frontend-web/src/App.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import {useState} from 'react';
|
||||
import WebSocketService from './services/WebSocket/WebSocketService';
|
||||
import {Container} from './components/Container';
|
||||
|
||||
export default function App() {
|
||||
const websocketUrl = `ws://${new globalThis.URL(origin).hostname}:8080/ws`;
|
||||
const [websocketService, setWebSocketService] = useState<WebSocketService>(new WebSocketService(websocketUrl));
|
||||
|
||||
|
||||
console.log('Using [%o]', websocketUrl);
|
||||
|
||||
return <Container style={{
|
||||
display: 'flex',
|
||||
width: '100vw',
|
||||
height: '100vh'
|
||||
}}>
|
||||
|
||||
<Container>
|
||||
<h1>Hello World</h1>
|
||||
</Container>
|
||||
</Container>
|
||||
}
|
||||
17
frontend-web/src/components/Container/Container.tsx
Normal file
17
frontend-web/src/components/Container/Container.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import type {PropsWithChildren} from "react"
|
||||
export interface IContainerProps extends PropsWithChildren {
|
||||
style?: Record<string, string>;
|
||||
}
|
||||
|
||||
export function Container({style, children}: IContainerProps) {
|
||||
const containerStyle = Object.assign({}, style, {
|
||||
border: '2px solid white',
|
||||
width: '500px',
|
||||
height: '500px',
|
||||
margin: 'auto',
|
||||
display: 'flex'
|
||||
})
|
||||
return <div style={containerStyle}>
|
||||
{children}
|
||||
</div>
|
||||
}
|
||||
1
frontend-web/src/components/Container/index.ts
Normal file
1
frontend-web/src/components/Container/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './Container';
|
||||
69
frontend-web/src/index.css
Normal file
69
frontend-web/src/index.css
Normal file
@@ -0,0 +1,69 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
3
frontend-web/src/lang/assertUnreachable.ts
Normal file
3
frontend-web/src/lang/assertUnreachable.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function assertUnreachable(x: never): never {
|
||||
throw new Error(`Error: Unreachable code reached with value [${x}]`);
|
||||
}
|
||||
10
frontend-web/src/main.tsx
Normal file
10
frontend-web/src/main.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import {StrictMode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App.tsx';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
);
|
||||
36
frontend-web/src/services/WebSocket/WebSocketService.ts
Normal file
36
frontend-web/src/services/WebSocket/WebSocketService.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import {LoggerFactory, type ILogger} from '@techniker-me/logger';
|
||||
import { assertUnreachable, Subject } from '@techniker-me/tools';
|
||||
import {WebSocketServiceStatus, type WebSocketServiceStatusType} from './WebSocketServiceStatus';
|
||||
|
||||
export default class WebSocketService {
|
||||
private readonly _logger: ILogger = LoggerFactory.getLogger('WebSocketService');
|
||||
private readonly _websocket: WebSocket;
|
||||
private readonly _status: Subject<WebSocketServiceStatus> = new Subject(WebSocketServiceStatus.Closed);
|
||||
|
||||
constructor(websocketUrl: string) {
|
||||
this._websocket = new WebSocket(websocketUrl);
|
||||
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
private initialize() {
|
||||
this._websocket.onerror = () => {
|
||||
this.setStatus(WebSocketServiceStatus.Error);
|
||||
}
|
||||
|
||||
this._websocket.onopen = () => {
|
||||
this.setStatus(WebSocketServiceStatus.Open);
|
||||
}
|
||||
|
||||
this._websocket.onclose = () => {
|
||||
this.setStatus(WebSocketServiceStatus.Closed);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private setStatus(status: WebSocketServiceStatus): void {
|
||||
this._status.value = status;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import assertUnreachable from "../../lang/assertUnreachable";
|
||||
|
||||
export enum WebSocketServiceStatus {
|
||||
Closed = 0,
|
||||
Open = 1,
|
||||
Error = 2
|
||||
}
|
||||
|
||||
export type WebSocketServiceStatusType = 'Closed' | 'Open' | 'Error';
|
||||
|
||||
export class WebSocketServiceStatusMapping {
|
||||
public static convertWebSocketServiceStatusToWebSocketServiceStatusType(status: WebSocketServiceStatus): WebSocketServiceStatusType {
|
||||
switch(status) {
|
||||
case WebSocketServiceStatus.Closed:
|
||||
return 'Closed';
|
||||
case WebSocketServiceStatus.Open:
|
||||
return 'Open';
|
||||
case WebSocketServiceStatus.Error:
|
||||
return 'Error';
|
||||
|
||||
default:
|
||||
assertUnreachable(status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1
frontend-web/src/vite-env.d.ts
vendored
Normal file
1
frontend-web/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
Reference in New Issue
Block a user