refactor an lots of changes

This commit is contained in:
Khyretos 2023-08-08 06:46:21 +02:00
parent 7e733233ab
commit 039a16711f
29 changed files with 1802 additions and 1627 deletions

27
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "loquendo-bot",
"version": "2.0.0",
"version": "2.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "loquendo-bot",
"version": "2.0.0",
"version": "2.1.0",
"license": "ISC",
"dependencies": {
"axios": "^1.4.0",
@ -15,6 +15,7 @@
"franc": "^6.1.0",
"i18next-electron-language-detector": "^0.0.10",
"ini": "^2.0.0",
"kill-port": "^2.0.1",
"langdetect": "^0.2.1",
"node-google-tts-api": "^1.1.1",
"querystring": "^0.2.1",
@ -3331,6 +3332,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-them-args": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/get-them-args/-/get-them-args-1.3.2.tgz",
"integrity": "sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw=="
},
"node_modules/getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@ -4013,6 +4019,18 @@
"json-buffer": "3.0.1"
}
},
"node_modules/kill-port": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/kill-port/-/kill-port-2.0.1.tgz",
"integrity": "sha512-e0SVOV5jFo0mx8r7bS29maVWp17qGqLBZ5ricNSajON6//kmb7qqqNnml4twNE8Dtj97UQD+gNFOaipS/q1zzQ==",
"dependencies": {
"get-them-args": "1.3.2",
"shell-exec": "1.0.2"
},
"bin": {
"kill-port": "cli.js"
}
},
"node_modules/kuler": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
@ -5899,6 +5917,11 @@
"node": ">=8"
}
},
"node_modules/shell-exec": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/shell-exec/-/shell-exec-1.0.2.tgz",
"integrity": "sha512-jyVd+kU2X+mWKMmGhx4fpWbPsjvD53k9ivqetutVW/BQ+WIZoDoP4d8vUMGezV6saZsiNoW2f9GIhg9Dondohg=="
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",

View file

@ -23,6 +23,7 @@
"franc": "^6.1.0",
"i18next-electron-language-detector": "^0.0.10",
"ini": "^2.0.0",
"kill-port": "^2.0.1",
"langdetect": "^0.2.1",
"node-google-tts-api": "^1.1.1",
"querystring": "^0.2.1",
@ -45,4 +46,4 @@
"@electron-forge/plugin-auto-unpack-natives": "^6.2.1",
"electron": "25.4.0"
}
}
}

View file

@ -369,7 +369,7 @@ select {
.AdvancedMenu {
border: 1px var(--main-color2) solid;
margin-top: 10px;
width: 300px;
min-width: 555px;
border-radius: 5px;
border-radius: 5px;
}
@ -377,6 +377,8 @@ select {
.legendStyle {
margin-left: 1em;
padding: 0.2em 0.8em;
display: flex;
align-items: center;
}
.AdvancedMenuRow {

View file

@ -14,15 +14,15 @@ td {
}
.info {
background-color: lightblue;
background-color: lightblue !important;
}
.warn {
background-color: yellow;
background-color: #f39c12 !important;
}
.error {
background-color: lightcoral;
background-color: #e74c3c !important;
}
#logTable {

View file

@ -28,6 +28,7 @@
.OptionPanel.show {
display: block;
overflow: auto;
}
.menu {

View file

@ -1,184 +1,179 @@
/*generated with Input range slider CSS style generator (version 20211225)
https://toughengineer.github.io/demo/slider-styler*/
input[type=range].styled-slider {
/* height: 500px; */
background: transparent;
-webkit-appearance: none;
width: 300px;
input[type='range'].styled-slider {
/* height: 500px; */
background: transparent;
-webkit-appearance: none;
width: 300px;
}
/*progress support*/
input[type=range].styled-slider.slider-progress1 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5* 2em + var(--ratio) * (100% - 2em));
input[type='range'].styled-slider.slider-progress1 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5 * 2em + var(--ratio) * (100% - 2em));
}
input[type=range].styled-slider.slider-progress2 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5 * 2em + var(--ratio) * (100% - 2em));
input[type='range'].styled-slider.slider-progress2 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5 * 2em + var(--ratio) * (100% - 2em));
}
input[type=range].styled-slider.slider-progress3 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5 * 2em + var(--ratio) * (100% - 2em));
input[type='range'].styled-slider.slider-progress3 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5 * 2em + var(--ratio) * (100% - 2em));
}
input[type=range].styled-slider.slider-progress4 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5 * 2em + var(--ratio) * (100% - 2em));
input[type='range'].styled-slider.slider-progress4 {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--tiempotemporal) - var(--min)) / var(--range));
--sx: calc(0.5 * 2em + var(--ratio) * (100% - 2em));
}
/*webkit*/
input[type=range].styled-slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 2em;
height: 40px;
border-radius: 20px;
background: #FFFFFF;
border: none;
box-shadow: 0 0 2px black;
margin-top: calc(2em * 0.5 - 2em * 0.5);
input[type='range'].styled-slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 2em;
height: 40px;
border-radius: 20px;
background: #ffffff;
border: none;
box-shadow: 0 0 2px black;
margin-top: calc(2em * 0.5 - 2em * 0.5);
}
input[type=range].styled-slider::-webkit-slider-runnable-track {
height: 40px;
border: none;
border-radius: 20px;
background: #1a1a1a;
box-shadow: none;
input[type='range'].styled-slider::-webkit-slider-runnable-track {
height: 40px;
border: none;
border-radius: 20px;
background: #1a1a1a;
box-shadow: none;
}
input[type=range].styled-slider.slider-progress1::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #1a1a1a;
;
input[type='range'].styled-slider.slider-progress1::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #1a1a1a;
}
input[type=range].styled-slider.slider-progress2::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #1a1a1a;
;
input[type='range'].styled-slider.slider-progress2::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #1a1a1a;
}
input[type=range].styled-slider.slider-progress3::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #1a1a1a;
;
input[type='range'].styled-slider.slider-progress3::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #1a1a1a;
}
input[type=range].styled-slider.slider-progress4::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #1a1a1a;
;
input[type='range'].styled-slider.slider-progress4::-webkit-slider-runnable-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #1a1a1a;
}
/*mozilla*/
input[type=range].styled-slider::-moz-range-thumb {
width: 2em;
height: 40px;
border-radius: 20px;
background: #FFFFFF;
border: none;
box-shadow: 0 0 2px black;
input[type='range'].styled-slider::-moz-range-thumb {
width: 2em;
height: 40px;
border-radius: 20px;
background: #ffffff;
border: none;
box-shadow: 0 0 2px black;
}
input[type=range].styled-slider::-moz-range-track {
height: 40px;
border: none;
border-radius: 20px;
background: #1a1a1a;
box-shadow: none;
input[type='range'].styled-slider::-moz-range-track {
height: 40px;
border: none;
border-radius: 20px;
background: #1a1a1a;
box-shadow: none;
}
input[type=range].styled-slider.slider-progress1::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #464646;
input[type='range'].styled-slider.slider-progress1::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #464646;
}
input[type=range].styled-slider.slider-progress2::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #464646;
input[type='range'].styled-slider.slider-progress2::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #464646;
}
input[type=range].styled-slider.slider-progress3::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #464646;
input[type='range'].styled-slider.slider-progress3::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #464646;
}
input[type=range].styled-slider.slider-progress4::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0/var(--sx) 100% no-repeat, #464646;
input[type='range'].styled-slider.slider-progress4::-moz-range-track {
background: linear-gradient(#7b2cbf, #7b2cbf) 0 / var(--sx) 100% no-repeat, #464646;
}
/*ms*/
input[type=range].styled-slider::-ms-fill-upper {
background: transparent;
border-color: transparent;
input[type='range'].styled-slider::-ms-fill-upper {
background: transparent;
border-color: transparent;
}
input[type=range].styled-slider::-ms-fill-lower {
background: transparent;
border-color: transparent;
input[type='range'].styled-slider::-ms-fill-lower {
background: transparent;
border-color: transparent;
}
input[type=range].styled-slider::-ms-thumb {
width: 2em;
height: 40px;
border-radius: 20px;
background: #FFFFFF;
border: none;
box-shadow: 0 0 2px black;
margin-top: 0;
box-sizing: border-box;
input[type='range'].styled-slider::-ms-thumb {
width: 2em;
height: 40px;
border-radius: 20px;
background: #ffffff;
border: none;
box-shadow: 0 0 2px black;
margin-top: 0;
box-sizing: border-box;
}
input[type=range].styled-slider::-ms-track {
height: 40px;
border-radius: 20px;
background: #1a1a1a;
border: none;
box-shadow: none;
box-sizing: border-box;
input[type='range'].styled-slider::-ms-track {
height: 40px;
border-radius: 20px;
background: #1a1a1a;
border: none;
box-shadow: none;
box-sizing: border-box;
}
input[type=range].styled-slider.slider-progress1::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
input[type='range'].styled-slider.slider-progress1::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
}
input[type=range].styled-slider.slider-progress2::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
input[type='range'].styled-slider.slider-progress2::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
}
input[type=range].styled-slider.slider-progress3::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
input[type='range'].styled-slider.slider-progress3::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
}
input[type=range].styled-slider.slider-progress4::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
input[type='range'].styled-slider.slider-progress4::-ms-fill-lower {
height: 40px;
border-radius: 1em 0 0 1em;
margin: -undefined 0 -undefined -undefined;
background: #7b2cbf;
border: none;
border-right-width: 0;
}
.inputBox {
border: none;
width: 50px;
border-radius: 10px;
text-align: center;
font-size: 14pt;
font-weight: bold;
margin-left: 10px;
}
border: none;
width: 38px;
border-radius: 10px;
text-align: center;
font-size: 14pt;
font-weight: bold;
}

View file

@ -73,7 +73,7 @@ section {
.scale {
height: 2em;
width: 2em;
vertical-align: bottom
vertical-align: bottom;
}
.tab {
@ -83,15 +83,14 @@ section {
cursor: pointer;
}
input:checked+label {
border-top-color: #FFB03D;
border-right-color: #DDD;
border-left-color: #DDD;
input:checked + label {
border-top-color: #ffb03d;
border-right-color: #ddd;
border-left-color: #ddd;
border-bottom-color: transparent;
text-decoration: none;
}
/* --------------------------------- */
.radius {
@ -129,13 +128,13 @@ input:checked+label {
.tabx-bar .tabx::before {
position: absolute;
content: "";
content: '';
width: 26%;
height: 13%;
border-top-left-radius: 200px;
border-top-right-radius: 200px;
border-bottom: none;
background-color: #607D8B;
background-color: #607d8b;
/* bottom: -8px; */
opacity: 0;
transition: all 0.3s ease-in-out;
@ -153,7 +152,8 @@ input:checked+label {
bottom: 0px;
}
.tabx-bar .tabx::after {}
.tabx-bar .tabx::after {
}
.tabx-bar .tabx:hover {
padding-bottom: 10px;
@ -192,7 +192,7 @@ input:checked+label {
}
select {
font-size: .9rem;
font-size: 0.9rem;
height: 40px;
border-radius: 20px;
background-color: var(--main-color3);
@ -258,7 +258,7 @@ select {
padding-left: 10px;
}
input[type="password"] {
input[type='password'] {
background: var(--main-color3);
border: none;
height: 40px;
@ -272,7 +272,19 @@ input[type="password"] {
/* To make space for the reveal button */
}
input[type="lol"] {
input[type='url'] {
background: var(--main-color3);
border: none;
height: 40px;
border-radius: 40px;
width: 260px;
outline: none;
color: var(--main-color2);
font-size: 10pt;
margin-left: 10px;
}
input[type='lol'] {
background: var(--main-color3);
border: none;
height: 40px;
@ -292,7 +304,7 @@ input[type="lol"] {
background-color: transparent;
border: none;
cursor: pointer;
left: 450px;
left: 425px;
}
/* Hide the default appearance of the button */
@ -331,20 +343,20 @@ input[type="lol"] {
}
/* Apply different colors based on the toast type */
.toast.info {
background-color: #3498db;
.info {
background-color: lightblue !important;
}
.toast.success {
background-color: #2ecc71;
.success {
background-color: #2ecc71 !important;
}
.toast.warning {
background-color: #f39c12;
.warning {
background-color: #f39c12 !important;
}
.toast.error {
background-color: #e74c3c;
.error {
background-color: #e74c3c !important;
}
/* CSS animation for the toast appearance */
@ -413,19 +425,30 @@ input[type="lol"] {
visibility: visible;
} */
input[type=text]:disabled {
background: #dddddd;
div[type='text']:disabled {
background: #4b4b4b;
display: none;
}
input[type2=text]:disabled {
background: #dddddd;
input[type='text']:disabled {
background: #4b4b4b;
}
button[type=text]:disabled {
background: #dddddd;
button[type='text']:disabled {
background: #4b4b4b;
display: none;
}
input[type2='text']:disabled {
background: #4b4b4b;
}
div:disabled {
background: #dddddd;
background: #4b4b4b;
filter: brightness(200%);
}
}
div:disabled {
background: #4b4b4b;
filter: brightness(200%);
}

View file

@ -22,9 +22,10 @@
#volume-icon {
color: var(--main-color2);
width: 50px;
scale: 0.75;
cursor: pointer;
text-align: center;
align-self: center;
}
#image {
@ -131,4 +132,4 @@ textarea {
/* filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(350deg) brightness(104%) contrast(101%); */
align-items: flex-start;
margin: auto;
}
}

View file

@ -67,11 +67,14 @@
box-shadow: 0 0 0 3px rgba(255, 255, 255, 1);
}
.volume-icon-container {
.option-icon-container {
display: flex;
flex-direction: column;
justify-content: center;
/* justify-content: center; */
align-items: center;
/* width: 78px; */
/* float: right; */
flex-grow: 1;
}
.brush-icon-container {
@ -81,4 +84,4 @@
.icon {
fill: var(--main-color2);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 79 KiB

3
src/images/note.svg Normal file
View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="24px" height="24px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M703.90625 865.90625l-39.9375-15.65625 148.6875-380.0625c6.84375-17.53125-2.4375-37.3125-20.34375-43.125l-260.0625-84.9375c-16.6875-5.4375-34.6875 3.1875-40.875 19.59375L361.8125 704.46875l-61.40625-23.15625 181.875-481.125c6.09375-16.21875 23.8125-24.84375 40.40625-19.78125l389.0625 120.1875c18.1875 5.625 27.84375 25.5 20.90625 43.3125l-199.125 509.0625c-4.6875 11.71875-17.90625 17.53125-29.625 12.9375z" fill="#360682" /><path d="M241.0625 658.15625m-129.375 0a129.375 129.375 0 1 0 258.75 0 129.375 129.375 0 1 0-258.75 0Z" fill="#360682" /><path d="M614.375 802.90625m-129.375 0a129.375 129.375 0 1 0 258.75 0 129.375 129.375 0 1 0-258.75 0Z" fill="#360682" /><path d="M246.53333333 379.36666667L142.43333333 118.66666667c-6.8-16.9 2.4-36 19.8-41.3l107.9-32.9c14.4-4.4 29.7 2.5 36 16.2l13.2 28.8c7.5 16.3-0.9 35.4-17.9 41l-73.7 24.3c-6.9 2.3-10.5 9.9-7.8 16.6L290.33333333 350.96666667c2.1 5.4-0.5 11.4-5.9 13.6l-37.9 14.8z" fill="#E51C5A" /><path d="M211.53333333 379.36666667m-84.8 0a84.8 84.8 0 1 0 169.6 0 84.8 84.8 0 1 0-169.6 0Z" fill="#E51C5A" /></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

48
src/images/stt.svg Normal file
View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>.cls-1{fill:#4285f4;}.cls-2{fill:none;}.cls-3{fill:#669df6;}</style>
</defs>
<title>Icon_24px_SpeechtoText_Color</title>
<g data-name="Product Icons">
<g data-name="colored-32/speech">
<rect class="cls-1" x="11" y="2" width="2" height="20"/>
<rect class="cls-2" width="24" height="24"/>
<g >
<rect id="Rectangle-path-2" data-name="Rectangle-path" class="cls-1" x="7" y="8" width="2" height="8"/>
<rect id="Rectangle-path-3" data-name="Rectangle-path" class="cls-1" x="15" y="8" width="2" height="8"/>
<rect id="Rectangle-path-4" data-name="Rectangle-path" class="cls-1" x="3" y="5" width="2" height="14"/>
<rect id="Rectangle-path-5" data-name="Rectangle-path" class="cls-1" x="19" y="5" width="2" height="14"/>
<rect id="Rectangle-path-6" data-name="Rectangle-path" class="cls-3" x="11" y="2" width="2" height="10"/>
<rect id="Rectangle-path-7" data-name="Rectangle-path" class="cls-3" x="7" y="8" width="2" height="4"/>
<rect id="Rectangle-path-8" data-name="Rectangle-path" class="cls-3" x="15" y="8" width="2" height="4"/>
<rect id="Rectangle-path-9" data-name="Rectangle-path" class="cls-3" x="3" y="5" width="2" height="7"/>
<rect id="Rectangle-path-10" data-name="Rectangle-path" class="cls-3" x="19" y="5" width="2" height="7"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

28
src/images/theme.svg Normal file
View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg height="24px" width="24px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 512 512" xml:space="preserve">
<path style="fill:#FFC033;" d="M491.09,328.459c-10.239-17.809-28.826-27.937-51.199-27.937c-28.737,0-47.726-21.359-48.085-44.522
c-0.111-9.906,3.228-20.035,10.685-28.828c8.459-10.017,20.815-15.694,33.837-15.694c24.598,0,44.522-10.351,54.872-28.271
c9.796-17.03,9.685-38.4-0.333-55.652C445.122,48.863,360.307,0,269.373,0C146.938,0,41.421,86.15,18.381,204.911
c-3.338,17.03-5.009,34.059-4.896,51.089v0.668c0.223,58.991,20.48,116.313,58.435,162.282C120.671,478.052,192.685,512,269.374,512
c91.157,0,176.085-49.085,221.717-128C500.997,366.859,500.997,345.6,491.09,328.459z M292.745,104.181
c13.803-23.93,44.3-32.278,68.452-18.365c23.93,13.803,32.167,44.412,18.365,68.452c-13.803,23.819-44.412,32.167-68.452,18.254
C287.18,158.72,278.945,128.223,292.745,104.181z"/>
<path style="fill:#F9A926;" d="M71.919,418.95C120.67,478.052,192.684,512,269.373,512c91.157,0,176.085-49.085,221.717-128
c9.907-17.141,9.907-38.4,0-55.541c-10.239-17.809-28.826-27.937-51.199-27.937c-28.737,0-47.726-21.359-48.085-44.522H13.483v0.668
C13.707,315.659,33.963,372.981,71.919,418.95z"/>
<path style="fill:#88CC2A;" d="M124.677,306.087c-27.619,0-50.087-22.468-50.087-50.087s22.468-50.087,50.087-50.087
s50.087,22.468,50.087,50.087S152.296,306.087,124.677,306.087z"/>
<path style="fill:#736056;" d="M171.981,420.609c-23.923-13.802-32.21-44.397-18.326-68.424
c13.695-23.726,44.21-32.294,68.413-18.321c23.922,13.801,32.21,44.392,18.326,68.419
C226.622,426.154,196.056,434.511,171.981,420.609z"/>
<path style="fill:#37AFCC;" d="M323.198,431.18c-26.712-7.156-42.599-34.587-35.424-61.342c7.175-26.741,34.59-42.578,61.336-35.413
c12.924,3.456,23.728,11.745,30.413,23.326l0,0c6.696,11.587,8.478,25.087,5.011,38.016
C377.349,422.55,349.888,438.339,323.198,431.18z"/>
<path style="fill:#E6563A;" d="M153.655,159.81c-13.855-23.966-5.651-54.579,18.326-68.424
c24.013-13.841,54.599-5.613,68.413,18.332l0,0c13.877,24.016,5.607,54.605-18.326,68.424
C197.941,192.057,167.398,183.631,153.655,159.81z"/>
<path style="fill:#7FB335;" d="M124.677,306.087c27.619,0,50.087-22.468,50.087-50.087H74.59
C74.59,283.619,97.057,306.087,124.677,306.087z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

26
src/images/tts.svg Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>.cls-1{fill:#669df6;}.cls-2{fill:#4285f4;}</style>
</defs>
<title>Icon_24px_TexttoSpeech_Color</title>
<g data-name="Product Icons">
<rect class="cls-1" x="2.01" y="6.99" width="6.64" height="1.67"/>
<polygon class="cls-1" points="11.17 15.32 2 15.32 2 16.99 2 16.99 11.17 16.99 11.17 15.32"/>
<polygon class="cls-1" points="4.51 11.16 2 11.16 2 12.82 6.18 12.82 12 12.82 10.33 11.16 4.51 11.16"/>
<path class="cls-2" d="M12,9.07a.42.42,0,0,1,.42-.36.41.41,0,0,1,.41.36v9.18a2.09,2.09,0,0,0,2.61,2A2.16,2.16,0,0,0,17,18.14V5.75a.4.4,0,0,1,.19-.4.41.41,0,0,1,.45,0,.4.4,0,0,1,.19.4v9.16a2.07,2.07,0,0,0,.81,1.64,2,2,0,0,0,1.8.37A2.16,2.16,0,0,0,22,14.8V12H20.33v2.92a.4.4,0,0,1-.19.4.41.41,0,0,1-.45,0,.4.4,0,0,1-.19-.4V5.75a2.09,2.09,0,0,0-2.61-2,2.16,2.16,0,0,0-1.56,2.13V18.25a.4.4,0,0,1-.19.4.41.41,0,0,1-.45,0,.4.4,0,0,1-.19-.4V9.08a2.07,2.07,0,0,0-4.11-.36,2.4,2.4,0,0,0-.05.46v2L12,12.82V9.07Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because it is too large Load diff

65
src/js/auth.js Normal file
View file

@ -0,0 +1,65 @@
console.log("kees");
// const clientId = 'YOUR_TWITCH_CLIENT_ID';
// const redirectUri = 'http://localhost:1989/auth';
// const scopes = ['chat:edit', 'chat:read'];
// const express = require('express');
// const tempAuthServer = express();
// const port = 1989;
// const { parse: parseQueryString } = require('querystring');
// tempAuthServer.use(function (req, res, next) {
// if (req.url !== "/auth") {
// let token = parseQueryString(req.query.auth)
// res.json(token["#access_token"]);
// // settings.TWITCH.OAUTH_TOKEN = token["#access_token"];
// // fs.writeFileSync(settingsPath, ini.stringify(settings));
// // settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8'));
// // tempAuthServer.close();
// }
// next();
// });
// const htmlString = `
// <!DOCTYPE html>
// <html>
// <head>
// <title>Authentication</title>
// </head>
// <body>
// <h1>Authentication successful! You can close this window now.</h1>
// <form name="auth" "action="auth" method="get" >
// <input type="text" id="auth" name="auth"/>
// <input type="submit" />
// </form>
// </body>
// </html>
// <script>
// function onSubmitComplete() {
// close();
// }
// document.querySelector("#auth").value = document.location.hash;
// document.auth.submit();
// setTimeout(onSubmitComplete, 500);
// </script>`;
// tempAuthServer.get('/auth', (req, res) => {
// // res.send(htmlString);
// });
// tempAuthServer.post('/auth', (req, res) => {
// res.render('authentication', { name: req.body.name });
// });
// tempAuthServer.listen(port, () => { });
// const authURL = `https://id.twitch.tv/oauth2/authorize?client_id=${settings.TWITCH.CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=token&scope=${scopes.join(' ')}`;
// shell.openExternal(authURL);
onsole.log('ExecPath', process.execPath);
process.on('message', (m) => {
console.log('Got message:', m);
process.send("message", "lol");
});

View file

@ -117,7 +117,6 @@ displayPanel('.OptionPanel', '#Configuration', '#btnConfiguration');
displayPanel('.OptionPanel', '#Logs', '#btnLogs');
displayPanel('.OptionPanel', '#BrowsersourceChat', '#btnBrowsersourceChat');
displayPanel('.OptionPanel', '#BrowsersourceVtuber', '#btnBrowsersourceVtuber');
displayPanel('.OptionPanel', '#TTS', '#btnTTS');
displayPanel('.OptionPanel', '#Chat', '#btnChat');
// #endregion
@ -142,25 +141,12 @@ const displayPanelX = (panelSelectorClass, panelSelectorID, btnSelectorID) => {
});
};
displayPanelX('.item', '#btnTTS', '#btnTTS');
displayPanelX('.item', '#btnChat', '#btnChat');
displayPanelX('.item', '#btnBrowsersourceChat', '#btnBrowsersourceChat');
displayPanelX('.item', '#btnBrowsersourceVtuber', '#btnBrowsersourceVtuber');
displayPanelX('.item', '#btnLogs', '#btnLogs');
displayPanelX('.item', '#btnConfiguration', '#btnConfiguration');
// #region Show/Hide Advanced Menu
document.body.querySelector('#ShowAdvancedMenu').addEventListener('click', () => {
document.getElementById('AdvancedMenu_mask').style.visibility = 'visible';
});
document.body.querySelector('#HideAdvancedMenu').addEventListener('click', () => {
document.getElementById('AdvancedMenu_mask').style.visibility = 'hidden';
});
// #endregion
// #region Show/Hide Theme Creator
document.body.querySelector('#ShowThemeCreator').addEventListener('click', () => {
document.getElementById('ThemeCreator_mask').style.visibility = 'visible';

View file

@ -24,11 +24,11 @@ const logger = createLogger({
format: fileFormat,
transports: [
new transports.File({
filename: path.join(__dirname, '../logs/error.log'),
filename: path.join(resourcesPath, '../logs/error.log'),
level: 'error',
}),
new transports.File({
filename: path.join(__dirname, '../logs/activity.log'),
filename: path.join(resourcesPath, '../logs/activity.log'),
maxsize: 5242880,
maxFiles: 5,
}),
@ -44,7 +44,7 @@ if (process.env.NODE_ENV !== 'production') {
);
}
fetch(path.join(__dirname, '../logs/activity.log'))
fetch(path.join(resourcesPath, '../logs/activity.log'))
.then((response) => response.text())
.then((logData) => {
const logLines = logData.trim().split('\n');

View file

@ -1,14 +1,13 @@
const fs = require('fs');
const ini = require('ini');
const path = require('path'); // get directory path
const {
ipcRenderer,
} = require('electron'); // necessary electron libraries to send data to the app
const { ipcRenderer } = require('electron'); // necessary electron libraries to send data to the app
const say = require('say');
const request = require('request');
const langdetect = require('langdetect');
const io = require('socket.io-client');
const fs = require('fs');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
@ -17,16 +16,18 @@ const GoogleTTS = require('node-google-tts-api');
const tts = new GoogleTTS();
const { Socket } = require('socket.io-client');
const ini = require('ini');
const main = ipcRenderer.sendSync('environment');
let envInfo = (ipcRenderer.sendSync('environment'))
const resourcesPath = main.resourcesPath;
const settingsPath = main.settingsPath.toString();
const settings = main.settings;
// TODO: remove gooogle voices txt and use api instead
const googleVoices = fs.readFileSync(path.join(__dirname, './config/googleVoices.txt')).toString().split('\r\n');
const googleVoices = fs.readFileSync(path.join(resourcesPath, './config/googleVoices.txt')).toString().split('\r\n');
// TODO: remove amazon voices txt and use api instead (sakura project has it)
const amazonVoices = fs.readFileSync(path.join(__dirname, './config/amazonVoices.txt')).toString().split('\r\n');
const amazonVoices = fs.readFileSync(path.join(resourcesPath, './config/amazonVoices.txt')).toString().split('\r\n');
const languagesObject = fs.readFileSync(path.join(__dirname, './config/languages.txt')).toString().split('\r\n');
const languagesObject = fs.readFileSync(path.join(resourcesPath, './config/languages.txt')).toString().split('\r\n');
// html elements
const root = document.documentElement;
@ -37,46 +38,44 @@ const devicesDropdown = document.querySelector('#devicesDropdown');
const notificationSound = document.querySelector('#notification'); // obtain the html reference of the sound comboBox
const ttsAudioDevices = document.querySelector('#ttsAudioDevice'); // obtain the html reference of the installedTTS comboBox
// laod local javascript files
const chat = require(path.join(__dirname, './js/chat'));
const chat = require(path.join(resourcesPath, './js/chat'));
const messageTemplates = require(path.join(__dirname, './js/messageTemplates'));
const logger = require(path.join(__dirname, './js/logger'));
const sound = require(path.join(__dirname, './js/sound'));
const talk = require(path.join(__dirname, './js/voiceQueue')); // Voice queue system
const config = require(path.join(__dirname, './js/settings'));
const messageTemplates = require(path.join(resourcesPath, './js/messageTemplates'));
const logger = require(path.join(resourcesPath, './js/logger'));
const sound = require(path.join(resourcesPath, './js/sound'));
const talk = require(path.join(resourcesPath, './js/voiceQueue')); // Voice queue system
const config = require(path.join(resourcesPath, './js/settings'));
let notificationSounds = undefined;
if (envInfo.env) {
notificationSounds = path.join(envInfo.path, './sounds/notifications');
} else {
notificationSounds = path.join(__dirname, './sounds/notifications');
let notificationSounds = path.join(resourcesPath, './sounds/notifications');
let twitch = require(path.join(resourcesPath, './js/twitch'));
function reset() {
ipcRenderer.send('restart');
}
const twitch = config.settings.TWITCH.USE_TWITCH ? require(path.join(__dirname, './js/twitch')) : '';
let server;
let socket;
if (config.settings.SERVER.USE_SERVER) {
server = require(path.join(__dirname, './js/server'));
socket = io(`http://localhost:${config.settings.SERVER.PORT}`); // Connect to your Socket.IO server
function setServer() {
if (!settings.SERVER.USE_SERVER) {
return;
}
server = require(path.join(resourcesPath, './js/server'));
socket = io(`http://localhost:${settings.SERVER.PORT}`); // Connect to your Socket.IO server
}
const Polly = config.settings.AMAZON.USE_AMAZON ? require(path.join(__dirname, './js/amazon')) : '';
const google = config.settings.GOOGLE.USE_GOOGLE ? require(path.join(__dirname, './js/amazon')) : '';
setServer();
const theme = require(path.join(__dirname, './js/theme'));
const Polly = settings.AMAZON.USE_AMAZON ? require(path.join(resourcesPath, './js/amazon')) : '';
const google = settings.GOOGLE.USE_GOOGLE ? require(path.join(resourcesPath, './js/amazon')) : '';
const theme = require(path.join(resourcesPath, './js/theme'));
// initialize values
config.getGeneralSettings();
config.setCustomThemeToggle();
let selectedVoiceIndex;
let selectedEncodingIndex;
let selectedTtsAudioDeviceIndex;
const TTSVolume = 1;
const notificationSoundVolume = 1;
@ -85,236 +84,233 @@ const StartDateAndTime = Date.now();
const speakButton = document.querySelector('#speakBtn');
const amazonCredentials = {
accessKeyId: config.settings.AMAZON.ACCESS_KEY,
secretAccessKey: config.settings.AMAZON.ACCESS_SECRET,
accessKeyId: settings.AMAZON.ACCESS_KEY,
secretAccessKey: settings.AMAZON.ACCESS_SECRET,
};
// Check for installed sounds
fs.readdir(notificationSounds, (err, files) => {
files.forEach((file, i) => {
// Create a new option element.
const option = document.createElement('option');
files.forEach((file, i) => {
// Create a new option element.
const option = document.createElement('option');
// Set the options value and text.
option.value = i;
option.innerHTML = file;
// Set the options value and text.
option.value = i;
option.innerHTML = file;
// Add the option to the sound selector.
notificationSound.appendChild(option);
});
// Add the option to the sound selector.
notificationSound.appendChild(option);
});
// set the saved notification sound
notificationSound.selectedIndex = config.settings.AUDIO.NOTIFICATION_SOUND;
// set the saved notification sound
notificationSound.selectedIndex = settings.AUDIO.NOTIFICATION_SOUND;
});
async function getAudioDevices() {
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
// logger.info('enumerateDevices() not supported.');
return;
}
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
// logger.info('enumerateDevices() not supported.');
return;
}
const devices = await navigator.mediaDevices.enumerateDevices();
const audioOutputDevices = devices.filter((device) => device.kind === 'audiooutput');
const devices = await navigator.mediaDevices.enumerateDevices();
const audioOutputDevices = devices.filter((device) => device.kind === 'audiooutput');
audioOutputDevices.forEach((device) => {
const option = document.createElement('option');
option.text = device.label || `Output ${device.deviceId}`;
option.value = device.deviceId;
ttsAudioDevices.appendChild(option);
});
audioOutputDevices.forEach((device) => {
const option = document.createElement('option');
option.text = device.label || `Output ${device.deviceId}`;
option.value = device.deviceId;
ttsAudioDevices.appendChild(option);
});
ttsAudioDevices.selectedIndex = config.settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE;
ttsAudioDevices.selectedIndex = settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE;
}
getAudioDevices();
function setLanguagesinSelect(languageSelector, setting) {
let languageSelect = document.querySelector(languageSelector); // obtain the html reference of the google voices comboBox
let languageSelect = document.querySelector(languageSelector); // obtain the html reference of the google voices comboBox
const languages = Object.keys(languagesObject);
languages.forEach((language) => {
const option = document.createElement('option');
const languages = Object.keys(languagesObject);
languages.forEach((language) => {
const option = document.createElement('option');
option.value = language;
option.innerHTML = languagesObject[language];
option.value = language;
option.innerHTML = languagesObject[language];
languageSelect.appendChild(option);
});
languageSelect.appendChild(option);
});
languageSelect.selectedIndex = setting;
languageSelect.selectedIndex = setting;
}
setLanguagesinSelect("#primaryLanguage", config.settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX);
setLanguagesinSelect("#secondaryLanguage", config.settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX);
setLanguagesinSelect('#primaryLanguage', settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX);
setLanguagesinSelect('#secondaryLanguage', settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX);
function getInstalledVoices(callback) {
say.getInstalledVoices((err, voices) => {
say.getInstalledVoices((err, voices) => {
function setVoicesinSelect(voiceSelector) {
let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox
function setVoicesinSelect(voiceSelector) {
let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox
const internalTTSHeader = document.createElement('optgroup');
internalTTSHeader.label = 'Internal TTS';
voiceSelect.appendChild(internalTTSHeader);
const internalTTSHeader = document.createElement('optgroup');
internalTTSHeader.label = "Internal TTS";
voiceSelect.appendChild(internalTTSHeader);
// const installedTTS = document.querySelector('#installedTTS'); // obtain the html reference of the installedTTS comboBox
voices.forEach((voice, i) => {
const option = document.createElement('option');
// const installedTTS = document.querySelector('#installedTTS'); // obtain the html reference of the installedTTS comboBox
voices.forEach((voice, i) => {
const option = document.createElement('option');
option.value = i;
option.innerHTML = voice;
option.value = i;
option.innerHTML = voice;
// installedTTS.appendChild(option);
internalTTSHeader.appendChild(option);
});
}
setVoicesinSelect('#primaryVoice');
setVoicesinSelect('#secondaryVoice');
// installedTTS.appendChild(option);
internalTTSHeader.appendChild(option);
});
}
setVoicesinSelect("#primaryVoice");
setVoicesinSelect("#secondaryVoice");
callback();
});
callback();
});
}
function getAmazonVoices(callback) {
if (!config.settings.AMAZON.USE_AMAZON) {
callback();
return;
}
if (!settings.AMAZON.USE_AMAZON) {
callback();
return;
}
function setVoicesinSelect(voiceSelector) {
let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox
function setVoicesinSelect(voiceSelector) {
let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox
const internalTTSHeader = document.createElement('optgroup');
internalTTSHeader.label = "Amazon TTS";
voiceSelect.appendChild(internalTTSHeader);
const internalTTSHeader = document.createElement('optgroup');
internalTTSHeader.label = 'Amazon TTS';
voiceSelect.appendChild(internalTTSHeader);
const voices = Object.keys(amazonVoices);
voices.forEach((voice) => {
const option = document.createElement('option');
const voices = Object.keys(amazonVoices);
voices.forEach((voice) => {
const option = document.createElement('option');
option.value = voice;
option.innerHTML = amazonVoices[voice];
option.value = voice;
option.innerHTML = amazonVoices[voice];
internalTTSHeader.appendChild(option);
});
}
internalTTSHeader.appendChild(option);
});
}
setVoicesinSelect("#primaryVoice");
setVoicesinSelect("#secondaryVoice");
setVoicesinSelect('#primaryVoice');
setVoicesinSelect('#secondaryVoice');
callback();
callback();
}
function getGoogleVoices(callback) {
if (!config.settings.GOOGLE.USE_GOOGLE) {
callback();
return;
}
if (!settings.GOOGLE.USE_GOOGLE) {
callback();
return;
}
function setVoicesinSelect(voiceSelector) {
let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox
function setVoicesinSelect(voiceSelector) {
let voiceSelect = document.querySelector(voiceSelector); // obtain the html reference of the google voices comboBox
const internalTTSHeader = document.createElement('optgroup');
internalTTSHeader.label = "Google TTS";
voiceSelect.appendChild(internalTTSHeader);
const internalTTSHeader = document.createElement('optgroup');
internalTTSHeader.label = 'Google TTS';
voiceSelect.appendChild(internalTTSHeader);
const googleVoiceSelect = document.querySelector('#googleVoice'); // obtain the html reference of the google voices comboBox
const voices = Object.keys(googleVoices);
voices.forEach((voice) => {
const option = document.createElement('option');
option.classList.add("option");
const googleVoiceSelect = document.querySelector('#googleVoice'); // obtain the html reference of the google voices comboBox
const voices = Object.keys(googleVoices);
voices.forEach((voice) => {
const option = document.createElement('option');
option.classList.add('option');
option.value = voice;
option.innerHTML = googleVoices[voice];
option.value = voice;
option.innerHTML = googleVoices[voice];
internalTTSHeader.appendChild(option);
});
}
setVoicesinSelect("#primaryVoice");
setVoicesinSelect("#secondaryVoice");
internalTTSHeader.appendChild(option);
});
}
setVoicesinSelect('#primaryVoice');
setVoicesinSelect('#secondaryVoice');
callback();
callback();
}
getGoogleVoices(function () {
getAmazonVoices(function () {
getInstalledVoices(function () {
let primaryVoice = document.querySelector("#primaryVoice");
primaryVoice.selectedIndex = config.settings.TTS.PRIMARY_TTS_VOICE;
getAmazonVoices(function () {
getInstalledVoices(function () {
let primaryVoice = document.querySelector('#primaryVoice');
primaryVoice.selectedIndex = settings.TTS.PRIMARY_TTS_VOICE;
let secondaryVoice = document.querySelector("#secondaryVoice");
secondaryVoice.selectedIndex = config.settings.TTS.SECONDARY_TTS_VOICE;
});
});
let secondaryVoice = document.querySelector('#secondaryVoice');
secondaryVoice.selectedIndex = settings.TTS.SECONDARY_TTS_VOICE;
});
});
});
// Small tooltip
Array.from(document.body.querySelectorAll('[tip]')).forEach((el) => {
const tip = document.createElement('div');
const body = document.querySelector('.container');
const element = el;
tip.classList.add('tooltip');
tip.classList.add('tooltiptext');
tip.innerText = el.getAttribute('tip');
tip.style.transform = `translate(${el.hasAttribute('tip-left') ? 'calc(-100% - 5px)' : '15px'}, ${el.hasAttribute('tip-top') ? '-100%' : '15px'
})`;
body.appendChild(tip);
element.onmousemove = (e) => {
tip.style.left = `${e.x}px`;
tip.style.top = `${e.y}px`;
tip.style.zIndex = 1;
tip.style.visibility = "visible";
};
element.onmouseleave = (e) => {
tip.style.visibility = "hidden";
};
const tip = document.createElement('div');
const body = document.querySelector('.container');
const element = el;
tip.classList.add('tooltip');
tip.classList.add('tooltiptext');
tip.innerText = el.getAttribute('tip');
tip.style.transform = `translate(${el.hasAttribute('tip-left') ? 'calc(-100% - 5px)' : '15px'}, ${
el.hasAttribute('tip-top') ? '-100%' : '15px'
})`;
body.appendChild(tip);
element.onmousemove = (e) => {
tip.style.left = `${e.x}px`;
tip.style.top = `${e.y}px`;
tip.style.zIndex = 1;
tip.style.visibility = 'visible';
};
element.onmouseleave = (e) => {
tip.style.visibility = 'hidden';
};
});
function showChatMessage(article) {
document.querySelector('#chatBox').appendChild(article);
const messages = Array.from(document.body.querySelectorAll('.msg-container'));
const lastMessage = messages[messages.length - 1];
lastMessage.scrollIntoView({ behavior: 'smooth' });
document.querySelector('#chatBox').appendChild(article);
const messages = Array.from(document.body.querySelectorAll('.msg-container'));
const lastMessage = messages[messages.length - 1];
lastMessage.scrollIntoView({ behavior: 'smooth' });
}
function getPostTime() {
const date = new Date();
document.body.querySelectorAll('.container').innerHTML = date.getHours();
const hours = date.getHours();
const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
const time = `${hours}:${minutes}`;
const date = new Date();
document.body.querySelectorAll('.container').innerHTML = date.getHours();
const hours = date.getHours();
const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
const time = `${hours}:${minutes}`;
return time;
return time;
}
function showPreviewChatMessage() {
const message = messageTemplates.messageTemplate;
document.querySelector('#mini-mid').innerHTML += message;
const messages = Array.from(document.body.querySelectorAll('#mini-mid'));
const lastMessage = messages[messages.length - 1];
lastMessage.scrollIntoView({ behavior: 'smooth' });
const message = messageTemplates.messageTemplate;
document.querySelector('#mini-mid').innerHTML += message;
const messages = Array.from(document.body.querySelectorAll('#mini-mid'));
const lastMessage = messages[messages.length - 1];
lastMessage.scrollIntoView({ behavior: 'smooth' });
}
showPreviewChatMessage();
function hideText(button, field) {
document.body.querySelector(button).addEventListener('click', () => {
const passwordInput = document.querySelector(field);
if (passwordInput.type === 'password') {
passwordInput.type = 'lol';
} else {
passwordInput.type = 'password';
}
});
document.body.querySelector(button).addEventListener('click', () => {
const passwordInput = document.querySelector(field);
if (passwordInput.type === 'password') {
passwordInput.type = 'lol';
} else {
passwordInput.type = 'password';
}
});
}
hideText('.password-toggle-btn1', "#TWITCH_OAUTH_TOKEN");
hideText('.password-toggle-btn2', "#TWITCH_CLIENT_ID");
hideText('.password-toggle-btn3', "#TWITCH_CLIENT_SECRET");
hideText('.password-toggle-btn4', "#AMAZON_ACCESS_KEY");
hideText('.password-toggle-btn5', "#AMAZON_ACCESS_SECRET");
hideText('.password-toggle-btn6', "#GOOGLE_API_KEY");
hideText('.password-toggle-btn1', '#TWITCH_OAUTH_TOKEN');
hideText('.password-toggle-btn4', '#AMAZON_ACCESS_KEY');
hideText('.password-toggle-btn5', '#AMAZON_ACCESS_SECRET');
hideText('.password-toggle-btn6', '#GOOGLE_API_KEY');
// Amazon TTS
// const polly = new Polly(amazonCredentials);
@ -323,7 +319,7 @@ hideText('.password-toggle-btn6', "#GOOGLE_API_KEY");
// voiceId: 'Lotte',
// };
// const fileStream = fs.createWriteStream(path.join(__dirname, '/public/sounds/tts/Amazon_audio.mp3'));
// const fileStream = fs.createWriteStream(path.join(resourcesPath, '/public/sounds/tts/Amazon_audio.mp3'));
// polly.textToSpeech(options, (err, audioStream) => {
// if (err) {
@ -331,4 +327,4 @@ hideText('.password-toggle-btn6', "#GOOGLE_API_KEY");
// }
// audioStream.pipe(fileStream);
// return 1;
// });
// });

View file

@ -1,54 +1,81 @@
const express = require('express');
const app = express();
const path = require('path');
const http = require('http').createServer(app);
const io = require('socket.io')(http);
if (!config.settings.SERVER.USE_SERVER) {
return;
if (!settings.SERVER.USE_SERVER) {
return;
}
const PORT = config.settings.SERVER.PORT;
const PORT = settings.SERVER.PORT;
let isVtuberEnabled = true;
let isChatBubbleEnabled = true;
function startVtuber() {
if (!settings.SERVER.USE_VTUBER) {
isVtuberEnabled = false;
return;
}
app.use('/vtuber', express.static(path.join(resourcesPath, './modules/vtuber/')));
let vtuber = document.body.querySelector('#BrowsersourceVtuber');
let vtuberframe = document.createElement('iframe');
vtuberframe.class = 'frame';
vtuberframe.src = `http://localhost:${PORT}/vtuber`;
vtuberframe.style.width = '100%';
vtuberframe.style.height = '100%';
vtuberframe.frameBorder = 0;
vtuber.appendChild(vtuberframe);
}
function startChatBubble() {
if (!settings.SERVER.USE_CHATBUBBLE) {
isChatBubbleEnabled = false;
return;
}
app.use('/chat', express.static(path.join(resourcesPath, './modules/chat')));
let chat = document.body.querySelector('#BrowsersourceChat');
let chatframe = document.createElement('iframe');
chatframe.class = 'frame';
chatframe.src = `http://localhost:${PORT}/chat`;
chatframe.style.width = '100%';
chatframe.style.height = '100%';
chatframe.frameBorder = 0;
chat.appendChild(chatframe);
}
// Middleware to conditionally serve routes
app.use((req, res, next) => {
if (!isVtuberEnabled && req.path === '/vtuber') {
res.sendStatus(404); // Return a 404 status for /vtuber when it's disabled
} else if (!isChatBubbleEnabled && req.path === '/chat') {
res.sendStatus(404); // Return a 404 status for /chat when it's disabled
} else {
next(); // Proceed to the next middleware or route handler
}
});
http.listen(PORT, () => {
if (config.settings.SERVER.USE_VTUBER) {
app.use('/vtuber', express.static(path.join(__dirname, '../modules/vtuber/')));
let vtuber = document.body.querySelector('#BrowsersourceVtuber');
let vtuberframe = document.createElement('iframe');
vtuberframe.class = "frame";
vtuberframe.src = `http://localhost:${PORT}/vtuber`;
vtuberframe.style.width = "100%";
vtuberframe.style.height = "100%";
vtuberframe.frameBorder = 0;
vtuber.appendChild(vtuberframe);
}
if (config.settings.SERVER.USE_CHATBUBBLE) {
app.use('/chat', express.static(path.join(__dirname, '../modules/chat')));
let chat = document.body.querySelector('#BrowsersourceChat');
let chatframe = document.createElement('iframe');
chatframe.class = "frame";
chatframe.src = `http://localhost:${PORT}/chat`;
chatframe.style.width = "100%";
chatframe.style.height = "100%";
chatframe.frameBorder = 0;
chat.appendChild(chatframe);
}
startVtuber();
startChatBubble();
});
// Handle socket connections
io.on('connection', (socket) => {
// Receive data from the client
socket.on('message', (data) => {});
// Receive data from the client
socket.on('message', (data) => { });
// Receive data from the client
socket.on('xxx', (logoUrl, username, message) => {
socket.broadcast.emit('message', logoUrl, username, message);
});
// Receive data from the client
socket.on('xxx', (logoUrl, username, message) => {
socket.broadcast.emit('message', logoUrl, username, message);
});
socket.on('disconnect', () => { });
socket.on('disconnect', () => {});
});
module.exports = { startVtuber, startChatBubble };

View file

@ -1,394 +1,478 @@
let resourcesPath = path.join(__dirname, '../config/settings.ini');
let settings = ini.parse(fs.readFileSync(resourcesPath, 'utf-8'));
if (envInfo.env) {
resourcesPath = path.join(envInfo.path, './settings.ini');
settings = ini.parse(fs.readFileSync(resourcesPath, 'utf-8'));
}
document.body.querySelector('#primaryVoice').addEventListener('change', () => {
var select = document.querySelector("#primaryVoice");
settings.TTS.PRIMARY_TTS_VOICE = select.selectedIndex;
settings.TTS.PRIMARY_TTS_NAME = select.options[select.selectedIndex].text;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
var select = document.querySelector('#primaryVoice');
settings.TTS.PRIMARY_TTS_VOICE = select.selectedIndex;
settings.TTS.PRIMARY_TTS_NAME = select.options[select.selectedIndex].text;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved primary voice!', 'success');
});
document.body.querySelector('#primaryLanguage').addEventListener('change', () => {
var select = document.querySelector("#primaryLanguage");
settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
settings.TTS.PRIMARY_TTS_LANGUAGE = select.options[select.selectedIndex].text;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
var select = document.querySelector('#primaryLanguage');
settings.TTS.PRIMARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
settings.TTS.PRIMARY_TTS_LANGUAGE = select.options[select.selectedIndex].text;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved primary language!', 'success');
});
document.body.querySelector('#secondaryVoice').addEventListener('change', () => {
var select = document.querySelector("#secondaryVoice");
settings.TTS.SECONDARY_TTS_VOICE = select.selectedIndex;
settings.TTS.SECONDARY_TTS_NAME = select.options[select.selectedIndex].text;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
var select = document.querySelector('#secondaryVoice');
settings.TTS.SECONDARY_TTS_VOICE = select.selectedIndex;
settings.TTS.SECONDARY_TTS_NAME = select.options[select.selectedIndex].text;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved secondary voice!', 'success');
});
document.body.querySelector('#secondaryLanguage').addEventListener('change', () => {
var select = document.querySelector("#secondaryLanguage");
settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
settings.TTS.SECONDARY_TTS_LANGUAGE = select.options[select.selectedIndex].text;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
var select = document.querySelector('#secondaryLanguage');
settings.TTS.SECONDARY_TTS_LANGUAGE_INDEX = select.selectedIndex;
settings.TTS.SECONDARY_TTS_LANGUAGE = select.options[select.selectedIndex].text;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved secondary language!', 'success');
});
document.body.querySelector('#ttsAudioDevice').addEventListener('change', () => {
settings.AUDIO.TTS_AUDIO_DEVICE = ttsAudioDevices.value;
settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE = ttsAudioDevices.selectedIndex;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
settings.AUDIO.TTS_AUDIO_DEVICE = ttsAudioDevices.value;
settings.AUDIO.SELECTED_TTS_AUDIO_DEVICE = ttsAudioDevices.selectedIndex;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved audio device!', 'success');
});
document.body.querySelector('#TWITCH_CHANNEL_NAME').addEventListener('change', () => {
settings.TWITCH.CHANNEL_NAME = document.body.querySelector('#TWITCH_CHANNEL_NAME').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
});
settings.TWITCH.CHANNEL_NAME = document.body.querySelector('#TWITCH_CHANNEL_NAME').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
document.body.querySelector('#TWITCH_USERNAME').addEventListener('change', () => {
settings.TWITCH.USERNAME = document.body.querySelector('#TWITCH_USERNAME').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
let button = document.body.querySelector('#TestTwitchCredentials');
button.className = 'AdvancedMenuButton';
createNotification('Saved Channel name, please restart the application to reset twitch service', 'warning');
});
document.body.querySelector('#TWITCH_OAUTH_TOKEN').addEventListener('change', () => {
settings.TWITCH.OAUTH_TOKEN = document.body.querySelector('#TWITCH_OAUTH_TOKEN').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
});
settings.TWITCH.OAUTH_TOKEN = document.body.querySelector('#TWITCH_OAUTH_TOKEN').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved OAuth token!', 'success');
document.body.querySelector('#TWITCH_CLIENT_ID').addEventListener('change', () => {
settings.TWITCH.CLIENT_ID = document.body.querySelector('#TWITCH_CLIENT_ID').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
});
document.body.querySelector('#TWITCH_CLIENT_SECRET').addEventListener('change', () => {
settings.TWITCH.CLIENT_SECRET = document.body.querySelector('#TWITCH_CLIENT_SECRET').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
let button = document.body.querySelector('#TestTwitchCredentials');
button.className = 'AdvancedMenuButton';
createNotification('Saved OAuth token, please restart the application to reset twitch service', 'warning');
});
document.body.querySelector('#PORT').addEventListener('change', () => {
settings.SERVER.PORT = document.body.querySelector('#PORT').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
settings.SERVER.PORT = document.body.querySelector('#PORT').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved port, please restart the application to reset the port', 'warning');
});
document.body.querySelector('#AMAZON_ACCESS_KEY').addEventListener('change', () => {
settings.AMAZON.ACCESS_KEY = document.body.querySelector('#AMAZON_ACCESS_KEY').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
settings.AMAZON.ACCESS_KEY = document.body.querySelector('#AMAZON_ACCESS_KEY').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved Amazon access key!', 'success');
});
document.body.querySelector('#AMAZON_ACCESS_SECRET').addEventListener('change', () => {
settings.AMAZON.ACCESS_SECRET = document.body.querySelector('#AMAZON_ACCESS_SECRET').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
settings.AMAZON.ACCESS_SECRET = document.body.querySelector('#AMAZON_ACCESS_SECRET').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved Amazon access secret!', 'success');
});
document.body.querySelector('#GOOGLE_API_KEY').addEventListener('change', () => {
settings.GOOGLE.API_KEY = document.body.querySelector('#GOOGLE_API_KEY').value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
settings.GOOGLE.API_KEY = document.body.querySelector('#GOOGLE_API_KEY').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved Google api key!', 'success');
});
// document.body.querySelector('#sliderX').addEventListener('change', () => {
// // TODO: resolve volume control of TTS
// config.SETTINGS.VOICE_VOLUME;
// fs.writeFileSync(path.join(__dirname, '/public/config/settings.ini'), ini.stringify(config));
// });
// #region Test/change/Save Configuration
document.body.querySelector('#notification').addEventListener('change', () => {
settings.AUDIO.NOTIFICATION_SOUND = notificationSound.selectedIndex;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
settings.AUDIO.NOTIFICATION_SOUND = notificationSound.selectedIndex;
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved notification sound!', 'success');
});
// document.body.querySelector('#slider').addEventListener('change', () => {
// settings.SETTINGS.NOTIFICATION_VOLUME = parseInt(document.getElementById('SoundVolume').
// innerText);
// fs.writeFileSync(path.join(__dirname, '/public/config/settings.ini'), ini.stringify(settings));
// });
function getGeneralSettings() {
// Theme
document.querySelector('#USE_CUSTOM_THEME').value = settings.THEME.USE_CUSTOM_THEME;
const USE_CUSTOM_THEME = settings.THEME.USE_CUSTOM_THEME;
// Theme
document.querySelector('#USE_CUSTOM_THEME').value = settings.THEME.USE_CUSTOM_THEME;
document.body.querySelector('#USE_CUSTOM_THEME').checked = settings.THEME.USE_CUSTOM_THEME === true ? 1 : 0;
theme.setTheme();
document.body.querySelector('#USE_CUSTOM_THEME').checked = settings.THEME.USE_CUSTOM_THEME === true ? 1 : 0;
theme.setTheme(USE_CUSTOM_THEME);
// TTS
document.body.querySelector('#USE_TTS').checked = settings.TTS.USE_TTS;
// Twitch
document.body.querySelector('#USE_TWITCH').checked = settings.TWITCH.USE_TWITCH;
document.body.querySelector('#TWITCH_CHANNEL_NAME').value = settings.TWITCH.CHANNEL_NAME;
document.body.querySelector('#TWITCH_USERNAME').value = settings.TWITCH.USERNAME;
document.body.querySelector('#TWITCH_OAUTH_TOKEN').value = settings.TWITCH.OAUTH_TOKEN;
document.body.querySelector('#TWITCH_CLIENT_ID').value = settings.TWITCH.CLIENT_ID;
document.body.querySelector('#TWITCH_CLIENT_SECRET').value = settings.TWITCH.CLIENT_SECRET;
// Notification sounds
document.body.querySelector('#USE_NOTIFICATION_SOUNDS').checked = settings.AUDIO.USE_NOTIFICATION_SOUNDS;
// Server
document.body.querySelector('#USE_SERVER').checked = settings.SERVER.USE_SERVER;
document.body.querySelector('#PORT').value = settings.SERVER.PORT;
document.body.querySelector('#USE_VTUBER').checked = settings.SERVER.USE_VTUBER;
showMenuButton("#btnBrowsersourceVtuber", settings.SERVER.USE_VTUBER)
document.body.querySelector('#USE_CHATBUBBLE').checked = settings.SERVER.USE_CHATBUBBLE;
showMenuButton("#btnBrowsersourceChat", settings.SERVER.USE_CHATBUBBLE)
// Twitch
document.body.querySelector('#USE_TWITCH').checked = settings.TWITCH.USE_TWITCH;
document.body.querySelector('#TWITCH_CHANNEL_NAME').value = settings.TWITCH.CHANNEL_NAME;
document.body.querySelector('#TWITCH_OAUTH_TOKEN').value = settings.TWITCH.OAUTH_TOKEN;
// Amazon
document.body.querySelector('#USE_AMAZON').checked = settings.AMAZON.USE_AMAZON;
document.body.querySelector('#AMAZON_ACCESS_KEY').value = settings.AMAZON.ACCESS_KEY;
document.body.querySelector('#AMAZON_ACCESS_SECRET').value = settings.AMAZON.ACCESS_SECRET;
// Server
document.body.querySelector('#USE_SERVER').checked = settings.SERVER.USE_SERVER;
document.body.querySelector('#PORT').value = settings.SERVER.PORT;
document.body.querySelector('#USE_VTUBER').checked = settings.SERVER.USE_VTUBER;
document.body.querySelector('#VTUBER_URL').value = `http://localhost:${settings.SERVER.PORT}/vtuber/`;
showMenuButton('#btnBrowsersourceVtuber', settings.SERVER.USE_VTUBER);
document.body.querySelector('#USE_CHATBUBBLE').checked = settings.SERVER.USE_CHATBUBBLE;
document.body.querySelector('#CHATBUBBLE_URL').value = `http://localhost:${settings.SERVER.PORT}/chat/`;
showMenuButton('#btnBrowsersourceChat', settings.SERVER.USE_CHATBUBBLE);
// Google
document.body.querySelector('#USE_GOOGLE').checked = settings.GOOGLE.USE_GOOGLE;
document.body.querySelector('#GOOGLE_API_KEY').value = settings.GOOGLE.API_KEY;
// Amazon
document.body.querySelector('#USE_AMAZON').checked = settings.AMAZON.USE_AMAZON;
document.body.querySelector('#AMAZON_ACCESS_KEY').value = settings.AMAZON.ACCESS_KEY;
document.body.querySelector('#AMAZON_ACCESS_SECRET').value = settings.AMAZON.ACCESS_SECRET;
// Google
document.body.querySelector('#USE_GOOGLE').checked = settings.GOOGLE.USE_GOOGLE;
document.body.querySelector('#GOOGLE_API_KEY').value = settings.GOOGLE.API_KEY;
}
function showMenuButton(menuButton, toggle) {
let option = document.body.querySelector(menuButton);
if (!toggle) {
option.style.display = "none";
} else {
option.style.display = "";
}
let option = document.body.querySelector(menuButton);
if (!toggle) {
option.style.display = 'none';
} else {
option.style.display = '';
}
}
const notificationToasts = document.querySelector('#toasts'); // toast messages
function createNotification(message = null, type = null) {
const notification = document.createElement('div');
notification.classList.add('toast');
notification.classList.add(type);
notification.innerText = message;
notificationToasts.appendChild(notification);
let notfication = undefined;
const notification = document.createElement('div');
notification.classList.add('toast');
notification.classList.add(type);
notification.innerText = message;
notificationToasts.appendChild(notification);
let alertSound = "info.mp3";
if (type === "error") {
alertSound = "error.mp3";
}
let alertSound = 'info.mp3';
if (type === 'error') {
alertSound = 'error.mp3';
}
if (envInfo.env) {
notfication = new Audio(path.join(envInfo.path, `./sounds/notifications/${alertSound}`));
} else {
notfication = new Audio(path.join(__dirname, `../sounds/notifications/${alertSound}`));
}
notfication.play();
setTimeout(() => notification.remove(), 10000);
let notfication = new Audio(path.join(resourcesPath, `./sounds/notifications/${alertSound}`));
notfication.volume = settings.AUDIO.NOTIFICATION_VOLUME / 100;
notfication.play();
setTimeout(() => notification.remove(), 10000);
}
// Check for configs
if (!settings.TWITCH.USE_TWITCH) {
const text = 'Please setup a service to connect to in Configuration > Show Advanced';
createNotification(text, 'warning');
const text = 'Please setup a service to connect to in Configuration > Show Advanced';
createNotification(text, 'warning');
}
if (settings.TWITCH.USE_TWITCH && !settings.TWITCH.CHANNEL_NAME) {
const text = 'No channel name inserted in the Twitch service';
createNotification(text, 'alert');
const text = 'No channel name inserted in the Twitch service';
createNotification(text, 'warning');
}
if (settings.TWITCH.USE_TWITCH && !settings.TWITCH.USERNAME) {
const text = 'No username inserted in the Twitch service';
createNotification(text, 'alert');
const text = 'No username inserted in the Twitch service';
createNotification(text, 'warning');
}
function toggleRadio(toggle, inputs) {
const element = inputs;
if (toggle === true) {
for (let i = 0; i < inputs.length; i += 1) { element[i].disabled = false; }
} else {
for (let i = 0; i < inputs.length; i += 1) { element[i].disabled = true; }
}
}
function setCustomThemeToggle() {
const toggle = document.getElementById('USE_CUSTOM_THEME').checked;
const inputs = document.getElementsByClassName('inputTheme');
toggleRadio(toggle, inputs);
theme.setTheme(toggle);
const element = inputs;
if (toggle === true) {
for (let i = 0; i < inputs.length; i += 1) {
element[i].style.display = '';
}
} else {
for (let i = 0; i < inputs.length; i += 1) {
element[i].style.display = 'none';
}
}
}
// #region Use Custom theme toggle logic
document.body.querySelector('#USE_CUSTOM_THEME').addEventListener('click', () => {
setCustomThemeToggle();
const toggle = document.getElementById('USE_CUSTOM_THEME').checked;
const inputs = document.getElementsByClassName('inputTheme');
toggleRadio(toggle, inputs);
const toggle = document.getElementById('USE_CUSTOM_THEME').checked;
settings.THEME.USE_CUSTOM_THEME = toggle;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
settings.THEME.USE_CUSTOM_THEME = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
theme.setTheme();
createNotification(`${toggle ? 'Enabled' : 'Disabled'} custom theme!`, 'success');
});
// #region Top bar buttons
document.body.querySelector('#min-button').addEventListener('click', () => {
ipcRenderer.send('minimize-window');
ipcRenderer.send('minimize-window');
});
// #region Top bar buttons
document.body.querySelector('#Info_USERNAME').addEventListener('click', () => {
const key = ipcRenderer.sendSync('twitch');
let element = document.body.querySelector('#TWITCH_OAUTH_TOKEN');
element.value = key;
});
document.body.querySelector('#Info_VTUBER').addEventListener('click', () => {
ipcRenderer.send('vtuber');
});
document.body.querySelector('#Info_CHATBUBBLE').addEventListener('click', () => {
ipcRenderer.send('chatBubble');
});
document.body.querySelector('#max-button').addEventListener('click', () => {
ipcRenderer.send('maximize-window');
ipcRenderer.send('maximize-window');
});
document.body.querySelector('#close-button').addEventListener('click', (event) => {
ipcRenderer.send('close-window');
ipcRenderer.send('close-window');
});
// #endregion
// #region Notification sound test
document.body.querySelector('#SoundTestButton').addEventListener('click', () => {
sound.playAudio();
sound.playAudio();
});
document.body.querySelector('#TestTwitchCredentials').addEventListener('click', () => {
twitch.ping('#TestTwitchCredentials');
// resetTwitch(;
});
function toggleTwitch() {
const toggle = settings.TWITCH.USE_TWITCH;
const inputs = document.getElementsByClassName('inputTwitch');
toggleRadio(toggle, inputs);
const toggle = settings.TWITCH.USE_TWITCH;
const inputs = document.getElementsByClassName('inputTwitch');
toggleRadio(toggle, inputs);
}
document.body.querySelector('#USE_TWITCH').addEventListener('click', () => {
const toggle = document.getElementById('USE_TWITCH').checked;
settings.TWITCH.USE_TWITCH = toggle;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputTwitch');
toggleRadio(toggle, inputs);
});
toggleTwitch();
function toggleGoogle() {
const toggle = settings.GOOGLE.USE_GOOGLE;
const inputs = document.getElementsByClassName('inputGoogle');
toggleRadio(toggle, inputs);
}
document.body.querySelector('#USE_GOOGLE').addEventListener('click', () => {
const toggle = document.getElementById('USE_GOOGLE').checked;
settings.GOOGLE.USE_GOOGLE = toggle;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputGoogle');
toggleRadio(toggle, inputs);
document.body.querySelector('#USE_TWITCH').addEventListener('click', () => {
const toggle = document.getElementById('USE_TWITCH').checked;
settings.TWITCH.USE_TWITCH = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputTwitch');
toggleRadio(toggle, inputs);
twitch = settings.TWITCH.USE_TWITCH ? require(path.join(resourcesPath, './js/twitch')) : null;
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Twitch settings!`, 'success');
});
function toggleGoogle() {
const toggle = settings.GOOGLE.USE_GOOGLE;
const inputs = document.getElementsByClassName('inputGoogle');
toggleRadio(toggle, inputs);
}
toggleGoogle();
function toggleAmazon() {
const toggle = settings.AMAZON.USE_AMAZON;
const inputs = document.getElementsByClassName('inputAmazon');
toggleRadio(toggle, inputs);
}
document.body.querySelector('#USE_AMAZON').addEventListener('click', () => {
const toggle = document.getElementById('USE_AMAZON').checked;
settings.AMAZON.USE_AMAZON = toggle;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputAmazon');
toggleRadio(toggle, inputs);
document.body.querySelector('#USE_GOOGLE').addEventListener('click', () => {
const toggle = document.getElementById('USE_GOOGLE').checked;
settings.GOOGLE.USE_GOOGLE = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputGoogle');
toggleRadio(toggle, inputs);
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Google settings!`, 'success');
});
function toggleAmazon() {
const toggle = settings.AMAZON.USE_AMAZON;
const inputs = document.getElementsByClassName('inputAmazon');
toggleRadio(toggle, inputs);
}
toggleAmazon();
function toggleServer() {
const toggle = settings.SERVER.USE_SERVER;
const inputs = document.getElementsByClassName('inputServer');
toggleRadio(toggle, inputs);
}
document.body.querySelector('#USE_SERVER').addEventListener('click', () => {
const toggle = document.getElementById('USE_SERVER').checked;
settings.SERVER.USE_SERVER = toggle;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputServer');
toggleRadio(toggle, inputs);
document.body.querySelector('#USE_AMAZON').addEventListener('click', () => {
const toggle = document.getElementById('USE_AMAZON').checked;
settings.AMAZON.USE_AMAZON = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputAmazon');
toggleRadio(toggle, inputs);
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Amazon settings!`, 'success');
});
function toggleServer() {
const toggle = settings.SERVER.USE_SERVER;
const inputs = document.getElementsByClassName('inputServer');
toggleRadio(toggle, inputs);
}
toggleServer();
document.body.querySelector('#USE_SERVER').addEventListener('click', () => {
const toggle = document.getElementById('USE_SERVER').checked;
settings.SERVER.USE_SERVER = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputServer');
toggleRadio(toggle, inputs);
setServer();
createNotification(
`${toggle ? 'Enabled' : 'Disabled'} server settings!, the service will stop working after restarting the application`,
'success',
);
});
document.body.querySelector('#USE_VTUBER').addEventListener('change', () => {
const toggle = document.getElementById('USE_VTUBER').checked;
settings.SERVER.USE_VTUBER = toggle;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
showMenuButton("#btnBrowsersourceVtuber", toggle);
const toggle = document.getElementById('USE_VTUBER').checked;
settings.SERVER.USE_VTUBER = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
showMenuButton('#btnBrowsersourceVtuber', toggle);
createNotification(
`${toggle ? 'Enabled' : 'Disabled'} Vtuber setting!, the service will stop working after restarting the application`,
'success',
);
server.startVtuber();
});
document.body.querySelector('#USE_CHATBUBBLE').addEventListener('change', () => {
const toggle = document.getElementById('USE_CHATBUBBLE').checked;
settings.SERVER.USE_CHATBUBBLE = toggle;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
showMenuButton("#btnBrowsersourceChat", toggle);
const toggle = document.getElementById('USE_CHATBUBBLE').checked;
settings.SERVER.USE_CHATBUBBLE = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
showMenuButton('#btnBrowsersourceChat', toggle);
createNotification(`${toggle ? 'Enabled' : 'Disabled'} chatbubble setting!`, 'success');
server.startChatBubble();
});
// Get the selected TTS
const currentlySelectedTTS = ttsSelector.querySelector(`#${settings.TTS.SELECTED_TTS}`);
if (currentlySelectedTTS) {
currentlySelectedTTS.checked = true;
// Dispatch the event to initialize logic.
currentlySelectedTTS.dispatchEvent(new Event('change'));
function toggleTTS() {
const toggle = settings.TTS.USE_TTS;
const inputs = document.getElementsByClassName('inputTTS');
toggleRadio(toggle, inputs);
}
document.body.querySelector('#notificationVolumeSlider').addEventListener('change', () => {
const e = document.querySelector('#notificationVolumeSlider');
e.style.setProperty('--tiempotemporal', e.value);
e.style.setProperty('--min', e.min === '' ? '0' : e.min);
e.style.setProperty('--max', e.max === '' ? '100' : e.max);
document.querySelector('#notificationVolume').value = e.value;
toggleTTS();
e.addEventListener('input', () => {
e.style.setProperty('--tiempotemporal', e.value);
document.querySelector('#notificationVolume').value = e.value;
settings.AUDIO.NOTIFICATION_VOLUME = e.value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
});
document.body.querySelector('#USE_TTS').addEventListener('change', () => {
const toggle = document.getElementById('USE_TTS').checked;
settings.TTS.USE_TTS = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputTTS');
toggleRadio(toggle, inputs);
createNotification(`${toggle ? 'Enabled' : 'Disabled'} text to speech!`, 'success');
});
function toggleNotificationSounds() {
const toggle = settings.AUDIO.USE_NOTIFICATION_SOUNDS;
const inputs = document.getElementsByClassName('inputNotificationSound');
toggleRadio(toggle, inputs);
}
toggleNotificationSounds();
document.body.querySelector('#USE_NOTIFICATION_SOUNDS').addEventListener('change', () => {
const toggle = document.getElementById('USE_NOTIFICATION_SOUNDS').checked;
settings.AUDIO.USE_NOTIFICATION_SOUNDS = toggle;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const inputs = document.getElementsByClassName('inputNotificationSound');
toggleRadio(toggle, inputs);
createNotification(`${toggle ? 'Enabled' : 'Disabled'} notification sounds!`, 'success');
});
document.body.querySelector('#notificationVolume').addEventListener('change', () => {
let element = document.body.querySelector('#notificationVolume');
settings.AUDIO.NOTIFICATION_VOLUME = element.value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const slider = document.querySelector('#notificationVolumeSlider');
slider.value = settings.AUDIO.NOTIFICATION_VOLUME;
slider.style.setProperty('--tiempotemporal', settings.AUDIO.NOTIFICATION_VOLUME);
createNotification('Saved notification volume!', 'success');
});
document.body.querySelector('#notificationVolumeSlider').addEventListener('change', () => {
const e = document.querySelector('#notificationVolumeSlider');
e.style.setProperty('--tiempotemporal', e.value);
e.style.setProperty('--min', e.min === '' ? '0' : e.min);
e.style.setProperty('--max', e.max === '' ? '100' : e.max);
document.querySelector('#notificationVolume').value = e.value;
e.addEventListener('input', () => {
e.style.setProperty('--tiempotemporal', e.value);
document.querySelector('#notificationVolume').value = e.value;
settings.AUDIO.NOTIFICATION_VOLUME = e.value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
});
});
document.body.querySelector('#notificationVolumeSlider').addEventListener('mouseup', () => {
createNotification('Saved notification volume!', 'success');
});
if (settings.AUDIO.NOTIFICATION_VOLUME) {
document.querySelector('#notificationVolumeSlider').value = settings.AUDIO.NOTIFICATION_VOLUME;
document.querySelector('#notificationVolumeSlider').dispatchEvent(new Event('change'));
document.querySelector('#notificationVolumeSlider').value = settings.AUDIO.NOTIFICATION_VOLUME;
document.querySelector('#notificationVolumeSlider').dispatchEvent(new Event('change'));
} else {
document.querySelector('#notificationVolumeSlider').dispatchEvent(new Event('change', { value: 50 }));
document.querySelector('#notificationVolumeSlider').dispatchEvent(new Event('change', { value: 50 }));
}
document.body.querySelector('#ttsVolumeSlider').addEventListener('change', () => {
const e = document.querySelector('#ttsVolumeSlider');
e.style.setProperty('--tiempotemporal', e.value);
e.style.setProperty('--min', e.min === '' ? '0' : e.min);
e.style.setProperty('--max', e.max === '' ? '100' : e.max);
document.querySelector('#ttsVolume').value = e.value;
document.body.querySelector('#ttsVolume').addEventListener('change', () => {
let element = document.body.querySelector('#ttsVolume');
settings.TTS.TTS_VOLUME = element.value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
e.addEventListener('input', () => {
e.style.setProperty('--tiempotemporal', e.value);
document.querySelector('#ttsVolume').value = e.value;
settings.AUDIO.TTS_VOLUME = e.value;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
});
const slider = document.querySelector('#ttsVolumeSlider');
slider.value = settings.TTS.TTS_VOLUME;
slider.style.setProperty('--tiempotemporal', settings.TTS.TTS_VOLUME);
createNotification('Saved TTS volume!', 'success');
});
if (settings.AUDIO.TTS_VOLUME) {
document.querySelector('#ttsVolumeSlider').value = settings.AUDIO.TTS_VOLUME;
document.querySelector('#ttsVolumeSlider').dispatchEvent(new Event('change'));
document.body.querySelector('#ttsVolumeSlider').addEventListener('change', () => {
const e = document.querySelector('#ttsVolumeSlider');
e.style.setProperty('--tiempotemporal', e.value);
e.style.setProperty('--min', e.min === '' ? '0' : e.min);
e.style.setProperty('--max', e.max === '' ? '100' : e.max);
document.querySelector('#ttsVolume').value = e.value;
e.addEventListener('input', () => {
e.style.setProperty('--tiempotemporal', e.value);
document.querySelector('#ttsVolume').value = e.value;
settings.TTS.TTS_VOLUME = e.value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
});
});
document.body.querySelector('#ttsVolumeSlider').addEventListener('mouseup', () => {
createNotification('Saved TTS volume!', 'success');
});
if (settings.TTS.TTS_VOLUME) {
document.querySelector('#ttsVolumeSlider').value = settings.TTS.TTS_VOLUME;
document.querySelector('#ttsVolumeSlider').dispatchEvent(new Event('change'));
} else {
document.querySelector('#ttsVolumeSlider').dispatchEvent(new Event('change', { value: 50 }));
document.querySelector('#ttsVolumeSlider').dispatchEvent(new Event('change', { value: 50 }));
}
document.body.querySelector('#ttsVolume').addEventListener('change', () => {
let element = document.body.querySelector('#ttsVolume');
settings.TTS.TTS_VOLUME = element.value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
const slider = document.querySelector('#ttsVolumeSlider');
slider.value = settings.TTS.TTS_VOLUME;
slider.style.setProperty('--tiempotemporal', settings.TTS.TTS_VOLUME);
});
document.body.querySelector('.language-selector').addEventListener('click', () => {
var dropdown = document.body.querySelector('.language-dropdown');
dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block';
var dropdown = document.body.querySelector('.language-dropdown');
dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block';
});
document.body.querySelector('.language-dropdown').addEventListener('mouseleave', () => {
hideDropdown();
hideDropdown();
});
let languageSelector = document.querySelectorAll(".language-item");
languageSelector.forEach(item => {
item.addEventListener('click', (event) => {
const el = event.target;
// tip.innerText = el.getAttribute('language');
document.getElementById('selected-language').innerText = el.getAttribute('language');
document.getElementById('selected-flag').innerText = el.getAttribute('flag');
hideDropdown();
});
let languageSelector = document.querySelectorAll('.language-item');
languageSelector.forEach((item) => {
item.addEventListener('click', (event) => {
const el = event.target;
// tip.innerText = el.getAttribute('language');
document.getElementById('selected-language').innerText = el.getAttribute('language');
document.getElementById('selected-flag').innerText = el.getAttribute('flag');
hideDropdown();
});
});
function hideDropdown() {
var dropdown = document.body.querySelector('.language-dropdown');
dropdown.style.display = 'none';
var dropdown = document.body.querySelector('.language-dropdown');
dropdown.style.display = 'none';
}
// let primaryTTSSelector = document.body.querySelector(".optgroup");
// primaryTTSSelector.forEach(item => {
// item.addEventListener('hover', (event) => {
@ -398,10 +482,6 @@ function hideDropdown() {
// });
// });
module.exports = {
ini,
settings,
getGeneralSettings,
setCustomThemeToggle
getGeneralSettings,
};

View file

@ -4,26 +4,33 @@ let currentUsername = '';
let voiceSoundArray = [];
let status = 0;
const playTTS = (ttsData) => new Promise((resolve) => {
const tts = new Audio(ttsData.path);
const playTTS = (ttsData) =>
new Promise((resolve) => {
const tts = new Audio(ttsData.path);
tts.addEventListener('ended', () => {
fs.unlink(ttsData.path, (err) => {
if (err) {
console.error(err);
return;
}
resolve('finished');
tts.addEventListener('ended', () => {
fs.unlink(ttsData.path, (err) => {
if (err) {
console.error(err);
return;
}
resolve('finished');
});
});
});
tts.setSinkId(config.settings.AUDIO.TTS_AUDIO_DEVICE).then(() => {
tts.play();
socket.emit('xxx', currentLogoUrl, currentUsername, ttsData.message);
}).catch((error) => {
console.error('Failed to set audio output device:', error);
tts.setSinkId(settings.AUDIO.TTS_AUDIO_DEVICE)
.then(() => {
tts.volume = settings.TTS.TTS_VOLUME / 100;
tts.play();
if (settings.SERVER.USE_SERVER) {
socket.emit('xxx', currentLogoUrl, currentUsername, ttsData.message);
}
})
.catch((error) => {
console.error('Failed to set audio output device:', error);
});
});
});
async function shiftVoice() {
status = 1;
@ -41,18 +48,19 @@ function add(ttsData) {
}
// Play sound function
function playAudio(ttsData = undefined) {
let audioPath;
if (!ttsData) {
let notfication = undefined;
if (envInfo.env) {
notfication = new Audio(path.join(envInfo.path, `./sounds/notifications/${notificationSound.options[config.settings.AUDIO.NOTIFICATION_SOUND].text}`));
} else {
notfication = new Audio(path.join(__dirname, `../sounds/notifications/${notificationSound.options[config.settings.AUDIO.NOTIFICATION_SOUND].text}`));
}
function playAudio(data) {
if (settings.AUDIO.USE_NOTIFICATION_SOUNDS) {
let notfication = new Audio(
path.join(resourcesPath, `../src/sounds/notifications/${notificationSound.options[settings.AUDIO.NOTIFICATION_SOUND].text}`),
);
notfication.volume = settings.AUDIO.NOTIFICATION_VOLUME / 100;
notfication.play();
} else {
add(ttsData);
}
if (settings.TTS.USE_TTS) {
add(data);
} else if (settings.SERVER.USE_SERVER) {
socket.emit('xxx', currentLogoUrl, currentUsername, data);
}
}
@ -60,19 +68,26 @@ function playVoice(filteredMessage, logoUrl, username, message) {
trueMessage = filteredMessage;
currentLogoUrl = logoUrl;
currentUsername = username;
let textObject = { "filtered": filteredMessage, "formatted": message };
let textObject = { filtered: filteredMessage, formatted: message };
let voice;
const language = langdetect.detect(filteredMessage);
if (language[0].lang === config.settings.TTS.SECONDARY_TTS_LANGUAGE.toLowerCase()) {
voice = config.settings.TTS.SECONDARY_TTS_NAME;
if (
settings.TTS.PRIMARY_TTS_LANGUAGE.toLowerCase() !== settings.TTS.SECONDARY_TTS_LANGUAGE.toLowerCase() ||
language[0].lang === settings.TTS.SECONDARY_TTS_LANGUAGE.toLowerCase()
) {
voice = settings.TTS.SECONDARY_TTS_NAME;
textObject.filtered = `${username}: ${filteredMessage}`;
} else {
voice = config.settings.TTS.PRIMARY_TTS_NAME;
voice = settings.TTS.PRIMARY_TTS_NAME;
textObject.filtered = `${username}: ${filteredMessage}`;
}
talk.add(textObject, voice);
if (settings.TTS.USE_TTS) {
talk.add(textObject, voice);
} else {
playAudio(textObject);
}
}
module.exports = { playAudio, playVoice };

View file

@ -1,89 +1,49 @@
function setTheme(USE_CUSTOM_THEME) {
document.querySelector('#MAIN_COLOR_1').value = config.settings.THEME.MAIN_COLOR_1;
const MAIN_COLOR_1 = document.querySelector('#MAIN_COLOR_1').value;
root.style.setProperty('--main-color1-temp', MAIN_COLOR_1);
document.querySelector('#MAIN_COLOR_2').value = config.settings.THEME.MAIN_COLOR_2;
const MAIN_COLOR_2 = document.querySelector('#MAIN_COLOR_2').value;
root.style.setProperty('--main-color2-temp', MAIN_COLOR_2);
document.querySelector('#MAIN_COLOR_3').value = config.settings.THEME.MAIN_COLOR_3;
const MAIN_COLOR_3 = document.querySelector('#MAIN_COLOR_3').value;
root.style.setProperty('--main-color3-temp', MAIN_COLOR_3);
document.querySelector('#MAIN_COLOR_4').value = config.settings.THEME.MAIN_COLOR_4;
const MAIN_COLOR_4 = document.querySelector('#MAIN_COLOR_4').value;
root.style.setProperty('--main-color4-temp', MAIN_COLOR_4);
document.querySelector('#TOP_BAR').value = config.settings.THEME.TOP_BAR;
const TOP_BAR = document.querySelector('#TOP_BAR').value;
root.style.setProperty('--top-bar-temp', TOP_BAR);
document.querySelector('#MID_SECTION').value = config.settings.THEME.MID_SECTION;
const MID_SECTION = document.querySelector('#MID_SECTION').value;
root.style.setProperty('--mid-section-temp', MID_SECTION);
document.querySelector('#CHAT_BUBBLE_BG').value = config.settings.THEME.CHAT_BUBBLE_BG;
const CHAT_BUBBLE_BG = document.querySelector('#CHAT_BUBBLE_BG').value;
root.style.setProperty('--chat-bubble-temp', CHAT_BUBBLE_BG);
document.querySelector('#CHAT_BUBBLE_HEADER').value = config.settings.THEME.CHAT_BUBBLE_HEADER;
const CHAT_BUBBLE_HEADER = document.querySelector('#CHAT_BUBBLE_HEADER').value;
root.style.setProperty('--chat-bubble-header-temp', CHAT_BUBBLE_HEADER);
document.querySelector('#CHAT_BUBBLE_MESSAGE').value = config.settings.THEME.CHAT_BUBBLE_MESSAGE;
const CHAT_BUBBLE_MESSAGE = document.querySelector('#CHAT_BUBBLE_MESSAGE').value;
root.style.setProperty('--chat-bubble-message-temp', CHAT_BUBBLE_MESSAGE);
if (USE_CUSTOM_THEME) {
root.style.setProperty('--main-color1', MAIN_COLOR_1);
root.style.setProperty('--main-color2', MAIN_COLOR_2);
root.style.setProperty('--main-color3', MAIN_COLOR_3);
root.style.setProperty('--main-color4', MAIN_COLOR_4);
root.style.setProperty('--top-bar', TOP_BAR);
root.style.setProperty('--mid-section', MID_SECTION);
root.style.setProperty('--chat-bubble', CHAT_BUBBLE_BG);
root.style.setProperty('--chat-bubble-header', CHAT_BUBBLE_HEADER);
root.style.setProperty('--chat-bubble-message', CHAT_BUBBLE_MESSAGE);
} else {
root.style.setProperty('--main-color1', '#6e2c8c');
root.style.setProperty('--main-color2', 'white');
root.style.setProperty('--main-color3', '#211E1E');
root.style.setProperty('--main-color4', '#2f2c34');
root.style.setProperty('--top-bar', '#100B12');
root.style.setProperty('--mid-section', '#352d3d');
root.style.setProperty('--chat-bubble', ' #7A6D7F');
root.style.setProperty('--chat-bubble-header', '#141414');
root.style.setProperty('--chat-bubble-message', 'white');
}
function changeColor(section, setting, tempSection) {
document.querySelector(section).value = setting;
const value = document.querySelector(section).value;
root.style.setProperty(tempSection, value);
}
function setCurrentTheme(adjustTemp = false) {
changeColor("#MAIN_COLOR_1", settings.THEME.MAIN_COLOR_1, adjustTemp ? "--main-color1-temp" : "--main-color1");
changeColor("#MAIN_COLOR_2", settings.THEME.MAIN_COLOR_2, adjustTemp ? "--main-color2-temp" : "--main-color2");
changeColor("#MAIN_COLOR_3", settings.THEME.MAIN_COLOR_3, adjustTemp ? "--main-color3-temp" : "--main-color3");
changeColor("#MAIN_COLOR_4", settings.THEME.MAIN_COLOR_4, adjustTemp ? "--main-color4-temp" : "--main-color4");
changeColor("#TOP_BAR", settings.THEME.TOP_BAR, adjustTemp ? "--top-bar-temp" : "--top-bar");
changeColor("#MID_SECTION", settings.THEME.MID_SECTION, adjustTemp ? "--mid-section-temp" : "--mid-section");
changeColor("#CHAT_BUBBLE_BG", settings.THEME.CHAT_BUBBLE_BG, adjustTemp ? "--chat-bubble-temp" : "--chat-bubble");
changeColor("#CHAT_BUBBLE_HEADER", settings.THEME.CHAT_BUBBLE_HEADER, adjustTemp ? "--chat-bubble-header-temp" : "--chat-bubble-header");
changeColor("#CHAT_BUBBLE_MESSAGE", settings.THEME.CHAT_BUBBLE_MESSAGE, adjustTemp ? "--chat-bubble-message-temp" : "--chat-bubble-message");
}
setCurrentTheme(true);
function setTheme() {
if (settings.THEME.USE_CUSTOM_THEME) {
setCurrentTheme();
} else {
root.style.setProperty('--main-color1', '#6e2c8c');
root.style.setProperty('--main-color2', 'white');
root.style.setProperty('--main-color3', '#211E1E');
root.style.setProperty('--main-color4', '#2f2c34');
root.style.setProperty('--top-bar', '#100B12');
root.style.setProperty('--mid-section', '#352d3d');
root.style.setProperty('--chat-bubble', ' #7A6D7F');
root.style.setProperty('--chat-bubble-header', '#141414');
root.style.setProperty('--chat-bubble-message', 'white');
};
}
// #region Save Theme
document.body.querySelector('#MAIN_COLOR_1').addEventListener('input', () => {
const x = document.getElementById('MAIN_COLOR_1').value;
root.style.setProperty('--main-color1-temp', x);
console.log(x);
});
document.body.querySelector('#MAIN_COLOR_1').addEventListener('change', () => {
config.settings.THEME.MAIN_COLOR_1 = document.getElementById('MAIN_COLOR_1').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.MAIN_COLOR_1 = document.getElementById('MAIN_COLOR_1').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#MAIN_COLOR_1", settings.THEME.MAIN_COLOR_1, "--main-color1");
});
document.body.querySelector('#MAIN_COLOR_2').addEventListener('input', () => {
@ -92,9 +52,9 @@ document.body.querySelector('#MAIN_COLOR_2').addEventListener('input', () => {
});
document.body.querySelector('#MAIN_COLOR_2').addEventListener('change', () => {
config.settings.THEME.MAIN_COLOR_2 = document.getElementById('MAIN_COLOR_2').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.MAIN_COLOR_2 = document.getElementById('MAIN_COLOR_2').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#MAIN_COLOR_2", settings.THEME.MAIN_COLOR_2, "--main-color2");
});
document.body.querySelector('#MAIN_COLOR_3').addEventListener('input', () => {
@ -103,9 +63,9 @@ document.body.querySelector('#MAIN_COLOR_3').addEventListener('input', () => {
});
document.body.querySelector('#MAIN_COLOR_3').addEventListener('change', () => {
config.settings.THEME.MAIN_COLOR_3 = document.getElementById('MAIN_COLOR_3').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.MAIN_COLOR_3 = document.getElementById('MAIN_COLOR_3').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#MAIN_COLOR_3", settings.THEME.MAIN_COLOR_3, "--main-color3");
});
document.body.querySelector('#MAIN_COLOR_4').addEventListener('input', () => {
@ -114,9 +74,9 @@ document.body.querySelector('#MAIN_COLOR_4').addEventListener('input', () => {
});
document.body.querySelector('#MAIN_COLOR_4').addEventListener('change', () => {
config.settings.THEME.MAIN_COLOR_4 = document.getElementById('MAIN_COLOR_4').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.MAIN_COLOR_4 = document.getElementById('MAIN_COLOR_4').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#MAIN_COLOR_4", settings.THEME.MAIN_COLOR_4, "--main-color4");
});
document.body.querySelector('#TOP_BAR').addEventListener('input', () => {
@ -125,9 +85,9 @@ document.body.querySelector('#TOP_BAR').addEventListener('input', () => {
});
document.body.querySelector('#TOP_BAR').addEventListener('change', () => {
config.settings.THEME.TOP_BAR = document.getElementById('TOP_BAR').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.TOP_BAR = document.getElementById('TOP_BAR').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#TOP_BAR", settings.THEME.TOP_BAR, "--top-bar");
});
document.body.querySelector('#MID_SECTION').addEventListener('input', () => {
@ -136,9 +96,9 @@ document.body.querySelector('#MID_SECTION').addEventListener('input', () => {
});
document.body.querySelector('#MID_SECTION').addEventListener('change', () => {
config.settings.THEME.MID_SECTION = document.getElementById('MID_SECTION').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.MID_SECTION = document.getElementById('MID_SECTION').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#MID_SECTION", settings.THEME.MID_SECTION, "--mid-section");
});
document.body.querySelector('#CHAT_BUBBLE_BG').addEventListener('input', () => {
@ -147,9 +107,9 @@ document.body.querySelector('#CHAT_BUBBLE_BG').addEventListener('input', () => {
});
document.body.querySelector('#CHAT_BUBBLE_BG').addEventListener('change', () => {
config.settings.THEME.CHAT_BUBBLE_BG = document.getElementById('CHAT_BUBBLE_BG').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.CHAT_BUBBLE_BG = document.getElementById('CHAT_BUBBLE_BG').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#CHAT_BUBBLE_BG", settings.THEME.CHAT_BUBBLE_BG, "--chat-bubble");
});
document.body.querySelector('#CHAT_BUBBLE_HEADER').addEventListener('input', () => {
@ -158,9 +118,9 @@ document.body.querySelector('#CHAT_BUBBLE_HEADER').addEventListener('input', ()
});
document.body.querySelector('#CHAT_BUBBLE_HEADER').addEventListener('change', () => {
config.settings.THEME.CHAT_BUBBLE_HEADER = document.getElementById('CHAT_BUBBLE_HEADER').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.CHAT_BUBBLE_HEADER = document.getElementById('CHAT_BUBBLE_HEADER').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#CHAT_BUBBLE_HEADER", settings.THEME.CHAT_BUBBLE_HEADER, "--chat-bubble-header");
});
document.body.querySelector('#CHAT_BUBBLE_MESSAGE').addEventListener('input', () => {
@ -169,11 +129,9 @@ document.body.querySelector('#CHAT_BUBBLE_MESSAGE').addEventListener('input', ()
});
document.body.querySelector('#CHAT_BUBBLE_MESSAGE').addEventListener('change', () => {
config.settings.THEME.CHAT_BUBBLE_MESSAGE = document.getElementById('CHAT_BUBBLE_MESSAGE').value;
fs.writeFileSync(path.join(__dirname, '../config/settings.ini'), config.ini.stringify(config.settings));
setTheme(config.settings.THEME.USE_CUSTOM_THEME);
settings.THEME.CHAT_BUBBLE_MESSAGE = document.getElementById('CHAT_BUBBLE_MESSAGE').value;
fs.writeFileSync(settingsPath, ini.stringify(settings));
changeColor("#CHAT_BUBBLE_MESSAGE", settings.THEME.CHAT_BUBBLE_MESSAGE, "--chat-bubble-message");
});
// #endregion
module.exports = { setTheme };

View file

@ -1,146 +1,151 @@
const tmi = require('tmi.js');
const axios = require('axios');
const client = new tmi.Client({
options: {
skipUpdatingEmotesets: true,
},
identity: {
username: config.settings.TWITCH.USERNAME,
password: config.settings.TWITCH.OAUTH_TOKEN,
},
channels: [config.settings.TWITCH.CHANNEL_NAME],
});
let client;
function sendMessage(message) {
client.say(config.settings.TWITCH.CHANNEL_NAME, message).catch(console.error);
client.say(settings.TWITCH.CHANNEL_NAME, message).catch(console.error);
}
client.connect().catch(console.error);
client = new tmi.Client({
options: {
skipUpdatingEmotesets: true,
},
identity: {
username: settings.TWITCH.USERNAME,
password: settings.TWITCH.OAUTH_TOKEN,
},
channels: [settings.TWITCH.CHANNEL_NAME],
});
client
.connect()
.then((data) => {})
.catch(console.error);
function ping(element) {
let value = document.body.querySelector(element);
client
.ping()
.then((data) => {
console.log(client.readyState());
console.log(data);
value.classList.add('success');
value.innerText = 'Success!';
})
.catch((e) => {
console.log(e);
value.classList.add('error');
value.innerText = 'Failed!';
});
}
function displayTwitchMessage(logoUrl, username, messageObject, fileteredMessage) {
const article = document.createElement('article');
article.className = 'msg-container msg-remote';
const article = document.createElement('article');
article.className = 'msg-container msg-remote';
article.innerHTML = messageTemplates.twitchTemplate;
article.innerHTML = messageTemplates.twitchTemplate;
const userImg = article.querySelector('.icon-container > .user-img');
if (userImg) {
userImg.src = logoUrl;
}
const userImg = article.querySelector('.icon-container > .user-img');
if (userImg) {
userImg.src = logoUrl;
}
const usernameHtml = article.querySelector('.username');
if (usernameHtml) {
usernameHtml.innerText = username;
}
const usernameHtml = article.querySelector('.username');
if (usernameHtml) {
usernameHtml.innerText = username;
}
const postTime = article.querySelector('.post-time');
if (postTime) {
postTime.innerText = getPostTime();
}
const postTime = article.querySelector('.post-time');
if (postTime) {
postTime.innerText = getPostTime();
}
const msg = article.querySelector('.msg');
if (msg) {
msg.innerHTML = "";
const msg = article.querySelector('.msg');
if (msg) {
msg.innerHTML = '';
const messageElement = document.createElement("div");
const messageElement = document.createElement('div');
messageObject.forEach((entry) => {
const messageElement = document.createElement("div");
if (entry.text) {
messageElement.innerText = entry.text;
msg.appendChild(messageElement);
} else {
messageElement.innerHTML = entry.html;
msg.appendChild(messageElement);
}
})
}
messageObject.forEach((entry) => {
const messageElement = document.createElement('div');
if (entry.text) {
messageElement.innerText = entry.text;
msg.appendChild(messageElement);
} else {
messageElement.innerHTML = entry.html;
msg.appendChild(messageElement);
}
});
}
// Appends the message to the main chat box (shows the message)
showChatMessage(article);
// Appends the message to the main chat box (shows the message)
showChatMessage(article);
if (fileteredMessage) {
sound.playVoice(fileteredMessage, logoUrl, username, msg);
}
if (fileteredMessage) {
sound.playVoice(fileteredMessage, logoUrl, username, msg);
}
window.article = article;
window.article = article;
}
function getProfileImage(userid, username, message, fileteredMessage) {
// Get Access Token
let options = {
method: 'POST',
url: 'https://id.twitch.tv/oauth2/token',
data: {
grant_type: 'client_credentials',
client_Id: config.settings.TWITCH.CLIENT_ID,
client_Secret: config.settings.TWITCH.CLIENT_SECRET,
audience: 'YOUR_API_IDENTIFIER',
},
};
// Get user Logo with access token
options = {
method: 'GET',
url: `https://api.twitch.tv/helix/users?id=${userid}`,
headers: { 'Client-ID': settings.TWITCH.CLIENT_ID, Authorization: `Bearer ${settings.TWITCH.OAUTH_TOKEN}` },
};
axios.request(options).then((responseAccessToken) => {
const accessToken = responseAccessToken.data.access_token;
// Get user Logo with access token
options = {
method: 'GET',
url: `https://api.twitch.tv/helix/users?id=${userid}`,
headers: { 'Client-ID': config.settings.TWITCH.CLIENT_ID, Authorization: `Bearer ${accessToken}` },
};
axios.request(options).then((responseLogoUrl) => {
const logoUrl = responseLogoUrl.data.data[0].profile_image_url;
displayTwitchMessage(logoUrl, username, message, fileteredMessage);
}).catch((error) => {
console.error(error);
});
}).catch((error) => {
console.error(error);
});
axios
.request(options)
.then((responseLogoUrl) => {
const logoUrl = responseLogoUrl.data.data[0].profile_image_url;
displayTwitchMessage(logoUrl, username, message, fileteredMessage);
})
.catch((error) => {
console.error(error);
});
}
function parseString(inputString) {
const regex = /(<img.*?\/>)|([^<]+)/g;
const matches = inputString.match(regex) || [];
const result = [];
const regex = /(<img.*?\/>)|([^<]+)/g;
const matches = inputString.match(regex) || [];
const result = [];
for (let i = 0; i < matches.length; i++) {
const match = matches[i].trim();
if (match.startsWith("<img")) {
result.push({ html: match });
} if (match !== '' && !match.startsWith("<img")) {
result.push({ text: match });
}
}
return result;
for (let i = 0; i < matches.length; i++) {
const match = matches[i].trim();
if (match.startsWith('<img')) {
result.push({ html: match });
}
if (match !== '' && !match.startsWith('<img')) {
result.push({ text: match });
}
}
return result;
}
client.on('message', (channel, tags, message, self) => {
if (self) {
return;
}
if (self) {
return;
}
const emotes = tags.emotes || {};
const emoteValues = Object.entries(emotes);
let fileteredMessage = message;
let emoteMessage = message;
const emotes = tags.emotes || {};
const emoteValues = Object.entries(emotes);
let fileteredMessage = message;
let emoteMessage = message;
emoteValues.forEach((entry) => {
entry[1].forEach((lol) => {
const [start, end] = lol.split('-');
let emote = `<img src="https://static-cdn.jtvnw.net/emoticons/v2/${entry[0]}/default/dark/1.0"/>`;
emoteMessage = emoteMessage.replaceAll(message.slice(parseInt(start), parseInt(end) + 1), emote);
fileteredMessage = fileteredMessage.replaceAll(message.slice(parseInt(start), parseInt(end) + 1), '');
});
});
emoteValues.forEach((entry) => {
entry[1].forEach((lol) => {
const [start, end] = lol.split('-');
let emote = `<img src="https://static-cdn.jtvnw.net/emoticons/v2/${entry[0]}/default/dark/1.0"/>`;
emoteMessage = emoteMessage.replaceAll(message.slice(parseInt(start), parseInt(end) + 1), emote);
fileteredMessage = fileteredMessage.replaceAll(message.slice(parseInt(start), parseInt(end) + 1), '');
})
});
let messageObject = parseString(emoteMessage)
sound.playAudio();
getProfileImage(tags['user-id'], tags['display-name'], messageObject, fileteredMessage);
let messageObject = parseString(emoteMessage);
getProfileImage(tags['user-id'], tags['display-name'], messageObject, fileteredMessage);
});
module.exports = { sendMessage };
module.exports = { sendMessage, ping, client };

View file

@ -2,26 +2,21 @@ let SelectedVoice = '';
let Encoding = '';
let counter = 0;
// wrap in promise
const speak = (textObject) => new Promise((resolve) => {
// say.setEncoding(Encoding);
counter += 1;
let savePath = '';
const speak = (textObject) =>
new Promise((resolve) => {
// say.setEncoding(Encoding);
counter += 1;
let savePath = path.join(resourcesPath, '../src/sounds/tts/internal_audio_' + counter + '.mp3');
if (envInfo.env) {
savePath = path.join(envInfo.path, './sounds/tts/internal_audio_' + counter + '.mp3')
} else {
savePath = path.join(__dirname, '../sounds/tts/internal_audio_' + counter + '.mp3')
}
say.export(textObject.filtered, SelectedVoice, 1, savePath, (err) => {
if (err) {
console.error(err);
} else {
sound.playAudio({ "path": savePath, "message": textObject });
}
resolve('finished');
say.export(textObject.filtered, SelectedVoice, 1, savePath, (err) => {
if (err) {
console.error(err);
} else {
sound.playAudio({ path: savePath, message: textObject });
}
resolve('finished');
});
});
});
// queue system
class SayQueue {
@ -41,7 +36,9 @@ class SayQueue {
add(message, selectedVoice) {
this.messages.push(message);
SelectedVoice = selectedVoice;
if (this.status === 0) { this.shift(); }
if (this.status === 0) {
this.shift();
}
}
}

View file

@ -1,179 +1,273 @@
const { app, BrowserWindow, ipcMain } = require('electron');
const { writeIniFile } = require('write-ini-file')
const { app, shell, BrowserWindow, ipcMain } = require('electron');
const writeIniFile = require('write-ini-file');
const path = require('path');
const ini = require('ini');
const fs = require('fs');
let resourcesPath;
let settingsPath;
let settings;
let window;
if (app.isPackaged) {
resourcesPath = path.join(process.resourcesPath, './settings.ini');
resourcesPath = process.resourcesPath;
} else {
resourcesPath = path.join(__dirname, './config/settings.ini');
resourcesPath = __dirname;
}
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {
app.quit();
app.quit();
}
async function createWindow() {
if (!fs.existsSync(resourcesPath)) {
await createIniFile(resourcesPath);
} else {
settings = ini.parse(fs.readFileSync(resourcesPath, 'utf-8'));
}
if (!fs.existsSync(resourcesPath)) {
await createIniFile(path.join(resourcesPath, '../config/settings.ini'));
} else {
settingsPath = path.join(resourcesPath, './config/settings.ini');
settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8'));
}
window = new BrowserWindow({
icon: path.join(__dirname, '/images/icon.png'),
width: parseInt(settings.SETTINGS.WIDTH),
height: parseInt(settings.SETTINGS.HEIGHT),
x: parseInt(settings.SETTINGS.POSITION_X),
y: parseInt(settings.SETTINGS.POSITION_Y),
frame: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
},
});
window.loadURL('https://github.com')
window = new BrowserWindow({
icon: path.join(resourcesPath, '/images/icon.png'),
width: parseInt(settings.SETTINGS.WIDTH),
height: parseInt(settings.SETTINGS.HEIGHT),
x: parseInt(settings.SETTINGS.POSITION_X),
y: parseInt(settings.SETTINGS.POSITION_Y),
frame: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
},
});
window.loadURL('https://github.com');
window.loadFile(path.join(__dirname, 'index.html'));
window.loadFile(path.join(resourcesPath, 'index.html'));
if (!app.isPackaged) {
window.webContents.openDevTools();
}
if (!app.isPackaged) {
window.webContents.openDevTools();
}
window.on('close', e => {
settings = ini.parse(fs.readFileSync(resourcesPath, 'utf-8')); // load newest settings in case anything changed after starting the program
const bounds = window.getBounds();
window.on('close', (e) => {
settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8')); // load newest settings in case anything changed after starting the program
const bounds = window.getBounds();
settings.SETTINGS.WIDTH = bounds.width;
settings.SETTINGS.HEIGHT = bounds.height;
settings.SETTINGS.POSITION_X = bounds.x;
settings.SETTINGS.POSITION_Y = bounds.y;
settings.SETTINGS.WIDTH = bounds.width;
settings.SETTINGS.HEIGHT = bounds.height;
settings.SETTINGS.POSITION_X = bounds.x;
settings.SETTINGS.POSITION_Y = bounds.y;
fs.writeFileSync(resourcesPath, ini.stringify(settings));
})
};
fs.writeFileSync(settingsPath, ini.stringify(settings));
});
}
app.whenReady().then(() => {
createWindow();
})
createWindow();
});
app.on('window-all-closed', (event) => {
if (process.platform !== 'darwin') {
app.quit();
}
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
ipcMain.on('resize-window', (event, width, height) => {
const browserWindow = BrowserWindow.fromWebContents(event.sender);
browserWindow.setSize(width, height);
const browserWindow = BrowserWindow.fromWebContents(event.sender);
browserWindow.setSize(width, height);
});
ipcMain.on('minimize-window', (event) => {
const browserWindow = BrowserWindow.fromWebContents(event.sender);
browserWindow.minimize();
const browserWindow = BrowserWindow.fromWebContents(event.sender);
browserWindow.minimize();
});
ipcMain.on('maximize-window', (event) => {
const browserWindow = BrowserWindow.fromWebContents(event.sender);
const browserWindow = BrowserWindow.fromWebContents(event.sender);
if (!browserWindow.isMaximized()) {
browserWindow.maximize();
} else {
browserWindow.unmaximize();
}
if (!browserWindow.isMaximized()) {
browserWindow.maximize();
} else {
browserWindow.unmaximize();
}
});
ipcMain.on('close-window', (event) => {
const browserWindow = BrowserWindow.fromWebContents(event.sender);
browserWindow.close();
app.quit();
const browserWindow = BrowserWindow.fromWebContents(event.sender);
browserWindow.close();
app.quit();
});
ipcMain.on('restart', (event) => {
app.relaunch();
});
ipcMain.on('environment', (event) => {
event.returnValue = { "env": app.isPackaged, "path": process.resourcesPath };
event.returnValue = { resourcesPath: resourcesPath, settingsPath: settingsPath, settings: settings };
});
let twitchAuthentication = () =>
new Promise((resolve) => {
const http = require('http');
const redirectUri = 'http://localhost:1989/auth';
const scopes = ['chat:edit', 'chat:read'];
const express = require('express');
let tempAuthServer = express();
const port = 1989;
const { parse: parseQueryString } = require('querystring');
tempAuthServer.use(function (req, res, next) {
if (req.url !== '/auth') {
let token = parseQueryString(req.query.auth);
settings.TWITCH.OAUTH_TOKEN = token['#access_token'];
fs.writeFileSync(settingsPath, ini.stringify(settings));
settings = ini.parse(fs.readFileSync(settingsPath, 'utf-8'));
resolve('finished');
stopServer();
}
next();
});
function stopServer() {
tempAuthServer.close();
}
const htmlString = `
<!DOCTYPE html>
<html>
<head>
<title>Authentication</title>
</head>
<body>
<h1>Authentication successful! You can close this window now.</h1>
<form name="auth" "action="auth" method="get" >
<input type="text" id="auth" name="auth"/>
<input type="submit" />
</form>
</body>
</html>
<script>
function onSubmitComplete() {
close();
}
document.querySelector("#auth").value = document.location.hash;
document.auth.submit();
setTimeout(onSubmitComplete, 500);
</script>
`;
tempAuthServer.get('/auth', (req, res) => {
res.send(htmlString);
});
tempAuthServer.post('/auth', (req, res) => {
res.render('authentication', { name: req.body.name });
});
const server = http.createServer(tempAuthServer);
server.listen(port, () => {
const authURL = `https://id.twitch.tv/oauth2/authorize?client_id=${settings.TWITCH.CLIENT_ID}&redirect_uri=${encodeURIComponent(
redirectUri,
)}&response_type=token&scope=${scopes.join(' ')}`;
shell.openExternal(authURL);
});
function stopServer() {
server.close(() => {});
}
});
ipcMain.on('twitch', async (event) => {
await twitchAuthentication();
event.returnValue = settings.TWITCH.OAUTH_TOKEN;
});
ipcMain.on('vtuber', async (event) => {
shell.openExternal(`http://localhost:${settings.SERVER.PORT}/vtuber/`);
});
ipcMain.on('chatBubble', async (event) => {
shell.openExternal(`http://localhost:${settings.SERVER.PORT}/chat/`);
});
async function createIniFile() {
await writeIniFile(resourcesPath, {
SETTINGS: {
VOICE_ENABLED: true,
NOTIFICATION_ENABLED: true,
POSITION_X: 0,
POSITION_Y: 0,
WIDTH: 1024,
HEIGHT: 768,
LANGUAGE: "EN"
},
TTS: {
PRIMARY_TTS_VOICE: 0,
PRIMARY_TTS_NAME: "",
PRIMARY_TTS_LANGUAGE: "EN",
PRIMARY_TTS_LANGUAGE_INDEX: 0,
SECONDARY_TTS_VOICE: 0,
SECONDARY_TTS_NAME: "",
SECONDARY_TTS_LANGUAGE: "EN",
SECONDARY_TTS_LANGUAGE_INDEX: 0
},
AUDIO: {
NOTIFICATION_AUDIO_DEVICE: 0,
NOTIFICATION_SOUND: 0,
NOTIFICATION_VOLUME: 100,
SELECTED_TTS_AUDIO_DEVICE: 0,
TTS_AUDIO_DEVICE: "default",
TTS_VOLUME: 100
},
THEME: {
USE_CUSTOM_THEME: false,
MAIN_COLOR_1: "\#cdc1c1",
MAIN_COLOR_2: "\#b12020",
MAIN_COLOR_3: "\#6c4104",
MAIN_COLOR_4: "\#532d2d",
TOP_BAR: "\#c8ff00",
MID_SECTION: "\#6b8578",
CHAT_BUBBLE_BG: "\#447466",
CHAT_BUBBLE_HEADER: "\#ffffff",
CHAT_BUBBLE_MESSAGE: "\#b5b5b5",
},
TWITCH: {
USE_TWITCH: false,
CHANNEL_NAME: "khyretos",
USERNAME: "loquendo",
OAUTH_TOKEN: "",
CLIENT_ID: "",
CLIENT_SECRET: "",
},
SERVER: {
USE_SERVER: false,
PORT: "9000",
USE_VTUBER: false,
USE_CHATBUBBLE: false,
},
AMAZON: {
USE_TWITCH: false,
ACCESS_KEY: "",
ACCESS_SECRET: "",
},
GOOGLE: {
USE_GOOGLE: false,
API_KEY: "",
}
}).then(() => {
settings = ini.parse(fs.readFileSync(resourcesPath, 'utf-8'));
})
}
await writeIniFile(resourcesPath, {
SETTINGS: {
VOICE_ENABLED: true,
NOTIFICATION_ENABLED: true,
POSITION_X: 0,
POSITION_Y: 0,
WIDTH: 1024,
HEIGHT: 768,
LANGUAGE: 'EN',
},
TTS: {
USE_TTS: true,
PRIMARY_TTS_VOICE: 0,
PRIMARY_TTS_NAME: '',
PRIMARY_TTS_LANGUAGE: 'EN',
PRIMARY_TTS_LANGUAGE_INDEX: 0,
SECONDARY_TTS_VOICE: 0,
SECONDARY_TTS_NAME: '',
SECONDARY_TTS_LANGUAGE: 'EN',
SECONDARY_TTS_LANGUAGE_INDEX: 0,
TTS_VOLUME: 50,
},
AUDIO: {
USE_NOTIFICATION_SOUNDS: true,
NOTIFICATION_AUDIO_DEVICE: 0,
NOTIFICATION_SOUND: 0,
NOTIFICATION_VOLUME: 50,
SELECTED_TTS_AUDIO_DEVICE: 0,
TTS_AUDIO_DEVICE: 'default',
},
THEME: {
USE_CUSTOM_THEME: false,
MAIN_COLOR_1: '#cdc1c1',
MAIN_COLOR_2: '#b12020',
MAIN_COLOR_3: '#6c4104',
MAIN_COLOR_4: '#532d2d',
TOP_BAR: '#c8ff00',
MID_SECTION: '#6b8578',
CHAT_BUBBLE_BG: '#447466',
CHAT_BUBBLE_HEADER: '#ffffff',
CHAT_BUBBLE_MESSAGE: '#b5b5b5',
},
TWITCH: {
USE_TWITCH: false,
CHANNEL_NAME: '',
USERNAME: 'loquendo',
OAUTH_TOKEN: '',
CLIENT_ID: '2t206sj7rvtr1rutob3p627d13jch9',
},
SERVER: {
USE_SERVER: false,
PORT: '9000',
USE_VTUBER: false,
USE_CHATBUBBLE: false,
},
AMAZON: {
USE_TWITCH: false,
ACCESS_KEY: '',
ACCESS_SECRET: '',
},
GOOGLE: {
USE_GOOGLE: false,
API_KEY: '',
},
}).then(() => {
settings = ini.parse(fs.readFileSync(resourcesPath, 'utf-8'));
});
}

View file

@ -1,3 +1,4 @@
// Connect to the Socket.IO server
const socket = io();

Binary file not shown.