Skip to content
Snippets Groups Projects
Commit c9033eaa authored by Leon Tappe's avatar Leon Tappe :fire:
Browse files

update printer pages to hold all the info

parent 73f3ac3a
No related branches found
No related tags found
No related merge requests found
import 'dart:async';
import 'package:asta_theme/asta_theme.dart';
import 'package:blocs_astaprint/auth.dart';
import 'package:blocs_astaprint/print_queue.dart';
import 'package:blocs_astaprint/printers.dart';
......@@ -5,6 +8,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart' as http;
import '/widgets/cool_card.dart';
import 'toner_indicator.dart';
class PrinterDetailsPage extends StatefulWidget {
static const routeName = '/printers/id/';
......@@ -23,6 +29,12 @@ class _PrinterDetailsPageState extends State<PrinterDetailsPage> {
Printer _printer;
bool _dirty = false;
bool _saving = false;
StreamSubscription<PrintersState> _printerListener;
StreamSubscription<PrintQueueState> _queueListener;
@override
Widget build(BuildContext context) {
return Scaffold(
......@@ -37,88 +49,376 @@ class _PrinterDetailsPageState extends State<PrinterDetailsPage> {
state.value.singleWhere((Printer printer) => printer.id == widget.printer.id);
return ListView(
children: <Widget>[
Text('Grundlegend', style: Theme.of(context).textTheme.subtitle1),
Table(
columnWidths: {0: FlexColumnWidth(3.0), 1: FlexColumnWidth(1.5)},
border: TableBorder.symmetric(inside: BorderSide(color: Colors.grey[100])),
children: <TableRow>[
TableRow(children: <Widget>[Text('ID:'), Text('${_printer.id}')]),
TableRow(children: <Widget>[
Text('Stellplatznummer:'),
Text('${_printer.deviceId}')
]),
TableRow(children: <Widget>[Text('Standort:'), Text(_printer.location)]),
TableRow(children: <Widget>[Text('IP:'), Text(_printer.ip)]),
TableRow(children: <Widget>[Text('MAC:'), Text(_printer.mac)]),
TableRow(children: <Widget>[Text('Info:'), Text(_printer.description)]),
TableRow(children: <Widget>[
Text('Münzbetrieben:'),
Text(_printer.coinOperated ? 'Ja' : 'Nein')
]),
TableRow(children: <Widget>[
Text('Kann A3:'),
Text(_printer.hasA3 ? 'Ja' : 'Nein')
]),
TableRow(children: <Widget>[
Text('Community String:'),
Text(' ${_printer.community}')
]),
CoolCard(
title: Text('Daten', style: Theme.of(context).textTheme.headline5),
actions: [
if (_saving)
const SizedBox(
width: 24.0, height: 24.0, child: CircularProgressIndicator())
else if (_dirty)
IconButton(
tooltip: 'Speichern',
onPressed: _onSaveAll,
icon: Icon(Icons.save_rounded, color: wine),
)
else
const Icon(Icons.check, color: darkGreen),
],
),
Divider(height: 16.0),
Text('Zählerstände', style: Theme.of(context).textTheme.subtitle1),
Table(
columnWidths: {0: FlexColumnWidth(3.0), 1: FlexColumnWidth(1.5)},
border: TableBorder.symmetric(inside: BorderSide(color: Colors.grey[100])),
children: <TableRow>[
TableRow(children: <Widget>[Text('Insgesamt'), Text('')]),
TableRow(children: [Text('Farbe'), Text('')]),
TableRow(children: [Text('Schwarzweiß'), Text('')]),
children: [
ListTile(
title: Text('ID'),
trailing: Text(
widget.printer.id.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
Divider(),
ListTile(
title: Text('Stellplatznummer'),
trailing: SizedBox(
width: 256.0,
child: TextFormField(
validator: (input) =>
int.tryParse(input) == null ? 'Nur Zahlen erlaubt' : null,
autovalidateMode: AutovalidateMode.onUserInteraction,
textAlign: TextAlign.end,
initialValue: _printer.deviceId.toString() ?? '',
decoration: InputDecoration(border: InputBorder.none),
onChanged: (String input) => setState(() {
_dirty = true;
_printer.deviceId = int.tryParse(input) ?? _printer.deviceId;
}),
onFieldSubmitted: (_) => _onSaveDeviceId(),
),
),
),
ListTile(
title: Text('Standort'),
trailing: SizedBox(
width: 256.0,
child: TextFormField(
textAlign: TextAlign.end,
initialValue: _printer.location ?? '',
decoration: InputDecoration(border: InputBorder.none),
onChanged: (String input) => setState(() {
_dirty = true;
_printer.location = input;
}),
onFieldSubmitted: (_) => _onSaveLocation(),
),
),
),
ListTile(
title: Text('IP-Adresse'),
trailing: SizedBox(
width: 256.0,
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (input) {
final parts = input.split('.');
if (parts.length != 4) {
return 'Eine IP muss im Format aaa.bbb.ccc.ddd vorliegen';
}
if (parts.map((e) => int.tryParse(e)).contains(null)) {
return 'Eine IP muss aus natürlichen Zahlen bestehen';
}
return null;
},
textAlign: TextAlign.end,
initialValue: _printer.ip ?? '',
decoration: InputDecoration(border: InputBorder.none),
onChanged: (String input) => setState(() {
_dirty = true;
_printer.ip = input;
}),
onFieldSubmitted: (_) => _onSaveIP(),
),
),
),
ListTile(
title: Text('MAC-Adresse'),
trailing: SizedBox(
width: 256.0,
child: TextFormField(
textAlign: TextAlign.end,
initialValue: _printer.mac ?? '',
decoration: InputDecoration(border: InputBorder.none),
onChanged: (String input) => setState(() {
_dirty = true;
_printer.mac = input;
}),
onFieldSubmitted: (_) => _onSaveMac(),
),
),
),
ListTile(
title: Text('Beschreibung'),
trailing: SizedBox(
width: 256.0,
child: TextFormField(
textAlign: TextAlign.end,
maxLines: 2,
initialValue: _printer.description ?? '',
decoration: InputDecoration(border: InputBorder.none),
onChanged: (String input) => setState(() {
_dirty = true;
_printer.description = input;
}),
onFieldSubmitted: (_) => _onSaveMac(),
),
),
),
CheckboxListTile(
title: Text('Kann A3'),
value: _printer.hasA3,
onChanged: (bool input) {
setState(() {
_dirty = true;
_printer.hasA3 = input;
});
_onSaveA3();
},
),
CheckboxListTile(
title: Text('Münzbetrieben'),
value: _printer.coinOperated,
onChanged: (bool input) {
setState(() {
_dirty = true;
_printer.coinOperated = input;
});
_onSaveCoinOperated();
},
),
Divider(),
ListTile(
title: Text('SNMP-Community String'),
trailing: SizedBox(
width: 256.0,
child: TextFormField(
textAlign: TextAlign.end,
initialValue: _printer.community ?? '',
decoration: InputDecoration(border: InputBorder.none),
onChanged: (String input) => setState(() {
_dirty = true;
_printer.community = input;
}),
onFieldSubmitted: (_) => _onSaveCommunity(),
),
),
),
CheckboxListTile(
title: Text('Toner überwachen'),
value: _printer.watchToner,
onChanged: (bool input) {
setState(() {
_dirty = true;
_printer.watchToner = input;
});
_onSaveWatchers();
},
),
CheckboxListTile(
title: Text('Papierfach 1 überwachen'),
value: _printer.watchTray1,
onChanged: (bool input) {
setState(() {
_dirty = true;
_printer.watchTray1 = input;
});
_onSaveWatchers();
},
),
CheckboxListTile(
title: Text('Papierfach 2 überwachen'),
value: _printer.watchTray2,
onChanged: (bool input) {
setState(() {
_dirty = true;
_printer.watchTray2 = input;
});
_onSaveWatchers();
},
),
CheckboxListTile(
title: Text('Papierfach 3 überwachen'),
value: _printer.watchTray3,
onChanged: (bool input) {
setState(() {
_dirty = true;
_printer.watchTray3 = input;
});
_onSaveWatchers();
},
),
ListTile(
title: Text('Überwachungsintervall'),
trailing: SizedBox(
width: 256.0,
child: TextFormField(
validator: (input) =>
int.tryParse(input) == null ? 'Nur Zahlen erlaubt' : null,
autovalidateMode: AutovalidateMode.onUserInteraction,
textAlign: TextAlign.end,
initialValue: _printer.watchInterval.toString() ?? '',
decoration:
InputDecoration(border: InputBorder.none, suffixText: 'Sekunden'),
onChanged: (String input) => setState(() {
_dirty = true;
_printer.watchInterval =
int.tryParse(input) ?? _printer.watchInterval;
}),
onFieldSubmitted: (_) => _onSaveWatcherInterval(),
),
),
),
],
),
Divider(height: 16.0),
Text('Füllstände', style: Theme.of(context).textTheme.subtitle1),
Table(
columnWidths: {0: FlexColumnWidth(3.0), 1: FlexColumnWidth(1.5)},
border: TableBorder.symmetric(inside: BorderSide(color: Colors.grey[100])),
children: <TableRow>[
TableRow(children: <Widget>[Text('Magazin 1'), Text('')]),
TableRow(children: [Text('Magazin 2'), Text('')]),
TableRow(children: [Text('Magazin 4'), Text('')]),
TableRow(children: [Text('Bypass: '), Text('')]),
CoolCard(
title: Text('Überwachung', style: Theme.of(context).textTheme.headline5),
actions: [
if (_printer.status == null || _printer.counter == null)
const SizedBox(
width: 24.0, height: 24.0, child: CircularProgressIndicator())
],
children: [
if (_printer.counter != null)
Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: Text('Zählerstände',
style: Theme.of(context).textTheme.headline6),
contentPadding: EdgeInsets.all(0.0)),
ListTile(
title: Text('Gesamt'),
trailing: Text(
_printer.counter.total.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title: Text('Schwarz-Weiß'),
trailing: Text(
_printer.counter.printBw.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title: Text('Farbe'),
trailing: Text(
(_printer.counter.printTotal - _printer.counter.printBw)
.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title: Text('Schwarz-Weiß-Kopien'),
trailing: Text(
_printer.counter.copyBw.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title: Text('Farbkopien'),
trailing: Text(
(_printer.counter.copyTotal - _printer.counter.copyBw)
.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
],
),
if (_printer.status != null)
Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title:
Text('Status', style: Theme.of(context).textTheme.headline6),
contentPadding: EdgeInsets.all(0.0)),
ListTile(
title: Text('Scanner'),
trailing: Text(
_printer.status.scan == 0 ? 'Aktiv' : 'Fehler',
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title: Text('Kopierer'),
trailing: Text(
_printer.status.copy == 0 ? 'Aktiv' : 'Fehler',
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title:
Text('Papier', style: Theme.of(context).textTheme.headline6),
contentPadding: EdgeInsets.all(0.0)),
ListTile(
title: Text('Papierfach 1'),
trailing: Text(
_printer.status.tray1.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title: Text('Papierfach 2'),
trailing: Text(
_printer.status.tray2.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title: Text('Papierfach 3'),
trailing: Text(
_printer.status.tray3.toString(),
style: Theme.of(context).textTheme.subtitle1,
)),
ListTile(
title:
Text('Toner', style: Theme.of(context).textTheme.headline6),
contentPadding: EdgeInsets.all(0.0)),
ListTile(
title: Text('Cyan'),
trailing: TonerIndicator(
value: _printer.status.tonerC,
color: Colors.cyan,
)),
ListTile(
title: Text('Magenta'),
trailing: TonerIndicator(
value: _printer.status.tonerM,
color: Colors.pink,
)),
ListTile(
title: Text('Gelb'),
trailing: TonerIndicator(
value: _printer.status.tonerY, color: Colors.yellow)),
ListTile(
title: Text('Schwarz'),
trailing: TonerIndicator(
value: _printer.status.tonerK,
color: Colors.black,
)),
],
),
],
),
Divider(height: 16.0),
Text('Warteschlange', style: Theme.of(context).textTheme.subtitle1),
BlocBuilder<PrintQueueBloc, PrintQueueState>(
bloc: printQueueBloc,
builder: (BuildContext context, PrintQueueState state) {
if (state.isResult && state.value.isNotEmpty) {
return Column(
children: state.value
.map<Widget>(
(PrintQueueTask e) => ListTile(
title: Text(e.uid),
subtitle: Text('User: ${e.userId}'),
),
)
.toList(),
);
} else if (state.isException) {
return Text(
'Fehler beim holen der Warteschlange aufgetreten (${state.error.toString()})');
} else if (state.isBusy) {
return Center(
child: CircularProgressIndicator(backgroundColor: Colors.grey));
} else {
return ListTile(title: Text('Warteschlange steht leer'));
}
},
CoolCard(
title: Text('Warteschlange', style: Theme.of(context).textTheme.headline5),
actions: [
IconButton(
onPressed: () => printQueueBloc.onRefresh(),
icon: Icon(Icons.refresh_rounded))
],
children: [
if (_printer.queue != null)
ListTile(
title: Text(_printer.queue.uid),
subtitle: Text('User: ${_printer.queue.userId}'),
)
else
ListTile(title: Text('Warteschlange steht leer')),
ElevatedButton(
child: Text('Warteschlange leeren'),
onPressed: () => _onEmptyQueue(),
)
],
),
ElevatedButton(
child: Text('Warteschlange leeren'),
onPressed: () => _onEmptyQueue(),
)
],
);
} else {
......@@ -133,7 +433,9 @@ class _PrinterDetailsPageState extends State<PrinterDetailsPage> {
@override
void dispose() {
printQueueBloc.close();
printQueueBloc?.close();
_printerListener?.cancel();
_queueListener?.cancel();
super.dispose();
}
......@@ -145,7 +447,21 @@ class _PrinterDetailsPageState extends State<PrinterDetailsPage> {
printersBloc = BlocProvider.of<PrintersBloc>(context);
printQueueBloc = PrintQueueBloc(http.Client());
printersBloc.onRefresh();
_printerListener = printersBloc.stream.listen((PrintersState state) {
setState(() {
_printer = state.value.singleWhere((Printer e) => e.deviceId == widget.printer.deviceId);
});
});
printersBloc.onRefreshPrinterById(widget.printer.deviceId);
_queueListener = printQueueBloc.stream.listen((PrintQueueState state) {
if (state.isResult && state.value.isNotEmpty) {
setState(() {
_printer.queue = state.value.first;
});
}
});
/// Initialize [PrintQueueBloc] for this specific printer and get latest data
printQueueBloc.onStart(authBloc.state.token);
......@@ -156,4 +472,24 @@ class _PrinterDetailsPageState extends State<PrinterDetailsPage> {
void _onEmptyQueue() {
printQueueBloc.onCancelJobs();
}
void _onSaveA3() {}
void _onSaveAll() {}
void _onSaveCoinOperated() {}
void _onSaveCommunity() {}
void _onSaveDeviceId() {}
void _onSaveIP() {}
void _onSaveLocation() {}
void _onSaveMac() {}
void _onSaveWatcherInterval() {}
void _onSaveWatchers() {}
}
import 'package:asta_theme/asta_theme.dart';
import 'package:flutter/material.dart';
class TonerIndicator extends StatelessWidget {
final Color color;
final int value;
final double width;
final double height;
const TonerIndicator(
{Key key, @required this.color, @required this.value, this.width = 256.0, this.height = 24.0})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: width,
height: height,
color: grey,
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.centerLeft,
child: Container(
width: (value ?? 0) / 100 * width,
color: color,
),
),
Text(
'${value ?? 0}/100',
style: Theme.of(context)
.textTheme
.subtitle1
.copyWith(color: color.computeLuminance() < 0.5 ? offWhite : Colors.black),
textAlign: TextAlign.center,
)
],
),
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment