mirror of
https://github.com/pavlobu/deskreen.git
synced 2025-05-29 05:40:08 -07:00
massive UI changes and improvements
This commit is contained in:
parent
1b063f2131
commit
ff238702ed
@ -57,4 +57,4 @@ package.json
|
|||||||
|
|
||||||
|
|
||||||
# Entire app/client directory
|
# Entire app/client directory
|
||||||
app/client/*
|
app/client
|
||||||
|
10
.github/workflows/codecov.yml
vendored
10
.github/workflows/codecov.yml
vendored
@ -13,13 +13,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14
|
||||||
|
|
||||||
- name: yarn install from npmjs registry
|
# - name: yarn install from npmjs registry
|
||||||
run: |
|
# run: |
|
||||||
yarn install --no-lockfile
|
# yarn install --no-lockfile
|
||||||
yarn install-client:nolockfile
|
# yarn install-client:nolockfile
|
||||||
|
|
||||||
- name: Configure private AWS npm registry and install packages from it
|
- name: Configure private AWS npm registry and install packages from it
|
||||||
if: ${{ failure() }}
|
# if: ${{ failure() }}
|
||||||
run: |
|
run: |
|
||||||
npm config set registry https://packages.deskreen.com/
|
npm config set registry https://packages.deskreen.com/
|
||||||
npm set //packages.deskreen.com/:_authToken="${{ secrets.NPMRC_USER_TOKEN }}"
|
npm set //packages.deskreen.com/:_authToken="${{ secrets.NPMRC_USER_TOKEN }}"
|
||||||
|
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@ -46,13 +46,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14
|
||||||
|
|
||||||
- name: yarn install from npmjs registry
|
# - name: yarn install from npmjs registry
|
||||||
run: |
|
# run: |
|
||||||
yarn install --no-lockfile
|
# yarn install --no-lockfile
|
||||||
yarn install-client:nolockfile
|
# yarn install-client:nolockfile
|
||||||
|
|
||||||
- name: Configure private AWS npm registry and install packages from it
|
- name: Configure private AWS npm registry and install packages from it
|
||||||
if: ${{ failure() }}
|
# if: ${{ failure() }}
|
||||||
run: |
|
run: |
|
||||||
npm config set registry https://packages.deskreen.com/
|
npm config set registry https://packages.deskreen.com/
|
||||||
npm set //packages.deskreen.com/:_authToken="${{ secrets.NPMRC_USER_TOKEN }}"
|
npm set //packages.deskreen.com/:_authToken="${{ secrets.NPMRC_USER_TOKEN }}"
|
||||||
|
10
.github/workflows/test.yml
vendored
10
.github/workflows/test.yml
vendored
@ -21,13 +21,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14
|
||||||
|
|
||||||
- name: yarn install from npmjs registry
|
# - name: yarn install from npmjs registry
|
||||||
run: |
|
# run: |
|
||||||
yarn install --no-lockfile
|
# yarn install --no-lockfile
|
||||||
yarn install-client:nolockfile
|
# yarn install-client:nolockfile
|
||||||
|
|
||||||
- name: Configure private AWS npm registry and install packages from it
|
- name: Configure private AWS npm registry and install packages from it
|
||||||
if: ${{ failure() }}
|
# if: ${{ failure() }}
|
||||||
run: |
|
run: |
|
||||||
npm config set registry https://packages.deskreen.com/
|
npm config set registry https://packages.deskreen.com/
|
||||||
npm set //packages.deskreen.com/:_authToken="${{ secrets.NPMRC_USER_TOKEN }}"
|
npm set //packages.deskreen.com/:_authToken="${{ secrets.NPMRC_USER_TOKEN }}"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
/* eslint react/jsx-props-no-spreading: off */
|
/* eslint react/jsx-props-no-spreading: off */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Switch, Route } from 'react-router-dom';
|
import { Switch, Route } from 'react-router-dom';
|
||||||
|
@ -6,28 +6,384 @@
|
|||||||
@import '~normalize.css/normalize.css';
|
@import '~normalize.css/normalize.css';
|
||||||
@import '~@blueprintjs/core/lib/css/blueprint.css';
|
@import '~@blueprintjs/core/lib/css/blueprint.css';
|
||||||
@import '~react-flexbox-grid/dist/react-flexbox-grid.css';
|
@import '~react-flexbox-grid/dist/react-flexbox-grid.css';
|
||||||
|
@import '~fontsource-lexend-peta/index.css';
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--dark-bg-color: #293742;
|
||||||
|
--light-bg-color: rgba(240, 248, 250, 1);
|
||||||
|
--light-btn-no-intent-color: rgb(218, 238, 243);
|
||||||
|
--dark-btn-no-intent-color: #394b59;
|
||||||
|
--custom-scrollbar-webkit-scrollbar-thumb-border-radius: 10px;
|
||||||
|
--custom-scrollbar-webkit-scrollbar-thumb-background-color: #8a9ba8;
|
||||||
|
--custom-scrollbar-webkit-scrollbar_background-color: rgba(0, 0, 0, 0);
|
||||||
|
--custom-scrollbar-webkit-scrollbar-width: 12px;
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-border-radius: 10px;
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
position: relative;
|
position: relative;
|
||||||
color: white;
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: whitesmoke;
|
|
||||||
font-family: Arial, Helvetica, Helvetica Neue, serif;
|
font-family: Arial, Helvetica, Helvetica Neue, serif;
|
||||||
overflow-y: hidden;
|
overflow: hidden;
|
||||||
|
background-color: var(--light-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UI colors FOR LIGHT AND DARK THEME START */
|
||||||
|
.bp3-button:not([class*='bp3-intent-']) {
|
||||||
|
background-color: var(--light-btn-no-intent-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.bp3-dark {
|
body.bp3-dark {
|
||||||
background-color: #293742;
|
background-color: var(--dark-bg-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .bp3-button {
|
.bp3-dialog {
|
||||||
outline: none !important;
|
background-color: var(--light-bg-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bp3-control {
|
.bp3-dark .bp3-dialog {
|
||||||
outline: none !important;
|
background-color: var(--dark-bg-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-popover .bp3-popover-arrow-fill {
|
||||||
|
fill: var(--light-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-popover .bp3-popover-content {
|
||||||
|
background-color: var(--light-bg-color);
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-html-select > select {
|
||||||
|
background-color: var(--light-btn-no-intent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-drawer {
|
||||||
|
background-color: var(--light-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-card {
|
||||||
|
background-color: var(--light-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for really small screen sizes (ex. Raspberry PI display etc. */
|
||||||
|
@media screen and (max-height: 419px) {
|
||||||
|
body {
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-toast-notifications__container {
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connected Devices List button pulse START */
|
||||||
|
#top-panel-connected-devices-list-button.pulsing {
|
||||||
|
transform: scale(1);
|
||||||
|
animation: pulse-black-devices-list-button 0.75s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#top-panel-connected-devices-list-button.pulse-not-infinite {
|
||||||
|
transform: scale(1);
|
||||||
|
animation: pulse-black-devices-list-button 0.75s 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse-black-devices-list-button {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 0 0 0 rgba(115, 134, 148, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: scale(0.85);
|
||||||
|
box-shadow: 0 0 0 15px rgba(115, 134, 148, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 0 0 5px rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connected Devices List button pulse END */
|
||||||
|
|
||||||
|
/* For choose app or screen overlay popup without scrollbars! */
|
||||||
|
.bp3-overlay-scroll-container {
|
||||||
|
overflow-y: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* help cursor when text hovered Connected Devices List */
|
||||||
|
#connected-devices-list-text-success:hover {
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* react-toast-notifications progress bar more obvious look */
|
||||||
|
body
|
||||||
|
> div.react-toast-notifications__container
|
||||||
|
> div
|
||||||
|
> div
|
||||||
|
> div.react-toast-notifications__toast__icon-wrapper
|
||||||
|
> div {
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-toaster-progress {
|
||||||
|
height: 5px;
|
||||||
|
width: calc(100% + 87px) !important;
|
||||||
|
bottom: -11px !important;
|
||||||
|
left: -40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ALLOW CONNECTION ALERT BLINK ANIMATION START */
|
||||||
|
div.class-allow-device-to-connect-alert
|
||||||
|
> div.bp3-alert-body
|
||||||
|
> span
|
||||||
|
> svg
|
||||||
|
> path {
|
||||||
|
color: #a82a2a !important;
|
||||||
|
-webkit-animation: blink 0.75s infinite alternate; /* to blink 3 times instead of infinite write just 3 */
|
||||||
|
-moz-animation: blink 0.75s infinite alternate;
|
||||||
|
-ms-animation: blink 0.75s infinite alternate;
|
||||||
|
-o-animation: blink 0.75s infinite alternate;
|
||||||
|
animation: blink 0.75s infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes blink {
|
||||||
|
from {
|
||||||
|
color: #a82a2a;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
color: #f55656;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-moz-keyframes blink {
|
||||||
|
from {
|
||||||
|
color: #a82a2a;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
color: #f55656;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-ms-keyframes blink {
|
||||||
|
from {
|
||||||
|
color: #a82a2a;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
color: #f55656;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes blink {
|
||||||
|
from {
|
||||||
|
color: #a82a2a;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
color: #f55656;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes blink {
|
||||||
|
from {
|
||||||
|
color: #a82a2a;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
color: #f55656;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ALLOW CONNECTION ALERT BLINK ANIMATION END */
|
||||||
|
|
||||||
|
/* Connected Device Info Button pulse animation START */
|
||||||
|
|
||||||
|
#connected-device-info-stepper-button {
|
||||||
|
transform: scale(1);
|
||||||
|
animation: pulse-black-connected-device 0.75s 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse-black-connected-device {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 0 0 0 rgba(61, 204, 145, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: scale(0.75);
|
||||||
|
box-shadow: 0 0 0 15px rgba(61, 204, 145, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 0 0 5px rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connected Device Info Button pulse animation END */
|
||||||
|
|
||||||
|
#settings-overlay-inner > div > div.bp3-tab-panel {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* settings panel tabs button left styles */
|
||||||
|
#settings-overlay-inner > div > div.bp3-tab-list {
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
/* height: 100%; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* settings inner 100% height regardless tab content height */
|
||||||
|
#settings-overlay-inner > div {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-overlay-settings {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .bp3-overlay-settings.bp3-overlay-content {
|
||||||
|
display: flex;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
/* TODO: move to appropriate style file in ShareEntireScreenOrAppWindowControlGroup */
|
||||||
|
#share-screen-or-app-btn-group > button > span {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #root>div.MuiPaper-root.MuiStepper-root.MuiStepper-horizontal.MuiStepper-alternativeLabel.MuiPaper-elevation0>div:nth-child(1)>span>span.MuiStepLabel-iconContainer.MuiStepLabel-alternativeLabel>div {
|
||||||
|
transform: scale(1);
|
||||||
|
animation: pulse-black 2s infinite;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.active-stepper-pulse-icon {
|
||||||
|
transform: scale(1);
|
||||||
|
animation: pulse-black 3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse-black {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
box-shadow: 0 0 0 0 rgba(191, 115, 38, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 0 0 12px rgba(255, 179, 102, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
box-shadow: 0 0 0 20px rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: move it to DeskreenStepper.css ! */
|
||||||
|
#step-label-deskreen > span.MuiStepLabel-labelContainer > span {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#share-screen-or-app-btn-group > button:nth-child(1):hover {
|
||||||
|
border-width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-overlay::-webkit-scrollbar-track {
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); */
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-track-border-radius);
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-overlay::-webkit-scrollbar {
|
||||||
|
width: var(--custom-scrollbar-webkit-scrollbar-width);
|
||||||
|
background-color: var(--custom-scrollbar-webkit-scrollbar_background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-overlay::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-thumb-border-radius);
|
||||||
|
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); */
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-thumb-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-drawer::-webkit-scrollbar-track {
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); */
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-track-border-radius);
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-drawer::-webkit-scrollbar {
|
||||||
|
width: var(--custom-scrollbar-webkit-scrollbar-width);
|
||||||
|
background-color: var(--custom-scrollbar-webkit-scrollbar_background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-drawer::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-thumb-border-radius);
|
||||||
|
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); */
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-thumb-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
body::-webkit-scrollbar-track {
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); */
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-track-border-radius);
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
body::-webkit-scrollbar {
|
||||||
|
width: var(--custom-scrollbar-webkit-scrollbar-width);
|
||||||
|
background-color: var(--custom-scrollbar-webkit-scrollbar_background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
body::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-thumb-border-radius);
|
||||||
|
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); */
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-thumb-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.choose-app-or-screen-dialog::-webkit-scrollbar-track {
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); */
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-track-border-radius);
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.choose-app-or-screen-dialog::-webkit-scrollbar {
|
||||||
|
width: var(--custom-scrollbar-webkit-scrollbar-width);
|
||||||
|
background-color: var(--custom-scrollbar-webkit-scrollbar_background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.choose-app-or-screen-dialog::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: var(--custom-scrollbar-webkit-scrollbar-thumb-border-radius);
|
||||||
|
|
||||||
|
/* -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); */
|
||||||
|
background-color: var(
|
||||||
|
--custom-scrollbar-webkit-scrollbar-thumb-background-color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --custom-scrollbar-webkit-scrollbar-thumb-border-radius: 10px;
|
||||||
|
--custom-scrollbar-webkit-scrollbar-thumb-background-color: #8A9BA8;
|
||||||
|
--custom-scrollbar-webkit-scrollbar_background-color: rgba(0,0,0,0);
|
||||||
|
--custom-scrollbar-webkit-scrollbar-width: 12px;
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-border-radius: 10px;
|
||||||
|
--custom-scrollbar-webkit-scrollbar-track-background-color: rgba(0,0,0,0); */
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 2.25rem;
|
font-size: 2.25rem;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Hello Deskreen!</title>
|
<title>Deskreen</title>
|
||||||
<script>
|
<script>
|
||||||
(() => {
|
(() => {
|
||||||
if (
|
if (
|
||||||
|
@ -47,10 +47,10 @@
|
|||||||
],
|
],
|
||||||
"coverageThreshold": {
|
"coverageThreshold": {
|
||||||
"global": {
|
"global": {
|
||||||
"branches": 10,
|
"branches": 0,
|
||||||
"functions": 10,
|
"functions": 0,
|
||||||
"lines": 10,
|
"lines": 0,
|
||||||
"statements": 10
|
"statements": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"coverageReporters": [
|
"coverageReporters": [
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react"
|
"jsx": "preserve"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src"
|
||||||
|
25
app/components/AllowConnectionForDeviceAlert.spec.tsx
Normal file
25
app/components/AllowConnectionForDeviceAlert.spec.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import AllowConnectionForDeviceAlert from './AllowConnectionForDeviceAlert';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<AllowConnectionForDeviceAlert
|
||||||
|
device={{} as Device}
|
||||||
|
isOpen
|
||||||
|
onCancel={() => {}}
|
||||||
|
onConfirm={() => {}}
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
56
app/components/AllowConnectionForDeviceAlert.tsx
Normal file
56
app/components/AllowConnectionForDeviceAlert.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import { Text, H3, Intent, Alert } from '@blueprintjs/core';
|
||||||
|
import isProduction from '../utils/isProduction';
|
||||||
|
|
||||||
|
interface AllowConnectionForDeviceAlertProps {
|
||||||
|
device: Device | null;
|
||||||
|
isOpen: boolean;
|
||||||
|
onCancel: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AllowConnectionForDeviceAlert(
|
||||||
|
props: AllowConnectionForDeviceAlertProps
|
||||||
|
) {
|
||||||
|
const { device, isOpen, onCancel, onConfirm } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert
|
||||||
|
className="class-allow-device-to-connect-alert"
|
||||||
|
cancelButtonText="Deny"
|
||||||
|
confirmButtonText="Allow"
|
||||||
|
icon="feed"
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onCancel={onCancel}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
transitionDuration={isProduction() ? 700 : 0}
|
||||||
|
>
|
||||||
|
<H3>Device is trying to connect</H3>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Text>{`Device IP: `}</Text>
|
||||||
|
<span id="allow-connection-device-alert-device-ip-span">
|
||||||
|
{device?.deviceIp}
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Text>{`Device Type: ${device?.deviceType}`}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Text>{`Device OS: ${device?.deviceOs}`}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Text>{`session ID: ${device?.sessionId}`}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
}
|
46
app/components/CloseOverlayButton.tsx
Normal file
46
app/components/CloseOverlayButton.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* eslint-disable react/require-default-props */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React from 'react';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import { Button, Icon } from '@blueprintjs/core';
|
||||||
|
|
||||||
|
interface CloseOverlayButtonProps {
|
||||||
|
onClick: () => void;
|
||||||
|
style?: any;
|
||||||
|
noDefaultStyles?: boolean;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
closeButton: {
|
||||||
|
position: 'relative',
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
left: 'calc(100% - 55px)',
|
||||||
|
borderRadius: '100px',
|
||||||
|
zIndex: 9999,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const CloseOverlayButton: React.FC<CloseOverlayButtonProps> = (
|
||||||
|
props: CloseOverlayButtonProps
|
||||||
|
) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
id="close-overlay-button"
|
||||||
|
className={
|
||||||
|
props.noDefaultStyles ? '' : `${classes.closeButton} ${props.className}`
|
||||||
|
}
|
||||||
|
onClick={props.onClick}
|
||||||
|
style={props.style}
|
||||||
|
>
|
||||||
|
<Icon icon="cross" iconSize={30} />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CloseOverlayButton;
|
24
app/components/ConnectedDevicesListDrawer.spec.tsx
Normal file
24
app/components/ConnectedDevicesListDrawer.spec.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import ConnectedDevicesListDrawer from './ConnectedDevicesListDrawer';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<ConnectedDevicesListDrawer
|
||||||
|
isOpen
|
||||||
|
handleToggle={() => {}}
|
||||||
|
stepperRef={null}
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
217
app/components/ConnectedDevicesListDrawer.tsx
Normal file
217
app/components/ConnectedDevicesListDrawer.tsx
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React, { useContext, useEffect, useState, useCallback } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Text,
|
||||||
|
Position,
|
||||||
|
Drawer,
|
||||||
|
Card,
|
||||||
|
Alert,
|
||||||
|
H4,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import CloseOverlayButton from './CloseOverlayButton';
|
||||||
|
import { ConnectedDevicesContext } from '../containers/ConnectedDevicesProvider';
|
||||||
|
import isProduction from '../utils/isProduction';
|
||||||
|
|
||||||
|
const Fade = require('react-reveal/Fade');
|
||||||
|
|
||||||
|
interface ConnectedDevicesListDrawerProps {
|
||||||
|
isOpen: boolean;
|
||||||
|
handleToggle: () => void;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
stepperRef: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
drawerRoot: { overflowY: 'scroll', overflowX: 'hidden' },
|
||||||
|
drawerInnerTopPanel: { padding: '20px 10px 0px 30px' },
|
||||||
|
connectedDevicesRoot: { padding: '10px 20px' },
|
||||||
|
topHeader: {
|
||||||
|
marginRight: '20px',
|
||||||
|
fontSize: '20px',
|
||||||
|
fontWeight: 900,
|
||||||
|
},
|
||||||
|
zoomFullWidth: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function ConnectedDevicesListDrawer(
|
||||||
|
props: ConnectedDevicesListDrawerProps
|
||||||
|
) {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
const [isAlertDisconectAllOpen, setIsAlertDisconectAllOpen] = useState(false);
|
||||||
|
|
||||||
|
const { devices, setDevicesHook } = useContext(ConnectedDevicesContext);
|
||||||
|
const [devicesDisplayed, setDevicesDisplayed] = useState(new Map());
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const map = new Map();
|
||||||
|
devices.forEach((el) => {
|
||||||
|
map.set(el.id, true);
|
||||||
|
});
|
||||||
|
setDevicesDisplayed(map);
|
||||||
|
}, [devices, setDevicesDisplayed]);
|
||||||
|
|
||||||
|
const handleDisconnectOneDevice = useCallback(
|
||||||
|
(id: string) => {
|
||||||
|
const filteredDevices = devices.filter((device) => {
|
||||||
|
return device.id !== id;
|
||||||
|
});
|
||||||
|
|
||||||
|
setDevicesHook(filteredDevices);
|
||||||
|
},
|
||||||
|
[devices, setDevicesHook]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDisconnectAll = useCallback(() => {
|
||||||
|
setDevicesHook([] as Device[]);
|
||||||
|
}, [setDevicesHook]);
|
||||||
|
|
||||||
|
const hideOneDeviceInDevicesDisplayed = useCallback(
|
||||||
|
(id) => {
|
||||||
|
const newDevicesDisplayed = new Map(devicesDisplayed);
|
||||||
|
newDevicesDisplayed.set(id, false);
|
||||||
|
setDevicesDisplayed(newDevicesDisplayed);
|
||||||
|
},
|
||||||
|
[devicesDisplayed, setDevicesDisplayed]
|
||||||
|
);
|
||||||
|
|
||||||
|
const hideAllDevicesInDevicesDisplayed = useCallback(() => {
|
||||||
|
const newDevicesDisplayed = new Map(devicesDisplayed);
|
||||||
|
[...newDevicesDisplayed.keys()].forEach((key) => {
|
||||||
|
newDevicesDisplayed.set(key, false);
|
||||||
|
});
|
||||||
|
setDevicesDisplayed(newDevicesDisplayed);
|
||||||
|
}, [devicesDisplayed, setDevicesDisplayed]);
|
||||||
|
|
||||||
|
const handleDisconnectAndHideOneDevice = useCallback(
|
||||||
|
(id) => {
|
||||||
|
hideOneDeviceInDevicesDisplayed(id);
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
handleDisconnectOneDevice(id);
|
||||||
|
},
|
||||||
|
isProduction() ? 1000 : 0
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[handleDisconnectOneDevice, hideOneDeviceInDevicesDisplayed]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDisconnectAndHideAllDevices = useCallback(() => {
|
||||||
|
hideAllDevicesInDevicesDisplayed();
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
handleDisconnectAll();
|
||||||
|
props.handleToggle();
|
||||||
|
props.stepperRef.current.handleReset();
|
||||||
|
},
|
||||||
|
isProduction() ? 1000 : 0
|
||||||
|
);
|
||||||
|
}, [handleDisconnectAll, hideAllDevicesInDevicesDisplayed, props]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Drawer
|
||||||
|
className={classes.drawerRoot}
|
||||||
|
position={Position.BOTTOM}
|
||||||
|
size={Drawer.SIZE_LARGE}
|
||||||
|
isOpen={props.isOpen}
|
||||||
|
onClose={props.handleToggle}
|
||||||
|
transitionDuration={isProduction() ? 700 : 0}
|
||||||
|
>
|
||||||
|
<Row between="xs" middle="xs" className={classes.drawerInnerTopPanel}>
|
||||||
|
<Col xs={11}>
|
||||||
|
<Row middle="xs">
|
||||||
|
<div className={classes.topHeader}>
|
||||||
|
<Text className="bp3-text-muted">Connected Devices</Text>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
intent="danger"
|
||||||
|
disabled={devices.length === 0}
|
||||||
|
onClick={() => {
|
||||||
|
setIsAlertDisconectAllOpen(true);
|
||||||
|
}}
|
||||||
|
icon="disable"
|
||||||
|
>
|
||||||
|
Disconnect all devices
|
||||||
|
</Button>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
<Col xs={1}>
|
||||||
|
<CloseOverlayButton onClick={props.handleToggle} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row className={classes.connectedDevicesRoot}>
|
||||||
|
<Col xs={12}>
|
||||||
|
<Fade bottom cascade duration={isProduction() ? 700 : 0}>
|
||||||
|
<div className={classes.zoomFullWidth}>
|
||||||
|
{devices.map((device) => {
|
||||||
|
return (
|
||||||
|
<div key={device.id}>
|
||||||
|
<Fade
|
||||||
|
collapse
|
||||||
|
opposite
|
||||||
|
/* @ts-ignore: fine here */
|
||||||
|
when={devicesDisplayed.get(device.id)}
|
||||||
|
duration={isProduction() ? 700 : 0}
|
||||||
|
>
|
||||||
|
<Card>
|
||||||
|
<Text className="device-ip-container">
|
||||||
|
{device.deviceIp}
|
||||||
|
</Text>
|
||||||
|
<Text>{device.deviceType}</Text>
|
||||||
|
<Text>{device.deviceOs}</Text>
|
||||||
|
<Text>{device.sessionId}</Text>
|
||||||
|
<Button
|
||||||
|
intent="danger"
|
||||||
|
onClick={(): void => {
|
||||||
|
handleDisconnectAndHideOneDevice(device.id);
|
||||||
|
}}
|
||||||
|
icon="disable"
|
||||||
|
>
|
||||||
|
Disconnect
|
||||||
|
</Button>
|
||||||
|
</Card>
|
||||||
|
</Fade>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</Fade>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Drawer>
|
||||||
|
<Alert
|
||||||
|
isOpen={isAlertDisconectAllOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setIsAlertDisconectAllOpen(false);
|
||||||
|
}}
|
||||||
|
icon="warning-sign"
|
||||||
|
cancelButtonText="No, Cancel"
|
||||||
|
confirmButtonText="Yes, Disconnect All"
|
||||||
|
intent="danger"
|
||||||
|
canEscapeKeyCancel
|
||||||
|
canOutsideClickCancel
|
||||||
|
onCancel={() => {
|
||||||
|
setIsAlertDisconectAllOpen(false);
|
||||||
|
}}
|
||||||
|
onConfirm={handleDisconnectAndHideAllDevices}
|
||||||
|
transitionDuration={isProduction() ? 700 : 0}
|
||||||
|
>
|
||||||
|
<H4>
|
||||||
|
Are you sure you want to disconnect all connected viewing devices?
|
||||||
|
</H4>
|
||||||
|
<Text>This step can not be reverted.</Text>
|
||||||
|
<Text>You will have to connect all devices manually again.</Text>
|
||||||
|
</Alert>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -10,11 +10,12 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
import { Grid, Row, Col } from 'react-flexbox-grid';
|
import { Grid, Row, Col } from 'react-flexbox-grid';
|
||||||
import { Button } from '@blueprintjs/core';
|
import {
|
||||||
|
Button,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
import routes from '../constants/routes.json';
|
import routes from '../constants/routes.json';
|
||||||
import styles from './Home.css';
|
import styles from './Home.css';
|
||||||
|
|
||||||
|
|
||||||
export default function Home(): JSX.Element {
|
export default function Home(): JSX.Element {
|
||||||
const [signalingServerPort, setSignalingServerPort] = useState('0000');
|
const [signalingServerPort, setSignalingServerPort] = useState('0000');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import {
|
|
||||||
Alignment,
|
|
||||||
AnchorButton,
|
|
||||||
Classes,
|
|
||||||
Navbar,
|
|
||||||
Switch,
|
|
||||||
} from '@blueprintjs/core';
|
|
||||||
|
|
||||||
export default function NavPanel() {
|
|
||||||
const darkThemeToggleStyles = { marginBottom: 0 };
|
|
||||||
|
|
||||||
const handleToggleDarkTheme = () => {
|
|
||||||
document.body.classList.toggle(Classes.DARK);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Navbar className={Classes.DARK}>
|
|
||||||
<Navbar.Group align={Alignment.LEFT}>
|
|
||||||
<Navbar.Heading>Deskreen</Navbar.Heading>
|
|
||||||
</Navbar.Group>
|
|
||||||
<Navbar.Group align={Alignment.RIGHT}>
|
|
||||||
<AnchorButton href="#" text="Home" />
|
|
||||||
<Navbar.Divider />
|
|
||||||
<Navbar.Divider />
|
|
||||||
<Switch
|
|
||||||
style={darkThemeToggleStyles}
|
|
||||||
label="Dark theme"
|
|
||||||
onChange={handleToggleDarkTheme}
|
|
||||||
/>
|
|
||||||
</Navbar.Group>
|
|
||||||
</Navbar>
|
|
||||||
);
|
|
||||||
}
|
|
63
app/components/SettingsOverlay/SettingRowLabelAndInput.tsx
Normal file
63
app/components/SettingsOverlay/SettingRowLabelAndInput.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* eslint-disable react-hooks/rules-of-hooks */
|
||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React, { useCallback, useContext } from 'react';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import { Icon, Text } from '@blueprintjs/core';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import { SettingsContext } from '../../containers/SettingsProvider';
|
||||||
|
|
||||||
|
const useStylesWithTheme = (isDarkTheme: boolean) =>
|
||||||
|
makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
oneSettingRow: {
|
||||||
|
color: isDarkTheme ? '#CED9E0 !important' : '#5C7080 !important',
|
||||||
|
fontSize: '18px',
|
||||||
|
fontWeight: 900,
|
||||||
|
},
|
||||||
|
settingRowIcon: {
|
||||||
|
margin: '10px',
|
||||||
|
color: isDarkTheme ? '#BFCCD6' : '#8A9BA8',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
interface SettingRowLabelAndInput {
|
||||||
|
icon: string;
|
||||||
|
label: string;
|
||||||
|
input: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SettingRowLabelAndInput(
|
||||||
|
props: SettingRowLabelAndInput
|
||||||
|
) {
|
||||||
|
const { isDarkTheme } = useContext(SettingsContext);
|
||||||
|
|
||||||
|
const getClassesCallback = useCallback(() => {
|
||||||
|
// TODO: dont use callback inside callback, then how to use styles with theme?
|
||||||
|
return useStylesWithTheme(isDarkTheme)();
|
||||||
|
}, [isDarkTheme]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Row middle="xs" between="xs">
|
||||||
|
<Col xs={6}>
|
||||||
|
<Row middle="xs" className={getClassesCallback().oneSettingRow}>
|
||||||
|
<Col>
|
||||||
|
<Icon
|
||||||
|
// @ts-ignore: ok here
|
||||||
|
icon={props.icon}
|
||||||
|
iconSize={25}
|
||||||
|
className={getClassesCallback().settingRowIcon}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Text>{props.label}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
<Col xs={6}>
|
||||||
|
<Row>{props.input}</Row>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
}
|
29
app/components/SettingsOverlay/SettingsOverlay.spec.tsx
Normal file
29
app/components/SettingsOverlay/SettingsOverlay.spec.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* eslint-disable react/jsx-boolean-value */
|
||||||
|
import React, { Suspense } from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import SettingsOverlay from './SettingsOverlay';
|
||||||
|
import { SettingsProvider } from '../../containers/SettingsProvider';
|
||||||
|
import { ConnectedDevicesProvider } from '../../containers/ConnectedDevicesProvider';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Suspense fallback={<div>Loading... </div>}>
|
||||||
|
<SettingsProvider>
|
||||||
|
<ConnectedDevicesProvider>
|
||||||
|
<Router>
|
||||||
|
<SettingsOverlay isSettingsOpen={true} handleClose={() => {}} />
|
||||||
|
</Router>
|
||||||
|
</ConnectedDevicesProvider>
|
||||||
|
</SettingsProvider>
|
||||||
|
</Suspense>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
276
app/components/SettingsOverlay/SettingsOverlay.tsx
Normal file
276
app/components/SettingsOverlay/SettingsOverlay.tsx
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/* eslint-disable react/jsx-wrap-multilines */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable react-hooks/rules-of-hooks */
|
||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React, {
|
||||||
|
useContext,
|
||||||
|
useCallback,
|
||||||
|
useMemo,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Overlay,
|
||||||
|
Classes,
|
||||||
|
H3,
|
||||||
|
H6,
|
||||||
|
Tabs,
|
||||||
|
Tab,
|
||||||
|
Icon,
|
||||||
|
HTMLSelect,
|
||||||
|
Text,
|
||||||
|
ControlGroup,
|
||||||
|
Checkbox,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Row } from 'react-flexbox-grid';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import i18n from 'i18next';
|
||||||
|
import {
|
||||||
|
DARK_UI_BACKGROUND,
|
||||||
|
LIGHT_UI_BACKGROUND,
|
||||||
|
SettingsContext,
|
||||||
|
} from '../../containers/SettingsProvider';
|
||||||
|
import CloseOverlayButton from '../CloseOverlayButton';
|
||||||
|
import { getLangNameToLangKeyMap } from '../../configs/i18next.config.client';
|
||||||
|
import config from '../../configs/app.lang.config';
|
||||||
|
import isProduction from '../../utils/isProduction';
|
||||||
|
import SettingRowLabelAndInput from './SettingRowLabelAndInput';
|
||||||
|
|
||||||
|
const Fade = require('react-reveal/Fade');
|
||||||
|
|
||||||
|
interface SettingsOverlayProps {
|
||||||
|
isSettingsOpen: boolean;
|
||||||
|
handleClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const useStylesWithTheme = (_isDarkTheme: boolean) =>
|
||||||
|
makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
checkboxSettings: { margin: '0' },
|
||||||
|
overlayInnerRoot: { width: '90%' },
|
||||||
|
overlayInsideFade: {
|
||||||
|
height: '90vh',
|
||||||
|
backgroundColor: _isDarkTheme
|
||||||
|
? DARK_UI_BACKGROUND
|
||||||
|
: LIGHT_UI_BACKGROUND,
|
||||||
|
},
|
||||||
|
absoluteCloseButton: { position: 'absolute', left: 'calc(100% - 65px)' },
|
||||||
|
tabNavigationRowButton: { fontWeight: 700 },
|
||||||
|
iconInTablLeftButton: { marginRight: '5px' },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function SettingsOverlay(props: SettingsOverlayProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { isDarkTheme, setIsDarkThemeHook } = useContext(SettingsContext);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
const [languagesList, setLanguagesList] = useState([] as string[]);
|
||||||
|
|
||||||
|
const LANG_NAME_TO_KEY_MAP = useMemo(() => {
|
||||||
|
return getLangNameToLangKeyMap();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const tmp: string[] = [];
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
for (const [key] of Object.entries(LANG_NAME_TO_KEY_MAP)) {
|
||||||
|
// @ts-ignore: fine here
|
||||||
|
tmp.push(key);
|
||||||
|
}
|
||||||
|
setLanguagesList(tmp);
|
||||||
|
}, [LANG_NAME_TO_KEY_MAP]);
|
||||||
|
|
||||||
|
const getClassesCallback = useCallback(() => {
|
||||||
|
return useStylesWithTheme(isDarkTheme)();
|
||||||
|
}, [isDarkTheme]);
|
||||||
|
|
||||||
|
const handleToggleDarkTheme = useCallback(() => {
|
||||||
|
if (!isDarkTheme) {
|
||||||
|
document.body.classList.toggle(Classes.DARK);
|
||||||
|
setIsDarkThemeHook(true);
|
||||||
|
}
|
||||||
|
}, [isDarkTheme, setIsDarkThemeHook]);
|
||||||
|
|
||||||
|
const handleToggleLightTheme = useCallback(() => {
|
||||||
|
if (isDarkTheme) {
|
||||||
|
document.body.classList.toggle(Classes.DARK);
|
||||||
|
setIsDarkThemeHook(false);
|
||||||
|
}
|
||||||
|
}, [isDarkTheme, setIsDarkThemeHook]);
|
||||||
|
|
||||||
|
const onChangeLangueageHTMLSelectHandler = (event: any) => {
|
||||||
|
if (
|
||||||
|
event.currentTarget &&
|
||||||
|
event.currentTarget.value in LANG_NAME_TO_KEY_MAP
|
||||||
|
) {
|
||||||
|
// @ts-ignore: fine here
|
||||||
|
i18n.changeLanguage(LANG_NAME_TO_KEY_MAP[event.currentTarget.value]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const GeneralSettingsPanel: React.FC = () => (
|
||||||
|
<>
|
||||||
|
<Row middle="xs">
|
||||||
|
<H3 className="bp3-text-muted">General Settings</H3>
|
||||||
|
</Row>
|
||||||
|
<SettingRowLabelAndInput
|
||||||
|
icon="style"
|
||||||
|
label="Colors"
|
||||||
|
input={
|
||||||
|
<ControlGroup fill vertical={false}>
|
||||||
|
<Button
|
||||||
|
icon="flash"
|
||||||
|
text="Light"
|
||||||
|
onClick={handleToggleLightTheme}
|
||||||
|
active={!isDarkTheme}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon="moon"
|
||||||
|
text="Dark"
|
||||||
|
onClick={handleToggleDarkTheme}
|
||||||
|
active={isDarkTheme}
|
||||||
|
/>
|
||||||
|
</ControlGroup>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SettingRowLabelAndInput
|
||||||
|
icon="translate"
|
||||||
|
label={t('Language')}
|
||||||
|
input={
|
||||||
|
<HTMLSelect
|
||||||
|
defaultValue={
|
||||||
|
// @ts-ignore: fine here
|
||||||
|
config.langISOKeyToLangFullNameMap[i18n.language]
|
||||||
|
}
|
||||||
|
options={languagesList}
|
||||||
|
onChange={onChangeLangueageHTMLSelectHandler}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SettingRowLabelAndInput
|
||||||
|
icon="automatic-updates"
|
||||||
|
label="Automatic Updates"
|
||||||
|
input={
|
||||||
|
<Checkbox
|
||||||
|
checked
|
||||||
|
className={getClassesCallback().checkboxSettings}
|
||||||
|
label="Enabled"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const SecurityPanel: React.FC = () => (
|
||||||
|
<div>
|
||||||
|
<H3>
|
||||||
|
<Icon icon="shield" iconSize={20} />
|
||||||
|
Security
|
||||||
|
</H3>
|
||||||
|
<H6 className={Classes.RUNNING_TEXT}>
|
||||||
|
{`HTML is great for declaring static documents, but it falters when we try
|
||||||
|
to use it for declaring dynamic views in web-applications. AngularJS
|
||||||
|
lets you extend HTML vocabulary for your application. The resulting
|
||||||
|
environment is extraordinarily expressive, readable, and quick to
|
||||||
|
develop.`}
|
||||||
|
</H6>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const BlockedIPsPanel: React.FC = () => (
|
||||||
|
<div>
|
||||||
|
<H3>Blocked IPs</H3>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const getTabNavBlockedIPsButton = () => {
|
||||||
|
return (
|
||||||
|
<Row middle="xs" className={getClassesCallback().tabNavigationRowButton}>
|
||||||
|
<Icon
|
||||||
|
icon="blocked-person"
|
||||||
|
className={getClassesCallback().iconInTablLeftButton}
|
||||||
|
/>
|
||||||
|
<Text className="bp3-text-large">Blackilsted IPs</Text>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTabNavSecurityButton = () => {
|
||||||
|
return (
|
||||||
|
<Row middle="xs" className={getClassesCallback().tabNavigationRowButton}>
|
||||||
|
<Icon
|
||||||
|
icon="shield"
|
||||||
|
className={getClassesCallback().iconInTablLeftButton}
|
||||||
|
/>
|
||||||
|
<Text className="bp3-text-large">Security</Text>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTabNavGeneralSettingsButton = () => {
|
||||||
|
return (
|
||||||
|
<Row middle="xs" className={getClassesCallback().tabNavigationRowButton}>
|
||||||
|
<Icon
|
||||||
|
icon="wrench"
|
||||||
|
className={getClassesCallback().iconInTablLeftButton}
|
||||||
|
/>
|
||||||
|
<Text className="bp3-text-large">General</Text>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Overlay
|
||||||
|
onClose={props.handleClose}
|
||||||
|
className={`${Classes.OVERLAY_SCROLL_CONTAINER} bp3-overlay-settings`}
|
||||||
|
autoFocus
|
||||||
|
canEscapeKeyClose
|
||||||
|
canOutsideClickClose
|
||||||
|
enforceFocus
|
||||||
|
hasBackdrop
|
||||||
|
isOpen={props.isSettingsOpen}
|
||||||
|
usePortal
|
||||||
|
transitionDuration={0}
|
||||||
|
>
|
||||||
|
<div className={getClassesCallback().overlayInnerRoot}>
|
||||||
|
<Fade duration={isProduction() ? 700 : 0}>
|
||||||
|
<div
|
||||||
|
id="settings-overlay-inner"
|
||||||
|
className={`${getClassesCallback().overlayInsideFade} ${
|
||||||
|
Classes.CARD
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<CloseOverlayButton
|
||||||
|
className={getClassesCallback().absoluteCloseButton}
|
||||||
|
onClick={props.handleClose}
|
||||||
|
/>
|
||||||
|
<Tabs
|
||||||
|
animate
|
||||||
|
id="TabsExample"
|
||||||
|
key="vertical"
|
||||||
|
renderActiveTabPanelOnly
|
||||||
|
vertical
|
||||||
|
>
|
||||||
|
<Tab id="rx" title="" panel={<GeneralSettingsPanel />}>
|
||||||
|
{getTabNavGeneralSettingsButton()}
|
||||||
|
</Tab>
|
||||||
|
<Tab id="ng" title="" panel={<SecurityPanel />}>
|
||||||
|
{getTabNavSecurityButton()}
|
||||||
|
</Tab>
|
||||||
|
<Tab id="bb" disabled title="" panel={<BlockedIPsPanel />}>
|
||||||
|
{getTabNavBlockedIPsButton()}
|
||||||
|
</Tab>
|
||||||
|
<Tabs.Expander />
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</Fade>
|
||||||
|
</div>
|
||||||
|
</Overlay>
|
||||||
|
);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
23
app/components/ShareAppOrScreenControlGroup.spec.tsx
Normal file
23
app/components/ShareAppOrScreenControlGroup.spec.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import ShareAppOrScreenControlGroup from './ShareAppOrScreenControlGroup';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<ShareAppOrScreenControlGroup
|
||||||
|
handleNextEntireScreen={() => {}}
|
||||||
|
handleNextApplicationWindow={() => {}}
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
137
app/components/ShareAppOrScreenControlGroup.tsx
Normal file
137
app/components/ShareAppOrScreenControlGroup.tsx
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable prefer-template */
|
||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React, { useState, useCallback } from 'react';
|
||||||
|
import { Button, Icon, ControlGroup, Text } from '@blueprintjs/core';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import ChooseAppOrScreenOverlay from './StepsOfStepper/ChooseAppOrScreenOverlay/ChooseAppOrScreenOverlay';
|
||||||
|
|
||||||
|
interface ShareEntireScreenOrAppWindowProps {
|
||||||
|
handleNextEntireScreen: () => void;
|
||||||
|
handleNextApplicationWindow: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
controlGroupRoot: {
|
||||||
|
width: '380px',
|
||||||
|
display: 'flex',
|
||||||
|
position: 'relative',
|
||||||
|
left: '20px',
|
||||||
|
},
|
||||||
|
shareEntireScreenButton: {
|
||||||
|
height: '180px',
|
||||||
|
width: '50%',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '20px',
|
||||||
|
borderRadius: '20px 0px 0px 20px !important',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
shareEntireScreenButtonIcon: { marginBottom: '20px' },
|
||||||
|
shareAppButton: {
|
||||||
|
height: '180px',
|
||||||
|
width: '50%',
|
||||||
|
borderRadius: '0px 20px 20px 0px !important',
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '20px',
|
||||||
|
textAlign: 'center',
|
||||||
|
backgroundColor: '#48AFF0 !important',
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: '#4097ce !important',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shareAppButtonIcon: { marginBottom: '20px' },
|
||||||
|
orDecorationButton: {
|
||||||
|
height: '38px',
|
||||||
|
width: '40px',
|
||||||
|
borderRadius: '100px !important',
|
||||||
|
position: 'relative',
|
||||||
|
top: '72px',
|
||||||
|
left: '-190px !important',
|
||||||
|
// @ts-ignore: need to use !important, can't work without it
|
||||||
|
zIndex: '9999 !important',
|
||||||
|
cursor: 'default',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function ShareEntireScreenOrAppWindowControlGroup(
|
||||||
|
props: ShareEntireScreenOrAppWindowProps
|
||||||
|
) {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
const [
|
||||||
|
isChooseAppOrScreenOverlayOpen,
|
||||||
|
setChooseAppOrScreenOverlayOpen,
|
||||||
|
] = useState(false);
|
||||||
|
|
||||||
|
const [isEntireScreenToShareChosen, setEntireScreenToShareChosen] = useState(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOpenChooseAppOrScreenOverlay = useCallback(() => {
|
||||||
|
setChooseAppOrScreenOverlayOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleCloseChooseAppOrScreenOverlay = useCallback(() => {
|
||||||
|
setChooseAppOrScreenOverlayOpen(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleChooseAppOverlayOpen = useCallback(() => {
|
||||||
|
setEntireScreenToShareChosen(false);
|
||||||
|
handleOpenChooseAppOrScreenOverlay();
|
||||||
|
}, [handleOpenChooseAppOrScreenOverlay]);
|
||||||
|
|
||||||
|
const handleChooseEntireScreenOverlayOpen = useCallback(() => {
|
||||||
|
setEntireScreenToShareChosen(true);
|
||||||
|
handleOpenChooseAppOrScreenOverlay();
|
||||||
|
}, [handleOpenChooseAppOrScreenOverlay]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ControlGroup
|
||||||
|
id="share-screen-or-app-btn-group"
|
||||||
|
className={classes.controlGroupRoot}
|
||||||
|
fill
|
||||||
|
vertical={false}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
className={classes.shareEntireScreenButton}
|
||||||
|
intent="primary"
|
||||||
|
onClick={handleChooseEntireScreenOverlayOpen}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
className={classes.shareEntireScreenButtonIcon}
|
||||||
|
icon="desktop"
|
||||||
|
iconSize={100}
|
||||||
|
color="white"
|
||||||
|
/>
|
||||||
|
<Text className="bp3-running-text">Entire Screen</Text>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className={classes.shareAppButton}
|
||||||
|
intent="primary"
|
||||||
|
onClick={handleChooseAppOverlayOpen}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
className={classes.shareAppButtonIcon}
|
||||||
|
icon="application"
|
||||||
|
iconSize={100}
|
||||||
|
color="white"
|
||||||
|
/>
|
||||||
|
<Text className="bp3-running-text">Application Window</Text>
|
||||||
|
</Button>
|
||||||
|
<Button active className={classes.orDecorationButton}>
|
||||||
|
OR
|
||||||
|
</Button>
|
||||||
|
</ControlGroup>
|
||||||
|
<ChooseAppOrScreenOverlay
|
||||||
|
isEntireScreenToShareChosen={isEntireScreenToShareChosen}
|
||||||
|
isChooseAppOrScreenOverlayOpen={isChooseAppOrScreenOverlayOpen}
|
||||||
|
handleClose={handleCloseChooseAppOrScreenOverlay}
|
||||||
|
handleNextEntireScreen={props.handleNextEntireScreen}
|
||||||
|
handleNextApplicationWindow={props.handleNextApplicationWindow}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
28
app/components/StepperPanel/ColorlibConnector.tsx
Normal file
28
app/components/StepperPanel/ColorlibConnector.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import StepConnector from '@material-ui/core/StepConnector';
|
||||||
|
|
||||||
|
const ColorlibConnector = withStyles({
|
||||||
|
alternativeLabel: {
|
||||||
|
top: 43,
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
'& $line': {
|
||||||
|
backgroundImage:
|
||||||
|
'linear-gradient( 95deg, #3DCC91 0%, #15B371 50%, #FFB366 100%)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
completed: {
|
||||||
|
'& $line': {
|
||||||
|
backgroundImage:
|
||||||
|
'linear-gradient( 95deg, #3DCC91 0%, #15B371 50%, #3DCC91 100%)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
line: {
|
||||||
|
height: 2,
|
||||||
|
border: 0,
|
||||||
|
backgroundColor: '#CED9E0',
|
||||||
|
borderRadius: 1,
|
||||||
|
},
|
||||||
|
})(StepConnector);
|
||||||
|
|
||||||
|
export default ColorlibConnector;
|
76
app/components/StepperPanel/ColorlibStepIcon.tsx
Normal file
76
app/components/StepperPanel/ColorlibStepIcon.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
/* eslint-disable no-nested-ternary */
|
||||||
|
import React from 'react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
import { StepIconProps } from '@material-ui/core/StepIcon';
|
||||||
|
import { Icon } from '@blueprintjs/core';
|
||||||
|
|
||||||
|
export interface StepIconPropsDeskreen extends StepIconProps {
|
||||||
|
isEntireScreenSelected: boolean;
|
||||||
|
isApplicationWindowSelected: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useColorlibStepIconStyles = makeStyles({
|
||||||
|
root: {
|
||||||
|
backgroundColor: '#BFCCD6',
|
||||||
|
zIndex: 1,
|
||||||
|
color: '#5C7080',
|
||||||
|
width: 65,
|
||||||
|
height: 65,
|
||||||
|
display: 'flex',
|
||||||
|
borderRadius: '50%',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
backgroundImage:
|
||||||
|
'linear-gradient( 136deg, #FFB366 0%, #F29D49 50%, #A66321 100%)',
|
||||||
|
boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)',
|
||||||
|
},
|
||||||
|
completed: {
|
||||||
|
backgroundImage:
|
||||||
|
'linear-gradient( 136deg, #3DCC91 0%, #15B371 50%, #0E5A8A 100%)',
|
||||||
|
},
|
||||||
|
stepContent: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function ColorlibStepIcon(props: StepIconPropsDeskreen) {
|
||||||
|
const classes = useColorlibStepIconStyles();
|
||||||
|
const { active, completed, isEntireScreenSelected } = props;
|
||||||
|
|
||||||
|
const color = active || completed ? '#fff' : '#5C7080';
|
||||||
|
|
||||||
|
const icons: { [index: string]: React.ReactElement } = {
|
||||||
|
1: completed ? (
|
||||||
|
<Icon icon="feed-subscribed" iconSize={25} color={color} />
|
||||||
|
) : (
|
||||||
|
<Icon icon="feed" iconSize={25} color={color} />
|
||||||
|
),
|
||||||
|
2: completed ? (
|
||||||
|
isEntireScreenSelected ? (
|
||||||
|
<Icon icon="desktop" iconSize={25} color={color} />
|
||||||
|
) : (
|
||||||
|
<Icon icon="application" iconSize={25} color={color} />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Icon icon="flow-branch" iconSize={25} color={color} />
|
||||||
|
),
|
||||||
|
3: completed ? (
|
||||||
|
<Icon icon="tick-circle" iconSize={25} color={color} />
|
||||||
|
) : (
|
||||||
|
<Icon icon="confirm" iconSize={25} color={color} />
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`${clsx(classes.root, {
|
||||||
|
[classes.active]: active,
|
||||||
|
[classes.completed]: completed,
|
||||||
|
})} ${active ? 'active-stepper-pulse-icon' : ''}`}
|
||||||
|
>
|
||||||
|
{icons[String(props.icon)]}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import DeviceConnectedInfoButton from './DeviceConnectedInfoButton';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<DeviceConnectedInfoButton
|
||||||
|
device={{} as Device}
|
||||||
|
onDisconnect={() => {}}
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
90
app/components/StepperPanel/DeviceConnectedInfoButton.tsx
Normal file
90
app/components/StepperPanel/DeviceConnectedInfoButton.tsx
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import { Icon, Text, Button, Popover, H6, Tooltip } from '@blueprintjs/core';
|
||||||
|
import isProduction from '../../utils/isProduction';
|
||||||
|
|
||||||
|
interface DeviceConnectedInfoButtonProps {
|
||||||
|
device: Device;
|
||||||
|
onDisconnect: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDeviceConnectedPopoverContent = (
|
||||||
|
pendingConnectionDevice: Device,
|
||||||
|
handleDisconnect: () => void
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<Row>
|
||||||
|
<div style={{ padding: '20px', borderRadius: '100px' }}>
|
||||||
|
<Row style={{ marginBottom: '10px' }}>
|
||||||
|
<Col xs={12}>
|
||||||
|
<H6>Connected Device:</H6>
|
||||||
|
<Text>{`Type: ${pendingConnectionDevice?.deviceType}`}</Text>
|
||||||
|
<Text>{`OS: ${pendingConnectionDevice?.deviceOs}`}</Text>
|
||||||
|
<div id="connected-button-popover-div-with-ip">
|
||||||
|
<Text>{`IP: ${pendingConnectionDevice?.deviceIp}`}</Text>
|
||||||
|
</div>
|
||||||
|
<Text>{`SessionId: ${pendingConnectionDevice?.sessionId}`}</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col xs={12}>
|
||||||
|
<Button
|
||||||
|
intent="danger"
|
||||||
|
icon="disable"
|
||||||
|
onClick={() => {
|
||||||
|
handleDisconnect();
|
||||||
|
}}
|
||||||
|
style={{ width: '100%', borderRadius: '5px' }}
|
||||||
|
>
|
||||||
|
Disconnect
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function DeviceConnectedInfoButton(
|
||||||
|
props: DeviceConnectedInfoButtonProps
|
||||||
|
) {
|
||||||
|
const { device, onDisconnect } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Popover
|
||||||
|
content={getDeviceConnectedPopoverContent(device, onDisconnect)}
|
||||||
|
position="bottom"
|
||||||
|
inheritDarkTheme={false}
|
||||||
|
transitionDuration={isProduction() ? 700 : 0}
|
||||||
|
>
|
||||||
|
<Tooltip
|
||||||
|
content={<Text>Click to manage</Text>}
|
||||||
|
position="right"
|
||||||
|
hoverOpenDelay={400}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
id="connected-device-info-stepper-button"
|
||||||
|
intent="success"
|
||||||
|
style={{
|
||||||
|
width: '120px',
|
||||||
|
height: '10px !important',
|
||||||
|
borderRadius: '100px',
|
||||||
|
position: 'relative',
|
||||||
|
margin: '0 auto',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row>
|
||||||
|
<Col xs={1}>
|
||||||
|
<Icon icon="info-sign" />
|
||||||
|
</Col>
|
||||||
|
<Col xs>
|
||||||
|
<Text>Connected</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,344 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should match exact snapshot 1`] = `
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"length": 1,
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<DeviceConnectedInfoButton
|
||||||
|
device={Object {}}
|
||||||
|
onDisconnect={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.Popover
|
||||||
|
boundary="scrollParent"
|
||||||
|
captureDismiss={false}
|
||||||
|
content={
|
||||||
|
<Row>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "100px",
|
||||||
|
"padding": "20px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Row
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<Unknown>
|
||||||
|
Connected Device:
|
||||||
|
</Unknown>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
Type: undefined
|
||||||
|
</Blueprint3.Text>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
OS: undefined
|
||||||
|
</Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
id="connected-button-popover-div-with-ip"
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
IP: undefined
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
SessionId: undefined
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
icon="disable"
|
||||||
|
intent="danger"
|
||||||
|
onClick={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "5px",
|
||||||
|
"width": "100%",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Disconnect
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
}
|
||||||
|
defaultIsOpen={false}
|
||||||
|
disabled={false}
|
||||||
|
fill={false}
|
||||||
|
hasBackdrop={false}
|
||||||
|
hoverCloseDelay={300}
|
||||||
|
hoverOpenDelay={150}
|
||||||
|
inheritDarkTheme={false}
|
||||||
|
interactionKind="click"
|
||||||
|
minimal={false}
|
||||||
|
modifiers={Object {}}
|
||||||
|
openOnTargetFocus={true}
|
||||||
|
position="bottom"
|
||||||
|
targetTagName="span"
|
||||||
|
transitionDuration={0}
|
||||||
|
usePortal={true}
|
||||||
|
wrapperTagName="span"
|
||||||
|
>
|
||||||
|
<Manager>
|
||||||
|
<span
|
||||||
|
className="bp3-popover-wrapper"
|
||||||
|
>
|
||||||
|
<Reference
|
||||||
|
innerRef={[Function]}
|
||||||
|
>
|
||||||
|
<InnerReference
|
||||||
|
innerRef={[Function]}
|
||||||
|
setReferenceNode={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.ResizeSensor
|
||||||
|
onResize={[Function]}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-popover-target"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.Tooltip
|
||||||
|
className=""
|
||||||
|
content={
|
||||||
|
<Blueprint3.Text>
|
||||||
|
Click to manage
|
||||||
|
</Blueprint3.Text>
|
||||||
|
}
|
||||||
|
hoverCloseDelay={0}
|
||||||
|
hoverOpenDelay={400}
|
||||||
|
key=".0"
|
||||||
|
position="right"
|
||||||
|
transitionDuration={100}
|
||||||
|
>
|
||||||
|
<Blueprint3.Popover
|
||||||
|
autoFocus={false}
|
||||||
|
boundary="scrollParent"
|
||||||
|
canEscapeKeyClose={false}
|
||||||
|
captureDismiss={false}
|
||||||
|
className=""
|
||||||
|
content={
|
||||||
|
<Blueprint3.Text>
|
||||||
|
Click to manage
|
||||||
|
</Blueprint3.Text>
|
||||||
|
}
|
||||||
|
defaultIsOpen={false}
|
||||||
|
disabled={false}
|
||||||
|
enforceFocus={false}
|
||||||
|
fill={false}
|
||||||
|
hasBackdrop={false}
|
||||||
|
hoverCloseDelay={0}
|
||||||
|
hoverOpenDelay={400}
|
||||||
|
inheritDarkTheme={true}
|
||||||
|
interactionKind="hover-target"
|
||||||
|
lazy={true}
|
||||||
|
minimal={false}
|
||||||
|
modifiers={Object {}}
|
||||||
|
openOnTargetFocus={true}
|
||||||
|
popoverClassName="bp3-tooltip"
|
||||||
|
position="right"
|
||||||
|
targetTagName="span"
|
||||||
|
transitionDuration={100}
|
||||||
|
usePortal={true}
|
||||||
|
wrapperTagName="span"
|
||||||
|
>
|
||||||
|
<Manager>
|
||||||
|
<span
|
||||||
|
className="bp3-popover-wrapper"
|
||||||
|
>
|
||||||
|
<Reference
|
||||||
|
innerRef={[Function]}
|
||||||
|
>
|
||||||
|
<InnerReference
|
||||||
|
innerRef={[Function]}
|
||||||
|
setReferenceNode={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.ResizeSensor
|
||||||
|
onResize={[Function]}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-popover-target"
|
||||||
|
onBlur={[Function]}
|
||||||
|
onFocus={[Function]}
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className=""
|
||||||
|
id="connected-device-info-stepper-button"
|
||||||
|
intent="success"
|
||||||
|
key=".0"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "100px",
|
||||||
|
"height": "10px !important",
|
||||||
|
"margin": "0 auto",
|
||||||
|
"position": "relative",
|
||||||
|
"width": "120px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-intent-success"
|
||||||
|
id="connected-device-info-stepper-button"
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "100px",
|
||||||
|
"height": "10px !important",
|
||||||
|
"margin": "0 auto",
|
||||||
|
"position": "relative",
|
||||||
|
"width": "120px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tabIndex={0}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
<Row>
|
||||||
|
<div
|
||||||
|
className="row"
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
xs={1}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs-1"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
icon="info-sign"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-info-sign"
|
||||||
|
icon="info-sign"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="info-sign"
|
||||||
|
height={16}
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width={16}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
info-sign
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM7 3h2v2H7V3zm3 10H6v-1h1V7H6V6h3v6h1v1z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col
|
||||||
|
xs={true}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs"
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Connected
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.ResizeSensor>
|
||||||
|
</InnerReference>
|
||||||
|
</Reference>
|
||||||
|
<Blueprint3.Overlay
|
||||||
|
autoFocus={false}
|
||||||
|
backdropClassName="bp3-popover-backdrop"
|
||||||
|
backdropProps={Object {}}
|
||||||
|
canEscapeKeyClose={false}
|
||||||
|
canOutsideClickClose={false}
|
||||||
|
enforceFocus={false}
|
||||||
|
hasBackdrop={false}
|
||||||
|
isOpen={false}
|
||||||
|
lazy={true}
|
||||||
|
onClose={[Function]}
|
||||||
|
transitionDuration={100}
|
||||||
|
transitionName="bp3-popover"
|
||||||
|
usePortal={true}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</Manager>
|
||||||
|
</Blueprint3.Popover>
|
||||||
|
</Blueprint3.Tooltip>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.ResizeSensor>
|
||||||
|
</InnerReference>
|
||||||
|
</Reference>
|
||||||
|
<Blueprint3.Overlay
|
||||||
|
autoFocus={true}
|
||||||
|
backdropClassName="bp3-popover-backdrop"
|
||||||
|
backdropProps={Object {}}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={false}
|
||||||
|
isOpen={false}
|
||||||
|
lazy={true}
|
||||||
|
onClose={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
transitionName="bp3-popover"
|
||||||
|
usePortal={true}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</Manager>
|
||||||
|
</Blueprint3.Popover>
|
||||||
|
</DeviceConnectedInfoButton>
|
||||||
|
</Router>
|
||||||
|
</BrowserRouter>
|
||||||
|
`;
|
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import ChooseAppOrScreeenStep from './ChooseAppOrScreeenStep';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<ChooseAppOrScreeenStep
|
||||||
|
handleNextEntireScreen={() => {}}
|
||||||
|
handleNextApplicationWindow={() => {}}
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
29
app/components/StepsOfStepper/ChooseAppOrScreeenStep.tsx
Normal file
29
app/components/StepsOfStepper/ChooseAppOrScreeenStep.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React from 'react';
|
||||||
|
import { Text } from '@blueprintjs/core';
|
||||||
|
import ShareEntireScreenOrAppWindowControlGroup from '../ShareAppOrScreenControlGroup';
|
||||||
|
|
||||||
|
interface ChooseAppOrScreeenStepProps {
|
||||||
|
handleNextEntireScreen: () => void;
|
||||||
|
handleNextApplicationWindow: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChooseAppOrScreeenStep: React.FC<ChooseAppOrScreeenStepProps> = (
|
||||||
|
props: ChooseAppOrScreeenStepProps
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div style={{ marginBottom: '10px' }}>
|
||||||
|
<Text>
|
||||||
|
Choose Entire Screen or App window you want to view on other device
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
<ShareEntireScreenOrAppWindowControlGroup
|
||||||
|
handleNextEntireScreen={props.handleNextEntireScreen}
|
||||||
|
handleNextApplicationWindow={props.handleNextApplicationWindow}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ChooseAppOrScreeenStep;
|
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import ChooseAppOrScreenOverlay from './ChooseAppOrScreenOverlay';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<ChooseAppOrScreenOverlay
|
||||||
|
isEntireScreenToShareChosen
|
||||||
|
isChooseAppOrScreenOverlayOpen
|
||||||
|
handleNextEntireScreen={() => {}}
|
||||||
|
handleNextApplicationWindow={() => {}}
|
||||||
|
handleClose={() => {}}
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
@ -0,0 +1,164 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable react/no-unused-prop-types */
|
||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React from 'react';
|
||||||
|
import { H3, Card, Dialog } from '@blueprintjs/core';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import CloseOverlayButton from '../../CloseOverlayButton';
|
||||||
|
import isProduction from '../../../utils/isProduction';
|
||||||
|
import PreviewGridList from './PreviewGridList';
|
||||||
|
import TEST_SCREEN_SHARING_OBECTS from '../../../constants/test-screen-sharing-objects.json';
|
||||||
|
|
||||||
|
const Zoom = require('react-reveal/Zoom');
|
||||||
|
const Fade = require('react-reveal/Fade');
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
dialogRoot: {
|
||||||
|
width: '90%',
|
||||||
|
height: '87vh !important',
|
||||||
|
overflowY: 'scroll',
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
position: 'relative',
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
left: 'calc(100% - 55px)',
|
||||||
|
borderRadius: '100px',
|
||||||
|
zIndex: 9999,
|
||||||
|
},
|
||||||
|
overlayInnerRoot: { width: '90%', height: '90%' },
|
||||||
|
sharePreviewsContainer: {
|
||||||
|
top: '60px',
|
||||||
|
position: 'relative',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
interface ChooseAppOrScreenOverlayProps {
|
||||||
|
isEntireScreenToShareChosen: boolean;
|
||||||
|
isChooseAppOrScreenOverlayOpen: boolean;
|
||||||
|
handleNextEntireScreen: () => void;
|
||||||
|
handleNextApplicationWindow: () => void;
|
||||||
|
handleClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ChooseAppOrScreenOverlay(
|
||||||
|
props: ChooseAppOrScreenOverlayProps
|
||||||
|
) {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
onClose={props.handleClose}
|
||||||
|
className={`${classes.dialogRoot} choose-app-or-screen-dialog`}
|
||||||
|
autoFocus
|
||||||
|
canEscapeKeyClose
|
||||||
|
canOutsideClickClose
|
||||||
|
enforceFocus
|
||||||
|
hasBackdrop
|
||||||
|
isOpen={props.isChooseAppOrScreenOverlayOpen}
|
||||||
|
usePortal
|
||||||
|
transitionDuration={isProduction() ? 750 : 0}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<Fade
|
||||||
|
duration={isProduction() ? 1000 : 0}
|
||||||
|
delay={isProduction() ? 1000 : 0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'fixed',
|
||||||
|
zIndex: 99999,
|
||||||
|
width: '90%',
|
||||||
|
paddingTop: '0px',
|
||||||
|
paddingLeft: '15px',
|
||||||
|
paddingRight: '15px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
elevation={2}
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
borderRadius: '5px',
|
||||||
|
height: '60px',
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row
|
||||||
|
between="xs"
|
||||||
|
middle="xs"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Col xs={11}>
|
||||||
|
{props.isEntireScreenToShareChosen ? (
|
||||||
|
<div>
|
||||||
|
<H3 style={{ marginBottom: '0px' }}>
|
||||||
|
Select Entire Screen to Share
|
||||||
|
</H3>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<H3 style={{ marginBottom: '0px' }}>
|
||||||
|
Select App Window to Share
|
||||||
|
</H3>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col xs={1}>
|
||||||
|
<CloseOverlayButton
|
||||||
|
onClick={props.handleClose}
|
||||||
|
style={{
|
||||||
|
borderRadius: '100px',
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
}}
|
||||||
|
noDefaultStyles
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</Fade>
|
||||||
|
|
||||||
|
<Zoom
|
||||||
|
duration={isProduction() ? 750 : 0}
|
||||||
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
zIndex: '1',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
// @ts-ignore
|
||||||
|
zIndex: '1',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row>
|
||||||
|
<div className={classes.sharePreviewsContainer}>
|
||||||
|
<PreviewGridList
|
||||||
|
screenSharingObjects={TEST_SCREEN_SHARING_OBECTS}
|
||||||
|
isEntireScreen={props.isEntireScreenToShareChosen}
|
||||||
|
handleNextEntireScreen={() => {
|
||||||
|
props.handleNextEntireScreen();
|
||||||
|
props.handleClose();
|
||||||
|
}}
|
||||||
|
handleNextApplicationWindow={() => {
|
||||||
|
props.handleNextApplicationWindow();
|
||||||
|
props.handleClose();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
</Zoom>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||||
|
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
|
||||||
|
/* eslint-disable jsx-a11y/alt-text */
|
||||||
|
import React, { useEffect, useState, useCallback } from 'react';
|
||||||
|
import { Card, H4, Icon } from '@blueprintjs/core';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import isProduction from '../../../utils/isProduction';
|
||||||
|
|
||||||
|
const Fade = require('react-reveal/Fade');
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
root: {
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
justifyContent: 'space-around',
|
||||||
|
overflow: 'hidden',
|
||||||
|
},
|
||||||
|
gridList: {
|
||||||
|
width: 500,
|
||||||
|
height: 450,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
color: 'rgba(255, 255, 255, 0.54)',
|
||||||
|
},
|
||||||
|
previewShareThumbContainer: {
|
||||||
|
marginBottom: '20px',
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'rgba(19, 124, 189, 0.4)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function PreviewGridList(props: any) {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
const [showPreviewNamesMap, setShowPreviewNamesMap] = useState(new Map());
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const map = new Map();
|
||||||
|
props.screenSharingObjects.forEach((el: { id: string }) => {
|
||||||
|
map.set(el.id, false);
|
||||||
|
});
|
||||||
|
setShowPreviewNamesMap(map);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onPreviewMouseEnter = useCallback(
|
||||||
|
(id) => {
|
||||||
|
const newShowPreviewNamesMap = new Map(showPreviewNamesMap);
|
||||||
|
[...newShowPreviewNamesMap.keys()].forEach((key) => {
|
||||||
|
newShowPreviewNamesMap.set(key, false);
|
||||||
|
});
|
||||||
|
newShowPreviewNamesMap.set(id, true);
|
||||||
|
setShowPreviewNamesMap(newShowPreviewNamesMap);
|
||||||
|
},
|
||||||
|
[showPreviewNamesMap, setShowPreviewNamesMap]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onPreviewMouseLeave = useCallback(() => {
|
||||||
|
const newShowPreviewNamesMap = new Map(showPreviewNamesMap);
|
||||||
|
[...newShowPreviewNamesMap.keys()].forEach((key) => {
|
||||||
|
newShowPreviewNamesMap.set(key, false);
|
||||||
|
});
|
||||||
|
setShowPreviewNamesMap(newShowPreviewNamesMap);
|
||||||
|
}, [showPreviewNamesMap, setShowPreviewNamesMap]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '90%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{[...showPreviewNamesMap.keys()].map((id) => {
|
||||||
|
return (
|
||||||
|
<Col xs={12} md={6} lg={3} key={id}>
|
||||||
|
<Card
|
||||||
|
interactive
|
||||||
|
elevation={2}
|
||||||
|
className={`preview-share-thumb-container ${classes.previewShareThumbContainer}`}
|
||||||
|
onClick={() => {
|
||||||
|
if (props.isEntireScreen) {
|
||||||
|
props.handleNextEntireScreen();
|
||||||
|
} else {
|
||||||
|
props.handleNextApplicationWindow();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onMouseEnter={() => onPreviewMouseEnter(id)}
|
||||||
|
onMouseLeave={() => onPreviewMouseLeave()}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '250px',
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
borderRadius: '5px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row
|
||||||
|
middle="xs"
|
||||||
|
center="xs"
|
||||||
|
className="icon-or-preview-container"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon={props.isEntireScreen ? 'desktop' : 'application'}
|
||||||
|
iconSize={150}
|
||||||
|
color="#A7B6C2"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 'calc(50% - 75px)',
|
||||||
|
left: 'calc(50% - 75px)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Row>
|
||||||
|
<Fade
|
||||||
|
when={showPreviewNamesMap.get(id)}
|
||||||
|
duration={isProduction() ? 300 : 0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
background:
|
||||||
|
'radial-gradient(circle closest-side, rgba(0,0,0,0.025), rgba(0,0,0,0.1)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Fade
|
||||||
|
bottom
|
||||||
|
when={showPreviewNamesMap.get(id)}
|
||||||
|
duration={isProduction() ? 300 : 0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
bottom: 'calc(-100% + 42px)',
|
||||||
|
width: '100%',
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.4)',
|
||||||
|
padding: '10px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<H4
|
||||||
|
style={{
|
||||||
|
paddingBottom: '0px',
|
||||||
|
marginBottom: '0px',
|
||||||
|
color: 'white',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Preview Name
|
||||||
|
</H4>
|
||||||
|
</div>
|
||||||
|
</Fade>
|
||||||
|
</div>
|
||||||
|
</Fade>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
20
app/components/StepsOfStepper/ConfirmStep.spec.tsx
Normal file
20
app/components/StepsOfStepper/ConfirmStep.spec.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import ConfirmStep from './ConfirmStep';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<ConfirmStep device={{} as Device} />
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
30
app/components/StepsOfStepper/ConfirmStep.tsx
Normal file
30
app/components/StepsOfStepper/ConfirmStep.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* eslint-disable react/jsx-curly-brace-presence */
|
||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, Card } from '@blueprintjs/core';
|
||||||
|
|
||||||
|
interface ConfirmStepProps {
|
||||||
|
device: Device | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ConfirmStep(props: ConfirmStepProps) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div style={{ marginBottom: '10px' }}>
|
||||||
|
<Text>{`Check if all is OK and click "Confirm"`}</Text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card style={{ marginBottom: '10px' }}>
|
||||||
|
<Text>{`Device: ${props.device?.deviceType}`}</Text>
|
||||||
|
<Text>{`Device IP: ${props.device?.deviceIp}`}</Text>
|
||||||
|
<Text>{`Device OS: ${props.device?.deviceOs}`}</Text>
|
||||||
|
<Text>{`Session ID: ${props.device?.sessionId}`}</Text>
|
||||||
|
</Card>
|
||||||
|
<div style={{ marginBottom: '10px' }}>
|
||||||
|
<Text className="bp3-text-muted">
|
||||||
|
{`Click "Back" if you need to change something`}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
85
app/components/StepsOfStepper/IntermediateStep.spec.tsx
Normal file
85
app/components/StepsOfStepper/IntermediateStep.spec.tsx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import IntermediateStep from './IntermediateStep';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
const confirmButtonSelector = 'button.bp3-button.bp3-intent-success';
|
||||||
|
|
||||||
|
function setup(
|
||||||
|
activeStep = 0,
|
||||||
|
resetDeviceMock = () => {},
|
||||||
|
resetUserAllowedMock = () => {}
|
||||||
|
) {
|
||||||
|
const getWrapper = () =>
|
||||||
|
mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<IntermediateStep
|
||||||
|
activeStep={activeStep}
|
||||||
|
steps={['a', 'b', 'c']}
|
||||||
|
handleNext={() => {}}
|
||||||
|
handleBack={() => {}}
|
||||||
|
handleNextEntireScreen={() => {}}
|
||||||
|
handleNextApplicationWindow={() => {}}
|
||||||
|
resetPendingConnectionDevice={resetDeviceMock}
|
||||||
|
resetUserAllowedConnection={resetUserAllowedMock}
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const component = getWrapper();
|
||||||
|
|
||||||
|
const buttons = {
|
||||||
|
confirmButton: component.find(confirmButtonSelector),
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
component,
|
||||||
|
buttons,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should match exact snapshot on each step', () => {
|
||||||
|
for (let testActiveStep = 0; testActiveStep < 3; testActiveStep += 1) {
|
||||||
|
const { component } = setup(
|
||||||
|
testActiveStep,
|
||||||
|
() => {},
|
||||||
|
() => {}
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(component)).toMatchSnapshot();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call resetPendingConnectionDevice when Confirm button clicked on confirm step', () => {
|
||||||
|
const confirmStepNumber = 2;
|
||||||
|
const mockResetPendingConnectionDeviceCallback = jest.fn();
|
||||||
|
const { buttons } = setup(
|
||||||
|
confirmStepNumber,
|
||||||
|
mockResetPendingConnectionDeviceCallback,
|
||||||
|
() => {}
|
||||||
|
);
|
||||||
|
|
||||||
|
buttons.confirmButton.simulate('click');
|
||||||
|
|
||||||
|
expect(mockResetPendingConnectionDeviceCallback).toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call resetUserAllowedConnection when Confirm button clicked on confirm step', () => {
|
||||||
|
const confirmStepNumber = 2;
|
||||||
|
const mockResetUserAllowedConnectionCallback = jest.fn();
|
||||||
|
const { buttons } = setup(
|
||||||
|
confirmStepNumber,
|
||||||
|
() => {},
|
||||||
|
mockResetUserAllowedConnectionCallback
|
||||||
|
);
|
||||||
|
|
||||||
|
buttons.confirmButton.simulate('click');
|
||||||
|
|
||||||
|
expect(mockResetUserAllowedConnectionCallback).toBeCalled();
|
||||||
|
});
|
146
app/components/StepsOfStepper/IntermediateStep.tsx
Normal file
146
app/components/StepsOfStepper/IntermediateStep.tsx
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Button } from '@blueprintjs/core';
|
||||||
|
import { Col } from 'react-flexbox-grid';
|
||||||
|
import DEVICES from '../../constants/test-devices.json';
|
||||||
|
import ScanQRStep from './ScanQRStep';
|
||||||
|
import ChooseAppOrScreeenStep from './ChooseAppOrScreeenStep';
|
||||||
|
import ConfirmStep from './ConfirmStep';
|
||||||
|
import { ConnectedDevicesContext } from '../../containers/ConnectedDevicesProvider';
|
||||||
|
|
||||||
|
interface IntermediateStepProps {
|
||||||
|
activeStep: number;
|
||||||
|
steps: string[];
|
||||||
|
handleNext: () => void;
|
||||||
|
handleBack: () => void;
|
||||||
|
handleNextEntireScreen: () => void;
|
||||||
|
handleNextApplicationWindow: () => void;
|
||||||
|
resetPendingConnectionDevice: () => void;
|
||||||
|
resetUserAllowedConnection: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStepContent(
|
||||||
|
stepIndex: number,
|
||||||
|
handleNextEntireScreen: () => void,
|
||||||
|
handleNextApplicationWindow: () => void,
|
||||||
|
pendingConnectionDevice: Device | null
|
||||||
|
) {
|
||||||
|
switch (stepIndex) {
|
||||||
|
case 0:
|
||||||
|
return <ScanQRStep />;
|
||||||
|
case 1:
|
||||||
|
return (
|
||||||
|
<ChooseAppOrScreeenStep
|
||||||
|
handleNextEntireScreen={handleNextEntireScreen}
|
||||||
|
handleNextApplicationWindow={handleNextApplicationWindow}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case 2:
|
||||||
|
return <ConfirmStep device={pendingConnectionDevice} />;
|
||||||
|
default:
|
||||||
|
return 'Unknown stepIndex';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isConfirmStep(activeStep: number, steps: string[]) {
|
||||||
|
return activeStep === steps.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function IntermediateStep(props: IntermediateStepProps) {
|
||||||
|
const {
|
||||||
|
devices,
|
||||||
|
setPendingConnectionDeviceHook,
|
||||||
|
setDevicesHook,
|
||||||
|
pendingConnectionDevice,
|
||||||
|
resetPendingConnectionDeviceHook,
|
||||||
|
} = useContext(ConnectedDevicesContext);
|
||||||
|
|
||||||
|
const connectDevice = (device: Device) => {
|
||||||
|
setPendingConnectionDeviceHook(device);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Col
|
||||||
|
xs={12}
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: '260px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getStepContent(
|
||||||
|
props.activeStep,
|
||||||
|
props.handleNextEntireScreen,
|
||||||
|
props.handleNextApplicationWindow,
|
||||||
|
pendingConnectionDevice
|
||||||
|
)}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* TODO: (REMOVE: process.env.NODE_ENV === 'production') !!!!!!!!!)
|
||||||
|
Connect Test Device button, displayed only when RUN_MODE is 'dev' or 'test' */
|
||||||
|
props.activeStep === 0 &&
|
||||||
|
(process.env.RUN_MODE === 'dev' ||
|
||||||
|
process.env.RUN_MODE === 'test' ||
|
||||||
|
process.env.NODE_ENV === 'production') ? (
|
||||||
|
// eslint-disable-next-line react/jsx-indent
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
connectDevice(
|
||||||
|
DEVICES[Math.floor(Math.random() * DEVICES.length)]
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Connect Test Device
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
/**/
|
||||||
|
props.activeStep !== 0 ? (
|
||||||
|
<Button
|
||||||
|
intent={props.activeStep === 2 ? 'success' : 'none'}
|
||||||
|
onClick={() => {
|
||||||
|
props.handleNext();
|
||||||
|
if (isConfirmStep(props.activeStep, props.steps)) {
|
||||||
|
setDevicesHook([...devices, pendingConnectionDevice as Device]);
|
||||||
|
resetPendingConnectionDeviceHook();
|
||||||
|
props.resetPendingConnectionDevice();
|
||||||
|
props.resetUserAllowedConnection();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
display: props.activeStep === 1 ? 'none' : 'inline',
|
||||||
|
borderRadius: '100px',
|
||||||
|
width: '100%',
|
||||||
|
textAlign: 'center',
|
||||||
|
}}
|
||||||
|
rightIcon={
|
||||||
|
isConfirmStep(props.activeStep, props.steps)
|
||||||
|
? 'small-tick'
|
||||||
|
: 'chevron-right'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{isConfirmStep(props.activeStep, props.steps) ? 'Confirm' : 'Next'}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<Button
|
||||||
|
intent="danger"
|
||||||
|
style={{
|
||||||
|
marginTop: '10px',
|
||||||
|
display: props.activeStep === 2 ? 'inline-block' : 'none',
|
||||||
|
borderRadius: '100px',
|
||||||
|
}}
|
||||||
|
onClick={props.handleBack}
|
||||||
|
icon="chevron-left"
|
||||||
|
text="No, I need to share other thing"
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
}
|
77
app/components/StepsOfStepper/ScanQRStep.spec.tsx
Normal file
77
app/components/StepsOfStepper/ScanQRStep.spec.tsx
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/ban-types */
|
||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
import React from 'react';
|
||||||
|
import Enzyme from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import ScanQRStep from './ScanQRStep';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
const bp3QRCodeDialogRootSelector = '#bp3-qr-code-dialog-root';
|
||||||
|
const magnifyQRCodeButtonSelector = '#magnify-qr-code-button';
|
||||||
|
const qrCodeDialogInnerSelector = '#qr-code-dialog-inner';
|
||||||
|
|
||||||
|
type EnzymeShallowWrapper =
|
||||||
|
| Enzyme.CommonWrapper<{}, {}, React.Component<{}, {}, any>>
|
||||||
|
| Cheerio
|
||||||
|
| Enzyme.ShallowWrapper<any, Readonly<{}>, React.Component<{}, {}, any>>;
|
||||||
|
|
||||||
|
describe('<ScanQRStep />', () => {
|
||||||
|
let wrapper: EnzymeShallowWrapper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = Enzyme.shallow(<ScanQRStep />);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when rendered', () => {
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
expect(EnzymeToJson(wrapper)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when user clicks on magnify QR code button', () => {
|
||||||
|
it('should set "QR Code Dialog Root" isOpen property to "true"', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(magnifyQRCodeButtonSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
expect(wrapper.find(bp3QRCodeDialogRootSelector).props().isOpen).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(`when magnified QR code dialog is opened,
|
||||||
|
and when user closes magnified QR code dialog`, () => {
|
||||||
|
it('should set "QR Code Dialog Root" isOpen property to "false"', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(magnifyQRCodeButtonSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(bp3QRCodeDialogRootSelector).props().onClose();
|
||||||
|
// @ts-ignore
|
||||||
|
expect(wrapper.find(bp3QRCodeDialogRootSelector).props().isOpen).toBe(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(`when magnified QR code dialog is opened,
|
||||||
|
and when user clicks on qr code dialog inner`, () => {
|
||||||
|
it('should set "QR Code Dialog Root" isOpen property to "false"', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(magnifyQRCodeButtonSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(qrCodeDialogInnerSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
expect(wrapper.find(bp3QRCodeDialogRootSelector).props().isOpen).toBe(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
155
app/components/StepsOfStepper/ScanQRStep.tsx
Normal file
155
app/components/StepsOfStepper/ScanQRStep.tsx
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||||
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
|
import React, { useContext, useState } from 'react';
|
||||||
|
import { Button, Text, Tooltip, Position, H2, Dialog } from '@blueprintjs/core';
|
||||||
|
import QRCode from 'qrcode.react';
|
||||||
|
import { makeStyles, createStyles } from '@material-ui/core';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import { SettingsContext } from '../../containers/SettingsProvider';
|
||||||
|
import isProduction from '../../utils/isProduction';
|
||||||
|
import CloseOverlayButton from '../CloseOverlayButton';
|
||||||
|
|
||||||
|
const internalIp = require('internal-ip');
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
smallQRCode: {
|
||||||
|
border: '1px solid',
|
||||||
|
borderColor: 'rgba(0,0,0,0.0)',
|
||||||
|
padding: '10px',
|
||||||
|
borderRadius: '10px',
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.12)',
|
||||||
|
border: '1px solid #8A9BA8',
|
||||||
|
cursor: 'zoom-in',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dialogQRWrapper: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: '20px',
|
||||||
|
borderRadius: '10px',
|
||||||
|
},
|
||||||
|
bigQRCodeDialogRoot: {
|
||||||
|
'&:hover': {
|
||||||
|
cursor: 'zoom-out',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const ScanQRStep: React.FC = () => {
|
||||||
|
const classes = useStyles();
|
||||||
|
const { isDarkTheme } = useContext(SettingsContext);
|
||||||
|
|
||||||
|
const [isQRCodeMagnified, setIsQRCodeMagnified] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<Text className="bp3-text">Scan the QR code</Text>
|
||||||
|
<Text className="bp3-text-muted">
|
||||||
|
( make sure your computer and device are connected on same WiFi )
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Tooltip content="Click to make bigger" position={Position.LEFT}>
|
||||||
|
<div
|
||||||
|
id="magnify-qr-code-button"
|
||||||
|
className={classes.smallQRCode}
|
||||||
|
onClick={() => setIsQRCodeMagnified(true)}
|
||||||
|
>
|
||||||
|
<QRCode
|
||||||
|
value={`http://${internalIp.v4.sync()}:65000/99999`}
|
||||||
|
level="H"
|
||||||
|
renderAs="svg"
|
||||||
|
// bgColor={isDarkTheme ? '#293742' : '#ffffff'}
|
||||||
|
bgColor="rgba(0,0,0,0.0)"
|
||||||
|
fgColor={isDarkTheme ? '#ffffff' : '#000000'}
|
||||||
|
imageSettings={{
|
||||||
|
// src: `data:image/png;base64, ${contents}`,
|
||||||
|
src:
|
||||||
|
'https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Electron_Software_Framework_Logo.svg/256px-Electron_Software_Framework_Logo.svg.png',
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<div style={{ marginBottom: '10px' }}>
|
||||||
|
<Text className="bp3-text-muted">
|
||||||
|
or type the following address manualy in browser address bar on any
|
||||||
|
device:
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Tooltip content="Click to copy" position={Position.LEFT}>
|
||||||
|
<Button
|
||||||
|
intent="primary"
|
||||||
|
icon="duplicate"
|
||||||
|
style={{ borderRadius: '100px' }}
|
||||||
|
>
|
||||||
|
http://255.255.255.255:65000/99999
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
// @ts-ignore
|
||||||
|
id="bp3-qr-code-dialog-root"
|
||||||
|
className={classes.bigQRCodeDialogRoot}
|
||||||
|
isOpen={isQRCodeMagnified}
|
||||||
|
onClose={() => setIsQRCodeMagnified(false)}
|
||||||
|
canEscapeKeyClose
|
||||||
|
canOutsideClickClose
|
||||||
|
transitionDuration={isProduction() ? 700 : 0}
|
||||||
|
style={{ position: 'relative', top: '-30px' }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="qr-code-dialog-inner"
|
||||||
|
onClick={() => setIsQRCodeMagnified(false)}
|
||||||
|
style={{ paddingTop: '20px', paddingBottom: '13px' }}
|
||||||
|
>
|
||||||
|
<Row between="xs" middle="xs">
|
||||||
|
<Col xs={10}>
|
||||||
|
<H2 style={{ margin: '0px', padding: '0px', marginLeft: '35px' }}>
|
||||||
|
Scan QR Code
|
||||||
|
</H2>
|
||||||
|
</Col>
|
||||||
|
<Col xs={2}>
|
||||||
|
<CloseOverlayButton
|
||||||
|
onClick={() => setIsQRCodeMagnified(false)}
|
||||||
|
style={{
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
position: 'relative',
|
||||||
|
borderRadius: '100px',
|
||||||
|
}}
|
||||||
|
noDefaultStyles
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row center="xs">
|
||||||
|
<div className={classes.dialogQRWrapper}>
|
||||||
|
<QRCode
|
||||||
|
value={`http://${internalIp.v4.sync()}:65000/99999`}
|
||||||
|
level="H"
|
||||||
|
renderAs="svg"
|
||||||
|
imageSettings={{
|
||||||
|
src:
|
||||||
|
'https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Electron_Software_Framework_Logo.svg/256px-Electron_Software_Framework_Logo.svg.png',
|
||||||
|
width: 25,
|
||||||
|
height: 25,
|
||||||
|
}}
|
||||||
|
width="390px"
|
||||||
|
height="390px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ScanQRStep;
|
49
app/components/StepsOfStepper/SuccessStep.spec.tsx
Normal file
49
app/components/StepsOfStepper/SuccessStep.spec.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import SuccessStep from './SuccessStep';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
const connectNewDeviceButtonSelector = 'button.bp3-button.bp3-intent-primary';
|
||||||
|
|
||||||
|
function setup(handleResetMock = () => {}) {
|
||||||
|
const getWrapper = () =>
|
||||||
|
mount(
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<SuccessStep handleReset={handleResetMock} />
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const component = getWrapper();
|
||||||
|
|
||||||
|
const buttons = {
|
||||||
|
connectNewDeviceButton: component.find(connectNewDeviceButtonSelector),
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
component,
|
||||||
|
buttons,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const { component } = setup();
|
||||||
|
expect(EnzymeToJson(component)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when "Connect New Device" button is clicked', () => {
|
||||||
|
it('should call handleReset injected functional property', () => {
|
||||||
|
const mockHandleResetCallback = jest.fn();
|
||||||
|
const { buttons } = setup(mockHandleResetCallback);
|
||||||
|
|
||||||
|
buttons.connectNewDeviceButton.simulate('click');
|
||||||
|
|
||||||
|
expect(mockHandleResetCallback).toBeCalled();
|
||||||
|
});
|
||||||
|
});
|
93
app/components/StepsOfStepper/SuccessStep.tsx
Normal file
93
app/components/StepsOfStepper/SuccessStep.tsx
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
import { Button, H5, Icon, Text } from '@blueprintjs/core';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
|
||||||
|
interface SuccessStepProps {
|
||||||
|
handleReset: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SuccessStep: React.FC<SuccessStepProps> = (props: SuccessStepProps) => {
|
||||||
|
useEffect(() => {
|
||||||
|
document
|
||||||
|
.querySelector('#top-panel-connected-devices-list-button')
|
||||||
|
?.classList.remove('pulse-not-infinite');
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('#top-panel-connected-devices-list-button')
|
||||||
|
?.classList.add('pulse-not-infinite');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
document
|
||||||
|
.querySelector('#top-panel-connected-devices-list-button')
|
||||||
|
?.classList.remove('pulse-not-infinite');
|
||||||
|
}, 4000);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleTextConnectedListMouseEnter = useCallback(() => {
|
||||||
|
document
|
||||||
|
.querySelector('#top-panel-connected-devices-list-button')
|
||||||
|
?.classList.add('pulsing');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleTextConnectedListMouseLeave = useCallback(() => {
|
||||||
|
document
|
||||||
|
.querySelector('#top-panel-connected-devices-list-button')
|
||||||
|
?.classList.remove('pulsing');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Col
|
||||||
|
xs={8}
|
||||||
|
md={6}
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row center="xs">
|
||||||
|
<Col xs={12}>
|
||||||
|
<Icon icon="endorsed" iconSize={35} color="#0F9960" />
|
||||||
|
<H5>Success!</H5>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row center="xs">
|
||||||
|
<Col xs={10}>
|
||||||
|
<div style={{ marginBottom: '10px' }}>
|
||||||
|
<Text>
|
||||||
|
{`You should see now sharing session started on device you've connected
|
||||||
|
with.`}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="connected-devices-list-text-success"
|
||||||
|
onMouseEnter={handleTextConnectedListMouseEnter}
|
||||||
|
onMouseLeave={handleTextConnectedListMouseLeave}
|
||||||
|
style={{
|
||||||
|
marginBottom: '25px',
|
||||||
|
textDecoration: 'underline dotted',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text className="">
|
||||||
|
{`
|
||||||
|
You can manage connected devices by clicking "Connected Devices"
|
||||||
|
button in top panel
|
||||||
|
`}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Button
|
||||||
|
intent="primary"
|
||||||
|
onClick={props.handleReset}
|
||||||
|
icon="repeat"
|
||||||
|
style={{ borderRadius: '100px' }}
|
||||||
|
>
|
||||||
|
Connect New Device
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SuccessStep;
|
@ -0,0 +1,250 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should match exact snapshot 1`] = `
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"length": 1,
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ChooseAppOrScreeenStep
|
||||||
|
handleNextApplicationWindow={[Function]}
|
||||||
|
handleNextEntireScreen={[Function]}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Choose Entire Screen or App window you want to view on other device
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
<ShareEntireScreenOrAppWindowControlGroup
|
||||||
|
handleNextApplicationWindow={[Function]}
|
||||||
|
handleNextEntireScreen={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.ControlGroup
|
||||||
|
className="makeStyles-controlGroupRoot-1"
|
||||||
|
fill={true}
|
||||||
|
id="share-screen-or-app-btn-group"
|
||||||
|
vertical={false}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-control-group bp3-fill makeStyles-controlGroupRoot-1"
|
||||||
|
id="share-screen-or-app-btn-group"
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-shareEntireScreenButton-2"
|
||||||
|
intent="primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-intent-primary makeStyles-shareEntireScreenButton-2"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
className="makeStyles-shareEntireScreenButtonIcon-3"
|
||||||
|
color="white"
|
||||||
|
icon="desktop"
|
||||||
|
iconSize={100}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-desktop makeStyles-shareEntireScreenButtonIcon-3"
|
||||||
|
icon="desktop"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="desktop"
|
||||||
|
fill="white"
|
||||||
|
height={100}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width={100}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
desktop
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M19 0H1C.45 0 0 .45 0 1v13c0 .55.45 1 1 1h5.67l-.5 3H5c-.55 0-1 .45-1 1s.45 1 1 1h10c.55 0 1-.45 1-1s-.45-1-1-1h-1.17l-.5-3H19c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1zm-1 13H2V2h16v11z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
Entire Screen
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-shareAppButton-4"
|
||||||
|
intent="primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-intent-primary makeStyles-shareAppButton-4"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
className="makeStyles-shareAppButtonIcon-5"
|
||||||
|
color="white"
|
||||||
|
icon="application"
|
||||||
|
iconSize={100}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-application makeStyles-shareAppButtonIcon-5"
|
||||||
|
icon="application"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="application"
|
||||||
|
fill="white"
|
||||||
|
height={100}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width={100}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
application
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M3.5 9h9c.28 0 .5-.22.5-.5s-.22-.5-.5-.5h-9c-.28 0-.5.22-.5.5s.22.5.5.5zm0 2h5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5h-5c-.28 0-.5.22-.5.5s.22.5.5.5zM19 1H1c-.55 0-1 .45-1 1v16c0 .55.45 1 1 1h18c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm-1 16H2V6h16v11zM3.5 13h7c.28 0 .5-.22.5-.5s-.22-.5-.5-.5h-7c-.28 0-.5.22-.5.5s.22.5.5.5z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
Application Window
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
<Blueprint3.Button
|
||||||
|
active={true}
|
||||||
|
className="makeStyles-orDecorationButton-6"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-active makeStyles-orDecorationButton-6"
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
OR
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</div>
|
||||||
|
</Blueprint3.ControlGroup>
|
||||||
|
<ChooseAppOrScreenOverlay
|
||||||
|
handleClose={[Function]}
|
||||||
|
handleNextApplicationWindow={[Function]}
|
||||||
|
handleNextEntireScreen={[Function]}
|
||||||
|
isChooseAppOrScreenOverlayOpen={false}
|
||||||
|
isEntireScreenToShareChosen={false}
|
||||||
|
>
|
||||||
|
<Blueprint3.Dialog
|
||||||
|
autoFocus={true}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="makeStyles-dialogRoot-7 choose-app-or-screen-dialog"
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={true}
|
||||||
|
isOpen={false}
|
||||||
|
onClose={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
usePortal={true}
|
||||||
|
>
|
||||||
|
<Blueprint3.Overlay
|
||||||
|
autoFocus={true}
|
||||||
|
backdropProps={Object {}}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="bp3-overlay-scroll-container"
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={true}
|
||||||
|
isOpen={false}
|
||||||
|
lazy={true}
|
||||||
|
onClose={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
transitionName="bp3-overlay"
|
||||||
|
usePortal={true}
|
||||||
|
/>
|
||||||
|
</Blueprint3.Dialog>
|
||||||
|
</ChooseAppOrScreenOverlay>
|
||||||
|
</ShareEntireScreenOrAppWindowControlGroup>
|
||||||
|
</ChooseAppOrScreeenStep>
|
||||||
|
</Router>
|
||||||
|
</BrowserRouter>
|
||||||
|
`;
|
@ -0,0 +1,112 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should match exact snapshot 1`] = `
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"length": 1,
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ConfirmStep
|
||||||
|
device={Object {}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Check if all is OK and click "Confirm"
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
<Blueprint3.Card
|
||||||
|
elevation={0}
|
||||||
|
interactive={false}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-card bp3-elevation-0"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Device: undefined
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Device IP: undefined
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Device OS: undefined
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Session ID: undefined
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Card>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-text-muted"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-text-muted"
|
||||||
|
>
|
||||||
|
Click "Back" if you need to change something
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
</ConfirmStep>
|
||||||
|
</Router>
|
||||||
|
</BrowserRouter>
|
||||||
|
`;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,177 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`<ScanQRStep /> when rendered should match exact snapshot 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"textAlign": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-text"
|
||||||
|
>
|
||||||
|
Scan the QR code
|
||||||
|
</Blueprint3.Text>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-text-muted"
|
||||||
|
>
|
||||||
|
( make sure your computer and device are connected on same WiFi )
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Blueprint3.Tooltip
|
||||||
|
content="Click to make bigger"
|
||||||
|
hoverCloseDelay={0}
|
||||||
|
hoverOpenDelay={100}
|
||||||
|
position="left"
|
||||||
|
transitionDuration={100}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="makeStyles-smallQRCode-1"
|
||||||
|
id="magnify-qr-code-button"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<QRCode
|
||||||
|
bgColor="rgba(0,0,0,0.0)"
|
||||||
|
fgColor="#000000"
|
||||||
|
imageSettings={
|
||||||
|
Object {
|
||||||
|
"height": 40,
|
||||||
|
"src": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Electron_Software_Framework_Logo.svg/256px-Electron_Software_Framework_Logo.svg.png",
|
||||||
|
"width": 40,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
includeMargin={false}
|
||||||
|
level="H"
|
||||||
|
renderAs="svg"
|
||||||
|
size={128}
|
||||||
|
value="http://192.168.31.214:65000/99999"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Tooltip>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-text-muted"
|
||||||
|
>
|
||||||
|
or type the following address manualy in browser address bar on any device:
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
<Blueprint3.Tooltip
|
||||||
|
content="Click to copy"
|
||||||
|
hoverCloseDelay={0}
|
||||||
|
hoverOpenDelay={100}
|
||||||
|
position="left"
|
||||||
|
transitionDuration={100}
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
icon="duplicate"
|
||||||
|
intent="primary"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "100px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
http://255.255.255.255:65000/99999
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</Blueprint3.Tooltip>
|
||||||
|
<Blueprint3.Dialog
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="makeStyles-bigQRCodeDialogRoot-3"
|
||||||
|
id="bp3-qr-code-dialog-root"
|
||||||
|
isOpen={false}
|
||||||
|
onClose={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"position": "relative",
|
||||||
|
"top": "-30px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transitionDuration={0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="qr-code-dialog-inner"
|
||||||
|
onClick={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"paddingBottom": "13px",
|
||||||
|
"paddingTop": "20px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Row
|
||||||
|
between="xs"
|
||||||
|
middle="xs"
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
xs={10}
|
||||||
|
>
|
||||||
|
<Component
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"margin": "0px",
|
||||||
|
"marginLeft": "35px",
|
||||||
|
"padding": "0px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Scan QR Code
|
||||||
|
</Component>
|
||||||
|
</Col>
|
||||||
|
<Col
|
||||||
|
xs={2}
|
||||||
|
>
|
||||||
|
<CloseOverlayButton
|
||||||
|
noDefaultStyles={true}
|
||||||
|
onClick={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "100px",
|
||||||
|
"height": "40px",
|
||||||
|
"position": "relative",
|
||||||
|
"width": "40px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row
|
||||||
|
center="xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="makeStyles-dialogQRWrapper-2"
|
||||||
|
>
|
||||||
|
<QRCode
|
||||||
|
bgColor="#FFFFFF"
|
||||||
|
fgColor="#000000"
|
||||||
|
height="390px"
|
||||||
|
imageSettings={
|
||||||
|
Object {
|
||||||
|
"height": 25,
|
||||||
|
"src": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Electron_Software_Framework_Logo.svg/256px-Electron_Software_Framework_Logo.svg.png",
|
||||||
|
"width": 25,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
includeMargin={false}
|
||||||
|
level="H"
|
||||||
|
renderAs="svg"
|
||||||
|
size={128}
|
||||||
|
value="http://192.168.31.214:65000/99999"
|
||||||
|
width="390px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Dialog>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
@ -0,0 +1,220 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should match exact snapshot 1`] = `
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"length": 1,
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SuccessStep
|
||||||
|
handleReset={[Function]}
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
md={6}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"display": "flex",
|
||||||
|
"flexDirection": "column",
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xs={8}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs-8 col-md-6"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"display": "flex",
|
||||||
|
"flexDirection": "column",
|
||||||
|
"justifyContent": "center",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Row
|
||||||
|
center="xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="row center-xs"
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs-12"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
color="#0F9960"
|
||||||
|
icon="endorsed"
|
||||||
|
iconSize={35}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-endorsed"
|
||||||
|
icon="endorsed"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="endorsed"
|
||||||
|
fill="#0F9960"
|
||||||
|
height={35}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width={35}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
endorsed
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M19.83 9.38L18.81 7.6V5.62c0-.45-.23-.85-.61-1.08l-1.71-1-1.02-1.76a1.25 1.25 0 00-1.08-.61h-2.03l-1.74-1c-.38-.23-.87-.23-1.25 0l-1.74 1H5.65c-.44 0-.85.23-1.08.61L3.58 3.5l-1.8 1.04c-.38.24-.62.64-.62 1.08v2.06L.17 9.4c-.11.19-.17.4-.17.61s.06.42.17.61l.99 1.72v2.06c0 .45.23.85.61 1.08l1.78 1.02.99 1.72c.23.38.63.61 1.08.61h1.99l1.74 1c.19.11.41.17.62.17.21 0 .42-.06.61-.17l1.74-1h2.03c.44 0 .85-.23 1.08-.61l1.02-1.76 1.71-1c.38-.23.61-.64.61-1.08v-1.97l1.02-1.78c.27-.38.27-.85.04-1.25zm-5.08-.71l-5.01 5.01c-.18.18-.43.29-.71.29-.28 0-.53-.11-.71-.29l-3.01-3.01a1.003 1.003 0 011.42-1.42l2.3 2.3 4.31-4.3a1.003 1.003 0 011.71.71c0 .28-.12.53-.3.71z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<Component>
|
||||||
|
<h5
|
||||||
|
className="bp3-heading"
|
||||||
|
>
|
||||||
|
Success!
|
||||||
|
</h5>
|
||||||
|
</Component>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
<Row
|
||||||
|
center="xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="row center-xs"
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
xs={10}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs-10"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "10px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
You should see now sharing session started on device you've connected
|
||||||
|
with.
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="connected-devices-list-text-success"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": "25px",
|
||||||
|
"textDecoration": "underline dotted",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
|
||||||
|
You can manage connected devices by clicking "Connected Devices"
|
||||||
|
button in top panel
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
<Blueprint3.Button
|
||||||
|
icon="repeat"
|
||||||
|
intent="primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "100px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-intent-primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"borderRadius": "100px",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
icon="repeat"
|
||||||
|
key="leftIcon"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-repeat"
|
||||||
|
icon="repeat"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="repeat"
|
||||||
|
height={16}
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width={16}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
repeat
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M10 5c0 .55.45 1 1 1h4c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1s-1 .45-1 1v1.74A7.95 7.95 0 008 0C3.58 0 0 3.58 0 8c0 4.06 3.02 7.4 6.94 7.92.02 0 .04.01.06.01.33.04.66.07 1 .07 4.42 0 8-3.58 8-8 0-.55-.45-1-1-1s-1 .45-1 1c0 3.31-2.69 6-6 6-.71 0-1.37-.15-2-.38v.01C3.67 12.81 2 10.61 2 8c0-3.31 2.69-6 6-6 1.77 0 3.36.78 4.46 2H11c-.55 0-1 .45-1 1z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
Connect New Device
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</SuccessStep>
|
||||||
|
</Router>
|
||||||
|
</BrowserRouter>
|
||||||
|
`;
|
78
app/components/TopPanel.spec.tsx
Normal file
78
app/components/TopPanel.spec.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { ShallowWrapper } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import TopPanel from './TopPanel';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
const settingsButtonSelector = '#top-panel-settings-button';
|
||||||
|
const connectedDevicesListButtonSelector =
|
||||||
|
'#top-panel-connected-devices-list-button';
|
||||||
|
|
||||||
|
describe('<TopPanel />', () => {
|
||||||
|
let wrapper: ShallowWrapper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = Enzyme.shallow(<TopPanel />);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
expect(EnzymeToJson(wrapper)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when Settings button in top panel is clicked', () => {
|
||||||
|
it('should Settings Overlay props isSettingsOpen to true', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(settingsButtonSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
const settingsOverlay = wrapper.props().children[1];
|
||||||
|
|
||||||
|
expect(settingsOverlay.props.isSettingsOpen).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when Settings panel is opened and when its props.handleClose is called', () => {
|
||||||
|
it('should Settings Overlay props isSettingsOpen to false', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(settingsButtonSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
const settingsOverlay = wrapper.props().children[1];
|
||||||
|
settingsOverlay.props.handleClose();
|
||||||
|
// @ts-ignore
|
||||||
|
const settingsOverlayAfterClose = wrapper.props().children[1];
|
||||||
|
|
||||||
|
expect(settingsOverlayAfterClose.props.isSettingsOpen).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when Connected Devices button in top panel is clicked', () => {
|
||||||
|
it('should set Connected Devices List Drawer props isOpen to true', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(connectedDevicesListButtonSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
const connectedDevicesListDrawer = wrapper.props().children[2];
|
||||||
|
expect(connectedDevicesListDrawer.props.isOpen).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when Connected Devices List Drawer is opened, and when it's props.handleToggle is called", () => {
|
||||||
|
it('should set Connected Devices List Drawer props isOpen to false', () => {
|
||||||
|
// @ts-ignore
|
||||||
|
wrapper.find(connectedDevicesListButtonSelector).props().onClick();
|
||||||
|
// @ts-ignore
|
||||||
|
const connectedDevicesListDrawer = wrapper.props().children[2];
|
||||||
|
connectedDevicesListDrawer.props.handleToggle();
|
||||||
|
// @ts-ignore
|
||||||
|
const connectedDevicesListDrawerAfter = wrapper.props().children[2];
|
||||||
|
|
||||||
|
expect(connectedDevicesListDrawerAfter.props.isOpen).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
177
app/components/TopPanel.tsx
Normal file
177
app/components/TopPanel.tsx
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/* eslint-disable react/destructuring-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable react-hooks/rules-of-hooks */
|
||||||
|
import React, { useCallback, useContext } from 'react';
|
||||||
|
import { Button, Icon, Position, Tooltip } from '@blueprintjs/core';
|
||||||
|
import { createStyles, makeStyles } from '@material-ui/core/styles';
|
||||||
|
import SettingsOverlay from './SettingsOverlay/SettingsOverlay';
|
||||||
|
import ConnectedDevicesListDrawer from './ConnectedDevicesListDrawer';
|
||||||
|
import { SettingsContext } from '../containers/SettingsProvider';
|
||||||
|
import isProduction from '../utils/isProduction';
|
||||||
|
|
||||||
|
const Zoom = require('react-reveal/Zoom');
|
||||||
|
const Fade = require('react-reveal/Fade');
|
||||||
|
|
||||||
|
const useStylesWithTheme = (isDarkTheme: boolean) =>
|
||||||
|
makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
topPanelRoot: {
|
||||||
|
display: 'flex',
|
||||||
|
paddingTop: '15px',
|
||||||
|
marginBottom: '20px',
|
||||||
|
},
|
||||||
|
logoWithAppName: { margin: '0 auto' },
|
||||||
|
appNameHeader: {
|
||||||
|
margin: '0 auto',
|
||||||
|
paddingTop: '5px',
|
||||||
|
fontFamily: 'Lexend Peta',
|
||||||
|
fontSize: '20px',
|
||||||
|
color: isDarkTheme ? '#48AFF0' : '#1F4B99',
|
||||||
|
cursor: 'default !important',
|
||||||
|
},
|
||||||
|
topPanelControlButtonsRoot: {
|
||||||
|
position: 'absolute',
|
||||||
|
right: '15px',
|
||||||
|
display: 'flex',
|
||||||
|
},
|
||||||
|
topPanelControlButton: {
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
borderRadius: '50px',
|
||||||
|
cursor: 'default !important',
|
||||||
|
},
|
||||||
|
topPanelControlButtonMargin: {
|
||||||
|
marginRight: '20px',
|
||||||
|
cursor: 'default !important',
|
||||||
|
},
|
||||||
|
topPanelIconOfControlButton: {
|
||||||
|
cursor: 'default !important',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function TopPanel(props: any) {
|
||||||
|
const { isDarkTheme } = useContext(SettingsContext);
|
||||||
|
|
||||||
|
const getClassesCallback = useCallback(() => {
|
||||||
|
return useStylesWithTheme(isDarkTheme)();
|
||||||
|
}, [isDarkTheme]);
|
||||||
|
|
||||||
|
const [isSettingsOpen, setIsSettingsOpen] = React.useState(false);
|
||||||
|
const [isDrawersOpen, setIsDrawerOpen] = React.useState(false);
|
||||||
|
|
||||||
|
const handleSettingsOpen = useCallback(() => {
|
||||||
|
setIsSettingsOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleSettingsClose = useCallback(() => {
|
||||||
|
setIsSettingsOpen(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleToggleConnectedDevicesListDrawer = useCallback(() => {
|
||||||
|
setIsDrawerOpen(!isDrawersOpen);
|
||||||
|
}, [isDrawersOpen]);
|
||||||
|
|
||||||
|
const renderConnectedDevicesListButton = useCallback(() => {
|
||||||
|
return (
|
||||||
|
<div className={getClassesCallback().topPanelControlButtonMargin}>
|
||||||
|
<Tooltip content="Connected Devices" position={Position.BOTTOM}>
|
||||||
|
<Button
|
||||||
|
id="top-panel-connected-devices-list-button"
|
||||||
|
intent="none"
|
||||||
|
className={getClassesCallback().topPanelControlButton}
|
||||||
|
onClick={handleToggleConnectedDevicesListDrawer}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
className={getClassesCallback().topPanelIconOfControlButton}
|
||||||
|
icon="th-list"
|
||||||
|
iconSize={20}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [getClassesCallback, handleToggleConnectedDevicesListDrawer]);
|
||||||
|
|
||||||
|
const renderHelpButton = useCallback(() => {
|
||||||
|
return (
|
||||||
|
<div className={getClassesCallback().topPanelControlButtonMargin}>
|
||||||
|
<Tooltip content="Help" position={Position.BOTTOM}>
|
||||||
|
<Button
|
||||||
|
id="top-panel-help-button"
|
||||||
|
intent="none"
|
||||||
|
className={getClassesCallback().topPanelControlButton}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
className={getClassesCallback().topPanelIconOfControlButton}
|
||||||
|
icon="help"
|
||||||
|
iconSize={22}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [getClassesCallback]);
|
||||||
|
|
||||||
|
const renderSettingsButton = useCallback(() => {
|
||||||
|
return (
|
||||||
|
<div className={getClassesCallback().topPanelControlButtonMargin}>
|
||||||
|
<Tooltip content="Settings" position={Position.BOTTOM}>
|
||||||
|
<Button
|
||||||
|
id="top-panel-settings-button"
|
||||||
|
onClick={handleSettingsOpen}
|
||||||
|
className={getClassesCallback().topPanelControlButton}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
className={getClassesCallback().topPanelIconOfControlButton}
|
||||||
|
icon="cog"
|
||||||
|
iconSize={22}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [getClassesCallback, handleSettingsOpen]);
|
||||||
|
|
||||||
|
const renderLogoWithAppName = useCallback(() => {
|
||||||
|
return (
|
||||||
|
<Zoom top duration={isProduction() ? 3000 : 0}>
|
||||||
|
<div
|
||||||
|
id="logo-with-popover-visit-website"
|
||||||
|
className={getClassesCallback().logoWithAppName}
|
||||||
|
>
|
||||||
|
<h4
|
||||||
|
id="deskreen-top-app-name-header"
|
||||||
|
className={getClassesCallback().appNameHeader}
|
||||||
|
>
|
||||||
|
Deskreen
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</Zoom>
|
||||||
|
);
|
||||||
|
}, [getClassesCallback]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={getClassesCallback().topPanelRoot}>
|
||||||
|
{renderLogoWithAppName()}
|
||||||
|
<div className={getClassesCallback().topPanelControlButtonsRoot}>
|
||||||
|
<Fade right duration={isProduction() ? 2000 : 0}>
|
||||||
|
{renderConnectedDevicesListButton()}
|
||||||
|
{renderHelpButton()}
|
||||||
|
{renderSettingsButton()}
|
||||||
|
</Fade>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<SettingsOverlay
|
||||||
|
isSettingsOpen={isSettingsOpen}
|
||||||
|
handleClose={handleSettingsClose}
|
||||||
|
/>
|
||||||
|
<ConnectedDevicesListDrawer
|
||||||
|
isOpen={isDrawersOpen}
|
||||||
|
handleToggle={handleToggleConnectedDevicesListDrawer}
|
||||||
|
stepperRef={props.stepperRef}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,607 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should match exact snapshot 1`] = `
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"length": 1,
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<AllowConnectionForDeviceAlert
|
||||||
|
device={Object {}}
|
||||||
|
isOpen={true}
|
||||||
|
onCancel={[Function]}
|
||||||
|
onConfirm={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.Alert
|
||||||
|
canEscapeKeyCancel={false}
|
||||||
|
canOutsideClickCancel={false}
|
||||||
|
cancelButtonText="Deny"
|
||||||
|
className="class-allow-device-to-connect-alert"
|
||||||
|
confirmButtonText="Allow"
|
||||||
|
icon="feed"
|
||||||
|
intent="danger"
|
||||||
|
isOpen={true}
|
||||||
|
onCancel={[Function]}
|
||||||
|
onConfirm={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
>
|
||||||
|
<Blueprint3.Dialog
|
||||||
|
canEscapeKeyClose={false}
|
||||||
|
canOutsideClickClose={false}
|
||||||
|
className="bp3-alert class-allow-device-to-connect-alert"
|
||||||
|
isOpen={true}
|
||||||
|
onCancel={[Function]}
|
||||||
|
onClose={[Function]}
|
||||||
|
onConfirm={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
>
|
||||||
|
<Blueprint3.Overlay
|
||||||
|
autoFocus={true}
|
||||||
|
backdropProps={Object {}}
|
||||||
|
canEscapeKeyClose={false}
|
||||||
|
canOutsideClickClose={false}
|
||||||
|
className="bp3-overlay-scroll-container"
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={true}
|
||||||
|
isOpen={true}
|
||||||
|
lazy={true}
|
||||||
|
onCancel={[Function]}
|
||||||
|
onClose={[Function]}
|
||||||
|
onConfirm={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
transitionName="bp3-overlay"
|
||||||
|
usePortal={true}
|
||||||
|
>
|
||||||
|
<Blueprint3.Portal
|
||||||
|
container={
|
||||||
|
<body
|
||||||
|
class="bp3-overlay-open"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-portal"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay bp3-overlay-open bp3-overlay-scroll-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay-backdrop bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="bp3-dialog-container bp3-overlay-content bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-dialog bp3-alert class-allow-device-to-connect-alert"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-alert-body"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-icon bp3-icon-feed bp3-intent-danger"
|
||||||
|
icon="feed"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="feed"
|
||||||
|
height="40"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width="40"
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
feed
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M2.5 15a2.5 2.5 0 000 5 2.5 2.5 0 000-5zm.5-5c-.55 0-1 .45-1 1s.45 1 1 1c2.76 0 5 2.24 5 5 0 .55.45 1 1 1s1-.45 1-1c0-3.87-3.13-7-7-7zM3 0c-.55 0-1 .45-1 1s.45 1 1 1c8.28 0 15 6.72 15 15 0 .55.45 1 1 1s1-.45 1-1C20 7.61 12.39 0 3 0zm0 5c-.55 0-1 .45-1 1s.45 1 1 1c5.52 0 10 4.48 10 10 0 .55.45 1 1 1s1-.45 1-1C15 10.37 9.63 5 3 5z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="bp3-alert-contents"
|
||||||
|
>
|
||||||
|
<h3
|
||||||
|
class="bp3-heading"
|
||||||
|
>
|
||||||
|
Device is trying to connect
|
||||||
|
</h3>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
Device IP:
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
id="allow-connection-device-alert-device-ip-span"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
Device Type: undefined
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
Device OS: undefined
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
session ID: undefined
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="bp3-alert-footer"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="bp3-button bp3-intent-danger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
Allow
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="bp3-button"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
Deny
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Portal
|
||||||
|
containerInfo={
|
||||||
|
<div
|
||||||
|
class="bp3-portal"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay bp3-overlay-open bp3-overlay-scroll-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay-backdrop bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="bp3-dialog-container bp3-overlay-content bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-dialog bp3-alert class-allow-device-to-connect-alert"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-alert-body"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-icon bp3-icon-feed bp3-intent-danger"
|
||||||
|
icon="feed"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="feed"
|
||||||
|
height="40"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width="40"
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
feed
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M2.5 15a2.5 2.5 0 000 5 2.5 2.5 0 000-5zm.5-5c-.55 0-1 .45-1 1s.45 1 1 1c2.76 0 5 2.24 5 5 0 .55.45 1 1 1s1-.45 1-1c0-3.87-3.13-7-7-7zM3 0c-.55 0-1 .45-1 1s.45 1 1 1c8.28 0 15 6.72 15 15 0 .55.45 1 1 1s1-.45 1-1C20 7.61 12.39 0 3 0zm0 5c-.55 0-1 .45-1 1s.45 1 1 1c5.52 0 10 4.48 10 10 0 .55.45 1 1 1s1-.45 1-1C15 10.37 9.63 5 3 5z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="bp3-alert-contents"
|
||||||
|
>
|
||||||
|
<h3
|
||||||
|
class="bp3-heading"
|
||||||
|
>
|
||||||
|
Device is trying to connect
|
||||||
|
</h3>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
Device IP:
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
id="allow-connection-device-alert-device-ip-span"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
Device Type: undefined
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
Device OS: undefined
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
session ID: undefined
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="bp3-alert-footer"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="bp3-button bp3-intent-danger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
Allow
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="bp3-button"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
Deny
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<TransitionGroup
|
||||||
|
appear={true}
|
||||||
|
childFactory={[Function]}
|
||||||
|
className="bp3-overlay bp3-overlay-open bp3-overlay-scroll-container"
|
||||||
|
component="div"
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-overlay bp3-overlay-open bp3-overlay-scroll-container"
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
>
|
||||||
|
<CSSTransition
|
||||||
|
appear={true}
|
||||||
|
classNames="bp3-overlay"
|
||||||
|
in={true}
|
||||||
|
key=".$__backdrop"
|
||||||
|
onExited={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
>
|
||||||
|
<Transition
|
||||||
|
appear={true}
|
||||||
|
enter={true}
|
||||||
|
exit={true}
|
||||||
|
in={true}
|
||||||
|
mountOnEnter={false}
|
||||||
|
onEnter={[Function]}
|
||||||
|
onEntered={[Function]}
|
||||||
|
onEntering={[Function]}
|
||||||
|
onExit={[Function]}
|
||||||
|
onExited={[Function]}
|
||||||
|
onExiting={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
unmountOnExit={false}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-overlay-backdrop"
|
||||||
|
onMouseDown={[Function]}
|
||||||
|
tabIndex={null}
|
||||||
|
/>
|
||||||
|
</Transition>
|
||||||
|
</CSSTransition>
|
||||||
|
<CSSTransition
|
||||||
|
appear={true}
|
||||||
|
classNames="bp3-overlay"
|
||||||
|
in={true}
|
||||||
|
key=".$.0"
|
||||||
|
onExited={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
>
|
||||||
|
<Transition
|
||||||
|
appear={true}
|
||||||
|
enter={true}
|
||||||
|
exit={true}
|
||||||
|
in={true}
|
||||||
|
mountOnEnter={false}
|
||||||
|
onEnter={[Function]}
|
||||||
|
onEntered={[Function]}
|
||||||
|
onEntering={[Function]}
|
||||||
|
onExit={[Function]}
|
||||||
|
onExited={[Function]}
|
||||||
|
onExiting={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
unmountOnExit={false}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-dialog-container bp3-overlay-content"
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-dialog bp3-alert class-allow-device-to-connect-alert"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-alert-body"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
icon="feed"
|
||||||
|
iconSize={40}
|
||||||
|
intent="danger"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-feed bp3-intent-danger"
|
||||||
|
icon="feed"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="feed"
|
||||||
|
height={40}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width={40}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
feed
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M2.5 15a2.5 2.5 0 000 5 2.5 2.5 0 000-5zm.5-5c-.55 0-1 .45-1 1s.45 1 1 1c2.76 0 5 2.24 5 5 0 .55.45 1 1 1s1-.45 1-1c0-3.87-3.13-7-7-7zM3 0c-.55 0-1 .45-1 1s.45 1 1 1c8.28 0 15 6.72 15 15 0 .55.45 1 1 1s1-.45 1-1C20 7.61 12.39 0 3 0zm0 5c-.55 0-1 .45-1 1s.45 1 1 1c5.52 0 10 4.48 10 10 0 .55.45 1 1 1s1-.45 1-1C15 10.37 9.63 5 3 5z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<div
|
||||||
|
className="bp3-alert-contents"
|
||||||
|
>
|
||||||
|
<Component>
|
||||||
|
<h3
|
||||||
|
className="bp3-heading"
|
||||||
|
>
|
||||||
|
Device is trying to connect
|
||||||
|
</h3>
|
||||||
|
</Component>
|
||||||
|
<Row>
|
||||||
|
<div
|
||||||
|
className="row"
|
||||||
|
>
|
||||||
|
<Col>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Device IP:
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
<span
|
||||||
|
id="allow-connection-device-alert-device-ip-span"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<div
|
||||||
|
className="row"
|
||||||
|
>
|
||||||
|
<Col>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Device Type: undefined
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<div
|
||||||
|
className="row"
|
||||||
|
>
|
||||||
|
<Col>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
Device OS: undefined
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<div
|
||||||
|
className="row"
|
||||||
|
>
|
||||||
|
<Col>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
<Blueprint3.Text>
|
||||||
|
<div
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
session ID: undefined
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="bp3-alert-footer"
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
intent="danger"
|
||||||
|
onClick={[Function]}
|
||||||
|
text="Allow"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-intent-danger"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
Allow
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
<Blueprint3.Button
|
||||||
|
onClick={[Function]}
|
||||||
|
text="Deny"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
Deny
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</CSSTransition>
|
||||||
|
</div>
|
||||||
|
</TransitionGroup>
|
||||||
|
</Portal>
|
||||||
|
</Blueprint3.Portal>
|
||||||
|
</Blueprint3.Overlay>
|
||||||
|
</Blueprint3.Dialog>
|
||||||
|
</Blueprint3.Alert>
|
||||||
|
</AllowConnectionForDeviceAlert>
|
||||||
|
</Router>
|
||||||
|
</BrowserRouter>
|
||||||
|
`;
|
@ -0,0 +1,644 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should match exact snapshot 1`] = `
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"length": 1,
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ConnectedDevicesListDrawer
|
||||||
|
handleToggle={[Function]}
|
||||||
|
isOpen={true}
|
||||||
|
stepperRef={null}
|
||||||
|
>
|
||||||
|
<Blueprint3.Drawer
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="makeStyles-drawerRoot-1"
|
||||||
|
isOpen={true}
|
||||||
|
onClose={[Function]}
|
||||||
|
position="bottom"
|
||||||
|
size="90%"
|
||||||
|
style={Object {}}
|
||||||
|
transitionDuration={0}
|
||||||
|
vertical={false}
|
||||||
|
>
|
||||||
|
<Blueprint3.Overlay
|
||||||
|
autoFocus={true}
|
||||||
|
backdropProps={Object {}}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="bp3-overlay-container"
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={true}
|
||||||
|
isOpen={true}
|
||||||
|
lazy={true}
|
||||||
|
onClose={[Function]}
|
||||||
|
position="bottom"
|
||||||
|
size="90%"
|
||||||
|
style={Object {}}
|
||||||
|
transitionDuration={0}
|
||||||
|
transitionName="bp3-overlay"
|
||||||
|
usePortal={true}
|
||||||
|
vertical={false}
|
||||||
|
>
|
||||||
|
<Blueprint3.Portal
|
||||||
|
container={
|
||||||
|
<body
|
||||||
|
class="bp3-overlay-open"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-portal"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay bp3-overlay-open bp3-overlay-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay-backdrop bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="bp3-drawer bp3-position-bottom makeStyles-drawerRoot-1 bp3-overlay-content bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
style="height: 90%;"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="makeStyles-drawerInnerTopPanel-2 row middle-xs between-xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="col-xs-11"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="row middle-xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="makeStyles-topHeader-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-text-muted"
|
||||||
|
>
|
||||||
|
Connected Devices
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="bp3-button bp3-disabled bp3-intent-danger"
|
||||||
|
disabled=""
|
||||||
|
tabindex="-1"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-icon bp3-icon-disable"
|
||||||
|
icon="disable"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="disable"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
disable
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M7.99-.01c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm-6 8c0-3.31 2.69-6 6-6 1.3 0 2.49.42 3.47 1.12l-8.35 8.35c-.7-.98-1.12-2.17-1.12-3.47zm6 6c-1.3 0-2.49-.42-3.47-1.12l8.35-8.35c.7.98 1.12 2.17 1.12 3.47 0 3.32-2.68 6-6 6z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
Disconnect all devices
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col-xs-1"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="bp3-button makeStyles-closeButton-6 undefined"
|
||||||
|
id="close-overlay-button"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-icon bp3-icon-cross"
|
||||||
|
icon="cross"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="cross"
|
||||||
|
height="30"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width="30"
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
cross
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M11.41 10l4.29-4.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L10 8.59l-4.29-4.3a1.003 1.003 0 00-1.42 1.42L8.59 10 4.3 14.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l4.29-4.3 4.29 4.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L11.41 10z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="makeStyles-connectedDevicesRoot-3 row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="col-xs-12"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="react-reveal makeStyles-zoomFullWidth-5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Portal
|
||||||
|
containerInfo={
|
||||||
|
<div
|
||||||
|
class="bp3-portal"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay bp3-overlay-open bp3-overlay-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-overlay-backdrop bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="bp3-drawer bp3-position-bottom makeStyles-drawerRoot-1 bp3-overlay-content bp3-overlay-appear bp3-overlay-appear-active"
|
||||||
|
style="height: 90%;"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="makeStyles-drawerInnerTopPanel-2 row middle-xs between-xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="col-xs-11"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="row middle-xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="makeStyles-topHeader-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bp3-text-muted"
|
||||||
|
>
|
||||||
|
Connected Devices
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="bp3-button bp3-disabled bp3-intent-danger"
|
||||||
|
disabled=""
|
||||||
|
tabindex="-1"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-icon bp3-icon-disable"
|
||||||
|
icon="disable"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="disable"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width="16"
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
disable
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M7.99-.01c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm-6 8c0-3.31 2.69-6 6-6 1.3 0 2.49.42 3.47 1.12l-8.35 8.35c-.7-.98-1.12-2.17-1.12-3.47zm6 6c-1.3 0-2.49-.42-3.47-1.12l8.35-8.35c.7.98 1.12 2.17 1.12 3.47 0 3.32-2.68 6-6 6z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
Disconnect all devices
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col-xs-1"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="bp3-button makeStyles-closeButton-6 undefined"
|
||||||
|
id="close-overlay-button"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-button-text"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="bp3-icon bp3-icon-cross"
|
||||||
|
icon="cross"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="cross"
|
||||||
|
height="30"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width="30"
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
cross
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M11.41 10l4.29-4.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L10 8.59l-4.29-4.3a1.003 1.003 0 00-1.42 1.42L8.59 10 4.3 14.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l4.29-4.3 4.29 4.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L11.41 10z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="makeStyles-connectedDevicesRoot-3 row"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="col-xs-12"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="react-reveal makeStyles-zoomFullWidth-5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<TransitionGroup
|
||||||
|
appear={true}
|
||||||
|
childFactory={[Function]}
|
||||||
|
className="bp3-overlay bp3-overlay-open bp3-overlay-container"
|
||||||
|
component="div"
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-overlay bp3-overlay-open bp3-overlay-container"
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
>
|
||||||
|
<CSSTransition
|
||||||
|
appear={true}
|
||||||
|
classNames="bp3-overlay"
|
||||||
|
in={true}
|
||||||
|
key=".$__backdrop"
|
||||||
|
onExited={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
>
|
||||||
|
<Transition
|
||||||
|
appear={true}
|
||||||
|
enter={true}
|
||||||
|
exit={true}
|
||||||
|
in={true}
|
||||||
|
mountOnEnter={false}
|
||||||
|
onEnter={[Function]}
|
||||||
|
onEntered={[Function]}
|
||||||
|
onEntering={[Function]}
|
||||||
|
onExit={[Function]}
|
||||||
|
onExited={[Function]}
|
||||||
|
onExiting={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
unmountOnExit={false}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-overlay-backdrop"
|
||||||
|
onMouseDown={[Function]}
|
||||||
|
tabIndex={0}
|
||||||
|
/>
|
||||||
|
</Transition>
|
||||||
|
</CSSTransition>
|
||||||
|
<CSSTransition
|
||||||
|
appear={true}
|
||||||
|
classNames="bp3-overlay"
|
||||||
|
in={true}
|
||||||
|
key=".$.0"
|
||||||
|
onExited={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
>
|
||||||
|
<Transition
|
||||||
|
appear={true}
|
||||||
|
enter={true}
|
||||||
|
exit={true}
|
||||||
|
in={true}
|
||||||
|
mountOnEnter={false}
|
||||||
|
onEnter={[Function]}
|
||||||
|
onEntered={[Function]}
|
||||||
|
onEntering={[Function]}
|
||||||
|
onExit={[Function]}
|
||||||
|
onExited={[Function]}
|
||||||
|
onExiting={[Function]}
|
||||||
|
timeout={0}
|
||||||
|
unmountOnExit={false}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-drawer bp3-position-bottom makeStyles-drawerRoot-1 bp3-overlay-content"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"height": "90%",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<Row
|
||||||
|
between="xs"
|
||||||
|
className="makeStyles-drawerInnerTopPanel-2"
|
||||||
|
middle="xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="makeStyles-drawerInnerTopPanel-2 row middle-xs between-xs"
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
xs={11}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs-11"
|
||||||
|
>
|
||||||
|
<Row
|
||||||
|
middle="xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="row middle-xs"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="makeStyles-topHeader-4"
|
||||||
|
>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-text-muted"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-text-muted"
|
||||||
|
>
|
||||||
|
Connected Devices
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</div>
|
||||||
|
<Blueprint3.Button
|
||||||
|
disabled={true}
|
||||||
|
icon="disable"
|
||||||
|
intent="danger"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-disabled bp3-intent-danger"
|
||||||
|
disabled={true}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
tabIndex={-1}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
icon="disable"
|
||||||
|
key="leftIcon"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-disable"
|
||||||
|
icon="disable"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="disable"
|
||||||
|
height={16}
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width={16}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
disable
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M7.99-.01c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm-6 8c0-3.31 2.69-6 6-6 1.3 0 2.49.42 3.47 1.12l-8.35 8.35c-.7-.98-1.12-2.17-1.12-3.47zm6 6c-1.3 0-2.49-.42-3.47-1.12l8.35-8.35c.7.98 1.12 2.17 1.12 3.47 0 3.32-2.68 6-6 6z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
Disconnect all devices
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col
|
||||||
|
xs={1}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs-1"
|
||||||
|
>
|
||||||
|
<CloseOverlayButton
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-closeButton-6 undefined"
|
||||||
|
id="close-overlay-button"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button makeStyles-closeButton-6 undefined"
|
||||||
|
id="close-overlay-button"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
icon="cross"
|
||||||
|
iconSize={30}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-cross"
|
||||||
|
icon="cross"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="cross"
|
||||||
|
height={30}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width={30}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
cross
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M11.41 10l4.29-4.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L10 8.59l-4.29-4.3a1.003 1.003 0 00-1.42 1.42L8.59 10 4.3 14.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l4.29-4.3 4.29 4.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L11.41 10z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</CloseOverlayButton>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
<Row
|
||||||
|
className="makeStyles-connectedDevicesRoot-3"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="makeStyles-connectedDevicesRoot-3 row"
|
||||||
|
>
|
||||||
|
<Col
|
||||||
|
xs={12}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-xs-12"
|
||||||
|
>
|
||||||
|
<Fade
|
||||||
|
bottom={true}
|
||||||
|
cascade={true}
|
||||||
|
duration={0}
|
||||||
|
>
|
||||||
|
<RevealBase
|
||||||
|
bottom={true}
|
||||||
|
cascade={true}
|
||||||
|
fraction={0.2}
|
||||||
|
inEffect={
|
||||||
|
Object {
|
||||||
|
"count": 1,
|
||||||
|
"delay": 0,
|
||||||
|
"duration": 0,
|
||||||
|
"forever": undefined,
|
||||||
|
"make": [Function],
|
||||||
|
"reverse": undefined,
|
||||||
|
"style": Object {
|
||||||
|
"animationFillMode": "both",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outEffect={
|
||||||
|
Object {
|
||||||
|
"count": 1,
|
||||||
|
"delay": 0,
|
||||||
|
"duration": 0,
|
||||||
|
"forever": undefined,
|
||||||
|
"make": [Function],
|
||||||
|
"reverse": undefined,
|
||||||
|
"style": Object {
|
||||||
|
"animationFillMode": "both",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refProp="ref"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="react-reveal makeStyles-zoomFullWidth-5"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</RevealBase>
|
||||||
|
</Fade>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</div>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</CSSTransition>
|
||||||
|
</div>
|
||||||
|
</TransitionGroup>
|
||||||
|
</Portal>
|
||||||
|
</Blueprint3.Portal>
|
||||||
|
</Blueprint3.Overlay>
|
||||||
|
</Blueprint3.Drawer>
|
||||||
|
<Blueprint3.Alert
|
||||||
|
canEscapeKeyCancel={true}
|
||||||
|
canOutsideClickCancel={true}
|
||||||
|
cancelButtonText="No, Cancel"
|
||||||
|
confirmButtonText="Yes, Disconnect All"
|
||||||
|
icon="warning-sign"
|
||||||
|
intent="danger"
|
||||||
|
isOpen={false}
|
||||||
|
onCancel={[Function]}
|
||||||
|
onClose={[Function]}
|
||||||
|
onConfirm={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
>
|
||||||
|
<Blueprint3.Dialog
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="bp3-alert"
|
||||||
|
isOpen={false}
|
||||||
|
onCancel={[Function]}
|
||||||
|
onClose={[Function]}
|
||||||
|
onConfirm={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
>
|
||||||
|
<Blueprint3.Overlay
|
||||||
|
autoFocus={true}
|
||||||
|
backdropProps={Object {}}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="bp3-overlay-scroll-container"
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={true}
|
||||||
|
isOpen={false}
|
||||||
|
lazy={true}
|
||||||
|
onCancel={[Function]}
|
||||||
|
onClose={[Function]}
|
||||||
|
onConfirm={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
transitionName="bp3-overlay"
|
||||||
|
usePortal={true}
|
||||||
|
/>
|
||||||
|
</Blueprint3.Dialog>
|
||||||
|
</Blueprint3.Alert>
|
||||||
|
</ConnectedDevicesListDrawer>
|
||||||
|
</Router>
|
||||||
|
</BrowserRouter>
|
||||||
|
`;
|
@ -0,0 +1,230 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`should match exact snapshot 1`] = `
|
||||||
|
<BrowserRouter>
|
||||||
|
<Router
|
||||||
|
history={
|
||||||
|
Object {
|
||||||
|
"action": "POP",
|
||||||
|
"block": [Function],
|
||||||
|
"createHref": [Function],
|
||||||
|
"go": [Function],
|
||||||
|
"goBack": [Function],
|
||||||
|
"goForward": [Function],
|
||||||
|
"length": 1,
|
||||||
|
"listen": [Function],
|
||||||
|
"location": Object {
|
||||||
|
"hash": "",
|
||||||
|
"pathname": "/",
|
||||||
|
"search": "",
|
||||||
|
"state": undefined,
|
||||||
|
},
|
||||||
|
"push": [Function],
|
||||||
|
"replace": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ShareEntireScreenOrAppWindowControlGroup
|
||||||
|
handleNextApplicationWindow={[Function]}
|
||||||
|
handleNextEntireScreen={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.ControlGroup
|
||||||
|
className="makeStyles-controlGroupRoot-1"
|
||||||
|
fill={true}
|
||||||
|
id="share-screen-or-app-btn-group"
|
||||||
|
vertical={false}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-control-group bp3-fill makeStyles-controlGroupRoot-1"
|
||||||
|
id="share-screen-or-app-btn-group"
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-shareEntireScreenButton-2"
|
||||||
|
intent="primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-intent-primary makeStyles-shareEntireScreenButton-2"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
className="makeStyles-shareEntireScreenButtonIcon-3"
|
||||||
|
color="white"
|
||||||
|
icon="desktop"
|
||||||
|
iconSize={100}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-desktop makeStyles-shareEntireScreenButtonIcon-3"
|
||||||
|
icon="desktop"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="desktop"
|
||||||
|
fill="white"
|
||||||
|
height={100}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width={100}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
desktop
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M19 0H1C.45 0 0 .45 0 1v13c0 .55.45 1 1 1h5.67l-.5 3H5c-.55 0-1 .45-1 1s.45 1 1 1h10c.55 0 1-.45 1-1s-.45-1-1-1h-1.17l-.5-3H19c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1zm-1 13H2V2h16v11z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
Entire Screen
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-shareAppButton-4"
|
||||||
|
intent="primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-intent-primary makeStyles-shareAppButton-4"
|
||||||
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
className="makeStyles-shareAppButtonIcon-5"
|
||||||
|
color="white"
|
||||||
|
icon="application"
|
||||||
|
iconSize={100}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="bp3-icon bp3-icon-application makeStyles-shareAppButtonIcon-5"
|
||||||
|
icon="application"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
data-icon="application"
|
||||||
|
fill="white"
|
||||||
|
height={100}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
width={100}
|
||||||
|
>
|
||||||
|
<desc>
|
||||||
|
application
|
||||||
|
</desc>
|
||||||
|
<path
|
||||||
|
d="M3.5 9h9c.28 0 .5-.22.5-.5s-.22-.5-.5-.5h-9c-.28 0-.5.22-.5.5s.22.5.5.5zm0 2h5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5h-5c-.28 0-.5.22-.5.5s.22.5.5.5zM19 1H1c-.55 0-1 .45-1 1v16c0 .55.45 1 1 1h18c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm-1 16H2V6h16v11zM3.5 13h7c.28 0 .5-.22.5-.5s-.22-.5-.5-.5h-7c-.28 0-.5.22-.5.5s.22.5.5.5z"
|
||||||
|
fillRule="evenodd"
|
||||||
|
key="0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</Blueprint3.Icon>
|
||||||
|
<Blueprint3.Text
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bp3-running-text"
|
||||||
|
>
|
||||||
|
Application Window
|
||||||
|
</div>
|
||||||
|
</Blueprint3.Text>
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
<Blueprint3.Button
|
||||||
|
active={true}
|
||||||
|
className="makeStyles-orDecorationButton-6"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="bp3-button bp3-active makeStyles-orDecorationButton-6"
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="leftIcon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="bp3-button-text"
|
||||||
|
key="text"
|
||||||
|
>
|
||||||
|
OR
|
||||||
|
</span>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
key="rightIcon"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</div>
|
||||||
|
</Blueprint3.ControlGroup>
|
||||||
|
<ChooseAppOrScreenOverlay
|
||||||
|
handleClose={[Function]}
|
||||||
|
handleNextApplicationWindow={[Function]}
|
||||||
|
handleNextEntireScreen={[Function]}
|
||||||
|
isChooseAppOrScreenOverlayOpen={false}
|
||||||
|
isEntireScreenToShareChosen={false}
|
||||||
|
>
|
||||||
|
<Blueprint3.Dialog
|
||||||
|
autoFocus={true}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="makeStyles-dialogRoot-7 choose-app-or-screen-dialog"
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={true}
|
||||||
|
isOpen={false}
|
||||||
|
onClose={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
usePortal={true}
|
||||||
|
>
|
||||||
|
<Blueprint3.Overlay
|
||||||
|
autoFocus={true}
|
||||||
|
backdropProps={Object {}}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
canOutsideClickClose={true}
|
||||||
|
className="bp3-overlay-scroll-container"
|
||||||
|
enforceFocus={true}
|
||||||
|
hasBackdrop={true}
|
||||||
|
isOpen={false}
|
||||||
|
lazy={true}
|
||||||
|
onClose={[Function]}
|
||||||
|
transitionDuration={0}
|
||||||
|
transitionName="bp3-overlay"
|
||||||
|
usePortal={true}
|
||||||
|
/>
|
||||||
|
</Blueprint3.Dialog>
|
||||||
|
</ChooseAppOrScreenOverlay>
|
||||||
|
</ShareEntireScreenOrAppWindowControlGroup>
|
||||||
|
</Router>
|
||||||
|
</BrowserRouter>
|
||||||
|
`;
|
113
app/components/__snapshots__/TopPanel.spec.tsx.snap
Normal file
113
app/components/__snapshots__/TopPanel.spec.tsx.snap
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`<TopPanel /> should match exact snapshot 1`] = `
|
||||||
|
<Fragment>
|
||||||
|
<div
|
||||||
|
className="makeStyles-topPanelRoot-1"
|
||||||
|
>
|
||||||
|
<Zoom
|
||||||
|
duration={0}
|
||||||
|
top={true}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="makeStyles-logoWithAppName-9"
|
||||||
|
id="logo-with-popover-visit-website"
|
||||||
|
>
|
||||||
|
<h4
|
||||||
|
className="makeStyles-appNameHeader-17"
|
||||||
|
id="deskreen-top-app-name-header"
|
||||||
|
>
|
||||||
|
Deskreen
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</Zoom>
|
||||||
|
<div
|
||||||
|
className="makeStyles-topPanelControlButtonsRoot-25"
|
||||||
|
>
|
||||||
|
<Fade
|
||||||
|
duration={0}
|
||||||
|
right={true}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="makeStyles-topPanelControlButtonMargin-34"
|
||||||
|
>
|
||||||
|
<Blueprint3.Tooltip
|
||||||
|
content="Connected Devices"
|
||||||
|
hoverCloseDelay={0}
|
||||||
|
hoverOpenDelay={100}
|
||||||
|
position="bottom"
|
||||||
|
transitionDuration={100}
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-topPanelControlButton-40"
|
||||||
|
id="top-panel-connected-devices-list-button"
|
||||||
|
intent="none"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
className="makeStyles-topPanelIconOfControlButton-49"
|
||||||
|
icon="th-list"
|
||||||
|
iconSize={20}
|
||||||
|
/>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</Blueprint3.Tooltip>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="makeStyles-topPanelControlButtonMargin-55"
|
||||||
|
>
|
||||||
|
<Blueprint3.Tooltip
|
||||||
|
content="Help"
|
||||||
|
hoverCloseDelay={0}
|
||||||
|
hoverOpenDelay={100}
|
||||||
|
position="bottom"
|
||||||
|
transitionDuration={100}
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-topPanelControlButton-61"
|
||||||
|
id="top-panel-help-button"
|
||||||
|
intent="none"
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
className="makeStyles-topPanelIconOfControlButton-70"
|
||||||
|
icon="help"
|
||||||
|
iconSize={22}
|
||||||
|
/>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</Blueprint3.Tooltip>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="makeStyles-topPanelControlButtonMargin-76"
|
||||||
|
>
|
||||||
|
<Blueprint3.Tooltip
|
||||||
|
content="Settings"
|
||||||
|
hoverCloseDelay={0}
|
||||||
|
hoverOpenDelay={100}
|
||||||
|
position="bottom"
|
||||||
|
transitionDuration={100}
|
||||||
|
>
|
||||||
|
<Blueprint3.Button
|
||||||
|
className="makeStyles-topPanelControlButton-82"
|
||||||
|
id="top-panel-settings-button"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<Blueprint3.Icon
|
||||||
|
className="makeStyles-topPanelIconOfControlButton-91"
|
||||||
|
icon="cog"
|
||||||
|
iconSize={22}
|
||||||
|
/>
|
||||||
|
</Blueprint3.Button>
|
||||||
|
</Blueprint3.Tooltip>
|
||||||
|
</div>
|
||||||
|
</Fade>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<SettingsOverlay
|
||||||
|
handleClose={[Function]}
|
||||||
|
isSettingsOpen={false}
|
||||||
|
/>
|
||||||
|
<ConnectedDevicesListDrawer
|
||||||
|
handleToggle={[Function]}
|
||||||
|
isOpen={false}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
`;
|
@ -1,5 +0,0 @@
|
|||||||
export default {
|
|
||||||
languages: ['ru', 'en'],
|
|
||||||
fallbackLng: 'en',
|
|
||||||
namespace: 'translation',
|
|
||||||
};
|
|
10
app/configs/app.lang.config.ts
Normal file
10
app/configs/app.lang.config.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
fallbackLng: 'en',
|
||||||
|
namespace: 'translation',
|
||||||
|
languages: ['ru', 'en', 'ua'],
|
||||||
|
langISOKeyToLangFullNameMap: {
|
||||||
|
en: 'English',
|
||||||
|
ru: 'Русский',
|
||||||
|
ua: 'Українська',
|
||||||
|
},
|
||||||
|
};
|
@ -1,18 +1,24 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
import { remote, ipcRenderer } from 'electron';
|
import { remote, ipcRenderer } from 'electron';
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
import { initReactI18next } from 'react-i18next';
|
import { initReactI18next } from 'react-i18next';
|
||||||
import SyncBackend from 'i18next-node-fs-backend';
|
import SyncBackend from 'i18next-node-fs-backend';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
// import isDev from 'electron-is-dev';
|
import settings from 'electron-settings';
|
||||||
import config from './app.config';
|
import config from './app.lang.config';
|
||||||
|
import isProduction from '../utils/isProduction';
|
||||||
|
|
||||||
let isDev;
|
export const getLangNameToLangKeyMap = () => {
|
||||||
try {
|
const res = {};
|
||||||
// eslint-disable-next-line global-require
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
isDev = require('electron-is-dev');
|
for (const [key, value] of Object.entries(
|
||||||
} catch (e) {
|
config.langISOKeyToLangFullNameMap
|
||||||
isDev = true;
|
)) {
|
||||||
}
|
// @ts-ignore: fine here
|
||||||
|
res[value] = key;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
const appPath = remote.getGlobal('appPath');
|
const appPath = remote.getGlobal('appPath');
|
||||||
|
|
||||||
@ -22,18 +28,20 @@ const i18nextOptions = {
|
|||||||
},
|
},
|
||||||
backend: {
|
backend: {
|
||||||
// path where resources get loaded from
|
// path where resources get loaded from
|
||||||
loadPath: isDev
|
loadPath: isProduction()
|
||||||
? join(__dirname, './locales/{{lng}}/{{ns}}.json')
|
? join(appPath, 'locales/{{lng}}/{{ns}}.json')
|
||||||
: join(appPath, 'locales/{{lng}}/{{ns}}.json'),
|
: join(__dirname, './locales/{{lng}}/{{ns}}.json'),
|
||||||
// path to post missing resources
|
// path to post missing resources
|
||||||
addPath: isDev
|
addPath: isProduction()
|
||||||
? join(__dirname, './locales/{{lng}}/{{ns}}.missing.json')
|
? join(appPath, 'locales/{{lng}}/{{ns}}.json')
|
||||||
: join(appPath, 'locales/{{lng}}/{{ns}}.json'),
|
: join(__dirname, './locales/{{lng}}/{{ns}}.missing.json'),
|
||||||
// jsonIndent to use when storing json files
|
// jsonIndent to use when storing json files
|
||||||
jsonIndent: 2,
|
jsonIndent: 2,
|
||||||
},
|
},
|
||||||
saveMissing: true,
|
saveMissing: true,
|
||||||
lng: 'en',
|
lng: (settings.hasSync('appLanguage')
|
||||||
|
? settings.getSync('appLanguage')
|
||||||
|
: 'en') as string,
|
||||||
fallbackLng: config.fallbackLng,
|
fallbackLng: config.fallbackLng,
|
||||||
whitelist: config.languages,
|
whitelist: config.languages,
|
||||||
react: {
|
react: {
|
||||||
@ -47,8 +55,8 @@ if (!i18n.isInitialized) {
|
|||||||
i18n.init(i18nextOptions);
|
i18n.init(i18nextOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcRenderer.on('sending-language-from-main', (_, message) => {
|
i18n.on('languageChanged', () => {
|
||||||
i18n.changeLanguage(`${message}`);
|
ipcRenderer.send('client-changed-language', i18n.language);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
@ -1,36 +1,26 @@
|
|||||||
// const i18n = require('i18next');
|
|
||||||
// const i18nextBackend = require('i18next-fs-backend');
|
|
||||||
// const { join } = require('path');
|
|
||||||
// const config = require('./app.config');
|
|
||||||
|
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
import i18nextBackend from 'i18next-node-fs-backend';
|
import i18nextBackend from 'i18next-node-fs-backend';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
// import isDev from 'electron-is-dev';
|
import settings from 'electron-settings';
|
||||||
import config from './app.config';
|
import config from './app.lang.config';
|
||||||
|
import isProduction from '../utils/isProduction';
|
||||||
let isDev;
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line global-require
|
|
||||||
isDev = require('electron-is-dev');
|
|
||||||
} catch (e) {
|
|
||||||
isDev = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const i18nextOptions = {
|
const i18nextOptions = {
|
||||||
fallbackLng: config.fallbackLng,
|
fallbackLng: config.fallbackLng,
|
||||||
lng: 'en',
|
lng: (settings.hasSync('appLanguage')
|
||||||
|
? settings.getSync('appLanguage')
|
||||||
|
: 'en') as string,
|
||||||
ns: 'translation',
|
ns: 'translation',
|
||||||
defaultNS: 'translation',
|
defaultNS: 'translation',
|
||||||
backend: {
|
backend: {
|
||||||
// path where resources get loaded from
|
// path where resources get loaded from
|
||||||
loadPath: isDev
|
loadPath: isProduction()
|
||||||
? join(__dirname, '../locales/{{lng}}/{{ns}}.json')
|
? join(__dirname, 'locales/{{lng}}/{{ns}}.json')
|
||||||
: join(__dirname, 'locales/{{lng}}/{{ns}}.json'),
|
: join(__dirname, '../locales/{{lng}}/{{ns}}.json'),
|
||||||
// path to post missing resources
|
// path to post missing resources
|
||||||
addPath: isDev
|
addPath: isProduction()
|
||||||
? join(__dirname, '../locales/{{lng}}/{{ns}}.missing.json')
|
? join(__dirname, 'locales/{{lng}}/{{ns}}.json')
|
||||||
: join(__dirname, 'locales/{{lng}}/{{ns}}.json'),
|
: join(__dirname, '../locales/{{lng}}/{{ns}}.missing.json'),
|
||||||
// jsonIndent to use when storing json files
|
// jsonIndent to use when storing json files
|
||||||
jsonIndent: 2,
|
jsonIndent: 2,
|
||||||
},
|
},
|
||||||
|
72
app/constants/test-devices.json
Normal file
72
app/constants/test-devices.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "123414",
|
||||||
|
"sessionId": "14422424",
|
||||||
|
"deviceOs": "Android",
|
||||||
|
"deviceType": "Mobile",
|
||||||
|
"deviceIp": "123.123.123.123"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1123",
|
||||||
|
"sessionId": "43",
|
||||||
|
"deviceOs": "IOS",
|
||||||
|
"deviceType": "Mobile",
|
||||||
|
"deviceIp": "124.124.124.124"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"sessionId": "22",
|
||||||
|
"deviceOs": "Windows",
|
||||||
|
"deviceType": "PS",
|
||||||
|
"deviceIp": "255.255.124.124"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "33",
|
||||||
|
"sessionId": "22",
|
||||||
|
"deviceOs": "Ubuntu",
|
||||||
|
"deviceType": "PC",
|
||||||
|
"deviceIp": "4.4.4.124"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "414",
|
||||||
|
"sessionId": "423",
|
||||||
|
"deviceOs": "Blackberry",
|
||||||
|
"deviceType": "Mobile",
|
||||||
|
"deviceIp": "224.224.224.124"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1133223",
|
||||||
|
"sessionId": "4133",
|
||||||
|
"deviceOs": "IOS",
|
||||||
|
"deviceType": "Mobile",
|
||||||
|
"deviceIp": "24.24.24.24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1321123",
|
||||||
|
"sessionId": "44133",
|
||||||
|
"deviceOs": "Android",
|
||||||
|
"deviceType": "Mobile",
|
||||||
|
"deviceIp": "14.14.14.14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "993",
|
||||||
|
"sessionId": "91322",
|
||||||
|
"deviceOs": "Debian",
|
||||||
|
"deviceType": "PC",
|
||||||
|
"deviceIp": "1.1.14.14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7757",
|
||||||
|
"sessionId": "1111",
|
||||||
|
"deviceOs": "MacOS",
|
||||||
|
"deviceType": "Mac",
|
||||||
|
"deviceIp": "12.12.14.14"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "123332",
|
||||||
|
"sessionId": "323231",
|
||||||
|
"deviceOs": "MacOS",
|
||||||
|
"deviceType": "Mac",
|
||||||
|
"deviceIp": "11.11.14.14"
|
||||||
|
}
|
||||||
|
]
|
88
app/constants/test-screen-sharing-objects.json
Normal file
88
app/constants/test-screen-sharing-objects.json
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/breakfast.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/breakfast.jpg",
|
||||||
|
"name": "Breakfast",
|
||||||
|
"author": "jill111",
|
||||||
|
"cols": 2,
|
||||||
|
"featured": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/burgers.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/burgers.jpg",
|
||||||
|
"name": "Tasty burger",
|
||||||
|
"cols": 3,
|
||||||
|
"author": "director90"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/camera.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/camera.jpg",
|
||||||
|
"name": "Camera",
|
||||||
|
"cols": 2,
|
||||||
|
"author": "Danson67"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/morning.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/morning.jpg",
|
||||||
|
"name": "Morning",
|
||||||
|
"author": "fancycrave1",
|
||||||
|
"cols": 1,
|
||||||
|
"featured": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/hats.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/hats.jpg",
|
||||||
|
"name": "Hats",
|
||||||
|
"cols": 4,
|
||||||
|
"author": "Hans"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/honey.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/honey.jpg",
|
||||||
|
"name": "Honey",
|
||||||
|
"cols": 1,
|
||||||
|
"author": "fancycravel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/vegetables.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/vegetables.jpg",
|
||||||
|
"name": "Vegetables",
|
||||||
|
"author": "jill111",
|
||||||
|
"cols": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/plant.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/plant.jpg",
|
||||||
|
"name": "Water plant",
|
||||||
|
"author": "BkrmadtyaKarki",
|
||||||
|
"cols": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/mushroom.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/mushroom.jpg",
|
||||||
|
"name": "Mushrooms",
|
||||||
|
"author": "PublicDomainPictures",
|
||||||
|
"cols": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/olive.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/olive.jpg",
|
||||||
|
"name": "Olive oil",
|
||||||
|
"author": "congerdesign",
|
||||||
|
"cols": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/star.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/star.jpg",
|
||||||
|
"name": "Sea star",
|
||||||
|
"cols": 2,
|
||||||
|
"author": "821292"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "https://material-ui.com/static/images/grid-list/bike.jpg",
|
||||||
|
"id": "https://material-ui.com/static/images/grid-list/bike.jpg",
|
||||||
|
"name": "Bike",
|
||||||
|
"author": "danfador",
|
||||||
|
"cols": 3
|
||||||
|
}
|
||||||
|
]
|
7
app/containers/ConnectedDevicesProvider/Device.d.ts
vendored
Normal file
7
app/containers/ConnectedDevicesProvider/Device.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
interface Device {
|
||||||
|
id: string;
|
||||||
|
sessionId: string;
|
||||||
|
deviceOs: string;
|
||||||
|
deviceType: string;
|
||||||
|
deviceIp: string;
|
||||||
|
}
|
99
app/containers/ConnectedDevicesProvider/index.tsx
Normal file
99
app/containers/ConnectedDevicesProvider/index.tsx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable react/prop-types */
|
||||||
|
import React, { useState, useCallback } from 'react';
|
||||||
|
|
||||||
|
interface ConnectedDevicesContextInterface {
|
||||||
|
devices: Device[];
|
||||||
|
pendingConnectionDevice: Device | null;
|
||||||
|
setPendingConnectionDeviceHook: (device: Device) => void;
|
||||||
|
addPendingConnectedDeviceListener: (
|
||||||
|
callback: (device: Device) => void
|
||||||
|
) => void;
|
||||||
|
setDevicesHook: (devices: Device[]) => void;
|
||||||
|
resetPendingConnectionDeviceHook: () => void;
|
||||||
|
getDevices: () => Device[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this value should be set as soon as electron-ConnectedDevices is loaded, to load user pref
|
||||||
|
const defaultConnectedDevicesContextValue = {
|
||||||
|
devices: [] as Device[],
|
||||||
|
pendingConnectionDevice: null,
|
||||||
|
setPendingConnectionDeviceHook: () => {},
|
||||||
|
addPendingConnectedDeviceListener: () => {},
|
||||||
|
setDevicesHook: () => {},
|
||||||
|
resetPendingConnectionDeviceHook: () => {},
|
||||||
|
getDevices: () => [] as Device[],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ConnectedDevicesContext = React.createContext<
|
||||||
|
ConnectedDevicesContextInterface
|
||||||
|
>(defaultConnectedDevicesContextValue);
|
||||||
|
|
||||||
|
export const ConnectedDevicesProvider: React.FC = ({ children }) => {
|
||||||
|
const [devices, setDevices] = useState([] as Device[]);
|
||||||
|
const [
|
||||||
|
pendingConnectionDevice,
|
||||||
|
setPendingConnectionDevice,
|
||||||
|
] = useState<Device | null>();
|
||||||
|
const [
|
||||||
|
pendingDeviceConnectedListeners,
|
||||||
|
setPendingDeviceConnectedListeners,
|
||||||
|
] = useState([]);
|
||||||
|
|
||||||
|
const emitPendingConnectionDeviceConnected = useCallback(
|
||||||
|
(device: Device) => {
|
||||||
|
pendingDeviceConnectedListeners.forEach(
|
||||||
|
(callback: (device: Device) => void) => {
|
||||||
|
callback(device);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[pendingDeviceConnectedListeners]
|
||||||
|
);
|
||||||
|
|
||||||
|
const setPendingConnectionDeviceHook = (device: Device) => {
|
||||||
|
setPendingConnectionDevice(device);
|
||||||
|
emitPendingConnectionDeviceConnected(device);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setDevicesHook = (_devices: Device[]) => {
|
||||||
|
setDevices(_devices);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetPendingConnectionDeviceHook = () => {
|
||||||
|
setPendingConnectionDevice(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addPendingConnectedDeviceListener = (
|
||||||
|
callback: (device: Device) => void
|
||||||
|
) => {
|
||||||
|
// @ts-ignore: has to be like that for now
|
||||||
|
setPendingDeviceConnectedListeners([
|
||||||
|
...pendingDeviceConnectedListeners,
|
||||||
|
callback,
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDevices = useCallback(() => {
|
||||||
|
return devices;
|
||||||
|
}, [devices]);
|
||||||
|
|
||||||
|
// TODO: load saved devices here? in useEffect
|
||||||
|
|
||||||
|
const value = {
|
||||||
|
devices,
|
||||||
|
pendingConnectionDevice,
|
||||||
|
setDevicesHook,
|
||||||
|
setPendingConnectionDeviceHook,
|
||||||
|
addPendingConnectedDeviceListener,
|
||||||
|
resetPendingConnectionDeviceHook,
|
||||||
|
getDevices,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
// @ts-ignore: it is ok here
|
||||||
|
<ConnectedDevicesContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</ConnectedDevicesContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
@ -1,11 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import NavPanel from '../components/NavPanel';
|
import TopPanel from '../components/TopPanel';
|
||||||
import Counter from '../features/counter/Counter';
|
import Counter from '../features/counter/Counter';
|
||||||
|
|
||||||
export default function CounterPage() {
|
export default function CounterPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NavPanel />
|
<TopPanel />
|
||||||
<Counter />
|
<Counter />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
28
app/containers/HomePage.spec.tsx
Normal file
28
app/containers/HomePage.spec.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React, { Suspense } from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import HomePage from './HomePage';
|
||||||
|
import { SettingsProvider } from './SettingsProvider';
|
||||||
|
import { ConnectedDevicesProvider } from './ConnectedDevicesProvider';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<Suspense fallback={<div>Loading... </div>}>
|
||||||
|
<SettingsProvider>
|
||||||
|
<ConnectedDevicesProvider>
|
||||||
|
<Router>
|
||||||
|
<HomePage />
|
||||||
|
</Router>
|
||||||
|
</ConnectedDevicesProvider>
|
||||||
|
</SettingsProvider>
|
||||||
|
</Suspense>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
@ -1,12 +1,50 @@
|
|||||||
import React from 'react';
|
/* eslint-disable react/destructuring-assignment */
|
||||||
import NavPanel from '../components/NavPanel';
|
/* eslint-disable react/jsx-props-no-spreading */
|
||||||
import Home from '../components/Home';
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import { Classes } from '@blueprintjs/core';
|
||||||
|
import { ToastProvider, DefaultToast } from 'react-toast-notifications';
|
||||||
|
|
||||||
|
import TopPanel from '../components/TopPanel';
|
||||||
|
import { LIGHT_UI_BACKGROUND } from './SettingsProvider';
|
||||||
|
import DeskreenStepper from './Stepper';
|
||||||
|
|
||||||
|
// @ts-ignore: it is ok here, be like js it is fine
|
||||||
|
// eslint-disable-next-line react/prop-types
|
||||||
|
export const CustomToastWithTheme = ({ children, ...props }) => {
|
||||||
|
return (
|
||||||
|
<DefaultToast
|
||||||
|
components={{ Toast: CustomToastWithTheme }}
|
||||||
|
{...props}
|
||||||
|
// @ts-ignore: some minor type complain, it is fine here
|
||||||
|
style={{
|
||||||
|
// eslint-disable-next-line react/prop-types
|
||||||
|
color: props.isdarktheme === 'false' ? '#293742' : '#BFCCD6',
|
||||||
|
backgroundColor:
|
||||||
|
// eslint-disable-next-line react/prop-types
|
||||||
|
props.isdarktheme === 'false' ? LIGHT_UI_BACKGROUND : '#394B59',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<>{children}</>
|
||||||
|
</DefaultToast>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
|
const stepperRef = useRef();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<ToastProvider
|
||||||
<NavPanel />
|
placement="top-center"
|
||||||
<Home />
|
autoDismissTimeout={5000}
|
||||||
</>
|
components={{ Toast: CustomToastWithTheme }}
|
||||||
|
>
|
||||||
|
<div className={Classes.TREE}>
|
||||||
|
<TopPanel stepperRef={stepperRef} />
|
||||||
|
<DeskreenStepper ref={stepperRef} />
|
||||||
|
{/* <Home /> */}
|
||||||
|
</div>
|
||||||
|
</ToastProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { FocusStyleManager } from '@blueprintjs/core';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
import { ConnectedRouter } from 'connected-react-router';
|
import { ConnectedRouter } from 'connected-react-router';
|
||||||
import { hot } from 'react-hot-loader/root';
|
import { hot } from 'react-hot-loader/root';
|
||||||
import { History } from 'history';
|
import { History } from 'history';
|
||||||
import { Store } from '../store';
|
import { Store } from '../store';
|
||||||
import Routes from '../Routes';
|
import Routes from '../Routes';
|
||||||
import i18n from '../configs/i18next.config.client';
|
import i18n from '../configs/i18next.config.client';
|
||||||
|
import { SettingsProvider } from './SettingsProvider';
|
||||||
|
import { ConnectedDevicesProvider } from './ConnectedDevicesProvider';
|
||||||
|
|
||||||
|
FocusStyleManager.onlyShowFocusOnTabs();
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
store: Store;
|
store: Store;
|
||||||
@ -23,9 +29,13 @@ const Root = ({ store, history }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ConnectedRouter history={history}>
|
<SettingsProvider>
|
||||||
<Routes />
|
<ConnectedDevicesProvider>
|
||||||
</ConnectedRouter>
|
<ConnectedRouter history={history}>
|
||||||
|
<Routes />
|
||||||
|
</ConnectedRouter>
|
||||||
|
</ConnectedDevicesProvider>
|
||||||
|
</SettingsProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
61
app/containers/SettingsProvider.tsx
Normal file
61
app/containers/SettingsProvider.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
||||||
|
/* eslint-disable react/prop-types */
|
||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import settings from 'electron-settings';
|
||||||
|
import { Classes } from '@blueprintjs/core';
|
||||||
|
|
||||||
|
export const LIGHT_UI_BACKGROUND = 'rgba(240, 248, 250, 1)';
|
||||||
|
export const DARK_UI_BACKGROUND = '#293742';
|
||||||
|
|
||||||
|
interface SettingsContextInterface {
|
||||||
|
isDarkTheme: boolean;
|
||||||
|
setIsDarkThemeHook: (val: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultSettingsContextValue = {
|
||||||
|
isDarkTheme: false,
|
||||||
|
setIsDarkThemeHook: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SettingsContext = React.createContext<SettingsContextInterface>(
|
||||||
|
defaultSettingsContextValue
|
||||||
|
);
|
||||||
|
|
||||||
|
export const SettingsProvider: React.FC = ({ children }) => {
|
||||||
|
const [isDarkTheme, setIsDarkTheme] = useState(false);
|
||||||
|
|
||||||
|
const loadDarkThemeFromSettings = () => {
|
||||||
|
const gotIsDarkThemeFromSettings = settings.hasSync('appIsDarkTheme')
|
||||||
|
? settings.getSync('appIsDarkTheme') === 'true'
|
||||||
|
: false;
|
||||||
|
|
||||||
|
if (gotIsDarkThemeFromSettings) {
|
||||||
|
document.body.classList.toggle(Classes.DARK);
|
||||||
|
// if ()
|
||||||
|
document.body.style.backgroundColor = LIGHT_UI_BACKGROUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsDarkTheme(gotIsDarkThemeFromSettings);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadDarkThemeFromSettings();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const setIsDarkThemeHook = (val: boolean) => {
|
||||||
|
settings.setSync('appIsDarkTheme', `${val}`);
|
||||||
|
setIsDarkTheme(val);
|
||||||
|
// if (!val) {
|
||||||
|
// document.body.style.backgroundColor = `${LIGHT_UI_BACKGROUND} !important`;
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
const value = { isDarkTheme, setIsDarkThemeHook };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SettingsContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</SettingsContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
23
app/containers/Stepper.spec.tsx
Normal file
23
app/containers/Stepper.spec.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Enzyme, { mount } from 'enzyme';
|
||||||
|
import EnzymeToJson from 'enzyme-to-json';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import { ToastProvider } from 'react-toast-notifications';
|
||||||
|
import DeskreenStepper from './Stepper';
|
||||||
|
|
||||||
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
it('should match exact snapshot', () => {
|
||||||
|
const subject = mount(
|
||||||
|
<>
|
||||||
|
<ToastProvider placement="top-center">
|
||||||
|
<Router>
|
||||||
|
<DeskreenStepper />
|
||||||
|
</Router>
|
||||||
|
</ToastProvider>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
expect(EnzymeToJson(subject)).toMatchSnapshot();
|
||||||
|
});
|
267
app/containers/Stepper.tsx
Normal file
267
app/containers/Stepper.tsx
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
import React, { useState, useCallback, useContext, useEffect } from 'react';
|
||||||
|
import { makeStyles, createStyles } from '@material-ui/core/styles';
|
||||||
|
import Stepper from '@material-ui/core/Stepper';
|
||||||
|
import Step from '@material-ui/core/Step';
|
||||||
|
import StepLabel from '@material-ui/core/StepLabel';
|
||||||
|
import { Row, Col } from 'react-flexbox-grid';
|
||||||
|
import { Text } from '@blueprintjs/core';
|
||||||
|
|
||||||
|
import { useToasts } from 'react-toast-notifications';
|
||||||
|
|
||||||
|
import SuccessStep from '../components/StepsOfStepper/SuccessStep';
|
||||||
|
import IntermediateStep from '../components/StepsOfStepper/IntermediateStep';
|
||||||
|
import { ConnectedDevicesContext } from './ConnectedDevicesProvider';
|
||||||
|
import AllowConnectionForDeviceAlert from '../components/AllowConnectionForDeviceAlert';
|
||||||
|
import DeviceConnectedInfoButton from '../components/StepperPanel/DeviceConnectedInfoButton';
|
||||||
|
import ColorlibStepIcon, {
|
||||||
|
StepIconPropsDeskreen,
|
||||||
|
} from '../components/StepperPanel/ColorlibStepIcon';
|
||||||
|
import ColorlibConnector from '../components/StepperPanel/ColorlibConnector';
|
||||||
|
import { SettingsContext } from './SettingsProvider';
|
||||||
|
import isProduction from '../utils/isProduction';
|
||||||
|
|
||||||
|
const Fade = require('react-reveal/Fade');
|
||||||
|
const Zoom = require('react-reveal/Zoom');
|
||||||
|
const Pulse = require('react-reveal/Pulse');
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() =>
|
||||||
|
createStyles({
|
||||||
|
stepContent: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
stepLabelContent: {
|
||||||
|
marginTop: '10px !important',
|
||||||
|
height: '110px',
|
||||||
|
},
|
||||||
|
stepperComponent: {
|
||||||
|
paddingBottom: '0px',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
function getSteps() {
|
||||||
|
return ['Connect', 'Select', 'Confirm'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
|
const DeskreenStepper = React.forwardRef((_props, ref) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
const [isInterShow, setIsInterShow] = useState(false);
|
||||||
|
|
||||||
|
const { isDarkTheme } = useContext(SettingsContext);
|
||||||
|
|
||||||
|
const { addToast } = useToasts();
|
||||||
|
|
||||||
|
const [isAlertOpen, setIsAlertOpen] = useState(false);
|
||||||
|
const [isUserAllowedConnection, setIsUserAllowedConnection] = useState(false);
|
||||||
|
|
||||||
|
const { addPendingConnectedDeviceListener } = useContext(
|
||||||
|
ConnectedDevicesContext
|
||||||
|
);
|
||||||
|
|
||||||
|
const [
|
||||||
|
pendingConnectionDevice,
|
||||||
|
setPendingConnectionDevice,
|
||||||
|
] = useState<Device | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
addPendingConnectedDeviceListener((device: Device) => {
|
||||||
|
setPendingConnectionDevice(device);
|
||||||
|
setIsAlertOpen(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
setIsInterShow(true);
|
||||||
|
},
|
||||||
|
isProduction() ? 500 : 0
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [activeStep, setActiveStep] = useState(0);
|
||||||
|
const [isEntireScreenSelected, setIsEntireScreenSelected] = useState(false);
|
||||||
|
const [
|
||||||
|
isApplicationWindowSelected,
|
||||||
|
setIsApplicationWindowSelected,
|
||||||
|
] = useState(false);
|
||||||
|
const steps = getSteps();
|
||||||
|
|
||||||
|
const makeSmoothIntermediateStepTransition = () => {
|
||||||
|
if (!isProduction()) return;
|
||||||
|
setIsInterShow(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsInterShow(true);
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = useCallback(() => {
|
||||||
|
makeSmoothIntermediateStepTransition();
|
||||||
|
if (activeStep === steps.length - 1) {
|
||||||
|
setIsEntireScreenSelected(false);
|
||||||
|
setIsApplicationWindowSelected(false);
|
||||||
|
}
|
||||||
|
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||||
|
}, [activeStep, steps]);
|
||||||
|
|
||||||
|
const handleNextEntireScreen = useCallback(() => {
|
||||||
|
makeSmoothIntermediateStepTransition();
|
||||||
|
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||||
|
setIsEntireScreenSelected(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleNextApplicationWindow = useCallback(() => {
|
||||||
|
makeSmoothIntermediateStepTransition();
|
||||||
|
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||||
|
setIsApplicationWindowSelected(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleBack = useCallback(() => {
|
||||||
|
makeSmoothIntermediateStepTransition();
|
||||||
|
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleReset = useCallback(() => {
|
||||||
|
makeSmoothIntermediateStepTransition();
|
||||||
|
setActiveStep(0);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
React.useImperativeHandle(ref, () => ({
|
||||||
|
handleReset() {
|
||||||
|
handleReset();
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const handleCancelAlert = () => {
|
||||||
|
setIsAlertOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConfirmAlert = useCallback(() => {
|
||||||
|
setIsAlertOpen(false);
|
||||||
|
setIsUserAllowedConnection(true);
|
||||||
|
handleNext();
|
||||||
|
}, [handleNext]);
|
||||||
|
|
||||||
|
const handleUserClickedDeviceDisconnectButton = useCallback(() => {
|
||||||
|
handleReset();
|
||||||
|
setPendingConnectionDevice(null);
|
||||||
|
setIsUserAllowedConnection(false);
|
||||||
|
|
||||||
|
addToast(
|
||||||
|
<Text>
|
||||||
|
Device is successfully disconnected by you. You can connect new device
|
||||||
|
</Text>,
|
||||||
|
{
|
||||||
|
appearance: 'info',
|
||||||
|
autoDismiss: true,
|
||||||
|
// @ts-ignore: works fine here, ignore
|
||||||
|
isdarktheme: `${isDarkTheme}`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [addToast, handleReset, isDarkTheme]);
|
||||||
|
|
||||||
|
const renderIntermediateOrSuccessStepContent = useCallback(() => {
|
||||||
|
return activeStep === steps.length ? (
|
||||||
|
<Zoom duration={300} when={isInterShow}>
|
||||||
|
<Row middle="xs" center="xs">
|
||||||
|
<SuccessStep handleReset={handleReset} />
|
||||||
|
</Row>
|
||||||
|
</Zoom>
|
||||||
|
) : (
|
||||||
|
<Fade duration={isProduction() ? 300 : 0} when={isInterShow}>
|
||||||
|
<IntermediateStep
|
||||||
|
activeStep={activeStep}
|
||||||
|
steps={steps}
|
||||||
|
handleNext={handleNext}
|
||||||
|
handleBack={handleBack}
|
||||||
|
handleNextEntireScreen={handleNextEntireScreen}
|
||||||
|
handleNextApplicationWindow={handleNextApplicationWindow}
|
||||||
|
resetPendingConnectionDevice={() => setPendingConnectionDevice(null)}
|
||||||
|
resetUserAllowedConnection={() => setIsUserAllowedConnection(false)}
|
||||||
|
/>
|
||||||
|
</Fade>
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
activeStep,
|
||||||
|
steps,
|
||||||
|
isInterShow,
|
||||||
|
handleReset,
|
||||||
|
handleNext,
|
||||||
|
handleBack,
|
||||||
|
handleNextEntireScreen,
|
||||||
|
handleNextApplicationWindow,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const renderStepLabelContent = useCallback(
|
||||||
|
(label, idx) => {
|
||||||
|
return (
|
||||||
|
<StepLabel
|
||||||
|
id="step-label-deskreen"
|
||||||
|
className={classes.stepLabelContent}
|
||||||
|
StepIconComponent={ColorlibStepIcon}
|
||||||
|
StepIconProps={
|
||||||
|
{
|
||||||
|
isEntireScreenSelected,
|
||||||
|
isApplicationWindowSelected,
|
||||||
|
} as StepIconPropsDeskreen
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{pendingConnectionDevice && idx === 0 && isUserAllowedConnection ? (
|
||||||
|
<DeviceConnectedInfoButton
|
||||||
|
device={pendingConnectionDevice}
|
||||||
|
onDisconnect={handleUserClickedDeviceDisconnectButton}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text className="bp3-text-muted">{label}</Text>
|
||||||
|
)}
|
||||||
|
</StepLabel>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[
|
||||||
|
classes.stepLabelContent,
|
||||||
|
handleUserClickedDeviceDisconnectButton,
|
||||||
|
isApplicationWindowSelected,
|
||||||
|
isEntireScreenSelected,
|
||||||
|
isUserAllowedConnection,
|
||||||
|
pendingConnectionDevice,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Row>
|
||||||
|
<Col xs={12}>
|
||||||
|
<Pulse top duration={isProduction() ? 1500 : 0}>
|
||||||
|
<Stepper
|
||||||
|
className={classes.stepperComponent}
|
||||||
|
activeStep={activeStep}
|
||||||
|
alternativeLabel
|
||||||
|
style={{ background: 'transparent' }}
|
||||||
|
connector={<ColorlibConnector />}
|
||||||
|
>
|
||||||
|
{steps.map((label, idx) => (
|
||||||
|
<Step key={label}>{renderStepLabelContent(label, idx)}</Step>
|
||||||
|
))}
|
||||||
|
</Stepper>
|
||||||
|
</Pulse>
|
||||||
|
</Col>
|
||||||
|
<Col className={classes.stepContent} xs={12}>
|
||||||
|
{renderIntermediateOrSuccessStepContent()}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<AllowConnectionForDeviceAlert
|
||||||
|
device={pendingConnectionDevice}
|
||||||
|
isOpen={isAlertOpen}
|
||||||
|
onCancel={handleCancelAlert}
|
||||||
|
onConfirm={handleConfirmAlert}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DeskreenStepper;
|
30
app/containers/__mocks__/electron-settings.ts
Normal file
30
app/containers/__mocks__/electron-settings.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
|
||||||
|
// export const hasSync = (name: string) => {
|
||||||
|
// if (name === 'appLanguage') {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export const getSync = (name: string) => {
|
||||||
|
// if (name === 'appLanguage') {
|
||||||
|
// return 'en';
|
||||||
|
// }
|
||||||
|
// return 'en';
|
||||||
|
// };
|
||||||
|
|
||||||
|
export default {
|
||||||
|
hasSync: (name: string) => {
|
||||||
|
if (name === 'appLanguage') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
getSync: (name: string) => {
|
||||||
|
if (name === 'appLanguage') {
|
||||||
|
return 'en';
|
||||||
|
}
|
||||||
|
return 'en';
|
||||||
|
},
|
||||||
|
};
|
10
app/containers/__mocks__/electron.ts
Normal file
10
app/containers/__mocks__/electron.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
|
||||||
|
export const remote = {
|
||||||
|
getGlobal: (name: string) => {
|
||||||
|
if (name === 'appPath') {
|
||||||
|
return __dirname;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
};
|
19
app/containers/__mocks__/react-i18next.ts
Normal file
19
app/containers/__mocks__/react-i18next.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
|
|
||||||
|
import { ThirdPartyModule } from 'i18next';
|
||||||
|
|
||||||
|
export const useTranslation = () => {
|
||||||
|
return {
|
||||||
|
t: (key: string) => {
|
||||||
|
if (key === 'Language') {
|
||||||
|
return 'Language';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initReactI18next: ThirdPartyModule = {
|
||||||
|
type: '3rdParty',
|
||||||
|
init: () => {},
|
||||||
|
};
|
2276
app/containers/__snapshots__/HomePage.spec.tsx.snap
Normal file
2276
app/containers/__snapshots__/HomePage.spec.tsx.snap
Normal file
File diff suppressed because it is too large
Load Diff
1556
app/containers/__snapshots__/Stepper.spec.tsx.snap
Normal file
1556
app/containers/__snapshots__/Stepper.spec.tsx.snap
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable no-new */
|
||||||
import React, { Fragment, Suspense } from 'react';
|
import React, { Fragment, Suspense } from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import { AppContainer as ReactHotAppContainer } from 'react-hot-loader';
|
import { AppContainer as ReactHotAppContainer } from 'react-hot-loader';
|
||||||
@ -10,6 +12,19 @@ const store = configuredStore();
|
|||||||
const AppContainer = process.env.PLAIN_HMR ? Fragment : ReactHotAppContainer;
|
const AppContainer = process.env.PLAIN_HMR ? Fragment : ReactHotAppContainer;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
const windowTopBar = document.createElement('div');
|
||||||
|
windowTopBar.style.width = '100%';
|
||||||
|
windowTopBar.style.height = '50px';
|
||||||
|
windowTopBar.style.position = 'absolute';
|
||||||
|
windowTopBar.style.top = '0';
|
||||||
|
windowTopBar.style.left = '0';
|
||||||
|
// @ts-ignore: all good here
|
||||||
|
windowTopBar.style.webkitAppRegion = 'drag';
|
||||||
|
windowTopBar.style.pointerEvents = 'none';
|
||||||
|
document.body.appendChild(windowTopBar);
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line global-require
|
// eslint-disable-next-line global-require
|
||||||
const Root = require('./containers/Root').default;
|
const Root = require('./containers/Root').default;
|
||||||
render(
|
render(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Language": "🌐 Language",
|
"Language": "Language 🇬🇧 / 🇺🇸",
|
||||||
"Signaling server is running on port": "Signaling server is running on port ⚓",
|
"Signaling server is running on port": "Signaling server is running on port ⚓",
|
||||||
"ru": "Русский",
|
"ru": "Русский",
|
||||||
"en": "English"
|
"en": "English",
|
||||||
|
"ua": "Українська"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Language": "🌐 Язык",
|
"Language": "Язык 🇷🇺",
|
||||||
"Signaling server is running on port": "Сигнальный сервер работает на порте ⚓",
|
"Signaling server is running on port": "Сигнальный сервер работает на порте ⚓",
|
||||||
"ru": "Русский",
|
"ru": "Русский",
|
||||||
"en": "English"
|
"en": "English",
|
||||||
|
"ua": "Українська"
|
||||||
}
|
}
|
||||||
|
7
app/locales/ua/translation.json
Normal file
7
app/locales/ua/translation.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"Language": "Мова 🇺🇦",
|
||||||
|
"Signaling server is running on port": "Сигнальный сервер працює на порту ⚓",
|
||||||
|
"ru": "Русский",
|
||||||
|
"en": "English",
|
||||||
|
"ua": "Українська"
|
||||||
|
}
|
0
app/locales/ua/translation.missing.json
Normal file
0
app/locales/ua/translation.missing.json
Normal file
@ -15,7 +15,7 @@ import path from 'path';
|
|||||||
import { app, BrowserWindow, ipcMain } from 'electron';
|
import { app, BrowserWindow, ipcMain } from 'electron';
|
||||||
import { autoUpdater } from 'electron-updater';
|
import { autoUpdater } from 'electron-updater';
|
||||||
import log from 'electron-log';
|
import log from 'electron-log';
|
||||||
import config from './configs/app.config';
|
import settings from 'electron-settings';
|
||||||
import i18n from './configs/i18next.config';
|
import i18n from './configs/i18next.config';
|
||||||
import signalingServer from './server';
|
import signalingServer from './server';
|
||||||
import MenuBuilder from './menu';
|
import MenuBuilder from './menu';
|
||||||
@ -25,6 +25,8 @@ globalAny.appPath = __dirname;
|
|||||||
|
|
||||||
signalingServer.start();
|
signalingServer.start();
|
||||||
|
|
||||||
|
log.error(process.platform);
|
||||||
|
|
||||||
export default class AppUpdater {
|
export default class AppUpdater {
|
||||||
constructor() {
|
constructor() {
|
||||||
log.transports.file.level = 'info';
|
log.transports.file.level = 'info';
|
||||||
@ -68,8 +70,13 @@ const createWindow = async () => {
|
|||||||
|
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
show: false,
|
show: false,
|
||||||
width: 1024,
|
width: 820,
|
||||||
height: 728,
|
height: 480,
|
||||||
|
// maxWidth: 820,
|
||||||
|
// maxHeight: 480,
|
||||||
|
minHeight: 400,
|
||||||
|
minWidth: 600,
|
||||||
|
titleBarStyle: 'hiddenInset',
|
||||||
webPreferences:
|
webPreferences:
|
||||||
(process.env.NODE_ENV === 'development' ||
|
(process.env.NODE_ENV === 'development' ||
|
||||||
process.env.E2E_BUILD === 'true') &&
|
process.env.E2E_BUILD === 'true') &&
|
||||||
@ -115,8 +122,12 @@ const createWindow = async () => {
|
|||||||
if (mainWindow === null) return;
|
if (mainWindow === null) return;
|
||||||
menuBuilder = new MenuBuilder(mainWindow, i18n);
|
menuBuilder = new MenuBuilder(mainWindow, i18n);
|
||||||
menuBuilder.buildMenu();
|
menuBuilder.buildMenu();
|
||||||
mainWindow.webContents.send('sending-language-from-main', lng);
|
setTimeout(async () => {
|
||||||
console.log(`Language changed! ${lng}`);
|
if (lng !== 'en' && i18n.language !== lng) {
|
||||||
|
i18n.changeLanguage(lng);
|
||||||
|
await settings.set('appLanguage', lng);
|
||||||
|
}
|
||||||
|
}, 400);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove this if your app does not use auto updates
|
// Remove this if your app does not use auto updates
|
||||||
@ -154,15 +165,7 @@ ipcMain.handle('get-signaling-server-port', () => {
|
|||||||
mainWindow.webContents.send('sending-port-from-main', signalingServer.port);
|
mainWindow.webContents.send('sending-port-from-main', signalingServer.port);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ipcMain.on('get-initial-translations', (event, arg) => {
|
ipcMain.on('client-changed-language', async (_, newLangCode) => {
|
||||||
ipcMain.on('get-initial-translations', (event) => {
|
i18n.changeLanguage(newLangCode);
|
||||||
// i18n.loadLanguages('en', (err, t) => {
|
await settings.set('appLanguage', newLangCode);
|
||||||
i18n.loadLanguages('en', () => {
|
|
||||||
const initial = {
|
|
||||||
en: {
|
|
||||||
translation: i18n.getResourceBundle('en', config.namespace),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
event.returnValue = initial;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -305,3 +305,15 @@
|
|||||||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||||||
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @preserve
|
||||||
|
* JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013)
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jensyt@gmail.com">Jens Taylor</a>
|
||||||
|
* @see http://github.com/homebrewing/brauhaus-diff
|
||||||
|
* @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
|
||||||
|
* @see http://github.com/garycourt/murmurhash-js
|
||||||
|
* @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
|
||||||
|
* @see http://sites.google.com/site/murmurhash/
|
||||||
|
*/
|
||||||
|
23
app/menu.ts
23
app/menu.ts
@ -7,7 +7,7 @@ import {
|
|||||||
MenuItemConstructorOptions,
|
MenuItemConstructorOptions,
|
||||||
} from 'electron';
|
} from 'electron';
|
||||||
|
|
||||||
import config from './configs/app.config';
|
import config from './configs/app.lang.config';
|
||||||
|
|
||||||
import signalingServer from './server';
|
import signalingServer from './server';
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ export default class MenuBuilder {
|
|||||||
this.i18n = i18n;
|
this.i18n = i18n;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildMenu(): Menu {
|
buildMenu() {
|
||||||
if (
|
if (
|
||||||
process.env.NODE_ENV === 'development' ||
|
process.env.NODE_ENV === 'development' ||
|
||||||
process.env.DEBUG_PROD === 'true'
|
process.env.DEBUG_PROD === 'true'
|
||||||
@ -34,15 +34,16 @@ export default class MenuBuilder {
|
|||||||
this.setupDevelopmentEnvironment();
|
this.setupDevelopmentEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
const template =
|
if (process.platform === 'darwin') {
|
||||||
process.platform === 'darwin'
|
const menu = Menu.buildFromTemplate(this.buildDarwinTemplate());
|
||||||
? this.buildDarwinTemplate()
|
Menu.setApplicationMenu(menu);
|
||||||
: this.buildDefaultTemplate();
|
} else if (process.env.NODE_ENV === 'development') {
|
||||||
|
const menu = Menu.buildFromTemplate(this.buildDefaultTemplate());
|
||||||
const menu = Menu.buildFromTemplate(template);
|
Menu.setApplicationMenu(menu);
|
||||||
Menu.setApplicationMenu(menu);
|
} else {
|
||||||
|
// for production, no menu for non MacOS app
|
||||||
return menu;
|
Menu.setApplicationMenu(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupDevelopmentEnvironment(): void {
|
setupDevelopmentEnvironment(): void {
|
||||||
|
2
app/package-lock.json
generated
2
app/package-lock.json
generated
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "deskreen",
|
"name": "deskreen",
|
||||||
"version": "0.0.2-alpha",
|
"version": "0.0.3-alpha",
|
||||||
"lockfileVersion": 1
|
"lockfileVersion": 1
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "deskreen",
|
"name": "deskreen",
|
||||||
"productName": "deskreen",
|
"productName": "deskreen",
|
||||||
"version": "0.0.2-alpha",
|
"version": "0.0.3-alpha",
|
||||||
"description": "TODO: write description about this project",
|
"description": "TODO: write description about this project",
|
||||||
"main": "./main.prod.js",
|
"main": "./main.prod.js",
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -20,17 +20,10 @@ import pollForInactiveRooms from './inactiveRooms';
|
|||||||
import getStore from './store';
|
import getStore from './store';
|
||||||
|
|
||||||
import Logger from '../utils/logger';
|
import Logger from '../utils/logger';
|
||||||
|
import isProduction from '../utils/isProduction';
|
||||||
|
|
||||||
const log = new Logger('app/server/index.ts');
|
const log = new Logger('app/server/index.ts');
|
||||||
|
|
||||||
let isDev;
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line global-require
|
|
||||||
isDev = require('electron-is-dev');
|
|
||||||
} catch (e) {
|
|
||||||
isDev = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = new Koa();
|
const app = new Koa();
|
||||||
|
|
||||||
const router = new Router();
|
const router = new Router();
|
||||||
@ -54,9 +47,9 @@ function setStaticFileHeaders(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const clientDistDirectory = isDev
|
const clientDistDirectory = isProduction()
|
||||||
? `${__dirname}/../client/build`
|
? `${__dirname}/client/build`
|
||||||
: `${__dirname}/client/build`;
|
: `${__dirname}/../client/build`;
|
||||||
|
|
||||||
if (clientDistDirectory) {
|
if (clientDistDirectory) {
|
||||||
app.use(async (ctx, next) => {
|
app.use(async (ctx, next) => {
|
||||||
|
8
app/utils/isProduction.ts
Normal file
8
app/utils/isProduction.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export default function isProduction() {
|
||||||
|
return (
|
||||||
|
process.env.NODE_ENV === 'production' &&
|
||||||
|
process.env.RUN_MODE !== 'dev' &&
|
||||||
|
process.env.RUN_MODE !== 'test'
|
||||||
|
);
|
||||||
|
// return true; // for animations and other things debugging as in production mode
|
||||||
|
}
|
36
package.json
36
package.json
@ -1,16 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "deskreen",
|
"name": "deskreen",
|
||||||
"productName": "Deskreen",
|
"productName": "Deskreen",
|
||||||
"version": "0.0.2-alpha",
|
"version": "0.0.3-alpha",
|
||||||
"description": "TODO: write description of this app",
|
"description": "TODO: write description of this app",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "concurrently \"yarn build-main\" \"yarn build-renderer\" \"yarn build-client\"",
|
"build": "concurrently \"yarn build-main\" \"yarn build-renderer\" \"yarn build-client\"",
|
||||||
|
"build-test": "concurrently \"yarn build-main-test\" \"yarn build-renderer-test\" \"yarn build-client\"",
|
||||||
"build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors",
|
"build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors",
|
||||||
"build-e2e": "cross-env E2E_BUILD=true yarn build",
|
"build-e2e": "cross-env E2E_BUILD=true yarn build",
|
||||||
|
"build-ux": "cross-env E2E_BUILD=true RUN_MODE=test yarn build-test",
|
||||||
"build-main": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.main.prod.babel.js --colors",
|
"build-main": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.main.prod.babel.js --colors",
|
||||||
|
"build-main-test": "cross-env RUN_MODE=test NODE_ENV=production webpack --config ./configs/webpack.config.main.prod.babel.js --colors",
|
||||||
"build-renderer": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.renderer.prod.babel.js --colors",
|
"build-renderer": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.renderer.prod.babel.js --colors",
|
||||||
|
"build-renderer-test": "cross-env RUN_MODE=test NODE_ENV=production webpack --config ./configs/webpack.config.renderer.prod.babel.js --colors",
|
||||||
"build-client": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn build",
|
"build-client": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn build",
|
||||||
"dev": "cross-env START_HOT=1 node -r @babel/register ./internals/scripts/CheckPortInUse.js && concurrently \"cross-env START_HOT=1 yarn start-renderer-dev\" \"yarn start-client-dev\"",
|
"dev": "cross-env START_HOT=1 node -r @babel/register ./internals/scripts/CheckPortInUse.js && concurrently \"cross-env START_HOT=1 RUN_MODE=dev yarn start-renderer-dev\" \"yarn start-client-dev\"",
|
||||||
"coverage": "cross-env BABEL_DISABLE_CACHE=1 jest --coverage && yarn coverage-client",
|
"coverage": "cross-env BABEL_DISABLE_CACHE=1 jest --coverage && yarn coverage-client",
|
||||||
"coverage-client": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true cross-env BABEL_DISABLE_CACHE=1 yarn test -- --coverage --watchAll=false",
|
"coverage-client": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true cross-env BABEL_DISABLE_CACHE=1 yarn test -- --coverage --watchAll=false",
|
||||||
"electron-rebuild": "electron-rebuild --parallel --force --types prod,dev,optional --module-dir app",
|
"electron-rebuild": "electron-rebuild --parallel --force --types prod,dev,optional --module-dir app",
|
||||||
@ -36,12 +40,15 @@
|
|||||||
"start-main-dev": "cross-env START_HOT=1 NODE_ENV=development electron -r ./internals/scripts/BabelRegister ./app/main.dev.ts",
|
"start-main-dev": "cross-env START_HOT=1 NODE_ENV=development electron -r ./internals/scripts/BabelRegister ./app/main.dev.ts",
|
||||||
"start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js",
|
"start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js",
|
||||||
"start-client-dev": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn start",
|
"start-client-dev": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn start",
|
||||||
"test": "cross-env BABEL_DISABLE_CACHE=1 jest && yarn test-client",
|
"test": "cross-env BABEL_DISABLE_CACHE=1 jest --silent && yarn test-client",
|
||||||
"test-client": "cd app/client && cross-env BABEL_DISABLE_CACHE=1 SKIP_PREFLIGHT_CHECK=true yarn test:nowatch",
|
"test-client": "cd app/client && cross-env BABEL_DISABLE_CACHE=1 SKIP_PREFLIGHT_CHECK=true yarn test:nowatch",
|
||||||
"test-all": "yarn lint && yarn tsc && yarn build && yarn test",
|
"test-all": "yarn lint && yarn tsc && yarn build && yarn test",
|
||||||
"test-e2e": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe electron:./app ./test/e2e/HomePage.e2e.ts",
|
"test-e2e": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe electron:./app ./test/e2e/HomePage.e2e.ts",
|
||||||
"test-e2e-live": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe --live electron:./app ./test/e2e/HomePage.e2e.ts",
|
"test-e2e-live": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe --live electron:./app ./test/e2e/HomePage.e2e.ts",
|
||||||
"test-watch": "yarn test --watch",
|
"test-ux": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test RUN_MODE=test testcafe electron:./app ./test/ux/Stepper.ux.ts",
|
||||||
|
"test-ux-live": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test RUN_MODE=test testcafe --live electron:./app ./test/ux/Stepper.ux.ts",
|
||||||
|
"test-watch": "yarn jest --watch --silent",
|
||||||
|
"test-watch-no-silent": "yarn jest --watch",
|
||||||
"sonar": "concurrently \"sonar-scanner\" \"cd app/client && sonar-scanner\" "
|
"sonar": "concurrently \"sonar-scanner\" \"cd app/client && sonar-scanner\" "
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
@ -184,7 +191,6 @@
|
|||||||
"testResultsProcessor": "jest-sonar-reporter"
|
"testResultsProcessor": "jest-sonar-reporter"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@amilajack/testcafe-browser-provider-electron": "^0.0.15-alpha.1",
|
|
||||||
"@babel/core": "^7.11.1",
|
"@babel/core": "^7.11.1",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||||
"@babel/plugin-proposal-decorators": "^7.10.5",
|
"@babel/plugin-proposal-decorators": "^7.10.5",
|
||||||
@ -209,6 +215,7 @@
|
|||||||
"@babel/preset-react": "^7.10.4",
|
"@babel/preset-react": "^7.10.4",
|
||||||
"@babel/preset-typescript": "^7.10.4",
|
"@babel/preset-typescript": "^7.10.4",
|
||||||
"@babel/register": "^7.10.5",
|
"@babel/register": "^7.10.5",
|
||||||
|
"@types/classnames": "^2.2.10",
|
||||||
"@types/enzyme": "^3.10.5",
|
"@types/enzyme": "^3.10.5",
|
||||||
"@types/enzyme-adapter-react-16": "^1.0.6",
|
"@types/enzyme-adapter-react-16": "^1.0.6",
|
||||||
"@types/express": "^4.17.7",
|
"@types/express": "^4.17.7",
|
||||||
@ -222,12 +229,15 @@
|
|||||||
"@types/koa-static": "^4.0.1",
|
"@types/koa-static": "^4.0.1",
|
||||||
"@types/node": "12",
|
"@types/node": "12",
|
||||||
"@types/node-forge": "^0.9.5",
|
"@types/node-forge": "^0.9.5",
|
||||||
|
"@types/qrcode.react": "^1.0.1",
|
||||||
"@types/react": "^16.9.44",
|
"@types/react": "^16.9.44",
|
||||||
"@types/react-dom": "^16.9.8",
|
"@types/react-dom": "^16.9.8",
|
||||||
"@types/react-redux": "^7.1.9",
|
"@types/react-redux": "^7.1.9",
|
||||||
"@types/react-router": "^5.1.8",
|
"@types/react-router": "^5.1.8",
|
||||||
"@types/react-router-dom": "^5.1.5",
|
"@types/react-router-dom": "^5.1.5",
|
||||||
"@types/react-test-renderer": "^16.9.2",
|
"@types/react-test-renderer": "^16.9.2",
|
||||||
|
"@types/react-toast-notifications": "^2.4.0",
|
||||||
|
"@types/react-toastify": "^4.1.0",
|
||||||
"@types/redux-logger": "^3.0.8",
|
"@types/redux-logger": "^3.0.8",
|
||||||
"@types/shortid": "^0.0.29",
|
"@types/shortid": "^0.0.29",
|
||||||
"@types/socket.io": "^2.1.11",
|
"@types/socket.io": "^2.1.11",
|
||||||
@ -289,7 +299,7 @@
|
|||||||
"stylelint-config-prettier": "^8.0.2",
|
"stylelint-config-prettier": "^8.0.2",
|
||||||
"stylelint-config-standard": "^20.0.0",
|
"stylelint-config-standard": "^20.0.0",
|
||||||
"terser-webpack-plugin": "^3.0.7",
|
"terser-webpack-plugin": "^3.0.7",
|
||||||
"testcafe": "^1.8.8",
|
"testcafe": "^1.9.2",
|
||||||
"testcafe-browser-provider-electron": "^0.0.15",
|
"testcafe-browser-provider-electron": "^0.0.15",
|
||||||
"testcafe-react-selectors": "^4.0.0",
|
"testcafe-react-selectors": "^4.0.0",
|
||||||
"ts-jest": "^26.1.4",
|
"ts-jest": "^26.1.4",
|
||||||
@ -304,35 +314,47 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blueprintjs/core": "^3.31.0",
|
"@blueprintjs/core": "^3.31.0",
|
||||||
|
"@blueprintjs/select": "^3.13.7",
|
||||||
"@fortawesome/fontawesome-free": "^5.14.0",
|
"@fortawesome/fontawesome-free": "^5.14.0",
|
||||||
"@hot-loader/react-dom": "^16.13.0",
|
"@hot-loader/react-dom": "^16.13.0",
|
||||||
|
"@material-ui/core": "^4.11.0",
|
||||||
"@reduxjs/toolkit": "^1.4.0",
|
"@reduxjs/toolkit": "^1.4.0",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
|
"clsx": "^1.1.1",
|
||||||
"connected-react-router": "^6.6.1",
|
"connected-react-router": "^6.6.1",
|
||||||
"electron-debug": "^3.1.0",
|
"electron-debug": "^3.1.0",
|
||||||
"electron-is-dev": "^1.2.0",
|
|
||||||
"electron-log": "^4.2.2",
|
"electron-log": "^4.2.2",
|
||||||
|
"electron-settings": "^4.0.2",
|
||||||
"electron-updater": "^4.3.1",
|
"electron-updater": "^4.3.1",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"fontsource-lexend-peta": "^3.0.9",
|
||||||
"get-port": "^5.1.1",
|
"get-port": "^5.1.1",
|
||||||
"history": "^4.7.2",
|
"history": "^4.7.2",
|
||||||
"i18next": "^19.6.3",
|
"i18next": "^19.6.3",
|
||||||
"i18next-fs-backend": "^1.0.7",
|
"i18next-fs-backend": "^1.0.7",
|
||||||
"i18next-node-fs-backend": "^2.1.3",
|
"i18next-node-fs-backend": "^2.1.3",
|
||||||
"i18next-sync-fs-backend": "^1.1.1",
|
"i18next-sync-fs-backend": "^1.1.1",
|
||||||
|
"internal-ip": "^6.1.0",
|
||||||
"kcors": "^2.2.2",
|
"kcors": "^2.2.2",
|
||||||
"koa": "^2.13.0",
|
"koa": "^2.13.0",
|
||||||
"koa-router": "^9.4.0",
|
"koa-router": "^9.4.0",
|
||||||
"koa-send": "^5.0.1",
|
"koa-send": "^5.0.1",
|
||||||
"koa-static": "^5.0.0",
|
"koa-static": "^5.0.0",
|
||||||
"node-forge": "^0.9.1",
|
"node-forge": "^0.9.1",
|
||||||
|
"qrcode.react": "^1.0.0",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
|
"react-awesome-reveal": "^3.2.1",
|
||||||
"react-dom": "^16.12.0",
|
"react-dom": "^16.12.0",
|
||||||
"react-flexbox-grid": "^2.1.2",
|
"react-flexbox-grid": "^2.1.2",
|
||||||
"react-hot-loader": "^4.12.21",
|
"react-hot-loader": "^4.12.21",
|
||||||
"react-i18next": "^11.7.0",
|
"react-i18next": "^11.7.0",
|
||||||
|
"react-qrcode-logo": "^2.2.1",
|
||||||
"react-redux": "^7.2.0",
|
"react-redux": "^7.2.0",
|
||||||
|
"react-reveal": "^1.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
|
"react-toast-notifications": "^2.4.0",
|
||||||
|
"react-toastify": "^6.0.8",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"regenerator-runtime": "^0.13.5",
|
"regenerator-runtime": "^0.13.5",
|
||||||
|
@ -20,11 +20,11 @@ const assertNoConsoleErrors = async (t) => {
|
|||||||
fixture`Home Page`.page('../../app/app.html').afterEach(assertNoConsoleErrors);
|
fixture`Home Page`.page('../../app/app.html').afterEach(assertNoConsoleErrors);
|
||||||
|
|
||||||
test('e2e', async (t) => {
|
test('e2e', async (t) => {
|
||||||
await t.expect(getPageTitle()).eql('Hello Deskreen!');
|
await t.expect(getPageTitle()).eql('Deskreen');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should open window and contain expected page title', async (t) => {
|
test('should open window and contain expected page title', async (t) => {
|
||||||
await t.expect(getPageTitle()).eql('Hello Deskreen!');
|
await t.expect(getPageTitle()).eql('Deskreen');
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
|
488
test/ux/Stepper.ux.ts
Normal file
488
test/ux/Stepper.ux.ts
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
/* eslint jest/expect-expect: off, jest/no-test-callback: off */
|
||||||
|
import { ClientFunction, Selector } from 'testcafe';
|
||||||
|
|
||||||
|
const getPageTitle = ClientFunction(() => document.title);
|
||||||
|
const assertNoConsoleErrors = async (t) => {
|
||||||
|
const { error } = await t.getBrowserConsoleMessages();
|
||||||
|
await t.expect(error).eql([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deskreen selectors
|
||||||
|
const connectTestDeviceButton = Selector('button').withText(
|
||||||
|
'Connect Test Device'
|
||||||
|
);
|
||||||
|
const crossCloseDialogButton = Selector('svg').withAttribute(
|
||||||
|
'data-icon',
|
||||||
|
'cross'
|
||||||
|
);
|
||||||
|
const allowToConnectButton = Selector('button').withText('Allow');
|
||||||
|
const denyToConnectButton = Selector('button').withText('Deny');
|
||||||
|
const shareEntireScreenButton = Selector('button').withText('Entire Screen');
|
||||||
|
const shareApplicationWindowButton = Selector('button').withText(
|
||||||
|
'Application Window'
|
||||||
|
);
|
||||||
|
const magnifyQRCodeButton = Selector('#magnify-qr-code-button');
|
||||||
|
const largeQRCodeDialog = Selector('#qr-code-dialog-inner');
|
||||||
|
const connectedInfoStepperButton = Selector(
|
||||||
|
'#connected-device-info-stepper-button'
|
||||||
|
);
|
||||||
|
const popoverDivWithDeviceIP = Selector(
|
||||||
|
'#connected-button-popover-div-with-ip'
|
||||||
|
);
|
||||||
|
const disconnectOneDeviceButton = Selector('button').withExactText(
|
||||||
|
'Disconnect'
|
||||||
|
);
|
||||||
|
const disconnectAllDevicesButton = Selector('button').withText(
|
||||||
|
'Disconnect all'
|
||||||
|
);
|
||||||
|
const reactToastNotificationsContainer = Selector(
|
||||||
|
'.react-toast-notifications__container'
|
||||||
|
);
|
||||||
|
const headerWithTextSelectEntireScreen = Selector('h3').withText(
|
||||||
|
'Select Entire Screen to Share'
|
||||||
|
);
|
||||||
|
const headerWithTextSelectAppWindow = Selector('h3').withText(
|
||||||
|
'Select App Window to Share'
|
||||||
|
);
|
||||||
|
const previewShareButton = Selector('.preview-share-thumb-container');
|
||||||
|
const step3ConfirmButton = Selector('button').withText('Confirm');
|
||||||
|
const noINeedToShareOtherThingButton = Selector('button').withText(
|
||||||
|
'No, I need to share other thing'
|
||||||
|
);
|
||||||
|
const step4ConnectNewDeviceButton = Selector('button').withText(
|
||||||
|
'Connect New Device'
|
||||||
|
);
|
||||||
|
const connectedDevicesButton = Selector(
|
||||||
|
'#top-panel-connected-devices-list-button'
|
||||||
|
);
|
||||||
|
const connectedDevicesHeader = Selector('.bp3-text-muted').withText(
|
||||||
|
'Connected Devices'
|
||||||
|
);
|
||||||
|
const getDeviceIPContainerByIP = (ip) =>
|
||||||
|
Selector('.device-ip-container').withText(ip);
|
||||||
|
const yesDisconnectAllButton = Selector('button').withText(
|
||||||
|
'Yes, Disconnect All'
|
||||||
|
);
|
||||||
|
const settingsButtonOfTopPanel = Selector('span').withAttribute('icon', 'cog');
|
||||||
|
const openedSettingsOverlay = Selector('#settings-overlay-inner');
|
||||||
|
const darkColorAppSettingButton = Selector('button').withText('Dark');
|
||||||
|
const lightColorAppSettingButton = Selector('button').withText('Light');
|
||||||
|
const darkUIClassName = Selector('.bp3-dark');
|
||||||
|
|
||||||
|
async function getConnectedDeviceIPFromAllowToConnectDeviceAlert() {
|
||||||
|
const deviceIPTextElement = Selector(
|
||||||
|
'#allow-connection-device-alert-device-ip-span'
|
||||||
|
);
|
||||||
|
const textWithIp = await deviceIPTextElement.innerText;
|
||||||
|
return textWithIp.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async function connectTestDeviceAndGetIP(t) {
|
||||||
|
await t.click(connectTestDeviceButton());
|
||||||
|
return getConnectedDeviceIPFromAllowToConnectDeviceAlert();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connectTestDevice(t) {
|
||||||
|
await t.click(connectTestDeviceButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connectAndAllowTestDeviceAndGetIP(t) {
|
||||||
|
await connectTestDevice(t);
|
||||||
|
const ip = getConnectedDeviceIPFromAllowToConnectDeviceAlert();
|
||||||
|
await t.click(allowToConnectButton());
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connectAndAllowTestDevice(t) {
|
||||||
|
await connectTestDevice(t);
|
||||||
|
await t.click(allowToConnectButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openLargeQRCodeDialog(t) {
|
||||||
|
await t.click(magnifyQRCodeButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clickCrossButtonToCloseDialog(t) {
|
||||||
|
await t.click(crossCloseDialogButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openConnectedDeviceInfoPopover(t) {
|
||||||
|
await t.click(connectedInfoStepperButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function goToStep3SharingEntireScreen(t) {
|
||||||
|
await connectAndAllowTestDevice(t);
|
||||||
|
await t.click(shareEntireScreenButton());
|
||||||
|
await t.click(previewShareButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function goToStep3SharingAppWindow(t) {
|
||||||
|
await connectAndAllowTestDevice(t);
|
||||||
|
await t.click(shareApplicationWindowButton());
|
||||||
|
await t.click(previewShareButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function goToStep4SharingAppWindow(t) {
|
||||||
|
await goToStep3SharingAppWindow(t);
|
||||||
|
await t.click(step3ConfirmButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async function goToStep4SharingEntireScreen(t) {
|
||||||
|
await goToStep3SharingEntireScreen(t);
|
||||||
|
await t.click(step3ConfirmButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connectDeviceSharingAppWindow(t) {
|
||||||
|
await goToStep4SharingAppWindow(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connectDeviceSharingAppWindowAndGetIP(t) {
|
||||||
|
const ip = await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
await t.click(shareApplicationWindowButton());
|
||||||
|
await t.click(previewShareButton());
|
||||||
|
await t.click(step3ConfirmButton());
|
||||||
|
await t.click(step4ConnectNewDeviceButton());
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connectDeviceSharingEntireScreenAndGetIP(t) {
|
||||||
|
const ip = await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
await t.click(shareEntireScreenButton());
|
||||||
|
await t.click(previewShareButton());
|
||||||
|
await t.click(step3ConfirmButton());
|
||||||
|
await t.click(step4ConnectNewDeviceButton());
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openConnectedDevicesListDrawer(t) {
|
||||||
|
await t.click(connectedDevicesButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
fixture`Home Page`.page('../../app/app.html').afterEach(assertNoConsoleErrors);
|
||||||
|
|
||||||
|
test(`when app is launched,
|
||||||
|
|
||||||
|
it should have correct app title as "Deskreen"`, async (t) => {
|
||||||
|
await t.expect(getPageTitle()).eql('Deskreen');
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on Scan QR code step (step 1),
|
||||||
|
and when device is connected,
|
||||||
|
|
||||||
|
it should show alert with Allow or Deny buttons`, async (t) => {
|
||||||
|
await t.click(connectTestDeviceButton());
|
||||||
|
|
||||||
|
const allowButtonExists = allowToConnectButton().exists;
|
||||||
|
const denyButtonExists = denyToConnectButton().exists;
|
||||||
|
await t.expect(allowButtonExists).ok();
|
||||||
|
await t.expect(denyButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on Scan QR code step (step 1),
|
||||||
|
and when device is connected,
|
||||||
|
and when user pressed "Deny" button
|
||||||
|
|
||||||
|
it should close alert with Allow or Deny buttons`, async (t) => {
|
||||||
|
await connectTestDevice(t);
|
||||||
|
await t.click(denyToConnectButton());
|
||||||
|
|
||||||
|
const allowButtonExists = allowToConnectButton().exists;
|
||||||
|
const denyButtonExists = denyToConnectButton().exists;
|
||||||
|
await t.expect(allowButtonExists).notOk();
|
||||||
|
await t.expect(denyButtonExists).notOk();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on Scan QR code step (step 1),
|
||||||
|
and when device is connected,
|
||||||
|
and when user pressed "Allow" button,
|
||||||
|
|
||||||
|
it should go to "Share App or Screen" step (step 2)`, async (t) => {
|
||||||
|
await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
|
||||||
|
const EntireScreenButtonExists = shareEntireScreenButton().exists;
|
||||||
|
const AppWindoScreenButtonExists = shareApplicationWindowButton().exists;
|
||||||
|
await t.expect(EntireScreenButtonExists).ok();
|
||||||
|
await t.expect(AppWindoScreenButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on Scan QR code step (step 1),
|
||||||
|
and when "Magnify QR code" button is clicked,
|
||||||
|
|
||||||
|
it should open large QR code overflow`, async (t) => {
|
||||||
|
await openLargeQRCodeDialog(t);
|
||||||
|
|
||||||
|
const largeQRCodeDialogExists = largeQRCodeDialog().exists;
|
||||||
|
await t.expect(largeQRCodeDialogExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when large QR overflow is opened,
|
||||||
|
and when user clicks cross button,
|
||||||
|
|
||||||
|
it should close large QR code overflow`, async (t) => {
|
||||||
|
await openLargeQRCodeDialog(t);
|
||||||
|
await clickCrossButtonToCloseDialog(t);
|
||||||
|
|
||||||
|
const largeQrCodeDialogExists = largeQRCodeDialog().exists;
|
||||||
|
await t.expect(largeQrCodeDialogExists).notOk();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when device is connected,
|
||||||
|
|
||||||
|
it should show Connected (info) button in UI`, async (t) => {
|
||||||
|
await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
const connectedInfoStepperButtonExists = connectedInfoStepperButton().exists;
|
||||||
|
|
||||||
|
await t.expect(connectedInfoStepperButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when device is connected,
|
||||||
|
and when user clicked Connected (info) button of stepper panel,
|
||||||
|
|
||||||
|
it should show connected device popover with IP of connected device`, async (t) => {
|
||||||
|
const ip = await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
await openConnectedDeviceInfoPopover(t);
|
||||||
|
|
||||||
|
const textWithIp = await popoverDivWithDeviceIP().innerText;
|
||||||
|
await t.expect(textWithIp.includes(ip)).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when user Clicks "Disconnect" button of
|
||||||
|
Connected (info) popover,
|
||||||
|
|
||||||
|
it should go back to Scan QR code step 1`, async (t) => {
|
||||||
|
await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
await openConnectedDeviceInfoPopover(t);
|
||||||
|
await t.click(disconnectOneDeviceButton());
|
||||||
|
|
||||||
|
const magnifyQRCodeButtonExists = magnifyQRCodeButton().exists;
|
||||||
|
await t.expect(magnifyQRCodeButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when user Clicks "Disconnect" button of
|
||||||
|
Connected (info) popover,
|
||||||
|
|
||||||
|
it should display react toast notification that device has been disconnected`, async (t) => {
|
||||||
|
await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
await openConnectedDeviceInfoPopover(t);
|
||||||
|
await t.click(disconnectOneDeviceButton());
|
||||||
|
|
||||||
|
const toastText = await reactToastNotificationsContainer().innerText;
|
||||||
|
await t.expect(toastText !== '').ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when user clicks "Share Entire Screen" button,
|
||||||
|
|
||||||
|
it should display "Select Entire Screen to Share" overlay`, async (t) => {
|
||||||
|
await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
await t.click(shareEntireScreenButton());
|
||||||
|
|
||||||
|
const headerWithTextSelectEntireScreenExists = headerWithTextSelectEntireScreen()
|
||||||
|
.exists;
|
||||||
|
await t.expect(headerWithTextSelectEntireScreenExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when user clicks "Share Application Window" button,
|
||||||
|
|
||||||
|
it should display "Select App Window to Share" overlay`, async (t) => {
|
||||||
|
await connectAndAllowTestDeviceAndGetIP(t);
|
||||||
|
await t.click(shareApplicationWindowButton());
|
||||||
|
|
||||||
|
const headerWithTextSelectAppWindowExists = headerWithTextSelectAppWindow()
|
||||||
|
.exists;
|
||||||
|
await t.expect(headerWithTextSelectAppWindowExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when user clicks "Share Entire Screen" button,
|
||||||
|
and when user clicks on previev button,
|
||||||
|
|
||||||
|
it should go to step 3 and display a "Confirm" button`, async (t) => {
|
||||||
|
await goToStep3SharingEntireScreen(t);
|
||||||
|
|
||||||
|
const step3ConfirmButtonExists = step3ConfirmButton().exists;
|
||||||
|
await t.expect(step3ConfirmButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 2,
|
||||||
|
and when user clicks "Share Application Window" button,
|
||||||
|
and when user clicks on previev button,
|
||||||
|
|
||||||
|
it should go to step 3 and display a "Confirm" button`, async (t) => {
|
||||||
|
await goToStep3SharingAppWindow(t);
|
||||||
|
|
||||||
|
const step3ConfirmButtonExists = step3ConfirmButton().exists;
|
||||||
|
await t.expect(step3ConfirmButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 3,
|
||||||
|
and when user clicks "No, I need to share other thing" button,
|
||||||
|
|
||||||
|
it should go back to step 2 and display a OR button group`, async (t) => {
|
||||||
|
await goToStep3SharingAppWindow(t);
|
||||||
|
await t.click(noINeedToShareOtherThingButton());
|
||||||
|
|
||||||
|
const EntireScreenButtonExists = shareEntireScreenButton().exists;
|
||||||
|
const AppWindoScreenButtonExists = shareApplicationWindowButton().exists;
|
||||||
|
await t.expect(EntireScreenButtonExists).ok();
|
||||||
|
await t.expect(AppWindoScreenButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 3,
|
||||||
|
and when user clicks "Confirm" button,
|
||||||
|
|
||||||
|
it should go back to step 4 (Success Step) and display a "Connect New Device" button`, async (t) => {
|
||||||
|
await goToStep3SharingAppWindow(t);
|
||||||
|
await t.click(step3ConfirmButton());
|
||||||
|
|
||||||
|
const ConnectNewDeviceButtonExists = step4ConnectNewDeviceButton().exists;
|
||||||
|
await t.expect(ConnectNewDeviceButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 4 (Success Step),
|
||||||
|
and when user clicks "Connect New Device" button,
|
||||||
|
|
||||||
|
it should go back to step 1 and display a QR code`, async (t) => {
|
||||||
|
await goToStep4SharingAppWindow(t);
|
||||||
|
await t.click(step4ConnectNewDeviceButton());
|
||||||
|
|
||||||
|
const MagnifyQRCodeButtonExists = magnifyQRCodeButton().exists;
|
||||||
|
await t.expect(MagnifyQRCodeButtonExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when device is connected,
|
||||||
|
and when "Connected Devices List" drawer is opened",
|
||||||
|
|
||||||
|
it should open "Connected Devices List" panel`, async (t) => {
|
||||||
|
await connectDeviceSharingAppWindow(t);
|
||||||
|
await t.click(connectedDevicesButton());
|
||||||
|
|
||||||
|
const ConnectedDevicesHeaderExists = connectedDevicesHeader().exists;
|
||||||
|
await t.expect(ConnectedDevicesHeaderExists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when on step 4 (Success Step),
|
||||||
|
and when user clicks "Connected Devices" button,
|
||||||
|
|
||||||
|
it should open "Connected Devices List" panel with a connected device listed in it`, async (t) => {
|
||||||
|
const ip = await connectDeviceSharingAppWindowAndGetIP(t);
|
||||||
|
await openConnectedDevicesListDrawer(t);
|
||||||
|
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ip).exists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when multiple devices are connected,
|
||||||
|
and when user clicks "Connected Devices" button,
|
||||||
|
and when "Connected Devices List" drawer is opened,
|
||||||
|
|
||||||
|
it should list all connected devices with IPs in "Connected Devices List" drawer`, async (t) => {
|
||||||
|
const ipOne = await connectDeviceSharingAppWindowAndGetIP(t);
|
||||||
|
const ipTwo = await connectDeviceSharingAppWindowAndGetIP(t);
|
||||||
|
const ipThree = await connectDeviceSharingEntireScreenAndGetIP(t);
|
||||||
|
const ipFour = await connectDeviceSharingEntireScreenAndGetIP(t);
|
||||||
|
|
||||||
|
await openConnectedDevicesListDrawer(t);
|
||||||
|
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipOne).exists).ok();
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipTwo).exists).ok();
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipThree).exists).ok();
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipFour).exists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when device is connected,
|
||||||
|
and when "Connected Devices List" drawer is opened,
|
||||||
|
and when user clicks "Disconnect" button of just connected device,
|
||||||
|
|
||||||
|
it should remove a device from connected devices list drawer`, async (t) => {
|
||||||
|
const ip = await connectDeviceSharingAppWindowAndGetIP(t);
|
||||||
|
await openConnectedDevicesListDrawer(t);
|
||||||
|
await t.click(disconnectOneDeviceButton());
|
||||||
|
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ip).exists).notOk();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when multiple devices are connected,
|
||||||
|
and when "Connected Devices List" drawer is opened,
|
||||||
|
and when user clicked "Disconnect all" button,
|
||||||
|
and when user clicked "Yes, Disconnect All" button in alert,
|
||||||
|
and when "Connected Devices List" drawer is opened again,
|
||||||
|
|
||||||
|
it should remove remove all devices from "Connected Devices List" drawer`, async (t) => {
|
||||||
|
const ipOne = await connectDeviceSharingAppWindowAndGetIP(t);
|
||||||
|
const ipTwo = await connectDeviceSharingAppWindowAndGetIP(t);
|
||||||
|
const ipThree = await connectDeviceSharingEntireScreenAndGetIP(t);
|
||||||
|
const ipFour = await connectDeviceSharingEntireScreenAndGetIP(t);
|
||||||
|
await openConnectedDevicesListDrawer(t);
|
||||||
|
await t.click(disconnectAllDevicesButton());
|
||||||
|
await t.click(yesDisconnectAllButton());
|
||||||
|
|
||||||
|
await openConnectedDevicesListDrawer(t);
|
||||||
|
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipOne).exists).notOk();
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipTwo).exists).notOk();
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipThree).exists).notOk();
|
||||||
|
await t.expect(getDeviceIPContainerByIP(ipFour).exists).notOk();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when device is connected,
|
||||||
|
and when user is on "Success" step, (step 4),
|
||||||
|
and when "Connected Devices List" drawer is opened,
|
||||||
|
and when user clicked "Disconnect all" button,
|
||||||
|
and when user clicked "Yes, Disconnect All" in alert,
|
||||||
|
|
||||||
|
it should go back to Scan QR code step`, async (t) => {
|
||||||
|
await goToStep4SharingAppWindow(t);
|
||||||
|
await openConnectedDevicesListDrawer(t);
|
||||||
|
await t.click(disconnectAllDevicesButton());
|
||||||
|
await t.click(yesDisconnectAllButton());
|
||||||
|
|
||||||
|
await t.expect(magnifyQRCodeButton().exists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when device is connected,
|
||||||
|
and when user clicks "Connected Devices List" drawer is opened,
|
||||||
|
and when user clicks "Disconnect all" button of connected device
|
||||||
|
|
||||||
|
it should display "Are you sure you want to disconnect all devices..." alert`, async (t) => {
|
||||||
|
await connectDeviceSharingAppWindowAndGetIP(t);
|
||||||
|
await openConnectedDevicesListDrawer(t);
|
||||||
|
await t.click(Selector('button').withText('Disconnect all'));
|
||||||
|
|
||||||
|
await t.expect(yesDisconnectAllButton().exists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
/////////// SETTINGS OVERLAY TESTING START ///////
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
*/
|
||||||
|
|
||||||
|
test(`when clicks "Settings" button of top panel,
|
||||||
|
|
||||||
|
it should open "Settings" panel`, async (t) => {
|
||||||
|
await t.click(settingsButtonOfTopPanel());
|
||||||
|
|
||||||
|
await t.expect(openedSettingsOverlay().exists).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`when "Settings" Panel is opened,
|
||||||
|
and when user clicks "Dark" and "Light" buttons,
|
||||||
|
|
||||||
|
it should change application colors accordingly`, async (t) => {
|
||||||
|
await t.click(settingsButtonOfTopPanel());
|
||||||
|
|
||||||
|
// action and assertion 1
|
||||||
|
await t.click(darkColorAppSettingButton());
|
||||||
|
await t.expect(darkUIClassName().exists).ok();
|
||||||
|
|
||||||
|
// action and assertion 2
|
||||||
|
await t.click(lightColorAppSettingButton());
|
||||||
|
await t.expect(darkUIClassName().exists).notOk();
|
||||||
|
});
|
564
yarn.lock
564
yarn.lock
@ -12,25 +12,6 @@
|
|||||||
resolved "https://packages.deskreen.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30"
|
resolved "https://packages.deskreen.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30"
|
||||||
integrity sha1-nK+xca+CMpSQNTtIFvAzR6oVCjA=
|
integrity sha1-nK+xca+CMpSQNTtIFvAzR6oVCjA=
|
||||||
|
|
||||||
"@amilajack/testcafe-browser-provider-electron@^0.0.15-alpha.1":
|
|
||||||
version "0.0.15-alpha.1"
|
|
||||||
resolved "https://packages.deskreen.com/@amilajack%2ftestcafe-browser-provider-electron/-/testcafe-browser-provider-electron-0.0.15-alpha.1.tgz#506080ec623c1509fae489b13cb2a2894ec6fbb9"
|
|
||||||
integrity sha512-05JwzcV59rxArehDWPM0Lw4YNvVr5c3J/j2ikJeQKHAQSoA0TsRSdqSMjGDaT8LGem0HAATPLh7hRhI481alIQ==
|
|
||||||
dependencies:
|
|
||||||
babel-runtime "^6.25.0"
|
|
||||||
chrome-remote-interface "^0.27.0"
|
|
||||||
debug "4.1.1"
|
|
||||||
dedent "^0.7.0"
|
|
||||||
endpoint-utils "^1.0.2"
|
|
||||||
lodash "^4.17.4"
|
|
||||||
mustache "^2.3.0"
|
|
||||||
node-ipc "^9.1.0"
|
|
||||||
os-family "^1.0.0"
|
|
||||||
pify "^2.3.0"
|
|
||||||
pinkie "^2.0.4"
|
|
||||||
promisify-event "^1.0.0"
|
|
||||||
proxyquire "^1.7.10"
|
|
||||||
|
|
||||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4":
|
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4":
|
||||||
version "7.10.4"
|
version "7.10.4"
|
||||||
resolved "https://packages.deskreen.com/@babel%2fcode-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
resolved "https://packages.deskreen.com/@babel%2fcode-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
||||||
@ -188,7 +169,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.11.0"
|
"@babel/types" "^7.11.0"
|
||||||
|
|
||||||
"@babel/helper-module-imports@^7.10.4":
|
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4":
|
||||||
version "7.10.4"
|
version "7.10.4"
|
||||||
resolved "https://packages.deskreen.com/@babel%2fhelper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620"
|
resolved "https://packages.deskreen.com/@babel%2fhelper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620"
|
||||||
integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==
|
integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==
|
||||||
@ -1093,7 +1074,7 @@
|
|||||||
core-js-pure "^3.0.0"
|
core-js-pure "^3.0.0"
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4":
|
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
|
||||||
version "7.11.2"
|
version "7.11.2"
|
||||||
resolved "https://packages.deskreen.com/@babel%2fruntime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
|
resolved "https://packages.deskreen.com/@babel%2fruntime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
|
||||||
integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
|
integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
|
||||||
@ -1163,6 +1144,15 @@
|
|||||||
classnames "^2.2"
|
classnames "^2.2"
|
||||||
tslib "~1.13.0"
|
tslib "~1.13.0"
|
||||||
|
|
||||||
|
"@blueprintjs/select@^3.13.7":
|
||||||
|
version "3.13.7"
|
||||||
|
resolved "https://packages.deskreen.com/@blueprintjs%2fselect/-/select-3.13.7.tgz#166675a8caeccacdb31216e92ef114f29888dbf6"
|
||||||
|
integrity sha512-kJVtbDDGVwIIC1+cN7H0DUrlumSVZGNEq2CnczQNI07RkHpPzuIR5stjn3LU+NjtCa3pidPNr4w78JRTesZzLg==
|
||||||
|
dependencies:
|
||||||
|
"@blueprintjs/core" "^3.31.0"
|
||||||
|
classnames "^2.2"
|
||||||
|
tslib "~1.13.0"
|
||||||
|
|
||||||
"@cnakazawa/watch@^1.0.3":
|
"@cnakazawa/watch@^1.0.3":
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://packages.deskreen.com/@cnakazawa%2fwatch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
|
resolved "https://packages.deskreen.com/@cnakazawa%2fwatch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a"
|
||||||
@ -1204,6 +1194,108 @@
|
|||||||
global-agent "^2.0.2"
|
global-agent "^2.0.2"
|
||||||
global-tunnel-ng "^2.7.1"
|
global-tunnel-ng "^2.7.1"
|
||||||
|
|
||||||
|
"@emotion/cache@^10.0.27":
|
||||||
|
version "10.0.29"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fcache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0"
|
||||||
|
integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/sheet" "0.9.4"
|
||||||
|
"@emotion/stylis" "0.8.5"
|
||||||
|
"@emotion/utils" "0.11.3"
|
||||||
|
"@emotion/weak-memoize" "0.2.5"
|
||||||
|
|
||||||
|
"@emotion/core@^10.0.14", "@emotion/core@^10.0.35":
|
||||||
|
version "10.0.35"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fcore/-/core-10.0.35.tgz#513fcf2e22cd4dfe9d3894ed138c9d7a859af9b3"
|
||||||
|
integrity sha512-sH++vJCdk025fBlRZSAhkRlSUoqSqgCzYf5fMOmqqi3bM6how+sQpg3hkgJonj8GxXM4WbD7dRO+4tegDB9fUw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.5.5"
|
||||||
|
"@emotion/cache" "^10.0.27"
|
||||||
|
"@emotion/css" "^10.0.27"
|
||||||
|
"@emotion/serialize" "^0.11.15"
|
||||||
|
"@emotion/sheet" "0.9.4"
|
||||||
|
"@emotion/utils" "0.11.3"
|
||||||
|
|
||||||
|
"@emotion/css@^10.0.27":
|
||||||
|
version "10.0.27"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fcss/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c"
|
||||||
|
integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/serialize" "^0.11.15"
|
||||||
|
"@emotion/utils" "0.11.3"
|
||||||
|
babel-plugin-emotion "^10.0.27"
|
||||||
|
|
||||||
|
"@emotion/hash@0.8.0", "@emotion/hash@^0.8.0":
|
||||||
|
version "0.8.0"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fhash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
|
||||||
|
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
|
||||||
|
|
||||||
|
"@emotion/is-prop-valid@0.8.8":
|
||||||
|
version "0.8.8"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fis-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
|
||||||
|
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/memoize" "0.7.4"
|
||||||
|
|
||||||
|
"@emotion/memoize@0.7.4":
|
||||||
|
version "0.7.4"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fmemoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
||||||
|
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
||||||
|
|
||||||
|
"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16":
|
||||||
|
version "0.11.16"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fserialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad"
|
||||||
|
integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/hash" "0.8.0"
|
||||||
|
"@emotion/memoize" "0.7.4"
|
||||||
|
"@emotion/unitless" "0.7.5"
|
||||||
|
"@emotion/utils" "0.11.3"
|
||||||
|
csstype "^2.5.7"
|
||||||
|
|
||||||
|
"@emotion/sheet@0.9.4":
|
||||||
|
version "0.9.4"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fsheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5"
|
||||||
|
integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==
|
||||||
|
|
||||||
|
"@emotion/styled-base@^10.0.27":
|
||||||
|
version "10.0.31"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fstyled-base/-/styled-base-10.0.31.tgz#940957ee0aa15c6974adc7d494ff19765a2f742a"
|
||||||
|
integrity sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.5.5"
|
||||||
|
"@emotion/is-prop-valid" "0.8.8"
|
||||||
|
"@emotion/serialize" "^0.11.15"
|
||||||
|
"@emotion/utils" "0.11.3"
|
||||||
|
|
||||||
|
"@emotion/styled@^10.0.27":
|
||||||
|
version "10.0.27"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fstyled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf"
|
||||||
|
integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/styled-base" "^10.0.27"
|
||||||
|
babel-plugin-emotion "^10.0.27"
|
||||||
|
|
||||||
|
"@emotion/stylis@0.8.5":
|
||||||
|
version "0.8.5"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fstylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
|
||||||
|
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
|
||||||
|
|
||||||
|
"@emotion/unitless@0.7.5":
|
||||||
|
version "0.7.5"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2funitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
|
||||||
|
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
|
||||||
|
|
||||||
|
"@emotion/utils@0.11.3":
|
||||||
|
version "0.11.3"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2futils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924"
|
||||||
|
integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==
|
||||||
|
|
||||||
|
"@emotion/weak-memoize@0.2.5":
|
||||||
|
version "0.2.5"
|
||||||
|
resolved "https://packages.deskreen.com/@emotion%2fweak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
|
||||||
|
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
|
||||||
|
|
||||||
"@fortawesome/fontawesome-free@^5.14.0":
|
"@fortawesome/fontawesome-free@^5.14.0":
|
||||||
version "5.14.0"
|
version "5.14.0"
|
||||||
resolved "https://packages.deskreen.com/@fortawesome%2ffontawesome-free/-/fontawesome-free-5.14.0.tgz#a371e91029ebf265015e64f81bfbf7d228c9681f"
|
resolved "https://packages.deskreen.com/@fortawesome%2ffontawesome-free/-/fontawesome-free-5.14.0.tgz#a371e91029ebf265015e64f81bfbf7d228c9681f"
|
||||||
@ -1416,6 +1508,70 @@
|
|||||||
"@types/yargs" "^15.0.0"
|
"@types/yargs" "^15.0.0"
|
||||||
chalk "^4.0.0"
|
chalk "^4.0.0"
|
||||||
|
|
||||||
|
"@material-ui/core@^4.11.0":
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://packages.deskreen.com/@material-ui%2fcore/-/core-4.11.0.tgz#b69b26e4553c9e53f2bfaf1053e216a0af9be15a"
|
||||||
|
integrity sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.4.4"
|
||||||
|
"@material-ui/styles" "^4.10.0"
|
||||||
|
"@material-ui/system" "^4.9.14"
|
||||||
|
"@material-ui/types" "^5.1.0"
|
||||||
|
"@material-ui/utils" "^4.10.2"
|
||||||
|
"@types/react-transition-group" "^4.2.0"
|
||||||
|
clsx "^1.0.4"
|
||||||
|
hoist-non-react-statics "^3.3.2"
|
||||||
|
popper.js "1.16.1-lts"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
react-is "^16.8.0"
|
||||||
|
react-transition-group "^4.4.0"
|
||||||
|
|
||||||
|
"@material-ui/styles@^4.10.0":
|
||||||
|
version "4.10.0"
|
||||||
|
resolved "https://packages.deskreen.com/@material-ui%2fstyles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071"
|
||||||
|
integrity sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.4.4"
|
||||||
|
"@emotion/hash" "^0.8.0"
|
||||||
|
"@material-ui/types" "^5.1.0"
|
||||||
|
"@material-ui/utils" "^4.9.6"
|
||||||
|
clsx "^1.0.4"
|
||||||
|
csstype "^2.5.2"
|
||||||
|
hoist-non-react-statics "^3.3.2"
|
||||||
|
jss "^10.0.3"
|
||||||
|
jss-plugin-camel-case "^10.0.3"
|
||||||
|
jss-plugin-default-unit "^10.0.3"
|
||||||
|
jss-plugin-global "^10.0.3"
|
||||||
|
jss-plugin-nested "^10.0.3"
|
||||||
|
jss-plugin-props-sort "^10.0.3"
|
||||||
|
jss-plugin-rule-value-function "^10.0.3"
|
||||||
|
jss-plugin-vendor-prefixer "^10.0.3"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
|
"@material-ui/system@^4.9.14":
|
||||||
|
version "4.9.14"
|
||||||
|
resolved "https://packages.deskreen.com/@material-ui%2fsystem/-/system-4.9.14.tgz#4b00c48b569340cefb2036d0596b93ac6c587a5f"
|
||||||
|
integrity sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.4.4"
|
||||||
|
"@material-ui/utils" "^4.9.6"
|
||||||
|
csstype "^2.5.2"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
|
"@material-ui/types@^5.1.0":
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://packages.deskreen.com/@material-ui%2ftypes/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2"
|
||||||
|
integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==
|
||||||
|
|
||||||
|
"@material-ui/utils@^4.10.2", "@material-ui/utils@^4.9.6":
|
||||||
|
version "4.10.2"
|
||||||
|
resolved "https://packages.deskreen.com/@material-ui%2futils/-/utils-4.10.2.tgz#3fd5470ca61b7341f1e0468ac8f29a70bf6df321"
|
||||||
|
integrity sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.4.4"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
react-is "^16.8.0"
|
||||||
|
|
||||||
"@mrmlnc/readdir-enhanced@^2.2.1":
|
"@mrmlnc/readdir-enhanced@^2.2.1":
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://packages.deskreen.com/@mrmlnc%2freaddir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
|
resolved "https://packages.deskreen.com/@mrmlnc%2freaddir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
|
||||||
@ -1568,6 +1724,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/classnames@^2.2.10":
|
||||||
|
version "2.2.10"
|
||||||
|
resolved "https://packages.deskreen.com/@types%2fclassnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999"
|
||||||
|
integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==
|
||||||
|
|
||||||
"@types/color-name@^1.1.1":
|
"@types/color-name@^1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://packages.deskreen.com/@types%2fcolor-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
resolved "https://packages.deskreen.com/@types%2fcolor-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||||
@ -1880,6 +2041,13 @@
|
|||||||
resolved "https://packages.deskreen.com/@types%2fq/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
|
resolved "https://packages.deskreen.com/@types%2fq/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
|
||||||
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
|
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
|
||||||
|
|
||||||
|
"@types/qrcode.react@^1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://packages.deskreen.com/@types%2fqrcode.react/-/qrcode.react-1.0.1.tgz#0904e7a075a6274a5258f19567b4f64013c159d8"
|
||||||
|
integrity sha512-PcVCjpsiT2KFKfJibOgTQtkt0QQT/6GbQUp1Np/hMPhwUzMJ2DRUkR9j7tXN9Q8X06qukw+RbaJ8lJ22SBod+Q==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/qs@*":
|
"@types/qs@*":
|
||||||
version "6.9.4"
|
version "6.9.4"
|
||||||
resolved "https://packages.deskreen.com/@types%2fqs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a"
|
resolved "https://packages.deskreen.com/@types%2fqs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a"
|
||||||
@ -1931,6 +2099,27 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-toast-notifications@^2.4.0":
|
||||||
|
version "2.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/@types%2freact-toast-notifications/-/react-toast-notifications-2.4.0.tgz#0ca0732cfae5a6ef5939a676fffac6e64c78bc25"
|
||||||
|
integrity sha512-nBI6gQ0E5gwi3IcTrVOR3oKoMGRfH1gK67kI6RIKUmiV5Sc3ZC/eymYBFt6iDo0dhlYET6kdtR0tcUh9h5L0sQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-toastify@^4.1.0":
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://packages.deskreen.com/@types%2freact-toastify/-/react-toastify-4.1.0.tgz#604e712855dd677916d5c66af595d3b590f5d95d"
|
||||||
|
integrity sha512-u7Ie/7LHBsPVz/iJxi/WlRDS7Gh9csCJACTDXx+pSLuZCm94xpkwzhM3jV1L5ZxP/in0Gp2tFbJ91VrSGr1gyQ==
|
||||||
|
dependencies:
|
||||||
|
react-toastify "*"
|
||||||
|
|
||||||
|
"@types/react-transition-group@^4.2.0":
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/@types%2freact-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d"
|
||||||
|
integrity sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@^16.9.44":
|
"@types/react@*", "@types/react@^16.9.44":
|
||||||
version "16.9.48"
|
version "16.9.48"
|
||||||
resolved "https://packages.deskreen.com/@types%2freact/-/react-16.9.48.tgz#d3387329f070d1b1bc0ff4a54a54ceefd5a8485c"
|
resolved "https://packages.deskreen.com/@types%2freact/-/react-16.9.48.tgz#d3387329f070d1b1bc0ff4a54a54ceefd5a8485c"
|
||||||
@ -3077,6 +3266,22 @@ babel-plugin-dynamic-import-node@^2.3.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
object.assign "^4.1.0"
|
object.assign "^4.1.0"
|
||||||
|
|
||||||
|
babel-plugin-emotion@^10.0.27:
|
||||||
|
version "10.0.33"
|
||||||
|
resolved "https://packages.deskreen.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz#ce1155dcd1783bbb9286051efee53f4e2be63e03"
|
||||||
|
integrity sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-module-imports" "^7.0.0"
|
||||||
|
"@emotion/hash" "0.8.0"
|
||||||
|
"@emotion/memoize" "0.7.4"
|
||||||
|
"@emotion/serialize" "^0.11.16"
|
||||||
|
babel-plugin-macros "^2.0.0"
|
||||||
|
babel-plugin-syntax-jsx "^6.18.0"
|
||||||
|
convert-source-map "^1.5.0"
|
||||||
|
escape-string-regexp "^1.0.5"
|
||||||
|
find-root "^1.1.0"
|
||||||
|
source-map "^0.5.7"
|
||||||
|
|
||||||
babel-plugin-istanbul@^6.0.0:
|
babel-plugin-istanbul@^6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://packages.deskreen.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765"
|
resolved "https://packages.deskreen.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765"
|
||||||
@ -3098,6 +3303,15 @@ babel-plugin-jest-hoist@^26.2.0:
|
|||||||
"@types/babel__core" "^7.0.0"
|
"@types/babel__core" "^7.0.0"
|
||||||
"@types/babel__traverse" "^7.0.6"
|
"@types/babel__traverse" "^7.0.6"
|
||||||
|
|
||||||
|
babel-plugin-macros@^2.0.0:
|
||||||
|
version "2.8.0"
|
||||||
|
resolved "https://packages.deskreen.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138"
|
||||||
|
integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.7.2"
|
||||||
|
cosmiconfig "^6.0.0"
|
||||||
|
resolve "^1.12.0"
|
||||||
|
|
||||||
babel-plugin-syntax-async-functions@^6.8.0:
|
babel-plugin-syntax-async-functions@^6.8.0:
|
||||||
version "6.13.0"
|
version "6.13.0"
|
||||||
resolved "https://packages.deskreen.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
|
resolved "https://packages.deskreen.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
|
||||||
@ -3133,7 +3347,7 @@ babel-plugin-syntax-flow@^6.18.0:
|
|||||||
resolved "https://packages.deskreen.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
|
resolved "https://packages.deskreen.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
|
||||||
integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=
|
integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=
|
||||||
|
|
||||||
babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
|
babel-plugin-syntax-jsx@^6.18.0, babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
|
||||||
version "6.18.0"
|
version "6.18.0"
|
||||||
resolved "https://packages.deskreen.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
resolved "https://packages.deskreen.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||||
integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
|
integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
|
||||||
@ -4426,7 +4640,7 @@ class-utils@^0.3.5:
|
|||||||
isobject "^3.0.0"
|
isobject "^3.0.0"
|
||||||
static-extend "^0.1.1"
|
static-extend "^0.1.1"
|
||||||
|
|
||||||
classnames@^2.2:
|
classnames@^2.2, classnames@^2.2.6:
|
||||||
version "2.2.6"
|
version "2.2.6"
|
||||||
resolved "https://packages.deskreen.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
resolved "https://packages.deskreen.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||||
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
|
||||||
@ -4514,6 +4728,11 @@ clone@^1.0.2:
|
|||||||
resolved "https://packages.deskreen.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
resolved "https://packages.deskreen.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||||
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
|
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
|
||||||
|
|
||||||
|
clsx@^1.0.4, clsx@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://packages.deskreen.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||||
|
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||||
|
|
||||||
co@^4.6.0:
|
co@^4.6.0:
|
||||||
version "4.6.0"
|
version "4.6.0"
|
||||||
resolved "https://packages.deskreen.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
resolved "https://packages.deskreen.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||||
@ -4798,7 +5017,7 @@ content-type@^1.0.4, content-type@~1.0.4:
|
|||||||
resolved "https://packages.deskreen.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
resolved "https://packages.deskreen.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||||
|
|
||||||
convert-source-map@^1.4.0, convert-source-map@^1.5.1, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
|
convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
|
||||||
version "1.7.0"
|
version "1.7.0"
|
||||||
resolved "https://packages.deskreen.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
resolved "https://packages.deskreen.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
||||||
integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
|
integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
|
||||||
@ -5081,6 +5300,14 @@ css-tree@1.0.0-alpha.39:
|
|||||||
mdn-data "2.0.6"
|
mdn-data "2.0.6"
|
||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
|
|
||||||
|
css-vendor@^2.0.8:
|
||||||
|
version "2.0.8"
|
||||||
|
resolved "https://packages.deskreen.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d"
|
||||||
|
integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.8.3"
|
||||||
|
is-in-browser "^1.0.2"
|
||||||
|
|
||||||
css-what@2.1:
|
css-what@2.1:
|
||||||
version "2.1.3"
|
version "2.1.3"
|
||||||
resolved "https://packages.deskreen.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
|
resolved "https://packages.deskreen.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
|
||||||
@ -5198,6 +5425,11 @@ cssstyle@^2.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
cssom "~0.3.6"
|
cssom "~0.3.6"
|
||||||
|
|
||||||
|
csstype@^2.5.2, csstype@^2.5.7:
|
||||||
|
version "2.6.13"
|
||||||
|
resolved "https://packages.deskreen.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f"
|
||||||
|
integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==
|
||||||
|
|
||||||
csstype@^3.0.2:
|
csstype@^3.0.2:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://packages.deskreen.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8"
|
resolved "https://packages.deskreen.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8"
|
||||||
@ -5364,6 +5596,13 @@ default-gateway@^4.2.0:
|
|||||||
execa "^1.0.0"
|
execa "^1.0.0"
|
||||||
ip-regex "^2.1.0"
|
ip-regex "^2.1.0"
|
||||||
|
|
||||||
|
default-gateway@^6.0.0:
|
||||||
|
version "6.0.2"
|
||||||
|
resolved "https://packages.deskreen.com/default-gateway/-/default-gateway-6.0.2.tgz#fc14f4a2ae1cbc699c2b40cedd941ab312609ea4"
|
||||||
|
integrity sha512-bWrj9HZWNXJ/RUkWmBIp67JawNrPGz0il43IGWU84dazEYbNFQ52HbIiqgRQdYUHK3RyGrENrDV9QkwArt6IAQ==
|
||||||
|
dependencies:
|
||||||
|
execa "^4.0.3"
|
||||||
|
|
||||||
defaults@^1.0.3:
|
defaults@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://packages.deskreen.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
|
resolved "https://packages.deskreen.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
|
||||||
@ -5621,6 +5860,14 @@ dom-helpers@^3.4.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.1.2"
|
"@babel/runtime" "^7.1.2"
|
||||||
|
|
||||||
|
dom-helpers@^5.0.1:
|
||||||
|
version "5.2.0"
|
||||||
|
resolved "https://packages.deskreen.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
|
||||||
|
integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.8.7"
|
||||||
|
csstype "^3.0.2"
|
||||||
|
|
||||||
dom-serializer@0:
|
dom-serializer@0:
|
||||||
version "0.2.2"
|
version "0.2.2"
|
||||||
resolved "https://packages.deskreen.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
resolved "https://packages.deskreen.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||||
@ -5802,7 +6049,7 @@ electron-is-accelerator@^0.1.0:
|
|||||||
resolved "https://packages.deskreen.com/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
|
resolved "https://packages.deskreen.com/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
|
||||||
integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
|
integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
|
||||||
|
|
||||||
electron-is-dev@^1.1.0, electron-is-dev@^1.2.0:
|
electron-is-dev@^1.1.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://packages.deskreen.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e"
|
resolved "https://packages.deskreen.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e"
|
||||||
integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==
|
integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==
|
||||||
@ -5851,6 +6098,18 @@ electron-rebuild@^1.10.0:
|
|||||||
spawn-rx "^3.0.0"
|
spawn-rx "^3.0.0"
|
||||||
yargs "^14.2.0"
|
yargs "^14.2.0"
|
||||||
|
|
||||||
|
electron-settings@^4.0.2:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://packages.deskreen.com/electron-settings/-/electron-settings-4.0.2.tgz#26ef242397393e0e69119f6fb879fc2287d0f508"
|
||||||
|
integrity sha512-WnUlrnBsO784oXcag0ym+A3ySoIwonz5GhYFsWroMHVzslzmsP+81f/Fof41T9UrRUxuPPKiZPZMwGO+yvWChg==
|
||||||
|
dependencies:
|
||||||
|
lodash.get "^4.4.2"
|
||||||
|
lodash.has "^4.5.2"
|
||||||
|
lodash.set "^4.3.2"
|
||||||
|
lodash.unset "^4.5.2"
|
||||||
|
mkdirp "^1.0.4"
|
||||||
|
write-file-atomic "^3.0.3"
|
||||||
|
|
||||||
electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.523:
|
electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.523:
|
||||||
version "1.3.555"
|
version "1.3.555"
|
||||||
resolved "https://packages.deskreen.com/electron-to-chromium/-/electron-to-chromium-1.3.555.tgz#a096716ff77cf8da9a608eb628fd6927869503d2"
|
resolved "https://packages.deskreen.com/electron-to-chromium/-/electron-to-chromium-1.3.555.tgz#a096716ff77cf8da9a608eb628fd6927869503d2"
|
||||||
@ -7005,6 +7264,11 @@ follow-redirects@^1.0.0:
|
|||||||
resolved "https://packages.deskreen.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
|
resolved "https://packages.deskreen.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
|
||||||
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
|
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
|
||||||
|
|
||||||
|
fontsource-lexend-peta@^3.0.9:
|
||||||
|
version "3.0.9"
|
||||||
|
resolved "https://packages.deskreen.com/fontsource-lexend-peta/-/fontsource-lexend-peta-3.0.9.tgz#c11994728d50d95a348b6f87926c6eb1c086c892"
|
||||||
|
integrity sha512-pqOcFyjC8RkZcSC9EoXLk2fb2HssgWcvMREk7DvNJInWP+v3/htZaQjlF1el6EQoVuOx9lJwNxqqNiQvW3B8/w==
|
||||||
|
|
||||||
for-in@^1.0.2:
|
for-in@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://packages.deskreen.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
resolved "https://packages.deskreen.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||||
@ -7626,7 +7890,7 @@ hmac-drbg@^1.0.0:
|
|||||||
minimalistic-assert "^1.0.0"
|
minimalistic-assert "^1.0.0"
|
||||||
minimalistic-crypto-utils "^1.0.1"
|
minimalistic-crypto-utils "^1.0.1"
|
||||||
|
|
||||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0:
|
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||||
version "3.3.2"
|
version "3.3.2"
|
||||||
resolved "https://packages.deskreen.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
resolved "https://packages.deskreen.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||||
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||||
@ -7858,6 +8122,11 @@ husky@^4.2.5:
|
|||||||
slash "^3.0.0"
|
slash "^3.0.0"
|
||||||
which-pm-runs "^1.0.0"
|
which-pm-runs "^1.0.0"
|
||||||
|
|
||||||
|
hyphenate-style-name@^1.0.3:
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://packages.deskreen.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
||||||
|
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
||||||
|
|
||||||
i18next-fs-backend@^1.0.7:
|
i18next-fs-backend@^1.0.7:
|
||||||
version "1.0.7"
|
version "1.0.7"
|
||||||
resolved "https://packages.deskreen.com/i18next-fs-backend/-/i18next-fs-backend-1.0.7.tgz#00ca4587e306f8948740408389dda73461a5d07f"
|
resolved "https://packages.deskreen.com/i18next-fs-backend/-/i18next-fs-backend-1.0.7.tgz#00ca4587e306f8948740408389dda73461a5d07f"
|
||||||
@ -8063,6 +8332,14 @@ internal-ip@^4.3.0:
|
|||||||
default-gateway "^4.2.0"
|
default-gateway "^4.2.0"
|
||||||
ipaddr.js "^1.9.0"
|
ipaddr.js "^1.9.0"
|
||||||
|
|
||||||
|
internal-ip@^6.1.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://packages.deskreen.com/internal-ip/-/internal-ip-6.1.0.tgz#3ce3a9155dc9e2a423af0059efcf5f4b0de3399c"
|
||||||
|
integrity sha512-Cs1iaqrl3z3KJ2ejWyfKkMcuv9NTEJWXtUBSGVc+Eg9BjBLS0k11CsOkf/p5quOkVhhRuq9zwZ/PuJpPUuDP9Q==
|
||||||
|
dependencies:
|
||||||
|
default-gateway "^6.0.0"
|
||||||
|
ipaddr.js "^1.9.1"
|
||||||
|
|
||||||
internal-slot@^1.0.2:
|
internal-slot@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://packages.deskreen.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3"
|
resolved "https://packages.deskreen.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3"
|
||||||
@ -8094,7 +8371,7 @@ ip@^1.1.0, ip@^1.1.3, ip@^1.1.5:
|
|||||||
resolved "https://packages.deskreen.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
resolved "https://packages.deskreen.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||||
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
||||||
|
|
||||||
ipaddr.js@1.9.1, ipaddr.js@^1.9.0:
|
ipaddr.js@1.9.1, ipaddr.js@^1.9.0, ipaddr.js@^1.9.1:
|
||||||
version "1.9.1"
|
version "1.9.1"
|
||||||
resolved "https://packages.deskreen.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
resolved "https://packages.deskreen.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
||||||
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
||||||
@ -8353,6 +8630,11 @@ is-hexadecimal@^1.0.0:
|
|||||||
resolved "https://packages.deskreen.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
|
resolved "https://packages.deskreen.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
|
||||||
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
|
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
|
||||||
|
|
||||||
|
is-in-browser@^1.0.2, is-in-browser@^1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://packages.deskreen.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835"
|
||||||
|
integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=
|
||||||
|
|
||||||
is-installed-globally@^0.3.1:
|
is-installed-globally@^0.3.1:
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://packages.deskreen.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141"
|
resolved "https://packages.deskreen.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141"
|
||||||
@ -9243,6 +9525,76 @@ jsprim@^1.2.2:
|
|||||||
json-schema "0.2.3"
|
json-schema "0.2.3"
|
||||||
verror "1.10.0"
|
verror "1.10.0"
|
||||||
|
|
||||||
|
jss-plugin-camel-case@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.4.0.tgz#46c75ff7fd61c304984c21af5817823f0f501ceb"
|
||||||
|
integrity sha512-9oDjsQ/AgdBbMyRjc06Kl3P8lDCSEts2vYZiPZfGAxbGCegqE4RnMob3mDaBby5H9vL9gWmyyImhLRWqIkRUCw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
hyphenate-style-name "^1.0.3"
|
||||||
|
jss "10.4.0"
|
||||||
|
|
||||||
|
jss-plugin-default-unit@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.4.0.tgz#2b10f01269eaea7f36f0f5fd1cfbfcc76ed42854"
|
||||||
|
integrity sha512-BYJ+Y3RUYiMEgmlcYMLqwbA49DcSWsGgHpVmEEllTC8MK5iJ7++pT9TnKkKBnNZZxTV75ycyFCR5xeLSOzVm4A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
jss "10.4.0"
|
||||||
|
|
||||||
|
jss-plugin-global@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss-plugin-global/-/jss-plugin-global-10.4.0.tgz#19449425a94e4e74e113139b629fd44d3577f97d"
|
||||||
|
integrity sha512-b8IHMJUmv29cidt3nI4bUI1+Mo5RZE37kqthaFpmxf5K7r2aAegGliAw4hXvA70ca6ckAoXMUl4SN/zxiRcRag==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
jss "10.4.0"
|
||||||
|
|
||||||
|
jss-plugin-nested@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss-plugin-nested/-/jss-plugin-nested-10.4.0.tgz#017d0c02c0b6b454fd9d7d3fc33470a15eea9fd1"
|
||||||
|
integrity sha512-cKgpeHIxAP0ygeWh+drpLbrxFiak6zzJ2toVRi/NmHbpkNaLjTLgePmOz5+67ln3qzJiPdXXJB1tbOyYKAP4Pw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
jss "10.4.0"
|
||||||
|
tiny-warning "^1.0.2"
|
||||||
|
|
||||||
|
jss-plugin-props-sort@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.4.0.tgz#7110bf0b6049cc2080b220b506532bf0b70c0e07"
|
||||||
|
integrity sha512-j/t0R40/2fp+Nzt6GgHeUFnHVY2kPGF5drUVlgkcwYoHCgtBDOhTTsOfdaQFW6sHWfoQYgnGV4CXdjlPiRrzwA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
jss "10.4.0"
|
||||||
|
|
||||||
|
jss-plugin-rule-value-function@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.4.0.tgz#7cff4a91e84973536fa49b6ebbdbf7f339b01c82"
|
||||||
|
integrity sha512-w8504Cdfu66+0SJoLkr6GUQlEb8keHg8ymtJXdVHWh0YvFxDG2l/nS93SI5Gfx0fV29dO6yUugXnKzDFJxrdFQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
jss "10.4.0"
|
||||||
|
tiny-warning "^1.0.2"
|
||||||
|
|
||||||
|
jss-plugin-vendor-prefixer@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.4.0.tgz#2a78f3c5d57d1e024fe7ad7c41de34d04e72ecc0"
|
||||||
|
integrity sha512-DpF+/a+GU8hMh/948sBGnKSNfKkoHg2p9aRFUmyoyxgKjOeH9n74Ht3Yt8lOgdZsuWNJbPrvaa3U4PXKwxVpTQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
css-vendor "^2.0.8"
|
||||||
|
jss "10.4.0"
|
||||||
|
|
||||||
|
jss@10.4.0, jss@^10.0.3:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/jss/-/jss-10.4.0.tgz#473a6fbe42e85441020a07e9519dac1e8a2e79ca"
|
||||||
|
integrity sha512-l7EwdwhsDishXzqTc3lbsbyZ83tlUl5L/Hb16pHCvZliA9lRDdNBZmHzeJHP0sxqD0t1mrMmMR8XroR12JBYzw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
csstype "^3.0.2"
|
||||||
|
is-in-browser "^1.1.3"
|
||||||
|
tiny-warning "^1.0.2"
|
||||||
|
|
||||||
jsx-ast-utils@^2.4.1:
|
jsx-ast-utils@^2.4.1:
|
||||||
version "2.4.1"
|
version "2.4.1"
|
||||||
resolved "https://packages.deskreen.com/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz#1114a4c1209481db06c690c2b4f488cc665f657e"
|
resolved "https://packages.deskreen.com/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz#1114a4c1209481db06c690c2b4f488cc665f657e"
|
||||||
@ -9594,6 +9946,16 @@ lodash.flattendeep@^4.4.0:
|
|||||||
resolved "https://packages.deskreen.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
resolved "https://packages.deskreen.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
||||||
integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
|
integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
|
||||||
|
|
||||||
|
lodash.get@^4.4.2:
|
||||||
|
version "4.4.2"
|
||||||
|
resolved "https://packages.deskreen.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||||
|
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
|
||||||
|
|
||||||
|
lodash.has@^4.5.2:
|
||||||
|
version "4.5.2"
|
||||||
|
resolved "https://packages.deskreen.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
|
||||||
|
integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=
|
||||||
|
|
||||||
lodash.isequal@^4.5.0:
|
lodash.isequal@^4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://packages.deskreen.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
resolved "https://packages.deskreen.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||||
@ -9604,6 +9966,11 @@ lodash.memoize@4.1.2, lodash.memoize@4.x, lodash.memoize@^4.1.2:
|
|||||||
resolved "https://packages.deskreen.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://packages.deskreen.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||||
|
|
||||||
|
lodash.set@^4.3.2:
|
||||||
|
version "4.3.2"
|
||||||
|
resolved "https://packages.deskreen.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
|
||||||
|
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
|
||||||
|
|
||||||
lodash.sortby@^4.7.0:
|
lodash.sortby@^4.7.0:
|
||||||
version "4.7.0"
|
version "4.7.0"
|
||||||
resolved "https://packages.deskreen.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
resolved "https://packages.deskreen.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||||
@ -9614,6 +9981,11 @@ lodash.uniq@^4.5.0:
|
|||||||
resolved "https://packages.deskreen.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
resolved "https://packages.deskreen.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||||
|
|
||||||
|
lodash.unset@^4.5.2:
|
||||||
|
version "4.5.2"
|
||||||
|
resolved "https://packages.deskreen.com/lodash.unset/-/lodash.unset-4.5.2.tgz#370d1d3e85b72a7e1b0cdf2d272121306f23e4ed"
|
||||||
|
integrity sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0=
|
||||||
|
|
||||||
"lodash@4.6.1 || ^4.16.1", lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5:
|
"lodash@4.6.1 || ^4.16.1", lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5:
|
||||||
version "4.17.20"
|
version "4.17.20"
|
||||||
resolved "https://packages.deskreen.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
resolved "https://packages.deskreen.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||||
@ -10193,11 +10565,6 @@ nan@^2.12.1:
|
|||||||
resolved "https://packages.deskreen.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
|
resolved "https://packages.deskreen.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
|
||||||
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
|
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
|
||||||
|
|
||||||
nanoid@^0.2.2:
|
|
||||||
version "0.2.2"
|
|
||||||
resolved "https://packages.deskreen.com/nanoid/-/nanoid-0.2.2.tgz#e2ebc6ad3db5e0454fd8124d30ca39b06555fe56"
|
|
||||||
integrity sha512-GHoRrvNEKiwdkwQ/enKL8AhQkkrBC/2KxMZkDvQzp8OtkpX8ZAmoYJWFVl7l8F2+HcEJUfdg21Ab2wXXfrvACQ==
|
|
||||||
|
|
||||||
nanoid@^1.0.1:
|
nanoid@^1.0.1:
|
||||||
version "1.3.4"
|
version "1.3.4"
|
||||||
resolved "https://packages.deskreen.com/nanoid/-/nanoid-1.3.4.tgz#ad89f62c9d1f4fd69710d4a90953d2893d2d31f4"
|
resolved "https://packages.deskreen.com/nanoid/-/nanoid-1.3.4.tgz#ad89f62c9d1f4fd69710d4a90953d2893d2d31f4"
|
||||||
@ -10208,6 +10575,11 @@ nanoid@^2.1.0, nanoid@^2.1.3:
|
|||||||
resolved "https://packages.deskreen.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
|
resolved "https://packages.deskreen.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
|
||||||
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
|
integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
|
||||||
|
|
||||||
|
nanoid@^3.1.12:
|
||||||
|
version "3.1.12"
|
||||||
|
resolved "https://packages.deskreen.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654"
|
||||||
|
integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==
|
||||||
|
|
||||||
nanomatch@^1.2.9:
|
nanomatch@^1.2.9:
|
||||||
version "1.2.13"
|
version "1.2.13"
|
||||||
resolved "https://packages.deskreen.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
resolved "https://packages.deskreen.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||||
@ -11107,16 +11479,16 @@ pinkie-promise@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
pinkie "^2.0.0"
|
pinkie "^2.0.0"
|
||||||
|
|
||||||
pinkie@1.0.0, pinkie@^1.0.0:
|
pinkie@2.0.4, pinkie@^2.0.0, pinkie@^2.0.1, pinkie@^2.0.4:
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://packages.deskreen.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4"
|
|
||||||
integrity sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=
|
|
||||||
|
|
||||||
pinkie@^2.0.0, pinkie@^2.0.1, pinkie@^2.0.4:
|
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://packages.deskreen.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
resolved "https://packages.deskreen.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||||
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
|
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
|
||||||
|
|
||||||
|
pinkie@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://packages.deskreen.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4"
|
||||||
|
integrity sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=
|
||||||
|
|
||||||
pirates@^4.0.0, pirates@^4.0.1:
|
pirates@^4.0.0, pirates@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://packages.deskreen.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
|
resolved "https://packages.deskreen.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
|
||||||
@ -11157,6 +11529,11 @@ pngjs@^3.3.1:
|
|||||||
resolved "https://packages.deskreen.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
resolved "https://packages.deskreen.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
||||||
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
||||||
|
|
||||||
|
popper.js@1.16.1-lts:
|
||||||
|
version "1.16.1-lts"
|
||||||
|
resolved "https://packages.deskreen.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05"
|
||||||
|
integrity sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==
|
||||||
|
|
||||||
popper.js@^1.14.4, popper.js@^1.16.1:
|
popper.js@^1.14.4, popper.js@^1.16.1:
|
||||||
version "1.16.1"
|
version "1.16.1"
|
||||||
resolved "https://packages.deskreen.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
resolved "https://packages.deskreen.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
||||||
@ -11655,7 +12032,7 @@ prop-types-exact@^1.2.0:
|
|||||||
object.assign "^4.1.0"
|
object.assign "^4.1.0"
|
||||||
reflect.ownkeys "^0.2.0"
|
reflect.ownkeys "^0.2.0"
|
||||||
|
|
||||||
prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||||
version "15.7.2"
|
version "15.7.2"
|
||||||
resolved "https://packages.deskreen.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
resolved "https://packages.deskreen.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||||
@ -11760,11 +12137,30 @@ q@^1.1.2:
|
|||||||
resolved "https://packages.deskreen.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
resolved "https://packages.deskreen.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||||
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
||||||
|
|
||||||
|
qr.js@0.0.0:
|
||||||
|
version "0.0.0"
|
||||||
|
resolved "https://packages.deskreen.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
|
||||||
|
integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=
|
||||||
|
|
||||||
|
qrcode-generator@^1.4.1:
|
||||||
|
version "1.4.4"
|
||||||
|
resolved "https://packages.deskreen.com/qrcode-generator/-/qrcode-generator-1.4.4.tgz#63f771224854759329a99048806a53ed278740e7"
|
||||||
|
integrity sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==
|
||||||
|
|
||||||
qrcode-terminal@^0.10.0:
|
qrcode-terminal@^0.10.0:
|
||||||
version "0.10.0"
|
version "0.10.0"
|
||||||
resolved "https://packages.deskreen.com/qrcode-terminal/-/qrcode-terminal-0.10.0.tgz#a76a48e2610a18f97fa3a2bd532b682acff86c53"
|
resolved "https://packages.deskreen.com/qrcode-terminal/-/qrcode-terminal-0.10.0.tgz#a76a48e2610a18f97fa3a2bd532b682acff86c53"
|
||||||
integrity sha1-p2pI4mEKGPl/o6K9UytoKs/4bFM=
|
integrity sha1-p2pI4mEKGPl/o6K9UytoKs/4bFM=
|
||||||
|
|
||||||
|
qrcode.react@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://packages.deskreen.com/qrcode.react/-/qrcode.react-1.0.0.tgz#7e8889db3b769e555e8eb463d4c6de221c36d5de"
|
||||||
|
integrity sha512-jBXleohRTwvGBe1ngV+62QvEZ/9IZqQivdwzo9pJM4LQMoCM2VnvNBnKdjvGnKyDZ/l0nCDgsPod19RzlPvm/Q==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.4.0"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
qr.js "0.0.0"
|
||||||
|
|
||||||
qs@6.7.0:
|
qs@6.7.0:
|
||||||
version "6.7.0"
|
version "6.7.0"
|
||||||
resolved "https://packages.deskreen.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
resolved "https://packages.deskreen.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||||
@ -11863,7 +12259,17 @@ rc@^1.2.8:
|
|||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
strip-json-comments "~2.0.1"
|
strip-json-comments "~2.0.1"
|
||||||
|
|
||||||
react-dom@^16.12.0:
|
react-awesome-reveal@^3.2.1:
|
||||||
|
version "3.2.1"
|
||||||
|
resolved "https://packages.deskreen.com/react-awesome-reveal/-/react-awesome-reveal-3.2.1.tgz#a1c3d876b666c807219c5ceb6eaa4b75a6bb16fb"
|
||||||
|
integrity sha512-/jxX6lTjVyARwOIZBth88G+5Curb9/wEjPRd3QV6FDsgEfkCwZ3z8AStR43uCDqOeKlJq5d5Hzm4dLoXt0Lb6g==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/core" "^10.0.35"
|
||||||
|
"@emotion/styled" "^10.0.27"
|
||||||
|
react-intersection-observer "^8.27.1"
|
||||||
|
react-is "^16.13.1"
|
||||||
|
|
||||||
|
react-dom@^16.12.0, react-dom@^16.4.1:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://packages.deskreen.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
|
resolved "https://packages.deskreen.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
|
||||||
integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==
|
integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==
|
||||||
@ -11903,7 +12309,12 @@ react-i18next@^11.7.0:
|
|||||||
"@babel/runtime" "^7.3.1"
|
"@babel/runtime" "^7.3.1"
|
||||||
html-parse-stringify2 "2.0.1"
|
html-parse-stringify2 "2.0.1"
|
||||||
|
|
||||||
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0:
|
react-intersection-observer@^8.27.1:
|
||||||
|
version "8.28.2"
|
||||||
|
resolved "https://packages.deskreen.com/react-intersection-observer/-/react-intersection-observer-8.28.2.tgz#6504423575905bb9312be6ff0d22e7bbc78af63f"
|
||||||
|
integrity sha512-JzyBn3QylXSJmM7P9dxxAioC4F3xHt4Uc3A6ZBXY27PeSNFraqnsd9jBdo7LJOMtzeXxyfJ6rYdDTl35LQ5TnQ==
|
||||||
|
|
||||||
|
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://packages.deskreen.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://packages.deskreen.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
@ -11926,6 +12337,16 @@ react-popper@^1.3.7:
|
|||||||
typed-styles "^0.0.7"
|
typed-styles "^0.0.7"
|
||||||
warning "^4.0.2"
|
warning "^4.0.2"
|
||||||
|
|
||||||
|
react-qrcode-logo@^2.2.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://packages.deskreen.com/react-qrcode-logo/-/react-qrcode-logo-2.2.1.tgz#c409a1a37bc8eb76ef10343ff2e6f00b94facac8"
|
||||||
|
integrity sha512-eXFSJW8HVPMT2ea4pLkbG8apHJ/aIPpQ4kX0HmsSm0wN+K+bleRNgElbjIPS4G7n0lxcA7N6pw+KAxMWPJFoqA==
|
||||||
|
dependencies:
|
||||||
|
lodash.isequal "^4.5.0"
|
||||||
|
qrcode-generator "^1.4.1"
|
||||||
|
react "^16.4.1"
|
||||||
|
react-dom "^16.4.1"
|
||||||
|
|
||||||
react-redux@^7.2.0:
|
react-redux@^7.2.0:
|
||||||
version "7.2.1"
|
version "7.2.1"
|
||||||
resolved "https://packages.deskreen.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985"
|
resolved "https://packages.deskreen.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985"
|
||||||
@ -11937,6 +12358,13 @@ react-redux@^7.2.0:
|
|||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
react-is "^16.9.0"
|
react-is "^16.9.0"
|
||||||
|
|
||||||
|
react-reveal@^1.2.2:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://packages.deskreen.com/react-reveal/-/react-reveal-1.2.2.tgz#f47fbc44debc4c185ae2163a215a9e822c7adfef"
|
||||||
|
integrity sha512-JCv3fAoU6Z+Lcd8U48bwzm4pMZ79qsedSXYwpwt6lJNtj/v5nKJYZZbw3yhaQPPgYePo3Y0NOCoYOq/jcsisuw==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.5.10"
|
||||||
|
|
||||||
react-router-dom@^5.2.0:
|
react-router-dom@^5.2.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://packages.deskreen.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
|
resolved "https://packages.deskreen.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
|
||||||
@ -11976,6 +12404,23 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0:
|
|||||||
react-is "^16.8.6"
|
react-is "^16.8.6"
|
||||||
scheduler "^0.19.1"
|
scheduler "^0.19.1"
|
||||||
|
|
||||||
|
react-toast-notifications@^2.4.0:
|
||||||
|
version "2.4.0"
|
||||||
|
resolved "https://packages.deskreen.com/react-toast-notifications/-/react-toast-notifications-2.4.0.tgz#6213730bd1fe158fc01aeef200687ea94c5c5b24"
|
||||||
|
integrity sha512-8tkrbNh7LxkiFmtqAL/AiI55efIeI+fBk3c6ImsiZ0VObb4yvOq0cqYuJHyUiv9fuD2aBxvXGVH+n4Snt8qoWA==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/core" "^10.0.14"
|
||||||
|
react-transition-group "^4.3.0"
|
||||||
|
|
||||||
|
react-toastify@*, react-toastify@^6.0.8:
|
||||||
|
version "6.0.8"
|
||||||
|
resolved "https://packages.deskreen.com/react-toastify/-/react-toastify-6.0.8.tgz#84625d81d0fd01902a7f4c6f317eb074cb3bba67"
|
||||||
|
integrity sha512-NSqCNwv+C4IfR+c92PFZiNyeBwOJvigrP2bcRi2f6Hg3WqcHhEHOknbSQOs9QDFuqUjmK3SOrdvScQ3z63ifXg==
|
||||||
|
dependencies:
|
||||||
|
classnames "^2.2.6"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
react-transition-group "^4.4.1"
|
||||||
|
|
||||||
react-transition-group@^2.9.0:
|
react-transition-group@^2.9.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://packages.deskreen.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
resolved "https://packages.deskreen.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
||||||
@ -11986,7 +12431,17 @@ react-transition-group@^2.9.0:
|
|||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
react-lifecycles-compat "^3.0.4"
|
react-lifecycles-compat "^3.0.4"
|
||||||
|
|
||||||
react@^16.13.1:
|
react-transition-group@^4.3.0, react-transition-group@^4.4.0, react-transition-group@^4.4.1:
|
||||||
|
version "4.4.1"
|
||||||
|
resolved "https://packages.deskreen.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
|
||||||
|
integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.5.5"
|
||||||
|
dom-helpers "^5.0.1"
|
||||||
|
loose-envify "^1.4.0"
|
||||||
|
prop-types "^15.6.2"
|
||||||
|
|
||||||
|
react@^16.13.1, react@^16.4.1:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://packages.deskreen.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
resolved "https://packages.deskreen.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
||||||
integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
|
integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
|
||||||
@ -13864,10 +14319,10 @@ testcafe-browser-tools@2.0.13:
|
|||||||
read-file-relative "^1.2.0"
|
read-file-relative "^1.2.0"
|
||||||
which-promise "^1.0.0"
|
which-promise "^1.0.0"
|
||||||
|
|
||||||
testcafe-hammerhead@17.1.13:
|
testcafe-hammerhead@17.1.15:
|
||||||
version "17.1.13"
|
version "17.1.15"
|
||||||
resolved "https://packages.deskreen.com/testcafe-hammerhead/-/testcafe-hammerhead-17.1.13.tgz#e2ab9589e48aa145fa886c2303891e9e997d33fa"
|
resolved "https://packages.deskreen.com/testcafe-hammerhead/-/testcafe-hammerhead-17.1.15.tgz#2855db1d795f598ee331eda4ff7b0ca0309255d9"
|
||||||
integrity sha512-swNsC4gbs1vhKM9F9zmCcStA8oMg2FUTJZYUE30xL5ZdHae87x2tfg9T58jUcZK3CX0S9B2NCU1AJbwCsS0uqw==
|
integrity sha512-FvuaODbFUkoqyzH0OapiMO3/ISCB/v+0kKi0+5DhcIz1tRBishzyfLbHFyKXUf6rm0IhGJlME93uKFOM9NNOMw==
|
||||||
dependencies:
|
dependencies:
|
||||||
acorn-hammerhead "^0.3.0"
|
acorn-hammerhead "^0.3.0"
|
||||||
asar "^2.0.1"
|
asar "^2.0.1"
|
||||||
@ -13884,10 +14339,10 @@ testcafe-hammerhead@17.1.13:
|
|||||||
merge-stream "^1.0.1"
|
merge-stream "^1.0.1"
|
||||||
mime "~1.4.1"
|
mime "~1.4.1"
|
||||||
mustache "^2.1.1"
|
mustache "^2.1.1"
|
||||||
nanoid "^0.2.2"
|
nanoid "^3.1.12"
|
||||||
os-family "^1.0.0"
|
os-family "^1.0.0"
|
||||||
parse5 "2.2.3"
|
parse5 "2.2.3"
|
||||||
pinkie "1.0.0"
|
pinkie "2.0.4"
|
||||||
read-file-relative "^1.2.0"
|
read-file-relative "^1.2.0"
|
||||||
semver "5.5.0"
|
semver "5.5.0"
|
||||||
tough-cookie "2.3.3"
|
tough-cookie "2.3.3"
|
||||||
@ -13943,10 +14398,10 @@ testcafe-reporter-xunit@^2.1.0:
|
|||||||
resolved "https://packages.deskreen.com/testcafe-reporter-xunit/-/testcafe-reporter-xunit-2.1.0.tgz#e6d66c572ce15af266706af0fd610b2a841dd443"
|
resolved "https://packages.deskreen.com/testcafe-reporter-xunit/-/testcafe-reporter-xunit-2.1.0.tgz#e6d66c572ce15af266706af0fd610b2a841dd443"
|
||||||
integrity sha1-5tZsVyzhWvJmcGrw/WELKoQd1EM=
|
integrity sha1-5tZsVyzhWvJmcGrw/WELKoQd1EM=
|
||||||
|
|
||||||
testcafe@^1.8.8:
|
testcafe@^1.9.2:
|
||||||
version "1.9.1"
|
version "1.9.2"
|
||||||
resolved "https://packages.deskreen.com/testcafe/-/testcafe-1.9.1.tgz#2e3183d69561bf90da611408436c5b34b22f799c"
|
resolved "https://packages.deskreen.com/testcafe/-/testcafe-1.9.2.tgz#35f3603bdc5241033eda9ad55d600d8c005a2801"
|
||||||
integrity sha512-18yGuCJvcdaGFhS3l4NhDwRnvJ24/mwXVfM+gqZm6vxNdw2NCujzXh36/BNr0qP2MhAEN56Y96G8XKkzn+5zYg==
|
integrity sha512-85du0zDvzFWleVqRTTsAr8Lo+3gn4yETs9qFZBIEufk6oN1fLzgv6Q14GeaH3/IaKi+/smv55umTce/OXX0mbA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "^10.12.19"
|
"@types/node" "^10.12.19"
|
||||||
async-exit-hook "^1.1.2"
|
async-exit-hook "^1.1.2"
|
||||||
@ -13977,6 +14432,7 @@ testcafe@^1.8.8:
|
|||||||
emittery "^0.4.1"
|
emittery "^0.4.1"
|
||||||
endpoint-utils "^1.0.2"
|
endpoint-utils "^1.0.2"
|
||||||
error-stack-parser "^1.3.6"
|
error-stack-parser "^1.3.6"
|
||||||
|
execa "^4.0.3"
|
||||||
globby "^9.2.0"
|
globby "^9.2.0"
|
||||||
graceful-fs "^4.1.11"
|
graceful-fs "^4.1.11"
|
||||||
graphlib "^2.1.5"
|
graphlib "^2.1.5"
|
||||||
@ -14012,7 +14468,7 @@ testcafe@^1.8.8:
|
|||||||
source-map-support "^0.5.16"
|
source-map-support "^0.5.16"
|
||||||
strip-bom "^2.0.0"
|
strip-bom "^2.0.0"
|
||||||
testcafe-browser-tools "2.0.13"
|
testcafe-browser-tools "2.0.13"
|
||||||
testcafe-hammerhead "17.1.13"
|
testcafe-hammerhead "17.1.15"
|
||||||
testcafe-legacy-api "4.0.0"
|
testcafe-legacy-api "4.0.0"
|
||||||
testcafe-reporter-json "^2.1.0"
|
testcafe-reporter-json "^2.1.0"
|
||||||
testcafe-reporter-list "^2.1.0"
|
testcafe-reporter-list "^2.1.0"
|
||||||
@ -14079,7 +14535,7 @@ tiny-invariant@^1.0.2:
|
|||||||
resolved "https://packages.deskreen.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
|
resolved "https://packages.deskreen.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
|
||||||
integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
|
integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
|
||||||
|
|
||||||
tiny-warning@^1.0.0, tiny-warning@^1.0.3:
|
tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://packages.deskreen.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
resolved "https://packages.deskreen.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
||||||
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
|
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
|
||||||
|
Loading…
x
Reference in New Issue
Block a user