This commit is contained in:
Miroslav Šedivý 2024-03-17 00:00:14 +01:00
parent 37f93eae6b
commit 27d88cee08
70 changed files with 6271 additions and 13595 deletions

View File

@ -1,3 +0,0 @@
{
"presets": ["@vue/cli-plugin-babel/preset"]
}

View File

@ -1,19 +0,0 @@
{
"root": true,
"env": {
"node": true
},
"extends": ["plugin:vue/essential", "@vue/prettier", "@vue/typescript"],
"parserOptions": {
"parser": "@typescript-eslint/parser"
},
"rules": {
"vue/multi-word-component-names": "off",
"vue/valid-v-for": "off",
"no-case-declarations": "off",
"no-dupe-class-members": "off",
"no-console": "off",
"no-empty": "off"
},
"ignorePatterns": ["**/*.js"]
}

26
.eslintrc.cjs Normal file
View File

@ -0,0 +1,26 @@
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting'
],
overrides: [
{
files: [
'e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'
],
'extends': [
'plugin:playwright/recommended'
]
}
],
parserOptions: {
ecmaVersion: 'latest'
},
ignorePatterns: ["**/*.js"]
}

37
.gitignore vendored
View File

@ -1,6 +1,33 @@
.env.local # Logs
node_modules logs
dist *.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
/src/page/plugins/* node_modules
!/src/page/plugins/.gitkeep .DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo
test-results/
playwright-report/

View File

@ -1,8 +0,0 @@
{
"semi": false,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 120,
"tabWidth": 2,
"vueIndentScriptAndStyle": true
}

8
.prettierrc.json Normal file
View File

@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"tabWidth": 2,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none"
}

15
.vscode/settings.json vendored
View File

@ -2,22 +2,9 @@
"editor.tabSize": 2, "editor.tabSize": 2,
"editor.insertSpaces": true, "editor.insertSpaces": true,
"editor.detectIndentation": false, "editor.detectIndentation": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.encoding": "utf8", "files.encoding": "utf8",
"files.eol": "\n", "files.eol": "\n",
"typescript.tsdk": "./node_modules/typescript/lib",
"todo-tree.filtering.excludeGlobs": ["**/node_modules/**"],
"eslint.validate": [
"vue",
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
],
"vetur.validation.template": true,
"vetur.useWorkspaceDependencies": true,
"remote.extensionKind": {
"ms-azuretools.vscode-docker": "ui"
},
"editor.formatOnSave": false, "editor.formatOnSave": false,
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit" "source.fixAll.eslint": "explicit"

View File

@ -1,11 +0,0 @@
FROM node:18-buster-slim
COPY . /app
WORKDIR /app
RUN npm i
EXPOSE 8080
CMD [ "npm", "run", "serve" ]

View File

@ -24,6 +24,68 @@ npm run build
KEYBOARD=novnc npm run build KEYBOARD=novnc npm run build
``` ```
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
## Type Support for `.vue` Imports in TS
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Type-Check, Compile and Minify for Production
```sh
npm run build
```
### Run Unit Tests with [Vitest](https://vitest.dev/)
```sh
npm run test:unit
```
### Run End-to-End Tests with [Playwright](https://playwright.dev)
```sh
# Install browsers for the first run
npx playwright install
# When testing on CI, must build the project first
npm run build
# Runs the end-to-end tests
npm run test:e2e
# Runs the tests only on Chromium
npm run test:e2e -- --project=chromium
# Runs the tests of a specific file
npm run test:e2e -- tests/example.spec.ts
# Runs the tests in debug mode
npm run test:e2e -- --debug
```
### Lint with [ESLint](https://eslint.org/)
```sh
npm run lint
```
### Example ### Example
API consists of accessing Vue reactive state, calling various methods and subscribing to events. Simple usage: API consists of accessing Vue reactive state, calling various methods and subscribing to events. Simple usage:

4
e2e/tsconfig.json Normal file
View File

@ -0,0 +1,4 @@
{
"extends": "@tsconfig/node20/tsconfig.json",
"include": ["./**/*"]
}

8
e2e/vue.spec.ts Normal file
View File

@ -0,0 +1,8 @@
import { test, expect } from '@playwright/test';
// See here how to get started:
// https://playwright.dev/docs/intro
test('visits the app root url', async ({ page }) => {
await page.goto('/');
await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
})

1
env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

12
index.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neko</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

12107
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +1,55 @@
{ {
"name": "@demodesk/neko", "name": "@demodesk/neko",
"version": "1.6.32", "version": "2.0.0",
"description": "Client as reusable Vue.js component for neko streaming server.", "description": "Client as reusable Vue.js component for neko streaming server.",
"repository": "https://github.com/demodesk/neko-client", "repository": "https://github.com/demodesk/neko-client",
"publishConfig": { "publishConfig": {
"registry": "https://npm.pkg.github.com" "registry": "https://npm.pkg.github.com"
}, },
"type": "module",
"main": "dist/neko.umd.js", "main": "dist/neko.umd.js",
"module": "dist/neko.common.js", "module": "dist/neko.common.js",
"typings": "dist/types/main.d.ts", "typings": "dist/types/main.d.ts",
"scripts": { "scripts": {
"serve": "vue-cli-service serve --mode development", "dev": "vite",
"lint": "vue-cli-service lint", "build": "run-p type-check \"build-only {@}\" --",
"build": "vue-cli-service build --target lib --name neko ./src/lib.ts && ./types-build.sh", "preview": "vite preview",
"build:page": "vue-cli-service build" "test:unit": "vitest",
"test:e2e": "playwright test",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
}, },
"dependencies": { "dependencies": {
"axios": "^1.6.7", "axios": "^1.6.8",
"eventemitter3": "^5.0.0", "eventemitter3": "^5.0.1",
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"vue": "^2.7.16", "vue": "^3.4.21"
"vue-class-component": "^7.2.6",
"vue-property-decorator": "^9.1.2"
}, },
"devDependencies": { "devDependencies": {
"@fortawesome/fontawesome-free": "^6.1.1", "@fortawesome/fontawesome-free": "^6.5.1",
"@types/node": "^18.0.0", "@playwright/test": "^1.42.1",
"@types/vue": "^2.0.0", "@rushstack/eslint-patch": "^1.3.3",
"@typescript-eslint/eslint-plugin": "^6.19.1", "@tsconfig/node20": "^20.1.2",
"@typescript-eslint/parser": "^6.19.1", "@types/jsdom": "^21.1.6",
"@vue/cli-plugin-babel": "^5.0.4", "@types/node": "^20.11.25",
"@vue/cli-plugin-eslint": "^5.0.4", "@vitejs/plugin-vue": "^5.0.4",
"@vue/cli-plugin-typescript": "^5.0.4", "@vue/eslint-config-prettier": "^8.0.0",
"@vue/cli-service": "^5.0.4",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^12.0.0", "@vue/eslint-config-typescript": "^12.0.0",
"eslint": "^8.15.0", "@vue/test-utils": "^2.4.4",
"eslint-plugin-prettier": "^5.1.3", "@vue/tsconfig": "^0.5.1",
"eslint-plugin-vue": "^9.20.1", "eslint": "^8.49.0",
"prettier": "^3.2.4", "eslint-plugin-playwright": "^1.5.2",
"sass": "^1.51.0", "eslint-plugin-vue": "^9.17.0",
"sass-loader": "^14.0.0", "jsdom": "^24.0.0",
"ts-node": "^10.7.0", "npm-run-all2": "^6.1.2",
"typescript": "^5.3.3", "prettier": "^3.0.3",
"vue-template-compiler": "^2.6.14" "sass": "^1.72.0",
"typescript": "~5.4.0",
"vite": "^5.1.5",
"vitest": "^1.3.1",
"vue-tsc": "^2.0.6"
}, },
"files": [ "files": [
"dist/*" "dist/*"

110
playwright.config.ts Normal file
View File

@ -0,0 +1,110 @@
import process from 'node:process'
import { defineConfig, devices } from '@playwright/test'
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './e2e',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000
},
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:5173',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
/* Only on CI systems run the tests headless */
headless: !!process.env.CI
},
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome']
}
},
{
name: 'firefox',
use: {
...devices['Desktop Firefox']
}
},
{
name: 'webkit',
use: {
...devices['Desktop Safari']
}
}
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: {
// ...devices['Pixel 5'],
// },
// },
// {
// name: 'Mobile Safari',
// use: {
// ...devices['iPhone 12'],
// },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: {
// channel: 'msedge',
// },
// },
// {
// name: 'Google Chrome',
// use: {
// channel: 'chrome',
// },
// },
],
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',
/* Run your local dev server before starting the tests */
webServer: {
/**
* Use the dev server by default for faster feedback loop.
* Use the preview server on CI for more realistic testing.
* Playwright will re-use the local server if there is already a dev-server running.
*/
command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
port: 5173,
reuseExistingServer: !process.env.CI
}
})

View File

@ -20,6 +20,7 @@ models/error-message.ts
models/index.ts models/index.ts
models/keyboard-map.ts models/keyboard-map.ts
models/keyboard-modifiers.ts models/keyboard-modifiers.ts
models/member-bulk-delete.ts
models/member-bulk-update.ts models/member-bulk-update.ts
models/member-create.ts models/member-create.ts
models/member-data.ts models/member-data.ts

View File

@ -1 +1 @@
6.6.0-SNAPSHOT 7.4.0-SNAPSHOT

View File

@ -14,17 +14,14 @@
import type { Configuration } from '../configuration'; import type { Configuration } from '../configuration';
import type { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'; import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
import globalAxios from 'axios'; import globalAxios from 'axios';
// Some imports not used depending on template conditions // Some imports not used depending on template conditions
// @ts-ignore
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';
// @ts-ignore import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError, operationServerMap } from '../base';
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base'; import type { RequestArgs } from '../base';
// @ts-ignore import type { BatchRequest } from '../models';
import { BatchRequest } from '../models'; import type { BatchResponse } from '../models';
// @ts-ignore
import { BatchResponse } from '../models';
/** /**
* DefaultApi - axios parameter creator * DefaultApi - axios parameter creator
* @export * @export
@ -38,7 +35,7 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
batch: async (batchRequest: Array<BatchRequest>, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { batch: async (batchRequest: Array<BatchRequest>, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'batchRequest' is not null or undefined // verify required parameter 'batchRequest' is not null or undefined
assertParamExists('batch', 'batchRequest', batchRequest) assertParamExists('batch', 'batchRequest', batchRequest)
const localVarPath = `/api/batch`; const localVarPath = `/api/batch`;
@ -82,7 +79,7 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
healthcheck: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { healthcheck: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/health`; const localVarPath = `/health`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -112,7 +109,7 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
metrics: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { metrics: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/metrics`; const localVarPath = `/metrics`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -153,9 +150,11 @@ export const DefaultApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async batch(batchRequest: Array<BatchRequest>, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<BatchResponse>>> { async batch(batchRequest: Array<BatchRequest>, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<BatchResponse>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.batch(batchRequest, options); const localVarAxiosArgs = await localVarAxiosParamCreator.batch(batchRequest, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['DefaultApi.batch']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -163,9 +162,11 @@ export const DefaultApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async healthcheck(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async healthcheck(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.healthcheck(options); const localVarAxiosArgs = await localVarAxiosParamCreator.healthcheck(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['DefaultApi.healthcheck']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -173,9 +174,11 @@ export const DefaultApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async metrics(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async metrics(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.metrics(options); const localVarAxiosArgs = await localVarAxiosParamCreator.metrics(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['DefaultApi.metrics']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
} }
}; };
@ -233,7 +236,7 @@ export class DefaultApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof DefaultApi * @memberof DefaultApi
*/ */
public batch(batchRequest: Array<BatchRequest>, options?: AxiosRequestConfig) { public batch(batchRequest: Array<BatchRequest>, options?: RawAxiosRequestConfig) {
return DefaultApiFp(this.configuration).batch(batchRequest, options).then((request) => request(this.axios, this.basePath)); return DefaultApiFp(this.configuration).batch(batchRequest, options).then((request) => request(this.axios, this.basePath));
} }
@ -244,7 +247,7 @@ export class DefaultApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof DefaultApi * @memberof DefaultApi
*/ */
public healthcheck(options?: AxiosRequestConfig) { public healthcheck(options?: RawAxiosRequestConfig) {
return DefaultApiFp(this.configuration).healthcheck(options).then((request) => request(this.axios, this.basePath)); return DefaultApiFp(this.configuration).healthcheck(options).then((request) => request(this.axios, this.basePath));
} }
@ -255,7 +258,8 @@ export class DefaultApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof DefaultApi * @memberof DefaultApi
*/ */
public metrics(options?: AxiosRequestConfig) { public metrics(options?: RawAxiosRequestConfig) {
return DefaultApiFp(this.configuration).metrics(options).then((request) => request(this.axios, this.basePath)); return DefaultApiFp(this.configuration).metrics(options).then((request) => request(this.axios, this.basePath));
} }
} }

View File

@ -14,31 +14,70 @@
import type { Configuration } from '../configuration'; import type { Configuration } from '../configuration';
import type { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'; import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
import globalAxios from 'axios'; import globalAxios from 'axios';
// Some imports not used depending on template conditions // Some imports not used depending on template conditions
// @ts-ignore
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';
// @ts-ignore import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError, operationServerMap } from '../base';
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base'; import type { RequestArgs } from '../base';
// @ts-ignore import type { ErrorMessage } from '../models';
import { ErrorMessage } from '../models'; import type { MemberBulkDelete } from '../models';
// @ts-ignore import type { MemberBulkUpdate } from '../models';
import { MemberBulkUpdate } from '../models'; import type { MemberCreate } from '../models';
// @ts-ignore import type { MemberData } from '../models';
import { MemberCreate } from '../models'; import type { MemberPassword } from '../models';
// @ts-ignore import type { MemberProfile } from '../models';
import { MemberData } from '../models';
// @ts-ignore
import { MemberPassword } from '../models';
// @ts-ignore
import { MemberProfile } from '../models';
/** /**
* MembersApi - axios parameter creator * MembersApi - axios parameter creator
* @export * @export
*/ */
export const MembersApiAxiosParamCreator = function (configuration?: Configuration) { export const MembersApiAxiosParamCreator = function (configuration?: Configuration) {
return { return {
/**
*
* @summary bulk delete members
* @param {MemberBulkDelete} memberBulkDelete
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
membersBulkDelete: async (memberBulkDelete: MemberBulkDelete, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'memberBulkDelete' is not null or undefined
assertParamExists('membersBulkDelete', 'memberBulkDelete', memberBulkDelete)
const localVarPath = `/api/members_bulk/delete`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication CookieAuth required
// authentication TokenAuth required
await setApiKeyToObject(localVarQueryParameter, "token", configuration)
// authentication BearerAuth required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(memberBulkDelete, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/** /**
* *
* @summary bulk update members * @summary bulk update members
@ -46,7 +85,7 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
membersBulkUpdate: async (memberBulkUpdate: MemberBulkUpdate, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { membersBulkUpdate: async (memberBulkUpdate: MemberBulkUpdate, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'memberBulkUpdate' is not null or undefined // verify required parameter 'memberBulkUpdate' is not null or undefined
assertParamExists('membersBulkUpdate', 'memberBulkUpdate', memberBulkUpdate) assertParamExists('membersBulkUpdate', 'memberBulkUpdate', memberBulkUpdate)
const localVarPath = `/api/members_bulk/update`; const localVarPath = `/api/members_bulk/update`;
@ -91,7 +130,7 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
membersCreate: async (memberCreate: MemberCreate, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { membersCreate: async (memberCreate: MemberCreate, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'memberCreate' is not null or undefined // verify required parameter 'memberCreate' is not null or undefined
assertParamExists('membersCreate', 'memberCreate', memberCreate) assertParamExists('membersCreate', 'memberCreate', memberCreate)
const localVarPath = `/api/members`; const localVarPath = `/api/members`;
@ -136,7 +175,7 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
membersGetProfile: async (memberId: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { membersGetProfile: async (memberId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'memberId' is not null or undefined // verify required parameter 'memberId' is not null or undefined
assertParamExists('membersGetProfile', 'memberId', memberId) assertParamExists('membersGetProfile', 'memberId', memberId)
const localVarPath = `/api/members/{memberId}` const localVarPath = `/api/members/{memberId}`
@ -180,7 +219,7 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
membersList: async (limit?: number, offset?: number, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { membersList: async (limit?: number, offset?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/members`; const localVarPath = `/api/members`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -228,7 +267,7 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
membersRemove: async (memberId: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { membersRemove: async (memberId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'memberId' is not null or undefined // verify required parameter 'memberId' is not null or undefined
assertParamExists('membersRemove', 'memberId', memberId) assertParamExists('membersRemove', 'memberId', memberId)
const localVarPath = `/api/members/{memberId}` const localVarPath = `/api/members/{memberId}`
@ -272,7 +311,7 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
membersUpdatePassword: async (memberId: string, memberPassword: MemberPassword, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { membersUpdatePassword: async (memberId: string, memberPassword: MemberPassword, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'memberId' is not null or undefined // verify required parameter 'memberId' is not null or undefined
assertParamExists('membersUpdatePassword', 'memberId', memberId) assertParamExists('membersUpdatePassword', 'memberId', memberId)
// verify required parameter 'memberPassword' is not null or undefined // verify required parameter 'memberPassword' is not null or undefined
@ -321,7 +360,7 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
membersUpdateProfile: async (memberId: string, memberProfile: MemberProfile, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { membersUpdateProfile: async (memberId: string, memberProfile: MemberProfile, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'memberId' is not null or undefined // verify required parameter 'memberId' is not null or undefined
assertParamExists('membersUpdateProfile', 'memberId', memberId) assertParamExists('membersUpdateProfile', 'memberId', memberId)
// verify required parameter 'memberProfile' is not null or undefined // verify required parameter 'memberProfile' is not null or undefined
@ -372,6 +411,19 @@ export const MembersApiAxiosParamCreator = function (configuration?: Configurati
export const MembersApiFp = function(configuration?: Configuration) { export const MembersApiFp = function(configuration?: Configuration) {
const localVarAxiosParamCreator = MembersApiAxiosParamCreator(configuration) const localVarAxiosParamCreator = MembersApiAxiosParamCreator(configuration)
return { return {
/**
*
* @summary bulk delete members
* @param {MemberBulkDelete} memberBulkDelete
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async membersBulkDelete(memberBulkDelete: MemberBulkDelete, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersBulkDelete(memberBulkDelete, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersBulkDelete']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/** /**
* *
* @summary bulk update members * @summary bulk update members
@ -379,9 +431,11 @@ export const MembersApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async membersBulkUpdate(memberBulkUpdate: MemberBulkUpdate, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async membersBulkUpdate(memberBulkUpdate: MemberBulkUpdate, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersBulkUpdate(memberBulkUpdate, options); const localVarAxiosArgs = await localVarAxiosParamCreator.membersBulkUpdate(memberBulkUpdate, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersBulkUpdate']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -390,9 +444,11 @@ export const MembersApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async membersCreate(memberCreate: MemberCreate, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MemberData>> { async membersCreate(memberCreate: MemberCreate, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MemberData>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersCreate(memberCreate, options); const localVarAxiosArgs = await localVarAxiosParamCreator.membersCreate(memberCreate, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersCreate']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -401,9 +457,11 @@ export const MembersApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async membersGetProfile(memberId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MemberProfile>> { async membersGetProfile(memberId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MemberProfile>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersGetProfile(memberId, options); const localVarAxiosArgs = await localVarAxiosParamCreator.membersGetProfile(memberId, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersGetProfile']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -413,9 +471,11 @@ export const MembersApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async membersList(limit?: number, offset?: number, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<MemberData>>> { async membersList(limit?: number, offset?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<MemberData>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersList(limit, offset, options); const localVarAxiosArgs = await localVarAxiosParamCreator.membersList(limit, offset, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersList']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -424,9 +484,11 @@ export const MembersApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async membersRemove(memberId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async membersRemove(memberId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersRemove(memberId, options); const localVarAxiosArgs = await localVarAxiosParamCreator.membersRemove(memberId, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersRemove']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -436,9 +498,11 @@ export const MembersApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async membersUpdatePassword(memberId: string, memberPassword: MemberPassword, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async membersUpdatePassword(memberId: string, memberPassword: MemberPassword, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersUpdatePassword(memberId, memberPassword, options); const localVarAxiosArgs = await localVarAxiosParamCreator.membersUpdatePassword(memberId, memberPassword, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersUpdatePassword']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -448,9 +512,11 @@ export const MembersApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async membersUpdateProfile(memberId: string, memberProfile: MemberProfile, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async membersUpdateProfile(memberId: string, memberProfile: MemberProfile, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.membersUpdateProfile(memberId, memberProfile, options); const localVarAxiosArgs = await localVarAxiosParamCreator.membersUpdateProfile(memberId, memberProfile, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['MembersApi.membersUpdateProfile']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
} }
}; };
@ -462,6 +528,16 @@ export const MembersApiFp = function(configuration?: Configuration) {
export const MembersApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { export const MembersApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
const localVarFp = MembersApiFp(configuration) const localVarFp = MembersApiFp(configuration)
return { return {
/**
*
* @summary bulk delete members
* @param {MemberBulkDelete} memberBulkDelete
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
membersBulkDelete(memberBulkDelete: MemberBulkDelete, options?: any): AxiosPromise<void> {
return localVarFp.membersBulkDelete(memberBulkDelete, options).then((request) => request(axios, basePath));
},
/** /**
* *
* @summary bulk update members * @summary bulk update members
@ -545,6 +621,18 @@ export const MembersApiFactory = function (configuration?: Configuration, basePa
* @extends {BaseAPI} * @extends {BaseAPI}
*/ */
export class MembersApi extends BaseAPI { export class MembersApi extends BaseAPI {
/**
*
* @summary bulk delete members
* @param {MemberBulkDelete} memberBulkDelete
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof MembersApi
*/
public membersBulkDelete(memberBulkDelete: MemberBulkDelete, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersBulkDelete(memberBulkDelete, options).then((request) => request(this.axios, this.basePath));
}
/** /**
* *
* @summary bulk update members * @summary bulk update members
@ -553,7 +641,7 @@ export class MembersApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof MembersApi * @memberof MembersApi
*/ */
public membersBulkUpdate(memberBulkUpdate: MemberBulkUpdate, options?: AxiosRequestConfig) { public membersBulkUpdate(memberBulkUpdate: MemberBulkUpdate, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersBulkUpdate(memberBulkUpdate, options).then((request) => request(this.axios, this.basePath)); return MembersApiFp(this.configuration).membersBulkUpdate(memberBulkUpdate, options).then((request) => request(this.axios, this.basePath));
} }
@ -565,7 +653,7 @@ export class MembersApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof MembersApi * @memberof MembersApi
*/ */
public membersCreate(memberCreate: MemberCreate, options?: AxiosRequestConfig) { public membersCreate(memberCreate: MemberCreate, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersCreate(memberCreate, options).then((request) => request(this.axios, this.basePath)); return MembersApiFp(this.configuration).membersCreate(memberCreate, options).then((request) => request(this.axios, this.basePath));
} }
@ -577,7 +665,7 @@ export class MembersApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof MembersApi * @memberof MembersApi
*/ */
public membersGetProfile(memberId: string, options?: AxiosRequestConfig) { public membersGetProfile(memberId: string, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersGetProfile(memberId, options).then((request) => request(this.axios, this.basePath)); return MembersApiFp(this.configuration).membersGetProfile(memberId, options).then((request) => request(this.axios, this.basePath));
} }
@ -590,7 +678,7 @@ export class MembersApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof MembersApi * @memberof MembersApi
*/ */
public membersList(limit?: number, offset?: number, options?: AxiosRequestConfig) { public membersList(limit?: number, offset?: number, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersList(limit, offset, options).then((request) => request(this.axios, this.basePath)); return MembersApiFp(this.configuration).membersList(limit, offset, options).then((request) => request(this.axios, this.basePath));
} }
@ -602,7 +690,7 @@ export class MembersApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof MembersApi * @memberof MembersApi
*/ */
public membersRemove(memberId: string, options?: AxiosRequestConfig) { public membersRemove(memberId: string, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersRemove(memberId, options).then((request) => request(this.axios, this.basePath)); return MembersApiFp(this.configuration).membersRemove(memberId, options).then((request) => request(this.axios, this.basePath));
} }
@ -615,7 +703,7 @@ export class MembersApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof MembersApi * @memberof MembersApi
*/ */
public membersUpdatePassword(memberId: string, memberPassword: MemberPassword, options?: AxiosRequestConfig) { public membersUpdatePassword(memberId: string, memberPassword: MemberPassword, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersUpdatePassword(memberId, memberPassword, options).then((request) => request(this.axios, this.basePath)); return MembersApiFp(this.configuration).membersUpdatePassword(memberId, memberPassword, options).then((request) => request(this.axios, this.basePath));
} }
@ -628,7 +716,8 @@ export class MembersApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof MembersApi * @memberof MembersApi
*/ */
public membersUpdateProfile(memberId: string, memberProfile: MemberProfile, options?: AxiosRequestConfig) { public membersUpdateProfile(memberId: string, memberProfile: MemberProfile, options?: RawAxiosRequestConfig) {
return MembersApiFp(this.configuration).membersUpdateProfile(memberId, memberProfile, options).then((request) => request(this.axios, this.basePath)); return MembersApiFp(this.configuration).membersUpdateProfile(memberId, memberProfile, options).then((request) => request(this.axios, this.basePath));
} }
} }

View File

@ -14,29 +14,20 @@
import type { Configuration } from '../configuration'; import type { Configuration } from '../configuration';
import type { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'; import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
import globalAxios from 'axios'; import globalAxios from 'axios';
// Some imports not used depending on template conditions // Some imports not used depending on template conditions
// @ts-ignore
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';
// @ts-ignore import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError, operationServerMap } from '../base';
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base'; import type { RequestArgs } from '../base';
// @ts-ignore import type { BroadcastStatus } from '../models';
import { BroadcastStatus } from '../models'; import type { ClipboardText } from '../models';
// @ts-ignore import type { ControlStatus } from '../models';
import { ClipboardText } from '../models'; import type { ErrorMessage } from '../models';
// @ts-ignore import type { KeyboardMap } from '../models';
import { ControlStatus } from '../models'; import type { KeyboardModifiers } from '../models';
// @ts-ignore import type { ScreenConfiguration } from '../models';
import { ErrorMessage } from '../models'; import type { Settings } from '../models';
// @ts-ignore
import { KeyboardMap } from '../models';
// @ts-ignore
import { KeyboardModifiers } from '../models';
// @ts-ignore
import { ScreenConfiguration } from '../models';
// @ts-ignore
import { Settings } from '../models';
/** /**
* RoomApi - axios parameter creator * RoomApi - axios parameter creator
* @export * @export
@ -50,7 +41,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
boradcastStart: async (broadcastStatus: BroadcastStatus, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { boradcastStart: async (broadcastStatus: BroadcastStatus, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'broadcastStatus' is not null or undefined // verify required parameter 'broadcastStatus' is not null or undefined
assertParamExists('boradcastStart', 'broadcastStatus', broadcastStatus) assertParamExists('boradcastStart', 'broadcastStatus', broadcastStatus)
const localVarPath = `/api/room/broadcast/start`; const localVarPath = `/api/room/broadcast/start`;
@ -94,7 +85,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
boradcastStop: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { boradcastStop: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/broadcast/stop`; const localVarPath = `/api/room/broadcast/stop`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -133,7 +124,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
broadcastStatus: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { broadcastStatus: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/broadcast`; const localVarPath = `/api/room/broadcast`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -172,7 +163,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
clipboardGetImage: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { clipboardGetImage: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/clipboard/image.png`; const localVarPath = `/api/room/clipboard/image.png`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -211,7 +202,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
clipboardGetText: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { clipboardGetText: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/clipboard`; const localVarPath = `/api/room/clipboard`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -251,7 +242,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
clipboardSetText: async (clipboardText: ClipboardText, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { clipboardSetText: async (clipboardText: ClipboardText, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'clipboardText' is not null or undefined // verify required parameter 'clipboardText' is not null or undefined
assertParamExists('clipboardSetText', 'clipboardText', clipboardText) assertParamExists('clipboardSetText', 'clipboardText', clipboardText)
const localVarPath = `/api/room/clipboard`; const localVarPath = `/api/room/clipboard`;
@ -296,7 +287,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
controlGive: async (sessionId: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { controlGive: async (sessionId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'sessionId' is not null or undefined // verify required parameter 'sessionId' is not null or undefined
assertParamExists('controlGive', 'sessionId', sessionId) assertParamExists('controlGive', 'sessionId', sessionId)
const localVarPath = `/api/room/control/give/{sessionId}` const localVarPath = `/api/room/control/give/{sessionId}`
@ -338,7 +329,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
controlRelease: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { controlRelease: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/control/release`; const localVarPath = `/api/room/control/release`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -377,7 +368,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
controlRequest: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { controlRequest: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/control/request`; const localVarPath = `/api/room/control/request`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -416,7 +407,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
controlReset: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { controlReset: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/control/reset`; const localVarPath = `/api/room/control/reset`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -455,7 +446,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
controlStatus: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { controlStatus: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/control`; const localVarPath = `/api/room/control`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -494,7 +485,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
controlTake: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { controlTake: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/control/take`; const localVarPath = `/api/room/control/take`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -533,7 +524,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
keyboardMapGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { keyboardMapGet: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/keyboard/map`; const localVarPath = `/api/room/keyboard/map`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -573,7 +564,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
keyboardMapSet: async (keyboardMap: KeyboardMap, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { keyboardMapSet: async (keyboardMap: KeyboardMap, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'keyboardMap' is not null or undefined // verify required parameter 'keyboardMap' is not null or undefined
assertParamExists('keyboardMapSet', 'keyboardMap', keyboardMap) assertParamExists('keyboardMapSet', 'keyboardMap', keyboardMap)
const localVarPath = `/api/room/keyboard/map`; const localVarPath = `/api/room/keyboard/map`;
@ -617,7 +608,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
keyboardModifiersGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { keyboardModifiersGet: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/keyboard/modifiers`; const localVarPath = `/api/room/keyboard/modifiers`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -657,7 +648,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
keyboardModifiersSet: async (keyboardModifiers: KeyboardModifiers, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { keyboardModifiersSet: async (keyboardModifiers: KeyboardModifiers, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'keyboardModifiers' is not null or undefined // verify required parameter 'keyboardModifiers' is not null or undefined
assertParamExists('keyboardModifiersSet', 'keyboardModifiers', keyboardModifiers) assertParamExists('keyboardModifiersSet', 'keyboardModifiers', keyboardModifiers)
const localVarPath = `/api/room/keyboard/modifiers`; const localVarPath = `/api/room/keyboard/modifiers`;
@ -701,7 +692,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
screenCastImage: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { screenCastImage: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/screen/cast.jpg`; const localVarPath = `/api/room/screen/cast.jpg`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -740,7 +731,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
screenConfiguration: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { screenConfiguration: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/screen`; const localVarPath = `/api/room/screen`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -780,7 +771,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
screenConfigurationChange: async (screenConfiguration: ScreenConfiguration, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { screenConfigurationChange: async (screenConfiguration: ScreenConfiguration, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'screenConfiguration' is not null or undefined // verify required parameter 'screenConfiguration' is not null or undefined
assertParamExists('screenConfigurationChange', 'screenConfiguration', screenConfiguration) assertParamExists('screenConfigurationChange', 'screenConfiguration', screenConfiguration)
const localVarPath = `/api/room/screen`; const localVarPath = `/api/room/screen`;
@ -824,7 +815,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
screenConfigurationsList: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { screenConfigurationsList: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/screen/configurations`; const localVarPath = `/api/room/screen/configurations`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -863,7 +854,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
screenShotImage: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { screenShotImage: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/screen/shot.jpg`; const localVarPath = `/api/room/screen/shot.jpg`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -902,7 +893,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
settingsGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { settingsGet: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/settings`; const localVarPath = `/api/room/settings`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -942,7 +933,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
settingsSet: async (settings: Settings, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { settingsSet: async (settings: Settings, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'settings' is not null or undefined // verify required parameter 'settings' is not null or undefined
assertParamExists('settingsSet', 'settings', settings) assertParamExists('settingsSet', 'settings', settings)
const localVarPath = `/api/room/settings`; const localVarPath = `/api/room/settings`;
@ -987,7 +978,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
uploadDialog: async (files?: Array<File>, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { uploadDialog: async (files?: Array<File>, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/upload/dialog`; const localVarPath = `/api/room/upload/dialog`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -1036,7 +1027,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
uploadDialogClose: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { uploadDialogClose: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/upload/dialog`; const localVarPath = `/api/room/upload/dialog`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -1078,7 +1069,7 @@ export const RoomApiAxiosParamCreator = function (configuration?: Configuration)
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
uploadDrop: async (x?: number, y?: number, files?: Array<File>, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { uploadDrop: async (x?: number, y?: number, files?: Array<File>, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/room/upload/drop`; const localVarPath = `/api/room/upload/drop`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -1146,9 +1137,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async boradcastStart(broadcastStatus: BroadcastStatus, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async boradcastStart(broadcastStatus: BroadcastStatus, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.boradcastStart(broadcastStatus, options); const localVarAxiosArgs = await localVarAxiosParamCreator.boradcastStart(broadcastStatus, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.boradcastStart']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1156,9 +1149,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async boradcastStop(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async boradcastStop(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.boradcastStop(options); const localVarAxiosArgs = await localVarAxiosParamCreator.boradcastStop(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.boradcastStop']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1166,9 +1161,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async broadcastStatus(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<BroadcastStatus>> { async broadcastStatus(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<BroadcastStatus>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.broadcastStatus(options); const localVarAxiosArgs = await localVarAxiosParamCreator.broadcastStatus(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.broadcastStatus']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1176,9 +1173,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async clipboardGetImage(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> { async clipboardGetImage(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.clipboardGetImage(options); const localVarAxiosArgs = await localVarAxiosParamCreator.clipboardGetImage(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.clipboardGetImage']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1186,9 +1185,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async clipboardGetText(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ClipboardText>> { async clipboardGetText(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ClipboardText>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.clipboardGetText(options); const localVarAxiosArgs = await localVarAxiosParamCreator.clipboardGetText(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.clipboardGetText']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1197,9 +1198,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async clipboardSetText(clipboardText: ClipboardText, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async clipboardSetText(clipboardText: ClipboardText, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.clipboardSetText(clipboardText, options); const localVarAxiosArgs = await localVarAxiosParamCreator.clipboardSetText(clipboardText, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.clipboardSetText']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1208,9 +1211,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async controlGive(sessionId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async controlGive(sessionId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.controlGive(sessionId, options); const localVarAxiosArgs = await localVarAxiosParamCreator.controlGive(sessionId, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.controlGive']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1218,9 +1223,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async controlRelease(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async controlRelease(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.controlRelease(options); const localVarAxiosArgs = await localVarAxiosParamCreator.controlRelease(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.controlRelease']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1228,9 +1235,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async controlRequest(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async controlRequest(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.controlRequest(options); const localVarAxiosArgs = await localVarAxiosParamCreator.controlRequest(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.controlRequest']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1238,9 +1247,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async controlReset(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async controlReset(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.controlReset(options); const localVarAxiosArgs = await localVarAxiosParamCreator.controlReset(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.controlReset']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1248,9 +1259,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async controlStatus(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ControlStatus>> { async controlStatus(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ControlStatus>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.controlStatus(options); const localVarAxiosArgs = await localVarAxiosParamCreator.controlStatus(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.controlStatus']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1258,9 +1271,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async controlTake(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async controlTake(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.controlTake(options); const localVarAxiosArgs = await localVarAxiosParamCreator.controlTake(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.controlTake']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1268,9 +1283,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async keyboardMapGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<KeyboardMap>> { async keyboardMapGet(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<KeyboardMap>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardMapGet(options); const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardMapGet(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.keyboardMapGet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1279,9 +1296,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async keyboardMapSet(keyboardMap: KeyboardMap, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async keyboardMapSet(keyboardMap: KeyboardMap, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardMapSet(keyboardMap, options); const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardMapSet(keyboardMap, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.keyboardMapSet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1289,9 +1308,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async keyboardModifiersGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<KeyboardModifiers>> { async keyboardModifiersGet(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<KeyboardModifiers>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardModifiersGet(options); const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardModifiersGet(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.keyboardModifiersGet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1300,9 +1321,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async keyboardModifiersSet(keyboardModifiers: KeyboardModifiers, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async keyboardModifiersSet(keyboardModifiers: KeyboardModifiers, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardModifiersSet(keyboardModifiers, options); const localVarAxiosArgs = await localVarAxiosParamCreator.keyboardModifiersSet(keyboardModifiers, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.keyboardModifiersSet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1310,9 +1333,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async screenCastImage(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> { async screenCastImage(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.screenCastImage(options); const localVarAxiosArgs = await localVarAxiosParamCreator.screenCastImage(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.screenCastImage']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1320,9 +1345,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async screenConfiguration(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ScreenConfiguration>> { async screenConfiguration(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ScreenConfiguration>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.screenConfiguration(options); const localVarAxiosArgs = await localVarAxiosParamCreator.screenConfiguration(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.screenConfiguration']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1331,9 +1358,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async screenConfigurationChange(screenConfiguration: ScreenConfiguration, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ScreenConfiguration>> { async screenConfigurationChange(screenConfiguration: ScreenConfiguration, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ScreenConfiguration>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.screenConfigurationChange(screenConfiguration, options); const localVarAxiosArgs = await localVarAxiosParamCreator.screenConfigurationChange(screenConfiguration, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.screenConfigurationChange']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1341,9 +1370,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async screenConfigurationsList(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ScreenConfiguration>>> { async screenConfigurationsList(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ScreenConfiguration>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.screenConfigurationsList(options); const localVarAxiosArgs = await localVarAxiosParamCreator.screenConfigurationsList(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.screenConfigurationsList']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1351,9 +1382,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async screenShotImage(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> { async screenShotImage(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.screenShotImage(options); const localVarAxiosArgs = await localVarAxiosParamCreator.screenShotImage(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.screenShotImage']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1361,9 +1394,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async settingsGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Settings>> { async settingsGet(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Settings>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.settingsGet(options); const localVarAxiosArgs = await localVarAxiosParamCreator.settingsGet(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.settingsGet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1372,9 +1407,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async settingsSet(settings: Settings, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async settingsSet(settings: Settings, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.settingsSet(settings, options); const localVarAxiosArgs = await localVarAxiosParamCreator.settingsSet(settings, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.settingsSet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1383,9 +1420,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async uploadDialog(files?: Array<File>, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async uploadDialog(files?: Array<File>, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.uploadDialog(files, options); const localVarAxiosArgs = await localVarAxiosParamCreator.uploadDialog(files, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.uploadDialog']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1393,9 +1432,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async uploadDialogClose(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async uploadDialogClose(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.uploadDialogClose(options); const localVarAxiosArgs = await localVarAxiosParamCreator.uploadDialogClose(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.uploadDialogClose']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -1406,9 +1447,11 @@ export const RoomApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async uploadDrop(x?: number, y?: number, files?: Array<File>, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async uploadDrop(x?: number, y?: number, files?: Array<File>, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.uploadDrop(x, y, files, options); const localVarAxiosArgs = await localVarAxiosParamCreator.uploadDrop(x, y, files, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['RoomApi.uploadDrop']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
} }
}; };
@ -1683,7 +1726,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public boradcastStart(broadcastStatus: BroadcastStatus, options?: AxiosRequestConfig) { public boradcastStart(broadcastStatus: BroadcastStatus, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).boradcastStart(broadcastStatus, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).boradcastStart(broadcastStatus, options).then((request) => request(this.axios, this.basePath));
} }
@ -1694,7 +1737,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public boradcastStop(options?: AxiosRequestConfig) { public boradcastStop(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).boradcastStop(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).boradcastStop(options).then((request) => request(this.axios, this.basePath));
} }
@ -1705,7 +1748,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public broadcastStatus(options?: AxiosRequestConfig) { public broadcastStatus(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).broadcastStatus(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).broadcastStatus(options).then((request) => request(this.axios, this.basePath));
} }
@ -1716,7 +1759,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public clipboardGetImage(options?: AxiosRequestConfig) { public clipboardGetImage(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).clipboardGetImage(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).clipboardGetImage(options).then((request) => request(this.axios, this.basePath));
} }
@ -1727,7 +1770,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public clipboardGetText(options?: AxiosRequestConfig) { public clipboardGetText(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).clipboardGetText(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).clipboardGetText(options).then((request) => request(this.axios, this.basePath));
} }
@ -1739,7 +1782,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public clipboardSetText(clipboardText: ClipboardText, options?: AxiosRequestConfig) { public clipboardSetText(clipboardText: ClipboardText, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).clipboardSetText(clipboardText, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).clipboardSetText(clipboardText, options).then((request) => request(this.axios, this.basePath));
} }
@ -1751,7 +1794,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public controlGive(sessionId: string, options?: AxiosRequestConfig) { public controlGive(sessionId: string, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).controlGive(sessionId, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).controlGive(sessionId, options).then((request) => request(this.axios, this.basePath));
} }
@ -1762,7 +1805,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public controlRelease(options?: AxiosRequestConfig) { public controlRelease(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).controlRelease(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).controlRelease(options).then((request) => request(this.axios, this.basePath));
} }
@ -1773,7 +1816,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public controlRequest(options?: AxiosRequestConfig) { public controlRequest(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).controlRequest(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).controlRequest(options).then((request) => request(this.axios, this.basePath));
} }
@ -1784,7 +1827,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public controlReset(options?: AxiosRequestConfig) { public controlReset(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).controlReset(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).controlReset(options).then((request) => request(this.axios, this.basePath));
} }
@ -1795,7 +1838,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public controlStatus(options?: AxiosRequestConfig) { public controlStatus(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).controlStatus(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).controlStatus(options).then((request) => request(this.axios, this.basePath));
} }
@ -1806,7 +1849,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public controlTake(options?: AxiosRequestConfig) { public controlTake(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).controlTake(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).controlTake(options).then((request) => request(this.axios, this.basePath));
} }
@ -1817,7 +1860,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public keyboardMapGet(options?: AxiosRequestConfig) { public keyboardMapGet(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).keyboardMapGet(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).keyboardMapGet(options).then((request) => request(this.axios, this.basePath));
} }
@ -1829,7 +1872,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public keyboardMapSet(keyboardMap: KeyboardMap, options?: AxiosRequestConfig) { public keyboardMapSet(keyboardMap: KeyboardMap, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).keyboardMapSet(keyboardMap, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).keyboardMapSet(keyboardMap, options).then((request) => request(this.axios, this.basePath));
} }
@ -1840,7 +1883,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public keyboardModifiersGet(options?: AxiosRequestConfig) { public keyboardModifiersGet(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).keyboardModifiersGet(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).keyboardModifiersGet(options).then((request) => request(this.axios, this.basePath));
} }
@ -1852,7 +1895,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public keyboardModifiersSet(keyboardModifiers: KeyboardModifiers, options?: AxiosRequestConfig) { public keyboardModifiersSet(keyboardModifiers: KeyboardModifiers, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).keyboardModifiersSet(keyboardModifiers, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).keyboardModifiersSet(keyboardModifiers, options).then((request) => request(this.axios, this.basePath));
} }
@ -1863,7 +1906,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public screenCastImage(options?: AxiosRequestConfig) { public screenCastImage(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).screenCastImage(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).screenCastImage(options).then((request) => request(this.axios, this.basePath));
} }
@ -1874,7 +1917,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public screenConfiguration(options?: AxiosRequestConfig) { public screenConfiguration(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).screenConfiguration(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).screenConfiguration(options).then((request) => request(this.axios, this.basePath));
} }
@ -1886,7 +1929,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public screenConfigurationChange(screenConfiguration: ScreenConfiguration, options?: AxiosRequestConfig) { public screenConfigurationChange(screenConfiguration: ScreenConfiguration, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).screenConfigurationChange(screenConfiguration, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).screenConfigurationChange(screenConfiguration, options).then((request) => request(this.axios, this.basePath));
} }
@ -1897,7 +1940,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public screenConfigurationsList(options?: AxiosRequestConfig) { public screenConfigurationsList(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).screenConfigurationsList(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).screenConfigurationsList(options).then((request) => request(this.axios, this.basePath));
} }
@ -1908,7 +1951,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public screenShotImage(options?: AxiosRequestConfig) { public screenShotImage(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).screenShotImage(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).screenShotImage(options).then((request) => request(this.axios, this.basePath));
} }
@ -1919,7 +1962,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public settingsGet(options?: AxiosRequestConfig) { public settingsGet(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).settingsGet(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).settingsGet(options).then((request) => request(this.axios, this.basePath));
} }
@ -1931,7 +1974,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public settingsSet(settings: Settings, options?: AxiosRequestConfig) { public settingsSet(settings: Settings, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).settingsSet(settings, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).settingsSet(settings, options).then((request) => request(this.axios, this.basePath));
} }
@ -1943,7 +1986,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public uploadDialog(files?: Array<File>, options?: AxiosRequestConfig) { public uploadDialog(files?: Array<File>, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).uploadDialog(files, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).uploadDialog(files, options).then((request) => request(this.axios, this.basePath));
} }
@ -1954,7 +1997,7 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public uploadDialogClose(options?: AxiosRequestConfig) { public uploadDialogClose(options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).uploadDialogClose(options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).uploadDialogClose(options).then((request) => request(this.axios, this.basePath));
} }
@ -1968,7 +2011,8 @@ export class RoomApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof RoomApi * @memberof RoomApi
*/ */
public uploadDrop(x?: number, y?: number, files?: Array<File>, options?: AxiosRequestConfig) { public uploadDrop(x?: number, y?: number, files?: Array<File>, options?: RawAxiosRequestConfig) {
return RoomApiFp(this.configuration).uploadDrop(x, y, files, options).then((request) => request(this.axios, this.basePath)); return RoomApiFp(this.configuration).uploadDrop(x, y, files, options).then((request) => request(this.axios, this.basePath));
} }
} }

View File

@ -14,19 +14,15 @@
import type { Configuration } from '../configuration'; import type { Configuration } from '../configuration';
import type { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'; import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
import globalAxios from 'axios'; import globalAxios from 'axios';
// Some imports not used depending on template conditions // Some imports not used depending on template conditions
// @ts-ignore
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';
// @ts-ignore import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError, operationServerMap } from '../base';
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base'; import type { RequestArgs } from '../base';
// @ts-ignore import type { ErrorMessage } from '../models';
import { ErrorMessage } from '../models'; import type { SessionData } from '../models';
// @ts-ignore import type { SessionLogin } from '../models';
import { SessionData } from '../models';
// @ts-ignore
import { SessionLogin } from '../models';
/** /**
* SessionApi - axios parameter creator * SessionApi - axios parameter creator
* @export * @export
@ -40,7 +36,7 @@ export const SessionApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
login: async (sessionLogin: SessionLogin, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { login: async (sessionLogin: SessionLogin, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'sessionLogin' is not null or undefined // verify required parameter 'sessionLogin' is not null or undefined
assertParamExists('login', 'sessionLogin', sessionLogin) assertParamExists('login', 'sessionLogin', sessionLogin)
const localVarPath = `/api/login`; const localVarPath = `/api/login`;
@ -75,7 +71,7 @@ export const SessionApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
logout: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { logout: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/logout`; const localVarPath = `/api/logout`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -99,6 +95,45 @@ export const SessionApiAxiosParamCreator = function (configuration?: Configurati
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary get sessions
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
sessionsGet: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/sessions`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication CookieAuth required
// authentication TokenAuth required
await setApiKeyToObject(localVarQueryParameter, "token", configuration)
// authentication BearerAuth required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter); setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
@ -114,7 +149,7 @@ export const SessionApiAxiosParamCreator = function (configuration?: Configurati
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
whoami: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { whoami: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/whoami`; const localVarPath = `/api/whoami`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -164,9 +199,11 @@ export const SessionApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async login(sessionLogin: SessionLogin, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SessionData>> { async login(sessionLogin: SessionLogin, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SessionData>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.login(sessionLogin, options); const localVarAxiosArgs = await localVarAxiosParamCreator.login(sessionLogin, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['SessionApi.login']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -174,9 +211,23 @@ export const SessionApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async logout(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> { async logout(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.logout(options); const localVarAxiosArgs = await localVarAxiosParamCreator.logout(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['SessionApi.logout']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
*
* @summary get sessions
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async sessionsGet(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<SessionData>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.sessionsGet(options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['SessionApi.sessionsGet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/** /**
* *
@ -184,9 +235,11 @@ export const SessionApiFp = function(configuration?: Configuration) {
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async whoami(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SessionData>> { async whoami(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SessionData>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.whoami(options); const localVarAxiosArgs = await localVarAxiosParamCreator.whoami(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['SessionApi.whoami']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
} }
}; };
@ -217,6 +270,15 @@ export const SessionApiFactory = function (configuration?: Configuration, basePa
logout(options?: any): AxiosPromise<void> { logout(options?: any): AxiosPromise<void> {
return localVarFp.logout(options).then((request) => request(axios, basePath)); return localVarFp.logout(options).then((request) => request(axios, basePath));
}, },
/**
*
* @summary get sessions
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
sessionsGet(options?: any): AxiosPromise<Array<SessionData>> {
return localVarFp.sessionsGet(options).then((request) => request(axios, basePath));
},
/** /**
* *
* @summary whoami * @summary whoami
@ -244,7 +306,7 @@ export class SessionApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof SessionApi * @memberof SessionApi
*/ */
public login(sessionLogin: SessionLogin, options?: AxiosRequestConfig) { public login(sessionLogin: SessionLogin, options?: RawAxiosRequestConfig) {
return SessionApiFp(this.configuration).login(sessionLogin, options).then((request) => request(this.axios, this.basePath)); return SessionApiFp(this.configuration).login(sessionLogin, options).then((request) => request(this.axios, this.basePath));
} }
@ -255,10 +317,21 @@ export class SessionApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof SessionApi * @memberof SessionApi
*/ */
public logout(options?: AxiosRequestConfig) { public logout(options?: RawAxiosRequestConfig) {
return SessionApiFp(this.configuration).logout(options).then((request) => request(this.axios, this.basePath)); return SessionApiFp(this.configuration).logout(options).then((request) => request(this.axios, this.basePath));
} }
/**
*
* @summary get sessions
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SessionApi
*/
public sessionsGet(options?: RawAxiosRequestConfig) {
return SessionApiFp(this.configuration).sessionsGet(options).then((request) => request(this.axios, this.basePath));
}
/** /**
* *
* @summary whoami * @summary whoami
@ -266,7 +339,8 @@ export class SessionApi extends BaseAPI {
* @throws {RequiredError} * @throws {RequiredError}
* @memberof SessionApi * @memberof SessionApi
*/ */
public whoami(options?: AxiosRequestConfig) { public whoami(options?: RawAxiosRequestConfig) {
return SessionApiFp(this.configuration).whoami(options).then((request) => request(this.axios, this.basePath)); return SessionApiFp(this.configuration).whoami(options).then((request) => request(this.axios, this.basePath));
} }
} }

View File

@ -16,7 +16,7 @@
import type { Configuration } from './configuration'; import type { Configuration } from './configuration';
// Some imports not used depending on template conditions // Some imports not used depending on template conditions
// @ts-ignore // @ts-ignore
import type { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'; import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
import globalAxios from 'axios'; import globalAxios from 'axios';
export const BASE_PATH = "http://localhost:3000".replace(/\/+$/, ""); export const BASE_PATH = "http://localhost:3000".replace(/\/+$/, "");
@ -39,7 +39,7 @@ export const COLLECTION_FORMATS = {
*/ */
export interface RequestArgs { export interface RequestArgs {
url: string; url: string;
options: AxiosRequestConfig; options: RawAxiosRequestConfig;
} }
/** /**
@ -53,7 +53,7 @@ export class BaseAPI {
constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) { constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {
if (configuration) { if (configuration) {
this.configuration = configuration; this.configuration = configuration;
this.basePath = configuration.basePath || this.basePath; this.basePath = configuration.basePath ?? basePath;
} }
} }
}; };
@ -70,3 +70,17 @@ export class RequiredError extends Error {
this.name = "RequiredError" this.name = "RequiredError"
} }
} }
interface ServerMap {
[key: string]: {
url: string,
description: string,
}[];
}
/**
*
* @export
*/
export const operationServerMap: ServerMap = {
}

View File

@ -144,7 +144,7 @@ export const toPathString = function (url: URL) {
*/ */
export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) { export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) {
return <T = unknown, R = AxiosResponse<T>>(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { return <T = unknown, R = AxiosResponse<T>>(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs = {...axiosArgs.options, url: (configuration?.basePath || basePath) + axiosArgs.url}; const axiosRequestArgs = {...axiosArgs.options, url: (axios.defaults.baseURL ? '' : configuration?.basePath ?? basePath) + axiosArgs.url};
return axios.request<T, R>(axiosRequestArgs); return axios.request<T, R>(axiosRequestArgs);
}; };
} }

View File

@ -19,6 +19,7 @@ export interface ConfigurationParameters {
password?: string; password?: string;
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>); accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
basePath?: string; basePath?: string;
serverIndex?: number;
baseOptions?: any; baseOptions?: any;
formDataCtor?: new () => any; formDataCtor?: new () => any;
} }
@ -58,6 +59,13 @@ export class Configuration {
* @memberof Configuration * @memberof Configuration
*/ */
basePath?: string; basePath?: string;
/**
* override server index
*
* @type {number}
* @memberof Configuration
*/
serverIndex?: number;
/** /**
* base options for axios calls * base options for axios calls
* *
@ -80,6 +88,7 @@ export class Configuration {
this.password = param.password; this.password = param.password;
this.accessToken = param.accessToken; this.accessToken = param.accessToken;
this.basePath = param.basePath; this.basePath = param.basePath;
this.serverIndex = param.serverIndex;
this.baseOptions = param.baseOptions; this.baseOptions = param.baseOptions;
this.formDataCtor = param.formDataCtor; this.formDataCtor = param.formDataCtor;
} }

View File

@ -1,18 +1,19 @@
export * from './batch-request' export * from './batch-request';
export * from './batch-response' export * from './batch-response';
export * from './broadcast-status' export * from './broadcast-status';
export * from './clipboard-text' export * from './clipboard-text';
export * from './control-status' export * from './control-status';
export * from './error-message' export * from './error-message';
export * from './keyboard-map' export * from './keyboard-map';
export * from './keyboard-modifiers' export * from './keyboard-modifiers';
export * from './member-bulk-update' export * from './member-bulk-delete';
export * from './member-create' export * from './member-bulk-update';
export * from './member-data' export * from './member-create';
export * from './member-password' export * from './member-data';
export * from './member-profile' export * from './member-password';
export * from './screen-configuration' export * from './member-profile';
export * from './session-data' export * from './screen-configuration';
export * from './session-login' export * from './session-data';
export * from './session-state' export * from './session-login';
export * from './settings' export * from './session-state';
export * from './settings';

View File

@ -0,0 +1,30 @@
/* tslint:disable */
/* eslint-disable */
/**
* n.eko REST API
* Next Gen Renderer.
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
*
* @export
* @interface MemberBulkDelete
*/
export interface MemberBulkDelete {
/**
*
* @type {Array<string>}
* @memberof MemberBulkDelete
*/
'ids'?: Array<string>;
}

View File

@ -15,7 +15,7 @@
// May contain unused imports in some cases // May contain unused imports in some cases
// @ts-ignore // @ts-ignore
import { MemberProfile } from './member-profile'; import type { MemberProfile } from './member-profile';
/** /**
* *

View File

@ -14,8 +14,7 @@
// May contain unused imports in some cases // May contain unused imports in some cases
// @ts-ignore import type { MemberProfile } from './member-profile';
import { MemberProfile } from './member-profile';
/** /**
* *

View File

@ -14,8 +14,7 @@
// May contain unused imports in some cases // May contain unused imports in some cases
// @ts-ignore import type { MemberProfile } from './member-profile';
import { MemberProfile } from './member-profile';
/** /**
* *

View File

@ -14,11 +14,9 @@
// May contain unused imports in some cases // May contain unused imports in some cases
// @ts-ignore import type { MemberProfile } from './member-profile';
import { MemberProfile } from './member-profile';
// May contain unused imports in some cases // May contain unused imports in some cases
// @ts-ignore import type { SessionState } from './session-state';
import { SessionState } from './session-state';
/** /**
* *

View File

@ -13,265 +13,250 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Ref, Prop, Watch } from 'vue-property-decorator'
import { SessionCursors, Cursor, Session } from './types/state' import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { InactiveCursorDrawFunction, Dimension } from './types/cursors'
import { getMovementXYatPercent } from './utils/canvas-movement'
// How often are position data arriving import type { SessionCursors, Cursor, Session } from './types/state'
const POS_INTERVAL_MS = 750 import type { InactiveCursorDrawFunction, Dimension } from './types/cursors'
// How many pixel change is considered as movement import { getMovementXYatPercent } from './utils/canvas-movement'
const POS_THRESHOLD_PX = 20
@Component({ // How often are position data arriving
name: 'neko-cursors', const POS_INTERVAL_MS = 750
}) // How many pixel change is considered as movement
export default class extends Vue { const POS_THRESHOLD_PX = 20
@Ref('overlay') readonly _overlay!: HTMLCanvasElement
_ctx!: CanvasRenderingContext2D
canvasScale = window.devicePixelRatio const props = defineProps<{
sessions: Record<string, Session>
sessionId: string
hostId: string | null
screenSize: Dimension
canvasSize: Dimension
cursors: SessionCursors[]
cursorDraw: InactiveCursorDrawFunction | null
fps: number
}>()
@Prop() const overlay = ref<HTMLCanvasElement | null>(null)
readonly sessions!: Record<string, Session> const ctx = ref<CanvasRenderingContext2D | null>(null)
const canvasScale = ref(window.devicePixelRatio)
@Prop() let unsubscribePixelRatioChange = null as (() => void) | null
readonly sessionId!: string
@Prop() onMounted(() => {
readonly hostId!: string | null // get canvas overlay context
const canvas = overlay.value
if (canvas != null) {
ctx.value = canvas.getContext('2d')
@Prop() // synchronize intrinsic with extrinsic dimensions
readonly screenSize!: Dimension const { width, height } = canvas.getBoundingClientRect()
canvasResize({ width, height })
@Prop()
readonly canvasSize!: Dimension
@Prop()
readonly cursors!: SessionCursors[]
@Prop()
readonly cursorDraw!: InactiveCursorDrawFunction | null
@Prop()
readonly fps!: number
mounted() {
// get canvas overlay context
const ctx = this._overlay.getContext('2d')
if (ctx != null) {
this._ctx = ctx
}
// synchronize intrinsic with extrinsic dimensions
const { width, height } = this._overlay.getBoundingClientRect()
this.canvasResize({ width, height })
// react to pixel ratio changes
this.onPixelRatioChange()
// store last drawing points
this._last_points = {}
}
beforeDestroy() {
// stop pixel ratio change listener
if (this.unsubscribePixelRatioChange) {
this.unsubscribePixelRatioChange()
}
}
private unsubscribePixelRatioChange?: () => void
private onPixelRatioChange() {
if (this.unsubscribePixelRatioChange) {
this.unsubscribePixelRatioChange()
}
const media = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)
media.addEventListener('change', this.onPixelRatioChange)
this.unsubscribePixelRatioChange = () => {
media.removeEventListener('change', this.onPixelRatioChange)
}
this.canvasScale = window.devicePixelRatio
this.onCanvasSizeChange(this.canvasSize)
}
@Watch('canvasSize')
onCanvasSizeChange({ width, height }: Dimension) {
this.canvasResize({ width, height })
this.canvasUpdateCursors()
}
canvasResize({ width, height }: Dimension) {
this._overlay.width = width * this.canvasScale
this._overlay.height = height * this.canvasScale
this._ctx.setTransform(this.canvasScale, 0, 0, this.canvasScale, 0, 0)
}
// start as undefined to prevent jumping
private _last_animation_time!: number
// current animation progress (0-1)
private _percent!: number
// points to be animated for each session
private _points!: SessionCursors[]
// last points coordinates for each session
private _last_points!: Record<string, Cursor>
canvasAnimateFrame(now: number = NaN) {
// request another frame
if (this._percent <= 1) window.requestAnimationFrame(this.canvasAnimateFrame)
// calc elapsed time since last loop
const elapsed = now - this._last_animation_time
// skip if fps is set and elapsed time is less than fps
if (this.fps > 0 && elapsed < 1000 / this.fps) return
// calc current animation progress
const delta = elapsed / POS_INTERVAL_MS
this._last_animation_time = now
// skip very first delta to prevent jumping
if (isNaN(delta)) return
// set the animation position
this._percent += delta
// draw points for current frame
this.canvasDrawPoints(this._percent)
}
canvasDrawPoints(percent: number = 1) {
// clear canvas
this.canvasClear()
// draw current position
for (const p of this._points) {
const { x, y } = getMovementXYatPercent(p.cursors, percent)
this.canvasDrawCursor(x, y, p.id)
}
}
@Watch('hostId')
@Watch('cursors')
canvasUpdateCursors() {
let new_last_points = {} as Record<string, Cursor>
// track unchanged cursors
let unchanged = 0
// create points for animation
this._points = []
for (const { id, cursors } of this.cursors) {
if (
// if there are no positions
cursors.length == 0 ||
// ignore own cursor
id == this.sessionId ||
// ignore host's cursor
id == this.hostId
) {
unchanged++
continue
}
// get last point
const new_last_point = cursors[cursors.length - 1]
// add last cursor position to cursors (if available)
let pos = { id } as SessionCursors
if (id in this._last_points) {
const last_point = this._last_points[id]
// if cursor did not move considerably
if (
Math.abs(last_point.x - new_last_point.x) < POS_THRESHOLD_PX &&
Math.abs(last_point.y - new_last_point.y) < POS_THRESHOLD_PX
) {
// we knew that this cursor did not change, but other
// might, so we keep only one point to be drawn
pos.cursors = [new_last_point]
// and increase unchanged counter
unchanged++
} else {
// if cursor moved, we want to include last point
// in the animation, so that movement can be seamless
pos.cursors = [last_point, ...cursors]
}
} else {
// if cursor does not have last point, it is not
// displayed in canvas and it should be now
pos.cursors = [...cursors]
}
new_last_points[id] = new_last_point
this._points.push(pos)
}
// apply new last points
this._last_points = new_last_points
// no cursors to animate
if (this._points.length == 0) {
this.canvasClear()
return
}
// if all cursors are unchanged
if (unchanged == this.cursors.length) {
// draw only last known position without animation
this.canvasDrawPoints()
return
}
// start animation if not running
const percent = this._percent
this._percent = 0
if (percent > 1 || !percent) {
this.canvasAnimateFrame()
}
}
canvasDrawCursor(x: number, y: number, id: string) {
// get intrinsic dimensions
const { width, height } = this.canvasSize
x = Math.round((x / this.screenSize.width) * width)
y = Math.round((y / this.screenSize.height) * height)
// reset transformation, X and Y will be 0 again
this._ctx.setTransform(this.canvasScale, 0, 0, this.canvasScale, 0, 0)
// use custom draw function, if available
if (this.cursorDraw) {
this.cursorDraw(this._ctx, x, y, id)
return
}
// get cursor tag
const cursorTag = this.sessions[id]?.profile.name || ''
// draw inactive cursor tag
this._ctx.font = '14px Arial, sans-serif'
this._ctx.textBaseline = 'top'
this._ctx.shadowColor = 'black'
this._ctx.shadowBlur = 2
this._ctx.lineWidth = 2
this._ctx.fillStyle = 'black'
this._ctx.strokeText(cursorTag, x, y)
this._ctx.shadowBlur = 0
this._ctx.fillStyle = 'white'
this._ctx.fillText(cursorTag, x, y)
}
canvasClear() {
// reset transformation, X and Y will be 0 again
this._ctx.setTransform(this.canvasScale, 0, 0, this.canvasScale, 0, 0)
const { width, height } = this.canvasSize
this._ctx.clearRect(0, 0, width, height)
}
} }
// react to pixel ratio changes
onPixelRatioChange()
// store last drawing points
last_points.value = {}
})
onBeforeUnmount(() => {
// stop pixel ratio change listener
if (unsubscribePixelRatioChange) {
unsubscribePixelRatioChange()
}
})
function onPixelRatioChange() {
if (unsubscribePixelRatioChange) {
unsubscribePixelRatioChange()
}
const media = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)
media.addEventListener('change', onPixelRatioChange)
unsubscribePixelRatioChange = () => {
media.removeEventListener('change', onPixelRatioChange)
}
canvasScale.value = window.devicePixelRatio
onCanvasSizeChange(props.canvasSize)
}
function onCanvasSizeChange({ width, height }: Dimension) {
canvasResize({ width, height })
canvasUpdateCursors()
}
watch(() => props.canvasSize, onCanvasSizeChange)
function canvasResize({ width, height }: Dimension) {
overlay.value!.width = width * canvasScale.value
overlay.value!.height = height * canvasScale.value
ctx.value?.setTransform(canvasScale.value, 0, 0, canvasScale.value, 0, 0)
}
// start as undefined to prevent jumping
const last_animation_time = ref<number>(0)
// current animation progress (0-1)
const percent = ref<number>(0)
// points to be animated for each session
const points = ref<SessionCursors[]>([])
// last points coordinates for each session
const last_points = ref<Record<string, Cursor>>({})
function canvasAnimateFrame(now: number = NaN) {
// request another frame
if (percent.value <= 1) window.requestAnimationFrame(canvasAnimateFrame)
// calc elapsed time since last loop
const elapsed = now - last_animation_time.value
// skip if fps is set and elapsed time is less than fps
if (props.fps > 0 && elapsed < 1000 / props.fps) return
// calc current animation progress
const delta = elapsed / POS_INTERVAL_MS
last_animation_time.value = now
// skip very first delta to prevent jumping
if (isNaN(delta)) return
// set the animation position
percent.value += delta
// draw points for current frame
canvasDrawPoints(percent.value)
}
function canvasDrawPoints(percent: number = 1) {
// clear canvas
canvasClear()
// draw current position
for (const p of points.value) {
const { x, y } = getMovementXYatPercent(p.cursors, percent)
canvasDrawCursor(x, y, p.id)
}
}
function canvasUpdateCursors() {
let new_last_points = {} as Record<string, Cursor>
// track unchanged cursors
let unchanged = 0
// create points for animation
points.value = []
for (const { id, cursors } of props.cursors) {
if (
// if there are no positions
cursors.length == 0 ||
// ignore own cursor
id == props.sessionId ||
// ignore host's cursor
id == props.hostId
) {
unchanged++
continue
}
// get last point
const new_last_point = cursors[cursors.length - 1]
// add last cursor position to cursors (if available)
let pos = { id } as SessionCursors
if (id in last_points.value) {
const last_point = last_points.value[id]
// if cursor did not move considerably
if (
Math.abs(last_point.x - new_last_point.x) < POS_THRESHOLD_PX &&
Math.abs(last_point.y - new_last_point.y) < POS_THRESHOLD_PX
) {
// we knew that this cursor did not change, but other
// might, so we keep only one point to be drawn
pos.cursors = [new_last_point]
// and increase unchanged counter
unchanged++
} else {
// if cursor moved, we want to include last point
// in the animation, so that movement can be seamless
pos.cursors = [last_point, ...cursors]
}
} else {
// if cursor does not have last point, it is not
// displayed in canvas and it should be now
pos.cursors = [...cursors]
}
new_last_points[id] = new_last_point
points.value.push(pos)
}
// apply new last points
last_points.value = new_last_points
// no cursors to animate
if (points.value.length == 0) {
canvasClear()
return
}
// if all cursors are unchanged
if (unchanged == props.cursors.length) {
// draw only last known position without animation
canvasDrawPoints()
return
}
// start animation if not running
const p = percent.value
percent.value = 0
if (p > 1 || !p) {
canvasAnimateFrame()
}
}
watch(() => props.hostId, canvasUpdateCursors)
watch(() => props.cursors, canvasUpdateCursors)
function canvasDrawCursor(x: number, y: number, id: string) {
// get intrinsic dimensions
const { width, height } = props.canvasSize
x = Math.round((x / props.screenSize.width) * width)
y = Math.round((y / props.screenSize.height) * height)
// reset transformation, X and Y will be 0 again
ctx.value!.setTransform(canvasScale.value, 0, 0, canvasScale.value, 0, 0)
// use custom draw function, if available
if (props.cursorDraw) {
props.cursorDraw(ctx.value!, x, y, id)
return
}
// get cursor tag
const cursorTag = props.sessions[id]?.profile.name || ''
// draw inactive cursor tag
ctx.value!.font = '14px Arial, sans-serif'
ctx.value!.textBaseline = 'top'
ctx.value!.shadowColor = 'black'
ctx.value!.shadowBlur = 2
ctx.value!.lineWidth = 2
ctx.value!.fillStyle = 'black'
ctx.value!.strokeText(cursorTag, x, y)
ctx.value!.shadowBlur = 0
ctx.value!.fillStyle = 'white'
ctx.value!.fillText(cursorTag, x, y)
}
function canvasClear() {
// reset transformation, X and Y will be 0 again
ctx.value?.setTransform(canvasScale.value, 0, 0, canvasScale.value, 0, 0)
const { width, height } = props.canvasSize
ctx.value?.clearRect(0, 0, width, height)
}
</script> </script>

View File

@ -1,12 +1,11 @@
import Vue from 'vue'
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import * as EVENT from '../types/events' import * as EVENT from '../types/events'
import * as webrtcTypes from '../types/webrtc' import type * as webrtcTypes from '../types/webrtc'
import { NekoWebSocket } from './websocket' import { NekoWebSocket } from './websocket'
import { NekoLoggerFactory } from './logger' import { NekoLoggerFactory } from './logger'
import { NekoWebRTC } from './webrtc' import { NekoWebRTC } from './webrtc'
import { Connection, WebRTCStats } from '../types/state' import type { Connection, WebRTCStats } from '../types/state'
import { Reconnector } from './reconnector' import { Reconnector } from './reconnector'
import { WebsocketReconnector } from './reconnector/websocket' import { WebsocketReconnector } from './reconnector/websocket'
@ -56,11 +55,11 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
} }
this._onConnectHandle = () => { this._onConnectHandle = () => {
Vue.set(this._state.websocket, 'connected', this.websocket.connected) this._state.websocket.connected = this.websocket.connected // TODO: Vue.Set
Vue.set(this._state.webrtc, 'connected', this.webrtc.connected) this._state.webrtc.connected = this.webrtc.connected // TODO: Vue.Set
if (this._state.status !== 'connected' && this.websocket.connected && this.webrtc.connected) { if (this._state.status !== 'connected' && this.websocket.connected && this.webrtc.connected) {
Vue.set(this._state, 'status', 'connected') this._state.status = 'connected' // TODO: Vue.Set
} }
if (this.websocket.connected && !this.webrtc.connected) { if (this.websocket.connected && !this.webrtc.connected) {
@ -76,15 +75,15 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
} }
this._onDisconnectHandle = () => { this._onDisconnectHandle = () => {
Vue.set(this._state.websocket, 'connected', this.websocket.connected) this._state.websocket.connected = this.websocket.connected // TODO: Vue.Set
Vue.set(this._state.webrtc, 'connected', this.webrtc.connected) this._state.webrtc.connected = this.webrtc.connected // TODO: Vue.Set
if (this._state.webrtc.stable && !this.webrtc.connected) { if (this._state.webrtc.stable && !this.webrtc.connected) {
Vue.set(this._state.webrtc, 'stable', false) this._state.webrtc.stable = false // TODO: Vue.Set
} }
if (this._state.status === 'connected' && this.activated) { if (this._state.status === 'connected' && this.activated) {
Vue.set(this._state, 'status', 'connecting') this._state.status = 'connecting' // TODO: Vue.Set
} }
} }
@ -99,13 +98,13 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
// synchronize webrtc stats with global state // synchronize webrtc stats with global state
this._webrtcStatsHandle = (stats: WebRTCStats) => { this._webrtcStatsHandle = (stats: WebRTCStats) => {
Vue.set(this._state.webrtc, 'stats', stats) this._state.webrtc.stats = stats // TODO: Vue.Set
} }
this.webrtc.on('stats', this._webrtcStatsHandle) this.webrtc.on('stats', this._webrtcStatsHandle)
// synchronize webrtc stable with global state // synchronize webrtc stable with global state
this._webrtcStableHandle = (isStable: boolean) => { this._webrtcStableHandle = (isStable: boolean) => {
Vue.set(this._state.webrtc, 'stable', isStable) this._state.webrtc.stable = isStable // TODO: Vue.Set
} }
this.webrtc.on('stable', this._webrtcStableHandle) this.webrtc.on('stable', this._webrtcStableHandle)
@ -138,7 +137,7 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
window.clearTimeout(webrtcFallbackTimeout) window.clearTimeout(webrtcFallbackTimeout)
} }
Vue.set(this._state.webrtc, 'connected', true) this._state.webrtc.connected = true // TODO: Vue.Set
webrtcCongestion = 0 webrtcCongestion = 0
return return
} }
@ -146,7 +145,7 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
// try to downgrade quality if it happend many times // try to downgrade quality if it happend many times
if (++webrtcCongestion >= WEBRTC_RECONN_FAILED_ATTEMPTS) { if (++webrtcCongestion >= WEBRTC_RECONN_FAILED_ATTEMPTS) {
webrtcFallbackTimeout = window.setTimeout(() => { webrtcFallbackTimeout = window.setTimeout(() => {
Vue.set(this._state.webrtc, 'connected', false) this._state.webrtc.connected = false // TODO: Vue.Set
}, WEBRTC_FALLBACK_TIMEOUT_MS) }, WEBRTC_FALLBACK_TIMEOUT_MS)
webrtcCongestion = 0 webrtcCongestion = 0
@ -193,7 +192,7 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
this._open = true this._open = true
this._peerRequest = peerRequest this._peerRequest = peerRequest
Vue.set(this._state, 'status', 'connecting') this._state.status = 'connecting' // TODO: Vue.Set
// open all reconnectors with deferred connection // open all reconnectors with deferred connection
Object.values(this._reconnector).forEach((r) => r.open(true)) Object.values(this._reconnector).forEach((r) => r.open(true))
@ -208,9 +207,9 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
if (active) { if (active) {
// set state to disconnected // set state to disconnected
Vue.set(this._state.websocket, 'connected', false) this._state.websocket.connected = false // TODO: Vue.Set
Vue.set(this._state.webrtc, 'connected', false) this._state.webrtc.connected = false // TODO: Vue.Set
Vue.set(this._state, 'status', 'disconnected') this._state.status = 'disconnected' // TODO: Vue.Set
this._closing = true this._closing = true
} }
@ -243,9 +242,9 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
Object.values(this._reconnector).forEach((r) => r.destroy()) Object.values(this._reconnector).forEach((r) => r.destroy())
// set state to disconnected // set state to disconnected
Vue.set(this._state.websocket, 'connected', false) this._state.websocket.connected = false // TODO: Vue.Set
Vue.set(this._state.webrtc, 'connected', false) this._state.webrtc.connected = false // TODO: Vue.Set
Vue.set(this._state, 'status', 'disconnected') this._state.status = 'disconnected' // TODO: Vue.Set
} }
_webrtcQualityDowngrade(quality: string): string | undefined { _webrtcQualityDowngrade(quality: string): string | undefined {

View File

@ -1,11 +1,9 @@
import Vue from 'vue'
import * as EVENT from '../types/events' import * as EVENT from '../types/events'
import * as message from '../types/messages' import * as message from '../types/messages'
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import { NekoConnection } from './connection' import { NekoConnection } from './connection'
import { Control } from '../types/state' import type { Control } from '../types/state'
export interface NekoControlEvents { export interface NekoControlEvents {
['overlay.click']: (e: MouseEvent) => void ['overlay.click']: (e: MouseEvent) => void
@ -48,11 +46,11 @@ export class NekoControl extends EventEmitter<NekoControlEvents> {
} }
public lock() { public lock() {
Vue.set(this._state, 'locked', true) this._state.locked = true // TODO: Vue.Set
} }
public unlock() { public unlock() {
Vue.set(this._state, 'locked', false) this._state.locked = false // TODO: Vue.Set
} }
public request() { public request() {

View File

@ -1,12 +1,11 @@
import Vue from 'vue'
import * as EVENT from '../types/events' import * as EVENT from '../types/events'
import * as message from '../types/messages' import * as message from '../types/messages'
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import { AxiosProgressEvent } from 'axios' import type { AxiosProgressEvent } from 'axios'
import { Logger } from '../utils/logger' import { Logger } from '../utils/logger'
import { NekoConnection } from './connection' import { NekoConnection } from './connection'
import NekoState from '../types/state' import type NekoState from '../types/state'
export interface NekoEvents { export interface NekoEvents {
// connection events // connection events
@ -104,11 +103,11 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
protected [EVENT.SYSTEM_INIT](conf: message.SystemInit) { protected [EVENT.SYSTEM_INIT](conf: message.SystemInit) {
this._localLog.debug(`EVENT.SYSTEM_INIT`) this._localLog.debug(`EVENT.SYSTEM_INIT`)
Vue.set(this._state, 'session_id', conf.session_id) this._state.session_id = conf.session_id // TODO: Vue.Set
// check if backend supports touch events // check if backend supports touch events
Vue.set(this._state.control.touch, 'supported', conf.touch_events) this._state.control.touch.supported = conf.touch_events // TODO: Vue.Set
Vue.set(this._state.connection, 'screencast', conf.screencast_enabled) this._state.connection.screencast = conf.screencast_enabled // TODO: Vue.Set
Vue.set(this._state.connection.webrtc, 'videos', conf.webrtc.videos) this._state.connection.webrtc.videos = conf.webrtc.videos // TODO: Vue.Set
for (const id in conf.sessions) { for (const id in conf.sessions) {
this[EVENT.SESSION_CREATED](conf.sessions[id]) this[EVENT.SESSION_CREATED](conf.sessions[id])
@ -131,14 +130,14 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
return b.width - a.width return b.width - a.width
}) })
Vue.set(this._state.screen, 'configurations', list) this._state.screen.configurations = list // TODO: Vue.Set
this[EVENT.BORADCAST_STATUS](broadcast_status) this[EVENT.BORADCAST_STATUS](broadcast_status)
} }
protected [EVENT.SYSTEM_SETTINGS](settings: message.SystemSettings) { protected [EVENT.SYSTEM_SETTINGS](settings: message.SystemSettings) {
this._localLog.debug(`EVENT.SYSTEM_SETTINGS`) this._localLog.debug(`EVENT.SYSTEM_SETTINGS`)
Vue.set(this._state, 'settings', settings) this._state.settings = settings // TODO: Vue.Set
} }
protected [EVENT.SYSTEM_DISCONNECT]({ message }: message.SystemDisconnect) { protected [EVENT.SYSTEM_DISCONNECT]({ message }: message.SystemDisconnect) {
@ -201,14 +200,14 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
protected [EVENT.SIGNAL_VIDEO]({ disabled, id, auto }: message.SignalVideo) { protected [EVENT.SIGNAL_VIDEO]({ disabled, id, auto }: message.SignalVideo) {
this._localLog.debug(`EVENT.SIGNAL_VIDEO`, { disabled, id, auto }) this._localLog.debug(`EVENT.SIGNAL_VIDEO`, { disabled, id, auto })
Vue.set(this._state.connection.webrtc.video, 'disabled', disabled) this._state.connection.webrtc.video.disabled = disabled // TODO: Vue.Set
Vue.set(this._state.connection.webrtc.video, 'id', id) this._state.connection.webrtc.video.id = id // TODO: Vue.Set
Vue.set(this._state.connection.webrtc.video, 'auto', auto) this._state.connection.webrtc.video.auto = auto // TODO: Vue.Set
} }
protected [EVENT.SIGNAL_AUDIO]({ disabled }: message.SignalAudio) { protected [EVENT.SIGNAL_AUDIO]({ disabled }: message.SignalAudio) {
this._localLog.debug(`EVENT.SIGNAL_AUDIO`, { disabled }) this._localLog.debug(`EVENT.SIGNAL_AUDIO`, { disabled })
Vue.set(this._state.connection.webrtc.audio, 'disabled', disabled) this._state.connection.webrtc.audio.disabled = disabled // TODO: Vue.Set
} }
protected [EVENT.SIGNAL_CLOSE]() { protected [EVENT.SIGNAL_CLOSE]() {
@ -220,22 +219,22 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
// Session Events // Session Events
///////////////////////////// /////////////////////////////
protected [EVENT.SESSION_CREATED]({ id, ...data }: message.SessionData) { protected [EVENT.SESSION_CREATED]({ id, profile, ...state }: message.SessionData) {
this._localLog.debug(`EVENT.SESSION_CREATED`, { id }) this._localLog.debug(`EVENT.SESSION_CREATED`, { id })
Vue.set(this._state.sessions, id, data) this._state.sessions[id] = { id, profile, state } // TODO: Vue.Set
this.emit('session.created', id) this.emit('session.created', id)
} }
protected [EVENT.SESSION_DELETED]({ id }: message.SessionID) { protected [EVENT.SESSION_DELETED]({ id }: message.SessionID) {
this._localLog.debug(`EVENT.SESSION_DELETED`, { id }) this._localLog.debug(`EVENT.SESSION_DELETED`, { id })
Vue.delete(this._state.sessions, id) delete this._state.sessions[id] // TODO: Vue.Delete
this.emit('session.deleted', id) this.emit('session.deleted', id)
} }
protected [EVENT.SESSION_PROFILE]({ id, ...profile }: message.MemberProfile) { protected [EVENT.SESSION_PROFILE]({ id, ...profile }: message.MemberProfile) {
if (id in this._state.sessions) { if (id in this._state.sessions) {
this._localLog.debug(`EVENT.SESSION_PROFILE`, { id }) this._localLog.debug(`EVENT.SESSION_PROFILE`, { id })
Vue.set(this._state.sessions[id], 'profile', profile) this._state.sessions[id].profile = profile // TODO: Vue.Set
this.emit('session.updated', id) this.emit('session.updated', id)
} }
} }
@ -243,13 +242,17 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
protected [EVENT.SESSION_STATE]({ id, ...state }: message.SessionState) { protected [EVENT.SESSION_STATE]({ id, ...state }: message.SessionState) {
if (id in this._state.sessions) { if (id in this._state.sessions) {
this._localLog.debug(`EVENT.SESSION_STATE`, { id }) this._localLog.debug(`EVENT.SESSION_STATE`, { id })
Vue.set(this._state.sessions[id], 'state', state) this._state.sessions[id].state = state // TODO: Vue.Set
this.emit('session.updated', id) this.emit('session.updated', id)
} }
} }
protected [EVENT.SESSION_CURSORS](cursors: message.SessionCursor[]) { protected [EVENT.SESSION_CURSORS](cursors: message.SessionCursor[]) {
Vue.set(this._state, 'cursors', cursors) //
// TODO: Resolve conflict with state.cursors.
//
//@ts-ignore
this._state.cursors = cursors // TODO: Vue.Set
} }
///////////////////////////// /////////////////////////////
@ -260,13 +263,13 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
this._localLog.debug(`EVENT.CONTROL_HOST`) this._localLog.debug(`EVENT.CONTROL_HOST`)
if (has_host && host_id) { if (has_host && host_id) {
Vue.set(this._state.control, 'host_id', host_id) this._state.control.host_id = host_id // TODO: Vue.Set
} else { } else {
Vue.set(this._state.control, 'host_id', null) this._state.control.host_id = null // TODO: Vue.Set
} }
// save if user is host // save if user is host
Vue.set(this._state.control, 'is_host', has_host && this._state.control.host_id === this._state.session_id) this._state.control.is_host = has_host && this._state.control.host_id === this._state.session_id // TODO: Vue.Set
this.emit('room.control.host', has_host, host_id) this.emit('room.control.host', has_host, host_id)
} }
@ -277,7 +280,7 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
protected [EVENT.SCREEN_UPDATED]({ width, height, rate }: message.ScreenSize) { protected [EVENT.SCREEN_UPDATED]({ width, height, rate }: message.ScreenSize) {
this._localLog.debug(`EVENT.SCREEN_UPDATED`) this._localLog.debug(`EVENT.SCREEN_UPDATED`)
Vue.set(this._state.screen, 'size', { width, height, rate }) this._state.screen.size = { width, height, rate } // TODO: Vue.Set
this.emit('room.screen.updated', width, height, rate) this.emit('room.screen.updated', width, height, rate)
} }
@ -287,7 +290,7 @@ export class NekoMessages extends EventEmitter<NekoEvents> {
protected [EVENT.CLIPBOARD_UPDATED]({ text }: message.ClipboardData) { protected [EVENT.CLIPBOARD_UPDATED]({ text }: message.ClipboardData) {
this._localLog.debug(`EVENT.CLIPBOARD_UPDATED`) this._localLog.debug(`EVENT.CLIPBOARD_UPDATED`)
Vue.set(this._state.control, 'clipboard', { text }) this._state.control.clipboard = { text } // TODO: Vue.Set
try { try {
navigator.clipboard.writeText(text) // sync user's clipboard navigator.clipboard.writeText(text) // sync user's clipboard

View File

@ -1,6 +1,6 @@
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import { ReconnectorConfig } from '../../types/reconnector' import type { ReconnectorConfig } from '../../types/reconnector'
export interface ReconnectorAbstractEvents { export interface ReconnectorAbstractEvents {
connect: () => void connect: () => void

View File

@ -1,5 +1,5 @@
import * as EVENT from '../../types/events' import * as EVENT from '../../types/events'
import { Connection } from '../../types/state' import type { Connection } from '../../types/state'
import { NekoWebSocket } from '../websocket' import { NekoWebSocket } from '../websocket'
import { NekoWebRTC } from '../webrtc' import { NekoWebRTC } from '../webrtc'

View File

@ -1,4 +1,4 @@
import { Connection } from '../../types/state' import type { Connection } from '../../types/state'
import { NekoWebSocket } from '../websocket' import { NekoWebSocket } from '../websocket'

View File

@ -1,31 +1,30 @@
import Vue from 'vue' import type { Video } from '../types/state'
import { Video } from '../types/state'
export function register(el: HTMLVideoElement, state: Video) { export function register(el: HTMLVideoElement, state: Video) {
el.addEventListener('canplaythrough', () => { el.addEventListener('canplaythrough', () => {
Vue.set(state, 'playable', true) state.playable = true
}) })
el.addEventListener('playing', () => { el.addEventListener('playing', () => {
Vue.set(state, 'playing', true) state.playing = true
}) })
el.addEventListener('pause', () => { el.addEventListener('pause', () => {
Vue.set(state, 'playing', false) state.playing = false
}) })
el.addEventListener('emptied', () => { el.addEventListener('emptied', () => {
Vue.set(state, 'playable', false) state.playable = false
Vue.set(state, 'playing', false) state.playing = false
}) })
el.addEventListener('error', () => { el.addEventListener('error', () => {
Vue.set(state, 'playable', false) state.playable = false
Vue.set(state, 'playing', false) state.playing = false
}) })
el.addEventListener('volumechange', () => { el.addEventListener('volumechange', () => {
Vue.set(state, 'muted', el.muted) state.muted = el.muted
Vue.set(state, 'volume', el.volume) state.volume = el.volume
}) })
// Initial state // Initial state
Vue.set(state, 'muted', el.muted) state.muted = el.muted
Vue.set(state, 'volume', el.volume) state.volume = el.volume
Vue.set(state, 'playing', !el.paused) state.playing = !el.paused
} }

View File

@ -1,5 +1,5 @@
import EventEmitter from 'eventemitter3' import EventEmitter from 'eventemitter3'
import { WebRTCStats, CursorPosition, CursorImage } from '../types/webrtc' import type { WebRTCStats, CursorPosition, CursorImage } from '../types/webrtc'
import { Logger } from '../utils/logger' import { Logger } from '../utils/logger'
import { videoSnap } from '../utils/video-snap' import { videoSnap } from '../utils/video-snap'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,98 +2,93 @@
<img :src="imageSrc" @load="onImageLoad" @error="onImageError" /> <img :src="imageSrc" @load="onImageLoad" @error="onImageError" />
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Watch, Prop } from 'vue-property-decorator' import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
import { RoomApi } from './api' import { RoomApi } from './api'
const REFRESH_RATE = 1e3 const REFRESH_RATE = 1e3
const ERROR_DELAY_MS = 2500 const ERROR_DELAY_MS = 2500
@Component({ const imageSrc = ref('')
name: 'neko-screencast',
})
export default class extends Vue {
imageSrc = ''
running = false
continue = false
@Prop() const props = defineProps<{
readonly image!: string image: string
enabled: boolean
api: RoomApi
}>()
@Watch('image') const emit = defineEmits(['imageReady'])
setImage(image: string) {
this.imageSrc = image
}
@Prop() watch(() => props.image, (image) => {
readonly enabled!: boolean imageSrc.value = image
})
@Prop() let isRunning = false
readonly api!: RoomApi let isStopped = false
async loop() { async function loop() {
if (this.running) return if (isRunning) return
this.running = true isRunning = true
while (this.continue) { while (!isStopped) {
const lastLoad = Date.now() const lastLoad = Date.now()
try { try {
const res = await this.api.screenCastImage({ responseType: 'blob' }) const res = await props.api.screenCastImage({ responseType: 'blob' })
this.imageSrc = URL.createObjectURL(res.data) imageSrc.value = URL.createObjectURL(res.data)
const delay = lastLoad - Date.now() + REFRESH_RATE const delay = lastLoad - Date.now() + REFRESH_RATE
if (delay > 0) { if (delay > 0) {
await new Promise((res) => setTimeout(res, delay)) await new Promise((res) => setTimeout(res, delay))
}
} catch {
await new Promise((res) => setTimeout(res, ERROR_DELAY_MS))
}
} }
} catch {
this.running = false await new Promise((res) => setTimeout(res, ERROR_DELAY_MS))
this.imageSrc = ''
}
mounted() {
if (this.enabled) {
this.start()
}
}
beforeDestroy() {
this.stop()
}
start() {
this.continue = true
if (!this.running) {
setTimeout(this.loop, 0)
}
}
stop() {
this.continue = false
}
@Watch('enabled')
onEnabledChanged(enabled: boolean) {
if (enabled) {
this.start()
} else {
this.stop()
}
}
onImageLoad() {
URL.revokeObjectURL(this.imageSrc)
this.$emit('imageReady', this.running)
}
onImageError() {
if (this.imageSrc) URL.revokeObjectURL(this.imageSrc)
this.$emit('imageReady', false)
} }
} }
isRunning = false
imageSrc.value = ''
}
onMounted(() => {
if (props.enabled) {
start()
}
})
onBeforeUnmount(() => {
stop()
})
function start() {
isStopped = false
if (!isRunning) {
setTimeout(loop, 0)
}
}
function stop() {
isStopped = true
}
function onEnabledChanged(enabled: boolean) {
if (enabled) {
start()
} else {
stop()
}
}
watch(() => props.enabled, onEnabledChanged)
function onImageLoad() {
URL.revokeObjectURL(imageSrc.value)
emit('imageReady', isRunning)
}
function onImageError() {
if (imageSrc.value) URL.revokeObjectURL(imageSrc.value)
emit('imageReady', false)
}
</script> </script>

View File

@ -1,4 +1,4 @@
import { CursorImage } from './webrtc' import type { CursorImage } from './webrtc'
export type CursorDrawFunction = ( export type CursorDrawFunction = (
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,

View File

@ -1,6 +1,6 @@
import { ICEServer } from '../internal/webrtc' import type { ICEServer } from '../internal/webrtc'
import { Settings } from './state' import type { Settings } from './state'
import { PeerRequest, PeerVideo, PeerAudio } from './webrtc' import type { PeerRequest, PeerVideo, PeerAudio } from './webrtc'
///////////////////////////// /////////////////////////////
// System // System

View File

@ -1,5 +1,5 @@
import * as webrtcTypes from './webrtc' import type * as webrtcTypes from './webrtc'
import * as reconnectorTypes from './reconnector' import type * as reconnectorTypes from './reconnector'
export default interface State { export default interface State {
authenticated: boolean authenticated: boolean

View File

@ -1,5 +1,7 @@
//@ts-ignore //
import Keyboard from './keyboards/__KEYBOARD__' // TODO: add support for other keyboards
//
import Keyboard from './keyboards/guacamole'
// conditional import at build time: // conditional import at build time:
// __KEYBOARD__ is replaced by the value of the env variable KEYBOARD // __KEYBOARD__ is replaced by the value of the env variable KEYBOARD

View File

@ -2,7 +2,7 @@ export class Logger {
// eslint-disable-next-line // eslint-disable-next-line
constructor( constructor(
protected readonly _scope: string = 'main', protected readonly _scope: string = 'main',
private readonly _color: boolean = !!process.env.VUE_APP_LOG_COLOR, private readonly _color: boolean = false // !!process.env.VUE_APP_LOG_COLOR, // TODO: add support for color
) {} ) {}
protected _console(level: string, m: string, fields?: Record<string, any>) { protected _console(level: string, m: string, fields?: Record<string, any>) {

View File

@ -1,6 +1,11 @@
import Vue from 'vue' import Vue from 'vue'
import Neko from './component/main.vue' import Neko from './component/main.vue'
// TODO
export * as ApiModels from './component/api/models'
export * as StateModels from './component/types/state'
export * as webrtcTypes from './component/types/webrtc'
/** /**
* Fügt eine "install" function hinzu * Fügt eine "install" function hinzu
* *
@ -9,10 +14,14 @@ import Neko from './component/main.vue'
*/ */
const NekoElements = { const NekoElements = {
install(vue: typeof Vue): void { install(vue: typeof Vue): void {
// TODO
// @ts-ignore
vue.component('Neko', Neko) vue.component('Neko', Neko)
}, },
} }
// TODO
// @ts-ignore
if (typeof window !== 'undefined' && window.Vue) { if (typeof window !== 'undefined' && window.Vue) {
// @ts-ignore // @ts-ignore
window.Vue.use(NekoElements, {}) window.Vue.use(NekoElements, {})

View File

@ -1,8 +1,6 @@
import Vue from 'vue' import { createApp } from 'vue'
import app from './page/main.vue' import App from './page/main.vue'
Vue.config.productionTip = false const app = createApp(App)
new Vue({ app.mount('#app')
render: (h) => h(app),
}).$mount('#app')

View File

@ -2,7 +2,7 @@
@use "sass:math"; @use "sass:math";
$fa-font-path: "~@fortawesome/fontawesome-free/webfonts"; $fa-font-path: "@fortawesome/fontawesome-free/webfonts";
$fa-font-size-base: 16px; $fa-font-size-base: 16px;
$fa-font-display: auto; $fa-font-display: auto;
$fa-css-prefix: fa; $fa-css-prefix: fa;
@ -16,7 +16,7 @@ $fa-secondary-opacity: .4;
$fa-family-default: 'Font Awesome 6 Free'; $fa-family-default: 'Font Awesome 6 Free';
// Import FA source files // Import FA source files
@import "~@fortawesome/fontawesome-free/scss/brands"; @import "@fortawesome/fontawesome-free/scss/brands";
@import "~@fortawesome/fontawesome-free/scss/solid"; @import "@fortawesome/fontawesome-free/scss/solid";
@import "~@fortawesome/fontawesome-free/scss/regular"; @import "@fortawesome/fontawesome-free/scss/regular";
@import "~@fortawesome/fontawesome-free/scss/fontawesome"; @import "@fortawesome/fontawesome-free/scss/fontawesome";

View File

@ -0,0 +1,11 @@
// import { describe, it, expect } from 'vitest'
//
// import { mount } from '@vue/test-utils'
// import HelloWorld from '../HelloWorld.vue'
//
// describe('HelloWorld', () => {
// it('renders properly', () => {
// const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
// expect(wrapper.text()).toContain('Hello Vitest')
// })
// })

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="chat"> <div class="chat">
<ul class="chat-history" ref="history"> <ul class="chat-history" ref="history">
<template v-for="(message, index) in history"> <template v-for="(message, index) in messages" :key="index">
<li :key="index" class="message" v-show="neko && neko.connected"> <li class="message" v-show="neko && neko.connected">
<div class="content"> <div class="content">
<div class="content-head"> <div class="content-head">
<span class="session">{{ session(message.id) }}</span> <span class="session">{{ session(message.id) }}</span>
@ -162,105 +162,114 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Prop, Watch, Ref } from 'vue-property-decorator' import { ref, watch, onMounted } from 'vue'
import Neko from '~/component/main.vue' import Neko from '@/component/main.vue'
const length = 512 // max length of message const length = 512 // max length of message
@Component({ const history = ref<HTMLUListElement | null>(null)
name: 'neko-chat',
const props = defineProps<{
neko: typeof Neko
}>()
const emit = defineEmits(['send_message'])
type Message = {
id: string
created: Date
content: string
}
const messages = ref<Message[]>([])
const content = ref('')
onMounted(() => {
setTimeout(() => {
history.value!.scrollTop = history.value!.scrollHeight
}, 0)
})
function timestamp(date: Date | string) {
date = new Date(date)
return (
date.getFullYear() +
'-' +
String(date.getMonth() + 1).padStart(2, '0') +
'-' +
String(date.getDate()).padStart(2, '0') +
' ' +
String(date.getHours()).padStart(2, '0') +
':' +
String(date.getMinutes()).padStart(2, '0') +
':' +
String(date.getSeconds()).padStart(2, '0')
)
}
function session(id: string) {
let session = props.neko.state.sessions[id]
return session ? session.profile.name : id
}
function onNekoChange() {
props.neko.events.on('receive.broadcast', (sender: string, subject: string, body: any) => {
if (subject === 'chat') {
const message = body as Message
messages.value = [...messages.value, message]
}
}) })
export default class extends Vue { }
@Ref('history') readonly _history!: HTMLElement
@Prop() readonly neko!: Neko
history = [] watch(() => props.neko, onNekoChange)
content = ''
mounted() { function onHistroyChange() {
this.$nextTick(() => { setTimeout(() => {
this._history.scrollTop = this._history.scrollHeight history.value!.scrollTop = history.value!.scrollHeight
}) }, 0)
} }
timestamp(date: Date | string) { watch(messages, onHistroyChange)
date = new Date(date)
return ( function onKeyDown(event: KeyboardEvent) {
date.getFullYear() + if (content.value.length > length) {
'-' + content.value = content.value.substring(0, length)
String(date.getMonth() + 1).padStart(2, '0') +
'-' +
String(date.getDate()).padStart(2, '0') +
' ' +
String(date.getHours()).padStart(2, '0') +
':' +
String(date.getMinutes()).padStart(2, '0') +
':' +
String(date.getSeconds()).padStart(2, '0')
)
}
session(id: string) {
let session = this.neko.state.sessions[id]
return session ? session.profile.name : id
}
@Watch('neko')
onNekoChange() {
this.neko.events.on('receive.broadcast', (sender: string, subject: string, body: string) => {
if (subject === 'chat') {
Vue.set(this, 'history', [...this.history, body])
}
})
}
@Watch('history')
onHistroyChange() {
this.$nextTick(() => {
this._history.scrollTop = this._history.scrollHeight
})
}
onKeyDown(event: KeyboardEvent) {
if (this.content.length > length) {
this.content = this.content.substring(0, length)
}
if (this.content.length == length) {
if (
[8, 16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 91, 93, 144].includes(event.keyCode) ||
(event.ctrlKey && [67, 65, 88].includes(event.keyCode))
) {
return
}
event.preventDefault()
return
}
if (event.keyCode !== 13 || event.shiftKey) {
return
}
if (this.content === '') {
event.preventDefault()
return
}
this.$emit('send_message', this.content)
let message = {
id: this.neko.state.session_id,
created: new Date(),
content: this.content,
}
this.neko.sendBroadcast('chat', message)
Vue.set(this, 'history', [...this.history, message])
this.content = ''
event.preventDefault()
}
} }
if (content.value.length == length) {
if (
[8, 16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 91, 93, 144].includes(event.keyCode) ||
(event.ctrlKey && [67, 65, 88].includes(event.keyCode))
) {
return
}
event.preventDefault()
return
}
if (event.keyCode !== 13 || event.shiftKey) {
return
}
if (content.value === '') {
event.preventDefault()
return
}
emit('send_message', content.value)
let message = {
id: props.neko.state.session_id,
created: new Date(),
content: content.value,
}
props.neko.sendBroadcast('chat', message)
messages.value = [...messages.value, message]
content.value = ''
event.preventDefault()
}
</script> </script>

View File

@ -35,185 +35,182 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Ref, Watch } from 'vue-property-decorator' import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
@Component({ const canvas = ref<HTMLCanvasElement | null>(null)
name: 'neko-color', const color = ref<HTMLDivElement | null>(null)
})
export default class extends Vue {
@Ref('canvas') readonly _canvas!: HTMLCanvasElement
@Ref('color') readonly _color!: HTMLDivElement
ctx!: CanvasRenderingContext2D | null const ctx = ref<CanvasRenderingContext2D | null>(null)
video!: HTMLVideoElement | null const video = ref<HTMLVideoElement | null>(null)
interval!: number const interval = ref<number>(0)
picker!: HTMLDivElement | null const picker = ref<HTMLDivElement | null>(null)
bullet!: HTMLDivElement | null const bullet = ref<HTMLDivElement | null>(null)
color!: string const currColor = ref<string>('')
x = 0 const x = ref<number>(0)
y = 0 const y = ref<number>(0)
clickOnChange = false const clickOnChange = ref<boolean>(false)
mounted() { const emit = defineEmits(['colorChange'])
this.video = document.querySelector('video')
this.ctx = this._canvas.getContext('2d')
}
beforeDestroy() { onMounted(() => {
if (this.interval) { video.value = document.querySelector('video')
window.clearInterval(this.interval) ctx.value = canvas.value?.getContext('2d') || null
} })
this.clearPoint() onBeforeUnmount(() => {
} if (interval.value) {
window.clearInterval(interval.value)
@Watch('clickOnChange')
clickOnChangeChanged() {
if (this.clickOnChange) {
// register interval timer
this.interval = window.setInterval(this.intervalTimer, 0)
} else {
// unregister interval timer
window.clearInterval(this.interval)
this.color = ''
}
}
intervalTimer() {
if (!this.video || !this.ctx) {
return
}
this._canvas.width = this.video.videoWidth
this._canvas.height = this.video.videoHeight
this.ctx.clearRect(0, 0, this.video.videoWidth, this.video.videoHeight)
this.ctx.drawImage(this.video, 0, 0, this.video.videoWidth, this.video.videoHeight)
// get color from pixel at x,y
var pixel = this.ctx.getImageData(this.x, this.y, 1, 1)
var data = pixel.data
var rgba = 'rgba(' + data[0] + ', ' + data[1] + ', ' + data[2] + ', ' + data[3] / 255 + ')'
// if color is different, update it
if (this.color != rgba) {
if (this.clickOnChange && this.color) {
this.$emit('colorChange', { x: this.x, y: this.y })
this.clickOnChange = false
}
console.log('color change', rgba, this.color)
this._color.style.backgroundColor = rgba
this.color = rgba
}
}
getCoords(elem: HTMLElement) {
// crossbrowser version
let box = elem.getBoundingClientRect()
let body = document.body
let docEl = document.documentElement
let scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop
let scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft
let clientTop = docEl.clientTop || body.clientTop || 0
let clientLeft = docEl.clientLeft || body.clientLeft || 0
let top = box.top + scrollTop - clientTop
let left = box.left + scrollLeft - clientLeft
return { top: Math.round(top), left: Math.round(left) }
}
setPoint() {
// create new element and add to body
var picker = document.createElement('div')
// coordinates of video element
var video = this.getCoords(this.video!)
// match that dimensions and offset matches video
picker.style.width = this.video!.offsetWidth + 'px'
picker.style.height = this.video!.offsetHeight + 'px'
picker.style.left = video.left + 'px'
picker.style.top = video.top + 'px'
picker.style.position = 'absolute'
picker.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
picker.style.cursor = 'crosshair'
// put it on top of video
picker.style.zIndex = '100'
document.body.appendChild(picker)
// add click event listener to new element
picker.addEventListener('click', this.clickPicker)
this.picker = picker
}
clearPoint() {
this.x = 0
this.y = 0
this.color = ''
this._color.style.backgroundColor = 'transparent'
if (this.bullet) {
this.bullet.remove()
}
if (this.picker) {
this.picker.remove()
}
}
clickPicker(e: any) {
// get mouse position
var x = e.pageX
var y = e.pageY
// get picker position
var picker = this.getCoords(this.picker!)
// calculate new x,y position
var newX = x - picker.left
var newY = y - picker.top
// make it relative to video size
newX = Math.round((newX / this.video!.offsetWidth) * this.video!.videoWidth)
newY = Math.round((newY / this.video!.offsetHeight) * this.video!.videoHeight)
console.log(newX, newY)
// set new x,y position
this.x = newX
this.y = newY
// remove picker element
this.picker!.remove()
// add bullet element to the position
if (this.bullet) {
this.bullet.remove()
}
var bullet = document.createElement('div')
bullet.style.left = x + 'px'
bullet.style.top = y + 'px'
// width and height of bullet
bullet.style.width = '10px'
bullet.style.height = '10px'
// background color of bullet
bullet.style.backgroundColor = 'red'
// border radius of bullet
bullet.style.borderRadius = '50%'
// transform bullet to center
bullet.style.transform = 'translate(-50%, -50%)'
bullet.style.position = 'absolute'
bullet.style.zIndex = '100'
document.body.appendChild(bullet)
this.bullet = bullet
}
} }
clearPoint()
})
function clickOnChangeChanged() {
if (clickOnChange.value) {
// register interval timer
interval.value = window.setInterval(intervalTimer, 0)
} else {
// unregister interval timer
window.clearInterval(interval.value)
currColor.value = ''
}
}
watch(clickOnChange, clickOnChangeChanged)
function intervalTimer() {
if (!video.value || !ctx.value) {
return
}
canvas.value!.width = video.value.videoWidth
canvas.value!.height = video.value.videoHeight
ctx.value.clearRect(0, 0, video.value.videoWidth, video.value.videoHeight)
ctx.value.drawImage(video.value, 0, 0, video.value.videoWidth, video.value.videoHeight)
// get color from pixel at x,y
const pixel = ctx.value.getImageData(x.value, y.value, 1, 1)
const data = pixel.data
const rgba = `rgba(${data[0]}, ${data[1]}, ${data[2]}, ${data[3] / 255})`
// if color is different, update it
if (currColor.value !== rgba) {
if (clickOnChange.value && currColor.value) {
emit('colorChange', { x: x.value, y: y.value })
clickOnChange.value = false
}
console.log('color change', rgba, currColor.value)
color.value!.style.backgroundColor = rgba
currColor.value = rgba
}
}
function getCoords(elem: HTMLElement) {
// crossbrowser version
const box = elem.getBoundingClientRect()
const body = document.body
const docEl = document.documentElement
const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop
const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft
const clientTop = docEl.clientTop || body.clientTop || 0
const clientLeft = docEl.clientLeft || body.clientLeft || 0
const top = box.top + scrollTop - clientTop
const left = box.left + scrollLeft - clientLeft
return { top: Math.round(top), left: Math.round(left) }
}
function setPoint() {
// create new element and add to body
const p = document.createElement('div')
// coordinates of video element
const v = getCoords(video.value!)
// match that dimensions and offset matches video
p.style.width = video.value!.offsetWidth + 'px'
p.style.height = video.value!.offsetHeight + 'px'
p.style.left = v.left + 'px'
p.style.top = v.top + 'px'
p.style.position = 'absolute'
p.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
p.style.cursor = 'crosshair'
// put it on top of video
p.style.zIndex = '100'
document.body.appendChild(p)
// add click event listener to new element
p.addEventListener('click', clickPicker)
picker.value = p
}
function clearPoint() {
x.value = 0
y.value = 0
color.value!.style.backgroundColor = 'transparent'
if (bullet.value) {
bullet.value.remove()
}
if (picker.value) {
picker.value.remove()
}
}
function clickPicker(e: any) {
// get mouse position
const x = e.pageX
const y = e.pageY
// get picker position
const p = getCoords(picker.value!)
// calculate new x,y position
let newX = x - p.left
let newY = y - p.top
// make it relative to video size
newX = Math.round((newX / video.value!.offsetWidth) * video.value!.videoWidth)
newY = Math.round((newY / video.value!.offsetHeight) * video.value!.videoHeight)
console.log(newX, newY)
// set new x,y position
x.value = newX
y.value = newY
// remove picker element
picker.value!.remove()
// add bullet element to the position
if (bullet.value) {
bullet.value.remove()
}
const b = document.createElement('div')
b.style.left = x + 'px'
b.style.top = y + 'px'
// width and height of bullet
b.style.width = '10px'
b.style.height = '10px'
// background color of bullet
b.style.backgroundColor = 'red'
// border radius of bullet
b.style.borderRadius = '50%'
// transform bullet to center
b.style.transform = 'translate(-50%, -50%)'
b.style.position = 'absolute'
b.style.zIndex = '100'
document.body.appendChild(b)
bullet.value = b
}
</script> </script>

View File

@ -24,56 +24,53 @@
<style lang="scss"></style> <style lang="scss"></style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Prop } from 'vue-property-decorator' import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
import Neko from '~/component/main.vue' import Neko from '@/component/main.vue'
@Component({ const props = defineProps<{
name: 'neko-controls', neko: typeof Neko
}) }>()
export default class extends Vue {
@Prop() readonly neko!: Neko
username: string = 'admin' const username = ref('admin')
password: string = 'admin' const password = ref('admin')
async login() { async function login() {
localStorage.setItem('username', this.username) localStorage.setItem('username', username.value)
localStorage.setItem('password', this.password) localStorage.setItem('password', password.value)
try { try {
await this.neko.login(this.username, this.password) await props.neko.login(username.value, password.value)
} catch (e: any) { } catch (e: any) {
alert(e.response ? e.response.data.message : e) alert(e.response ? e.response.data.message : e)
}
}
async connect() {
try {
await this.neko.connect()
} catch (e: any) {
alert(e)
}
}
async logout() {
try {
await this.neko.logout()
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
mounted() {
const username = localStorage.getItem('username')
if (username) {
this.username = username
}
const password = localStorage.getItem('password')
if (password) {
this.password = password
}
}
} }
}
async function connect() {
try {
await props.neko.connect()
} catch (e: any) {
alert(e)
}
}
async function logout() {
try {
await props.neko.logout()
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
onMounted(() => {
const u = localStorage.getItem('username')
if (u) {
username.value = u
}
const p = localStorage.getItem('password')
if (p) {
password.value = p
}
})
</script> </script>

View File

@ -67,7 +67,6 @@
background: transparent; background: transparent;
width: 150px; width: 150px;
height: 20px; height: 20px;
-webkit-appearance: none;
&::-moz-range-thumb { &::-moz-range-thumb {
height: 12px; height: 12px;
width: 12px; width: 12px;
@ -160,88 +159,67 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Prop } from 'vue-property-decorator' import { ref, watch, computed, onMounted, onBeforeUnmount } from 'vue'
import Neko from '~/component/main.vue' import Neko from '@/component/main.vue'
@Component({ const props = defineProps<{
name: 'neko-controls', neko: typeof Neko
}) }>()
export default class extends Vue {
@Prop() readonly neko!: Neko
get can_host() { const can_host = computed(() => props.neko.connected)
return this.neko.connected const hosting = computed(() => props.neko.controlling)
const volume = computed({
get: () => props.neko.state.video.volume * 100,
set: (volume: number) => {
props.neko.setVolume(volume / 100)
},
})
const muted = computed(() => props.neko.state.video.muted || props.neko.state.video.volume === 0)
const playing = computed(() => props.neko.state.video.playing)
const playable = computed(() => props.neko.state.video.playable)
const locked = computed({
get: () => props.neko.state.control.locked,
set: (lock: boolean) => {
if (lock) {
props.neko.control.lock()
} else {
props.neko.control.unlock()
} }
},
})
get hosting() { function toggleControl() {
return this.neko.controlling if (can_host.value && hosting.value) {
} props.neko.room.controlRelease()
get volume() {
return this.neko.state.video.volume * 100
}
set volume(volume: number) {
this.neko.setVolume(volume / 100)
}
get muted() {
return this.neko.state.video.muted || this.neko.state.video.volume === 0
}
get playing() {
return this.neko.state.video.playing
}
get playable() {
return this.neko.state.video.playable
}
get locked() {
return this.neko.state.control.locked
}
set locked(lock: boolean) {
if (lock) {
this.neko.control.lock()
} else {
this.neko.control.unlock()
}
}
toggleControl() {
if (this.can_host && this.hosting) {
this.neko.room.controlRelease()
}
if (this.can_host && !this.hosting) {
this.neko.room.controlRequest()
}
}
toggleMedia() {
if (this.playable && this.playing) {
this.neko.pause()
}
if (this.playable && !this.playing) {
this.neko.play()
}
}
toggleMute() {
if (this.playable && this.muted) {
this.neko.unmute()
}
if (this.playable && !this.muted) {
this.neko.mute()
}
}
disconnect() {
this.neko.logout()
}
} }
if (can_host.value && !hosting.value) {
props.neko.room.controlRequest()
}
}
function toggleMedia() {
if (playable.value && playing.value) {
props.neko.video.pause()
}
if (playable.value && !playing.value) {
props.neko.video.play()
}
}
function toggleMute() {
if (playable.value && muted.value) {
props.neko.video.unmute()
}
if (playable.value && !muted.value) {
props.neko.video.mute()
}
}
function disconnect() {
props.neko.logout()
}
</script> </script>

View File

@ -209,7 +209,7 @@
<td> <td>
<select <select
:value="neko.state.connection.webrtc.video.id" :value="neko.state.connection.webrtc.video.id"
@input="neko.setWebRTCVideo({ selector: { id: $event.target.value } })" @input="neko.setWebRTCVideo({ selector: { id: ($event.target as HTMLSelectElement)!.value || '' } })"
> >
<option v-for="video in neko.state.connection.webrtc.videos" :key="video" :value="video"> <option v-for="video in neko.state.connection.webrtc.videos" :key="video" :value="video">
{{ video }} {{ video }}
@ -252,7 +252,7 @@
min="0" min="0"
max="1" max="1"
:value="neko.state.video.volume" :value="neko.state.video.volume"
@input="neko.setVolume(Number($event.target.value))" @input="neko.setVolume(Number(($event.target as HTMLInputElement)!.value))"
step="0.01" step="0.01"
/> />
</td> </td>
@ -289,7 +289,7 @@
min="-5" min="-5"
max="5" max="5"
:value="neko.state.control.scroll.sensitivity" :value="neko.state.control.scroll.sensitivity"
@input="neko.setScrollSensitivity(Number($event.target.value))" @input="neko.setScrollSensitivity(Number(($event.target as HTMLInputElement)!.value))"
step="1" step="1"
/> />
</td> </td>
@ -300,7 +300,7 @@
<textarea <textarea
:readonly="!neko.controlling" :readonly="!neko.controlling"
:value="neko.state.control.clipboard ? neko.state.control.clipboard.text : ''" :value="neko.state.control.clipboard ? neko.state.control.clipboard.text : ''"
@input="clipboardText = $event.target.value" @input="clipboardText = ($event.target as HTMLTextAreaElement)!.value"
></textarea> ></textarea>
<button :disabled="!neko.controlling" @click="neko.room.clipboardSetText({ text: clipboardText })"> <button :disabled="!neko.controlling" @click="neko.room.clipboardSetText({ text: clipboardText })">
send clipboard send clipboard
@ -322,14 +322,14 @@
type="text" type="text"
placeholder="Layout" placeholder="Layout"
:value="neko.state.control.keyboard.layout" :value="neko.state.control.keyboard.layout"
@input="neko.setKeyboard($event.target.value, neko.state.control.keyboard.variant)" @input="neko.setKeyboard(($event.target as HTMLInputElement)!.value, neko.state.control.keyboard.variant)"
style="width: 50%; box-sizing: border-box" style="width: 50%; box-sizing: border-box"
/> />
<input <input
type="text" type="text"
placeholder="Variant" placeholder="Variant"
:value="neko.state.control.keyboard.variant" :value="neko.state.control.keyboard.variant"
@input="neko.setKeyboard(neko.state.control.keyboard.layout, $event.target.value)" @input="neko.setKeyboard(neko.state.control.keyboard.layout, ($event.target as HTMLInputElement)!.value)"
style="width: 50%; box-sizing: border-box" style="width: 50%; box-sizing: border-box"
/> />
</td> </td>
@ -409,7 +409,7 @@
min="0" min="0"
max="10" max="10"
:value="neko.state.screen.sync.multiplier" :value="neko.state.screen.sync.multiplier"
@input="neko.state.screen.sync.multiplier = Number($event.target.value)" @input="neko.state.screen.sync.multiplier = Number(($event.target as HTMLInputElement)!.value)"
step="0.1" step="0.1"
/> />
</td> </td>
@ -425,7 +425,7 @@
min="5" min="5"
max="60" max="60"
:value="neko.state.screen.sync.rate" :value="neko.state.screen.sync.rate"
@input="neko.state.screen.sync.rate = Number($event.target.value)" @input="neko.state.screen.sync.rate = Number(($event.target as HTMLInputElement)!.value)"
step="5" step="5"
/> />
</td> </td>
@ -597,94 +597,82 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Prop, Watch } from 'vue-property-decorator' import { ref, watch, computed, onMounted, onBeforeUnmount } from 'vue'
import Neko from '~/component/main.vue' import Neko from '@/component/main.vue'
import NekoColor from './color.vue' import NekoColor from './color.vue'
@Component({ const props = defineProps<{
name: 'neko-events', neko: typeof Neko
components: { }>()
NekoColor,
},
})
export default class extends Vue {
@Prop() readonly neko!: Neko
clipboardText: string = '' const clipboardText = ref('')
bitrate: number | null = null const bitrate = ref<number | null>(null)
@Watch('neko.state.connection.webrtc.bitrate') watch(() => props.neko.state.connection.webrtc.bitrate, (val) => {
onBitrateChange(val: number) { bitrate.value = val
this.bitrate = val })
}
shift = false const shift = ref(false)
get letters(): number[] { const letters = computed(() => {
let letters = [] as number[] let letters = [] as number[]
for (let i = (this.shift ? 'A' : 'a').charCodeAt(0); i <= (this.shift ? 'Z' : 'z').charCodeAt(0); i++) { for (let i = (shift.value ? 'A' : 'a').charCodeAt(0); i <= (shift.value ? 'Z' : 'z').charCodeAt(0); i++) {
letters.push(i) letters.push(i)
}
return letters
}
// fast sceen changing test
screen_interval = null
screenChangingToggle() {
if (this.screen_interval === null) {
let sizes = this.neko.state.screen.configurations
let len = sizes.length
//@ts-ignore
this.screen_interval = setInterval(() => {
let { width, height, rate } = sizes[Math.floor(Math.random() * len)]
this.neko.setScreenSize(width, height, rate)
}, 10)
} else {
//@ts-ignore
clearInterval(this.screen_interval)
this.screen_interval = null
}
}
screenConfiguration = ''
setScreenConfiguration() {
let [width, height, rate] = this.screenConfiguration.split(/[@x]/)
this.neko.setScreenSize(parseInt(width), parseInt(height), parseInt(rate))
}
@Watch('neko.state.screen.size', { immediate: true })
onScreenSizeChange(val: any) {
this.screenConfiguration = `${val.width}x${val.height}@${val.rate}`
}
// fast cursor moving test
cursor_interval = null
cursorMovingToggle() {
if (this.cursor_interval === null) {
let len = this.neko.state.screen.size.width
//@ts-ignore
this.cursor_interval = setInterval(() => {
let x = Math.floor(Math.random() * len)
let y = Math.floor(Math.random() * len)
this.neko.control.move({ x, y })
}, 10)
} else {
//@ts-ignore
clearInterval(this.cursor_interval)
this.cursor_interval = null
}
}
async updateSettings(settings: any) {
try {
await this.neko.room.settingsSet(settings)
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
} }
return letters
})
// fast sceen changing test
let screen_interval: number | null = null
function screenChangingToggle() {
if (screen_interval === null) {
let sizes = props.neko.state.screen.configurations
let len = sizes.length
screen_interval = setInterval(() => {
let { width, height, rate } = sizes[Math.floor(Math.random() * len)]
props.neko.setScreenSize(width, height, rate)
}, 10)
} else {
clearInterval(screen_interval)
screen_interval = null
}
}
const screenConfiguration = ref('')
function setScreenConfiguration() {
let [width, height, rate] = screenConfiguration.value.split(/[@x]/)
props.neko.setScreenSize(parseInt(width), parseInt(height), parseInt(rate))
}
watch(props.neko.state.screen.size, (val) => {
screenConfiguration.value = `${val.width}x${val.height}@${val.rate}`
})
// fast cursor moving test
let cursor_interval: number | null = null
function cursorMovingToggle() {
if (cursor_interval === null) {
let len = props.neko.state.screen.size.width
cursor_interval = setInterval(() => {
let x = Math.floor(Math.random() * len)
let y = Math.floor(Math.random() * len)
props.neko.control.move({ x, y })
}, 10)
} else {
clearInterval(cursor_interval)
cursor_interval = null
}
}
async function updateSettings(settings: any) {
try {
await props.neko.room.settingsSet(settings)
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
</script> </script>

View File

@ -84,34 +84,29 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
import { Component, Prop, Watch, Vue } from 'vue-property-decorator' import { ref, watch, computed, onMounted, onBeforeUnmount } from 'vue'
import Neko from '~/component/main.vue' import Neko from '@/component/main.vue'
@Component({ const props = defineProps<{
name: 'neko-header', neko: typeof Neko
}) }>()
export default class extends Vue {
@Prop() readonly neko!: Neko
@Watch('neko.state.connection.url') const url = ref('')
updateUrl(url: string) {
this.url = url
}
url: string = '' watch(() => props.neko.state.connection.url, (u) => {
url.value = u
})
async setUrl() { async function setUrl() {
if (this.url == '') { if (url.value == '') {
this.url = location.href url.value = location.href
}
await this.neko.setUrl(this.url)
}
toggleMenu() {
this.$emit('toggle')
//this.$accessor.client.toggleSide()
}
} }
await props.neko.setUrl(url.value)
}
function toggleMenu() {
props.neko.toggleSide()
}
</script> </script>

View File

@ -40,146 +40,144 @@
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Prop, Ref } from 'vue-property-decorator' import { ref, watch, computed, onMounted, onBeforeUnmount } from 'vue'
import Neko from '~/component/main.vue' import Neko from '@/component/main.vue'
@Component({ const props = defineProps<{
name: 'neko-media', neko: typeof Neko
}) }>()
export default class extends Vue {
@Prop() readonly neko!: Neko
@Ref('audio') readonly _audio!: HTMLAudioElement
@Ref('video') readonly _video!: HTMLVideoElement
private audioDevice: string = '' const audio = ref<HTMLAudioElement | null>(null)
private audioDevices: MediaDeviceInfo[] = [] const video = ref<HTMLVideoElement | null>(null)
private micTracks: MediaStreamTrack[] = [] const audioDevice = ref<string>('')
private micSenders: RTCRtpSender[] = [] const audioDevices = ref<MediaDeviceInfo[]>([])
private videoDevice: string = '' const micTracks = ref<MediaStreamTrack[]>([])
private videoDevices: MediaDeviceInfo[] = [] const micSenders = ref<RTCRtpSender[]>([])
private camTracks: MediaStreamTrack[] = [] const videoDevice = ref<string>('')
private camSenders: RTCRtpSender[] = [] const videoDevices = ref<MediaDeviceInfo[]>([])
mounted() { const camTracks = ref<MediaStreamTrack[]>([])
this.loadAudioDevices() const camSenders = ref<RTCRtpSender[]>([])
this.loadVideoDevices()
onMounted(() => {
loadAudioDevices()
loadVideoDevices()
})
async function loadAudioDevices() {
let devices = await navigator.mediaDevices.enumerateDevices()
audioDevices.value = devices.filter((device) => device.kind === 'audioinput')
console.log('audioDevices', audioDevices.value)
}
async function addMicrophone() {
micTracks.value = []
micSenders.value = []
try {
let a = { echoCancellation: true } as MediaTrackConstraints
if (audioDevice.value != '') {
a.deviceId = audioDevice.value
} }
async loadAudioDevices() { const stream = await navigator.mediaDevices.getUserMedia({ video: false, audio: a })
let devices = await navigator.mediaDevices.enumerateDevices() audio.value!.srcObject = stream
this.audioDevices = devices.filter((device) => device.kind === 'audioinput') console.log('Got MediaStream:', stream)
console.log('audioDevices', this.audioDevices)
}
async addMicrophone() { const tracks = stream.getTracks()
this.micTracks = [] console.log('Got tracks:', tracks)
this.micSenders = []
try { tracks.forEach((track) => {
let audio = { echoCancellation: true } as MediaTrackConstraints micTracks.value.push(track)
if (this.audioDevice != '') { console.log('Adding track', track, stream)
audio.deviceId = this.audioDevice
}
const stream = await navigator.mediaDevices.getUserMedia({ video: false, audio }) const rtcp = props.neko.addTrack(track, stream)
this._audio.srcObject = stream micSenders.value.push(rtcp)
console.log('Got MediaStream:', stream) console.log('rtcp sender', rtcp, rtcp.transport)
const tracks = stream.getTracks() // TODO: Can be null.
console.log('Got tracks:', tracks) rtcp.transport?.addEventListener('statechange', () => {
console.log('track - on state change', rtcp.transport?.state)
tracks.forEach((track) => {
this.micTracks.push(track)
console.log('Adding track', track, stream)
const rtcp = this.neko.addTrack(track, stream)
this.micSenders.push(rtcp)
console.log('rtcp sender', rtcp, rtcp.transport)
// TODO: Can be null.
rtcp.transport?.addEventListener('statechange', () => {
console.log('track - on state change', rtcp.transport?.state)
})
})
} catch (error) {
alert('Error accessing media devices.' + error)
}
}
stopMicrophone() {
this.micTracks.forEach((track) => {
track.stop()
}) })
})
this.micSenders.forEach((rtcp) => { } catch (error) {
this.neko.removeTrack(rtcp) alert('Error accessing media devices.' + error)
})
this._audio.srcObject = null
this.micTracks = []
this.micSenders = []
}
async loadVideoDevices() {
let devices = await navigator.mediaDevices.enumerateDevices()
this.videoDevices = devices.filter((device) => device.kind === 'videoinput')
console.log('videoDevices', this.videoDevices)
}
async addWebcam() {
this.camTracks = []
this.camSenders = []
try {
let video = {
width: 1280,
height: 720,
} as MediaTrackConstraints
if (this.videoDevice != '') {
video.deviceId = this.videoDevice
}
const stream = await navigator.mediaDevices.getUserMedia({ video, audio: false })
this._video.srcObject = stream
console.log('Got MediaStream:', stream)
const tracks = stream.getTracks()
console.log('Got tracks:', tracks)
tracks.forEach((track) => {
this.camTracks.push(track)
console.log('Adding track', track, stream)
const rtcp = this.neko.addTrack(track, stream)
this.camSenders.push(rtcp)
console.log('rtcp sender', rtcp, rtcp.transport)
// TODO: Can be null.
rtcp.transport?.addEventListener('statechange', () => {
console.log('track - on state change', rtcp.transport?.state)
})
})
} catch (error) {
alert('Error accessing media devices.' + error)
}
}
stopWebcam() {
this.camTracks.forEach((track) => {
track.stop()
})
this.camSenders.forEach((rtcp) => {
this.neko.removeTrack(rtcp)
})
this._audio.srcObject = null
this.camTracks = []
this.camSenders = []
}
} }
}
function stopMicrophone() {
micTracks.value.forEach((track) => {
track.stop()
})
micSenders.value.forEach((rtcp) => {
props.neko.removeTrack(rtcp)
})
audio.value!.srcObject = null
micTracks.value = []
micSenders.value = []
}
async function loadVideoDevices() {
let devices = await navigator.mediaDevices.enumerateDevices()
videoDevices.value = devices.filter((device) => device.kind === 'videoinput')
console.log('videoDevices', videoDevices.value)
}
async function addWebcam() {
camTracks.value = []
camSenders.value = []
try {
let v = {
width: 1280,
height: 720,
} as MediaTrackConstraints
if (videoDevice.value != '') {
v.deviceId = videoDevice.value
}
const stream = await navigator.mediaDevices.getUserMedia({ video: v, audio: false })
video.value!.srcObject = stream
console.log('Got MediaStream:', stream)
const tracks = stream.getTracks()
console.log('Got tracks:', tracks)
tracks.forEach((track) => {
camTracks.value.push(track)
console.log('Adding track', track, stream)
const rtcp = props.neko.addTrack(track, stream)
camSenders.value.push(rtcp)
console.log('rtcp sender', rtcp, rtcp.transport)
// TODO: Can be null.
rtcp.transport?.addEventListener('statechange', () => {
console.log('track - on state change', rtcp.transport?.state)
})
})
} catch (error) {
alert('Error accessing media devices.' + error)
}
}
function stopWebcam() {
camTracks.value.forEach((track) => {
track.stop()
})
camSenders.value.forEach((rtcp) => {
props.neko.removeTrack(rtcp)
})
video.value!.srcObject = null
camTracks.value = []
camSenders.value = []
}
</script> </script>

View File

@ -14,7 +14,7 @@
</tr> </tr>
<tr> <tr>
<td colspan="2" style="text-align: center"> <td colspan="2" style="text-align: center">
<button @click="$set(plugins, 'new', [...plugins.new, ['', '']])">+</button> <button @click="plugins.new = [...plugins.new, ['', '']]">+</button>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -114,7 +114,7 @@
'state-is': 'state-is':
session.profile.sends_inactive_cursor && session.profile.sends_inactive_cursor &&
neko.state.settings.inactive_cursors && neko.state.settings.inactive_cursors &&
neko.state.cursors.some((e) => e.id == id), neko.state.cursors.some((e:any) => e.id == id),
'state-disabled': !session.profile.can_login || !session.profile.can_connect, 'state-disabled': !session.profile.can_login || !session.profile.can_connect,
}" }"
@click=" @click="
@ -141,7 +141,7 @@
<p class="title"> <p class="title">
<span>Members</span> <span>Members</span>
<button @click="membersLoad">reload</button> <button @click="membersLoad()">reload</button>
</p> </p>
<div <div
@ -152,7 +152,7 @@
v-for="member in membersWithoutSessions" v-for="member in membersWithoutSessions"
:key="'member-' + member.id" :key="'member-' + member.id"
> >
<div class="topbar"> <div class="topbar" v-if="member.profile && member.id">
<div class="name"> <div class="name">
<i v-if="neko.is_admin" class="fa fa-trash-alt" @click="memberRemove(member.id)" title="remove" /> <i v-if="neko.is_admin" class="fa fa-trash-alt" @click="memberRemove(member.id)" title="remove" />
{{ member.profile.name }} {{ member.profile.name }}
@ -406,168 +406,160 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
import { Vue, Component, Prop } from 'vue-property-decorator' import { ref, watch, computed, onMounted, onBeforeUnmount } from 'vue'
import Neko, { ApiModels, StateModels } from '~/component/main.vue' import Neko from '@/component/main.vue'
@Component({ // TODO: get from lib ts?
name: 'neko-members', import type * as ApiModels from '@/component/api/models'
}) import type * as StateModels from '@/component/types/state'
export default class extends Vue {
@Prop() readonly neko!: Neko
constructor() { const props = defineProps<{
super() neko: typeof Neko
}>()
// init const sessions = computed(() => props.neko.state.sessions as Record<string, StateModels.Session>)
this.newProfile = Object.assign({}, this.defProfile) const membersWithoutSessions = computed(() => {
return props.neko.state.members.filter(({ id }: { id: string }) => id && !(id in sessions.value)) as ApiModels.MemberData[]
})
const members = ref<ApiModels.MemberData[]>([])
const plugins = ref<{
id: string
old: Array<Array<string>>
new: Array<Array<string>>
profile: ApiModels.MemberProfile
} | null>(null)
const newUsername = ref('')
const newPassword = ref('')
const newProfile = ref<ApiModels.MemberProfile>({})
const defProfile = ref<ApiModels.MemberProfile>({
name: '',
is_admin: false,
can_login: true,
can_connect: true,
can_watch: true,
can_host: true,
can_share_media: true,
can_access_clipboard: true,
sends_inactive_cursor: true,
can_see_inactive_cursors: true,
})
newProfile.value = Object.assign({}, defProfile.value)
async function memberCreate() {
try {
const res = await props.neko.members.membersCreate({
username: newUsername.value,
password: newPassword.value,
profile: newProfile.value,
})
if (res.data) {
members.value = [...members.value, res.data]
} }
get sessions(): Record<string, StateModels.Session> { // clear
return this.neko.state.sessions newUsername.value = ''
} newPassword.value = ''
newProfile.value = Object.assign({}, defProfile.value)
get membersWithoutSessions(): ApiModels.MemberData[] { } catch (e: any) {
return this.members.filter(({ id }) => id && !(id in this.sessions)) alert(e.response ? e.response.data.message : e)
}
members: ApiModels.MemberData[] = []
plugins: {
id: string
old: Array<Array<string>>
new: Array<Array<string>>
profile: ApiModels.MemberProfile
} | null = null
newUsername: string = ''
newPassword: string = ''
newProfile: ApiModels.MemberProfile = {}
defProfile: ApiModels.MemberProfile = {
name: '',
is_admin: false,
can_login: true,
can_connect: true,
can_watch: true,
can_host: true,
can_share_media: true,
can_access_clipboard: true,
sends_inactive_cursor: true,
can_see_inactive_cursors: true,
}
async memberCreate() {
try {
const res = await this.neko.members.membersCreate({
username: this.newUsername,
password: this.newPassword,
profile: this.newProfile,
})
if (res.data) {
Vue.set(this, 'members', [...this.members, res.data])
}
// clear
Vue.set(this, 'newUsername', '')
Vue.set(this, 'newPassword', '')
Vue.set(this, 'newProfile', Object.assign({}, this.defProfile))
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async membersLoad(limit: number = 0) {
const offset = 0
try {
const res = await this.neko.members.membersList(limit, offset)
Vue.set(this, 'members', res.data)
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async memberGetProfile(memberId: string): Promise<ApiModels.MemberProfile | undefined> {
try {
const res = await this.neko.members.membersGetProfile(memberId)
return res.data
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async updateProfile(memberId: string, memberProfile: ApiModels.MemberProfile) {
try {
await this.neko.members.membersUpdateProfile(memberId, memberProfile)
const members = this.members.map((member) => {
if (member.id == memberId) {
return {
id: memberId,
profile: { ...member.profile, ...memberProfile },
}
} else {
return member
}
})
Vue.set(this, 'members', members)
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async updatePassword(memberId: string, password: string) {
try {
await this.neko.members.membersUpdatePassword(memberId, { password })
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async memberRemove(memberId: string) {
try {
await this.neko.members.membersRemove(memberId)
const members = this.members.filter(({ id }) => id != memberId)
Vue.set(this, 'members', members)
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
showPlugins(id: string, profile: ApiModels.MemberProfile) {
const old = Object.entries(profile.plugins || {}).map(([key, val]) => [key, JSON.stringify(val, null, 2)])
this.plugins = {
id,
old,
new: old.length > 0 ? [] : [['', '']],
profile,
}
}
savePlugins() {
if (!this.plugins) return
let errKey = ''
try {
let plugins = {} as any
for (let [key, val] of this.plugins.old) {
errKey = key
plugins[key] = JSON.parse(val)
}
for (let [key, val] of this.plugins.new) {
errKey = key
plugins[key] = JSON.parse(val)
}
this.updateProfile(this.plugins.id, { plugins })
this.plugins = null
} catch (e: any) {
alert(errKey + ': ' + e)
}
}
mounted() {
this.membersLoad(10)
}
} }
}
async function membersLoad(limit: number = 0) {
const offset = 0
try {
const res = await props.neko.members.membersList(limit, offset)
members.value = res.data
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async function memberGetProfile(memberId: string): Promise<ApiModels.MemberProfile | undefined> {
try {
const res = await props.neko.members.membersGetProfile(memberId)
return res.data
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async function updateProfile(memberId: string, memberProfile: ApiModels.MemberProfile) {
try {
await props.neko.members.membersUpdateProfile(memberId, memberProfile)
const newMembers = members.value.map((member) => {
if (member.id == memberId) {
return {
id: memberId,
profile: { ...member.profile, ...memberProfile },
}
} else {
return member
}
})
members.value = newMembers // TODO: Vue.Set
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async function updatePassword(memberId: string, password: string) {
try {
await props.neko.members.membersUpdatePassword(memberId, { password })
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
async function memberRemove(memberId: string) {
try {
await props.neko.members.membersRemove(memberId)
const newMembers = members.value.filter(({ id }) => id != memberId)
members.value = newMembers // TODO: Vue.Set
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
}
}
function showPlugins(id: string, profile: ApiModels.MemberProfile) {
const old = Object.entries(profile.plugins || {}).map(([key, val]) => [key, JSON.stringify(val, null, 2)])
plugins.value = {
id,
old,
new: old.length > 0 ? [] : [['', '']],
profile,
}
}
function savePlugins() {
if (!plugins.value) return
let errKey = ''
try {
let plugins = {} as any
for (let [key, val] of plugins.value.old) {
errKey = key
plugins[key] = JSON.parse(val)
}
for (let [key, val] of plugins.value.new) {
errKey = key
plugins[key] = JSON.parse(val)
}
updateProfile(plugins.value.id, { plugins })
plugins.value = null
} catch (e: any) {
alert(errKey + ': ' + e)
}
}
onMounted(() => {
membersLoad(10)
})
</script> </script>

View File

@ -1,17 +1,17 @@
<template> <template>
<div id="neko" :class="[expanded ? 'expanded' : '']"> <div id="neko" :class="[expanded ? 'expanded' : '']">
<main class="neko-main"> <main class="neko-main">
<div class="header-container"> <div class="header-container" v-if="neko">
<neko-header :neko="neko" @toggle="expanded = !expanded" /> <NekoHeader :neko="neko" @toggle="expanded = !expanded" />
</div> </div>
<div class="video-container"> <div class="video-container">
<neko-canvas ref="neko" :server="server" autologin autoconnect autoplay /> <NekoCanvas ref="neko" :server="server" autologin autoconnect autoplay />
<div v-if="loaded && neko.private_mode_enabled" class="player-notif">Private mode is currently enabled.</div> <div v-if="loaded && neko!.private_mode_enabled" class="player-notif">Private mode is currently enabled.</div>
<div <div
v-if="loaded && neko.state.connection.type === 'webrtc' && !neko.state.video.playing" v-if="loaded && neko!.state.connection.type === 'webrtc' && !neko!.state.video.playing"
class="player-overlay" class="player-overlay"
> >
<i @click.stop.prevent="neko.play()" v-if="neko.state.video.playable" class="fas fa-play-circle" /> <i @click.stop.prevent="neko!.play()" v-if="neko!.state.video.playable" class="fas fa-play-circle" />
</div> </div>
<div v-if="uploadActive" class="player-overlay" style="background: rgba(0, 0, 0, 0.8); font-size: 1vw"> <div v-if="uploadActive" class="player-overlay" style="background: rgba(0, 0, 0, 0.8); font-size: 1vw">
UPLOAD IN PROGRESS: {{ Math.round(uploadProgress) }}% UPLOAD IN PROGRESS: {{ Math.round(uploadProgress) }}%
@ -30,11 +30,11 @@
@dragenter.stop.prevent @dragenter.stop.prevent
@dragleave.stop.prevent @dragleave.stop.prevent
@dragover.stop.prevent @dragover.stop.prevent
@drop.stop.prevent="dialogUploadFiles($event.dataTransfer.files)" @drop.stop.prevent="dialogUploadFiles([...$event.dataTransfer!.files])"
> >
<span style="padding: 1em">UPLOAD REQUESTED:</span> <span style="padding: 1em">UPLOAD REQUESTED:</span>
<span style="background: white"> <span style="background: white">
<input type="file" @change="dialogUploadFiles($event.target.files)" multiple /> <input type="file" @change="dialogUploadFiles([...($event.target as HTMLInputElement)!.files!])" multiple />
</span> </span>
<span style="padding: 1em; padding-bottom: 0; font-style: italic">(or drop files here)</span> <span style="padding: 1em; padding-bottom: 0; font-style: italic">(or drop files here)</span>
<span style="padding: 1em"> <span style="padding: 1em">
@ -45,15 +45,15 @@
<div class="room-container" style="text-align: center"> <div class="room-container" style="text-align: center">
<button <button
v-if="loaded && isTouchDevice" v-if="loaded && isTouchDevice"
@click="neko.mobileKeyboardToggle" @click="neko!.mobileKeyboardToggle"
style="position: absolute; left: 5px; transform: translateY(-100%)" style="position: absolute; left: 5px; transform: translateY(-100%)"
> >
<i class="fa fa-keyboard" /> <i class="fa fa-keyboard" />
</button> </button>
<span v-if="loaded && neko.state.session_id" style="padding-top: 10px"> <span v-if="loaded && neko!.state.session_id" style="padding-top: 10px">
You are logged in as You are logged in as
<strong style="font-weight: bold"> <strong style="font-weight: bold">
{{ neko.state.sessions[neko.state.session_id].profile.name }} {{ neko!.state.sessions[neko!.state.session_id].profile.name }}
</strong> </strong>
</span> </span>
@ -65,14 +65,14 @@
</button> </button>
</div> </div>
<div class="controls"> <div class="controls">
<template v-if="loaded"> <template v-if="loaded && neko">
<neko-connect v-if="neko.state.connection.status == 'disconnected'" :neko="neko" /> <NekoConnect v-if="neko!.state.connection.status == 'disconnected'" :neko="neko" />
<neko-controls v-else :neko="neko" /> <NekoControls v-else :neko="neko" />
</template> </template>
</div> </div>
<div class="right-menu"> <div class="right-menu">
<div style="text-align: right" v-if="loaded"> <div style="text-align: right" v-if="loaded">
<button v-if="neko.state.connection.status != 'disconnected'" @click="neko.disconnect()"> <button v-if="neko!.state.connection.status != 'disconnected'" @click="neko!.disconnect()">
disconnect disconnect
</button> </button>
</div> </div>
@ -104,11 +104,11 @@
<component v-for="(el, key) in pluginsTabs" :key="key" :is="el" :tab="tab" @tab="tab = $event" /> <component v-for="(el, key) in pluginsTabs" :key="key" :is="el" :tab="tab" @tab="tab = $event" />
</ul> </ul>
</div> </div>
<div class="page-container"> <div class="page-container" v-if="neko">
<neko-events v-if="tab === 'events'" :neko="neko" /> <NekoEvents v-if="tab === 'events'" :neko="neko" />
<neko-members v-if="tab === 'members'" :neko="neko" /> <NekoMembers v-if="tab === 'members'" :neko="neko" />
<neko-media v-if="tab === 'media'" :neko="neko" /> <NekoMedia v-if="tab === 'media'" :neko="neko" />
<neko-chat v-show="tab === 'chat'" :neko="neko" /> <NekoChat v-show="tab === 'chat'" :neko="neko" />
<!-- Plugins --> <!-- Plugins -->
<component v-for="(el, key) in pluginsComponents" :key="key" :is="el" :tab="tab" :neko="neko" /> <component v-for="(el, key) in pluginsComponents" :key="key" :is="el" :tab="tab" :neko="neko" />
@ -318,345 +318,331 @@
} }
</style> </style>
<script lang="ts"> <script lang="ts" setup>
// plugins must be available at: // plugins must be available at:
// ./plugins/{name}/main-tabs.vue // ./plugins/{name}/main-tabs.vue
// ./plugins/{name}/main-components.vue // ./plugins/{name}/main-components.vue
let plugins = [] as string[] let plugins = [] as string[]
// dynamic plugins loader // dynamic plugins loader
;(function (r: any) { //;(function (r: any) {
r.keys().forEach((key: string) => { // r.keys().forEach((key: string) => {
const found = key.match(/\.\/(.*?)\//) // const found = key.match(/\.\/(.*?)\//)
if (found) { // if (found) {
plugins.push(found[1]) // plugins.push(found[1])
console.log('loading a plugin:', found[1]) // console.log('loading a plugin:', found[1])
} // }
}) // })
})(require.context('./plugins/', true, /(main-tabs|main-components)\.vue$/)) //})(require.context('./plugins/', true, /(main-tabs|main-components)\.vue$/))
import { Vue, Component, Ref } from 'vue-property-decorator' import { ref, computed, onMounted } from 'vue'
import { AxiosProgressEvent } from 'axios'
import NekoCanvas from '~/component/main.vue'
import NekoHeader from './components/header.vue'
import NekoConnect from './components/connect.vue'
import NekoControls from './components/controls.vue'
import NekoEvents from './components/events.vue'
import NekoMembers from './components/members.vue'
import NekoMedia from './components/media.vue'
import NekoChat from './components/chat.vue'
@Component({ import type { AxiosProgressEvent } from 'axios'
name: 'neko', import NekoCanvas from '@/component/main.vue'
components: { import NekoHeader from './components/header.vue'
'neko-canvas': NekoCanvas, import NekoConnect from './components/connect.vue'
'neko-header': NekoHeader, import NekoControls from './components/controls.vue'
'neko-connect': NekoConnect, import NekoEvents from './components/events.vue'
'neko-controls': NekoControls, import NekoMembers from './components/members.vue'
'neko-events': NekoEvents, import NekoMedia from './components/media.vue'
'neko-members': NekoMembers, import NekoChat from './components/chat.vue'
'neko-media': NekoMedia,
'neko-chat': NekoChat,
},
computed: {
pluginsTabs() {
let x = {} as Record<string, any>
for (let p of plugins) {
x[p] = () => import('./plugins/' + p + '/main-tabs.vue')
}
return x
},
pluginsComponents() {
let x = {} as Record<string, any>
for (let p of plugins) {
x[p] = () => import('./plugins/' + p + '/main-components.vue')
}
return x
},
},
})
export default class extends Vue {
@Ref('neko') readonly neko!: NekoCanvas
expanded: boolean = !window.matchMedia('(max-width: 600px)').matches // default to expanded on bigger screens
loaded: boolean = false
tab: string = ''
server: string = location.href const pluginsTabs = computed(() => {
let x = {} as Record<string, any>
for (let p of plugins) {
x[p] = () => import('./plugins/' + p + '/main-tabs.vue')
}
return x
})
uploadActive = false const pluginsComponents = computed(() => {
uploadProgress = 0 let x = {} as Record<string, any>
for (let p of plugins) {
x[p] = () => import('./plugins/' + p + '/main-components.vue')
}
return x
})
get isTouchDevice(): boolean { const neko = ref<typeof NekoCanvas>()
return 'ontouchstart' in window || navigator.maxTouchPoints > 0
}
dialogOverlayActive = false const expanded = ref(!window.matchMedia('(max-width: 600px)').matches) // default to expanded on bigger screens
dialogRequestActive = false const loaded = ref(false)
async dialogUploadFiles(files: File[]) { const tab = ref('')
console.log('will upload files', files)
this.uploadActive = true const server = ref(location.href)
this.uploadProgress = 0
try {
await this.neko.room.uploadDialog([...files], {
onUploadProgress: (progressEvent: AxiosProgressEvent) => {
if (!progressEvent.total) {
this.uploadProgress = 0
return
}
this.uploadProgress = (progressEvent.loaded / progressEvent.total) * 100
},
})
} catch (e: any) {
alert(e.response ? e.response.data.message : e)
} finally {
this.uploadActive = false
}
}
dialogCancel() { const uploadActive = ref(false)
this.neko.room.uploadDialogClose() const uploadProgress = ref(0)
}
mounted() { const isTouchDevice = computed(() => 'ontouchstart' in window || navigator.maxTouchPoints > 0)
this.loaded = true
this.tab = 'events'
//@ts-ignore
window.neko = this.neko
// initial URL const dialogOverlayActive = ref(false)
const url = new URL(location.href).searchParams.get('url') const dialogRequestActive = ref(false)
if (url) { async function dialogUploadFiles(files: File[]) {
this.server = url console.log('will upload files', files)
}
// uploadActive.value = true
// connection events uploadProgress.value = 0
// try {
this.neko.events.on('connection.status', (status: 'connected' | 'connecting' | 'disconnected') => { await neko.value!.room.uploadDialog([...files], {
console.log('connection.status', status) onUploadProgress: (progressEvent: AxiosProgressEvent) => {
})
this.neko.events.on('connection.type', (type: 'fallback' | 'webrtc' | 'none') => {
console.log('connection.type', type)
})
this.neko.events.on('connection.webrtc.sdp', (type: 'local' | 'remote', data: string) => {
console.log('connection.webrtc.sdp', type, data)
})
this.neko.events.on('connection.webrtc.sdp.candidate', (type: 'local' | 'remote', data: RTCIceCandidateInit) => {
console.log('connection.webrtc.sdp.candidate', type, data)
})
this.neko.events.on('connection.closed', (error?: Error) => {
if (error) {
alert('Connection closed with error: ' + error.message)
} else {
alert('Connection closed without error.')
}
})
//
// drag and drop events
//
this.neko.events.on('upload.drop.started', () => {
this.uploadActive = true
this.uploadProgress = 0
})
this.neko.events.on('upload.drop.progress', (progressEvent: AxiosProgressEvent) => {
if (!progressEvent.total) { if (!progressEvent.total) {
this.uploadProgress = 0 uploadProgress.value = 0
return return
} }
this.uploadProgress = (progressEvent.loaded / progressEvent.total) * 100 uploadProgress.value = (progressEvent.loaded / progressEvent.total) * 100
}) },
this.neko.events.on('upload.drop.finished', (e?: any) => { })
this.uploadActive = false } catch (e: any) {
if (e) { alert(e.response ? e.response.data.message : e)
alert(e.response ? e.response.data.message : e) } finally {
} uploadActive.value = false
})
//
// upload dialog events
//
this.neko.events.on('upload.dialog.requested', () => {
this.dialogRequestActive = true
})
this.neko.events.on('upload.dialog.overlay', (id: string) => {
this.dialogOverlayActive = true
console.log('upload.dialog.overlay', id)
})
this.neko.events.on('upload.dialog.closed', () => {
this.dialogOverlayActive = false
this.dialogRequestActive = false
})
//
// custom messages events
//
this.neko.events.on('receive.unicast', (sender: string, subject: string, body: string) => {
console.log('receive.unicast', sender, subject, body)
})
this.neko.events.on('receive.broadcast', (sender: string, subject: string, body: string) => {
console.log('receive.broadcast', sender, subject, body)
})
//
// session events
//
this.neko.events.on('session.created', (id: string) => {
console.log('session.created', id)
})
this.neko.events.on('session.deleted', (id: string) => {
console.log('session.deleted', id)
})
this.neko.events.on('session.updated', (id: string) => {
console.log('session.updated', id)
})
//
// room events
//
this.neko.events.on('room.control.host', (hasHost: boolean, hostID?: string) => {
console.log('room.control.host', hasHost, hostID)
})
this.neko.events.on('room.screen.updated', (width: number, height: number, rate: number) => {
console.log('room.screen.updated', width, height, rate)
})
this.neko.events.on('room.clipboard.updated', (text: string) => {
console.log('room.clipboard.updated', text)
})
this.neko.events.on('room.broadcast.status', (isActive: boolean, url?: string) => {
console.log('room.broadcast.status', isActive, url)
})
//
// control events
//
this.neko.control.on('overlay.click', (e: MouseEvent) => {
console.log('control: overlay.click', e)
})
this.neko.control.on('overlay.contextmenu', (e: MouseEvent) => {
console.log('control: overlay.contextmenu', e)
})
// custom inactive cursor draw function
this.neko.setInactiveCursorDrawFunction(
(ctx: CanvasRenderingContext2D, x: number, y: number, sessionId: string) => {
const cursorTag = this.neko.state.sessions[sessionId]?.profile.name || ''
const colorLight = '#CCDFF6'
const colorDark = '#488DDE'
// get current cursor position
x -= 4
y -= 4
// draw arrow path
const arrowPath = new Path2D('M5 5L19 12.5L12.3286 14.465L8.29412 20L5 5Z')
ctx.globalAlpha = 0.5
ctx.translate(x, y)
ctx.fillStyle = colorLight
ctx.fill(arrowPath)
ctx.lineWidth = 1.5
ctx.lineJoin = 'miter'
ctx.miterLimit = 10
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.strokeStyle = colorDark
ctx.stroke(arrowPath)
// draw cursor tag
if (cursorTag) {
const x = 20 // box margin x
const y = 20 // box margin y
ctx.globalAlpha = 0.5
ctx.font = '10px Arial, sans-serif'
ctx.textBaseline = 'top'
ctx.shadowColor = 'black'
ctx.shadowBlur = 2
ctx.lineWidth = 2
ctx.fillStyle = 'black'
ctx.strokeText(cursorTag, x, y)
ctx.shadowBlur = 0
ctx.fillStyle = 'white'
ctx.fillText(cursorTag, x, y)
}
},
)
this.toggleCursor()
}
private usesCursor = false
toggleCursor() {
if (this.usesCursor) {
this.usesCursor = false
this.neko.setCursorDrawFunction()
return
}
// custom cursor draw function
this.neko.setCursorDrawFunction(
(ctx: CanvasRenderingContext2D, x: number, y: number, {}, {}, sessionId: string) => {
const cursorTag = this.neko.state.sessions[sessionId]?.profile.name || ''
const colorLight = '#CCDFF6'
const colorDark = '#488DDE'
const fontColor = '#ffffff'
// get current cursor position
x -= 4
y -= 4
// draw arrow path
const arrowPath = new Path2D('M5 5L26 16.5L15.9929 19.513L9.94118 28L5 5Z')
ctx.translate(x, y)
ctx.fillStyle = colorLight
ctx.fill(arrowPath)
ctx.lineWidth = 2
ctx.lineJoin = 'miter'
ctx.miterLimit = 10
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.strokeStyle = colorDark
ctx.stroke(arrowPath)
// draw cursor tag
if (cursorTag) {
const fontSize = 12
const boxPaddingX = 9
const boxPaddingY = 6
const x = 22 // box margin x
const y = 28 // box margin y
// prepare tag text
ctx.font = '500 ' + fontSize + 'px Roboto, sans-serif'
ctx.textBaseline = 'ideographic'
// create tag container
const txtWidth = ctx.measureText(cursorTag).width
const w = txtWidth + boxPaddingX * 2
const h = fontSize + boxPaddingY * 2
const r = Math.min(w / 2, h / 2)
ctx.beginPath()
ctx.moveTo(x + r, y)
ctx.arcTo(x + w, y, x + w, y + h, r) // Top-Right
ctx.arcTo(x + w, y + h, x, y + h, r) // Bottom-Right
ctx.arcTo(x, y + h, x, y, r) // Bottom-Left
ctx.arcTo(x, y, x + w, y, 2) // Top-Left
ctx.closePath()
ctx.fillStyle = colorDark
ctx.fill()
// fill in tag text
ctx.fillStyle = fontColor
ctx.fillText(cursorTag, x + boxPaddingX, y + fontSize + boxPaddingY)
}
},
)
this.usesCursor = true
}
} }
}
function dialogCancel() {
neko.value!.room.uploadDialogClose()
}
onMounted(() => {
loaded.value = true
tab.value = 'events'
//@ts-ignore
window.neko = neko
// initial URL
const url = new URL(location.href).searchParams.get('url')
if (url) {
server.value = url
}
//
// connection events
//
neko.value!.events.on('connection.status', (status: 'connected' | 'connecting' | 'disconnected') => {
console.log('connection.status', status)
})
neko.value!.events.on('connection.type', (type: 'fallback' | 'webrtc' | 'none') => {
console.log('connection.type', type)
})
neko.value!.events.on('connection.webrtc.sdp', (type: 'local' | 'remote', data: string) => {
console.log('connection.webrtc.sdp', type, data)
})
neko.value!.events.on('connection.webrtc.sdp.candidate', (type: 'local' | 'remote', data: RTCIceCandidateInit) => {
console.log('connection.webrtc.sdp.candidate', type, data)
})
neko.value!.events.on('connection.closed', (error?: Error) => {
if (error) {
alert('Connection closed with error: ' + error.message)
} else {
alert('Connection closed without error.')
}
})
//
// drag and drop events
//
neko.value!.events.on('upload.drop.started', () => {
uploadActive.value = true
uploadProgress.value = 0
})
neko.value!.events.on('upload.drop.progress', (progressEvent: AxiosProgressEvent) => {
if (!progressEvent.total) {
uploadProgress.value = 0
return
}
uploadProgress.value = (progressEvent.loaded / progressEvent.total) * 100
})
neko.value!.events.on('upload.drop.finished', (e?: any) => {
uploadActive.value = false
if (e) {
alert(e.response ? e.response.data.message : e)
}
})
//
// upload dialog events
//
neko.value!.events.on('upload.dialog.requested', () => {
dialogRequestActive.value = true
})
neko.value!.events.on('upload.dialog.overlay', (id: string) => {
dialogOverlayActive.value = true
console.log('upload.dialog.overlay', id)
})
neko.value!.events.on('upload.dialog.closed', () => {
dialogOverlayActive.value = false
dialogRequestActive.value = false
})
//
// custom messages events
//
neko.value!.events.on('receive.unicast', (sender: string, subject: string, body: string) => {
console.log('receive.unicast', sender, subject, body)
})
neko.value!.events.on('receive.broadcast', (sender: string, subject: string, body: string) => {
console.log('receive.broadcast', sender, subject, body)
})
//
// session events
//
neko.value!.events.on('session.created', (id: string) => {
console.log('session.created', id)
})
neko.value!.events.on('session.deleted', (id: string) => {
console.log('session.deleted', id)
})
neko.value!.events.on('session.updated', (id: string) => {
console.log('session.updated', id)
})
//
// room events
//
neko.value!.events.on('room.control.host', (hasHost: boolean, hostID?: string) => {
console.log('room.control.host', hasHost, hostID)
})
neko.value!.events.on('room.screen.updated', (width: number, height: number, rate: number) => {
console.log('room.screen.updated', width, height, rate)
})
neko.value!.events.on('room.clipboard.updated', (text: string) => {
console.log('room.clipboard.updated', text)
})
neko.value!.events.on('room.broadcast.status', (isActive: boolean, url?: string) => {
console.log('room.broadcast.status', isActive, url)
})
//
// control events
//
neko.value!.control.on('overlay.click', (e: MouseEvent) => {
console.log('control: overlay.click', e)
})
neko.value!.control.on('overlay.contextmenu', (e: MouseEvent) => {
console.log('control: overlay.contextmenu', e)
})
// custom inactive cursor draw function
neko.value!.setInactiveCursorDrawFunction(
(ctx: CanvasRenderingContext2D, x: number, y: number, sessionId: string) => {
const cursorTag = neko.value!.state.sessions[sessionId]?.profile.name || ''
const colorLight = '#CCDFF6'
const colorDark = '#488DDE'
// get current cursor position
x -= 4
y -= 4
// draw arrow path
const arrowPath = new Path2D('M5 5L19 12.5L12.3286 14.465L8.29412 20L5 5Z')
ctx.globalAlpha = 0.5
ctx.translate(x, y)
ctx.fillStyle = colorLight
ctx.fill(arrowPath)
ctx.lineWidth = 1.5
ctx.lineJoin = 'miter'
ctx.miterLimit = 10
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.strokeStyle = colorDark
ctx.stroke(arrowPath)
// draw cursor tag
if (cursorTag) {
const x = 20 // box margin x
const y = 20 // box margin y
ctx.globalAlpha = 0.5
ctx.font = '10px Arial, sans-serif'
ctx.textBaseline = 'top'
ctx.shadowColor = 'black'
ctx.shadowBlur = 2
ctx.lineWidth = 2
ctx.fillStyle = 'black'
ctx.strokeText(cursorTag, x, y)
ctx.shadowBlur = 0
ctx.fillStyle = 'white'
ctx.fillText(cursorTag, x, y)
}
},
)
toggleCursor()
})
const usesCursor = ref(false)
function toggleCursor() {
if (usesCursor.value) {
neko.value!.setCursorDrawFunction()
usesCursor.value = false
return
}
// custom cursor draw function
neko.value!.setCursorDrawFunction(
(ctx: CanvasRenderingContext2D, x: number, y: number, {}, {}, sessionId: string) => {
const cursorTag = neko.value!.state.sessions[sessionId]?.profile.name || ''
const colorLight = '#CCDFF6'
const colorDark = '#488DDE'
const fontColor = '#ffffff'
// get current cursor position
x -= 4
y -= 4
// draw arrow path
const arrowPath = new Path2D('M5 5L26 16.5L15.9929 19.513L9.94118 28L5 5Z')
ctx.translate(x, y)
ctx.fillStyle = colorLight
ctx.fill(arrowPath)
ctx.lineWidth = 2
ctx.lineJoin = 'miter'
ctx.miterLimit = 10
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.strokeStyle = colorDark
ctx.stroke(arrowPath)
// draw cursor tag
if (cursorTag) {
const fontSize = 12
const boxPaddingX = 9
const boxPaddingY = 6
const x = 22 // box margin x
const y = 28 // box margin y
// prepare tag text
ctx.font = '500 ' + fontSize + 'px Roboto, sans-serif'
ctx.textBaseline = 'ideographic'
// create tag container
const txtWidth = ctx.measureText(cursorTag).width
const w = txtWidth + boxPaddingX * 2
const h = fontSize + boxPaddingY * 2
const r = Math.min(w / 2, h / 2)
ctx.beginPath()
ctx.moveTo(x + r, y)
ctx.arcTo(x + w, y, x + w, y + h, r) // Top-Right
ctx.arcTo(x + w, y + h, x, y + h, r) // Bottom-Right
ctx.arcTo(x, y + h, x, y, r * 2) // Bottom-Left
ctx.arcTo(x, y, x + w, y, r * 2) // Top-Left
ctx.closePath()
ctx.fillStyle = colorDark
ctx.fill()
// fill in tag text
ctx.fillStyle = fontColor
ctx.fillText(cursorTag, x + boxPaddingX, y + fontSize + boxPaddingY)
}
},
)
usesCursor.value = true
}
</script> </script>
<style> <style>

14
tsconfig.app.json Normal file
View File

@ -0,0 +1,14 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}

View File

@ -1,42 +1,14 @@
{ {
"compilerOptions": { "files": [],
"target": "esnext", "references": [
"module": "esnext", {
"strict": true, "path": "./tsconfig.node.json"
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"skipLibCheck": true,
"baseUrl": ".",
"types": [
"node",
"webpack-env"
],
"paths": {
"~/*": [
"src/*"
],
"@/*": [
"src/*"
]
}, },
"lib": [ {
"esnext", "path": "./tsconfig.app.json"
"dom", },
"dom.iterable", {
"scripthost" "path": "./tsconfig.vitest.json"
], }
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
],
"exclude": [
"node_modules"
] ]
} }

19
tsconfig.node.json Normal file
View File

@ -0,0 +1,19 @@
{
"extends": "@tsconfig/node20/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*"
],
"compilerOptions": {
"composite": true,
"noEmit": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}

11
tsconfig.vitest.json Normal file
View File

@ -0,0 +1,11 @@
{
"extends": "./tsconfig.app.json",
"exclude": [],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
"lib": [],
"types": ["node", "jsdom"]
}
}

View File

@ -1,50 +0,0 @@
#!/bin/bash
rm -rf dist/types
# Find all vue files, and convert them to .ts files
find src/component -name "*.vue" -type f -print0 | while IFS= read -r -d '' file; do
# Get the file name
filename=$(basename -- "$file")
# Get the file name without extension
filename="${filename%.*}"
# Get the directory name
directory=$(dirname -- "$file")
# Get the directory name without the first dot
directory="${directory}"
if [ "$directory" = "" ]; then
directory="."
fi
echo "Creating: $file --> $directory/$filename.ts"
# Get contant of the file, that is between <script lang="ts"> and </script>
content=$(sed -n '/<script lang="ts">/,/<\/script>/p' "$file" | sed '1d;$d')
# Remove .vue in imports
content=$(echo "$content" | sed 's/\.vue//g')
# Create a new file with the same name and .ts extension
echo "$content" > "$directory/$filename.ts"
# Add file to .toDelete file
echo "$directory/$filename.ts" >> .toDelete
done
echo "Compiling files"
npx tsc -p types-tsconfig.json
# Remove all .js files in dist/types folder
echo "Removing .js files in dist/types"
find dist/types -name "*.js" -type f -delete
# Remove all files listed in .toDelete
echo "Removing files listed in .toDelete"
while read -r file; do
echo "Removing: $file"
rm -f "$file"
done < .toDelete
# Remove .toDelete file
rm -f .toDelete

View File

@ -1,26 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"declaration": true,
"rootDir": "src/component",
"outDir": "dist/types",
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/component/**/*.ts"
],
"exclude": [
"node_modules"
]
}

16
vite.config.ts Normal file
View File

@ -0,0 +1,16 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})

14
vitest.config.ts Normal file
View File

@ -0,0 +1,14 @@
import { fileURLToPath } from 'node:url'
import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
import viteConfig from './vite.config'
export default mergeConfig(
viteConfig,
defineConfig({
test: {
environment: 'jsdom',
exclude: [...configDefaults.exclude, 'e2e/*'],
root: fileURLToPath(new URL('./', import.meta.url))
}
})
)

View File

@ -1,33 +0,0 @@
const path = require('path')
const webpack = require('webpack')
module.exports = {
productionSourceMap: false,
publicPath: './',
assetsDir: './',
configureWebpack: {
resolve: {
alias: {
vue$: 'vue/dist/vue.esm.js',
'~': path.resolve(__dirname, 'src/'),
},
},
plugins: [
new webpack.NormalModuleReplacementPlugin(
/(.*)__KEYBOARD__/,
function(resource){
resource.request = resource.request
.replace(/__KEYBOARD__/, process.env.KEYBOARD || 'guacamole');
},
),
],
},
devServer: {
allowedHosts: "all",
proxy: {
'^/api': {
target: 'http://' + process.env.NEKO_HOST + ':' + process.env.NEKO_PORT + '/',
},
},
},
}