7
7
// You may not use this file except in compliance with the License.
8
8
import React , { useState , useReducer } from "react" ;
9
9
import { hot } from "react-hot-loader/root" ;
10
+ import styled from "styled-components" ;
10
11
11
12
import helpContent from "./index.help.md" ;
12
13
import { PanelToolbarInput , PanelToolbarLabel } from "webviz-core/shared/panelToolbarStyles" ;
@@ -35,6 +36,14 @@ type Props = {
35
36
datatypes : RosDatatypes ,
36
37
} ;
37
38
39
+ const SErrorText = styled . div `
40
+ flex: 1 1 auto;
41
+ display: flex;
42
+ align-items: center;
43
+ padding: 4px;
44
+ color: ${ colors . red } ;
45
+ ` ;
46
+
38
47
function Teleop ( props : Props ) {
39
48
const { config, saveConfig, capabilities } = props ;
40
49
const { topicName } = config ;
@@ -49,6 +58,10 @@ function Teleop(props: Props) {
49
58
" " : false ,
50
59
} ) ;
51
60
61
+ const isValidTopic = ( t ) => {
62
+ return t . startsWith ( "/" ) && t . length >= 3 ;
63
+ } ;
64
+
52
65
const composeTwist = ( key ) => {
53
66
const COMMANDS = {
54
67
// Map x, y, z, th here
@@ -81,12 +94,12 @@ function Teleop(props: Props) {
81
94
const handleKey = ( event ) => {
82
95
const newPressing = pressing ;
83
96
newPressing [ event . key ] = event . type === "keydown" ;
84
- if ( publisher . current ) {
97
+ if ( publisher . current && isValidTopic ( topicName ) ) {
85
98
if ( event . type === "keydown" ) {
86
99
publisher . current . publish ( composeTwist ( event . key ) ) ;
87
100
}
88
101
} else {
89
- console . error ( "Publisher not set! " ) ;
102
+ console . error ( "Publisher not set or topic name invalid " ) ;
90
103
}
91
104
setPressing ( newPressing ) ;
92
105
@@ -111,8 +124,28 @@ function Teleop(props: Props) {
111
124
112
125
const buttonColor = "#00A871" ;
113
126
114
- const canPublish = capabilities . includes ( PlayerCapabilities . advertise ) && topicName ;
115
-
127
+ const canPublish = capabilities . includes ( PlayerCapabilities . advertise ) && isValidTopic ( topicName ) ;
128
+
129
+ const renderError = ( ) => {
130
+ if ( topicName . length === 0 ) {
131
+ return (
132
+ < >
133
+ < SErrorText > Topic name can't be empty!</ SErrorText >
134
+ </ >
135
+ ) ;
136
+ } else if ( ! isValidTopic ( topicName ) ) {
137
+ return (
138
+ < >
139
+ {
140
+ < SErrorText >
141
+ Topic name "{ topicName } " is invalid (must be at least 2 characters long and start with /)
142
+ </ SErrorText >
143
+ }
144
+ </ >
145
+ ) ;
146
+ }
147
+ return < > </ > ;
148
+ } ;
116
149
const renderMenuContent = ( ) => {
117
150
return (
118
151
< >
@@ -179,6 +212,9 @@ function Teleop(props: Props) {
179
212
Stop
180
213
</ Button >
181
214
</ Flex >
215
+ < Flex row style = { { flex : "0 0 auto" , justifyContent : "center" , paddingTop : "5px" , paddingBottom : "5px" } } >
216
+ { renderError ( ) }
217
+ </ Flex >
182
218
</ Flex >
183
219
) ;
184
220
}
0 commit comments