push ac batch control

This commit is contained in:
ashrafzarkanisala
2024-09-18 12:27:00 +03:00
parent 7c28012d79
commit abb0a58468
26 changed files with 516 additions and 66 deletions

View File

@ -3,12 +3,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_state.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/ac_mode.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/ac_toggle.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/current_temp.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/control_list/fan_speed.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_ac_mode.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_current_temp.dart';
import 'package:syncrow_web/pages/device_managment/ac/view/batch_control_list/batch_fan_speed.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart';
import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart';
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
@ -25,7 +25,7 @@ class AcDeviceBatchControlView extends StatelessWidget
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) => AcBloc(deviceId: devicesIds.first)
..add(AcFetchBatchStatus(devicesIds.first)),
..add(AcFetchBatchStatusEvent(devicesIds)),
child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) {
if (state is ACStatusLoaded) {
@ -44,34 +44,49 @@ class AcDeviceBatchControlView extends StatelessWidget
mainAxisSpacing: 12,
),
children: [
AcToggle(
value: state.status.acSwitch,
code: 'switch',
ToggleWidget(
deviceId: devicesIds.first,
code: 'switch',
value: state.status.acSwitch,
label: 'ThermoState',
onChange: (value) {
context.read<AcBloc>().add(AcBatchControlEvent(
devicesIds: devicesIds,
code: 'switch',
value: value,
));
},
),
CurrentTemp(
BatchCurrentTemp(
currentTemp: state.status.currentTemp,
tempSet: state.status.tempSet,
code: 'temp_set',
deviceId: devicesIds.first,
devicesIds: devicesIds,
),
AcMode(
BatchAcMode(
value: state.status.acMode,
code: 'mode',
deviceId: devicesIds.first,
devicesIds: devicesIds,
),
FanSpeedControl(
BatchFanSpeedControl(
value: state.status.acFanSpeed,
code: 'level',
deviceId: devicesIds.first,
devicesIds: devicesIds,
),
AcToggle(
value: state.status.childLock,
code: 'child_lock',
ToggleWidget(
deviceId: devicesIds.first,
description: 'Child Lock',
code: 'child_lock',
value: state.status.childLock,
label: 'Child Lock',
icon:
state.status.childLock ? Assets.childLock : Assets.unlock,
onChange: (value) {
context.read<AcBloc>().add(AcBatchControlEvent(
devicesIds: devicesIds,
code: 'child_lock',
value: value,
));
},
),
FirmwareUpdateWidget(deviceId: devicesIds.first, version: 5),
FactoryResetWidget(deviceId: devicesIds.first),

View File

@ -23,7 +23,7 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) => AcBloc(deviceId: device.uuid!)
..add(AcFetchDeviceStatus(device.uuid!)),
..add(AcFetchDeviceStatusEvent(device.uuid!)),
child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) {
if (state is ACStatusLoaded) {

View File

@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
class BatchAcMode extends StatelessWidget {
const BatchAcMode({
super.key,
required this.value,
required this.code,
required this.devicesIds,
});
final TempModes value;
final String code;
final List<String> devicesIds;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildIconContainer(context, TempModes.cold, Assets.freezing,
value == TempModes.cold),
_buildIconContainer(
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
value == TempModes.wind),
],
),
);
}
Widget _buildIconContainer(
BuildContext context, TempModes mode, String assetPath, bool isSelected) {
return Flexible(
child: GestureDetector(
onTap: () {
context.read<AcBloc>().add(
AcBatchControlEvent(
devicesIds: devicesIds,
code: code,
value: mode.name,
),
);
},
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: ColorsManager.whiteColors,
border: Border.all(
color: isSelected ? Colors.blue : Colors.transparent,
width: 2.0,
),
),
margin: const EdgeInsets.symmetric(horizontal: 4),
padding: const EdgeInsets.all(4),
child: ClipOval(
child: SvgPicture.asset(
assetPath,
fit: BoxFit.contain,
),
),
),
),
);
}
}

View File

@ -0,0 +1,138 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
import 'package:syncrow_web/pages/device_managment/shared/celciuse_symbol.dart';
import 'package:syncrow_web/pages/device_managment/shared/increament_decreament.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
class BatchCurrentTemp extends StatefulWidget {
const BatchCurrentTemp({
super.key,
required this.code,
required this.devicesIds,
required this.currentTemp,
required this.tempSet,
});
final String code;
final List<String> devicesIds;
final int currentTemp;
final int tempSet;
@override
State<BatchCurrentTemp> createState() => _CurrentTempState();
}
class _CurrentTempState extends State<BatchCurrentTemp> {
late double _adjustedValue;
Timer? _debounce;
@override
void initState() {
super.initState();
_adjustedValue = _initialAdjustedValue(widget.tempSet);
}
double _initialAdjustedValue(dynamic value) {
if (value is int || value is double) {
double doubleValue = value.toDouble();
return doubleValue > 99 ? doubleValue / 10 : doubleValue;
} else {
throw ArgumentError('Invalid value type: Expected int or double');
}
}
void _onValueChanged(double newValue) {
if (_debounce?.isActive ?? false) {
_debounce?.cancel();
}
_debounce = Timer(const Duration(milliseconds: 500), () {
context.read<AcBloc>().add(
AcBatchControlEvent(
devicesIds: widget.devicesIds,
code: widget.code,
value: (newValue * 10).toInt(),
),
);
});
}
@override
void dispose() {
_debounce?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Current Temperature',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.grey),
),
const SizedBox(
height: 5,
),
Row(
children: [
Text(
(widget.currentTemp > 99
? widget.currentTemp / 10
: widget.currentTemp)
.toString(),
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.grey),
),
const CelsiusSymbol(
color: Colors.grey,
)
],
),
],
),
const Spacer(),
IncrementDecrementWidget(
value: _adjustedValue.toString(),
description: '°C',
descriptionColor: ColorsManager.dialogBlueTitle,
onIncrement: () {
if (_adjustedValue < 30) {
setState(() {
_adjustedValue++;
});
_onValueChanged(_adjustedValue);
}
},
onDecrement: () {
if (_adjustedValue > 20) {
setState(() {
_adjustedValue--;
});
_onValueChanged(_adjustedValue);
}
}),
],
),
);
}
}

View File

@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
class BatchFanSpeedControl extends StatelessWidget {
const BatchFanSpeedControl({
super.key,
required this.value,
required this.code,
required this.devicesIds,
});
final FanSpeeds value;
final String code;
final List<String> devicesIds;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: ColorsManager.greyColor.withOpacity(0.2),
border: Border.all(color: ColorsManager.boxDivider),
),
padding: const EdgeInsets.all(8),
child: Column(
children: [
Wrap(
runSpacing: 8,
spacing: 8,
children: [
_buildIconContainer(context, FanSpeeds.auto, Assets.acFanAuto,
value == FanSpeeds.auto),
_buildIconContainer(context, FanSpeeds.low, Assets.acFanLow,
value == FanSpeeds.low),
],
),
Wrap(
runSpacing: 8,
spacing: 8,
children: [
_buildIconContainer(context, FanSpeeds.middle, Assets.acFanMiddle,
value == FanSpeeds.middle),
_buildIconContainer(context, FanSpeeds.high, Assets.acFanHigh,
value == FanSpeeds.high),
],
)
],
),
);
}
Widget _buildIconContainer(BuildContext context, FanSpeeds speed,
String assetPath, bool isSelected) {
return GestureDetector(
onTap: () {
context.read<AcBloc>().add(
AcBatchControlEvent(
devicesIds: devicesIds,
code: code,
value: speed.name,
),
);
},
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: ColorsManager.whiteColors,
border: Border.all(
color: isSelected ? Colors.blue : Colors.transparent,
width: 2.0,
),
),
padding: const EdgeInsets.all(8),
child: ClipOval(
child: SvgPicture.asset(
assetPath,
fit: BoxFit.contain,
),
),
),
);
}
}

View File

@ -49,7 +49,7 @@ class AcMode extends StatelessWidget {
child: GestureDetector(
onTap: () {
context.read<AcBloc>().add(
AcControl(
AcControlEvent(
deviceId: deviceId,
code: code,
value: mode.name,

View File

@ -57,7 +57,7 @@ class AcToggle extends StatelessWidget {
value: value,
onChanged: (newValue) {
context.read<AcBloc>().add(
AcControl(
AcControlEvent(
deviceId: deviceId,
code: code,
value: newValue,

View File

@ -50,7 +50,7 @@ class _CurrentTempState extends State<CurrentTemp> {
}
_debounce = Timer(const Duration(milliseconds: 500), () {
context.read<AcBloc>().add(
AcControl(
AcControlEvent(
deviceId: widget.deviceId,
code: widget.code,
value: (newValue * 10).toInt(),

View File

@ -60,7 +60,7 @@ class FanSpeedControl extends StatelessWidget {
return GestureDetector(
onTap: () {
context.read<AcBloc>().add(
AcControl(
AcControlEvent(
deviceId: deviceId,
code: code,
value: speed.name,