Compare commits

...

175 Commits

Author SHA1 Message Date
Janis
1a5f0b8e6e update version 2023-11-12 18:35:34 +01:00
Janis
8db32153d2 Use Hashrouter because of ghpages 2023-11-12 18:34:40 +01:00
Janis
b1da52ad1d Merge pull request #88 from DerTyp7/dev
Implement generator to simplify customization
2023-11-12 18:24:08 +01:00
Janis
dbc2bd422d Merge pull request #87 from DerTyp7/feature_implement-url-generator
Feature implement URL generator
2023-11-12 18:21:44 +01:00
Janis
86d2eb4c50 remove vite-plugin-singlefile 2023-11-12 18:19:14 +01:00
Janis
63bef6e11d update readme 2023-11-12 18:16:18 +01:00
Janis
e65eb5b3c4 Update README.md 2023-11-12 18:14:30 +01:00
Janis
e847dde41d update readme 2023-11-12 18:14:08 +01:00
Janis
5f0ca2c209 clean up 2023-11-12 18:03:20 +01:00
Janis
a4f64c3781 add instructions 2023-11-12 17:24:34 +01:00
Janis
9870fdcdb4 add responsive design 2023-11-12 17:16:58 +01:00
Janis
ce7aee8481 fix viewer style 2023-11-12 16:41:09 +01:00
Janis
5ef2facfec better generator 2023-11-12 16:28:42 +01:00
bbd10af0dc add basic generator structure 2023-11-10 11:20:58 +01:00
Janis
e2a8472cf9 add generator url 2023-11-05 17:40:16 +01:00
Janis
ed78b23bb1 add router 2023-11-05 17:32:27 +01:00
Janis
58fa81eb71 change version to 2.0.0 2023-11-05 17:20:01 +01:00
Janis
3a75c91bbd use moduleResolution node 2023-11-05 17:19:14 +01:00
Janis
fa64de9666 update vite 2023-11-05 17:16:22 +01:00
Janis
847cb76bca Merge pull request #83 from DerTyp7/dependabot/npm_and_yarn/dev/eslint-8.53.0
Bump eslint from 8.45.0 to 8.53.0
2023-11-05 17:10:25 +01:00
Janis
6a7dd4455e Merge pull request #84 from DerTyp7/dependabot/npm_and_yarn/dev/typescript-eslint/parser-6.9.1
Bump @typescript-eslint/parser from 6.2.1 to 6.9.1
2023-11-05 17:10:19 +01:00
dependabot[bot]
61678b3ed4 Bump eslint from 8.45.0 to 8.53.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.45.0 to 8.53.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.45.0...v8.53.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-05 16:10:14 +00:00
Janis
fea7f03d20 Merge pull request #85 from DerTyp7/dependabot/npm_and_yarn/dev/types/react-dom-18.2.14
Bump @types/react-dom from 18.2.7 to 18.2.14
2023-11-05 17:10:12 +01:00
dependabot[bot]
7551dd421c Bump @typescript-eslint/parser from 6.2.1 to 6.9.1
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.2.1 to 6.9.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-05 16:10:00 +00:00
dependabot[bot]
18b4c0c67d Bump @types/react-dom from 18.2.7 to 18.2.14
Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 18.2.7 to 18.2.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-05 16:09:55 +00:00
Janis
e75116d6c9 Merge pull request #86 from DerTyp7/dependabot/npm_and_yarn/dev/types/react-18.2.35
Bump @types/react from 18.2.23 to 18.2.35
2023-11-05 17:09:20 +01:00
dependabot[bot]
176cdc79ed Bump @types/react from 18.2.23 to 18.2.35
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.23 to 18.2.35.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-05 16:08:39 +00:00
Janis
6ca724bd77 Merge pull request #82 from DerTyp7/dependabot/npm_and_yarn/react-router-dom-6.18.0
Bump react-router-dom from 6.14.2 to 6.18.0
2023-11-05 17:07:53 +01:00
Janis
3bd6c60987 dependabot should target dev branch 2023-11-05 17:06:49 +01:00
dependabot[bot]
eb73c51ee1 Bump react-router-dom from 6.14.2 to 6.18.0
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.14.2 to 6.18.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.18.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 01:11:44 +00:00
Janis
945c3ec582 Update bug_report.md 2023-10-23 15:12:11 +02:00
Janis
2c24379bbb Update README.md 2023-10-21 16:28:24 +02:00
Janis
d67a243c5d Update README 2023-10-07 23:04:42 +02:00
Janis
3174145067 update package.json 2023-10-07 22:59:51 +02:00
Janis
c40b33de2b update prettier config 2023-10-07 22:53:39 +02:00
Janis
7974a08b24 remove old eslint comment 2023-10-07 22:50:45 +02:00
Janis
ab38a1b1fe add . to meta 2023-10-07 22:48:23 +02:00
Janis
bb7d2d61c6 add meta tags 2023-10-07 22:46:04 +02:00
Janis
81eed1e0ab Delete .github/workflows/eslint.yml 2023-10-07 22:39:04 +02:00
Janis
d75e11f3cd Create eslint.yml 2023-10-07 22:36:17 +02:00
Janis
c5a8f484b7 Update README.md 2023-10-07 20:32:00 +02:00
Janis
c5b801d3d5 Update README.md 2023-10-07 17:29:33 +02:00
Janis
c86618f78f add better readability 2023-10-07 17:26:20 +02:00
Janis
2f1e91c199 add new common issue 2023-10-07 17:24:26 +02:00
Janis
59594125a5 change version to 1.3.1 2023-10-07 17:15:09 +02:00
Janis
32108d7a99 change author and version 2023-10-07 17:10:37 +02:00
Janis
5c8d9721b2 add quick instructions 2023-10-07 17:06:25 +02:00
Janis
24f3e6dd88 Rewrite instructions 2023-10-07 16:36:19 +02:00
Janis
3461e2be0a Add new instruction for the easy online usage 2023-10-07 16:04:48 +02:00
Janis
456d09d647 update version to 1.2.5 2023-10-07 15:42:53 +02:00
Janis
09d24b2acd Merge pull request #75 from DerTyp7/dependabot/npm_and_yarn/types/node-20.8.3
Bump @types/node from 20.8.0 to 20.8.3
2023-10-07 15:41:33 +02:00
dependabot[bot]
389033e795 Bump @types/node from 20.8.0 to 20.8.3
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.0 to 20.8.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-07 13:41:03 +00:00
Janis
76ee50e262 Merge pull request #76 from DerTyp7/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.7.4
Bump @typescript-eslint/eslint-plugin from 6.7.3 to 6.7.4
2023-10-07 15:40:26 +02:00
Janis
2fb3c47e33 uninstall jest (not used) 2023-10-07 15:40:07 +02:00
dependabot[bot]
7676e72ca1 Bump @typescript-eslint/eslint-plugin from 6.7.3 to 6.7.4
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.3 to 6.7.4.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.4/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-07 13:39:09 +00:00
Janis
7bd7786465 Merge pull request #70 from DerTyp7/dependabot/npm_and_yarn/sass-1.68.0
Bump sass from 1.64.1 to 1.68.0
2023-10-07 15:38:39 +02:00
Janis
e27cd40234 Merge pull request #71 from DerTyp7/dependabot/npm_and_yarn/types/node-20.8.0
Bump @types/node from 20.4.5 to 20.8.0
2023-10-07 15:38:32 +02:00
Janis
13080ca9d1 Merge pull request #72 from DerTyp7/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.7.3
Bump @typescript-eslint/eslint-plugin from 6.2.0 to 6.7.3
2023-10-07 15:38:26 +02:00
Janis
a74ae8988f Merge pull request #73 from DerTyp7/dependabot/npm_and_yarn/types/react-18.2.23
Bump @types/react from 18.2.15 to 18.2.23
2023-10-07 15:38:19 +02:00
Janis
31b564d676 Merge pull request #74 from DerTyp7/dependabot/npm_and_yarn/postcss-8.4.31
Bump postcss from 8.4.26 to 8.4.31
2023-10-07 15:38:10 +02:00
Janis
c9c31a3e64 update package.json values 2023-10-07 15:37:34 +02:00
Janis
295153e702 newer gh-pages actions version 2023-10-07 15:32:27 +02:00
Janis
1cac2ca77f change version in auth payload 2023-10-07 15:22:49 +02:00
Janis
f6bf559612 update to version 1.2.3 2023-10-07 15:22:30 +02:00
dependabot[bot]
db770ab2b1 Bump postcss from 8.4.26 to 8.4.31
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.26 to 8.4.31.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.26...8.4.31)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-07 13:21:18 +00:00
Janis
15f18ecf31 Merge branch 'main' of https://github.com/DerTyp7/ts5-obs-overlay 2023-10-07 15:20:47 +02:00
Janis
6998f7cbbf add github actions deploy 2023-10-07 15:20:46 +02:00
Janis
bb707b7450 Update README.md 2023-10-07 15:10:26 +02:00
dependabot[bot]
9d3a30462c Bump @types/react from 18.2.15 to 18.2.23
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.15 to 18.2.23.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 01:33:44 +00:00
dependabot[bot]
dbb171ef11 Bump @typescript-eslint/eslint-plugin from 6.2.0 to 6.7.3
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.2.0 to 6.7.3.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.3/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 01:33:23 +00:00
dependabot[bot]
66e8f699e3 Bump @types/node from 20.4.5 to 20.8.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.5 to 20.8.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 01:32:22 +00:00
dependabot[bot]
c8a44d5a5d Bump sass from 1.64.1 to 1.68.0
Bumps [sass](https://github.com/sass/dart-sass) from 1.64.1 to 1.68.0.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.64.1...1.68.0)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 01:31:48 +00:00
Janis
1afc82ff93 Update dependabot.yml 2023-09-08 11:00:45 +02:00
Janis
9f11fa0241 updated version 2023-08-03 00:14:58 +02:00
Janis
33a6e20e00 updated api version 2023-08-03 00:13:52 +02:00
Janis
5d1b32eda3 updated api version 2023-08-02 23:51:06 +02:00
Janis
2f040b1b59 "@typescript-eslint/parser": "^6.2.1", 2023-08-02 23:44:41 +02:00
Janis
8808785bab Merge pull request #45 from DerTyp7/dependabot/npm_and_yarn/react-router-dom-6.14.2
Bump react-router-dom from 6.14.1 to 6.14.2
2023-08-02 23:42:43 +02:00
Janis
4787124f3f Merge pull request #46 from DerTyp7/dependabot/npm_and_yarn/sass-1.64.1
Bump sass from 1.63.6 to 1.64.1
2023-08-02 23:42:36 +02:00
Janis
6884abb1b8 Merge pull request #49 from DerTyp7/dependabot/npm_and_yarn/vite-4.4.7
Bump vite from 4.4.4 to 4.4.7
2023-08-02 23:42:30 +02:00
Janis
e1d9ff1145 Merge pull request #50 from DerTyp7/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.2.0
Bump @typescript-eslint/eslint-plugin from 5.59.8 to 6.2.0
2023-08-02 23:42:24 +02:00
Janis
d824d5023c Merge pull request #51 from DerTyp7/dependabot/npm_and_yarn/types/node-20.4.5
Bump @types/node from 20.4.2 to 20.4.5
2023-08-02 23:42:16 +02:00
dependabot[bot]
4493a1e97f Bump @types/node from 20.4.2 to 20.4.5
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.2 to 20.4.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 01:25:02 +00:00
dependabot[bot]
79f78defbe Bump @typescript-eslint/eslint-plugin from 5.59.8 to 6.2.0
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.59.8 to 6.2.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 01:23:47 +00:00
dependabot[bot]
074e7b95e9 Bump vite from 4.4.4 to 4.4.7
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.4 to 4.4.7.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.7/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 01:22:04 +00:00
dependabot[bot]
72c9e8d51e Bump sass from 1.63.6 to 1.64.1
Bumps [sass](https://github.com/sass/dart-sass) from 1.63.6 to 1.64.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.63.6...1.64.1)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 02:03:13 +00:00
dependabot[bot]
c6b151384f Bump react-router-dom from 6.14.1 to 6.14.2
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.14.1 to 6.14.2.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.14.2/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 02:03:04 +00:00
Janis
e5aef6eea8 update change version to 1.2.0 2023-07-24 02:35:51 +02:00
Janis
b541edbb58 Merge pull request #43 from DerTyp7/refactor_custom-react-hook
Refactor custom react hook
2023-07-24 02:33:44 +02:00
Janis
8587271283 change version to 1.2.0 2023-07-24 02:33:21 +02:00
Janis
728afd5d1c remove handler from this package and use seperate package 2023-07-24 01:59:57 +02:00
Janis
793ae71186 better readability 2023-07-24 00:50:08 +02:00
Janis
da518bbd1e add searchparams port 2023-07-24 00:47:55 +02:00
Janis
bd5ecc1ab0 outsource to react hook 2023-07-24 00:46:00 +02:00
Janis
04112657e6 change version to 1.1.3 2023-07-24 00:36:58 +02:00
Janis
02a572c316 Merge pull request #38 from DerTyp7/dependabot/npm_and_yarn/types/node-20.4.2
Bump @types/node from 20.4.1 to 20.4.2
2023-07-24 00:33:47 +02:00
Janis
c34c98fe86 Merge pull request #39 from DerTyp7/dependabot/npm_and_yarn/types/react-dom-18.2.7
Bump @types/react-dom from 18.2.4 to 18.2.7
2023-07-24 00:33:42 +02:00
Janis
7e729c2055 Merge pull request #40 from DerTyp7/dependabot/npm_and_yarn/eslint-8.45.0
Bump eslint from 8.44.0 to 8.45.0
2023-07-24 00:33:35 +02:00
Janis
f304133f34 Merge pull request #41 from DerTyp7/dependabot/npm_and_yarn/vite-4.4.4
Bump vite from 4.4.2 to 4.4.4
2023-07-24 00:33:29 +02:00
Janis
989fff4b72 Merge pull request #42 from DerTyp7/dependabot/npm_and_yarn/typescript-eslint/parser-5.62.0
Bump @typescript-eslint/parser from 5.59.8 to 5.62.0
2023-07-24 00:33:20 +02:00
dependabot[bot]
585622cec7 Bump @typescript-eslint/parser from 5.59.8 to 5.62.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.59.8 to 5.62.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.62.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-17 01:19:29 +00:00
dependabot[bot]
e89cdb40a2 Bump vite from 4.4.2 to 4.4.4
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.2 to 4.4.4.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.4/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-17 01:19:00 +00:00
dependabot[bot]
7f866ae2c1 Bump eslint from 8.44.0 to 8.45.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.44.0 to 8.45.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.44.0...v8.45.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-17 01:18:39 +00:00
dependabot[bot]
e326e93f2f Bump @types/react-dom from 18.2.4 to 18.2.7
Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 18.2.4 to 18.2.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-17 01:18:24 +00:00
dependabot[bot]
767bd39806 Bump @types/node from 20.4.1 to 20.4.2
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.1 to 20.4.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-17 01:18:13 +00:00
Janis
a5432884f0 Merge pull request #32 from DerTyp7/dependabot/npm_and_yarn/vite-4.4.2
Bump vite from 4.3.9 to 4.4.2
2023-07-11 12:36:11 +02:00
dependabot[bot]
4c8f748472 Bump vite from 4.3.9 to 4.4.2
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.3.9 to 4.4.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 10:36:01 +00:00
Janis
7ba46e4518 Merge pull request #33 from DerTyp7/dependabot/npm_and_yarn/typescript-5.1.6
Bump typescript from 5.1.3 to 5.1.6
2023-07-11 12:35:15 +02:00
dependabot[bot]
fb17fe7657 Bump typescript from 5.1.3 to 5.1.6
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.1.3 to 5.1.6.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.1.3...v5.1.6)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 10:34:41 +00:00
Janis
a09212cc21 Merge pull request #34 from DerTyp7/dependabot/npm_and_yarn/eslint-8.44.0
Bump eslint from 8.42.0 to 8.44.0
2023-07-11 12:34:05 +02:00
Janis
6a1c32e6e8 Merge pull request #37 from DerTyp7/dependabot/npm_and_yarn/semver-6.3.1
Bump semver from 6.3.0 to 6.3.1
2023-07-11 12:33:01 +02:00
DerTyp7
2152aa64cb add common issues to readme 2023-07-11 12:32:04 +02:00
dependabot[bot]
1ca70bbabd Bump eslint from 8.42.0 to 8.44.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.42.0 to 8.44.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.42.0...v8.44.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 10:19:10 +00:00
Janis
5033753397 Merge pull request #35 from DerTyp7/dependabot/npm_and_yarn/eslint-plugin-react-refresh-0.4.3
Bump eslint-plugin-react-refresh from 0.4.1 to 0.4.3
2023-07-11 12:18:24 +02:00
DerTyp7
bd2611875a Merge branch 'main' into dependabot/npm_and_yarn/eslint-plugin-react-refresh-0.4.3 2023-07-11 11:37:04 +02:00
dependabot[bot]
d7f6aead15 Bump semver from 6.3.0 to 6.3.1
Bumps [semver](https://github.com/npm/node-semver) from 6.3.0 to 6.3.1.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v6.3.1/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v6.3.0...v6.3.1)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 09:36:40 +00:00
Janis
33fd746f01 Merge pull request #36 from DerTyp7/dependabot/npm_and_yarn/types/node-20.4.1
Bump @types/node from 20.3.2 to 20.4.1
2023-07-11 11:36:12 +02:00
DerTyp7
176cd6b05f change version 2023-07-11 11:34:16 +02:00
dependabot[bot]
f8aee2ab49 Bump @types/node from 20.3.2 to 20.4.1
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.3.2 to 20.4.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 01:28:06 +00:00
dependabot[bot]
900c6c9380 Bump eslint-plugin-react-refresh from 0.4.1 to 0.4.3
Bumps [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) from 0.4.1 to 0.4.3.
- [Release notes](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/releases)
- [Changelog](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/compare/v0.4.1...v0.4.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-react-refresh
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 01:27:56 +00:00
Janis
a64bf30fd3 update readme 2023-07-08 14:20:03 +02:00
Janis
43dc2f1160 update build options 2023-07-08 14:17:36 +02:00
Janis
810da5173a Merge pull request #31 from DerTyp7/dependabot/npm_and_yarn/eslint-plugin-react-refresh-0.4.1
Bump eslint-plugin-react-refresh from 0.3.5 to 0.4.1
2023-07-08 13:58:12 +02:00
Janis
541514df9a Merge pull request #28 from DerTyp7/dependabot/npm_and_yarn/sass-1.63.6
Bump sass from 1.62.1 to 1.63.6
2023-07-08 13:57:59 +02:00
dependabot[bot]
a3335cb44d Bump sass from 1.62.1 to 1.63.6
Bumps [sass](https://github.com/sass/dart-sass) from 1.62.1 to 1.63.6.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.62.1...1.63.6)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 11:56:56 +00:00
Janis
9cdba50155 Merge pull request #30 from DerTyp7/dependabot/npm_and_yarn/jest-29.6.1
Bump jest from 29.5.0 to 29.6.1
2023-07-08 13:56:34 +02:00
dependabot[bot]
ad94353c64 Bump jest from 29.5.0 to 29.6.1
Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 29.5.0 to 29.6.1.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v29.6.1/packages/jest)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 11:56:23 +00:00
Janis
e18420540f Merge pull request #29 from DerTyp7/dependabot/npm_and_yarn/react-router-dom-6.14.1
Bump react-router-dom from 6.14.0 to 6.14.1
2023-07-08 13:56:17 +02:00
Janis
87d8f628c2 Merge pull request #27 from DerTyp7:dependabot/npm_and_yarn/types/react-18.2.14
Bump @types/react from 18.2.8 to 18.2.14
2023-07-08 13:55:31 +02:00
dependabot[bot]
c962aae1a7 Bump eslint-plugin-react-refresh from 0.3.5 to 0.4.1
Bumps [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) from 0.3.5 to 0.4.1.
- [Release notes](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/releases)
- [Changelog](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/compare/v0.3.5...v0.4.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-react-refresh
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 11:52:10 +00:00
dependabot[bot]
9ec6d0bc1b Bump react-router-dom from 6.14.0 to 6.14.1
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.14.0 to 6.14.1.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.14.1/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 11:51:43 +00:00
dependabot[bot]
db1b7153f9 Bump @types/react from 18.2.8 to 18.2.14
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.8 to 18.2.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-08 11:51:20 +00:00
Janis
7da123fb42 Update dependabot.yml package-ecosystem 2023-07-08 13:50:53 +02:00
Janis
e49791cb1e Create dependabot.yml 2023-07-08 13:47:54 +02:00
Janis
e4d6d59d5c Update README.md 2023-07-01 21:33:37 +02:00
Janis
df0e38242c Update bug_report.md 2023-07-01 21:14:56 +02:00
Janis
3864207b6a Update issue templates 2023-07-01 21:14:14 +02:00
Janis
6524b85142 Update README.md 2023-07-01 13:31:13 +02:00
Janis
4677e98bf3 Merge pull request #25 from DerTyp876/19-show-if-a-client-is-hardware-muted
[feature] add hardware muted inputs
2023-06-30 13:59:12 +02:00
Janis Meister
5f81bbf46a [feature] add hardware muted inputs 2023-06-30 13:58:08 +02:00
Janis
3733f7ef79 Merge pull request #24 from DerTyp876/5-show-channel-name
5 show channel name
2023-06-30 13:27:22 +02:00
Janis Meister
14db96d10a [refactor] update readme paramter table 2023-06-30 13:26:58 +02:00
Janis Meister
0d3317802c [refactor] update channel name style 2023-06-30 13:25:44 +02:00
Janis Meister
113fcb28de [feature] get boolean from parameter 2023-06-30 13:22:07 +02:00
Janis
9758520239 Merge pull request #23 from DerTyp876/6-set-a-show-clients-limit
6 set a show clients limit
2023-06-30 13:20:20 +02:00
Janis Meister
d6e0517ddb [refactor] update readme paramter table 2023-06-30 13:19:55 +02:00
Janis Meister
f919b39548 [feature] add client limit 2023-06-30 13:18:37 +02:00
Janis
4ec685bd75 Merge pull request #22 from DerTyp876/16-hide-non-talking-clients
16 hide non talking clients
2023-06-30 13:06:11 +02:00
Janis Meister
7c3b67de4d [feature] update readme parameter table 2023-06-30 13:05:35 +02:00
Janis Meister
c1c9db8f95 [feature] add hideNonTalking boolean 2023-06-30 13:05:24 +02:00
Janis
ba5930cadc [feature] add log tag to logger.log 2023-06-29 21:49:33 +02:00
Janis
afe2376ea0 Merge pull request #21 from DerTyp876/feature_better-logger
Better logger
2023-06-29 21:26:11 +02:00
Janis
f0290bb44d [feature] integrated Logger 2023-06-29 21:17:31 +02:00
Janis
e411c1c126 [feature] integrated Logger 2023-06-29 21:17:30 +02:00
Janis
033cd77e04 [feature] update logger parameters 2023-06-29 21:07:02 +02:00
Janis
619e66375f [feature] created Logger 2023-06-29 18:09:03 +02:00
Janis
c6289ddc0f Merge pull request #20 from DerTyp876/refactor_clean-up
Clean up project
2023-06-29 12:54:11 +02:00
Janis Meister
eb0e005882 [fix] alias imports 2023-06-29 12:53:17 +02:00
Janis Meister
e5f4e7b4fa [fix] aliases 2023-06-29 12:51:58 +02:00
Janis
98deb4db19 [feature] add interfaces for classes 2023-06-29 01:10:08 +02:00
Janis
3d99e206c1 [feature] add interfaces for classes 2023-06-29 01:07:30 +02:00
Janis
70b2506118 [refactor] remove unused interface 2023-06-29 01:03:40 +02:00
Janis
d1dca713aa [refactor] split up handler classes 2023-06-29 00:56:33 +02:00
Janis
9382572bd7 [refactor] split up handler classes 2023-06-29 00:56:30 +02:00
Janis
f296bba7d6 [fix] fixed a bug when connected twice to the same server 2023-06-28 23:32:18 +02:00
Janis
268252bf56 Update README.md 2023-06-28 19:19:16 +02:00
Janis
b7beddb32e [fix] bug while reconnecting server 2023-06-28 19:16:03 +02:00
Janis
92906d25c3 [feature] add key to div 2023-06-28 18:57:32 +02:00
Janis
1bd6e3400b [refactor] add setTimeout before reconnect 2023-06-28 18:48:19 +02:00
Janis
7d2409f6f4 Update README.md 2023-06-28 18:46:17 +02:00
Janis
b702b82cce [refactor] update readme 2023-06-28 18:43:49 +02:00
Janis
00b8db20c3 [feature] add remoteAppPort as query param 2023-06-28 18:33:57 +02:00
Janis
16573394b1 Update README.md 2023-06-28 18:23:09 +02:00
Janis
08fa223207 [feature] add content table 2023-06-28 18:01:52 +02:00
Janis
e2423a54cf [feature] add README.md 2023-06-28 18:01:24 +02:00
22 changed files with 1974 additions and 1336 deletions

View File

@@ -1,14 +1,11 @@
module.exports = {
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
plugins: ['react-refresh'],
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react-hooks/recommended"],
parser: "@typescript-eslint/parser",
parserOptions: { ecmaVersion: "latest", sourceType: "module" },
plugins: ["react-refresh"],
rules: {
'react-refresh/only-export-components': 'warn',
"react-refresh/only-export-components": "warn",
"react-hooks/exhaustive-deps": "ignore",
},
}
};

27
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,27 @@
---
name: Bug report
about: Something isn't working for you
title: ''
labels: bug
assignees: ''
---
> Screenshots are welcome
## Describe the bug
A clear and concise description of what the bug is.
## To Reproduce
Example or explanation to reproduce the issue.
## Expected behavior
A clear and concise description of what you expected to happen.
**Do you use the local or online version?**
- [x] Online version with URL: `https://dertyp7.github.io/ts5-obs-overlay`
- [ ] The version named below locally downloaded on my device
**Your environment:**
- OS: [e.g. Windows 11]
- OBS version: [e.g. 29.1.3]
- Overlay version [e.g. v1.1.0]

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"
target-branch: "dev"

31
.github/workflows/deploy.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Deploy to GitHub Pages on Release
on:
release:
types:
- created
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3.9.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist

View File

@@ -1,5 +1,7 @@
{
"tabWidth": 2,
"useTabs": false,
"printWidth": 120
"printWidth": 180,
"singleQuote": false,
"semi": true
}

82
README.md Normal file
View File

@@ -0,0 +1,82 @@
# TeamSpeak5-OBS-Overlay
This is an overlay for OBS to show the current talking clients in your TeamSpeak5 Channel.
This App uses the new "Remote Apps" feature of TeamSpeak5.
This overlay uses the [TeamSpeak5 Remote App API](https://github.com/DerTyp7/react-ts5-remote-app-api).
![image](https://github.com/DerTyp7/ts5-obs-overlay/assets/76851529/d0ab06f2-1a36-479d-826f-bd4bd3d405b7)
- [TeamSpeak5-OBS-Overlay](#teamspeak5-obs-overlay)
- [Usage](#usage)
- [Quick instructions](#quick-instructions)
- [Detailed instructions](#detailed-instructions)
- [Common Issues](#common-issues)
- [The overlay is empty, but i'm connected to a TeamSpeak5 server](#the-overlay-is-empty-but-im-connected-to-a-teamspeak5-server)
- [OBS doesn't show the latest version of the overlay](#obs-doesnt-show-the-latest-version-of-the-overlay)
- [Setup (Developer)](#setup-developer)
## Usage
### Quick instructions
1. Open this link in your Browser: [https://dertyp7.github.io/ts5-obs-overlay/generate](https://dertyp7.github.io/ts5-obs-overlay/generate)
2. Follow the instructions on the website
3. Accept overlay inside TeamSpeak5
![image](https://github.com/DerTyp7/ts5-obs-overlay/assets/76851529/40faa435-e128-415f-98eb-a9e8809e8f65)
### Detailed instructions
Try this instruction if you have problems with the quick instructions above.
1. Open this link in your Browser: [https://dertyp7.github.io/ts5-obs-overlay/generate](https://dertyp7.github.io/ts5-obs-overlay/generate)
2. Follow the instructions on the website
3. Go into the TeamSpeak5 Settings and enable "Remote Apps"
![image](https://github.com/DerTyp7/ts5-obs-overlay/assets/76851529/b31bc553-fde2-46ab-b07c-d3c81339cc7d)
4. Add a new Browser Source to your OBS Scene
![image](https://github.com/DerTyp7/ts5-obs-overlay/assets/76851529/0198b468-bb96-4b65-bdd4-3d6bb3ef7d25)
![image](https://github.com/DerTyp7/ts5-obs-overlay/assets/76851529/58ad399f-5344-456f-b243-6e267b489fd5)
5. Enter the in step 1 generated URL into the URL field of the Browser Source
![image](https://github.com/DerTyp7/ts5-obs-overlay/assets/76851529/50b755f9-d4b4-469f-9136-e2b18f226547)
6. Set the width and height to your desired size. Recommended is a ratio of 1:1 or 1:2 (e.g. 1500x3000 OR 1000x2000)
7. You should now receive a notification in TeamSpeak5 that the app is allowed to connect to your TeamSpeak5 client. Allow it. (If you don't get a notification, restart TeamSpeak5 and OBS -> try again)
![image](https://github.com/DerTyp7/ts5-obs-overlay/assets/76851529/40faa435-e128-415f-98eb-a9e8809e8f65)
## Common Issues
### The overlay is empty, but i'm connected to a TeamSpeak5 server
**Fix 1**
Make sure you accepted the notification in your TeamSpeak Client.
**Fix 2**
Sadly TeamSpeak5 does not give us any information about the current active server tab.
So we try currently use a workaround, where the active server tab is determined by looking on which server the your hardware input was unmuted the latest, since the non-active server tabs in TS5 usually mute the clients microphone.
However this workaround is not 100% accurate and can fail in some cases.
Possible fixes:
- Unmute and mute yourself in the active server tab (Just a normal unmute and mute, not the hardware mute)
- Reconnect to the TS5 server while the overlay is open
### OBS doesn't show the latest version of the overlay
This can happen if the OBS Browser Source is caching the overlay.
To fix this, open the Browser Source settings and click on "Refresh cache of current page".
## Setup (Developer)
1. Clone this repository
2. Run `npm install`
3. To start the development server run `npm run dev`
> **Note:** Pull requests are welcome, but please be consistent with the code style.
> This project uses [Prettier](https://prettier.io/) to format the code.
> Pull requests always in the `dev` branch.

View File

@@ -1,12 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TS5-OBS-Overlay</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="An OBS overlay for TeamSpeak5, so your audience can see who is talking. https://github.com/DerTyp7/ts5-obs-overlay"
/>
<meta name="author" content="DerTyp7" />
<title>TS5-OBS-Overlay</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

1471
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,27 @@
{
"name": "ts5-obs-overlay",
"private": true,
"version": "0.0.0",
"private": false,
"version": "2.0.1",
"description": "Overlay for OBS to show the current talking clients in your TeamSpeak 5 Channel",
"author": "DerTyp7",
"homepage": "https://dertyp7.github.io/ts5-obs-overlay/#",
"repository": {
"type": "git",
"url": "https://github.com/DerTyp7/ts5-obs-overlay"
},
"keywords": [
"ts5",
"teamspeak",
"overlay",
"remote app",
"obs",
"typescript",
"react",
"vite"
],
"bugs": {
"url": "https://github.com/DerTyp7/ts5-obs-overlay/issues"
},
"type": "module",
"scripts": {
"dev": "vite",
@@ -10,21 +30,24 @@
"preview": "vite preview"
},
"dependencies": {
"@types/node": "^20.8.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass": "^1.62.1"
"react-router-dom": "^6.18.0",
"react-ts5-remote-app-api": "^1.1.1",
"sass": "^1.68.0"
},
"devDependencies": {
"@types/react": "^18.0.37",
"@types/react-dom": "^18.0.11",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"@types/jest": "^29.5.2",
"@types/react": "^18.2.35",
"@types/react-dom": "^18.2.14",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.9.1",
"@vitejs/plugin-react-swc": "^3.0.0",
"eslint": "^8.38.0",
"eslint": "^8.53.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
"typescript": "^5.0.2",
"vite": "^4.3.9",
"vite-plugin-singlefile": "^0.13.5"
"eslint-plugin-react-refresh": "^0.4.3",
"typescript": "^5.2.2",
"vite": "^4.5.0"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

@@ -1,64 +1,27 @@
/* eslint-disable react-hooks/exhaustive-deps */
import "@styles/App.scss";
import { TS5Connection } from "./teamspeak5Handler";
import { IChannel, IClient, IConnection } from "interfaces/teamspeak";
import { useEffect, useState } from "react";
import { Navigate, Route, Routes, useSearchParams } from "react-router-dom";
import Viewer from "./Viewer";
import Generator from "./Generator";
export default function App() {
const [clients, setClients] = useState<IClient[]>([]);
const [channels, setChannels] = useState<IChannel[]>([]);
const [connections, setConnections] = useState<IConnection[]>([]);
const [activeConnectionId, setActiveConnectionId] = useState<number>(1);
const [currentConnection, setCurrentConnection] = useState<IConnection | undefined>(undefined);
const [currentChannel, setCurrentChannel] = useState<IChannel | undefined>(undefined);
const [currentClient, setCurrentClient] = useState<IClient | undefined>(undefined);
function setCurrentStates() {
const currentConnection = connections.find((connection) => connection.id === activeConnectionId);
setCurrentConnection(currentConnection);
if (currentConnection) {
const currentClient = clients.find((client) => client.id === currentConnection.clientId);
setCurrentClient(currentClient);
if (currentClient) {
const currentChannel = channels.find((channel) => channel.id === currentClient.channel?.id);
setCurrentChannel(currentChannel);
if (currentChannel) {
return currentChannel;
}
}
}
}
useEffect(() => {
const tsConnection: TS5Connection = new TS5Connection(
5899,
setConnections,
setChannels,
setClients,
setActiveConnectionId
);
tsConnection.connect();
}, []);
useEffect(() => {
setCurrentStates();
}, [clients, channels, connections, activeConnectionId]);
const [searchParams] = useSearchParams();
return (
<div className="App">
<Viewer
clients={
clients.map((client) => {
if (client.channel?.id === currentChannel?.id) {
return client;
}
}) as IClient[]
<Routes>
<Route
path="/"
element={
<Viewer
remoteAppPort={parseInt(searchParams.get("remoteAppPort") ?? "5899")}
showChannelName={searchParams.get("showChannelName") === "true"}
hideNonTalking={searchParams.get("hideNonTalking") === "true"}
clientLimit={searchParams.get("clientLimit") ? parseInt(searchParams.get("clientLimit") ?? "0") : 0}
/>
}
channel={currentChannel}
/>
</div>
<Route path="/generate" element={<Generator />} />
<Route path="*" element={<Navigate to="/generate" replace />} />
</Routes>
);
}

122
src/Generator.tsx Normal file
View File

@@ -0,0 +1,122 @@
import React, { ChangeEvent, useRef, useState, useEffect } from "react";
import "@styles/Generator.scss";
import Viewer from "./Viewer";
export default function Generator() {
// State variables
const [outputUrl, setOutputUrl] = useState(() => new URL(window.location.href).toString());
const copiedTooltipRef = useRef<HTMLDivElement>(null);
const [remoteAppPort, setRemoteAppPort] = useState(5899);
const [showChannelName, setShowChannelName] = useState(true);
const [hideNonTalking, setHideNonTalking] = useState(false);
const [clientLimit, setClientLimit] = useState(0);
// Effect to generate URL when dependencies change
useEffect(() => {
generateUrl();
}, [remoteAppPort, showChannelName, hideNonTalking, clientLimit]);
// Function to generate the output URL
function generateUrl() {
const url = new URL(window.location.href.replace("/#/generate", ""));
url.searchParams.set("remoteAppPort", remoteAppPort.toString());
url.searchParams.set("showChannelName", showChannelName.toString());
url.searchParams.set("hideNonTalking", hideNonTalking.toString());
url.searchParams.set("clientLimit", clientLimit.toString());
setOutputUrl(url.toString());
}
// Function to copy URL to clipboard
function copy() {
navigator.clipboard.writeText(outputUrl);
if (copiedTooltipRef.current) {
copiedTooltipRef.current.style.animation = "tooltipAnimation 200ms";
copiedTooltipRef.current.style.opacity = "1";
setTimeout(() => {
if (copiedTooltipRef.current) {
copiedTooltipRef.current.style.opacity = "0";
copiedTooltipRef.current.style.animation = "";
}
}, 1000);
}
}
return (
<div className="generator">
{/* Header */}
<div className="headline">
<h1>TS5-OBS-Overlay Generator</h1>
<h4>by DerTyp7</h4>
</div>
{/* Instructions */}
<div className="instructions">
<p>1. Customize your settings</p>
<p>2. Copy the generated URL</p>
<p>3. Paste the URL into the BrowserSource URL field in OBS</p>
<a href="#">Click here for detailed instructions</a>
</div>
{/* Output Section */}
<div className="output">
<p className="url">
<code>{outputUrl}</code>
</p>
<button onClick={copy} className="copy">
Copy
</button>
<div ref={copiedTooltipRef} className="copiedTooltip">
Copied!
</div>
</div>
{/* Generator Content */}
<div className="generatorContent">
{/* Configurations */}
<div className="configurations">
<h2>Configurations</h2>
<div className="options">
{/* Option Sections */}
<section>
{/* Show Channel Name Option */}
<div className="option" onClick={() => setShowChannelName(!showChannelName)}>
<input type="checkbox" checked={showChannelName} />
<label>Show channel name</label>
</div>
{/* Hide Non-Talking Clients Option */}
<div className="option" onClick={() => setHideNonTalking(!hideNonTalking)}>
<input type="checkbox" checked={hideNonTalking} />
<label>Hide non talking clients</label>
</div>
</section>
<section>
{/* Client Limit Option */}
<div className="option">
<input type="number" value={clientLimit} min={0} onChange={(e: ChangeEvent<HTMLInputElement>) => setClientLimit(parseInt(e.target.value))} />
<label>Client Limit</label>
</div>
{/* RemoteApp-Port Option */}
<div className="option">
<input type="number" value={remoteAppPort} min={0} onChange={(e: ChangeEvent<HTMLInputElement>) => setRemoteAppPort(parseInt(e.target.value))} />
<label>RemoteApp-Port</label>
</div>
</section>
</div>
</div>
{/* Preview */}
<div className="preview">
<Viewer remoteAppPort={remoteAppPort} showChannelName={showChannelName} hideNonTalking={hideNonTalking} clientLimit={clientLimit} />
</div>
</div>
</div>
);
}

View File

@@ -1,23 +1,94 @@
import { IChannel, IClient } from "interfaces/teamspeak";
import "@styles/Viewer.scss";
import useTSRemoteApp, { IClient } from "react-ts5-remote-app-api";
export default function Viewer({
clients,
channel,
remoteAppPort = 5899,
showChannelName = false,
hideNonTalking = false,
clientLimit = 0,
}: {
clients: IClient[] | undefined;
channel: IChannel | undefined;
remoteAppPort?: number;
showChannelName?: boolean;
hideNonTalking?: boolean;
clientLimit?: number;
}) {
const { clients, activeConnectionId, currentChannel } = useTSRemoteApp({
remoteAppPort: remoteAppPort,
auth: {
identifier: "de.tealfire.obs",
version: "2.0.1",
name: "TS5 OBS Overlay",
description: "A OBS overlay for TS5 by DerTyp7",
},
logging: true,
});
const currentClients = clients.map((client) => {
if (client.channel?.id === currentChannel?.id && client.channel.connection.id === activeConnectionId) {
return client;
}
}) as IClient[];
return (
<div className="viewer">
{showChannelName ? <h3>{channel?.properties.name}</h3> : null}
{clients?.map((client) => {
{showChannelName ? (
<div className="channelNameContainer">
<h1>{currentChannel?.properties.name}</h1>
</div>
) : null}
{currentClients?.map((client, i) => {
//* Client limit
if (clientLimit != 0 && i >= clientLimit) {
return null;
}
if (client) {
//* Non-talking client
if (hideNonTalking && (client.properties.inputMuted || client.properties.outputMuted || client.talkStatus == 0)) {
return null;
}
//* Normal client
return (
<div className="client" key={`${client.id}-${client.channel?.connection.id}`}>
{client.properties.outputMuted ? (
{client.properties.outputHardware == false ? (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<title>muted_hardware_output</title>
<g id="muted_hardware_output.svg">
<path
d="M116.62,39a4.78,4.78,0,0,1-1.59.3l-6.29,3.63a45.42,45.42,0,0,1-13.33,57.64,49.4,49.4,0,0,1-5.82,3.62c-1.06.57-2.2.92-3.19,1.49-1.7,1-2.77,2.13-2.77,4.18a4.57,4.57,0,0,0,4.54,4.54,5.33,5.33,0,0,0,1.84-.35,54.49,54.49,0,0,0,26.94-75c-.12,0-.22,0-.34,0M88.18,13.58a4.57,4.57,0,0,0-4.54,4.54c0,2.06,1.06,3.19,2.77,4.18,1,.57,2.13.92,3.19,1.49a49.4,49.4,0,0,1,5.82,3.62,45.68,45.68,0,0,1,8.19,7.78l7-4a2.63,2.63,0,0,1,1.11-.34A54.31,54.31,0,0,0,90,13.94a5.33,5.33,0,0,0-1.84-.35"
fill="#d8d8d8"
/>
<path
d="M59.46,71.4,32.77,86.81l19,19a4.51,4.51,0,0,0,3.19,1.35,4.57,4.57,0,0,0,4.54-4.54V71.4M54.92,20.88a4.51,4.51,0,0,0-3.19,1.35L28.12,45.85H9.54A4.57,4.57,0,0,0,5,50.38V77.62a4.57,4.57,0,0,0,4.54,4.54H22.26l37.2-21.48V25.42a4.57,4.57,0,0,0-4.54-4.54"
fill="#d8d8d8"
/>
<path
d="M85.11,56.6l-7.87,4.54A10,10,0,0,1,77.62,64c0,8.58-8.23,7.09-8.23,12.48A4.53,4.53,0,0,0,73.93,81a4,4,0,0,0,1.77-.35A18.13,18.13,0,0,0,86.69,64a18.34,18.34,0,0,0-1.59-7.4M73.93,47a4.52,4.52,0,0,0-4.54,4.54,3.92,3.92,0,0,0,1.08,2.8l8.76-5.06a16.14,16.14,0,0,0-3.52-1.93A4,4,0,0,0,73.93,47"
fill="#d8d8d8"
/>
<path
d="M100.87,47.49,93,52a27.15,27.15,0,0,1-8.36,33.87A36.79,36.79,0,0,1,79.25,89a4.54,4.54,0,0,0,1.84,8.72,5.24,5.24,0,0,0,1.77-.35,36.34,36.34,0,0,0,18-49.91M81,30.25A4.54,4.54,0,0,0,79.25,39a36.82,36.82,0,0,1,5.39,3.12,27,27,0,0,1,2.86,2.4l8.14-4.7A35.37,35.37,0,0,0,82.86,30.6,5.31,5.31,0,0,0,81,30.25"
fill="#d8d8d8"
/>
<path
d="M126.57,43.71,10.42,110.77a2.88,2.88,0,0,1-3.93-1.05L4.33,106A2.88,2.88,0,0,1,5.38,102L121.53,35A2.88,2.88,0,0,1,125.46,36l2.16,3.75A2.88,2.88,0,0,1,126.57,43.71Z"
fill="#c9070a"
/>
</g>
</svg>
) : client.properties.inputHardware == false ? (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<title>muted_hardware_input</title>
<g id="muted_hardware_input.svg">
<path
d="M88.62,54.15V64A24.69,24.69,0,0,1,64,88.62a25.26,25.26,0,0,1-8.38-1.46l-7.39,7.39A34,34,0,0,0,64,98.46,34.5,34.5,0,0,0,98.46,64V54.15a4.92,4.92,0,1,1,9.85,0V64a44.31,44.31,0,0,1-39.38,44v10.15H88.62a4.92,4.92,0,0,1,0,9.85H39.38a4.92,4.92,0,1,1,0-9.85H59.08V108A43.3,43.3,0,0,1,41,101.77L21.46,121.31a2.46,2.46,0,0,1-3.54,0L11.62,115a2.46,2.46,0,0,1,0-3.54l94.92-94.92a2.46,2.46,0,0,1,3.54,0l6.31,6.31a2.46,2.46,0,0,1,0,3.54ZM22.92,80.46A43.3,43.3,0,0,1,19.69,64V54.15a4.92,4.92,0,1,1,9.85,0V64a35.94,35.94,0,0,0,1.15,8.69ZM39.38,64V24.62a24.62,24.62,0,0,1,47.77-8.38Z"
fill="#d8d8d8"
/>
<rect x="-5.93" y="61.89" width="139.87" height="14.02" rx="2.87" ry="2.87" transform="translate(-29.97 65.43) rotate(-45)" fill="#c9070a" />
</g>
</svg>
) : client.properties.outputMuted ? (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<title>muted_output</title>
<g id="muted_output">
@@ -72,7 +143,7 @@ export default function Viewer({
</div>
);
} else {
return <></>;
return <div key={Math.random()}></div>;
}
})}
</div>

View File

@@ -1,299 +0,0 @@
export interface TS5MessageHandlerOptions {
handleAuthMessage?: (data: IAuthMessage) => void;
handleClientMoved?: (data: IClientMovedMessage) => void;
handleClientPropertiesUpdate?: (data: IClientPropertiesUpdatedMessage) => void;
handleTalkStatusChanged?: (data: ITalkStatusChangedMessage) => void;
handleClientSelfPropertyUpdated?: (data: IClientSelfPropertyUpdatedMessage) => void;
}
export interface IAuthSenderPayload {
type: "auth";
payload: {
identifier: string;
version: string;
name: string;
description: string;
content: {
apiKey: string;
};
};
}
export interface IClient {
id: number;
talkStatus: number;
channel: IChannel;
properties: IClientProperties;
}
export interface IChannel {
id: number;
connection: IConnection;
order: string;
parentId: string;
properties: IChannelProperties;
}
export interface IConnection {
channelInfos?: IChannelInfos;
clientId: number;
clientInfos?: IClientInfo[];
id: number;
properties?: IServerProperties;
}
export interface IChannelProperties {
bannerGfxUrl: string;
bannerMode: number;
codec: number;
codecIsUnencrypted: boolean;
codecLatencyFactor: number;
codecQuality: number;
deleteDelay: number;
description: string;
flagAreSubscribed: boolean;
flagDefault: boolean;
flagMaxclientsUnlimited: boolean;
flagMaxfamilyclientsInherited: boolean;
flagMaxfamilyclientsUnlimited: boolean;
flagPassword: boolean;
flagPermanent: boolean;
flagSemiPermanent: boolean;
forcedSilence: boolean;
iconId: number;
maxclients: number;
maxfamilyclients: number;
name: string;
namePhonetic: string;
neededTalkPower: number;
order: string;
permissionHints: number;
storageQuota: number;
topic: string;
uniqueIdentifier: string;
}
export interface IChannelInfos {
rootChannels: IChannel[];
subChannels: { [key: number]: IChannel[] };
}
export interface IClientInfo {
channelId: number;
id: number;
properties: IClientProperties;
}
export interface IClientProperties {
away: boolean;
awayMessage: string;
badges: string;
channelGroupId: string;
channelGroupInheritedChannelId: string;
country: string;
created: number;
databaseId: string;
defaultChannel: string;
defaultChannelPassword: string;
defaultToken: string;
description: string;
flagAvatar: string;
flagTalking: boolean;
iconId: number;
idleTime: number;
inputDeactivated: boolean;
inputHardware: boolean;
inputMuted: boolean;
integrations: string;
isChannelCommander: boolean;
isMuted: boolean;
isPrioritySpeaker: boolean;
isRecording: boolean;
isTalker: boolean;
lastConnected: number;
metaData: string;
monthBytesDownloaded: number;
monthBytesUploaded: number;
myteamspeakAvatar: string;
myteamspeakId: string;
neededServerQueryViewPower: number;
nickname: string;
nicknamePhonetic: string;
outputHardware: boolean;
outputMuted: boolean;
outputOnlyMuted: boolean;
permissionHints: number;
platform: string;
serverGroups: string;
serverPassword: string;
signedBadges: string;
talkPower: number;
talkRequest: number;
talkRequestMsg: string;
totalBytesDownloaded: number;
totalBytesUploaded: number;
totalConnections: number;
type: number;
uniqueIdentifier: string;
unreadMessages: number;
userTag: string;
version: string;
volumeModificator: number;
}
export interface IServerProperties {
antiFloodPointsNeededCommandBlock: number;
antiFloodPointsNeededIpBlock: number;
antiFloodPointsNeededPluginBlock: number;
antiFloodPointsTickReduce: number;
askForPrivilegeKeyAfterNickname: boolean;
askForPrivilegeKeyForChannelCreation: boolean;
askForPrivilegeKeyForModify: boolean;
awayMessage: string;
badges: string;
channelGroupId: string;
channelGroupInheritedChannelId: string;
clientType: number;
connectionBandwidthReceived: number;
connectionBandwidthSent: number;
connectionClientIp: string;
connectionConnectedTime: number;
connectionFiletransferBandwidthReceived: number;
connectionFiletransferBandwidthSent: number;
connectionPacketloss: number;
connectionPing: number;
connectionPacketsReceived: number;
connectionPacketsSent: number;
connectionPort: number;
connectionQueryBandwidthReceived: number;
connectionQueryBandwidthSent: number;
connectionServerIp: string;
connectionServerPort: number;
connectionThrottleBandwidthReceived: number;
connectionThrottleBandwidthSent: number;
country: string;
created: number;
defaultChannel: string;
defaultChannelPassword: string;
defaultServerGroup: string;
defaultToken: string;
flagAvatar: string;
iconId: number;
inputHardware: boolean;
inputMuted: boolean;
isChannelCommander: boolean;
isMuted: boolean;
isPrioritySpeaker: boolean;
isRecording: boolean;
isTalker: boolean;
isTts: boolean;
metaData: string;
monthBytesDownloaded: number;
monthBytesUploaded: number;
myteamspeakAvatar: string;
myteamspeakId: string;
neededServerQueryViewPower: number;
nickname: string;
nicknamePhonetic: string;
outputHardware: boolean;
outputMuted: boolean;
outputOnlyMuted: boolean;
permissionHints: number;
platform: string;
serverPassword: string;
signedBadges: string;
talkPower: number;
talkRequest: number;
talkRequestMsg: string;
totalBytesDownloaded: number;
totalBytesUploaded: number;
totalConnections: number;
type: number;
uniqueIdentifier: string;
unreadMessages: number;
userTag: string;
version: string;
volumeModificator: number;
}
export interface IClientPropertiesUpdatedMessage {
type: "clientPropertiesUpdated";
payload: {
clientId: number;
connectionId: number;
properties: IClientProperties;
};
}
export interface IClientMovedMessage {
type: "clientMoved";
payload: {
properties: IClientProperties;
clientId: number;
connectionId: number;
newChannelId: number;
oldChannelId: number;
type: number;
visibility: number;
};
}
export interface ITalkStatusChangedMessage {
type: "talkStatusChanged";
payload: {
clientId: number;
connectionId: number;
isWhisper: boolean;
status: number;
};
}
export interface IClientSelfPropertyUpdatedMessage {
type: "clientSelfPropertyUpdated";
payload: {
connectionId: number;
flag: string;
newValue: boolean;
oldValue: boolean;
};
}
export interface IAuthMessage {
type: "auth";
payload: {
apiKey: string;
connections: IConnection[];
};
}
export interface IServerPropertiesUpdatedMessage {
type: "serverPropertiesUpdated";
payload: {
connectionId: number;
properties: IServerProperties;
};
}
export interface IConnectStatusChangedMessage {
type: "connectStatusChanged";
payload: {
connectionId: number;
error: number;
info: {
clientId: number;
}
status: number;
};
}
export interface IChannelsMessage {
type: "channels";
payload: {
connectionId: number;
info: IChannelInfos
}
}

View File

@@ -2,9 +2,10 @@ import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "@styles/index.scss";
import { BrowserRouter, HashRouter } from "react-router-dom";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
ReactDOM.createRoot(document.getElementById("root")!).render(
<HashRouter>
<App />
</HashRouter>
);

259
src/styles/Generator.scss Normal file
View File

@@ -0,0 +1,259 @@
// Breakpoints
$breakpoint-1: 1200px;
$breakpoint-2: 790px;
$breakpoint-3: 600px;
// Tooltip animation keyframes
@keyframes tooltipAnimation {
0% {
opacity: 0;
transform: translateY(-10px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.generator {
background-color: #232528;
color: #fff;
width: 100%;
display: flex;
height: 100%;
flex-direction: column;
align-items: center;
gap: 50px;
padding: 50px 0;
.headline {
text-align: center;
letter-spacing: 1.8px;
}
.instructions {
border-bottom: 2px solid #75797773;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 10px 50px;
flex-wrap: wrap;
padding-bottom: 10px;
p,
a {
font-size: 0.8rem;
}
p {
color: #b4b4b4;
}
}
.output {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
column-gap: 20px;
position: relative;
height: 50px;
.url {
white-space: nowrap;
overflow: auto;
font-weight: bold;
width: 500px;
padding: 5px 10px;
background-color: #313136;
border-radius: 5px;
text-align: center;
}
.copy {
padding: 5px 10px;
border: 2px solid #31f39973;
transition: all 100ms ease-in-out;
&:hover {
border-color: #42d486;
background-color: transparent;
color: #fff;
}
}
.copiedTooltip {
opacity: 0;
position: absolute;
right: -90px;
background-color: #31f399;
color: #202024;
padding: 5px 10px;
border-radius: 5px;
font-size: 0.8rem;
font-weight: bold;
}
}
.generatorContent {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 50px;
gap: 30px;
width: 100%;
.configurations {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
flex: 1;
gap: 50px;
.options {
display: flex;
flex-direction: row;
align-items: center;
gap: 100px;
user-select: none;
section {
display: flex;
flex-direction: column;
align-items: center;
justify-content: left;
gap: 10px;
}
.option {
display: flex;
flex-direction: row;
align-items: center;
justify-content: left;
column-gap: 10px;
width: 100%;
input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border: 2px solid #31f399;
border-radius: 5px;
background-color: #202024;
outline: none;
transition: all 200ms ease-in-out;
position: relative;
color: #fff;
text-align: center;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
// Cross when checked styles
&:checked {
&:after {
content: "";
position: absolute;
width: 10px;
height: 2px;
background-color: #31f399;
transform: rotate(45deg);
}
&:before {
content: "";
position: absolute;
width: 10px;
height: 2px;
background-color: #31f399;
transform: rotate(-45deg);
}
&:after,
&:before {
top: 7px;
left: 3px;
}
}
cursor: pointer;
}
input[type="number"] {
width: 50px;
height: 25px;
cursor: text;
-moz-appearance: textfield;
appearance: textfield;
}
label {
cursor: pointer;
}
}
}
}
// Preview styles
.preview {
flex: 1;
border: 2px solid #31f39973;
// Viewer styles (see src/styles/Viewer.scss)
.viewer {
background-image: url("/images/viewer_example_background.png");
background-repeat: no-repeat;
background-size: cover;
min-height: 500px;
}
}
}
// Responsive styles
@media screen and (max-width: $breakpoint-1) {
.generatorContent {
flex-direction: column;
.preview {
width: 80%;
}
}
}
@media screen and (max-width: $breakpoint-2) {
.output {
.url {
width: 300px;
}
}
.generatorContent {
.preview {
width: 100%;
}
}
}
@media screen and (max-width: $breakpoint-3) {
.output {
.url {
width: 200px;
}
.generatorContent {
.configurations {
.options {
flex-direction: column;
gap: 30px;
}
}
}
}
}
}

View File

@@ -1,13 +1,28 @@
//* Viewer styles
// this file contains styles for the viewer component
// styles for the viewer component should not be modified somewhere else
.viewer {
display: flex;
flex-direction: column;
gap: 0 0;
padding: 1rem;
padding: 0.5rem;
h3 {
font-size: 1.5rem;
font-weight: 500;
margin: 0;
h1,
p {
background-color: #2f313680;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 20ch;
user-select: none;
}
.channelNameContainer {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.client {
@@ -17,23 +32,16 @@
align-items: center;
margin: 0.5rem 0;
// icon styles
svg {
width: 2.8rem;
height: 2.8rem;
width: 2.1rem;
aspect-ratio: 1/1;
margin-right: 0.5rem;
}
p {
margin: 0;
color: white;
background-color: rgba(47, 49, 54, 0.5);
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
// ellipsis after 22 characters
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 20ch;
// client name styles
p {
font-size: 1.4rem;
}
}
}

View File

@@ -1,5 +1,101 @@
// Reset styles for all elements
* {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 3rem;
font-size: 1rem;
margin: 0;
padding: 0;
box-sizing: border-box;
}
// Set up basic styles for the entire page
body,
html {
min-height: 100vh;
min-width: 100%;
display: flex;
overflow-x: hidden;
color: #fff;
}
// Ensure the root element takes up the full viewport
#root {
height: 100%;
min-width: 100%;
}
// Headline styles
h1 {
font-size: 1.8rem;
}
h2 {
font-size: 1.5rem;
}
h3 {
font-size: 1.2rem;
}
h4 {
font-size: 1.1rem;
}
// Common styles for heading elements
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: bold;
}
// Text styles
a {
color: #3abe78;
font-weight: bold;
text-decoration: none;
transition: all 100ms ease-in-out;
&:hover {
color: #31f399;
}
}
// Button styles
button {
background-color: #202024;
color: #fff;
font-weight: bold;
border: 2px solid #31f399;
border-radius: 5px;
padding: 10px 20px;
cursor: pointer;
transition: all 300ms ease-in-out;
&:hover {
background-color: #42d486;
color: #202024;
}
}
// Custom dark-themed scrollbar
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
::-webkit-scrollbar-track {
background: #363638;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: #31f39973;
border-radius: 10px;
&:hover {
background: #48ee95;
}
}

View File

@@ -1,533 +0,0 @@
import { IAuthMessage, IAuthSenderPayload, IChannel, IChannelInfos, IChannelsMessage, IClient, IClientInfo, IClientMovedMessage, IClientPropertiesUpdatedMessage, IClientSelfPropertyUpdatedMessage, IConnectStatusChangedMessage, IConnection, IServerPropertiesUpdatedMessage, ITalkStatusChangedMessage } from "interfaces/teamspeak";
// Establish connection to TS5 client
// Main class
export class TS5Connection {
ws: WebSocket; // Websocket connection to TS5 client
authenticated = false; // Is the connection authenticated?
remoteAppPort: number; // Port of TS5 client
dataHandler: TS5DataHandler; // Handles data/lists and states
messageHandler: TS5MessageHandler; // Handles messages received from TS5 client
constructor(
// Port of TS5 client
remoteAppPort: number,
// State setters for dataHandler
setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>,
setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>,
setClients: React.Dispatch<React.SetStateAction<IClient[]>>,
setActiveConnectionId: React.Dispatch<React.SetStateAction<number>>,
) {
// Create websocket connection to TS5 client
this.remoteAppPort = remoteAppPort;
this.ws = new WebSocket(`ws://localhost:${this.remoteAppPort}`);
// Create dataHandler and messageHandler
this.dataHandler = new TS5DataHandler(setConnections, setChannels, setClients);
this.messageHandler = new TS5MessageHandler(this.ws, this.dataHandler, setActiveConnectionId);
}
reconnect() {
this.ws.close();
this.ws = new WebSocket(`ws://localhost:${this.remoteAppPort}`);
this.dataHandler.clearAll();
this.authenticated = false;
this.connect();
}
// Connect to TS5 client
connect() {
console.log('Connecting to TS5 client...');
console.log(localStorage.getItem("apiKey"))
// Create authentication payload
const initalPayload: IAuthSenderPayload = {
type: "auth",
payload: {
identifier: "de.tealfire.obs",
version: "1.0.0",
name: "TS5 OBS Overlay",
description: "A OBS overlay for TS5 by DerTyp876",
content: {
apiKey: localStorage.getItem("apiKey") ?? "",
},
},
};
this.ws.onopen = () => {
// Send authentication payload to TS5 client
console.log("Sending auth payload...")
this.ws.send(JSON.stringify(initalPayload));
};
this.ws.onclose = (event) => {
console.log("WebSocket connection closed", event);
// If the connection was closed before authentication, remove the API key from local storage
// OBS weirdly caches the localstorage and is very stubborn about clearing it (even when clicken "Clear Cache")
if (!this.authenticated) {
console.log("WebSocket connection closed before authentication");
localStorage.removeItem("apiKey");
}
this.reconnect();
};
// Handle messages received from TS5 client
// See TS5MessageHandler class
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data)
switch (data.type) {
case "auth":
this.messageHandler.handleAuthMessage(data);
this.authenticated = true;
break;
case "clientMoved":
this.messageHandler.handleClientMovedMessage(data);
break;
case "clientPropertiesUpdated":
this.messageHandler.handleClientPropertiesUpdatedMessage(data);
break;
case "talkStatusChanged":
this.messageHandler.handleTalkStatusChangedMessage(data);
break;
case "serverPropertiesUpdated":
this.messageHandler.handleServerPropertiesUpdatedMessage(data);
//this.ws.close();
break;
case "connectStatusChanged":
this.messageHandler.handleConnectStatusChangedMessage(data);
break;
case "clientSelfPropertyUpdated":
this.messageHandler.handleClientSelfPropertyUpdatedMessage(data);
break;
case "channels":
this.messageHandler.handleChannelsMessage(data);
break;
default:
console.log(`No handler for event type: ${data.type}`);
break;
}
};
}
}
class TS5DataHandler {
// Local lists of connections, channels and clients
// These lists are used to keep track of the data independent of the App.tsx state
localConnections: IConnection[];
localChannels: IChannel[];
localClients: IClient[];
// State setters for App.tsx
setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>;
setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>;
setClients: React.Dispatch<React.SetStateAction<IClient[]>>;
constructor(
// State setters for App.tsx
setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>,
setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>,
setClients: React.Dispatch<React.SetStateAction<IClient[]>>
) {
this.setConnections = setConnections;
this.setChannels = setChannels;
this.setClients = setClients;
this.localConnections = [];
this.localChannels = [];
this.localClients = [];
}
// Update App.tsx states
private updateConnectionsState() {
this.setConnections([...this.localConnections]);
}
private updateChannelsState() {
this.setChannels([...this.localChannels]);
}
private updateClientsState() {
this.setClients([...this.localClients]);
}
// Clear all data
clearAll() {
this.localConnections = [];
this.localChannels = [];
this.localClients = [];
this.updateConnectionsState();
this.updateChannelsState();
this.updateClientsState();
}
// Add data to local lists and update states
addConnection(connection: IConnection) {
console.log("Adding connection...", connection)
const existingConnection: IConnection | undefined = this.localConnections.find((localConnection: IConnection) => localConnection.id === connection.id);
if (existingConnection == undefined) {
this.localConnections.push(connection);
this.updateConnectionsState();
console.log("Connection added")
} else {
console.log("Connection already exists")
}
}
addChannel(channel: IChannel) {
console.log("Adding channel...", channel)
const existingChannel: IChannel | undefined = this.localChannels.find((localChannel: IChannel) => localChannel.id === channel.id && localChannel.connection.id === channel.connection.id);
if (existingChannel == undefined) {
this.localChannels.push(channel);
this.updateChannelsState();
console.log("Channel added")
} else {
console.log("Channel already exists")
}
}
addClient(client: IClient) {
console.log("Adding client...", client)
const existingClient: IClient | undefined = this.localClients.find((localClient: IClient) => localClient.id === client.id && localClient.channel?.connection.id === client.channel?.connection.id);
if (existingClient == undefined) {
this.localClients.push(client);
this.updateClientsState();
console.log("Client added")
} else {
console.log("Client already exists")
}
}
// Update data in local lists and update states
updateConnection(connection: IConnection) {
console.log("Updating connection...", connection)
const existingConnection: IConnection | undefined = this.localConnections.find((localConnection: IConnection) => localConnection.id === connection.id);
if (existingConnection !== undefined) {
this.localConnections[this.localConnections.indexOf(existingConnection)] = connection;
this.updateConnectionsState();
console.log("Connection updated")
} else {
console.log("Connection does not exist")
}
}
updateChannel(channel: IChannel) {
console.log("Updating channel...", channel)
const existingChannel: IChannel | undefined = this.localChannels.find((localChannel: IChannel) => localChannel.id === channel.id && localChannel.connection.id === channel.connection.id);
if (existingChannel !== undefined) {
this.localChannels[this.localChannels.indexOf(existingChannel)] = channel;
this.updateChannelsState();
console.log("Channel updated")
} else {
console.log("Channel does not exist")
}
}
updateClient(client: IClient) {
console.log("Updating client...", client)
const existingClient: IClient | undefined = this.localClients.find((localClient: IClient) => localClient.id === client.id && localClient.channel?.connection.id === client.channel?.connection.id);
if (existingClient !== undefined) {
this.localClients[this.localClients.indexOf(existingClient)] = client;
this.updateClientsState();
console.log("Client updated")
} else {
console.log("Client does not exist")
}
}
// Remove data from local lists and update states
removeConnection(connection: IConnection) {
console.log("Removing connection...", connection)
const existingConnection: IConnection | undefined = this.localConnections.find((localConnection: IConnection) => localConnection.id === connection.id);
if (existingConnection !== undefined) {
this.localConnections.splice(this.localConnections.indexOf(existingConnection), 1);
// Remove all channels and clients associated with the connection
this.localChannels = this.localChannels.filter((localChannel: IChannel) => localChannel.connection.id !== connection.id);
this.localClients = this.localClients.filter((localClient: IClient) => localClient.channel?.connection.id !== connection.id);
this.updateChannelsState();
this.updateClientsState();
this.updateConnectionsState();
console.log("Connection removed")
} else {
console.log("Connection does not exist")
}
}
removeChannel(channel: IChannel) {
console.log("Removing channel...", channel)
const existingChannel: IChannel | undefined = this.localChannels.find((localChannel: IChannel) => localChannel.id === channel.id && localChannel.connection.id === channel.connection.id);
if (existingChannel !== undefined) {
this.localChannels.splice(this.localChannels.indexOf(existingChannel), 1);
// Remove all clients associated with the channel
this.localClients = this.localClients.filter((localClient: IClient) => localClient.channel?.id !== channel.id);
this.updateClientsState();
this.updateChannelsState();
console.log("Channel removed")
} else {
console.log("Channel does not exist")
}
}
removeClient(client: IClient) {
console.log("Removing client...", client)
const existingClient: IClient | undefined = this.localClients.find((localClient: IClient) => localClient.id === client.id && localClient.channel?.connection.id === client.channel?.connection.id);
if (existingClient !== undefined) {
this.localClients.splice(this.localClients.indexOf(existingClient), 1);
this.updateClientsState();
console.log("Client removed")
} else {
console.log("Client does not exist")
}
}
// Helper functions
getConnectionById(id: number): IConnection | undefined {
return this.localConnections.find((connection: IConnection) => connection.id === id);
}
getChannelById(id: number, connectionId: number): IChannel | undefined {
return this.localChannels.find((channel: IChannel) => channel.id === id && channel.connection?.id === connectionId);
}
getClientById(id: number, connectionId: number): IClient | undefined {
return this.localClients.find((client: IClient) => client.id === id && client.channel?.connection.id === connectionId);
}
}
// Handle incoming messages from TS5 client
class TS5MessageHandler {
ws: WebSocket;
dataHandler: TS5DataHandler;
setActiveConnectionId: React.Dispatch<React.SetStateAction<number>>;
constructor(ws: WebSocket, dataHandler: TS5DataHandler, setActiveConnectionId: React.Dispatch<React.SetStateAction<number>>) {
this.ws = ws;
this.dataHandler = dataHandler;
this.setActiveConnectionId = setActiveConnectionId;
}
parseChannelInfos(channelInfos: IChannelInfos, connection: IConnection) {
channelInfos.rootChannels.forEach((channel: IChannel) => {
this.dataHandler.addChannel({ ...channel, connection: connection });
if (channelInfos) {
if (channelInfos.subChannels !== null && channel.id in channelInfos.subChannels) {
channelInfos.subChannels[channel.id].forEach((subChannel: IChannel) => {
this.dataHandler.addChannel({ ...subChannel, connection: connection });
});
}
}
});
}
// This message is sent by the TS5 server when the client is connected
// It contains the initial data
handleAuthMessage(data: IAuthMessage) {
console.log("handleAuthMessage", data);
localStorage.setItem("apiKey", data.payload.apiKey);
// Process auth payload and add initial data
data.payload.connections.forEach((connection: IConnection) => {
this.dataHandler.addConnection(connection);
// Add channels
if (connection.channelInfos !== undefined) {
this.parseChannelInfos(connection.channelInfos, connection);
}
// Add clients
connection.clientInfos?.forEach((clientInfo: IClientInfo) => {
const clientChannel: IChannel | undefined = this.dataHandler.getChannelById(clientInfo.channelId, connection.id);
if (clientChannel !== undefined) {
this.dataHandler.addClient({
id: clientInfo.id,
talkStatus: 0,
channel: { ...clientChannel, connection: connection },
properties: clientInfo.properties,
});
}
});
});
}
// This message is sent by the TS5 server when a client moves a channel OR joins/leaves the server
handleClientMovedMessage(data: IClientMovedMessage) {
console.log("handleClientMoved", data);
const client: IClient | undefined = this.dataHandler.getClientById(data.payload.clientId, data.payload.connectionId);
//* This gets called when we are connecting to the server and the new clients get loaded
if (+data.payload.oldChannelId == 0) { // Create new client(when connecting to server)
//set timout to wait for channels to be created
setTimeout(() => {
console.log("---> New Client created")
const newChannel = this.dataHandler.getChannelById(data.payload.newChannelId, data.payload.connectionId);
if (newChannel !== undefined) {
this.dataHandler.addClient(
{
id: data.payload.clientId,
talkStatus: 0,
channel: newChannel,
properties: data.payload.properties,
});
}
}, 2000);
} else {//* This gets called when a client moves a channel OR joins/leaves the server
const newChannel: IChannel | undefined = this.dataHandler.getChannelById(data.payload.newChannelId, data.payload.connectionId);
if (newChannel === undefined || newChannel.id === 0) {
console.log("---> Client left")
if (client !== undefined) {
this.dataHandler.removeClient(client);
}
return;
}
if (client !== undefined) { // Client already exists
// Client moved
console.log("---> Client moved")
this.dataHandler.updateClient({
...client,
channel: newChannel,
});
} else { // Client does not exist
// Client joined
console.log("---> New Client joined")
this.dataHandler.addClient(
{
id: data.payload.clientId,
talkStatus: 0,
channel: newChannel,
properties: data.payload.properties,
}
);
}
}
}
handleClientPropertiesUpdatedMessage(data: IClientPropertiesUpdatedMessage) {
console.log("handleClientPropertiesUpdate", data);
const client: IClient | undefined = this.dataHandler.getClientById(data.payload.clientId, data.payload.connectionId);
if (client !== undefined) {
this.dataHandler.updateClient({
...client,
properties: data.payload.properties,
});
}
}
handleTalkStatusChangedMessage(data: ITalkStatusChangedMessage) {
console.log("handleTalkStatusChanged", data);
const client: IClient | undefined = this.dataHandler.getClientById(data.payload.clientId, data.payload.connectionId);
if (client !== undefined) {
this.dataHandler.updateClient({
...client,
talkStatus: data.payload.status,
});
}
console.log(this.dataHandler.localConnections)
console.log(this.dataHandler.localChannels)
console.log(this.dataHandler.localClients)
}
handleClientSelfPropertyUpdatedMessage(data: IClientSelfPropertyUpdatedMessage) {
console.log("handleClientSelfPropertyUpdated", data);
if (data.payload.flag == "inputHardware") { // sadly thats the only way to detect if a server is active or not
this.setActiveConnectionId(data.payload.connectionId);
}
}
handleServerPropertiesUpdatedMessage(data: IServerPropertiesUpdatedMessage) {
console.log("handleServerPropertiesUpdated", data);
const connection: IConnection | undefined = this.dataHandler.getConnectionById(data.payload.connectionId);
if (connection !== undefined) { // Update existing connection
this.dataHandler.updateConnection({
...connection,
properties: data.payload.properties,
});
}
}
handleConnectStatusChangedMessage(data: IConnectStatusChangedMessage) {
console.log("handleConnectStatusChanged", data);
if (data.payload.status === 0) { // Disconnected from server
const connection: IConnection | undefined = this.dataHandler.getConnectionById(data.payload.connectionId);
if (connection !== undefined) {
this.dataHandler.removeConnection(connection);
}
}
// Status 1-3 are the connection steps (connecting, authenticating, etc.) (i guess)
if (data.payload.status === 4) { // Connected to server
this.dataHandler.addConnection({
id: data.payload.connectionId,
clientId: data.payload.info.clientId,
});
}
}
handleChannelsMessage(data: IChannelsMessage) {
console.log("handleChannels", data);
// Wait a bit for the connection to be added
setTimeout(() => {
console.log(this.dataHandler.localConnections);
console.log(data.payload.connectionId)
console.log(this.dataHandler.localConnections.filter((connection: IConnection) => connection.id === data.payload.connectionId)[0]);
console.log(this.dataHandler.localConnections.find((connection: IConnection) => connection.id === data.payload.connectionId));
const connection: IConnection | undefined = this.dataHandler.getConnectionById(data.payload.connectionId);
console.log(connection);
if (connection !== undefined) {
this.parseChannelInfos(data.payload.info, connection);
console.log(data.payload.info)
}
}, 1000);
}
}

31
src/utils/logger.tsx Normal file
View File

@@ -0,0 +1,31 @@
export default class Logger {
// Log message to the console
public static log(message: string, data: object | null = null): void {
console.log(`[Log] %c${message}`.trim(), "color: gray", data ?? "");
}
// Log warning to the console
public static warn(message: string, data: object | null = null): void {
console.warn(`%c${message}`.trim(), data ?? "");
}
// Log error to the console
public static error(message: string, data: object | null = null): void {
console.error(`%c${message}`.trim(), data ?? "");
}
// Log message received from the websocket to the console
public static wsReceived(data: object, message: string | undefined = undefined): void {
console.log(`%c[WS Recieved] ${message ?? ""}`.trim(), "color: #8258c7", data);
}
// Log message sent to the websocket to the console
public static wsSent(data: object, message: string | undefined = undefined): void {
console.log(`%c[WS Sent] ${message ?? ""}`.trim(), "color: #4eb570", data);
}
// Log message to the console with a timestamp
public static ts(message: string, data: object | null = null): void {
console.log(`%c[TS] ${message}`.trim(), "color: #2e6bc7", data ?? "");
}
}

View File

@@ -6,19 +6,20 @@
"module": "ESNext",
"skipLibCheck": true,
"baseUrl": "./src",
"baseUrl": ".",
"paths": {
"@/*": ["/src/*"],
"@components/*": ["/src/components/*"],
"@assets/*": ["/src/assets/*"],
"@styles/*": ["/src/styles/*"],
"@utils/*": ["/src/utils/*"],
"@interfaces/*": ["/src/interfaces/*"]
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@assets/*": ["src/assets/*"],
"@styles/*": ["src/styles/*"],
"@utils/*": ["src/utils/*"],
"@interfaces/*": ["src/interfaces/*"],
"@handlers/*": ["src/handlers/*"]
},
/* Bundler mode */
"moduleResolution": "bundler",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true,
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,

View File

@@ -1,19 +1,24 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { viteSingleFile } from "vite-plugin-singlefile"
import path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
base: "./",
resolve: {
alias: {
"@": "/src",
"@components": "/src/components",
"@styles": "/src/styles",
"@assets": "/src/assets",
"@interfaces": "/src/interfaces",
"@utils": "/src/utils",
'@': path.resolve(__dirname, './src'),
'@assets': path.resolve(__dirname, './src/assets'),
'@components': path.resolve(__dirname, './src/components'),
'@handlers': path.resolve(__dirname, './src/handlers'),
'@interfaces': path.resolve(__dirname, './src/interfaces'),
'@utils': path.resolve(__dirname, './src/utils'),
'@styles': path.resolve(__dirname, './src/styles'),
},
},
plugins: [react(), viteSingleFile({ useRecommendedBuildConfig: false })],
build: {
outDir: 'dist',
emptyOutDir: true,
},
plugins: [react()],
})