Update presence sensor interface and add parameter dialog

- Add parameter dialog for adjusting sensitivity in presence sensor interface.
- Implement toTitleCase helper method in StringHelpers class.
- Update UI elements in the presence sensor interface for better user interaction.
This commit is contained in:
Mohammad Salameh
2024-04-22 09:14:02 +03:00
parent 506068474b
commit 2eeee63e1d
3 changed files with 235 additions and 6 deletions
@@ -3,13 +3,17 @@ import 'dart:math';
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';
@@ -58,13 +62,58 @@ class CeilingSensorInterface extends StatelessWidget {
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.presenceSensorAssetsPresenceSensorMotion,
width: 100,
height: 100,
InkWell(
onTap: () {
if ((ceilingSensor.isOnline ?? false) == false) {
return;
}
showDialog(
context: context,
builder: (context) => ParameterDialog(
title: 'Sensitivity',
sensor: ceilingSensor,
value: ceilingSensor.status
.firstWhere((element) =>
element.code == 'sensitivity')
.value as int,
min: ceilingSensor.functions
.firstWhere((element) =>
element.code == 'sensitivity')
.values
?.min ??
0,
max: ceilingSensor.functions
.firstWhere((element) =>
element.code == 'sensitivity')
.values
?.max ??
0,
),
);
},
child: SvgPicture.asset(
Assets.presenceSensorAssetsPresenceSensorMotion,
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: 'Motion',
text: (ceilingSensor.isOnline ?? false)
? StringHelpers.toTitleCase(ceilingSensor.status
.firstWhere((element) =>
element.code == 'presence_state')
.value
.toString())
: "Offline",
style: context.bodyMedium.copyWith(
fontWeight: FontsManager.bold,
),
@@ -209,3 +258,173 @@ var ceilingSensorButtons = [
'page': null,
},
];
class ParameterDialog extends StatefulWidget {
final String title;
final DeviceModel sensor;
final int value;
final int min;
final int max;
const ParameterDialog({
super.key,
required this.title,
required this.sensor,
required this.value,
required this.min,
required this.max,
});
@override
_ParameterDialogState createState() => _ParameterDialogState();
}
class _ParameterDialogState extends State<ParameterDialog> {
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) {
return;
}
if (!widget.sensor.isOnline!) {
debugPrint('Device is offline');
return;
}
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: widget.sensor.id,
code: 'sensitivity',
value: widget.value),
widget.sensor.id ?? '');
},
child: Center(
child: BodyMedium(
text: 'Confirm',
style: context.bodyMedium.copyWith(
color: ColorsManager.primaryColorWithOpacity),
),
),
),
],
)
],
),
),
);
}
}
@@ -35,7 +35,10 @@ class WizartSwitches extends StatelessWidget {
onTap: () {
// DevicesCubit.getInstance().selectCategory(index);
//Navigate to the chosen category view without animation
if (DevicesCubit.getInstance().chosenCategoryView ==
null) {
return;
}
Navigator.push(context,
CustomPageRoute(builder: (context) {
return DevicesCubit.getInstance()
@@ -61,4 +61,11 @@ class StringHelpers {
return 0;
}
}
static String toTitleCase(String text) {
return text
.split(' ')
.map((word) => word[0].toUpperCase() + word.substring(1))
.join(' ');
}
}