style(web-client): run prettier

This commit is contained in:
Benoît CORTIER 2023-11-04 00:45:10 -04:00 committed by Benoît Cortier
parent dff3f307eb
commit d4ea558da0
52 changed files with 1346 additions and 1302 deletions

View file

@ -12,30 +12,30 @@
root: true
plugins:
- "@typescript-eslint"
- '@typescript-eslint'
extends:
- "eslint:recommended"
- "plugin:@typescript-eslint/recommended"
- "plugin:svelte/prettier" # Turns off rules that may conflict with Prettier
- "plugin:prettier/recommended"
- 'eslint:recommended'
- 'plugin:@typescript-eslint/recommended'
- 'plugin:svelte/prettier' # Turns off rules that may conflict with Prettier
- 'plugin:prettier/recommended'
parser: "@typescript-eslint/parser"
parser: '@typescript-eslint/parser'
parserOptions:
project: ./tsconfig.json
sourceType: module
ecmaVersion: 2020
extraFileExtensions:
- ".svelte"
- '.svelte'
ignorePatterns:
- "*.cjs"
- '*.cjs'
overrides:
- files: "*.svelte"
- files: '*.svelte'
parser: svelte-eslint-parser
parserOptions:
parser: "@typescript-eslint/parser"
parser: '@typescript-eslint/parser'
env:
browser: true
@ -44,10 +44,10 @@ env:
rules:
strict: 2
"@typescript-eslint/no-unused-vars":
- "error"
'@typescript-eslint/no-unused-vars':
- 'error'
- argsIgnorePattern: '^_'
"@typescript-eslint/strict-boolean-expressions":
'@typescript-eslint/strict-boolean-expressions':
- 2
- allowString: false
allowNumber: false

View file

@ -15,7 +15,7 @@ Run `npm run build`
As member of the Devolutions organization, you can import the Web Component from JFrog Artifactory by running the following npm command:
```shell
$ npm install @devolutions/iron-remote-gui
$ npm install @devolutions/iron-remote-gui
```
Otherwise, you can run `npm install` targeting the `dist/` folder directly.
@ -33,10 +33,10 @@ Call the `connect` method on this object.
For now, we didn't make the enums used by some method directly available (I didn't find the good way to export them directly with the component.).
You need to recreate them on your application for now (it will be improved in future version);
Also, even if the connection to RDP work there is still a lot of improvement to do.
Also, even if the connection to RDP work there is still a lot of improvement to do.
As of now, you can expect, mouse movement and click (4 buttons) - no scroll, Keyboard for at least the standard.
Windows and CTRL+ALT+DEL can be called by method on `UserInteractionService`.
Lock keys (like caps lock), have a partial support.
Windows and CTRL+ALT+DEL can be called by method on `UserInteractionService`.
Lock keys (like caps lock), have a partial support.
Other advanced functionalities (sharing / copy past...) are not implemented yet.
## Component parameters
@ -59,19 +59,18 @@ You can add some parameters for default initialization on the component `<iron-r
> `authtoken` is the authentication token to send to the Devolutions Gateway.
> `ctrlAltDel()`
>
>
> Sends the ctrl+alt+del key to server.
> `metaKey()`
>
>
> Sends the meta key event to remote host (i.e.: Windows key).
> `setVisibility(value: bool)`
>
>
> Shows or hides rendering canvas.
> `setScale(scale: ScreenScale)`
>
>
> Sets the scale behavior of the canvas.
> See the [ScreenScale](./src/services/user-interaction-service.ts) enum for possible values.

View file

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
@ -7,12 +7,12 @@
</head>
<body>
<script type="module" src="/src/main.ts"></script>
<iron-remote-gui isvisible="false" desktopwidth="600" desktopheight="400"/>
<iron-remote-gui isvisible="false" desktopwidth="600" desktopheight="400" />
<script>
var el = document.querySelector('iron-remote-gui');
el.addEventListener('ready', (e) => {
console.log("WebComponent Loaded");
console.log('WebComponent Loaded');
e.detail.irgUserInteraction.setVisibility(true);
});
</script>

View file

@ -16,14 +16,11 @@
"build-alone": "vite build",
"pre-build": "node ./pre-build.js",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "npm run lint:prettier && npm run lint:eslint",
"lint:prettier": "prettier . --check",
"lint:eslint": "eslint src/**",
"format": "prettier . --write ."
},
"devDependencies": {

View file

@ -1,8 +1,8 @@
import {spawn} from "child_process";
import { spawn } from 'child_process';
let run = async function (command, cwd) {
return new Promise(resolve => {
const buildCommand = spawn(command, {stdio: "pipe", shell: true, cwd: cwd});
return new Promise((resolve) => {
const buildCommand = spawn(command, { stdio: 'pipe', shell: true, cwd: cwd });
buildCommand.stdout.on('data', (data) => {
console.log(`${data}`);
@ -16,7 +16,7 @@ let run = async function (command, cwd) {
console.log(`child process exited with code ${code}`);
resolve();
});
})
}
});
};
await run('wasm-pack build --target web', '../../crates/ironrdp-web');

View file

@ -1,19 +1,19 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Test</title>
</head>
<body>
<script type="module" src="./iron-remote-gui.js"></script>
<iron-remote-gui isvisible="false" desktopwidth="600" desktopheight="400"/>
</head>
<body>
<script type="module" src="./iron-remote-gui.js"></script>
<iron-remote-gui isvisible="false" desktopwidth="600" desktopheight="400" />
<script>
var el = document.querySelector('iron-remote-gui');
el.addEventListener('ready', (e) => {
<script>
var el = document.querySelector('iron-remote-gui');
el.addEventListener('ready', (e) => {
e.detail.irgUserInteraction.setVisibility(true);
});
</script>
</body>
</html>
});
</script>
</body>
</html>

View file

@ -1,10 +1,10 @@
export enum LockKey {
CAPS_LOCK = "CapsLock",
NUM_LOCK = "NumLock",
SCROLL_LOCK = "ScrollLock",
KANA_MODE = "KanaMode",
"CapsLock" = CAPS_LOCK,
"ScrollLock" = SCROLL_LOCK,
"NumLock" = NUM_LOCK,
"KanaMode" = KANA_MODE
}
CAPS_LOCK = 'CapsLock',
NUM_LOCK = 'NumLock',
SCROLL_LOCK = 'ScrollLock',
KANA_MODE = 'KanaMode',
'CapsLock' = CAPS_LOCK,
'ScrollLock' = SCROLL_LOCK,
'NumLock' = NUM_LOCK,
'KanaMode' = KANA_MODE,
}

View file

@ -1,8 +1,8 @@
export enum LogType {
OFF = "OFF",
ERROR = "ERROR",
WARN = "WARN",
INFO = "INFO",
DEBUG = "DEBUG",
TRACE = "TRACE"
}
OFF = 'OFF',
ERROR = 'ERROR',
WARN = 'WARN',
INFO = 'INFO',
DEBUG = 'DEBUG',
TRACE = 'TRACE',
}

View file

@ -1,14 +1,14 @@
export enum ModifierKey {
CTRL_LEFT = "ControlLeft",
SHIFT_LEFT = "ShiftLeft",
SHIFT_RIGHT = "ShiftRight",
ALT_LEFT = "AltLeft",
CTRL_RIGHT = "ControlRight",
ALT_RIGHT = "AltRight",
"ControlLeft" = CTRL_LEFT,
"ShiftLeft" = SHIFT_LEFT,
"ShiftRight" = SHIFT_RIGHT,
"AltLeft" = ALT_LEFT,
"ControlRight" = CTRL_RIGHT,
"AltRight" = ALT_RIGHT,
}
CTRL_LEFT = 'ControlLeft',
SHIFT_LEFT = 'ShiftLeft',
SHIFT_RIGHT = 'ShiftRight',
ALT_LEFT = 'AltLeft',
CTRL_RIGHT = 'ControlRight',
ALT_RIGHT = 'AltRight',
'ControlLeft' = CTRL_LEFT,
'ShiftLeft' = SHIFT_LEFT,
'ShiftRight' = SHIFT_RIGHT,
'AltLeft' = ALT_LEFT,
'ControlRight' = CTRL_RIGHT,
'AltRight' = ALT_RIGHT,
}

View file

@ -3,5 +3,5 @@
MIDDLE = 1,
RIGHT = 2,
BROWSER_BACK = 3,
BROWSER_FORWARD = 4
BROWSER_FORWARD = 4,
}

View file

@ -1,4 +1,4 @@
export enum MouseButtonState {
MOUSE_DOWN,
MOUSE_UP
MOUSE_UP,
}

View file

@ -1,5 +1,5 @@
export enum OS {
WINDOWS = 'windows',
LINUX = 'linux',
ANDROID = 'android'
}
ANDROID = 'android',
}

View file

@ -1,5 +1,5 @@
export enum ScreenScale {
Fit = 1,
Full = 2,
Real = 3
Real = 3,
}

View file

@ -1,5 +1,5 @@
export enum SessionEventType {
STARTED,
TERMINATED,
ERROR
ERROR,
}

View file

@ -1,4 +1,4 @@
export enum SpecialCombination {
CTRL_ALT_DEL,
META
META,
}

View file

@ -1,4 +1,4 @@
export interface DesktopSize {
width: number,
height: number
width: number;
height: number;
}

View file

@ -1,7 +1,7 @@
import type {DesktopSize} from './DesktopSize';
import type { DesktopSize } from './DesktopSize';
export interface NewSessionInfo {
session_id: number,
websocket_port: number,
initial_desktop_size: DesktopSize,
session_id: number;
websocket_port: number;
initial_desktop_size: DesktopSize;
}

View file

@ -1,6 +1,6 @@
import type {DesktopSize} from './DesktopSize';
import type { DesktopSize } from './DesktopSize';
export interface ResizeEvent {
session_id: number,
desktop_size: DesktopSize,
session_id: number;
desktop_size: DesktopSize;
}

View file

@ -1,20 +1,29 @@
import type {ScreenScale} from '../enums/ScreenScale';
import type {Observable} from 'rxjs';
import type {NewSessionInfo} from './NewSessionInfo';
import type {SessionEvent} from './session-event';
import type {DesktopSize} from './DesktopSize';
import type { ScreenScale } from '../enums/ScreenScale';
import type { Observable } from 'rxjs';
import type { NewSessionInfo } from './NewSessionInfo';
import type { SessionEvent } from './session-event';
import type { DesktopSize } from './DesktopSize';
export interface UserInteraction {
setVisibility(state: boolean): void;
setScale(scale: ScreenScale): void;
connect(username: string, password: string, destination: string, proxyAddress: string, serverDomain: string, authToken: string, desktopSize?: DesktopSize, preConnectionBlob?: string): Observable<NewSessionInfo>;
connect(
username: string,
password: string,
destination: string,
proxyAddress: string,
serverDomain: string,
authToken: string,
desktopSize?: DesktopSize,
preConnectionBlob?: string,
): Observable<NewSessionInfo>;
ctrlAltDel(): void;
metaKey(): void;
shutdown(): void;
sessionListener: Observable<SessionEvent>;

View file

@ -1,7 +1,7 @@
import type {SessionEventType} from '../enums/SessionEventType';
import type { SessionEventType } from '../enums/SessionEventType';
import type { IronRdpError } from '../../../../crates/ironrdp-web/pkg/ironrdp_web';
export interface SessionEvent {
type: SessionEventType,
data?: IronRdpError | string
type: SessionEventType;
data?: IronRdpError | string;
}

View file

@ -1,18 +1,18 @@
<svelte:options tag="iron-remote-gui"/>
<svelte:options tag="iron-remote-gui" />
<script lang="ts">
import {onMount} from 'svelte';
import {get_current_component} from "svelte/internal";
import {loggingService} from "./services/logging.service";
import {WasmBridgeService} from './services/wasm-bridge.service';
import {LogType} from './enums/LogType';
import type {ResizeEvent} from './interfaces/ResizeEvent';
import {PublicAPI} from './services/PublicAPI';
import {ScreenScale} from './enums/ScreenScale';
import { onMount } from 'svelte';
import { get_current_component } from 'svelte/internal';
import { loggingService } from './services/logging.service';
import { WasmBridgeService } from './services/wasm-bridge.service';
import { LogType } from './enums/LogType';
import type { ResizeEvent } from './interfaces/ResizeEvent';
import { PublicAPI } from './services/PublicAPI';
import { ScreenScale } from './enums/ScreenScale';
export let scale = 'real';
export let verbose = 'false';
export let debugwasm: "OFF" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "TRACE" = 'INFO';
export let debugwasm: 'OFF' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE' = 'INFO';
export let flexcenter = 'true';
let isVisible = false;
@ -24,7 +24,7 @@
let viewerStyle: string;
let wrapperStyle: string;
let wasmService = new WasmBridgeService();
let publicAPI = new PublicAPI(wasmService);
@ -49,9 +49,9 @@
if (flexcenter === 'true') {
if (!full) {
currentComponent.style.flexGrow = 1;
currentComponent.style.display = "flex";
currentComponent.style.justifyContent = "center";
currentComponent.style.alignItems = "center";
currentComponent.style.display = 'flex';
currentComponent.style.justifyContent = 'center';
currentComponent.style.alignItems = 'center';
} else {
currentComponent.style.flexGrow = 1;
}
@ -86,16 +86,16 @@
scaleSession(scale);
});
wasmService.scaleObserver.subscribe(s => {
loggingService.info("Change scale!");
wasmService.scaleObserver.subscribe((s) => {
loggingService.info('Change scale!');
scaleSession(s);
});
wasmService.changeVisibilityObservable.subscribe(val => {
wasmService.changeVisibilityObservable.subscribe((val) => {
isVisible = val;
if (val) {
//Enforce first scaling and delay the call to scaleSession to ensure Dom is ready.
setWrapperStyle("100%", "100%", "hidden");
setWrapperStyle('100%', '100%', 'hidden');
setTimeout(() => scaleSession(scale), 150);
}
});
@ -107,22 +107,22 @@
switch (currentSize) {
case 'fit':
case ScreenScale.Fit:
loggingService.info("Size to fit");
loggingService.info('Size to fit');
scale = 'fit';
fitResize();
break;
case 'full':
case ScreenScale.Full:
loggingService.info("Size to full");
loggingService.info('Size to full');
fullResize();
scale = 'full';
break;
case 'real':
case ScreenScale.Real:
loggingService.info("Size to real");
loggingService.info('Size to real');
realResize();
scale = 'real';
break
break;
}
}
}
@ -181,7 +181,11 @@
const containerHeight = windowSize.y - wrapperBoundingBox.y;
if (containerWidth < canvas.width || containerHeight < canvas.height) {
setWrapperStyle(`${Math.min(containerHeight, canvas.height)}px`, `${Math.min(containerWidth, canvas.width)}px`, 'auto');
setWrapperStyle(
`${Math.min(containerHeight, canvas.height)}px`,
`${Math.min(containerWidth, canvas.width)}px`,
'auto',
);
} else {
setWrapperStyle('initial', 'initial', 'initial');
}
@ -197,7 +201,7 @@
const coord = {
x: Math.round((evt.clientX - rect.left) * scaleX),
y: Math.round((evt.clientY - rect.top) * scaleY)
y: Math.round((evt.clientY - rect.top) * scaleY),
};
wasmService.updateMousePosition(coord);
@ -232,11 +236,11 @@
body = doc.getElementsByTagName('body')[0],
x = win.innerWidth ?? docElem.clientWidth ?? body.clientWidth,
y = win.innerHeight ?? docElem.clientHeight ?? body.clientHeight;
return {x, y};
return { x, y };
}
async function initcanvas() {
loggingService.info('Start canvas initialization.')
loggingService.info('Start canvas initialization.');
canvas = currentComponent.shadowRoot.getElementById('renderer');
// Set a default canvas size. Need more test to know if i can remove it.
@ -250,11 +254,11 @@
initListeners();
let result = {
irgUserInteraction: publicAPI.getExposedFunctions()
irgUserInteraction: publicAPI.getExposedFunctions(),
};
loggingService.info('Component ready');
currentComponent.dispatchEvent(new CustomEvent("ready", {detail: result}));
currentComponent.dispatchEvent(new CustomEvent('ready', { detail: result }));
}
onMount(async () => {
@ -264,26 +268,28 @@
});
</script>
<div bind:this={wrapper} class="screen-wrapper scale-{scale}" class:hidden="{!isVisible}"
class:capturing-inputs="{capturingInputs}"
style="{wrapperStyle}">
<div class="screen-viewer" style="{viewerStyle}">
<div
bind:this={wrapper}
class="screen-wrapper scale-{scale}"
class:hidden={!isVisible}
class:capturing-inputs={capturingInputs}
style={wrapperStyle}
>
<div class="screen-viewer" style={viewerStyle}>
<canvas
on:mousemove={getMousePos}
on:mousedown={(event) => setMouseButtonState(event, true)}
on:mouseup={(event) => setMouseButtonState(event, false)}
on:mouseleave={(event) => {
setMouseButtonState(event, false);
setMouseOut(event);
}
}
on:mouseenter={(event) => {
setMouseIn(event);
}
}
on:contextmenu={(event) => event.preventDefault()}
on:wheel={mouseWheel}
id="renderer"
on:mousemove={getMousePos}
on:mousedown={(event) => setMouseButtonState(event, true)}
on:mouseup={(event) => setMouseButtonState(event, false)}
on:mouseleave={(event) => {
setMouseButtonState(event, false);
setMouseOut(event);
}}
on:mouseenter={(event) => {
setMouseIn(event);
}}
on:contextmenu={(event) => event.preventDefault()}
on:wheel={mouseWheel}
id="renderer"
/>
</div>
</div>
@ -294,7 +300,7 @@
}
.capturing-inputs {
outline: 1px solid rgba(0, 97, 166, .7);
outline: 1px solid rgba(0, 97, 166, 0.7);
outline-offset: -1px;
}

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
export * as default from './iron-remote-gui.svelte';
export type {UserInteraction} from './interfaces/UserInteraction';
export type {ResizeEvent} from './interfaces/ResizeEvent';
export type {NewSessionInfo} from './interfaces/NewSessionInfo';
export type {ServerRect} from './interfaces/ServerRect';
export type {DesktopSize} from './interfaces/DesktopSize';
export type {SessionEvent} from './interfaces/session-event';
export type {SessionEventType} from './enums/SessionEventType';
export type { UserInteraction } from './interfaces/UserInteraction';
export type { ResizeEvent } from './interfaces/ResizeEvent';
export type { NewSessionInfo } from './interfaces/NewSessionInfo';
export type { ServerRect } from './interfaces/ServerRect';
export type { DesktopSize } from './interfaces/DesktopSize';
export type { SessionEvent } from './interfaces/session-event';
export type { SessionEventType } from './enums/SessionEventType';

View file

@ -1,11 +1,11 @@
import {loggingService} from './logging.service';
import type {NewSessionInfo} from '../interfaces/NewSessionInfo';
import {SpecialCombination} from '../enums/SpecialCombination';
import type {WasmBridgeService} from './wasm-bridge.service';
import type {UserInteraction} from '../interfaces/UserInteraction';
import type {ScreenScale} from '../enums/ScreenScale';
import type {Observable} from 'rxjs';
import type {DesktopSize} from '../interfaces/DesktopSize';
import { loggingService } from './logging.service';
import type { NewSessionInfo } from '../interfaces/NewSessionInfo';
import { SpecialCombination } from '../enums/SpecialCombination';
import type { WasmBridgeService } from './wasm-bridge.service';
import type { UserInteraction } from '../interfaces/UserInteraction';
import type { ScreenScale } from '../enums/ScreenScale';
import type { Observable } from 'rxjs';
import type { DesktopSize } from '../interfaces/DesktopSize';
export class PublicAPI {
private wasmService: WasmBridgeService;
@ -14,9 +14,27 @@ export class PublicAPI {
this.wasmService = wasmService;
}
private connect(username: string, password: string, destination: string, proxyAddress: string, serverDomain: string, authToken: string, desktopSize?: DesktopSize, preConnectionBlob?: string): Observable<NewSessionInfo> {
private connect(
username: string,
password: string,
destination: string,
proxyAddress: string,
serverDomain: string,
authToken: string,
desktopSize?: DesktopSize,
preConnectionBlob?: string,
): Observable<NewSessionInfo> {
loggingService.info('Initializing connection.');
return this.wasmService.connect(username, password, destination, proxyAddress, serverDomain, authToken, desktopSize, preConnectionBlob);
return this.wasmService.connect(
username,
password,
destination,
proxyAddress,
serverDomain,
authToken,
desktopSize,
preConnectionBlob,
);
}
private ctrlAltDel() {
@ -35,8 +53,8 @@ export class PublicAPI {
private setScale(scale: ScreenScale) {
this.wasmService.setScale(scale);
}
private shutdown() {
private shutdown() {
this.wasmService.shutdown();
}
@ -48,8 +66,7 @@ export class PublicAPI {
sessionListener: this.wasmService.sessionObserver,
ctrlAltDel: this.ctrlAltDel.bind(this),
metaKey: this.metaKey.bind(this),
shutdown: this.shutdown.bind(this)
}
shutdown: this.shutdown.bind(this),
};
}
}

View file

@ -1,12 +1,12 @@
export class LoggingService {
verbose: boolean = false;
info(description: string) {
if (this.verbose) {
console.log(description);
console.log(description);
}
}
error(description: string, object?: unknown) {
if (this.verbose) {
console.error(description, object);
@ -14,4 +14,4 @@
}
}
export const loggingService = new LoggingService();
export const loggingService = new LoggingService();

View file

@ -1,26 +1,34 @@
import {BehaviorSubject, from, Observable, of, Subject} from 'rxjs';
import init, {DesktopSize, DeviceEvent, InputTransaction, ironrdp_init, IronRdpError, Session, SessionBuilder} from '../../../../crates/ironrdp-web/pkg/ironrdp_web';
import {loggingService} from './logging.service';
import {catchError, filter, map} from 'rxjs/operators';
import {scanCode} from '../lib/scancodes';
import {LogType} from '../enums/LogType';
import {OS} from '../enums/OS';
import {ModifierKey} from '../enums/ModifierKey';
import {LockKey} from '../enums/LockKey';
import {SessionEventType} from '../enums/SessionEventType';
import type {NewSessionInfo} from '../interfaces/NewSessionInfo';
import {SpecialCombination} from '../enums/SpecialCombination';
import type {ResizeEvent} from '../interfaces/ResizeEvent';
import {ScreenScale} from '../enums/ScreenScale';
import type {MousePosition} from '../interfaces/MousePosition';
import type {SessionEvent} from '../interfaces/session-event';
import type {DesktopSize as IDesktopSize} from '../interfaces/DesktopSize';
import { BehaviorSubject, from, Observable, of, Subject } from 'rxjs';
import init, {
DesktopSize,
DeviceEvent,
InputTransaction,
ironrdp_init,
IronRdpError,
Session,
SessionBuilder,
} from '../../../../crates/ironrdp-web/pkg/ironrdp_web';
import { loggingService } from './logging.service';
import { catchError, filter, map } from 'rxjs/operators';
import { scanCode } from '../lib/scancodes';
import { LogType } from '../enums/LogType';
import { OS } from '../enums/OS';
import { ModifierKey } from '../enums/ModifierKey';
import { LockKey } from '../enums/LockKey';
import { SessionEventType } from '../enums/SessionEventType';
import type { NewSessionInfo } from '../interfaces/NewSessionInfo';
import { SpecialCombination } from '../enums/SpecialCombination';
import type { ResizeEvent } from '../interfaces/ResizeEvent';
import { ScreenScale } from '../enums/ScreenScale';
import type { MousePosition } from '../interfaces/MousePosition';
import type { SessionEvent } from '../interfaces/session-event';
import type { DesktopSize as IDesktopSize } from '../interfaces/DesktopSize';
export class WasmBridgeService {
private _resize: Subject<ResizeEvent> = new Subject<ResizeEvent>();
private mousePosition: BehaviorSubject<MousePosition> = new BehaviorSubject<MousePosition>({
x: 0,
y: 0
y: 0,
});
private changeVisibility: Subject<boolean> = new Subject();
private sessionEvent: Subject<SessionEvent> = new Subject();
@ -82,8 +90,16 @@ export class WasmBridgeService {
this.mousePosition.next(position);
}
connect(username: string, password: string, destination: string, proxyAddress: string, serverDomain: string, authToken: string, desktopSize?: IDesktopSize, preConnectionBlob?: string): Observable<NewSessionInfo> {
connect(
username: string,
password: string,
destination: string,
proxyAddress: string,
serverDomain: string,
authToken: string,
desktopSize?: IDesktopSize,
preConnectionBlob?: string,
): Observable<NewSessionInfo> {
const sessionBuilder = SessionBuilder.new();
sessionBuilder.proxy_address(proxyAddress);
sessionBuilder.destination(destination);
@ -114,26 +130,28 @@ export class WasmBridgeService {
catchError((err: IronRdpError) => {
this.raiseSessionEvent({
type: SessionEventType.ERROR,
data: err
data: err,
});
return of(err);
}),
filter(isSession),
map((session: Session) => {
from(session.run()).pipe(
catchError(err => {
this.setVisibility(false);
this.raiseSessionEvent({
type: SessionEventType.ERROR,
data: err.backtrace()
});
this.raiseSessionEvent({
type: SessionEventType.TERMINATED,
data: 'Session was terminated.'
});
return of(err);
}),
).subscribe();
from(session.run())
.pipe(
catchError((err) => {
this.setVisibility(false);
this.raiseSessionEvent({
type: SessionEventType.ERROR,
data: err.backtrace(),
});
this.raiseSessionEvent({
type: SessionEventType.TERMINATED,
data: 'Session was terminated.',
});
return of(err);
}),
)
.subscribe();
return session;
}),
map((session: Session) => {
@ -141,17 +159,17 @@ export class WasmBridgeService {
this.session = session;
this._resize.next({
desktop_size: session.desktop_size(),
session_id: 0
session_id: 0,
});
this.raiseSessionEvent({
type: SessionEventType.STARTED,
data: 'Session started'
data: 'Session started',
});
return {
session_id: 0,
initial_desktop_size: session.desktop_size(),
websocket_port: 0
}
websocket_port: 0,
};
}),
);
}
@ -167,14 +185,12 @@ export class WasmBridgeService {
}
}
mouseWheel(event: WheelEvent) {
const vertical = event.deltaY !== 0;
const rotation = vertical ? event.deltaY : event.deltaX;
this.doTransactionFromDeviceEvents([DeviceEvent.new_wheel_rotations(vertical, -rotation)]);
}
setVisibility(state: boolean) {
this.changeVisibility.next(state);
}
@ -234,7 +250,12 @@ export class WasmBridgeService {
const syncScrollLockActive = evt.getModifierState(LockKey.SCROLL_LOCK);
const syncKanaModeActive = evt.getModifierState(LockKey.KANA_MODE);
this.session?.synchronize_lock_keys(syncScrollLockActive, syncNumsLockActive, syncCapsLockActive, syncKanaModeActive);
this.session?.synchronize_lock_keys(
syncScrollLockActive,
syncNumsLockActive,
syncCapsLockActive,
syncKanaModeActive,
);
}
private raiseSessionEvent(event: SessionEvent) {
@ -253,7 +274,7 @@ export class WasmBridgeService {
private doTransactionFromDeviceEvents(deviceEvents: DeviceEvent[]) {
const transaction = InputTransaction.new();
deviceEvents.forEach(event => transaction.add_event(event));
deviceEvents.forEach((event) => transaction.add_event(event));
this.session?.apply_inputs(transaction);
}

View file

@ -1,10 +1,10 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
export default {
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors
compilerOptions: {
customElement: true
},
preprocess: vitePreprocess(),
}
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors
compilerOptions: {
customElement: true,
},
preprocess: vitePreprocess(),
};

View file

@ -14,7 +14,7 @@
"allowJs": false,
"checkJs": false,
"isolatedModules": true,
"strict": true,
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true
},

View file

@ -1,22 +1,22 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import wasm from "vite-plugin-wasm";
import topLevelAwait from "vite-plugin-top-level-await";
import dtsPlugin from "vite-plugin-dts";
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import wasm from 'vite-plugin-wasm';
import topLevelAwait from 'vite-plugin-top-level-await';
import dtsPlugin from 'vite-plugin-dts';
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: './src/main.ts',
name: 'IronRemoteGui',
formats: ["umd", "es"],
}
},
server: {
fs: {
strict: false
}
},
plugins: [svelte(), wasm(), topLevelAwait(), dtsPlugin()],
})
build: {
lib: {
entry: './src/main.ts',
name: 'IronRemoteGui',
formats: ['umd', 'es'],
},
},
server: {
fs: {
strict: false,
},
},
plugins: [svelte(), wasm(), topLevelAwait(), dtsPlugin()],
});

View file

@ -12,31 +12,31 @@
root: true
plugins:
- "@typescript-eslint"
- '@typescript-eslint'
- 'html'
extends:
- "eslint:recommended"
- "plugin:@typescript-eslint/recommended"
- "plugin:svelte/prettier" # Turns off rules that may conflict with Prettier
- "plugin:prettier/recommended"
- 'eslint:recommended'
- 'plugin:@typescript-eslint/recommended'
- 'plugin:svelte/prettier' # Turns off rules that may conflict with Prettier
- 'plugin:prettier/recommended'
parser: "@typescript-eslint/parser"
parser: '@typescript-eslint/parser'
parserOptions:
project: ./tsconfig.json
sourceType: module
ecmaVersion: 2020
extraFileExtensions:
- ".svelte"
- '.svelte'
ignorePatterns:
- "*.cjs"
- '*.cjs'
overrides:
- files: "*.svelte"
- files: '*.svelte'
parser: svelte-eslint-parser
parserOptions:
parser: "@typescript-eslint/parser"
parser: '@typescript-eslint/parser'
env:
browser: true
@ -45,10 +45,10 @@ env:
rules:
strict: 2
"@typescript-eslint/no-unused-vars":
- "error"
'@typescript-eslint/no-unused-vars':
- 'error'
- argsIgnorePattern: '^_'
"@typescript-eslint/strict-boolean-expressions":
'@typescript-eslint/strict-boolean-expressions':
- 2
- allowString: false
allowNumber: false

View file

@ -97,7 +97,7 @@ $ New-DGatewayToken -Type ASSOCIATION -PrivateKeyFile <PRIVATE KEY PATH> -Destin
First, run `npm install` in the [iron-remote-gui](../iron-remote-gui/) folder,
and then `npm install` in [iron-svelte-client](./) folder.
You can then start the dev server with either:
You can then start the dev server with either:
- `npm run dev` - Runs only the final application.
- `npm run dev-all` - Builds WASM module and `iron-remote-gui` prior to starting the dev server.

View file

@ -11,14 +11,11 @@
"build": "npm run pre-build && vite build",
"build-no-wasm": "npm run pre-build-no-wasm && vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "npm run lint:prettier && npm run lint:eslint",
"lint:prettier": "prettier . --check",
"lint:eslint": "eslint src/**",
"format": "prettier . --write ."
},
"devDependencies": {

View file

@ -1,7 +1,7 @@
import * as fs from 'fs-extra';
import {spawn} from 'child_process';
import { spawn } from 'child_process';
import * as path from 'path';
import {fileURLToPath} from 'url';
import { fileURLToPath } from 'url';
import { argv } from 'node:process';
const __filename = fileURLToPath(import.meta.url);
@ -18,8 +18,8 @@ argv.forEach((val, index) => {
});
let run = async function (command, cwd) {
return new Promise(resolve => {
const buildCommand = spawn(command, {stdio: "pipe", shell: true, cwd: cwd});
return new Promise((resolve) => {
const buildCommand = spawn(command, { stdio: 'pipe', shell: true, cwd: cwd });
buildCommand.stdout.on('data', (data) => {
console.log(`${data}`);
@ -39,7 +39,7 @@ let run = async function (command, cwd) {
let copyCoreFiles = async function () {
console.log('Copying core files…');
await fs.remove(assetIronRemoteGuiFolder);
return new Promise(resolve => {
return new Promise((resolve) => {
let source = '../iron-remote-gui/dist';
let destination = assetIronRemoteGuiFolder;
@ -51,8 +51,8 @@ let copyCoreFiles = async function () {
console.log('Core files were copied successfully');
resolve();
});
})
}
});
};
let buildCommand = 'npm run build';
if (noWasm) {

View file

@ -2,8 +2,8 @@
// for information about these interfaces
// and what to do when importing types
declare namespace App {
// interface Locals {}
// interface PageData {}
// interface Error {}
// interface Platform {}
// interface Locals {}
// interface PageData {}
// interface Error {}
// interface Platform {}
}

View file

@ -1,19 +1,19 @@
<!DOCTYPE html>
<html lang="en" style="height: 100%; margin: 0; padding: 0;">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link href="%sveltekit.assets%/material-icons/index.css" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono" />
<link href="%sveltekit.assets%/beercss/beer.min.css" rel="stylesheet" />
<link href="%sveltekit.assets%/theme.css" rel="stylesheet" />
<script src="%sveltekit.assets%/beercss/beer.min.js" type="text/javascript"></script>
<script type="module" src="%sveltekit.assets%/iron-remote-gui/iron-remote-gui.js"></script>
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body class="light" style="height: 100%; margin: 0; padding: 0;">
<div style="display: contents" class="mdc-typography--font-family">%sveltekit.body%</div>
</body>
<!doctype html>
<html lang="en" style="height: 100%; margin: 0; padding: 0">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link href="%sveltekit.assets%/material-icons/index.css" rel="stylesheet" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono" />
<link href="%sveltekit.assets%/beercss/beer.min.css" rel="stylesheet" />
<link href="%sveltekit.assets%/theme.css" rel="stylesheet" />
<script src="%sveltekit.assets%/beercss/beer.min.js" type="text/javascript"></script>
<script type="module" src="%sveltekit.assets%/iron-remote-gui/iron-remote-gui.js"></script>
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body class="light" style="height: 100%; margin: 0; padding: 0">
<div style="display: contents" class="mdc-typography--font-family">%sveltekit.body%</div>
</body>
</html>

View file

@ -1,3 +1,3 @@
import {writable} from 'svelte/store';
import { writable } from 'svelte/store';
export const showLogin = writable(true);
export const showLogin = writable(true);

View file

@ -1,4 +1,4 @@
.wrapper {
display: flex;
justify-content: center;
}
display: flex;
justify-content: center;
}

View file

@ -1,27 +1,28 @@
<script lang="ts">
import {currentSession, userInteractionService} from '../../services/session.service';
import {catchError, filter} from "rxjs/operators";
import type {UserInteraction, NewSessionInfo} from '../../../static/iron-remote-gui';
import {of} from 'rxjs';
import {toast} from '$lib/messages/message-store';
import {showLogin} from '$lib/login/login-store';
import type {DesktopSize} from '../../models/desktop-size';
import { currentSession, userInteractionService } from '../../services/session.service';
import { catchError, filter } from 'rxjs/operators';
import type { UserInteraction, NewSessionInfo } from '../../../static/iron-remote-gui';
import { of } from 'rxjs';
import { toast } from '$lib/messages/message-store';
import { showLogin } from '$lib/login/login-store';
import type { DesktopSize } from '../../models/desktop-size';
let username = "Administrator";
let password = "DevoLabs123!";
let gatewayAddress = "ws://localhost:7171/jet/rdp";
let hostname = "10.10.0.3:3389";
let domain = "";
let authtoken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkFTU09DSUFUSU9OIn0.eyJkc3RfaHN0IjoiMTkyLjE2OC41Ni4xMDE6MzM4OSIsImV4cCI6MTY5MzQyMzY1NSwiamV0X2FpZCI6IjMwNzZjZGIwLWYxNTctNDJlNy1iOWMzLThhMTdlNDFkYjYwNyIsImpldF9hcCI6InJkcCIsImpldF9jbSI6ImZ3ZCIsImp0aSI6IjAwYjY4OTY2LWJiYjAtNDU0NS05ZDZiLWRjNmFmMjAzNjY5MiIsIm5iZiI6MTY5MzQyMjc1NX0.SYQv4HtWQbdHMHgoCLYejCfO3TtsMAyjjILB6-Nir3mBznKiSad3POeLf02n05JFc5QhCeSGxspAaoNU7-znQFhHr0Tt0MnZJ1YMQt4UoR3PR2fTuUqv8M5TKdm4lKwCIjh73tTD001glTkXHaxuCQBTFCUSzfZhXDIqq5-CQueKtCrgJfYepJLmlvgH-ujGcxfXoGJGmeUy3Fmaijiy0uaC98j9GNCfnAd6JENmSAOkxfroMFhq601PSEizRbPzq2exDakfJ0EkaANz15udBX1a7NP-RyANHWQb8hp0rj6hyuyg1-vfUKYusw5qNUjAGXaWOjHC5bLgnqfE2V8Xnw";
let username = 'Administrator';
let password = 'DevoLabs123!';
let gatewayAddress = 'ws://localhost:7171/jet/rdp';
let hostname = '10.10.0.3:3389';
let domain = '';
let authtoken =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkFTU09DSUFUSU9OIn0.eyJkc3RfaHN0IjoiMTkyLjE2OC41Ni4xMDE6MzM4OSIsImV4cCI6MTY5MzQyMzY1NSwiamV0X2FpZCI6IjMwNzZjZGIwLWYxNTctNDJlNy1iOWMzLThhMTdlNDFkYjYwNyIsImpldF9hcCI6InJkcCIsImpldF9jbSI6ImZ3ZCIsImp0aSI6IjAwYjY4OTY2LWJiYjAtNDU0NS05ZDZiLWRjNmFmMjAzNjY5MiIsIm5iZiI6MTY5MzQyMjc1NX0.SYQv4HtWQbdHMHgoCLYejCfO3TtsMAyjjILB6-Nir3mBznKiSad3POeLf02n05JFc5QhCeSGxspAaoNU7-znQFhHr0Tt0MnZJ1YMQt4UoR3PR2fTuUqv8M5TKdm4lKwCIjh73tTD001glTkXHaxuCQBTFCUSzfZhXDIqq5-CQueKtCrgJfYepJLmlvgH-ujGcxfXoGJGmeUy3Fmaijiy0uaC98j9GNCfnAd6JENmSAOkxfroMFhq601PSEizRbPzq2exDakfJ0EkaANz15udBX1a7NP-RyANHWQb8hp0rj6hyuyg1-vfUKYusw5qNUjAGXaWOjHC5bLgnqfE2V8Xnw';
let desktopSize: DesktopSize = {
width: 1280,
height: 768
height: 768,
};
let pcb: string;
let userInteraction: UserInteraction;
userInteractionService.subscribe(val => {
userInteractionService.subscribe((val) => {
userInteraction = val;
if (val != null) {
initListeners();
@ -29,9 +30,9 @@
});
const initListeners = () => {
userInteraction.sessionListener.subscribe(event => {
userInteraction.sessionListener.subscribe((event) => {
if (event.type === 2) {
console.log("Error event", event.data);
console.log('Error event', event.data);
toast.set({
type: 'error',
@ -40,27 +41,28 @@
} else {
toast.set({
type: 'info',
message: event.data ?? "No info",
message: event.data ?? 'No info',
});
}
});
}
};
const StartSession = () => {
toast.set({
type: 'info',
message: 'Connection in progress...'
message: 'Connection in progress...',
});
userInteraction.connect(username, password, hostname, gatewayAddress, domain, authtoken, desktopSize, pcb)
userInteraction
.connect(username, password, hostname, gatewayAddress, domain, authtoken, desktopSize, pcb)
.pipe(
catchError(err => {
catchError((err) => {
toast.set({
type: 'info',
message: err.backtrace()
message: err.backtrace(),
});
return of(null);
}),
filter(result => !!result)
filter((result) => !!result),
)
.subscribe((start_info: NewSessionInfo | null) => {
if (start_info != null && start_info.initial_desktop_size !== null) {
@ -68,11 +70,13 @@
type: 'info',
message: 'Success',
});
currentSession.update(session => Object.assign(session, {
sessionId: start_info.session_id,
desktopSize: start_info.initial_desktop_size,
active: true,
}));
currentSession.update((session) =>
Object.assign(session, {
sessionId: start_info.session_id,
desktopSize: start_info.initial_desktop_size,
active: true,
}),
);
showLogin.set(false);
} else {
toast.set({
@ -85,48 +89,48 @@
</script>
<main class="responsive">
<div class="large-space"/>
<div class="large-space" />
<div class="grid">
<div class="s2"/>
<div class="s2" />
<div class="s8">
<article class="primary-container">
<h5>Login</h5>
<div class="medium-space"/>
<div class="medium-space" />
<div>
<div class="field label border">
<input id="hostname" type="text" bind:value={hostname}/>
<input id="hostname" type="text" bind:value={hostname} />
<label for="hostname">Hostname</label>
</div>
<div class="field label border">
<input id="domain" type="text" bind:value={domain}/>
<input id="domain" type="text" bind:value={domain} />
<label for="domain">Domain</label>
</div>
<div class="field label border">
<input id="username" type="text" bind:value={username}/>
<input id="username" type="text" bind:value={username} />
<label for="username">Username</label>
</div>
<div class="field label border">
<input id="password" type="password" bind:value={password}/>
<input id="password" type="password" bind:value={password} />
<label for="password">Password</label>
</div>
<div class="field label border">
<input id="gatewayAddress" type="text" bind:value={gatewayAddress}/>
<input id="gatewayAddress" type="text" bind:value={gatewayAddress} />
<label for="gatewayAddress">Gateway Address</label>
</div>
<div class="field label border">
<input id="authtoken" type="text" bind:value={authtoken}/>
<input id="authtoken" type="text" bind:value={authtoken} />
<label for="authtoken">AuthToken</label>
</div>
<div class="field label border">
<input id="pcb" type="text" bind:value={pcb}/>
<input id="pcb" type="text" bind:value={pcb} />
<label for="pcb">Pre Connection Blob</label>
</div>
<div class="field label border">
<input id="desktopSizeW" type="text" bind:value={desktopSize.width}/>
<input id="desktopSizeW" type="text" bind:value={desktopSize.width} />
<label for="desktopSizeW">Desktop Width</label>
</div>
<div class="field label border">
<input id="desktopSizeH" type="text" bind:value={desktopSize.height}/>
<input id="desktopSizeH" type="text" bind:value={desktopSize.height} />
<label for="desktopSizeH">Desktop Height</label>
</div>
</div>
@ -135,11 +139,10 @@
</nav>
</article>
</div>
<div class="s2"/>
<div class="s2" />
</div>
</main>
<style>
@import './login.css';
</style>

View file

@ -1,8 +1,8 @@
import type {Writable} from 'svelte/store';
import {writable} from 'svelte/store';
import type { Writable } from 'svelte/store';
import { writable } from 'svelte/store';
type ToastMessage = {
message: string,
type: 'info' | 'error'
message: string;
type: 'info' | 'error';
};
export const toast: Writable<ToastMessage> = writable();
export const toast: Writable<ToastMessage> = writable();

View file

@ -1,9 +1,9 @@
<script lang="ts">
import {toast} from '$lib/messages/message-store';
import { toast } from '$lib/messages/message-store';
let toastMessage: string;
toast.subscribe(t => {
toast.subscribe((t) => {
if (t != null) {
toastMessage = t.message;
switch (t.type) {
@ -24,7 +24,6 @@
}
}
});
</script>
<div id="toast" class="toast blue white-text">

View file

@ -1,25 +1,22 @@
<script lang="ts">
import {onMount} from 'svelte';
import {
setCurrentSessionActive,
userInteractionService
} from '../../services/session.service';
import {showLogin} from '$lib/login/login-store';
import { onMount } from 'svelte';
import { setCurrentSessionActive, userInteractionService } from '../../services/session.service';
import { showLogin } from '$lib/login/login-store';
import type { UserInteraction } from '../../../static/iron-remote-gui/main';
let uiService: UserInteraction;
userInteractionService.subscribe(uis => {
userInteractionService.subscribe((uis) => {
if (uis != null) {
uiService = uis
uiService.sessionListener.subscribe(event => {
uiService = uis;
uiService.sessionListener.subscribe((event) => {
if (event.type === 0) {
uiService.setVisibility(true);
} else if (event.type === 1) {
setCurrentSessionActive(false);
showLogin.set(true);
}
})
});
}
});
@ -27,7 +24,7 @@
let el = document.querySelector('iron-remote-gui');
if (el == null) {
throw "`iron-remote-gui` element not found";
throw '`iron-remote-gui` element not found';
}
el.addEventListener('ready', (e) => {
@ -36,28 +33,30 @@
});
});
</script>
<div style="display: flex; height: 100%; flex-direction: column; background-color: #2e2e2e;" class:hideall={$showLogin}>
<div style="text-align: center; padding: 10px; background: black;">
<button on:click={() => uiService.setScale(1)}>Fit</button>
<button on:click={() => uiService.setScale(2)}>Full</button>
<button on:click={() => uiService.setScale(3)}>Real</button>
<button on:click={() => uiService.ctrlAltDel()}>Ctrl+Alt+Del</button>
<button on:click={() => uiService.metaKey()}>Meta
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 512 512"><title>
ionicons-v5_logos</title>
<path d="M480,265H232V444l248,36V265Z"/>
<path d="M216,265H32V415l184,26.7V265Z"/>
<path d="M480,32,232,67.4V249H480V32Z"/>
<path d="M216,69.7,32,96V249H216V69.7Z"/>
<button on:click={() => uiService.metaKey()}
>Meta
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 512 512"
><title> ionicons-v5_logos</title>
<path d="M480,265H232V444l248,36V265Z" />
<path d="M216,265H32V415l184,26.7V265Z" />
<path d="M480,32,232,67.4V249H480V32Z" />
<path d="M216,69.7,32,96V249H216V69.7Z" />
</svg>
</button>
<button on:click={() => uiService.shutdown()}>Terminate Session</button>
</div>
<iron-remote-gui debugwasm="INFO" verbose="true" scale="fit" flexcenter="true"/>
<iron-remote-gui debugwasm="INFO" verbose="true" scale="fit" flexcenter="true" />
</div>
<style>
.hideall {
display: none !important;
}
</style>
</style>

View file

@ -1,4 +1,4 @@
export class DesktopSize {
width!: number;
height!: number;
width!: number;
height!: number;
}

View file

@ -1,7 +1,7 @@
export class Rect {
top!: number;
left!: number;
width!: number;
height!: number;
buffer!: ArrayBuffer
top!: number;
left!: number;
width!: number;
height!: number;
buffer!: ArrayBuffer;
}

View file

@ -1,16 +1,16 @@
import {Guid} from "guid-typescript";
import type { DesktopSize } from "./desktop-size";
import { Guid } from 'guid-typescript';
import type { DesktopSize } from './desktop-size';
export class Session {
id:Guid;
sessionId!: number;
name?:string;
active!: boolean;
desktopSize!: DesktopSize;
id: Guid;
sessionId!: number;
name?: string;
active!: boolean;
desktopSize!: DesktopSize;
constructor(name?: string) {
this.id = Guid.create();
this.name = name;
this.active = false;
}
constructor(name?: string) {
this.id = Guid.create();
this.name = name;
this.active = false;
}
}

View file

@ -1,4 +1,4 @@
<script>
import { goto } from '$app/navigation';
goto("/session");
goto('/session');
</script>

View file

@ -2,14 +2,12 @@
import Login from '$lib/login/login.svelte';
import RemoteScreen from '$lib/remote-screen/remote-screen.svelte';
import Message from '$lib/messages/message.svelte';
import {showLogin} from "$lib/login/login-store";
import { showLogin } from '$lib/login/login-store';
</script>
{#if $showLogin}
<Login/>
<Login />
{/if}
<RemoteScreen/>
<RemoteScreen />
<Message></Message>

View file

@ -1,39 +1,38 @@
import type {Observable} from "rxjs";
import type { Observable } from 'rxjs';
export interface ServerRect {
free(): void;
free(): void;
clone_buffer(): Uint8Array;
clone_buffer(): Uint8Array;
bottom: number;
left: number;
right: number;
top: number;
bottom: number;
left: number;
right: number;
top: number;
}
export interface NewSessionInfo {
session_id: number,
websocket_port: number,
initial_desktop_size: DesktopSize,
session_id: number;
websocket_port: number;
initial_desktop_size: DesktopSize;
}
export interface DesktopSize {
width: number,
height: number
width: number;
height: number;
}
export interface ResizeEvent {
session_id: number,
desktop_size: DesktopSize,
session_id: number;
desktop_size: DesktopSize;
}
export abstract class ServerBridgeService {
abstract init(): void;
abstract init(): void;
abstract connect(username: string, password: string, address: string): Observable<NewSessionInfo>;
abstract connect(username: string, password: string, address: string): Observable<NewSessionInfo>;
abstract resize: Observable<ResizeEvent>;
abstract resize: Observable<ResizeEvent>;
abstract updateMouse(mouse_x: number, mouse_y: number, click_state: number): void;
abstract updateMouse(mouse_x: number, mouse_y: number, click_state: number): void;
}

View file

@ -1,8 +1,8 @@
import type {Guid} from "guid-typescript";
import type {Writable} from "svelte/store";
import {writable} from "svelte/store";
import {Session} from "../models/session";
import type {UserInteraction} from '../../static/iron-remote-gui';
import type { Guid } from 'guid-typescript';
import type { Writable } from 'svelte/store';
import { writable } from 'svelte/store';
import { Session } from '../models/session';
import type { UserInteraction } from '../../static/iron-remote-gui';
export const userInteractionService: Writable<UserInteraction> = writable();
export const currentSession: Writable<Session> = writable();
@ -23,14 +23,14 @@ export function getCurrentSession(): Session {
}
export function setCurrentSessionActive(active: boolean) {
currentSession.update(session => {
session.active = active;
return session;
});
currentSession.update((session) => {
session.active = active;
return session;
});
}
export function setCurrentSessionById(id: Guid) {
const session = sessions.find(session => session.id.equals(id));
const session = sessions.find((session) => session.id.equals(id));
if (session) {
setCurrentSession(session);
}
@ -47,7 +47,7 @@ export function addSession(name: string) {
export function closeSession(id: Guid) {
sessionCounter--;
sessions = sessions.filter(session => !session.id.equals(id));
sessions = sessions.filter((session) => !session.id.equals(id));
if (sessionCounter == 1) {
setCurrentSession(sessions[0]);
}

View file

@ -1,59 +1,59 @@
body.light {
--primary: #0061a6;
--on-primary: #ffffff;
--primary-container: #d0e4ff;
--on-primary-container: #001d36;
--secondary: #535f70;
--on-secondary: #ffffff;
--secondary-container: #d6e3f7;
--on-secondary-container: #101c2b;
--tertiary: #6b5778;
--on-tertiary: #ffffff;
--tertiary-container: #f3daff;
--on-tertiary-container: #251432;
--error: #ba1b1b;
--error-container: #ffdad4;
--on-error: #ffffff;
--on-error-container: #410001;
--background: #fdfcff;
--on-background: #1b1b1b;
--surface: #fdfcff;
--on-surface: #1b1b1b;
--surface-variant: #dfe2eb;
--on-surface-variant: #42474e;
--outline: #73777f;
--inverse-on-surface: #f1f0f4;
--inverse-surface: #2f3033;
--inverse-primary: #9ccaff;
--shadow: #000000;
--primary: #0061a6;
--on-primary: #ffffff;
--primary-container: #d0e4ff;
--on-primary-container: #001d36;
--secondary: #535f70;
--on-secondary: #ffffff;
--secondary-container: #d6e3f7;
--on-secondary-container: #101c2b;
--tertiary: #6b5778;
--on-tertiary: #ffffff;
--tertiary-container: #f3daff;
--on-tertiary-container: #251432;
--error: #ba1b1b;
--error-container: #ffdad4;
--on-error: #ffffff;
--on-error-container: #410001;
--background: #fdfcff;
--on-background: #1b1b1b;
--surface: #fdfcff;
--on-surface: #1b1b1b;
--surface-variant: #dfe2eb;
--on-surface-variant: #42474e;
--outline: #73777f;
--inverse-on-surface: #f1f0f4;
--inverse-surface: #2f3033;
--inverse-primary: #9ccaff;
--shadow: #000000;
}
body.dark {
--primary: #9ccaff;
--on-primary: #00325a;
--primary-container: #00497f;
--on-primary-container: #d0e4ff;
--secondary: #bbc8db;
--on-secondary: #253140;
--secondary-container: #3c4858;
--on-secondary-container: #d6e3f7;
--tertiary: #d6bee4;
--on-tertiary: #3b2948;
--tertiary-container: #523f5f;
--on-tertiary-container: #f3daff;
--error: #ffb4a9;
--error-container: #930006;
--on-error: #680003;
--on-error-container: #ffdad4;
--background: #1b1b1b;
--on-background: #e2e2e6;
--surface: #1b1b1b;
--on-surface: #e2e2e6;
--surface-variant: #42474e;
--on-surface-variant: #c3c7d0;
--outline: #8d9199;
--inverse-on-surface: #1b1b1b;
--inverse-surface: #e2e2e6;
--inverse-primary: #0061a6;
--shadow: #000000;
--primary: #9ccaff;
--on-primary: #00325a;
--primary-container: #00497f;
--on-primary-container: #d0e4ff;
--secondary: #bbc8db;
--on-secondary: #253140;
--secondary-container: #3c4858;
--on-secondary-container: #d6e3f7;
--tertiary: #d6bee4;
--on-tertiary: #3b2948;
--tertiary-container: #523f5f;
--on-tertiary-container: #f3daff;
--error: #ffb4a9;
--error-container: #930006;
--on-error: #680003;
--on-error-container: #ffdad4;
--background: #1b1b1b;
--on-background: #e2e2e6;
--surface: #1b1b1b;
--on-surface: #e2e2e6;
--surface-variant: #42474e;
--on-surface-variant: #c3c7d0;
--outline: #8d9199;
--inverse-on-surface: #1b1b1b;
--inverse-surface: #e2e2e6;
--inverse-primary: #0061a6;
--shadow: #000000;
}

View file

@ -3,19 +3,19 @@ import preprocess from 'svelte-preprocess';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: preprocess(),
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: preprocess(),
kit: {
adapter: adapter({
pages: 'build/browser',
assets: 'build/browser',
fallback: null,
precompress: false,
strict: true
})
}
kit: {
adapter: adapter({
pages: 'build/browser',
assets: 'build/browser',
fallback: null,
precompress: false,
strict: true,
}),
},
};
export default config;

View file

@ -1,19 +1,19 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": false,
"checkJs": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": false,
"checkJs": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true
},
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

View file

@ -4,8 +4,8 @@ import wasm from 'vite-plugin-wasm';
import topLevelAwait from 'vite-plugin-top-level-await';
const config: UserConfig = {
mode: 'process.env.MODE' || 'development',
plugins: [sveltekit(), wasm(), topLevelAwait()],
mode: 'process.env.MODE' || 'development',
plugins: [sveltekit(), wasm(), topLevelAwait()],
};
export default config;