add some ui improvements
This commit is contained in:
parent
9690161207
commit
003e982ff8
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart';
|
import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:forui/forui.dart';
|
import 'package:forui/forui.dart';
|
||||||
@ -46,6 +47,12 @@ class _AppState extends State<AppView> {
|
|||||||
// adapterState: _adapterState,
|
// adapterState: _adapterState,
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
// only allow portrait orientations
|
||||||
|
SystemChrome.setPreferredOrientations([
|
||||||
|
DeviceOrientation.portraitUp,
|
||||||
|
DeviceOrientation.portraitDown,
|
||||||
|
]);
|
||||||
|
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
title: 'Xiao Pet Tracker',
|
title: 'Xiao Pet Tracker',
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "2:1642885530071590702",
|
"id": "2:1642885530071590702",
|
||||||
"lastPropertyId": "3:4134744801341910087",
|
"lastPropertyId": "4:5477306218303066701",
|
||||||
"name": "CaptureBox",
|
"name": "CaptureBox",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
@ -87,6 +87,11 @@
|
|||||||
"id": "3:4134744801341910087",
|
"id": "3:4134744801341910087",
|
||||||
"name": "uuid",
|
"name": "uuid",
|
||||||
"type": 9
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4:5477306218303066701",
|
||||||
|
"name": "startTime",
|
||||||
|
"type": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relations": []
|
"relations": []
|
||||||
|
@ -87,7 +87,7 @@ final _entities = <obx_int.ModelEntity>[
|
|||||||
obx_int.ModelEntity(
|
obx_int.ModelEntity(
|
||||||
id: const obx_int.IdUid(2, 1642885530071590702),
|
id: const obx_int.IdUid(2, 1642885530071590702),
|
||||||
name: 'CaptureBox',
|
name: 'CaptureBox',
|
||||||
lastPropertyId: const obx_int.IdUid(3, 4134744801341910087),
|
lastPropertyId: const obx_int.IdUid(4, 5477306218303066701),
|
||||||
flags: 0,
|
flags: 0,
|
||||||
properties: <obx_int.ModelProperty>[
|
properties: <obx_int.ModelProperty>[
|
||||||
obx_int.ModelProperty(
|
obx_int.ModelProperty(
|
||||||
@ -104,6 +104,11 @@ final _entities = <obx_int.ModelEntity>[
|
|||||||
id: const obx_int.IdUid(3, 4134744801341910087),
|
id: const obx_int.IdUid(3, 4134744801341910087),
|
||||||
name: 'uuid',
|
name: 'uuid',
|
||||||
type: 9,
|
type: 9,
|
||||||
|
flags: 0),
|
||||||
|
obx_int.ModelProperty(
|
||||||
|
id: const obx_int.IdUid(4, 5477306218303066701),
|
||||||
|
name: 'startTime',
|
||||||
|
type: 10,
|
||||||
flags: 0)
|
flags: 0)
|
||||||
],
|
],
|
||||||
relations: <obx_int.ModelRelation>[],
|
relations: <obx_int.ModelRelation>[],
|
||||||
@ -252,10 +257,11 @@ obx_int.ModelDefinition getObjectBoxModel() {
|
|||||||
objectToFB: (CaptureBox object, fb.Builder fbb) {
|
objectToFB: (CaptureBox object, fb.Builder fbb) {
|
||||||
final typeOffset = fbb.writeString(object.type);
|
final typeOffset = fbb.writeString(object.type);
|
||||||
final uuidOffset = fbb.writeString(object.uuid);
|
final uuidOffset = fbb.writeString(object.uuid);
|
||||||
fbb.startTable(4);
|
fbb.startTable(5);
|
||||||
fbb.addInt64(0, object.id);
|
fbb.addInt64(0, object.id);
|
||||||
fbb.addOffset(1, typeOffset);
|
fbb.addOffset(1, typeOffset);
|
||||||
fbb.addOffset(2, uuidOffset);
|
fbb.addOffset(2, uuidOffset);
|
||||||
|
fbb.addInt64(3, object.startTime.millisecondsSinceEpoch);
|
||||||
fbb.finish(fbb.endTable());
|
fbb.finish(fbb.endTable());
|
||||||
return object.id;
|
return object.id;
|
||||||
},
|
},
|
||||||
@ -266,7 +272,10 @@ obx_int.ModelDefinition getObjectBoxModel() {
|
|||||||
.vTableGet(buffer, rootOffset, 6, '');
|
.vTableGet(buffer, rootOffset, 6, '');
|
||||||
final uuidParam = const fb.StringReader(asciiOptimization: true)
|
final uuidParam = const fb.StringReader(asciiOptimization: true)
|
||||||
.vTableGet(buffer, rootOffset, 8, '');
|
.vTableGet(buffer, rootOffset, 8, '');
|
||||||
final object = CaptureBox(type: typeParam, uuid: uuidParam)
|
final startTimeParam = DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0));
|
||||||
|
final object = CaptureBox(
|
||||||
|
type: typeParam, uuid: uuidParam, startTime: startTimeParam)
|
||||||
..id = const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0);
|
..id = const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0);
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
@ -336,4 +345,8 @@ class CaptureBox_ {
|
|||||||
/// See [CaptureBox.uuid].
|
/// See [CaptureBox.uuid].
|
||||||
static final uuid =
|
static final uuid =
|
||||||
obx.QueryStringProperty<CaptureBox>(_entities[1].properties[2]);
|
obx.QueryStringProperty<CaptureBox>(_entities[1].properties[2]);
|
||||||
|
|
||||||
|
/// See [CaptureBox.startTime].
|
||||||
|
static final startTime =
|
||||||
|
obx.QueryDateProperty<CaptureBox>(_entities[1].properties[3]);
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,9 @@ import 'package:csv/csv.dart';
|
|||||||
import 'package:ditredi/ditredi.dart';
|
import 'package:ditredi/ditredi.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:ditredi/ditredi.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
import 'package:xiao_pet_tracker/xiao_connector/cubit/xiao_connector_cubit.dart';
|
import 'package:xiao_pet_tracker/xiao_connector/cubit/xiao_connector_cubit.dart';
|
||||||
import 'package:xiao_pet_tracker/xiao_connector/models/capture_point.dart';
|
import 'package:xiao_pet_tracker/xiao_connector/models/capture_point.dart';
|
||||||
@ -31,8 +30,11 @@ class RecordingsDetailsPage extends StatefulWidget {
|
|||||||
class _RecordingsDetailsPageState extends State<RecordingsDetailsPage> {
|
class _RecordingsDetailsPageState extends State<RecordingsDetailsPage> {
|
||||||
final _controllerRotation = DiTreDiController();
|
final _controllerRotation = DiTreDiController();
|
||||||
final _controllerAcceleration = DiTreDiController();
|
final _controllerAcceleration = DiTreDiController();
|
||||||
|
final f = DateFormat('hh:mm:ss.SSS');
|
||||||
List<CapturePoint> _capturePoints = [];
|
List<CapturePoint> _capturePoints = [];
|
||||||
|
|
||||||
|
bool isStoringCSV = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_capturePoints =
|
_capturePoints =
|
||||||
@ -54,10 +56,10 @@ class _RecordingsDetailsPageState extends State<RecordingsDetailsPage> {
|
|||||||
height: 16,
|
height: 16,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'Capture Start Time: ${DateTime.fromMillisecondsSinceEpoch(_capturePoints.first.millisecondsSinceEpochSend)}',
|
'Start Time: ${f.format(DateTime.fromMillisecondsSinceEpoch(_capturePoints.first.millisecondsSinceEpochSend))}',
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'Capture End Time: ${DateTime.fromMillisecondsSinceEpoch(_capturePoints.first.millisecondsSinceEpochSend)}',
|
'End Time: ${f.format(DateTime.fromMillisecondsSinceEpoch(_capturePoints.last.millisecondsSinceEpochSend))}',
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8,
|
height: 8,
|
||||||
@ -66,50 +68,68 @@ class _RecordingsDetailsPageState extends State<RecordingsDetailsPage> {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 16,
|
height: 16,
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
if (isStoringCSV)
|
||||||
onPressed: () async {
|
const CircularProgressIndicator()
|
||||||
// await Permission.storage.request();
|
else
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
setState(() {
|
||||||
|
isStoringCSV = true;
|
||||||
|
});
|
||||||
|
// await Permission.storage.request();
|
||||||
|
|
||||||
final Directory? downloadsDir = (Platform.isIOS)
|
final Directory? downloadsDir = (Platform.isIOS)
|
||||||
? await getApplicationDocumentsDirectory()
|
? await getApplicationDocumentsDirectory()
|
||||||
: await getDownloadsDirectory();
|
: await getDownloadsDirectory();
|
||||||
|
|
||||||
File f = File(
|
File f = File(downloadsDir!.path +
|
||||||
downloadsDir!.path + "/${widget.type}_${widget.uuid}.csv");
|
"/${widget.type}_${widget.uuid}.csv");
|
||||||
|
|
||||||
List<List<dynamic>> rows = [];
|
List<List<dynamic>> rows = [];
|
||||||
|
|
||||||
List<dynamic> row = [];
|
|
||||||
row.add('sendTimeStamp');
|
|
||||||
row.add('receivedTimeStamp');
|
|
||||||
row.add('accelerationX');
|
|
||||||
row.add('accelerationY');
|
|
||||||
row.add('accelerationZ');
|
|
||||||
row.add('rotationX');
|
|
||||||
row.add('rotationY');
|
|
||||||
row.add('rotationZ');
|
|
||||||
|
|
||||||
rows.add(row);
|
|
||||||
|
|
||||||
for (var i = 0; i < _capturePoints.length; i++) {
|
|
||||||
List<dynamic> row = [];
|
List<dynamic> row = [];
|
||||||
row.add(_capturePoints[i].millisecondsSinceEpochSend);
|
row.add('sendTimeStamp');
|
||||||
row.add(_capturePoints[i].millisecondsSinceEpochReceived);
|
row.add('receivedTimeStamp');
|
||||||
row.add(_capturePoints[i].accelerationX);
|
row.add('accelerationX');
|
||||||
row.add(_capturePoints[i].accelerationY);
|
row.add('accelerationY');
|
||||||
row.add(_capturePoints[i].accelerationZ);
|
row.add('accelerationZ');
|
||||||
row.add(_capturePoints[i].rotationX);
|
row.add('rotationX');
|
||||||
row.add(_capturePoints[i].rotationY);
|
row.add('rotationY');
|
||||||
row.add(_capturePoints[i].rotationZ);
|
row.add('rotationZ');
|
||||||
|
|
||||||
rows.add(row);
|
rows.add(row);
|
||||||
}
|
|
||||||
|
|
||||||
String csv = const ListToCsvConverter().convert(rows);
|
for (var i = 0; i < _capturePoints.length; i++) {
|
||||||
|
List<dynamic> row = [];
|
||||||
|
row.add(_capturePoints[i].millisecondsSinceEpochSend);
|
||||||
|
row.add(_capturePoints[i].millisecondsSinceEpochReceived);
|
||||||
|
row.add(_capturePoints[i].accelerationX);
|
||||||
|
row.add(_capturePoints[i].accelerationY);
|
||||||
|
row.add(_capturePoints[i].accelerationZ);
|
||||||
|
row.add(_capturePoints[i].rotationX);
|
||||||
|
row.add(_capturePoints[i].rotationY);
|
||||||
|
row.add(_capturePoints[i].rotationZ);
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
|
||||||
f.writeAsString(csv);
|
String csv = const ListToCsvConverter().convert(rows);
|
||||||
},
|
|
||||||
child: const Text('Export to CSV'),
|
f.writeAsString(csv);
|
||||||
),
|
setState(
|
||||||
|
() {
|
||||||
|
isStoringCSV = false;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Succesfully exported the CSV!'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Export to CSV'),
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 16,
|
height: 16,
|
||||||
),
|
),
|
||||||
|
@ -2,10 +2,10 @@ import 'package:auto_route/auto_route.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:forui/forui.dart';
|
import 'package:forui/forui.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:xiao_pet_tracker/app_router/app_router.gr.dart';
|
import 'package:xiao_pet_tracker/app_router/app_router.gr.dart';
|
||||||
import 'package:xiao_pet_tracker/xiao_connector/cubit/xiao_connector_cubit.dart';
|
import 'package:xiao_pet_tracker/xiao_connector/cubit/xiao_connector_cubit.dart';
|
||||||
import 'package:xiao_pet_tracker/xiao_connector/models/capture_box.dart';
|
import 'package:xiao_pet_tracker/xiao_connector/models/capture_box.dart';
|
||||||
import 'package:xiao_pet_tracker/xiao_connector/view/xiao_connector_page.dart';
|
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class RecordingsPage extends StatelessWidget {
|
class RecordingsPage extends StatelessWidget {
|
||||||
@ -26,6 +26,7 @@ class RecordingsView extends StatefulWidget {
|
|||||||
|
|
||||||
class _SettingsViewState extends State<RecordingsView> {
|
class _SettingsViewState extends State<RecordingsView> {
|
||||||
List<CaptureBox> _captureBoxes = [];
|
List<CaptureBox> _captureBoxes = [];
|
||||||
|
final f = DateFormat('hh:mm - dd.MM.yyyy ');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -47,7 +48,7 @@ class _SettingsViewState extends State<RecordingsView> {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
leading: FIcon(FAssets.icons.pawPrint),
|
leading: FIcon(FAssets.icons.pawPrint),
|
||||||
title: Text('Collection Type: ${_captureBoxes[i].type}'),
|
title: Text('Collection Type: ${_captureBoxes[i].type}'),
|
||||||
subtitle: Text('Uuid: ${_captureBoxes[i].uuid}'),
|
subtitle: Text(f.format(_captureBoxes[i].startTime)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
AutoRouter.of(context).push(
|
AutoRouter.of(context).push(
|
||||||
RecordingsDetailsRoute(
|
RecordingsDetailsRoute(
|
||||||
@ -56,6 +57,38 @@ class _SettingsViewState extends State<RecordingsView> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Delete this recording?'),
|
||||||
|
content: const Text(
|
||||||
|
"Are you sure you want to delete this recording with all of it's data? This cannot be undone.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
context
|
||||||
|
.read<XiaoConnectorCubit>()
|
||||||
|
.deleteRecording(_captureBoxes[i].uuid);
|
||||||
|
_pullRefresh();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: const Text('Delete'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -228,6 +228,12 @@ class XiaoConnectorCubit extends Cubit<XiaoConnectorState> {
|
|||||||
emit(state.copyWith(status: XiaoConnectorStatus.connected));
|
emit(state.copyWith(status: XiaoConnectorStatus.connected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> disconnectDevice() async {
|
||||||
|
await device.disconnect();
|
||||||
|
_services = [];
|
||||||
|
emit(state.copyWith(status: XiaoConnectorStatus.initial));
|
||||||
|
}
|
||||||
|
|
||||||
void toggleRecording({required String captureType}) {
|
void toggleRecording({required String captureType}) {
|
||||||
isRecording = !isRecording;
|
isRecording = !isRecording;
|
||||||
if (isRecording) {
|
if (isRecording) {
|
||||||
@ -237,6 +243,7 @@ class XiaoConnectorCubit extends Cubit<XiaoConnectorState> {
|
|||||||
CaptureBox(
|
CaptureBox(
|
||||||
type: _captureType,
|
type: _captureType,
|
||||||
uuid: _uuid,
|
uuid: _uuid,
|
||||||
|
startTime: DateTime.now(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -256,6 +263,18 @@ class XiaoConnectorCubit extends Cubit<XiaoConnectorState> {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CaptureBox> getAllCaptureBoxes() => _captureBoxes.getAll();
|
void deleteRecording(String uuid) {
|
||||||
|
_capturePointsBox.query(CapturePoint_.uuid.equals(uuid)).build().remove();
|
||||||
|
_captureBoxes.query(CaptureBox_.uuid.equals(uuid)).build().remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CaptureBox> getAllCaptureBoxes() {
|
||||||
|
final query = (_captureBoxes.query()
|
||||||
|
..order(CaptureBox_.startTime, flags: Order.descending))
|
||||||
|
.build();
|
||||||
|
final boxes = query.find();
|
||||||
|
return boxes;
|
||||||
|
}
|
||||||
|
|
||||||
List<CapturePoint> getAllCapturePoints() => _capturePointsBox.getAll();
|
List<CapturePoint> getAllCapturePoints() => _capturePointsBox.getAll();
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,14 @@ class CaptureBox {
|
|||||||
CaptureBox({
|
CaptureBox({
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.uuid,
|
required this.uuid,
|
||||||
|
required this.startTime,
|
||||||
});
|
});
|
||||||
@Id()
|
@Id()
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
String type;
|
String type;
|
||||||
String uuid;
|
String uuid;
|
||||||
|
|
||||||
|
@Property(type: PropertyType.date)
|
||||||
|
DateTime startTime;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ class CapturePoint {
|
|||||||
int accelerationY;
|
int accelerationY;
|
||||||
int accelerationZ;
|
int accelerationZ;
|
||||||
|
|
||||||
// @Property(type: PropertyType.date)
|
|
||||||
int millisecondsSinceEpochReceived;
|
int millisecondsSinceEpochReceived;
|
||||||
int millisecondsSinceEpochSend;
|
int millisecondsSinceEpochSend;
|
||||||
}
|
}
|
||||||
|
@ -14,26 +14,36 @@ class ConnectedView extends StatelessWidget {
|
|||||||
title: const Text('Xiao Connector'),
|
title: const Text('Xiao Connector'),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: SingleChildScrollView(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
const Text(
|
children: [
|
||||||
'''
|
const Text(
|
||||||
You are connected to the Xiao Sense.
|
'''
|
||||||
Now you can open the live feed.''',
|
You are connected to the Xiao Sense.
|
||||||
textAlign: TextAlign.center,
|
Now you can open the live feed.''',
|
||||||
),
|
textAlign: TextAlign.center,
|
||||||
const SizedBox(
|
),
|
||||||
height: 8,
|
const SizedBox(
|
||||||
),
|
height: 48,
|
||||||
ElevatedButton(
|
),
|
||||||
onPressed: () {
|
ElevatedButton(
|
||||||
context.read<XiaoConnectorCubit>().startCapturing();
|
onPressed: () {
|
||||||
// context.read<XiaoConnectorCubit>().setCapturingOn();
|
context.read<XiaoConnectorCubit>().startCapturing();
|
||||||
},
|
},
|
||||||
child: const Text('Open Live Feed'),
|
child: const Text('Open Live Feed'),
|
||||||
),
|
),
|
||||||
],
|
const SizedBox(
|
||||||
|
height: 48,
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.read<XiaoConnectorCubit>().disconnectDevice();
|
||||||
|
},
|
||||||
|
child: const Text('Disconnect'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -5,6 +5,6 @@ class FailureView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const Text('Failure');
|
return const Text('Oops. Something bad happened! :(');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"machine"
|
"machine"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user