Start creating plug setting state
This commit is contained in:
parent
ada210206f
commit
5de0ffd37c
9 changed files with 159 additions and 121 deletions
|
@ -122,12 +122,13 @@ class CategoryWidget extends StatelessWidget {
|
||||||
return Wrap(
|
return Wrap(
|
||||||
spacing: 25,
|
spacing: 25,
|
||||||
runSpacing: 25,
|
runSpacing: 25,
|
||||||
children:
|
children: category.devices
|
||||||
category.devices.map((device) => device.create_widget()).toList(),
|
.map((device) => device.create_widget(context))
|
||||||
|
.toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Device {
|
abstract class Device {
|
||||||
Widget create_widget();
|
Widget create_widget(BuildContext context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ class DishWasher extends Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget create_widget() {
|
Widget create_widget(BuildContext context) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
import '../constants.dart';
|
import '../constants.dart';
|
||||||
|
import '../states/plug_settings.dart';
|
||||||
import 'devices.dart';
|
import 'devices.dart';
|
||||||
|
|
||||||
class Plug extends Device {
|
class Plug extends Device {
|
||||||
|
@ -44,7 +45,7 @@ class Plug extends Device {
|
||||||
this.power_draw, this.power_control);
|
this.power_draw, this.power_control);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget create_widget() {
|
Widget create_widget(BuildContext context) {
|
||||||
const double header_height = 40;
|
const double header_height = 40;
|
||||||
const double info_height = 30;
|
const double info_height = 30;
|
||||||
const double info_width = 60;
|
const double info_width = 60;
|
||||||
|
@ -78,7 +79,12 @@ class Plug extends Device {
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
Navigator.of(context).pushReplacementNamed(
|
||||||
|
'/plug_settings',
|
||||||
|
arguments: PlugSettingsArguments(
|
||||||
|
device_id, device_descriptor ?? ""));
|
||||||
|
},
|
||||||
icon: const Icon(Icons.settings)),
|
icon: const Icon(Icons.settings)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -146,42 +152,40 @@ class Plug extends Device {
|
||||||
|
|
||||||
class PlugLed extends StatefulWidget {
|
class PlugLed extends StatefulWidget {
|
||||||
final String device_id;
|
final String device_id;
|
||||||
final bool led_state;
|
bool led_state;
|
||||||
|
|
||||||
PlugLed({super.key, required this.device_id, required this.led_state});
|
PlugLed({super.key, required this.device_id, required this.led_state});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PlugLed> createState() => PlugLedState(device_id, led_state);
|
State<PlugLed> createState() => PlugLedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlugLedState extends State<PlugLed> {
|
class PlugLedState extends State<PlugLed> {
|
||||||
final String device_id;
|
String _led_state_info = "";
|
||||||
bool led_state;
|
|
||||||
String _led_state_info;
|
|
||||||
|
|
||||||
PlugLedState(this.device_id, this.led_state)
|
|
||||||
: this._led_state_info = led_state ? "On" : "Off";
|
|
||||||
|
|
||||||
void _toggle_led_state() {
|
void _toggle_led_state() {
|
||||||
String target_state;
|
String target_state;
|
||||||
|
|
||||||
if (led_state) {
|
if (widget.led_state) {
|
||||||
target_state = "off";
|
target_state = "off";
|
||||||
} else {
|
} else {
|
||||||
target_state = "on";
|
target_state = "on";
|
||||||
}
|
}
|
||||||
|
|
||||||
change_plug_state(device_id, "led", target_state).then((device_state) {
|
change_plug_state(widget.device_id, "led", target_state)
|
||||||
led_state = device_state["led"];
|
.then((device_state) {
|
||||||
|
widget.led_state = device_state["led"];
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_led_state_info = led_state ? "On" : "Off";
|
_led_state_info = widget.led_state ? "On" : "Off";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
_led_state_info = widget.led_state ? "On" : "Off";
|
||||||
|
|
||||||
return TextButton(
|
return TextButton(
|
||||||
onPressed: _toggle_led_state,
|
onPressed: _toggle_led_state,
|
||||||
child: Text(textAlign: TextAlign.center, _led_state_info));
|
child: Text(textAlign: TextAlign.center, _led_state_info));
|
||||||
|
@ -190,8 +194,8 @@ class PlugLedState extends State<PlugLed> {
|
||||||
|
|
||||||
class PlugPower extends StatefulWidget {
|
class PlugPower extends StatefulWidget {
|
||||||
final String device_id;
|
final String device_id;
|
||||||
final bool power_state;
|
bool power_state;
|
||||||
final bool power_control;
|
bool power_control;
|
||||||
|
|
||||||
PlugPower(
|
PlugPower(
|
||||||
{super.key,
|
{super.key,
|
||||||
|
@ -200,42 +204,38 @@ class PlugPower extends StatefulWidget {
|
||||||
required this.power_control});
|
required this.power_control});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PlugPower> createState() =>
|
State<PlugPower> createState() => PlugPowerState();
|
||||||
PlugPowerState(device_id, power_state, power_control);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlugPowerState extends State<PlugPower> {
|
class PlugPowerState extends State<PlugPower> {
|
||||||
final String device_id;
|
String _power_state_info = "";
|
||||||
bool power_state;
|
|
||||||
String _power_state_info;
|
|
||||||
bool power_control;
|
|
||||||
|
|
||||||
PlugPowerState(this.device_id, this.power_state, this.power_control)
|
|
||||||
: this._power_state_info = power_state ? "On" : "Off";
|
|
||||||
|
|
||||||
void _toggle_power_state() {
|
void _toggle_power_state() {
|
||||||
String target_state;
|
String target_state;
|
||||||
|
|
||||||
if (power_state) {
|
if (widget.power_state) {
|
||||||
target_state = "off";
|
target_state = "off";
|
||||||
} else {
|
} else {
|
||||||
target_state = "on";
|
target_state = "on";
|
||||||
}
|
}
|
||||||
|
|
||||||
change_plug_state(device_id, "power", target_state).then((device_state) {
|
change_plug_state(widget.device_id, "power", target_state)
|
||||||
power_state = device_state["power"];
|
.then((device_state) {
|
||||||
|
widget.power_state = device_state["power"];
|
||||||
|
|
||||||
power_control = device_state["power_draw"] < 15;
|
widget.power_control = device_state["power_draw"] < 15;
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_power_state_info = power_state ? "On" : "Off";
|
_power_state_info = widget.power_state ? "On" : "Off";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (power_control) {
|
_power_state_info = widget.power_state ? "On" : "Off";
|
||||||
|
|
||||||
|
if (widget.power_control) {
|
||||||
return TextButton(
|
return TextButton(
|
||||||
onPressed: _toggle_power_state,
|
onPressed: _toggle_power_state,
|
||||||
child: Text(textAlign: TextAlign.center, _power_state_info));
|
child: Text(textAlign: TextAlign.center, _power_state_info));
|
||||||
|
|
|
@ -9,7 +9,7 @@ class TemperatureHumidity extends Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget create_widget() {
|
Widget create_widget(BuildContext context) {
|
||||||
// TODO: implement create_widget
|
// TODO: implement create_widget
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Thermostat extends Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget create_widget() {
|
Widget create_widget(BuildContext context) {
|
||||||
// TODO: implement create_widget
|
// TODO: implement create_widget
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ class WashingMachine extends Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget create_widget() {
|
Widget create_widget(BuildContext context) {
|
||||||
// TODO: implement create_widget
|
// TODO: implement create_widget
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
|
||||||
|
|
||||||
import 'constants.dart';
|
import 'constants.dart';
|
||||||
import 'devices/devices.dart';
|
|
||||||
|
import 'states/home_page.dart';
|
||||||
|
import 'states/plug_settings.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
|
@ -21,81 +22,10 @@ class MyApp extends StatelessWidget {
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
),
|
),
|
||||||
home: const MyHomePage(title: 'Home Server'),
|
home: const MyHomePage(title: 'Home Server'),
|
||||||
);
|
routes: <String, WidgetBuilder>{
|
||||||
}
|
'/home': (BuildContext context) =>
|
||||||
}
|
const MyHomePage(title: 'Home Server'),
|
||||||
|
'/plug_settings': (BuildContext context) => const PlugSettings(),
|
||||||
class MyHomePage extends StatefulWidget {
|
|
||||||
const MyHomePage({super.key, required this.title});
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MyHomePage> createState() => _MyHomePageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
|
||||||
List<bool> expanded = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return FutureBuilder<List<Category>>(
|
|
||||||
future: Category.fetch(),
|
|
||||||
builder: (context, AsyncSnapshot<List<Category>> categories) {
|
|
||||||
if (!categories.hasData) {
|
|
||||||
return SpinKitWanderingCubes(
|
|
||||||
color: Colors.deepPurple[100],
|
|
||||||
size: 80.0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final data = categories.data!;
|
|
||||||
final category_count = data.length;
|
|
||||||
|
|
||||||
if (category_count > expanded.length) {
|
|
||||||
final int diff = category_count - expanded.length;
|
|
||||||
|
|
||||||
final List<bool> diff_list = List<bool>.filled(diff, true);
|
|
||||||
expanded.addAll(diff_list);
|
|
||||||
} else if (category_count < expanded.length) {
|
|
||||||
final int diff = expanded.length - category_count;
|
|
||||||
|
|
||||||
expanded = List<bool>.filled(diff, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
|
||||||
title: Text(widget.title),
|
|
||||||
),
|
|
||||||
body: Column(children: [
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.all(15.0),
|
|
||||||
padding: const EdgeInsets.all(15.0),
|
|
||||||
child: ExpansionPanelList(
|
|
||||||
expansionCallback: (int index, bool expand) {
|
|
||||||
setState(() {
|
|
||||||
expanded[index] = expand;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
children: data.asMap().entries.map(
|
|
||||||
(category) {
|
|
||||||
final CategoryWidget widget =
|
|
||||||
CategoryWidget(category: category.value);
|
|
||||||
|
|
||||||
return ExpansionPanel(
|
|
||||||
headerBuilder:
|
|
||||||
(BuildContext context, bool isExpanded) {
|
|
||||||
return ListTile(title: Text(widget.Name()));
|
|
||||||
},
|
|
||||||
body: widget,
|
|
||||||
isExpanded: expanded[category.key],
|
|
||||||
backgroundColor: Colors.deepPurple[100],
|
|
||||||
canTapOnHeader: true,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
).toList()))
|
|
||||||
]));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
79
frontend/lib/states/home_page.dart
Normal file
79
frontend/lib/states/home_page.dart
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
|
||||||
|
import '../devices/devices.dart';
|
||||||
|
|
||||||
|
class MyHomePage extends StatefulWidget {
|
||||||
|
const MyHomePage({super.key, required this.title});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MyHomePage> createState() => _MyHomePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
|
List<bool> expanded = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder<List<Category>>(
|
||||||
|
future: Category.fetch(),
|
||||||
|
builder: (context, AsyncSnapshot<List<Category>> categories) {
|
||||||
|
if (!categories.hasData) {
|
||||||
|
return SpinKitWanderingCubes(
|
||||||
|
color: Colors.deepPurple[100],
|
||||||
|
size: 80.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final data = categories.data!;
|
||||||
|
final category_count = data.length;
|
||||||
|
|
||||||
|
if (category_count > expanded.length) {
|
||||||
|
final int diff = category_count - expanded.length;
|
||||||
|
|
||||||
|
final List<bool> diff_list = List<bool>.filled(diff, true);
|
||||||
|
expanded.addAll(diff_list);
|
||||||
|
} else if (category_count < expanded.length) {
|
||||||
|
final int diff = expanded.length - category_count;
|
||||||
|
|
||||||
|
expanded = List<bool>.filled(diff, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||||
|
title: Text(widget.title),
|
||||||
|
),
|
||||||
|
body: Column(children: [
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.all(15.0),
|
||||||
|
padding: const EdgeInsets.all(15.0),
|
||||||
|
child: ExpansionPanelList(
|
||||||
|
expansionCallback: (int index, bool expand) {
|
||||||
|
setState(() {
|
||||||
|
expanded[index] = expand;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
children: data.asMap().entries.map(
|
||||||
|
(category) {
|
||||||
|
final CategoryWidget widget =
|
||||||
|
CategoryWidget(category: category.value);
|
||||||
|
|
||||||
|
return ExpansionPanel(
|
||||||
|
headerBuilder:
|
||||||
|
(BuildContext context, bool isExpanded) {
|
||||||
|
return ListTile(title: Text(widget.Name()));
|
||||||
|
},
|
||||||
|
body: widget,
|
||||||
|
isExpanded: expanded[category.key],
|
||||||
|
backgroundColor: Colors.deepPurple[100],
|
||||||
|
canTapOnHeader: true,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
).toList()))
|
||||||
|
]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
28
frontend/lib/states/plug_settings.dart
Normal file
28
frontend/lib/states/plug_settings.dart
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
|
||||||
|
import '../devices/devices.dart';
|
||||||
|
|
||||||
|
class PlugSettingsArguments {
|
||||||
|
final String device_id;
|
||||||
|
final String device_descriptor;
|
||||||
|
|
||||||
|
PlugSettingsArguments(this.device_id, this.device_descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlugSettings extends StatefulWidget {
|
||||||
|
const PlugSettings({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PlugSettings> createState() => _PlugSettingsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PlugSettingsState extends State<PlugSettings> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final args =
|
||||||
|
ModalRoute.of(context)!.settings.arguments! as PlugSettingsArguments;
|
||||||
|
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue