blob: e822fd3e524f59c76cd127bd18a329e6e5bbd25a [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
class BakuDistro extends StatefulWidget {
@override
_BakuDistroState createState() => new _BakuDistroState();
}
class _Device {
String name, description;
_Device(this.name, this.description);
}
class _BakuDistroState extends State<BakuDistro> {
_BakuDistroState() {
HostMessages.addMessageHandler('deviceOnline', _onDeviceOnline);
HostMessages.addMessageHandler('deviceOffline', _onDeviceOffline);
HostMessages.addMessageHandler('castTerminated', _onCastTerminated);
}
final Map<String, String> devices = {};
final Set<String> castTargets = new Set();
Future<String> _onDeviceOnline(final String json) async {
final Map<String, dynamic> message = JSON.decode(json);
setState(() => devices[message['name']] = message['description']);
return null;
}
Future<String> _onDeviceOffline(final String name) async {
setState(() {
devices.remove(name);
castTargets.remove(name);
}devices.remove(name));
if (castTargetName == name) {
terminateCast();
}
return null;
}
InputValue _data = InputValue.empty;
InputValue get data => _data;
void set data(final InputValue value) {
if (_data != value) {
final InputValue oldData = _data;
setState(() => _data = value);
if (castTargetName != null && oldData.text != value.text ) {
HostMessages.sendToHost('updateCast', getCastData())
.catchError(_handleCastError);
}
}
}
String getCastData() {
return JSON.encode({
'name': castTargetName,
'data': data.text
});
}
String _castTargetName;
String get castTargetName => _castTargetName;
void set castTargetName(final String value) {
if (_castTargetName != value) {
initiateCast(value);
}
}
void initiateCast(final String target) {
terminateCast();
if (target != null) {
setState(() => _castTargetName = target);
HostMessages.sendToHost('initiateCast', getCastData())
.catchError(_handleCastError);
}
}
void terminateCast() {
if (_castTargetName != null) {
HostMessages.sendToHost('terminateCast', _castTargetName);
setState(() => _castTargetName = null);
}
}
Future<String> _onCastTerminated(final String name) async {
if (castTargetName == name) {
terminateCast();
}
return null;
}
void _handleCastError(final Object e) {
terminateCast();
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text(e.toString())));
}
@override
Widget build(final BuildContext context) {
final List<_Device> sortedDevices = devices.keys.map((name) =>
new _Device(name, devices[name])).toList(growable: false);
sortedDevices.sort((a, b) => a.description.compareTo(b.description));
final List<Widget> layout = [];
if (castTargetName == null) {
final TextStyle style = Theme.of(context).textTheme.display1;
layout.add(new Padding(
padding: new EdgeInsets.all(8.0),
child: data.text.isEmpty?
new Text('No content', style:
style.copyWith(color: Theme.of(context).disabledColor)) :
new Text(data.text, style: style)
));
}
layout.add(new Input(
value: data,
labelText: 'Text content',
onChanged: (value) => data = value
));
if (castTargetName == null) {
layout.add(new MaterialList(
type: MaterialListType.oneLine,
children: sortedDevices.map((d) => new ListItem(
title: new Text(d.description),
onTap: () => castTargetName = d.name
))
));
} else {
layout.add(new RaisedButton(
child: new Text('Recall'),
onPressed: terminateCast
));
}
return new Scaffold(
appBar: new AppBar(
title: new Text('Baku Distro Example')
),
body: new Column(children: layout)
);
}
}