mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-10-24 17:57:54 +00:00
Implemented ceiling, wall sensors functionality
This commit is contained in:
@@ -0,0 +1,288 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ceiling_sensor_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/helpers/misc_string_helpers.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
import '../wall_sensor/wall_sensor_interface.dart';
|
||||
|
||||
class CeilingSensorInterface extends StatelessWidget {
|
||||
const CeilingSensorInterface({super.key, required this.ceilingSensor});
|
||||
final DeviceModel ceilingSensor;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// String state = ceilingSensor.status
|
||||
// .firstWhere((element) => element.code == "presence_state")
|
||||
// .value
|
||||
// .toString();
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
CeilingSensorBloc(deviceId: ceilingSensor.uuid ?? '')..add(InitialEvent()),
|
||||
child: BlocBuilder<CeilingSensorBloc, CeilingSensorState>(builder: (context, state) {
|
||||
CeilingSensorModel ceilingSensorModel =
|
||||
CeilingSensorModel(presenceState: 'none', sensitivity: 1, checkingResult: '');
|
||||
if (state is UpdateState) {
|
||||
ceilingSensorModel = state.ceilingSensorModel;
|
||||
} else if (state is LoadingNewSate) {
|
||||
ceilingSensorModel = state.ceilingSensorModel;
|
||||
}
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: BodyLarge(
|
||||
text: ceilingSensor.name ?? "",
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
body: state is LoadingInitialState
|
||||
? const Center(
|
||||
child: RefreshProgressIndicator(),
|
||||
)
|
||||
: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
padding: const EdgeInsets.all(Constants.defaultPadding),
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.assetsImagesBackground,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
const Spacer(),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
if ((ceilingSensor.isOnline ?? false) == false) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Device is offline',
|
||||
),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
String controlCode = 'sensitivity';
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => ParameterControlDialog(
|
||||
title: 'Sensitivity',
|
||||
sensor: ceilingSensor,
|
||||
controlCode: controlCode,
|
||||
value: ceilingSensor.status
|
||||
.firstWhere((element) => element.code == controlCode)
|
||||
.value as int,
|
||||
min: ceilingSensor.functions
|
||||
.firstWhere((element) => element.code == controlCode)
|
||||
.values
|
||||
?.min ??
|
||||
0,
|
||||
max: ceilingSensor.functions
|
||||
.firstWhere((element) => element.code == controlCode)
|
||||
.values
|
||||
?.max ??
|
||||
0,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
state == 'presence'
|
||||
? Assets.assetsIconsPresenceSensorAssetsPresence
|
||||
: Assets.assetsIconsPresenceSensorAssetsPresenceSensorMotion,
|
||||
width: 100,
|
||||
height: 100,
|
||||
// colorFilter: ColorFilter.mode(
|
||||
// (ceilingSensor.isOnline ?? false)
|
||||
// ? ColorsManager.primaryColor
|
||||
// : Colors.grey.withOpacity(0.9),
|
||||
// BlendMode.srcIn,
|
||||
// ),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
BodyMedium(
|
||||
text: StringHelpers.toTitleCase(ceilingSensorModel.presenceState),
|
||||
// (ceilingSensor.isOnline ?? false)
|
||||
// ? StringHelpers.toTitleCase(ceilingSensor.status
|
||||
// .firstWhere((element) =>
|
||||
// element.code == 'presence_state')
|
||||
// .value
|
||||
// .toString())
|
||||
// : "Offline",
|
||||
style: context.bodyMedium.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DefaultContainer(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 20, horizontal: 15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const BodySmall(text: 'Sports Para'),
|
||||
BodyLarge(
|
||||
text: '0',
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Container(
|
||||
width: 1,
|
||||
height: 45,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const BodySmall(text: 'Detection Range'),
|
||||
BodyLarge(
|
||||
text: '0.0M',
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Container(
|
||||
width: 1,
|
||||
height: 45,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const BodySmall(text: 'Movement'),
|
||||
BodyLarge(
|
||||
text: 'none',
|
||||
style: context.bodyLarge.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
...List.generate(
|
||||
ceilingSensorButtons.length,
|
||||
(index) => DefaultContainer(
|
||||
margin: const EdgeInsets.only(bottom: 5),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
|
||||
onTap: () {
|
||||
if (ceilingSensorButtons[index]['page'] != null) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
ceilingSensorButtons[index]['page'] as Widget,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
ceilingSensorButtons[index]['icon'] as String,
|
||||
// width: 30,
|
||||
// height: 50,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 25,
|
||||
),
|
||||
BodyMedium(
|
||||
text: ceilingSensorButtons[index]['title'] as String,
|
||||
style: context.bodyMedium.copyWith(
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var ceilingSensorButtons = [
|
||||
{
|
||||
'title': 'Parameter Settings',
|
||||
'icon': Assets.assetsIconsPresenceSensorAssetsParameterSettings,
|
||||
'page': null,
|
||||
},
|
||||
{
|
||||
'title': 'Induction History',
|
||||
'icon': Assets.assetsIconsPresenceSensorAssetsInductionRecording,
|
||||
'page': null,
|
||||
},
|
||||
{
|
||||
'title': 'Help Description',
|
||||
'icon': Assets.assetsIconsPresenceSensorAssetsHelpDescription,
|
||||
'page': null,
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,173 @@
|
||||
part of '../wall_sensor/wall_sensor_interface.dart';
|
||||
|
||||
class ParameterControlDialog extends StatefulWidget {
|
||||
final String title;
|
||||
final DeviceModel sensor;
|
||||
final int value;
|
||||
final int min;
|
||||
final int max;
|
||||
final String controlCode;
|
||||
|
||||
const ParameterControlDialog({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.sensor,
|
||||
required this.value,
|
||||
required this.min,
|
||||
required this.max,
|
||||
required this.controlCode,
|
||||
});
|
||||
|
||||
@override
|
||||
ParameterControlDialogState createState() => ParameterControlDialogState();
|
||||
}
|
||||
|
||||
class ParameterControlDialogState extends State<ParameterControlDialog> {
|
||||
late int _value;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_value = widget.value;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: widget.title,
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontsManager.extraBold,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: 50,
|
||||
),
|
||||
child: Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
),
|
||||
child: TitleMedium(
|
||||
text: _value.toString(),
|
||||
style: context.titleMedium.copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_value = (_value - 1).clamp(widget.min, widget.max);
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.remove,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
Slider(
|
||||
value: _value.toDouble(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_value = value.toInt();
|
||||
});
|
||||
},
|
||||
min: widget.min.toDouble(),
|
||||
max: widget.max.toDouble(),
|
||||
label: _value.toString(),
|
||||
inactiveColor: ColorsManager.greyColor,
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_value = (_value + 1).clamp(widget.min, widget.max);
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: 'Cancel',
|
||||
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 50,
|
||||
width: 1,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context, _value);
|
||||
if (widget.sensor.isOnline == null) {
|
||||
CustomSnackBar.displaySnackBar('The device is offline');
|
||||
return;
|
||||
}
|
||||
if (!widget.sensor.isOnline!) {
|
||||
CustomSnackBar.displaySnackBar('The device is offline');
|
||||
return;
|
||||
}
|
||||
|
||||
// DevicesCubit.getInstance().deviceControl(
|
||||
// DeviceControlModel(
|
||||
// deviceId: widget.sensor.uuid,
|
||||
// code: widget.controlCode,
|
||||
// value: widget.value),
|
||||
// widget.sensor.uuid ?? '');
|
||||
},
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: 'Confirm',
|
||||
style:
|
||||
context.bodyMedium.copyWith(color: ColorsManager.primaryColorWithOpacity),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user