changing ac bloc

This commit is contained in:
ashrafzarkanisala
2024-08-26 00:48:29 +03:00
parent d7e3c1e1d0
commit d94ec25003
23 changed files with 780 additions and 185 deletions

View File

@ -1,16 +1,31 @@
import 'dart:async';
import 'package:bloc/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/model/ac_model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
class AcBloc extends Bloc<AcsEvent, AcsState> {
AcStatusModel deviceStatus = AcStatusModel(
uuid: '',
acSwitch: true,
modeString: 'hot',
tempSet: 300,
currentTemp: 315,
fanSpeedsString: 'low',
childLock: false,
);
AcBloc() : super(AcsInitialState()) {
on<AcFetchDeviceStatus>(_onFetchAcStatus);
on<AcControl>(_onAcControl);
on<AcSwitch>(_changeAcSwitch);
on<IncreaseCoolToTemp>(_increaseCoolTo);
on<DecreaseCoolToTemp>(_decreaseCoolTo);
on<ChangeLock>(_changeLockValue);
on<ChangeAcMode>(_changeAcMode);
on<ChangeFanSpeed>(_changeFanSpeed);
}
FutureOr<void> _onFetchAcStatus(
@ -18,11 +33,121 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
emit(AcsLoadingState());
try {
final status =
await DevicesManagementApi().getDeviceStatus(event.deviceId);
emit(ACStatusLoaded(status));
await DevicesManagementApi().getDeviceStatus(event.deviceId);
deviceStatus = AcStatusModel.fromJson(status.productUuid, status.status);
emit(ACStatusLoaded(deviceStatus));
} catch (e) {
emit(AcsFailedState( error: e.toString()));
emit(AcsFailedState(error: e.toString()));
}
}
FutureOr<void> _onAcControl(AcControl event, Emitter<AcsState> emit) async {
final oldValue = _getValueByCode(event.code);
_updateLocalValue(event.code, event.value);
emit(ACStatusLoaded(deviceStatus));
try {
final status = Status(code: event.code, value: event.value);
final response =
await DevicesManagementApi().deviceControl(event.deviceId, status);
if (!response) {
_updateLocalValue(event.code, oldValue);
emit(ACStatusLoaded(deviceStatus));
emit(AcsFailedState(error: 'Failed to control the device.'));
}
} catch (e) {
_updateLocalValue(event.code, oldValue);
emit(ACStatusLoaded(deviceStatus));
emit(AcsFailedState(error: 'Error controlling the device: $e'));
}
}
void _updateLocalValue(String code, dynamic value) {
switch (code) {
case 'switch':
deviceStatus.acSwitch = value;
break;
case 'temp_set':
deviceStatus.tempSet = value;
break;
case 'mode':
deviceStatus.modeString = value;
deviceStatus.acMode = AcStatusModel.getACMode(value);
break;
case 'level':
deviceStatus.fanSpeedsString = value;
deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(value);
break;
case 'child_lock':
deviceStatus.childLock = value;
break;
default:
break;
}
}
dynamic _getValueByCode(String code) {
switch (code) {
case 'switch':
return deviceStatus.acSwitch;
case 'temp_set':
return deviceStatus.tempSet;
case 'mode':
return deviceStatus.modeString;
case 'level':
return deviceStatus.fanSpeedsString;
case 'child_lock':
return deviceStatus.childLock;
default:
return null;
}
}
FutureOr<void> _changeAcSwitch(AcSwitch event, Emitter<AcsState> emit) async {
final newValue = !event.acSwitch;
add(AcControl(deviceId: event.deviceId, code: 'switch', value: newValue));
}
FutureOr<void> _increaseCoolTo(
IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
final newValue = (event.value * 10).toInt() + 5;
if (_isValidTemperature(newValue)) {
add(AcControl(
deviceId: event.deviceId, code: 'temp_set', value: newValue));
}
}
FutureOr<void> _decreaseCoolTo(
DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
final newValue = (event.value * 10).toInt() - 5;
if (_isValidTemperature(newValue)) {
add(AcControl(
deviceId: event.deviceId, code: 'temp_set', value: newValue));
}
}
FutureOr<void> _changeLockValue(
ChangeLock event, Emitter<AcsState> emit) async {
final newValue = !event.lockBool;
add(AcControl(
deviceId: event.deviceId, code: 'child_lock', value: newValue));
}
FutureOr<void> _changeAcMode(
ChangeAcMode event, Emitter<AcsState> emit) async {
final newValue = AcStatusModel.getACMode(event.tempModes.name);
add(AcControl(deviceId: event.deviceId, code: 'mode', value: newValue));
}
FutureOr<void> _changeFanSpeed(
ChangeFanSpeed event, Emitter<AcsState> emit) async {
final newValue = AcStatusModel.getFanSpeed(event.fanSpeeds.name);
add(AcControl(deviceId: event.deviceId, code: 'level', value: newValue));
}
bool _isValidTemperature(int value) {
return value >= 200 && value <= 300;
}
}

View File

@ -1,6 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
sealed class AcsEvent extends Equatable {
const AcsEvent();
@ -21,12 +20,74 @@ class AcFetchDeviceStatus extends AcsEvent {
class AcControl extends AcsEvent {
final String deviceId;
final String code;
final bool value;
final dynamic value;
const AcControl(
{required this.deviceId, required this.code, required this.value});
const AcControl({
required this.deviceId,
required this.code,
required this.value,
});
@override
List<Object> get props => [deviceId, code, value];
}
class AcSwitch extends AcsEvent {
final bool acSwitch;
final String deviceId;
const AcSwitch({required this.acSwitch, required this.deviceId});
@override
List<Object> get props => [acSwitch, deviceId];
}
class IncreaseCoolToTemp extends AcsEvent {
final double value;
final String deviceId;
const IncreaseCoolToTemp({required this.value, required this.deviceId});
@override
List<Object> get props => [value, deviceId];
}
class DecreaseCoolToTemp extends AcsEvent {
final double value;
final String deviceId;
const DecreaseCoolToTemp({required this.value, required this.deviceId});
@override
List<Object> get props => [value, deviceId];
}
class ChangeLock extends AcsEvent {
final bool lockBool;
final String deviceId;
const ChangeLock({required this.lockBool, required this.deviceId});
@override
List<Object> get props => [lockBool, deviceId];
}
class ChangeAcMode extends AcsEvent {
final TempModes tempModes;
final String deviceId;
const ChangeAcMode({required this.tempModes, required this.deviceId});
@override
List<Object> get props => [tempModes, deviceId];
}
class ChangeFanSpeed extends AcsEvent {
final FanSpeeds fanSpeeds;
final String deviceId;
const ChangeFanSpeed({required this.fanSpeeds, required this.deviceId});
@override
List<Object> get props => [fanSpeeds, deviceId];
}

View File

@ -1,7 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
abstract class AcsState extends Equatable {
const AcsState();
@ -14,9 +12,8 @@ class AcsInitialState extends AcsState {}
class AcsLoadingState extends AcsState {}
class ACStatusLoaded extends AcsState {
final DeviceStatus status;
final AcStatusModel status;
const ACStatusLoaded(this.status);
@ -24,46 +21,49 @@ class ACStatusLoaded extends AcsState {
List<Object> get props => [status];
}
class AcChangeLoading extends AcsState {
final AcStatusModel acStatusModel;
const AcChangeLoading({required this.acStatusModel});
class AcSwitchChanged extends AcsState {
final bool acSwitch;
const AcSwitchChanged(this.acSwitch);
@override
List<Object> get props => [acStatusModel];
List<Object> get props => [acSwitch];
}
class AcModifyingState extends AcsState {
final AcStatusModel acStatusModel;
const AcModifyingState({required this.acStatusModel});
class AcTempChanged extends AcsState {
final double tempSet;
const AcTempChanged(this.tempSet);
@override
List<Object> get props => [acStatusModel];
List<Object> get props => [tempSet];
}
class GetAcStatusState extends AcsState {
final AcStatusModel acStatusModel;
const GetAcStatusState({required this.acStatusModel});
class AcModeChanged extends AcsState {
final TempModes mode;
const AcModeChanged(this.mode);
@override
List<Object> get props => [acStatusModel];
List<Object> get props => [mode];
}
class GetAllAcsStatusState extends AcsState {
final List<AcStatusModel> allAcsStatues;
final List<DeviceModel> allAcs;
final bool allOn;
final bool allTempSame;
final int temp;
class AcFanSpeedChanged extends AcsState {
final FanSpeeds fanSpeed;
const GetAllAcsStatusState(
{required this.allAcsStatues,
required this.allAcs,
required this.allOn,
required this.allTempSame,
required this.temp});
const AcFanSpeedChanged(this.fanSpeed);
@override
List<Object> get props => [allAcsStatues, allAcs, allAcs, allTempSame, temp];
List<Object> get props => [fanSpeed];
}
class AcLockChanged extends AcsState {
final bool lock;
const AcLockChanged(this.lock);
@override
List<Object> get props => [lock];
}
class AcsFailedState extends AcsState {

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 AcMode extends StatelessWidget {
const AcMode({
super.key,
required this.value,
required this.code,
required this.deviceId,
});
final TempModes value;
final String code;
final String deviceId;
void _onModeSelected(BuildContext context, TempModes mode) {
context.read<AcBloc>().add(
ChangeAcMode(tempModes: mode, deviceId: deviceId),
);
}
@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: () {
_onModeSelected(context, mode);
},
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

@ -1,43 +1,85 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/living_room_switch/bloc/living_room_bloc.dart';
import 'package:flutter_svg/flutter_svg.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/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class AcToggle extends StatelessWidget {
const AcToggle(
{super.key,
required this.value,
required this.code,
required this.deviceId});
const AcToggle({
super.key,
required this.value,
required this.code,
required this.deviceId,
this.icon,
this.description,
});
final bool value;
final String code;
final String deviceId;
final String? icon;
final String? description;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipOval(
child: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value:true,
onChanged: (value) {
},
applyTheme: true,
),
),),
],
),
],
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: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipOval(
child: Container(
color: ColorsManager.whiteColors,
child: SvgPicture.asset(
icon ?? Assets.acDevice,
width: 60,
height: 60,
fit: BoxFit.cover,
),
)),
SizedBox(
height: 20,
width: 35,
child: CupertinoSwitch(
activeColor: ColorsManager.dialogBlueTitle,
value: value,
onChanged: (newValue) {
context.read<AcBloc>().add(
AcControl(
deviceId: deviceId,
code: code,
value: newValue,
),
);
},
),
),
],
),
const Spacer(),
Center(
child: Text(
description ?? 'ThermoState',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
],
),
);
}
}

View File

@ -0,0 +1,134 @@
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 CurrentTemp extends StatefulWidget {
const CurrentTemp({
super.key,
required this.code,
required this.deviceId,
required this.currentTemp,
required this.tempSet,
});
final String code;
final String deviceId;
final int currentTemp;
final int tempSet;
@override
State<CurrentTemp> createState() => _CurrentTempState();
}
class _CurrentTempState extends State<CurrentTemp> {
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(
AcControl(
deviceId: widget.deviceId,
code: widget.code,
value: newValue * 10,
),
);
});
}
@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: () {
setState(() {
_adjustedValue++;
});
_onValueChanged(_adjustedValue);
},
onDecrement: () {
setState(() {
_adjustedValue--;
});
_onValueChanged(_adjustedValue);
}),
],
),
);
}
}

View File

@ -0,0 +1,35 @@
// import 'package:flutter/cupertino.dart';
// import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_mode.dart';
// import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart';
// import 'package:syncrow_web/pages/device_managment/ac/control_list/current_temp.dart';
// import 'package:syncrow_web/utils/constants/assets.dart';
// mixin ACHelper {
// Widget acHelperControlWidgets({
// required dynamic value,
// required String code,
// required String deviceId,
// }) {
// switch (code) {
// case 'switch':
// return AcToggle(value: value, code: code, deviceId: deviceId);
// case 'temp_current':
// return CurrentTemp(value: value, code: 'temp_set', deviceId: deviceId);
// case 'temp_set':
// return SizedBox();
// case 'mode':
// return AcMode(value: value, code: code, deviceId: deviceId);
// case 'level':
// return SizedBox();
// case 'child_lock':
// return AcToggle(
// value: value,
// code: code,
// deviceId: deviceId,
// icon: Assets.childLock,
// description: 'Child Lock');
// default:
// return const SizedBox();
// }
// }
// }

View File

@ -1,28 +1,33 @@
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/utils/constants/const.dart';
enum TempModes { hot, cold, wind }
enum FanSpeeds { auto, low, middle, high }
class AcStatusModel {
String uuid;
bool acSwitch;
String modeString;
int tempSet;
int currentTemp;
String fanSpeedsString;
bool childLock;
// late TempModes acMode;
// late FanSpeeds acFanSpeed;
late TempModes acMode;
late FanSpeeds acFanSpeed;
AcStatusModel(
{required this.acSwitch,
{required this.uuid,
required this.acSwitch,
required this.modeString,
required this.tempSet,
required this.currentTemp,
required this.fanSpeedsString,
required this.childLock}) {
// acMode = getACMode(modeString);
// acFanSpeed = getFanSpeed(fanSpeedsString);
acMode = getACMode(modeString);
acFanSpeed = getFanSpeed(fanSpeedsString);
}
factory AcStatusModel.fromJson(List<Status> jsonList) {
factory AcStatusModel.fromJson(String id, List<Status> jsonList) {
late bool _acSwitch;
late String _mode;
late int _tempSet;
@ -45,6 +50,7 @@ class AcStatusModel {
}
}
return AcStatusModel(
uuid: id,
acSwitch: _acSwitch,
modeString: _mode,
tempSet: _tempSet,

View File

@ -3,68 +3,72 @@ 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/all_devices/helper/ac_helper.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_mode.dart';
import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart';
import 'package:syncrow_web/pages/device_managment/ac/control_list/current_temp.dart';
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class AcDeviceControl extends StatelessWidget with ACHelper {
class AcDeviceControl extends StatelessWidget with HelperResponsiveLayout {
const AcDeviceControl({super.key, required this.device});
final AllDevicesModel device;
@override
Widget build(BuildContext context) {
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) =>
AcBloc()..add(AcFetchDeviceStatus(device.uuid!)),
child: BlocListener<AcBloc, AcsState>(
listener: (context, state) {
create: (context) => AcBloc()..add(AcFetchDeviceStatus(device.uuid!)),
child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) {
if (state is AcsLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is ACStatusLoaded) {
return _buildStatusControls(state.status, isLarge, isMedium);
} else {
return const Center(child: Text('Error fetching status'));
}
},
child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) {
if (state is AcsLoadingState) {
return const Center(child: CircularProgressIndicator());
} else if (state is ACStatusLoaded) {
return _buildStatusControls(state.status.status);
} else {
return const Center(child: Text('Error fetching status'));
}
},
),
),
);
}
Widget _buildStatusControls(List<Status> statuses) {
return GridView.builder(
padding: const EdgeInsets.symmetric(horizontal: 40),
Widget _buildStatusControls(
AcStatusModel statuses, bool isLarge, bool isMedium) {
return GridView(
padding: const EdgeInsets.symmetric(horizontal: 50),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge
? 3
: isMedium
? 2
: 1,
mainAxisExtent: 133,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
itemCount: statuses.length,
itemBuilder: (context, index) {
final status = statuses[index];
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: ACHelperControlWidgets(
value: status.value,
code: status.code,
deviceId: device.uuid!),
);
},
children: [
AcToggle(
value: statuses.acSwitch,
code: 'switch',
deviceId: statuses.uuid,
),
AcMode(
value: statuses.acMode,
code: 'mode',
deviceId: statuses.uuid,
),
CurrentTemp(
currentTemp: statuses.currentTemp,
tempSet: statuses.tempSet,
code: 'temp_set',
deviceId: statuses.uuid,
),
],
);
}
}

View File

@ -1,19 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart';
mixin ACHelper {
Widget ACHelperControlWidgets(
{required bool value, required String code, required String deviceId}) {
switch (code) {
case 'switch_1':
return AcToggle(value: value, code: code, deviceId: deviceId);
case 'switch_2':
return SizedBox();
case 'switch_3':
return SizedBox();
default:
return const SizedBox();
}
}
}

View File

@ -35,9 +35,12 @@ class LivingRoomBloc extends Bloc<LivingRoomEvent, LivingRoomState> {
await DevicesManagementApi().deviceControl(event.deviceId, status);
if (response) {
emit(LivingRoomControlSuccess());
await Future.delayed(const Duration(milliseconds: 500));
add(LivingRoomFetchDeviceStatus(event.deviceId));
final newStatus =
await DevicesManagementApi().getDeviceStatus(event.deviceId);
emit(LivingRoomDeviceStatusLoaded(newStatus));
} else {
emit(const LivingRoomControlError('Failed to control the device.'));
}
} catch (e) {
emit(LivingRoomControlError('Error controlling the device: $e'));

View File

@ -41,6 +41,7 @@ class CeilingLight extends StatelessWidget {
width: 35,
child: CupertinoSwitch(
value: value,
activeColor: ColorsManager.dialogBlueTitle,
onChanged: (newValue) {
context.read<LivingRoomBloc>().add(
LivingRoomControl(

View File

@ -41,6 +41,7 @@ class SpotLight extends StatelessWidget {
width: 35,
child: CupertinoSwitch(
value: value,
activeColor: ColorsManager.dialogBlueTitle,
onChanged: (newValue) {
context.read<LivingRoomBloc>().add(
LivingRoomControl(

View File

@ -41,6 +41,7 @@ class WallLight extends StatelessWidget {
width: 35,
child: CupertinoSwitch(
value: value,
activeColor: ColorsManager.dialogBlueTitle,
onChanged: (newValue) {
context.read<LivingRoomBloc>().add(
LivingRoomControl(

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart';
import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/cieling_light.dart';
import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/spot_light.dart';
import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/wall_light.dart';

View File

@ -16,25 +16,19 @@ class LivingRoomDeviceControl extends StatelessWidget with LivingRoomHelper {
return BlocProvider(
create: (context) =>
LivingRoomBloc()..add(LivingRoomFetchDeviceStatus(device.uuid!)),
child: BlocListener<LivingRoomBloc, LivingRoomState>(
listener: (context, state) {
if (state is LivingRoomControlSuccess) {
context
.read<LivingRoomBloc>()
.add(LivingRoomFetchDeviceStatus(device.uuid!));
child: BlocBuilder<LivingRoomBloc, LivingRoomState>(
builder: (context, state) {
if (state is LivingRoomDeviceStatusLoading) {
return const Center(child: CircularProgressIndicator());
} else if (state is LivingRoomDeviceStatusLoaded) {
return _buildStatusControls(state.status.status);
} else if ((state is LivingRoomDeviceManagementError) ||
(state is LivingRoomControlError)) {
return const Center(child: Text('Error fetching status'));
} else {
return const Center(child: CircularProgressIndicator());
}
},
child: BlocBuilder<LivingRoomBloc, LivingRoomState>(
builder: (context, state) {
if (state is LivingRoomDeviceStatusLoading) {
return const Center(child: CircularProgressIndicator());
} else if (state is LivingRoomDeviceStatusLoaded) {
return _buildStatusControls(state.status.status);
} else {
return const Center(child: Text('Error fetching status'));
}
},
),
),
);
}
@ -50,7 +44,7 @@ class LivingRoomDeviceControl extends StatelessWidget with LivingRoomHelper {
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
itemCount: statuses.length,
itemCount: 3,
itemBuilder: (context, index) {
final status = statuses[index];

View File

@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
class CelsiusSymbol extends StatelessWidget {
const CelsiusSymbol({this.color, super.key});
final Color? color;
@override
Widget build(BuildContext context) {
return Text(
'°C',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: color,
),
);
}
}

View File

@ -44,7 +44,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
const SizedBox(height: 20),
//// BUILD DEVICE CONTROLS
///
//// ROUTE TO SPECIFIC CONTROL VIEW BASED ON DEVICE CATEGORY
//// ROUTE TO SPECIFIC CONTROL VIEW BASED ON DEVICE CATEGORY
routeControlsWidgets(device: device),
],
),
@ -56,7 +56,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
Widget _buildDeviceInfoSection() {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 50),
padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 50),
child: Table(
children: [
TableRow(

View File

@ -6,6 +6,7 @@ class IncrementDecrementWidget extends StatelessWidget {
final String description;
final VoidCallback onIncrement;
final VoidCallback onDecrement;
final Color? descriptionColor;
const IncrementDecrementWidget({
super.key,
@ -13,6 +14,7 @@ class IncrementDecrementWidget extends StatelessWidget {
required this.description,
required this.onIncrement,
required this.onDecrement,
this.descriptionColor,
});
@override
@ -22,18 +24,20 @@ class IncrementDecrementWidget extends StatelessWidget {
children: [
Material(
type: MaterialType.transparency,
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: onDecrement,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
Icons.remove,
color: ColorsManager.greyColor,
size: 32,
child: Flexible(
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: onDecrement,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
Icons.remove,
color: ColorsManager.greyColor,
size: 28,
),
),
),
),
@ -53,9 +57,9 @@ class IncrementDecrementWidget extends StatelessWidget {
),
TextSpan(
text: description,
style: const TextStyle(
style: TextStyle(
fontSize: 12,
color: ColorsManager.blackColor,
color: descriptionColor ?? ColorsManager.blackColor,
fontWeight: FontWeight.bold,
),
),
@ -64,18 +68,20 @@ class IncrementDecrementWidget extends StatelessWidget {
),
Material(
type: MaterialType.transparency,
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: onIncrement,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
Icons.add,
color: ColorsManager.greyColor,
size: 32,
child: Flexible(
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: onIncrement,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
Icons.add,
color: ColorsManager.greyColor,
size: 28,
),
),
),
),