diff --git a/app/components/App.tsx b/app/components/App.tsx
index 7dab7c3..0597ff5 100644
--- a/app/components/App.tsx
+++ b/app/components/App.tsx
@@ -1,8 +1,10 @@
import { observer } from "mobx-react";
import DevTools from "mobx-react-devtools";
import * as React from "react";
+import { Container } from "semantic-ui-react";
import { DevicesView, MessagesView } from "@app/components";
+import MessageTest from "@app/components/MessageTest";
import "@app/styles/app.css";
import "font-awesome/css/font-awesome.css";
@@ -11,11 +13,12 @@ import "semantic-ui-css/semantic.css";
class App extends React.Component {
render() {
return (
-
-
+
+
+
-
+
);
}
}
diff --git a/app/components/MessageTest.tsx b/app/components/MessageTest.tsx
new file mode 100644
index 0000000..944d79a
--- /dev/null
+++ b/app/components/MessageTest.tsx
@@ -0,0 +1,40 @@
+import * as React from "react";
+import { Button, Segment } from "semantic-ui-react";
+
+import { injectState, State } from "@app/state";
+import { getRandomId } from "@common/utils";
+
+class MessageTest extends React.Component<{ state: State }> {
+ render() {
+ return (
+
+ Message Test
+
+
+
+
+ );
+ }
+
+ private test1 = () => {
+ this.props.state.uiStore.addMessage({
+ info: true, content: "Test Message! " + getRandomId(), header: "Header to test message",
+ });
+ }
+
+ private test2 = () => {
+ this.props.state.uiStore.addMessage({
+ warning: true, content: "Im gonna dissapear in 5 seconds " + getRandomId(),
+ header: "Header to test message", timeout: 5000,
+ });
+ }
+
+ private test3 = () => {
+ this.props.state.uiStore.addMessage({
+ color: "brown", content: I Have crazy content!
,
+ header: "Header to test message", timeout: 5000,
+ });
+ }
+}
+
+export default injectState(MessageTest);
diff --git a/app/components/MessagesView.tsx b/app/components/MessagesView.tsx
index ee2027a..1c3d889 100644
--- a/app/components/MessagesView.tsx
+++ b/app/components/MessagesView.tsx
@@ -1,3 +1,4 @@
+import * as classNames from "classnames";
import { observer } from "mobx-react";
import * as React from "react";
import { Message, MessageProps, TransitionGroup } from "semantic-ui-react";
@@ -8,36 +9,39 @@ import { injectState, State, UiMessage, UiStore } from "@app/state/";
class MessageView extends React.Component<{
uiStore: UiStore,
message: UiMessage,
- index: number,
+ className?: string,
}> {
render() {
const { id, ...messageProps } = this.props.message;
+ const className = classNames(messageProps.className, this.props.className);
return (
);
}
private dismiss: MessageProps["onDismiss"] = (event, data) => {
- const { uiStore, index } = this.props;
- uiStore.messages.splice(index, 1);
- if (this.props.message.onDismiss) {
- this.props.message.onDismiss(event, data);
+ const { uiStore, message } = this.props;
+ if (message.onDismiss) {
+ message.onDismiss(event, data);
}
+ uiStore.messages.remove(message);
}
}
class MessagesView extends React.Component<{ state: State }> {
render() {
const { uiStore } = this.props.state;
- const messages = uiStore.messages.map((message, index) => (
-
+ const messages = uiStore.messages.map((message) => (
+
));
+ messages.reverse();
return (
-
+
{messages}
);
diff --git a/app/state/ui.ts b/app/state/ui.ts
index 7a5a067..f0ce428 100644
--- a/app/state/ui.ts
+++ b/app/state/ui.ts
@@ -7,13 +7,22 @@ export interface UiMessage extends MessageProps {
id: number;
}
+export interface UiMessageProps extends MessageProps {
+ timeout?: number;
+}
+
export class UiStore {
messages: IObservableArray = observable.array();
- addMessage(message: MessageProps) {
- this.messages.push(observable({
- ...message,
+ addMessage(message: UiMessageProps) {
+ const { timeout, ...otherProps } = message;
+ const msg = observable({
+ ...otherProps,
id: getRandomId(),
- }));
+ });
+ this.messages.push(msg);
+ if (timeout) {
+ setTimeout(() => this.messages.remove(msg), timeout);
+ }
}
}
diff --git a/app/styles/app.css b/app/styles/app.css
index fafee8b..a412bc9 100644
--- a/app/styles/app.css
+++ b/app/styles/app.css
@@ -1,7 +1,7 @@
.device--connectionState {
- margin-left: 10px;
- font-size: 18px;
- font-weight: 100;
+ margin-left: .75em;
+ font-size: .75em;
+ font-weight: lighter;
}
.device--connectionState-connected {
@@ -14,12 +14,12 @@
.section--number,
.program--number {
- width: 20px
+ width: 2em
}
.section--name /*,
.program--name*/ {
- width: 150px;
+ width: 10em;
white-space: nowrap;
}
@@ -37,13 +37,16 @@
.durationInput--minutes > input,
.durationInput--seconds > input {
- width: 70px !important;
+ width: 6em !important;
}
.messages {
position: fixed;
- top: 12px;
- left: 12px;
- right: 12px;
+ /* top: 12px; */
+ bottom: 1em;
+ left: 1em;
+ right: 1em;
z-index: 1000;
+ display: flex;
+ flex-direction: column;
}
\ No newline at end of file
diff --git a/package.json b/package.json
index 06b9722..cbbf4e7 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,6 @@
"@types/react-dom": "^15.5.0",
"@types/react-fontawesome": "^1.5.0",
"@types/react-hot-loader": "^3.0.4",
- "@types/react-transition-group": "^1.1.1",
"@types/webpack-hot-middleware": "^2.16.0",
"classnames": "^2.2.5",
"core-js": "^2.4.1",
@@ -49,10 +48,9 @@
"object-assign": "^4.1.1",
"paho-mqtt": "^1.0.3",
"prop-types": "^15.5.10",
- "react": ">=16.0.0-beta.5 <17",
- "react-dom": ">=16.0.0-beta.5 <17",
+ "react": ">=15.6.1 <16",
+ "react-dom": ">=15.6.1 <16",
"react-fontawesome": "^1.6.1",
- "react-transition-group": "^1.2.0",
"semantic-ui-css": "^2.2.10",
"semantic-ui-react": "^0.72.0",
"webpack-hot-middleware": "^2.19.1",
diff --git a/server/index.ts b/server/index.ts
index 005c4b0..1a7fafc 100644
--- a/server/index.ts
+++ b/server/index.ts
@@ -1,7 +1,11 @@
+import { Server } from "http";
import app from "./app";
+const server = new Server(app);
+
const port = +(process.env.PORT || 8080);
const host = process.env.HOST || "0.0.0.0";
-app.listen(port, host, () => {
+
+server.listen(port, host, () => {
console.log(`listening at ${host}:${port}`);
});
diff --git a/yarn.lock b/yarn.lock
index e1d75b7..dee032d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -71,12 +71,6 @@
dependencies:
"@types/react" "*"
-"@types/react-transition-group@^1.1.1":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-1.1.2.tgz#a349e70788a6dc723a5f439217011ef926c27b4f"
- dependencies:
- "@types/react" "*"
-
"@types/react@*", "@types/react@^16":
version "16.0.5"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.5.tgz#d713cf67cc211dea20463d2a0b66005c22070c4b"
@@ -710,10 +704,6 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
-chain-function@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
-
chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -971,6 +961,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+create-react-class@^15.6.0:
+ version "15.6.0"
+ resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
+ dependencies:
+ fbjs "^0.8.9"
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
cross-spawn@^5.0.1, cross-spawn@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -1234,10 +1232,6 @@ dom-converter@~0.1:
dependencies:
utila "~0.3"
-dom-helpers@^3.2.0:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
-
dom-serializer@0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
@@ -3609,14 +3603,14 @@ react-deep-force-update@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.1.1.tgz#8ea4263cd6455a050b37445b3f08fd839d86e909"
-"react-dom@>=16.0.0-beta.5 <17":
- version "16.0.0-beta.5"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.0.0-beta.5.tgz#c9c2e5c059576f77b55e8c3959535d63cb1227e5"
+"react-dom@>=15.6.1 <16":
+ version "15.6.1"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.1.tgz#2cb0ed4191038e53c209eb3a79a23e2a4cf99470"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.1.0"
object-assign "^4.1.0"
- prop-types "^15.5.6"
+ prop-types "^15.5.10"
react-fontawesome@^1.6.1:
version "1.6.1"
@@ -3641,24 +3635,15 @@ react-proxy@^3.0.0-alpha.0:
dependencies:
lodash "^4.6.1"
-react-transition-group@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.0.tgz#b51fc921b0c3835a7ef7c571c79fc82c73e9204f"
- dependencies:
- chain-function "^1.0.0"
- dom-helpers "^3.2.0"
- loose-envify "^1.3.1"
- prop-types "^15.5.6"
- warning "^3.0.0"
-
-"react@>=16.0.0-beta.5 <17":
- version "16.0.0-beta.5"
- resolved "https://registry.yarnpkg.com/react/-/react-16.0.0-beta.5.tgz#b4abba9bce7db72c30633db54a148614b6574e79"
+"react@>=15.6.1 <16":
+ version "15.6.1"
+ resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
dependencies:
+ create-react-class "^15.6.0"
fbjs "^0.8.9"
loose-envify "^1.1.0"
object-assign "^4.1.0"
- prop-types "^15.5.6"
+ prop-types "^15.5.10"
read-pkg-up@^1.0.1:
version "1.0.1"
@@ -4698,12 +4683,6 @@ vm-browserify@0.0.4:
dependencies:
indexof "0.0.1"
-warning@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
- dependencies:
- loose-envify "^1.0.0"
-
watchpack@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"