Implemented ceiling, wall sensors functionality

This commit is contained in:
Abdullah Alassaf
2024-05-22 23:55:35 +03:00
parent 008ba8be32
commit 44b08c482d
26 changed files with 1296 additions and 493 deletions
@@ -6,7 +6,6 @@ import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_controls.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_temp_unit.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class AcInterface extends StatelessWidget {
const AcInterface({super.key, required this.ac});
@@ -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,
},
];
@@ -1,4 +1,4 @@
part of 'wall_sensor_interface.dart';
part of '../wall_sensor/wall_sensor_interface.dart';
class ParameterControlDialog extends StatefulWidget {
final String title;
@@ -127,8 +127,7 @@ class ParameterControlDialogState extends State<ParameterControlDialog> {
child: Center(
child: BodyMedium(
text: 'Cancel',
style: context.bodyMedium
.copyWith(color: ColorsManager.greyColor),
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
),
),
),
@@ -141,24 +140,26 @@ class ParameterControlDialogState extends State<ParameterControlDialog> {
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 ?? '');
// 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),
style:
context.bodyMedium.copyWith(color: ColorsManager.primaryColorWithOpacity),
),
),
),
@@ -1,275 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.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_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 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: 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(state),
// (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,
},
];
@@ -1,74 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_control_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/features/shared_widgets/text_widgets/title_medium.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';
part "parameters_list.dart";
part "presence_indicator.dart";
part "parameter_control_dialog.dart";
class WallMountedInterface extends StatelessWidget {
const WallMountedInterface({super.key, required this.wallSensor});
final DeviceModel wallSensor;
@override
Widget build(BuildContext context) {
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: wallSensor.name ?? "",
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
),
body: 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: [
PresenceIndicator(
wallSensor: wallSensor,
),
ParametersList(wallSensor: wallSensor),
],
),
),
),
),
);
}
}
@@ -10,8 +10,8 @@ import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/presence_sensors/wall_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/presence_sensors/ceiling_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
@@ -90,10 +90,20 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
// navigateToInterface(ACsView(deviceModel: device), context);
break;
case DeviceType.WallSensor:
navigateToInterface(WallMountedInterface(wallSensor: device), context);
// navigateToInterface(WallMountedInterface(wallSensor: device), context);
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
WallMountedInterface(deviceModel: device)));
break;
case DeviceType.CeilingSensor:
navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
CeilingSensorInterface(ceilingSensor: device)));
// navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
break;
case DeviceType.Curtain:
break;
@@ -8,56 +8,49 @@ import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class GangSwitch extends StatelessWidget {
const GangSwitch({
super.key,
required this.threeGangSwitch,
required this.value,
});
const GangSwitch(
{super.key, required this.threeGangSwitch, required this.value, required this.action});
final DeviceModel threeGangSwitch;
final bool value;
final Function action;
@override
Widget build(BuildContext context) {
return BlocBuilder<ThreeGangBloc, ThreeGangState>(
builder: (context, state) {
return InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () {
// var tempControl = DeviceControlModel(
// deviceId: control.deviceId, code: control.code!, value: !control.value!);
// DevicesCubit.getInstance().deviceControl(
// tempControl,
// control.deviceId!,
// );
},
child: Stack(
alignment: value ? Alignment.topCenter : Alignment.bottomCenter,
children: [
Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(100.0)),
color:
value ? ColorsManager.primaryColorWithOpacity : ColorsManager.switchOffColor,
),
width: 60,
height: 115,
),
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox.square(
dimension: 60,
child: SvgPicture.asset(
value ? Assets.assetsIconsLightSwitchOn : Assets.assetsIconsLightSwitchOff,
fit: BoxFit.fill,
),
),
),
],
),
);
return InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () {
action();
// var tempControl = DeviceControlModel(
// deviceId: control.deviceId, code: control.code!, value: !control.value!);
// DevicesCubit.getInstance().deviceControl(
// tempControl,
// control.deviceId!,
// );
},
child: Stack(
alignment: value ? Alignment.topCenter : Alignment.bottomCenter,
children: [
Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(100.0)),
color: value ? ColorsManager.primaryColorWithOpacity : ColorsManager.switchOffColor,
),
width: 60,
height: 115,
),
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox.square(
dimension: 60,
child: SvgPicture.asset(
value ? Assets.assetsIconsLightSwitchOn : Assets.assetsIconsLightSwitchOff,
fit: BoxFit.fill,
),
),
),
],
),
);
}
}
@@ -32,10 +32,12 @@ class ThreeGangScreen extends StatelessWidget {
firstCountDown: 0,
secondCountDown: 0,
thirdCountDown: 0);
if (state is UpdateState) {
if (state is LoadingNewSate) {
threeGangModel = state.threeGangModel;
} else if (state is UpdateState) {
threeGangModel = state.threeGangModel;
}
return state is LoadingState
return state is LoadingInitialState
? const Center(
child:
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
@@ -54,6 +56,11 @@ class ThreeGangScreen extends StatelessWidget {
GangSwitch(
threeGangSwitch: device,
value: threeGangModel.firstSwitch,
action: () {
BlocProvider.of<ThreeGangBloc>(context).add(
ChangeFirstSwitchStatusEvent(
value: threeGangModel.firstSwitch));
},
// control: DeviceControlModel(
// deviceId: device.uuid,
// // code: 'switch_1',
@@ -78,6 +85,11 @@ class ThreeGangScreen extends StatelessWidget {
GangSwitch(
threeGangSwitch: device,
value: threeGangModel.secondSwitch,
action: () {
BlocProvider.of<ThreeGangBloc>(context).add(
ChangeSecondSwitchStatusEvent(
value: threeGangModel.secondSwitch));
},
// control: DeviceControlModel(
// // deviceId: 'bfe10693d4fd263206ocq9',
// // code: 'switch_2',
@@ -103,6 +115,11 @@ class ThreeGangScreen extends StatelessWidget {
GangSwitch(
threeGangSwitch: device,
value: threeGangModel.thirdSwitch,
action: () {
BlocProvider.of<ThreeGangBloc>(context).add(
ChangeThirdSwitchStatusEvent(
value: threeGangModel.thirdSwitch));
},
),
const SizedBox(height: 20),
const SizedBox(
@@ -157,6 +174,7 @@ class ThreeGangScreen extends StatelessWidget {
// ),
// device.uuid!,
// );
BlocProvider.of<ThreeGangBloc>(context).add(AllOnEvent());
},
child: Stack(
alignment: Alignment.center,
@@ -287,6 +305,7 @@ class ThreeGangScreen extends StatelessWidget {
// ),
// device.uuid!,
// );
BlocProvider.of<ThreeGangBloc>(context).add(AllOffEvent());
},
child: Stack(
alignment: Alignment.center,
@@ -4,9 +4,11 @@ class ParametersList extends StatelessWidget {
const ParametersList({
super.key,
required this.wallSensor,
required this.presenceSensorsModel,
});
final DeviceModel wallSensor;
final WallSensorModel presenceSensorsModel;
@override
Widget build(BuildContext context) {
return Expanded(
@@ -23,41 +25,39 @@ class ParametersList extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
DefaultContainer(
padding: const EdgeInsets.symmetric(
vertical: 12, horizontal: 15),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
InkWell(
onTap: () {
onTap: () async {
if ((wallSensor.isOnline ?? false) == false) {
return;
}
String controlCode = 'motion_sensitivity_value';
showDialog(
final result = await showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Motion Detection Sensitivity',
sensor: wallSensor,
controlCode: controlCode,
value: wallSensor.status
.firstWhere((element) =>
element.code == controlCode)
.value as int,
value: presenceSensorsModel.motionSensitivity,
min: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.min ??
0,
max: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.max ??
0,
),
);
if (result != null) {
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeValueEvent(value: result, code: controlCode));
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -67,14 +67,8 @@ class ParametersList extends StatelessWidget {
text: 'Motion\nDetection\nSensitivity',
textAlign: TextAlign.center),
BodyLarge(
text: wallSensor.status
.firstWhere((element) =>
element.code ==
'motion_sensitivity_value')
.value
.toString(),
style: context.bodyLarge
.copyWith(fontWeight: FontsManager.bold),
text: presenceSensorsModel.motionSensitivity.toString(),
style: context.bodyLarge.copyWith(fontWeight: FontsManager.bold),
),
],
),
@@ -88,35 +82,35 @@ class ParametersList extends StatelessWidget {
),
),
InkWell(
onTap: () {
onTap: () async {
if ((wallSensor.isOnline ?? false) == false) {
return;
}
String controlCode = 'motionless_sensitivity';
showDialog(
final result = await showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Motionless Detection Sensitivity',
sensor: wallSensor,
controlCode: controlCode,
value: wallSensor.status
.firstWhere((element) =>
element.code == controlCode)
.value as int,
value: presenceSensorsModel.motionlessSensitivity,
min: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.min ??
0,
max: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.max ??
0,
),
);
if (result != null) {
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeValueEvent(value: result, code: controlCode));
}
},
child: Column(
mainAxisSize: MainAxisSize.min,
@@ -126,12 +120,7 @@ class ParametersList extends StatelessWidget {
text: 'Motionless\nDetection\nSensitivity',
textAlign: TextAlign.center),
BodyLarge(
text: wallSensor.status
.firstWhere((element) =>
element.code ==
'motionless_sensitivity')
.value
.toString(),
text: presenceSensorsModel.motionlessSensitivity.toString(),
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
@@ -148,46 +137,44 @@ class ParametersList extends StatelessWidget {
),
),
InkWell(
onTap: () {
onTap: () async {
if ((wallSensor.isOnline ?? false) == false) {
return;
}
String controlCode = 'far_detection';
showDialog(
final result = await showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Far Detection',
sensor: wallSensor,
controlCode: controlCode,
value: wallSensor.status
.firstWhere((element) =>
element.code == controlCode)
.value as int,
value: presenceSensorsModel.farDetection,
min: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.min ??
0,
max: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.max ??
0,
),
);
if (result != null) {
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeValueEvent(value: result, code: controlCode));
}
},
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const BodySmall(
text: 'Far\nDetection',
textAlign: TextAlign.center),
text: 'Far\nDetection', textAlign: TextAlign.center),
BodyLarge(
text:
'${wallSensor.status.firstWhere((element) => element.code == 'far_detection').value.toString()}${wallSensor.functions.firstWhere((element) => element.code == 'far_detection').values?.unit ?? ''}',
'${presenceSensorsModel.farDetection.toString()}${wallSensor.functions.firstWhere((element) => element.code == 'far_detection').values?.unit ?? ''}',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
@@ -198,11 +185,11 @@ class ParametersList extends StatelessWidget {
],
),
),
listItem(wallSensorButtons[index], context, wallSensor)
listItem(wallSensorButtons[index], context, wallSensor, presenceSensorsModel)
],
);
}
return listItem(wallSensorButtons[index], context, wallSensor);
return listItem(wallSensorButtons[index], context, wallSensor, presenceSensorsModel);
},
),
),
@@ -251,21 +238,26 @@ class ParametersList extends StatelessWidget {
];
}
Widget listItem(
Map<String, Object?> wallSensorButton,
BuildContext context,
DeviceModel wallSensor,
) {
Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, DeviceModel wallSensor,
WallSensorModel wallSensorStatus) {
String? unit;
dynamic value;
if (wallSensorButton['code'] != null) {
if (wallSensor.status
.any((element) => element.code == wallSensorButton['code'] as String)) {
// if (wallSensor.status.any((element) => element.code == wallSensorButton['code'] as String)) {
// unit = unitsMap[wallSensorButton['code'] as String];
// value = wallSensor.status
// .firstWhere((element) => element.code == wallSensorButton['code'] as String)
// .value;
// }
if (wallSensorButton['code'] == 'presence_time') {
unit = unitsMap[wallSensorButton['code'] as String];
value = wallSensor.status
.firstWhere(
(element) => element.code == wallSensorButton['code'] as String)
.value;
value = wallSensorStatus.presenceTime;
} else if (wallSensorButton['code'] == 'dis_current') {
unit = unitsMap[wallSensorButton['code'] as String];
value = wallSensorStatus.currentDistance;
} else if (wallSensorButton['code'] == 'illuminance_value') {
unit = unitsMap[wallSensorButton['code'] as String];
value = wallSensorStatus.illuminance;
}
}
return DefaultContainer(
@@ -297,8 +289,7 @@ Widget listItem(
if (wallSensorButton['title'] != 'Indicator')
BodyMedium(
text: '${value ?? 'N/A'}${unit ?? ''}',
style:
context.bodyMedium.copyWith(color: ColorsManager.greyColor),
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
),
if (wallSensorButton['title'] == 'Indicator')
Expanded(
@@ -308,16 +299,11 @@ Widget listItem(
Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: value ?? false,
value: wallSensorStatus.indicator,
onChanged: (value) {
if (wallSensor.isOnline ?? false) {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: wallSensor.uuid,
code: 'indicator',
value: value,
),
wallSensor.uuid ?? '');
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeIndicatorEvent(value: wallSensorStatus.indicator));
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
@@ -1,14 +1,14 @@
part of "wall_sensor_interface.dart";
class PresenceIndicator extends StatelessWidget {
const PresenceIndicator({super.key, required this.wallSensor});
final DeviceModel wallSensor;
const PresenceIndicator({super.key, required this.state});
final String state;
@override
Widget build(BuildContext context) {
String state = wallSensor.status
.firstWhere((element) => element.code == "presence_state")
.value
.toString();
// String state = wallSensor.status
// .firstWhere((element) => element.code == "presence_state")
// .value
// .toString();
return Expanded(
flex: 6,
child: Column(
@@ -0,0 +1,104 @@
import 'package:flutter/cupertino.dart';
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/wall_sensor_bloc/wall_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/wall_sensor_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/features/shared_widgets/text_widgets/title_medium.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/helpers/snack_bar.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';
part "parameters_list.dart";
part "presence_indicator.dart";
part "../ceiling_sensor/parameter_control_dialog.dart";
class WallMountedInterface extends StatelessWidget {
const WallMountedInterface({super.key, required this.deviceModel});
final DeviceModel deviceModel;
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => WallSensorBloc(deviceId: deviceModel.uuid ?? '')..add(InitialEvent()),
child: BlocBuilder<WallSensorBloc, WallSensorState>(builder: (context, state) {
WallSensorModel wallSensorModel = WallSensorModel(
presenceState: 'none',
farDetection: 0,
presenceTime: 0,
motionSensitivity: 0,
motionlessSensitivity: 0,
currentDistance: 0,
illuminance: 0,
indicator: false);
if (state is UpdateState) {
wallSensorModel = state.wallSensorModel;
} else if (state is LoadingNewSate) {
wallSensorModel = state.wallSensorModel;
}
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: deviceModel.name ?? "",
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
),
body: 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: state is LoadingInitialState
? const Center(
child: RefreshProgressIndicator(),
)
: Column(
children: [
PresenceIndicator(
state: wallSensorModel.presenceState,
),
ParametersList(
wallSensor: deviceModel,
presenceSensorsModel: wallSensorModel,
),
],
),
),
),
),
);
}),
);
}
}