Resolves #95: Input value validation

This commit is contained in:
estevez 2018-09-30 12:51:55 +03:00
parent 7dd8f65af7
commit 9de8a659d3
2 changed files with 56 additions and 10 deletions

View File

@ -33,6 +33,9 @@ class Entity {
double get maxValue => _attributes["max"] ?? 100.0; double get maxValue => _attributes["max"] ?? 100.0;
double get valueStep => _attributes["step"] ?? 1.0; double get valueStep => _attributes["step"] ?? 1.0;
double get doubleState => double.tryParse(_state) ?? 0.0; double get doubleState => double.tryParse(_state) ?? 0.0;
int get valueMinLength => _attributes["min"] ?? -1;
int get valueMaxLength => _attributes["max"] ?? -1;
String get valuePattern => _attributes["pattern"] ?? null;
bool get isSliderField => _attributes["mode"] == "slider"; bool get isSliderField => _attributes["mode"] == "slider";
bool get isTextField => _attributes["mode"] == "text"; bool get isTextField => _attributes["mode"] == "text";
bool get isPasswordField => _attributes["mode"] == "password"; bool get isPasswordField => _attributes["mode"] == "password";
@ -92,6 +95,10 @@ class Entity {
eventBus.fire(new ShowEntityPageEvent(this)); eventBus.fire(new ShowEntityPageEvent(this));
} }
void sendNewState(newState) {
return;
}
Widget buildWidget(bool inCard) { Widget buildWidget(bool inCard) {
return SizedBox( return SizedBox(
height: Entity.WIDGET_HEIGHT, height: Entity.WIDGET_HEIGHT,
@ -178,12 +185,17 @@ class SwitchEntity extends Entity {
SwitchEntity(Map rawData) : super(rawData); SwitchEntity(Map rawData) : super(rawData);
@override
void sendNewState(newValue) {
eventBus.fire(new ServiceCallEvent(_domain, (newValue as bool) ? "turn_on" : "turn_off", entityId, null));
}
@override @override
Widget _buildActionWidget(bool inCard) { Widget _buildActionWidget(bool inCard) {
return Switch( return Switch(
value: this.isOn, value: this.isOn,
onChanged: ((switchState) { onChanged: ((switchState) {
eventBus.fire(new ServiceCallEvent(_domain, switchState ? "turn_on" : "turn_off", entityId, null)); sendNewState(switchState);
}), }),
); );
} }
@ -194,11 +206,16 @@ class ButtonEntity extends Entity {
ButtonEntity(Map rawData) : super(rawData); ButtonEntity(Map rawData) : super(rawData);
@override
void sendNewState(newValue) {
eventBus.fire(new ServiceCallEvent(_domain, "turn_on", _entityId, null));
}
@override @override
Widget _buildActionWidget(bool inCard) { Widget _buildActionWidget(bool inCard) {
return FlatButton( return FlatButton(
onPressed: (() { onPressed: (() {
eventBus.fire(new ServiceCallEvent(_domain, "turn_on", _entityId, null)); sendNewState(null);
}), }),
child: Text( child: Text(
"EXECUTE", "EXECUTE",
@ -213,18 +230,43 @@ class ButtonEntity extends Entity {
class InputEntity extends Entity { class InputEntity extends Entity {
String tmpState; String tmpState;
FocusNode _focusNode; FocusNode _focusNode;
bool validValue = false;
InputEntity(Map rawData) : super(rawData) { InputEntity(Map rawData) : super(rawData) {
_focusNode = FocusNode(); _focusNode = FocusNode();
//TODO memory leak generator //TODO possible memory leak generator
_focusNode.addListener(_focusListener); _focusNode.addListener(_focusListener);
tmpState = state; //tmpState = state;
}
@override
void sendNewState(newValue) {
if (validate(newValue)) {
eventBus.fire(new ServiceCallEvent(_domain, "set_value", _entityId,
{"value": "${newValue.toString()}"}));
}
}
@override
void update(Map rawData) {
super.update(rawData);
tmpState = _state;
}
bool validate(newValue) {
if (newValue is String) {
//TODO add pattern support
validValue = (newValue.length >= this.valueMinLength) && (this.valueMaxLength == -1 || (newValue.length <= this.valueMaxLength));
} else {
validValue = true;
}
return validValue;
} }
void _focusListener() { void _focusListener() {
//TheLogger.log("Debug", "Focused ${_focusNode.hasFocus? 'on' : 'of'} $entityId. Old state: $state. New state: $tmpState");
if (!_focusNode.hasFocus && (tmpState != state)) { if (!_focusNode.hasFocus && (tmpState != state)) {
eventBus.fire(new ServiceCallEvent(_domain, "set_value", _entityId, {"value": "$tmpState"})); sendNewState(tmpState);
tmpState = state;
} }
} }
@ -241,10 +283,14 @@ class InputEntity extends Entity {
max: this.maxValue*10, max: this.maxValue*10,
value: (this.doubleState <= this.maxValue) && (this.doubleState >= this.minValue) ? this.doubleState*10 : this.minValue*10, value: (this.doubleState <= this.maxValue) && (this.doubleState >= this.minValue) ? this.doubleState*10 : this.minValue*10,
onChanged: (value) { onChanged: (value) {
eventBus.fire(new StateChangedEvent(_entityId, (value.roundToDouble() / 10).toString(), true)); if (validate(value.roundToDouble() / 10)) {
eventBus.fire(new StateChangedEvent(
_entityId, (value.roundToDouble() / 10).toString(),
true));
}
}, },
onChangeEnd: (value) { onChangeEnd: (value) {
eventBus.fire(new ServiceCallEvent(_domain, "set_value", _entityId,{"value": "$_state"})); sendNewState(value.roundToDouble() / 10);
}, },
), ),
), ),
@ -267,7 +313,7 @@ class InputEntity extends Entity {
child: TextField( child: TextField(
focusNode: inCard ? _focusNode : null, focusNode: inCard ? _focusNode : null,
obscureText: this.isPasswordField, obscureText: this.isPasswordField,
controller: new TextEditingController.fromValue(new TextEditingValue(text: _state,selection: new TextSelection.collapsed(offset: _state.length))), controller: new TextEditingController.fromValue(new TextEditingValue(text: tmpState,selection: new TextSelection.collapsed(offset: tmpState.length))),
onChanged: (value) { onChanged: (value) {
tmpState = value; tmpState = value;
} }

View File

@ -183,7 +183,7 @@ class HomeAssistant {
} }
void _handleEntityStateChange(Map eventData) { void _handleEntityStateChange(Map eventData) {
TheLogger.log("Debug", "Parsing new state for ${eventData['entity_id']}"); TheLogger.log("Debug", "New state for ${eventData['entity_id']}");
_entities.updateState(eventData); _entities.updateState(eventData);
eventBus.fire(new StateChangedEvent(eventData["entity_id"], null, false)); eventBus.fire(new StateChangedEvent(eventData["entity_id"], null, false));
} }