diff --git a/client/src/features/viewers/production/Pip.module.css b/client/src/features/viewers/production/Pip.module.css
deleted file mode 100644
index a46c4afcc..000000000
--- a/client/src/features/viewers/production/Pip.module.css
+++ /dev/null
@@ -1,136 +0,0 @@
-.container__gray,
-.container__grayFinished {
- margin: 0;
- box-sizing: border-box; /* reset */
- overflow: hidden;
- width: 100%; /* restrict the page width to viewport */
-
- background: linear-gradient(90deg, #252525 0%, #121212 100%);
- height: 100vh;
- color: #fffd;
- font-weight: 300;
- display: grid;
- grid-template-columns: 20vw 20vw 18vw 3vw 1fr;
- grid-template-rows: 60vh 1fr 1fr 1fr;
- grid-template-areas:
- ' pip pip pip . schd'
- ' titl titl titl . schd'
- ' info info clck . schd'
- ' info info time . schd';
- gap: 1vw;
- padding: 1vw;
-}
-
-.label {
- font-size: 1.3vw;
- color: #ff7597;
-}
-
-.eventTitle {
- grid-area: titl;
- font-size: 3vw;
- font-weight: 600;
- text-decoration: underline #ff7597 0.5vh;
- padding-top: 0.2vh;
- padding-left: 1vw;
-}
-
-.pip {
- grid-area: pip;
- background-color: rgba(0, 0, 0, 0.5);
- border: 1px solid rgba(255, 255, 2555, 0.07);
- width: 100%;
- text-align: center;
- display: grid;
- place-content: center;
-}
-
-.empty {
- opacity: 0.5;
-}
-
-.piptext {
- color: rgba(255, 255, 255, 0.13);
- font-weight: 600;
- font-size: 4vh;
-}
-
-/* =================== TITLES ===================*/
-
-.infoContainer > div {
- overflow: hidden;
-}
-
-.infoContainer,
-.clockContainer,
-.countdownContainer {
- background-color: rgba(255, 255, 255, 0.05);
- padding: 1vh 1vw;
-}
-
-.todayContainer {
- background-color: rgba(255, 255, 255, 0.07);
- padding: 2.5vh 2vw;
-}
-
-.infoContainer,
-.todayContainer {
- border-radius: 1vw;
-}
-
-.infoContainer {
- grid-area: info;
- display: grid;
-
- grid-template-rows: 3vh minmax(0, 1fr);
- grid-template-columns: 3fr 1fr;
- grid-template-areas:
- 'titl qr'
- 'binf qr';
- gap: 0.5vw;
-}
-
-.infoMessages {
- grid-area: binf;
- font-size: 1.5vw;
- line-height: 2vw;
- white-space: pre-line;
-}
-
-.qr {
- align-self: center;
- justify-self: center;
- grid-area: qr;
-}
-
-/* =================== SCHEDULE ===================*/
-
-.todayContainer {
- grid-area: schd;
- display: grid;
- grid-template-rows: 5vh 1fr 3vh;
- height: 100%;
- overflow: hidden;
- max-width: 100%;
-}
-
-/* =================== MAIN ===================*/
-
-.clockContainer {
- grid-area: time;
- border-radius: 0 0 1vw 1vw;
-}
-
-.countdownContainer {
- grid-area: clck;
- border-radius: 1vw 1vw 0 0;
-}
-
-.clock {
- font-family: 'Open Sans', sans-serif;
- font-size: 3vw;
- line-height: 3vw;
- text-align: center;
- letter-spacing: 0.25vw;
- color: #ddd;
-}
diff --git a/client/src/features/viewers/production/Pip.module.scss b/client/src/features/viewers/production/Pip.module.scss
new file mode 100644
index 000000000..d42657986
--- /dev/null
+++ b/client/src/features/viewers/production/Pip.module.scss
@@ -0,0 +1,63 @@
+@use '../../../styles/main' as *;
+@use '../../../styles/viewers' as *;
+
+.container__gray,
+.container__grayFinished {
+ @include viewer-container;
+
+ display: grid;
+ grid-template-columns: 20vw 20vw 18vw 3vw 1fr;
+ grid-template-rows: 60vh 1fr 1fr 1fr;
+ grid-template-areas:
+ ' pip pip pip . schd'
+ ' titl titl titl . schd'
+ ' info info clck . schd'
+ ' info info time . schd';
+ gap: 1vw;
+ padding: 1vw;
+}
+
+.eventTitle {
+ grid-area: titl;
+ @include viewer-event-title;
+}
+
+.pip {
+ grid-area: pip;
+ background-color: $bg-black-100;
+ border: 1px solid $bg-black-200;
+ width: 100%;
+ text-align: center;
+ display: grid;
+ place-content: center;
+}
+
+.empty {
+ opacity: 0.5;
+}
+
+.piptext {
+ color: $bg-gray-900;
+ font-weight: 600;
+ font-size: 4vh;
+}
+
+.infoContainer,
+.clockContainer,
+.countdownContainer {
+ background-color: $bg-gray-1000;
+ padding: 1vh 1vw;
+}
+
+.todayContainer {
+ grid-area: schd;
+}
+
+.countdownContainer {
+ grid-area: clck;
+ border-radius: 1vw 1vw 0 0;
+}
+
+.clockContainer {
+ border-radius: 0 0 1vw 1vw;
+}
diff --git a/client/src/features/viewers/production/lower/LowerWrapper.jsx b/client/src/features/viewers/production/lower/LowerWrapper.jsx
index 56265d5ca..196d913a2 100644
--- a/client/src/features/viewers/production/lower/LowerWrapper.jsx
+++ b/client/src/features/viewers/production/lower/LowerWrapper.jsx
@@ -65,51 +65,51 @@ const Lower = (props) => {
// Check for user options
useEffect(() => {
// create aux
- let options = {};
+ const options = {};
// preset: selector
// Should be a number 1-n
- let p = parseInt(searchParams.get('preset'));
+ const p = parseInt(searchParams.get('preset'));
if (!isNaN(p)) setPreset(p);
// size: multiplier
// Should be a number 0.0-n
- let s = searchParams.get('size');
+ const s = searchParams.get('size');
if (s) options.size = s;
// transitionIn: seconds
// Should be a number 0-n
- let t = parseInt(searchParams.get('transition'));
+ const t = parseInt(searchParams.get('transition'));
if (!isNaN(t)) options.transitionIn = t;
// textColour: string
// Should be a hex string '#ffffff'
- let c = searchParams.get('text');
+ const c = searchParams.get('text');
if (c) options.textColour = `#${c}`;
// bgColour: string
// Should be a hex string '#ffffff'
- let b = searchParams.get('bg');
+ const b = searchParams.get('bg');
if (b) options.bgColour = `#${b}`;
// key: string
// Should be a hex string '#00FF00' with key colour
- let k = searchParams.get('key');
+ const k = searchParams.get('key');
if (k) options.keyColour = `#${k}`;
// fadeOut: seconds
// Should be a number 0-n
- let f = parseInt(searchParams.get('fadeout'));
+ const f = parseInt(searchParams.get('fadeout'));
if (!isNaN(f)) options.fadeOut = f;
// x: pixels
// Should be a number 0-n
- let x = parseInt(searchParams.get('x'));
+ const x = parseInt(searchParams.get('x'));
if (!isNaN(x)) options.posX = x;
// y: pixels
// Should be a number 0-n
- let y = parseInt(searchParams.get('y'));
+ const y = parseInt(searchParams.get('y'));
if (!isNaN(y)) options.posY = y;
setLowerOptions({
diff --git a/client/src/features/viewers/studio/StudioClock.jsx b/client/src/features/viewers/studio/StudioClock.jsx
index 49e0885ac..98c2a8197 100644
--- a/client/src/features/viewers/studio/StudioClock.jsx
+++ b/client/src/features/viewers/studio/StudioClock.jsx
@@ -18,7 +18,7 @@ export default function StudioClock(props) {
const activeIndicators = [...Array(12).keys()];
const secondsIndicators = [...Array(60).keys()];
- const MAX_TITLES = 8;
+ const MAX_TITLES = 10;
// Set window title
useEffect(() => {
@@ -45,7 +45,7 @@ export default function StudioClock(props) {
{title.titleNext}
@@ -58,7 +58,7 @@ export default function StudioClock(props) {
key={i}
className={style.hours__active}
style={{
- transform: `rotate(${(360 / 12) * i - 90}deg) translateX(380px)`,
+ transform: `rotate(${(360 / 12) * i - 90}deg) translateX(40vh)`,
}}
/>
))}
@@ -67,7 +67,7 @@ export default function StudioClock(props) {
key={i}
className={i <= secondsNow ? style.min__active : style.min}
style={{
- transform: `rotate(${(360 / 60) * i - 90}deg) translateX(415px)`,
+ transform: `rotate(${(360 / 60) * i - 90}deg) translateX(43vh)`,
}}
/>
))}
@@ -94,8 +94,8 @@ export default function StudioClock(props) {
}
StudioClock.propTypes = {
- title: PropTypes.string,
- time: PropTypes.number,
+ title: PropTypes.object,
+ time: PropTypes.object,
backstageEvents: PropTypes.array,
selectedId: PropTypes.string,
nextId: PropTypes.string,
diff --git a/client/src/features/viewers/studio/StudioClock.module.scss b/client/src/features/viewers/studio/StudioClock.module.scss
index ce6a6e089..692321e24 100644
--- a/client/src/features/viewers/studio/StudioClock.module.scss
+++ b/client/src/features/viewers/studio/StudioClock.module.scss
@@ -3,6 +3,18 @@
src: local('digital-7'), url('./../../../assets/fonts/digital-7.monoitalic.ttf') format('truetype') ;
}
+/* =============== CLOCK STUFF ==================*/
+
+$clock-size: 90vh;
+$size-hours: min(3vh, 20px);
+$half-hours: min(1.5vh, 10px);
+$size-min: min(2.5vh, 18px);
+$half-min: min(1.25vh, 9px);
+$red-active: #c53030;
+$red-idle: #300000;
+$cyan-active: #0ff;
+$cyan-idle: #0aa;
+
.container {
margin: 0;
box-sizing: border-box; /* reset */
@@ -14,66 +26,27 @@
background: #000;
display: grid;
- grid-template-columns: 1000px 1fr;
- gap: 50px;
+ grid-template-columns: 95vh 1fr;
+ gap: 2vw;
grid-template-areas: "clck schd";
- /* =============== CLOCK STUFF ==================*/
-
- $clock-size: 900px;
- $size-hours: 20px;
- $half-hours: 10px;
- $size-min: 18px;
- $half-min: 9px;
- $red-active: #c53030;
- $red-idle: #300000;
- $cyan-active: #0ff;
- $cyan-idle: #0aa;
-
.clockContainer {
- display: grid;
- place-content: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
grid-area: clck;
width: $clock-size;
height: $clock-size;
+ aspect-ratio: 1;
text-align: center;
position: relative;
- margin: auto;
+ margin: 4vh auto;
font-family: digital-clock, monospace;
text-transform: uppercase;
- .time {
- margin-top: 175px;
- color: $red-active;
- font-size: 300px;
- line-height: 0.8em;
- }
- .nextTitle:after,
- .nextCountdown:after,
- .nextCountdown__overtime:after {
- content: '\200b';
- }
- .nextTitle {
- color:$cyan-idle;
- line-height: 100px;
- }
- .nextCountdown,
- .nextCountdown__overtime {
- font-size: 100px;
- line-height: 1em;
- }
- .nextCountdown {
- color: $cyan-active;
- text-shadow: rgb(0,100,100) 0 0 20px;
- }
- .nextCountdown::before {
- content: '-';
- }
- .nextCountdown__overtime {
- color: darken($red-active, 10%);
- }
- .indicators {
+ .indicators {
position: absolute;
+ top: 0;
width: 100%;
height: 100%;
@@ -85,6 +58,7 @@
position: absolute;
background: $red-idle;
}
+
.min,
.min__active {
min-height: $size-min;
@@ -92,60 +66,100 @@
top: calc(50% - #{$half_min});
left: calc(50% - #{$half_min});
}
+
.hours,
- .hours__active{
- min-height:$size-hours;
+ .hours__active {
+ min-height: $size-hours;
width: $size-hours;
top: calc(50% - #{$half_hours});
left: calc(50% - #{$half_hours});
}
+
.min__active,
.hours__active {
background: $red-active;
- box-shadow: 0 0 10px 2px rgba(255,0,0,0.25);
+ box-shadow: 0 0 10px 2px rgba(255, 0, 0, 0.25);
}
}
+
+ .time {
+ color: $red-active;
+ font-size: calc(#{$clock-size} / 3);
+ margin-top: calc(50% - calc(#{$clock-size} / 7));
+ line-height: 0.8em;
+ }
+
+ .nextTitle:after,
+ .nextCountdown:after,
+ .nextCountdown__overtime:after {
+ content: '\200b';
+ }
+
+ .nextTitle {
+ color: $cyan-idle;
+ text-align: center;
+ }
+
+ .nextCountdown,
+ .nextCountdown__overtime {
+ font-size: 10vh;
+ line-height: 1em;
+ }
+
+ .nextCountdown {
+ color: $cyan-active;
+ text-shadow: rgb(0, 100, 100) 0 0 20px;
+ }
+
+ .nextCountdown::before {
+ content: '-';
+ }
+
+ .nextCountdown__overtime {
+ color: darken($red-active, 10%);
+ }
}
/* ============= SCHEDULE STUFF =================*/
.scheduleContainer {
grid-area: schd;
- margin: 50px 0;
- padding-right: 50px;
+ margin: 4vh 0;
font-family: digital-clock, monospace;
text-transform: uppercase;
.onAir,
- .onAir__idle{
- padding-bottom: 50px;
- font-size: 170px;
+ .onAir__idle {
+ padding-bottom: 2vh;
+ font-size: 15vh;
line-height: 0.9em;
}
+
.onAir {
color: $red-active;
}
+
.onAir__idle {
color: $red-idle;
}
+
.schedule {
ul {
color: $cyan-idle;
+ font-size: 3.75vh;
line-height: 1em;
list-style: none;
- font-size: 40px;
}
+
li {
- margin-bottom: 0.5em;
- padding-left: 0.5em;
- display: flex;
- align-items: center;
- gap: 20px;
+ margin-bottom: 1.5vh;
}
+
.now {
color: $cyan-active;
}
+
.next {
color: $red-active;
}
@@ -153,14 +167,14 @@
}
}
-@media only screen and (max-width: 1600px) {
+@media only screen and (max-width: 1200px) {
.container {
display: grid;
grid-template-areas: "clck";
grid-template-columns: 100%;
place-content: center;
}
- .scheduleContainer{
+ .scheduleContainer {
display: none;
}
}
diff --git a/client/src/features/viewers/timer/MinimalTimer.jsx b/client/src/features/viewers/timer/MinimalTimer.jsx
index cf4aad5fc..e1a0d08c4 100644
--- a/client/src/features/viewers/timer/MinimalTimer.jsx
+++ b/client/src/features/viewers/timer/MinimalTimer.jsx
@@ -14,7 +14,7 @@ export default function MinimalTimer(props) {
const showOverlay = pres.text !== '' && pres.visible;
const isPlaying = time.playstate !== 'pause';
const timer = formatDisplay(time.running, true);
- const clean = timer.replaceAll(':', '');
+ const clean = timer.replace('/:/g', '');
return (
diff --git a/client/src/features/viewers/timer/MinimalTimer.module.scss b/client/src/features/viewers/timer/MinimalTimer.module.scss
index 6714e521a..40a0637b0 100644
--- a/client/src/features/viewers/timer/MinimalTimer.module.scss
+++ b/client/src/features/viewers/timer/MinimalTimer.module.scss
@@ -43,7 +43,7 @@
left: 0;
right: 0;
bottom: 0;
- background-color: rgba(0, 0, 0, 0.85);
+ background-color: $bg-overlay;
z-index: -1;
opacity: 0;
transition: 0.5s;
diff --git a/client/src/features/viewers/timer/Timer.module.scss b/client/src/features/viewers/timer/Timer.module.scss
index 7f569ac38..ba23ae2f5 100644
--- a/client/src/features/viewers/timer/Timer.module.scss
+++ b/client/src/features/viewers/timer/Timer.module.scss
@@ -7,7 +7,7 @@
overflow: hidden;
width: 100%; /* restrict the page width to viewport */
- background: radial-gradient(circle, $bg-black-gradient 0%, $bg-black 80%);
+ background: $bg-black;
height: 100vh;
color: $title-white;
display: grid;
@@ -31,7 +31,7 @@
.nowContainer,
.nextContainer {
- background-color: rgba(255, 255, 255, 0.05);
+ background-color: $bg-gray-1000;
padding: 1vh 2vw;
border-radius: 1vw;
max-width: 100%;
@@ -98,7 +98,7 @@
left: 0;
right: 0;
bottom: 0;
- background-color: rgba(0, 0, 0, 0.85);
+ background-color: $bg-overlay;
z-index: -1;
opacity: 0;
transition: 0.5s;
diff --git a/client/src/styles/_main.scss b/client/src/styles/_main.scss
index 03a955b86..23658c4ae 100644
--- a/client/src/styles/_main.scss
+++ b/client/src/styles/_main.scss
@@ -1,33 +1,96 @@
//////////////////////////////////// general app colours
-$ontime-accent: #4bffabcc;
+
+$bg-black-gradient: #202020;
+$bg-black: #121212;
+$bg-black-100: #070707;
+$bg-black-200: #1a1a1a; // container borders
+$bg-black-300: #1f1f1f; // container text
+$bg-gray-1100: #232323; // container borders
+$bg-gray-1000: #262626; // container borders
+$bg-gray-950: #292929;
+$bg-gray-900: #303030;
+$bg-gray-800: #404040;
+$bg-gray-700: #505050;
+$bg-gray-500: #666666;
+$bg-gray-100: #c0c0c0; // borders and whatnot
+
+$bg-overlay: rgba(0, 0, 0, 0.85);
+
+$ontime-accent: #4bffab;
+$ontime-accent-text: mix($bg-black, $ontime-accent, 10%);
$ontime-pink: #ff7597;
$ontime-pink-variant: #ff6969;
$ontime-roll: #2b6cb0;
+$ontime-delay: #dd6b20;
+
+
+//rgba(255, 255, 255, 0.39); - $bg-gray-700
+//rgba(255, 255, 255, 0.13); - $bg-gray-900
+//rgba(255, 255, 255, 0.05); - $bg-gray-1000
+//rgba(255, 255, 255, 0.07) - $bg-gray-1000
+// text input bg -
+// was rgba(255, 255, 255, 0.03)
+// container level 1 - $bg-gray-1000
+// container level 2 - $bg-gray-1100
+// container level 2 border - rgba(0, 0, 0, 0.05)
+// indent in level 2 - $bg-black-300
+// outdent in level2 - $bg-gray-950
+//////////////////////////////////// editor
$notes-color: #d69e2e;
+$text-white: #fffffa;
+$text-gray-disabled: #999;
$header-gray: #ccc;
$label-gray: #aaa;
+$clocks: #ddd;
$bg-gray: #f4f4f8;
$light-bg: #2b6cb0;
$light-bg-transparent: #2b6cb055;
$light-text: #2b6cb022;
-$error-red: #E53E3E;
+$info-gray: #aaa;
+$info-gray-hover: #ddd;
+$warning-orange: #dd6b20;
+$error-red: #e53e3e;
+//////////////////////////////////// viewers
$title-white: #fffd;
-$bg-black: #121212;
-$bg-black-gradient: #202020;
-
+$title-gray: #ddd;
+$subtitle-gray: #aaa;
//////////////////////////////////// block elements
$block-delay-color: #ecc94b;
+$block-delay-border: #d69e2e55;
$block-block-color: #805ad5;
-$block-icon-drag: rgba(255, 255, 255, 0.67);
-$block-border: 1px solid rgba(255, 255, 255, 0.05);
+$block-icon-drag: $bg-gray-100;
+$block-border: 1px solid $bg-gray-800;
+//////////////////////////////////// viewer cards
+@mixin card-title {
+ color: $title-gray;
+ font-weight: 600;
+}
+
+@mixin card-label {
+ font-size: 1.3vw;
+ color: $ontime-pink;
+}
+
+//////////////////////////////////// utils
+
+@mixin ellipsis {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+//////////////////////////////////// custom inputs
+$input-bg: rgba(255, 255, 255, 0.03);
+$input-border: 1px solid $bg-gray-800;
+$input-delayed-border: 1px solid $block-delay-border;
//////////////////////////////////// general app element overriders
diff --git a/client/src/styles/_mixins.scss b/client/src/styles/_mixins.scss
index 3a8572ee1..8938324a8 100644
--- a/client/src/styles/_mixins.scss
+++ b/client/src/styles/_mixins.scss
@@ -1,20 +1,27 @@
+@use "./main" as *;
+
//////////////////////////////////// general app elements
@mixin main-container {
- background-color: rgba(0, 0, 0, 0.05);
+ background-color: $bg-gray-1000;
+ border: 1px solid $bg-gray-1000;
+ border-radius: 4px;
+}
+
+@mixin second-container {
+ background-color: $bg-gray-1100;
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
-@mixin container-bg {
- background-color: rgba(0, 0, 0, 0.13);
+@mixin third-container {
+ background-color: $bg-black-300;
+ border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 2px;
- padding: 0 0.5em;
- margin: 0 0.5em;
}
@mixin osc-label {
- color: #4bffabcc;
+ color: $ontime-accent-text;
font-size: 0.8em;
-webkit-user-select: text;
user-select: text;
diff --git a/client/src/features/viewers/foh/Public.module.css b/client/src/styles/_viewers.scss
similarity index 56%
rename from client/src/features/viewers/foh/Public.module.css
rename to client/src/styles/_viewers.scss
index 7a26e7d19..65910d109 100644
--- a/client/src/features/viewers/foh/Public.module.css
+++ b/client/src/styles/_viewers.scss
@@ -1,43 +1,36 @@
-.container__gray,
-.container__grayFinished {
+@use './main' as *;
+
+@mixin viewer-container {
margin: 0;
box-sizing: border-box; /* reset */
overflow: hidden;
width: 100%; /* restrict the page width to viewport */
-
- background: linear-gradient(90deg, #252525 0%, #121212 100%);
+ background: $bg-black;
height: 100vh;
- color: #fffd;
+ color: $title-white;
font-weight: 300;
- display: grid;
- grid-template-columns: 1fr 1fr 1fr 3vw 2fr;
- grid-template-rows: 15vh 1fr 1fr 0 13vh 13vh;
- grid-template-areas:
- ' titl titl titl . schd'
- ' now now now . schd'
- ' next next .... . schd'
- ' ... .... .... . ....'
- ' publ publ .... . info'
- ' publ publ time . info';
- gap: 1vw;
- padding: 1vw;
}
-.label {
- font-size: 1.3vw;
- color: #ff7597;
-}
-
-.eventTitle {
- grid-area: titl;
+@mixin viewer-event-title {
font-size: 3vw;
font-weight: 600;
- text-decoration: underline #ff7597 0.5vh;
+ text-decoration: underline $ontime-pink 0.5vh;
padding-top: 0.2vh;
padding-left: 1vw;
}
-/* =================== TITLES ===================*/
+@mixin viewer-info-messages {
+ font-size: 1.5vw;
+ line-height: 2vw;
+ white-space: pre-line;
+}
+
+////////////////////////////// Specifics
+
+.label {
+ font-size: 1.3vw;
+ color: $ontime-pink;
+}
.infoContainer > div {
overflow: hidden;
@@ -45,24 +38,22 @@
.nextContainer > div,
.nowContainer > div {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+ @include ellipsis;
}
.nowContainer,
.nextContainer,
.todayContainer {
- background-color: rgba(255, 255, 255, 0.05);
+ background-color: $bg-gray-1000;
padding: 1vh 2vw;
-
overflow: hidden;
}
.clockContainer,
+.countdownContainer,
.publicContainer,
.publicContainerHidden {
- background-color: rgba(255, 255, 255, 0.05);
+ background-color: $bg-gray-1000;
padding: 1vh 1vw;
}
@@ -80,7 +71,7 @@
.todayContainer,
.infoContainer {
- background-color: rgba(255, 255, 255, 0.07);
+ background-color: $bg-gray-1100;
padding: 2.5vh 2vw;
}
@@ -96,38 +87,19 @@
margin-left: -1vw;
}
-.nowContainer {
- background-color: rgba(255, 255, 255, 0.09);
- grid-area: now;
- border-radius: 0 2vw 2vw 0;
+.qr {
+ align-self: center;
+ justify-self: center;
+ grid-area: qr;
}
-.publicContainer,
-.publicContainerHidden {
- grid-area: publ;
-}
-
-.nextContainer {
- grid-area: next;
- border-radius: 0 2vw 2vw 0;
-}
-
-/* =================== SCHEDULE ===================*/
-
-.todayContainer {
- grid-area: schd;
- display: grid;
- grid-template-rows: 5vh 1fr 3vh;
- margin-top: 3vh;
- height: 95%;
-}
-
-/* =================== OVERLAY ===================*/
-
-.message {
+.clock {
+ font-family: 'Open Sans', sans-serif;
font-size: 3vw;
line-height: 3vw;
- padding: 0.5vh 0 0.5vh 1vw;
+ text-align: center;
+ letter-spacing: 0.25vw;
+ color: $clocks;
}
.infoContainer {
@@ -149,24 +121,70 @@
white-space: pre-line;
}
-.qr {
- align-self: center;
- justify-self: center;
- grid-area: qr;
-}
-
-/* =================== MAIN ===================*/
-
.clockContainer {
grid-area: time;
border-radius: 1vw;
}
-.clock {
- font-family: 'Open Sans', sans-serif;
+.message {
font-size: 3vw;
line-height: 3vw;
- text-align: center;
- letter-spacing: 0.25vw;
- color: #ddd;
+ padding: 0.5vh 0 0.5vh 1vw;
+}
+
+.todayContainer {
+ margin-top: 3vh;
+ height: 95%;
+
+ .todayHeaderBlock {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 1.5vh;
+
+ .navItem,
+ .navItemSelected {
+ background-color: $bg-gray-700;
+ width: 0.7vw;
+ height: 0.7vw;
+ border-radius: 0.35vw;
+ }
+
+ .navItemSelected {
+ background-color: $bg-gray-100;
+ }
+
+ .nav {
+ align-self: center;
+ justify-content: flex-end;
+ display: flex;
+ margin-bottom: 2.5vh;
+ }
+
+ .nav > div {
+ margin-left: 0.5vw;
+ }
+ }
+}
+
+.infoContainer {
+ display: grid;
+
+ grid-template-rows: 3vh minmax(0, 1fr);
+ grid-template-columns: 3fr 1fr;
+ grid-template-areas:
+ 'titl .'
+ 'binf qr';
+ gap: 0.5vw;
+
+ .infoMessages {
+ grid-area: binf;
+ font-size: 1.5vw;
+ line-height: 2vw;
+ white-space: pre-line;
+ }
+
+ .clockContainer {
+ grid-area: time;
+ border-radius: 1vw;
+ }
}
diff --git a/client/yarn.lock b/client/yarn.lock
index c81b004dc..1fa8d2f81 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -7231,10 +7231,6 @@ onetime@^5.1.2:
dependencies:
mimic-fn "^2.1.0"
-"ontime-utils@link: ../server/utils":
- version "0.0.0"
- uid ""
-
open@^8.0.9, open@^8.4.0:
version "8.4.0"
resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8"
diff --git a/server/README.md b/server/README.md
deleted file mode 100644
index 02aac3f6e..000000000
--- a/server/README.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# Getting Started with Create React App
-
-This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
-
-## Available Scripts
-
-In the project directory, you can run:
-
-### `yarn start`
-
-Runs the app in the development mode.\
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
-
-The page will reload if you make edits.\
-You will also see any lint errors in the console.
-
-### `yarn test`
-
-Launches the test runner in the interactive watch mode.\
-See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
-
-### `yarn build`
-
-Builds the app for production to the `build` folder.\
-It correctly bundles React in production mode and optimizes the build for the best performance.
-
-The build is minified and the filenames include the hashes.\
-Your app is ready to be deployed!
-
-See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
-
-### `yarn eject`
-
-**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
-
-If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
-
-Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
-
-You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
-
-## Learn More
-
-You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
-
-To learn React, check out the [React documentation](https://reactjs.org/).
-
-### Code Splitting
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
-
-### Analyzing the Bundle Size
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
-
-### Making a Progressive Web App
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
-
-### Advanced Configuration
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
-
-### Deployment
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
-
-### `yarn build` fails to minify
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
diff --git a/server/main.js b/server/main.js
index fc7f9dd76..1cfdab480 100644
--- a/server/main.js
+++ b/server/main.js
@@ -54,13 +54,10 @@ let tray = null;
// Ensure there isn't another instance of the app running already
const lock = app.requestSingleInstanceLock();
if (!lock) {
- dialog.showErrorBox(
- 'Multiple instances',
- 'An instance if the App is already running.'
- );
+ dialog.showErrorBox('Multiple instances', 'An instance if the App is already running.');
app.quit();
} else {
- app.on('second-instance', (event, commandLine, workingDirectory) => {
+ app.on('second-instance', () => {
// Someone tried to run a second instance, we should focus our window.
if (win) {
if (win.isMinimized()) win.restore();
@@ -134,9 +131,7 @@ app.whenReady().then(() => {
setTimeout(() => {
// Load page served by node
const reactApp =
- env === 'prod'
- ? 'http://localhost:4001/editor'
- : 'http://localhost:3000/editor';
+ env === 'prod' ? 'http://localhost:4001/editor' : 'http://localhost:3000/editor';
win.loadURL(reactApp).then(() => {
win.webContents.setBackgroundThrottling(false);
@@ -190,13 +185,12 @@ app.whenReady().then(() => {
tray.setContextMenu(trayContextMenu);
// on tray click event, show main window
- tray.on('click', function (e) {
+ tray.on('click', function () {
if (!win.isVisible()) {
win.show();
}
win.focus();
});
-
});
// unregister shortcuts before quitting
@@ -216,7 +210,7 @@ ipcMain.on('test-message', (event, arg) => {
});
// Terminate
-ipcMain.on('shutdown', (event, arg) => {
+ipcMain.on('shutdown', () => {
console.log('Got IPC shutdown');
// terminate node service
@@ -238,8 +232,7 @@ ipcMain.on('set-window', (event, arg) => {
if (arg === 'to-max') {
// window full
- win.setContentSize(1920, 1000);
- win.setPosition(0, 0);
+ win.maximize();
} else if (arg === 'to-tray') {
// window to tray
win.hide();
diff --git a/server/package.json b/server/package.json
index 3ce96ad95..b19c93865 100644
--- a/server/package.json
+++ b/server/package.json
@@ -1,6 +1,6 @@
{
"name": "ontime",
- "version": "0.8.2",
+ "version": "0.9.0",
"author": "Carlos Valente",
"description": "Time keeping for live events",
"repository": "https://github.com/cpvalente/ontime",
@@ -14,7 +14,7 @@
"devDependencies": {
"cypress": "^9.4.1",
"electron": "13.6.7",
- "electron-builder": "^22.14.5",
+ "electron-builder": "^23.0.3",
"eslint": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-cypress": "^2.12.1",
@@ -27,10 +27,8 @@
},
"scripts": {
"nodestart": "NODE_ENV=development node src/app.js",
- "make": "mkdir -p src/data",
"setdb": "cp data/db.json src/data/db.json",
"clean": "rm -rf ../client/build/ && rm -rf ../client/node_modules && rm -rf src/node_modules && rm -rf ./node_modules && rm -rf ./dist",
- "cheat": "rm src/node_modules/ontime-utils && cp -R utils src/node_modules/ontime-utils",
"prep": "yarn clean && yarn setdb",
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
"start": "NODE_ENV=development electron .",
@@ -111,18 +109,6 @@
"!**/{test,tests,__test__,__tests__}",
"!**/{mock,mocks,__mock__,__mocks__}"
]
- },
- {
- "from": "utils",
- "to": "extraResources/utils",
- "filter": [
- "**/*",
- "!cypress/",
- "!**/{yarn.lock,yarn-error.log}",
- "!**/{test,tests,__test__,__tests__}",
- "!**/{mock,mocks,__mock__,__mocks__}",
- "!*{.spec.js,*.test.js}"
- ]
}
]
},
diff --git a/server/src/classes/EventTimer.js b/server/src/classes/EventTimer.js
index fe4b7f86a..d49a110de 100644
--- a/server/src/classes/EventTimer.js
+++ b/server/src/classes/EventTimer.js
@@ -5,8 +5,8 @@ import { OSCIntegration } from './integrations/Osc.js';
import { HTTPIntegration } from './integrations/Http.js';
import { cleanURL } from '../utils/url.js';
import getRandomName from '../utils/getRandomName.js';
-import { stringFromMillis } from 'ontime-utils/time.js';
-import { generateId } from 'ontime-utils/generate_id.js';
+import { generateId } from '../utils/generate_id.js';
+import { stringFromMillis } from '../utils/time.js';
/*
* Class EventTimer adds functions specific to APP
@@ -764,7 +764,7 @@ export class EventTimer extends Timer {
const numEvents = events.length;
// is this the first event
- let first = this.numEvents === 0;
+ const first = this.numEvents === 0;
// set general
this._eventlist = events;
@@ -822,7 +822,7 @@ export class EventTimer extends Timer {
if (e.id === this.selectedEventId) {
// handle reload selected
// Reload data if running
- let type = this.selectedEventId === id && this._startedAt != null ? 'reload' : 'load';
+ const type = this.selectedEventId === id && this._startedAt != null ? 'reload' : 'load';
this.loadEvent(this.selectedEventIndex, type);
} else if (e.id === this.nextEventId) {
// roll needs to recalculate
@@ -1178,7 +1178,7 @@ export class EventTimer extends Timer {
rollLoad() {
const now = this._getCurrentTime();
- let prevLoaded = this.selectedEventId;
+ const prevLoaded = this.selectedEventId;
// maybe roll has already been loaded
if (this.secondaryTimer === null) {
@@ -1428,7 +1428,7 @@ export class EventTimer extends Timer {
* @param {string} message
* @param {any} [payload]
*/
- async sendOsc(message, payload = undefined) {
+ async sendOsc(message, payload) {
// Todo: add disabled osc check
const reply = await this.osc.send(message, payload);
if (!reply.success) {
diff --git a/server/src/classes/Timer.js b/server/src/classes/Timer.js
index f8ee8f5b7..f6702560f 100644
--- a/server/src/classes/Timer.js
+++ b/server/src/classes/Timer.js
@@ -1,11 +1,11 @@
+import { stringFromMillis } from '../utils/time.js';
+
/*
* Timer implements simple countdown timer functions
* User needs to use setup function to be able to use
*
*/
-import { stringFromMillis } from 'ontime-utils/time.js';
-
export class Timer {
constructor() {
this.clock = null;
@@ -62,11 +62,7 @@ export class Timer {
if (this._startedAt != null) {
// update current timer
this.current =
- this._startedAt +
- this.duration +
- this._pausedTotal +
- this._pausedInterval -
- now;
+ this._startedAt + this.duration + this._pausedTotal + this._pausedInterval - now;
}
// enable flag
@@ -114,10 +110,7 @@ export class Timer {
if (this._finishedAt) return this._finishedAt;
return Math.max(
- this._startedAt +
- this.duration +
- this._pausedInterval +
- this._pausedTotal,
+ this._startedAt + this.duration + this._pausedInterval + this._pausedTotal,
this._startedAt
);
}
diff --git a/server/src/classes/classUtils.js b/server/src/classes/classUtils.js
index 13b5857ee..cc2e91b51 100644
--- a/server/src/classes/classUtils.js
+++ b/server/src/classes/classUtils.js
@@ -10,8 +10,7 @@ export const DAY_TO_MS = 86400000;
* @param {number} end - When does the event end
* @returns {number} normalised time
*/
-export const normaliseEndTime = (start, end) =>
- end < start ? end + DAY_TO_MS : end;
+export const normaliseEndTime = (start, end) => (end < start ? end + DAY_TO_MS : end);
/**
* @description Sorts an array of objects by given property
@@ -34,7 +33,7 @@ export const sortArrayByProperty = (arr, property) => {
*/
export const replacePlaceholder = (str, values) => {
- for (let [k, v] of Object.entries(values)) {
+ for (const [k, v] of Object.entries(values)) {
str = str.replace(k, v);
}
return str;
@@ -71,10 +70,7 @@ export const getSelectionByRoll = (arr, now) => {
// exit early if we are past the events
const lastEvent = orderedEvents[orderedEvents.length - 1];
- const lastNormalEnd = normaliseEndTime(
- lastEvent.timeStart,
- lastEvent.timeEnd
- );
+ const lastNormalEnd = normaliseEndTime(lastEvent.timeStart, lastEvent.timeEnd);
if (now > lastNormalEnd) {
return {
nowIndex,
@@ -163,14 +159,8 @@ export const getSelectionByRoll = (arr, now) => {
* @returns {object} object with selection variables
*/
export const updateRoll = (currentTimers) => {
- const {
- selectedEventId,
- current,
- _finishAt,
- clock,
- secondaryTimer,
- _secondaryTarget,
- } = currentTimers;
+ const { selectedEventId, current, _finishAt, clock, secondaryTimer, _secondaryTarget } =
+ currentTimers;
// timers
let updatedTimer = current;
@@ -200,8 +190,7 @@ export const updateRoll = (currentTimers) => {
// a) we just finished an event (finished was set to true)
// b) we need to look for events
// this could be caused by a secondary timer or event finished
- const secondaryRunning =
- updatedSecondaryTimer <= 0 && updatedSecondaryTimer != null;
+ const secondaryRunning = updatedSecondaryTimer <= 0 && updatedSecondaryTimer != null;
if (isFinished || secondaryRunning) {
// look for events
diff --git a/server/src/controllers/OscController.js b/server/src/controllers/OscController.js
index a0a0fb586..d8df6cd5c 100644
--- a/server/src/controllers/OscController.js
+++ b/server/src/controllers/OscController.js
@@ -68,10 +68,7 @@ export const initiateOSC = (config) => {
try {
const t = parseInt(args);
if (isNaN(t)) {
- global.timer.error(
- 'RX',
- `OSC IN: delay time not recognised ${args}`
- );
+ global.timer.error('RX', `OSC IN: delay time not recognised ${args}`);
return;
}
global.timer.increment(t * 1000 * 60);
@@ -82,7 +79,7 @@ export const initiateOSC = (config) => {
case 'goto':
try {
const eventIndex = parseInt(args);
- if (isNaN(eventIndex) || eventIndex <= 0 || eventIndex == null) {
+ if (isNaN(eventIndex) || eventIndex <= 0) {
global.timer.error(
'RX',
`OSC IN: event index not recognised or out of range ${eventIndex}`
@@ -96,10 +93,7 @@ export const initiateOSC = (config) => {
case 'gotoid':
console.log('calling gotoid with', args);
if (args == null) {
- global.timer.error(
- 'RX',
- `OSC IN: event id not recognised or out of range ${args}}`
- );
+ global.timer.error('RX', `OSC IN: event id not recognised or out of range ${args}}`);
return;
}
try {
diff --git a/server/src/controllers/eventsController.js b/server/src/controllers/eventsController.js
index a9b80af4a..90127e5f0 100644
--- a/server/src/controllers/eventsController.js
+++ b/server/src/controllers/eventsController.js
@@ -2,20 +2,20 @@
import { data, db } from '../app.js';
// utils
-import { generateId } from 'ontime-utils/generate_id.js';
import {
block as blockDef,
delay as delayDef,
event as eventDef,
} from '../models/eventsDefinition.js';
+import { generateId } from '../utils/generate_id.js';
const MAX_EVENTS = 99;
async function _insertAt(entry, index) {
// get events
- let events = data.events;
- let count = events.length;
- let order = entry.order;
+ const events = data.events;
+ const count = events.length;
+ const order = entry.order;
// Remove order field from object
delete entry.order;
@@ -146,7 +146,7 @@ export const eventsPut = async (req, res) => {
return;
}
- let eventId = req.body.id;
+ const eventId = req.body.id;
if (!eventId) {
res.status(400).send(`Object malformed: id missing`);
return;
@@ -191,8 +191,8 @@ export const eventsReorder = async (req, res) => {
const { index, from, to } = req.body;
// get events
- let events = data.events;
- let idx = events.findIndex((e) => e.id === index, from);
+ const events = data.events;
+ const idx = events.findIndex((e) => e.id === index, from);
// Check if item is at given index
if (idx !== from) {
@@ -233,7 +233,7 @@ export const eventsApplyDelay = async (req, res) => {
try {
// get events
- let events = data.events;
+ const events = data.events;
// AUX
let delayIndex = null;
diff --git a/server/src/controllers/ontimeController.js b/server/src/controllers/ontimeController.js
index 9ef4e247c..f12ae0b8e 100644
--- a/server/src/controllers/ontimeController.js
+++ b/server/src/controllers/ontimeController.js
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'url';
import { data, db } from '../app.js';
import { networkInterfaces } from 'os';
import { fileHandler } from '../utils/parser.js';
-import { generateId } from 'ontime-utils/generate_id.js';
+import { generateId } from '../utils/generate_id.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
diff --git a/server/src/data/.keep b/server/src/data/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/server/src/package.json b/server/src/package.json
index 8e8d37275..321144228 100644
--- a/server/src/package.json
+++ b/server/src/package.json
@@ -11,7 +11,6 @@
"nanoid": "^3.2.0",
"node-osc": "6.1.12",
"node-xlsx": "^0.21.0",
- "ontime-utils": "link: ../server/utils/",
"passport": "^0.5.2",
"passport-local": "~1.0.0",
"socket.io": "^4.4.1",
diff --git a/server/src/utils/__tests__/generate_id.test.js b/server/src/utils/__tests__/generate_id.test.js
new file mode 100644
index 000000000..df653f826
--- /dev/null
+++ b/server/src/utils/__tests__/generate_id.test.js
@@ -0,0 +1,28 @@
+import { generateId } from '../generate_id.js';
+
+test('generate a valid 5 digit id', () => {
+ const id = generateId();
+ expect(id.length).toBe(5);
+});
+
+test('generate 100 with less than 110 attempts', () => {
+ const ids = new Set();
+ let attempts = 1;
+ while (ids.size < 100) {
+ ids.add(generateId());
+ attempts++;
+ }
+
+ expect(attempts).toBeLessThan(105);
+});
+
+describe('generate 1000 with less than 1020 attempts', () => {
+ const ids = new Set();
+ let attempts = 1;
+ while (ids.size < 1000) {
+ ids.add(generateId());
+ attempts++;
+ }
+
+ expect(attempts).toBeLessThan(1020);
+});
diff --git a/server/src/utils/generate_id.js b/server/src/utils/generate_id.js
new file mode 100644
index 000000000..d3b245b45
--- /dev/null
+++ b/server/src/utils/generate_id.js
@@ -0,0 +1,4 @@
+import { customAlphabet } from 'nanoid';
+const nanoid = customAlphabet('1234567890abcdef', 5);
+
+export const generateId = () => nanoid();
diff --git a/server/src/utils/parser.js b/server/src/utils/parser.js
index fb2db67b3..73c7bc8cc 100644
--- a/server/src/utils/parser.js
+++ b/server/src/utils/parser.js
@@ -2,8 +2,6 @@ import fs from 'fs';
import xlsx from 'node-xlsx';
import { event as eventDef } from '../models/eventsDefinition.js';
import { dbModelv1 } from '../models/dataModel.js';
-import { generateId } from 'ontime-utils/generate_id.js';
-import { excelDateStringToMillis } from 'ontime-utils/time.js';
import { deleteFile, makeString, validateDuration } from './parserUtils.js';
import {
parseAliases_v1,
@@ -14,86 +12,25 @@ import {
parseSettings_v1,
parseUserFields_v1,
} from './parserUtils_v1.js';
+import { excelDateStringToMillis } from './time.js';
+import { generateId } from './generate_id.js';
export const EXCEL_MIME = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
export const JSON_MIME = 'application/json';
export const MAX_EVENTS = 99;
-/**
- * @description Middleware function that checks file type and calls relevant parser
- * @param {string} file - reference to file
- * @return {object} - parse result message
- */
-export const fileHandler = async (file) => {
- let res = {};
-
- // check which file type are we dealing with
-
- if (file.endsWith('.xlsx')) {
- try {
- const excelData = xlsx
- .parse(file, { cellDates: true })
- .find(
- ({ name }) => name.toLowerCase() === 'ontime' || name.toLowerCase() === 'event schedule'
- );
-
- // we only look at worksheets called ontime or event schedule
- if (excelData?.data) {
- const dataFromExcel = await parseExcel_v1(excelData.data);
- res.data = await parseJson_v1(dataFromExcel);
- res.message = 'success';
- } else {
- console.log('Error: No sheets found named ontime or event schedule');
- res = {
- error: true,
- message: `No sheets found named ontime or event schedule`,
- };
- }
- } catch (error) {
- res = { error: true, message: `Error parsing file: ${error}` };
- }
- }
-
- if (file.endsWith('.json')) {
- // if json check version
- const rawdata = fs.readFileSync(file);
- let uploadedJson = null;
-
- try {
- uploadedJson = JSON.parse(rawdata);
- } catch (error) {
- return { error: true, message: 'Error parsing JSON file' };
- }
-
- if (uploadedJson.settings.version === 1) {
- try {
- res.data = await parseJson_v1(uploadedJson);
- res.message = 'success';
- } catch (error) {
- res = { error: true, message: `Error parsing file: ${error}` };
- }
- } else {
- res = { error: true, message: 'Error parsing file, version unknown' };
- }
- }
-
- // delete file
- await deleteFile(file);
- return res;
-};
-
/**
* @description Excel array parser
* @param {array} excelData - array with excel sheet
* @returns {object} - parsed object
*/
export const parseExcel_v1 = async (excelData) => {
- let eventData = {
+ const eventData = {
title: '',
url: '',
};
- let customUserFields = {};
- let events = [];
+ const customUserFields = {};
+ const events = [];
let timeStartIndex = null;
let timeEndIndex = null;
let titleIndex = null;
@@ -291,7 +228,7 @@ export const parseJson_v1 = async (jsonData, enforce = false) => {
}
// object containing the parsed data
- let returnData = {};
+ const returnData = {};
// parse Events
returnData.events = parseEvents_v1(jsonData);
@@ -366,3 +303,66 @@ export const validateEvent_v1 = (eventArgs) => {
return event;
};
+
+/**
+ * @description Middleware function that checks file type and calls relevant parser
+ * @param {string} file - reference to file
+ * @return {object} - parse result message
+ */
+export const fileHandler = async (file) => {
+ let res = {};
+
+ // check which file type are we dealing with
+
+ if (file.endsWith('.xlsx')) {
+ try {
+ const excelData = xlsx
+ .parse(file, { cellDates: true })
+ .find(
+ ({ name }) => name.toLowerCase() === 'ontime' || name.toLowerCase() === 'event schedule'
+ );
+
+ // we only look at worksheets called ontime or event schedule
+ if (excelData?.data) {
+ const dataFromExcel = await parseExcel_v1(excelData.data);
+ res.data = await parseJson_v1(dataFromExcel);
+ res.message = 'success';
+ } else {
+ console.log('Error: No sheets found named ontime or event schedule');
+ res = {
+ error: true,
+ message: `No sheets found named ontime or event schedule`,
+ };
+ }
+ } catch (error) {
+ res = { error: true, message: `Error parsing file: ${error}` };
+ }
+ }
+
+ if (file.endsWith('.json')) {
+ // if json check version
+ const rawdata = fs.readFileSync(file);
+ let uploadedJson = null;
+
+ try {
+ uploadedJson = JSON.parse(rawdata);
+ } catch (error) {
+ return { error: true, message: 'Error parsing JSON file' };
+ }
+
+ if (uploadedJson.settings.version === 1) {
+ try {
+ res.data = await parseJson_v1(uploadedJson);
+ res.message = 'success';
+ } catch (error) {
+ res = { error: true, message: `Error parsing file: ${error}` };
+ }
+ } else {
+ res = { error: true, message: 'Error parsing file, version unknown' };
+ }
+ }
+
+ // delete file
+ await deleteFile(file);
+ return res;
+};
diff --git a/server/src/utils/parserUtils.js b/server/src/utils/parserUtils.js
index dbdd1e66a..230a31bf2 100644
--- a/server/src/utils/parserUtils.js
+++ b/server/src/utils/parserUtils.js
@@ -9,7 +9,7 @@ import fs from 'fs';
export const makeString = (val, fallback = '') => {
if (typeof val === 'string') return val;
else if (val == null || val.constructor === Object) return fallback;
- else return val.toString();
+ return val.toString();
};
/**
diff --git a/server/src/utils/parserUtils_v1.js b/server/src/utils/parserUtils_v1.js
index df9b250f8..1828c2ba8 100644
--- a/server/src/utils/parserUtils_v1.js
+++ b/server/src/utils/parserUtils_v1.js
@@ -1,7 +1,7 @@
import { block as blockDef, delay as delayDef } from '../models/eventsDefinition.js';
-import { generateId } from 'ontime-utils/generate_id.js';
import { dbModelv1 } from '../models/dataModel.js';
import { MAX_EVENTS, validateEvent_v1 } from './parser.js';
+import { generateId } from './generate_id.js';
/**
* Parse events array of an entry
@@ -12,8 +12,8 @@ export const parseEvents_v1 = (data) => {
let newEvents = [];
if ('events' in data) {
console.log('Found events definition, importing...');
- let events = [];
- let ids = [];
+ const events = [];
+ const ids = [];
for (const e of data.events) {
// cap number of events
if (events.length >= MAX_EVENTS) {
@@ -28,7 +28,7 @@ export const parseEvents_v1 = (data) => {
}
if (e.type === 'event') {
- let event = validateEvent_v1(e);
+ const event = validateEvent_v1(e);
if (event != null) {
events.push(event);
ids.push(event.id);
@@ -94,7 +94,7 @@ export const parseSettings_v1 = (data, enforce) => {
if (s.app == null || s.version == null) {
console.log('ERROR: unknown app version, skipping');
} else {
- let settings = {
+ const settings = {
lock: s.lock || null,
pinCode: s.pinCode || null,
};
@@ -123,12 +123,12 @@ export const parseOsc_v1 = (data, enforce) => {
if ('osc' in data) {
console.log('Found OSC definition, importing...');
const s = data.osc;
- let osc = {};
+ const osc = {};
if (s.port) osc.port = s.port;
if (s.portOut) osc.portOut = s.portOut;
if (s.targetIP) osc.targetIP = s.targetIP;
- if (s.enabled !== undefined) osc.enabled = s.enabled;
+ if (typeof s.enabled !== 'undefined') osc.enabled = s.enabled;
// write to db
newOsc = {
@@ -149,7 +149,7 @@ export const parseOsc_v1 = (data, enforce) => {
* @returns {object} - event object data
*/
export const parseHttp_v1 = (data, enforce) => {
- let newHttp = {};
+ const newHttp = {};
if ('http' in data) {
console.log('Found HTTP definition, importing...');
const h = data.osc;
@@ -207,13 +207,13 @@ export const parseAliases_v1 = (data) => {
* @returns {object} - event object data
*/
export const parseUserFields_v1 = (data) => {
- let newUserFields = dbModelv1.userFields;
+ const newUserFields = dbModelv1.userFields;
if ('userFields' in data) {
console.log('Found User Fields definition, importing...');
// we will only be importing the fields we know, so look for that
let fieldsFound = 0;
- for (let n in newUserFields) {
+ for (const n in newUserFields) {
if (n in data.userFields) {
fieldsFound++;
newUserFields[n] = data.userFields[n];
diff --git a/server/src/utils/time.js b/server/src/utils/time.js
index 1a121dfee..f1fcd1e18 100644
--- a/server/src/utils/time.js
+++ b/server/src/utils/time.js
@@ -27,12 +27,7 @@ export const nowInMillis = () => {
* @returns {string} String representing time 00:12:02
*/
-export const stringFromMillis = (
- ms,
- showSeconds = true,
- delim = ':',
- ifNull = '...'
-) => {
+export const stringFromMillis = (ms, showSeconds = true, delim = ':', ifNull = '...') => {
if (ms == null || isNaN(ms)) return ifNull;
const isNegative = ms < 0 ? '-' : '';
const millis = Math.abs(ms);
@@ -57,7 +52,7 @@ export const stringFromMillis = (
export const excelDateStringToMillis = (excelDate) => {
const date = new Date(excelDate);
if (date instanceof Date && !isNaN(date)) {
- const h = date.getUTCHours();
+ const h = date.getHours();
const m = date.getMinutes();
const s = date.getSeconds();
diff --git a/server/src/utils/upload.js b/server/src/utils/upload.js
index 04f8bc0d6..4c1e23c65 100644
--- a/server/src/utils/upload.js
+++ b/server/src/utils/upload.js
@@ -1,26 +1,52 @@
import multer from 'multer';
-import { statSync, mkdirSync } from 'fs';
+import { existsSync, mkdirSync } from 'fs';
+import * as path from 'path';
import { EXCEL_MIME, JSON_MIME } from './parser.js';
+/**
+ * @description Returns public path depending on os
+ * @return {string|*}
+ */
+function getAppDataPath() {
+ switch (process.platform) {
+ case 'darwin': {
+ return path.join(process.env.HOME, 'Library', 'Application Support', 'Ontime');
+ }
+ case 'win32': {
+ return path.join(process.env.APPDATA, 'Ontime');
+ }
+ case 'linux': {
+ return path.join(process.env.HOME, '.Ontime');
+ }
+ default: {
+ return '';
+ }
+ }
+}
+
// Define multer storage object
const storage = multer.diskStorage({
destination: function (req, file, cb) {
- let newDestination = 'uploads/';
- let stat = null;
- try {
- stat = statSync(newDestination);
- } catch (err) {
- mkdirSync(newDestination);
+ // get platform path
+ const appDataPath = getAppDataPath();
+ if (appDataPath === '') {
+ throw new Error('Could not resolve public folder for platform');
}
- if (stat && !stat.isDirectory()) {
- throw new Error(
- `Directory cannot be created because an inode of a different type exists at ${newDestination}`
- );
+ // append uploads folder
+ const newDestination = path.join(appDataPath, 'uploads');
+
+ // Create directory if not exist
+ if (!existsSync(newDestination)) {
+ try {
+ mkdirSync(newDestination);
+ } catch (err) {
+ throw new Error('Could not create directory');
+ }
}
cb(null, newDestination);
},
filename: function (req, file, cb) {
- cb(null, Date.now() + '--' + file.originalname);
+ cb(null, `${Date.now()}--${file.originalname}`);
},
});
diff --git a/server/src/utils/url.js b/server/src/utils/url.js
index cad293cf6..9da592e10 100644
--- a/server/src/utils/url.js
+++ b/server/src/utils/url.js
@@ -3,8 +3,7 @@
* @param {string} url - URL to be checked
* @returns {string} Sanitized url
*/
-export const cleanURL = (url) => {
-
+export const cleanURL = (url) => {
// trim whitespaces
let r = url.trim();
@@ -12,10 +11,9 @@ export const cleanURL = (url) => {
r = r.split(' ').join('%20');
// contain only allowed characters
- r = r.replace(/([^\x00-\x7F]|[@\s<>\[\]{}|\\^])+/g, '')
-
+ r = r.replace(/([@\s<>[\]{}|\\^])+/g, '');
// starts with http://
- if (!r.startsWith('http://')) r = `http://${r}`
+ if (!r.startsWith('http://')) r = `http://${r}`;
return r;
-}
\ No newline at end of file
+};
diff --git a/server/src/yarn.lock b/server/src/yarn.lock
index 34b54ad84..14a6e559d 100644
--- a/server/src/yarn.lock
+++ b/server/src/yarn.lock
@@ -1103,10 +1103,6 @@ once@^1.3.0:
dependencies:
wrappy "1"
-"ontime-utils@link: ../server/utils":
- version "0.0.0"
- uid ""
-
optionator@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
diff --git a/server/utils/__tests__/time.tests.js b/server/utils/__tests__/time.tests.js
deleted file mode 100644
index 5f11bb933..000000000
--- a/server/utils/__tests__/time.tests.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import { excelDateStringToMillis, stringFromMillis } from '../time.js';
-
-describe('test string to millis function', () => {
- it('test with null values', () => {
- const t = { val: null, result: '...' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with valid millis', () => {
- const t = { val: 3600000, result: '01:00:00' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with negative millis', () => {
- const t = { val: -3600000, result: '-01:00:00' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with -1', () => {
- const t = { val: -1, result: '-00:00:00' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with 0', () => {
- const t = { val: 0, result: '00:00:00' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with -0', () => {
- const t = { val: -0, result: '00:00:00' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with 999', () => {
- const t = { val: 999, result: '00:00:00' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with 1000', () => {
- const t = { val: 1000, result: '00:00:01' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with 86400000 (24 hours)', () => {
- const t = { val: 86400000, result: '00:00:00' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with 86401000 (24 hours and 1 second)', () => {
- const t = { val: 86401000, result: '00:00:01' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-
- it('test with -86401000 (-24 hours and 1 second)', () => {
- const t = { val: -86401000, result: '-00:00:01' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-});
-
-describe('test stringFromMillis handles partial secs', () => {
- it('test with 1795829', () => {
- const t = { val: 1795829, result: '00:29:55' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
- it('test with 1797482', () => {
- const t = { val: 1797482, result: '00:29:57' };
- expect(stringFromMillis(t.val)).toBe(t.result);
- });
-});
-
-describe('test excel date parser', () => {
- it('handles an invalid date string', () => {
- const s = 'hello';
- expect(excelDateStringToMillis(s)).toBe(0);
- });
-});
diff --git a/server/utils/package.json b/server/utils/package.json
deleted file mode 100644
index 3a02c4564..000000000
--- a/server/utils/package.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "ontime-utils",
- "type": "module",
- "private": true,
- "version": "1.0.0",
- "description": "ontime app utility functions",
- "dependencies": {
- "nanoid": "^3.2.0"
- },
- "devDependencies": {}
-}
diff --git a/server/utils/yarn.lock b/server/utils/yarn.lock
deleted file mode 100644
index 7a614f4b1..000000000
--- a/server/utils/yarn.lock
+++ /dev/null
@@ -1,8 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-nanoid@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
- integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
diff --git a/server/yarn.lock b/server/yarn.lock
index 9fd474c52..c5b0203a4 100644
--- a/server/yarn.lock
+++ b/server/yarn.lock
@@ -538,16 +538,18 @@
global-agent "^3.0.0"
global-tunnel-ng "^2.7.1"
-"@electron/universal@1.0.5":
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.5.tgz#b812340e4ef21da2b3ee77b2b4d35c9b86defe37"
- integrity sha512-zX9O6+jr2NMyAdSkwEUlyltiI4/EBLu2Ls/VD3pUQdi3cAYeYfdQnT2AJJ38HE4QxLccbU13LSpccw1IWlkyag==
+"@electron/universal@1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.2.0.tgz#518cac72bccd79c00bf41345119e6fdbabdb871d"
+ integrity sha512-eu20BwNsrMPKoe2bZ3/l9c78LclDvxg3PlVXrQf3L50NaUuW5M59gbPytI+V4z7/QMrohUHetQaU0ou+p1UG9Q==
dependencies:
"@malept/cross-spawn-promise" "^1.1.0"
- asar "^3.0.3"
+ asar "^3.1.0"
debug "^4.3.1"
dir-compare "^2.4.0"
fs-extra "^9.0.1"
+ minimatch "^3.0.4"
+ plist "^3.0.4"
"@eslint/eslintrc@^1.0.5":
version "1.0.5"
@@ -853,6 +855,11 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
+"@tootallnate/once@2":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
+ integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
+
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
version "7.1.17"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.17.tgz#f50ac9d20d64153b510578d84f9643f9a3afbe64"
@@ -1137,29 +1144,29 @@ anymatch@^3.0.3, anymatch@~3.1.2:
normalize-path "^3.0.0"
picomatch "^2.0.4"
-app-builder-bin@3.7.1:
- version "3.7.1"
- resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.7.1.tgz#cb0825c5e12efc85b196ac3ed9c89f076c61040e"
- integrity sha512-ql93vEUq6WsstGXD+SBLSIQw6SNnhbDEM0swzgugytMxLp3rT24Ag/jcC80ZHxiPRTdew1niuR7P3/FCrDqIjw==
+app-builder-bin@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-4.0.0.tgz#1df8e654bd1395e4a319d82545c98667d7eed2f0"
+ integrity sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==
-app-builder-lib@22.14.5:
- version "22.14.5"
- resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.14.5.tgz#a61a50b132b858e98fdc70b6b88994ae99b4f96d"
- integrity sha512-k3VwKP4kpsnUaXoUkm1s4zaSHPHIMFnN4kPMU9yXaKmE1LfHHqBaEah5bXeTAX5V/BC41wFdg8CF5vOjvgy8Rg==
+app-builder-lib@23.0.3:
+ version "23.0.3"
+ resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-23.0.3.tgz#44c90237abdc4ad9b34a24658bee022828ad6205"
+ integrity sha512-1qrtXYHXJfXhzJnMtVGjIva3067F1qYQubl2oBjI61gCBoCHvhghdYJ57XxXTQQ0VxnUhg1/Iaez87uXp8mD8w==
dependencies:
"7zip-bin" "~5.1.1"
"@develar/schema-utils" "~2.6.5"
- "@electron/universal" "1.0.5"
+ "@electron/universal" "1.2.0"
"@malept/flatpak-bundler" "^0.4.0"
async-exit-hook "^2.0.1"
bluebird-lst "^1.0.9"
- builder-util "22.14.5"
- builder-util-runtime "8.9.1"
+ builder-util "23.0.2"
+ builder-util-runtime "9.0.0"
chromium-pickle-js "^0.2.0"
debug "^4.3.2"
ejs "^3.1.6"
- electron-osx-sign "^0.5.0"
- electron-publish "22.14.5"
+ electron-osx-sign "^0.6.0"
+ electron-publish "23.0.2"
form-data "^4.0.0"
fs-extra "^10.0.0"
hosted-git-info "^4.0.2"
@@ -1195,7 +1202,7 @@ asap@^2.0.0:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
-asar@^3.0.3:
+asar@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/asar/-/asar-3.1.0.tgz#70b0509449fe3daccc63beb4d3c7d2e24d3c6473"
integrity sha512-vyxPxP5arcAqN4F/ebHd/HhwnAiZtwhglvdmc7BR2f0ywbVNTOpSeyhLDbGXtE/y58hv1oC75TaNIXutnsOZsQ==
@@ -1464,29 +1471,31 @@ buffer@^5.1.0, buffer@^5.6.0:
base64-js "^1.3.1"
ieee754 "^1.1.13"
-builder-util-runtime@8.9.1:
- version "8.9.1"
- resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.9.1.tgz#25f066b3fbc20b3e6236a9b956b1ebb0e33ff66a"
- integrity sha512-c8a8J3wK6BIVLW7ls+7TRK9igspTbzWmUqxFbgK0m40Ggm6efUbxtWVCGIjc+dtchyr5qAMAUL6iEGRdS/6vwg==
+builder-util-runtime@9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.0.0.tgz#3a40ba7382712ccdb24471567f91d7c167e00830"
+ integrity sha512-SkpEtSmTkREDHRJnxKEv43aAYp8sYWY8fxYBhGLBLOBIRXeaIp6Kv3lBgSD7uR8jQtC7CA659sqJrpSV6zNvSA==
dependencies:
debug "^4.3.2"
sax "^1.2.4"
-builder-util@22.14.5:
- version "22.14.5"
- resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.14.5.tgz#42a18608d2a566c0846e91266464776c8bfb0cc9"
- integrity sha512-zqIHDFJwmA7jV7SC9aI+33MWwT2mWoijH+Ol9IntNAwuuRXoS+7XeJwnhLBXOhcDBzXT4kDzHnRk4JKeaygEYA==
+builder-util@23.0.2:
+ version "23.0.2"
+ resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-23.0.2.tgz#da84a971076397e3a671726f4bb96f0c2214fea7"
+ integrity sha512-HaNHL3axNW/Ms8O1mDx3I07G+ZnZ/TKSWWvorOAPau128cdt9S+lNx5ocbx8deSaHHX4WFXSZVHh3mxlaKJNgg==
dependencies:
"7zip-bin" "~5.1.1"
"@types/debug" "^4.1.6"
"@types/fs-extra" "^9.0.11"
- app-builder-bin "3.7.1"
+ app-builder-bin "4.0.0"
bluebird-lst "^1.0.9"
- builder-util-runtime "8.9.1"
+ builder-util-runtime "9.0.0"
chalk "^4.1.1"
cross-spawn "^7.0.3"
debug "^4.3.2"
fs-extra "^10.0.0"
+ http-proxy-agent "^5.0.0"
+ https-proxy-agent "^5.0.0"
is-ci "^3.0.0"
js-yaml "^4.1.0"
source-map-support "^0.5.19"
@@ -2013,14 +2022,14 @@ dir-compare@^2.4.0:
commander "2.9.0"
minimatch "3.0.4"
-dmg-builder@22.14.5:
- version "22.14.5"
- resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.14.5.tgz#137c0b55e639badcc0b119eb060e6fa4ed61d948"
- integrity sha512-1GvFGQE332bvPamcMwZDqWqfWfJTyyDLOsHMcGi0zs+Jh7JOn6/zuBkHJIWHdsj2QJbhzLVyd2/ZqttOKv7I8w==
+dmg-builder@23.0.3:
+ version "23.0.3"
+ resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-23.0.3.tgz#ea94bc76fcd94612641580f3c6ae42c3f07f3fee"
+ integrity sha512-mBYrHHnSM5PC656TDE+xTGmXIuWHAGmmRfyM+dV0kP+AxtwPof4pAXNQ8COd0/exZQ4dqf72FiPS3B9G9aB5IA==
dependencies:
- app-builder-lib "22.14.5"
- builder-util "22.14.5"
- builder-util-runtime "8.9.1"
+ app-builder-lib "23.0.3"
+ builder-util "23.0.2"
+ builder-util-runtime "9.0.0"
fs-extra "^10.0.0"
iconv-lite "^0.6.2"
js-yaml "^4.1.0"
@@ -2097,17 +2106,17 @@ ejs@^3.1.6:
dependencies:
jake "^10.6.1"
-electron-builder@^22.14.5:
- version "22.14.5"
- resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.14.5.tgz#3a25547bd4fe3728d4704da80956a794c5c31496"
- integrity sha512-N73hSbXFz6Mz5Z6h6C5ly6CB+dUN6k1LuCDJjI8VF47bMXv/QE0HE+Kkb0GPKqTqM7Hsk/yIYX+kHCfSkR5FGg==
+electron-builder@^23.0.3:
+ version "23.0.3"
+ resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-23.0.3.tgz#16264a0d8e3d40da1467bcc8ef7917538b54a3bc"
+ integrity sha512-0lnTsljAgcOMuIiOjPcoFf+WxOOe/O04hZPgIvvUBXIbz3kolbNu0Xdch1f5WuQ40NdeZI7oqs8Eo395PcuGHQ==
dependencies:
"@types/yargs" "^17.0.1"
- app-builder-lib "22.14.5"
- builder-util "22.14.5"
- builder-util-runtime "8.9.1"
+ app-builder-lib "23.0.3"
+ builder-util "23.0.2"
+ builder-util-runtime "9.0.0"
chalk "^4.1.1"
- dmg-builder "22.14.5"
+ dmg-builder "23.0.3"
fs-extra "^10.0.0"
is-ci "^3.0.0"
lazy-val "^1.0.5"
@@ -2115,10 +2124,10 @@ electron-builder@^22.14.5:
update-notifier "^5.1.0"
yargs "^17.0.1"
-electron-osx-sign@^0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz#fc258c5e896859904bbe3d01da06902c04b51c3a"
- integrity sha512-icoRLHzFz/qxzDh/N4Pi2z4yVHurlsCAYQvsCSG7fCedJ4UJXBS6PoQyGH71IfcqKupcKeK7HX/NkyfG+v6vlQ==
+electron-osx-sign@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz#9b69c191d471d9458ef5b1e4fdd52baa059f1bb8"
+ integrity sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg==
dependencies:
bluebird "^3.5.0"
compare-version "^0.1.2"
@@ -2127,14 +2136,14 @@ electron-osx-sign@^0.5.0:
minimist "^1.2.0"
plist "^3.0.1"
-electron-publish@22.14.5:
- version "22.14.5"
- resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.14.5.tgz#34bcdce671f0e651330db20040d6919c77c94bd6"
- integrity sha512-h+NANRdaA0PqGF15GKvorseWPzh1PXa/zx4I37//PIokW8eKIov8ky23foUSb55ZFWUHGpxQJux7y2NCfBtQeg==
+electron-publish@23.0.2:
+ version "23.0.2"
+ resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-23.0.2.tgz#aa11419ae57b847df4beb63b95e2b2a43161957c"
+ integrity sha512-8gMYgWqv96lc83FCm85wd+tEyxNTJQK7WKyPkNkO8GxModZqt1GO8S+/vAnFGxilS/7vsrVRXFfqiCDUCSuxEg==
dependencies:
"@types/fs-extra" "^9.0.11"
- builder-util "22.14.5"
- builder-util-runtime "8.9.1"
+ builder-util "23.0.2"
+ builder-util-runtime "9.0.0"
chalk "^4.1.1"
fs-extra "^10.0.0"
lazy-val "^1.0.5"
@@ -2873,6 +2882,15 @@ http-proxy-agent@^4.0.1:
agent-base "6"
debug "4"
+http-proxy-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
+ integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==
+ dependencies:
+ "@tootallnate/once" "2"
+ agent-base "6"
+ debug "4"
+
http-signature@~1.3.6:
version "1.3.6"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9"