Converted all the devices models to extends from DeviceModel for the purpose of unifying.

Initialized Lights feature.
This commit is contained in:
Mohammad Salameh
2024-03-02 21:57:11 +03:00
parent 8203836332
commit bcaed7a4b8
17 changed files with 229 additions and 67 deletions

View File

@ -1,6 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:meta/meta.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart'; import 'package:syncrow_app/features/devices/model/ac_model.dart';
@ -8,7 +7,6 @@ part 'ac_state.dart';
class AcCubit extends Cubit<AcState> { class AcCubit extends Cubit<AcState> {
AcCubit() : super(AcInitial()) { AcCubit() : super(AcInitial()) {
averageTempForAll();
updateACsStatus(); updateACsStatus();
} }
@ -21,7 +19,7 @@ class AcCubit extends Cubit<AcState> {
ACModel? getSelectedAC() { ACModel? getSelectedAC() {
for (var ac in DevicesCubit.categories[0].devices) { for (var ac in DevicesCubit.categories[0].devices) {
if (ac.isSelected) { if (ac is ACModel && ac.isSelected) {
return ac; return ac;
} }
} }
@ -29,7 +27,7 @@ class AcCubit extends Cubit<AcState> {
} }
void turnACOn(ACModel model) { void turnACOn(ACModel model) {
if (!model.status) { if (model.status == false) {
model.status = true; model.status = true;
updateACsStatus(); updateACsStatus();
emit(ACTurnedOn()); emit(ACTurnedOn());
@ -37,7 +35,7 @@ class AcCubit extends Cubit<AcState> {
} }
void turnACOff(ACModel model) { void turnACOff(ACModel model) {
if (model.status) { if (model.status == true) {
model.status = false; model.status = false;
updateACsStatus(); updateACsStatus();
emit(ACTurnedOff()); emit(ACTurnedOff());
@ -45,7 +43,7 @@ class AcCubit extends Cubit<AcState> {
} }
void updateACsStatus() { void updateACsStatus() {
bool tempStatus = DevicesCubit.categories[0].devices[0].status; bool tempStatus = DevicesCubit.categories[0].devices[0].status ?? false;
for (var AC in DevicesCubit.categories[0].devices) { for (var AC in DevicesCubit.categories[0].devices) {
//check if there any AC have a different status than the initial ==> turn off the universal switch //check if there any AC have a different status than the initial ==> turn off the universal switch
if (AC.status != tempStatus) { if (AC.status != tempStatus) {
@ -75,49 +73,44 @@ class AcCubit extends Cubit<AcState> {
} }
void setTempToAll(double temperature) { void setTempToAll(double temperature) {
for (var ac in DevicesCubit.categories[0].devices) { for (var element in DevicesCubit.categories[0].devices) {
ac.temperature = temperature; if (element is ACModel) {
element.temperature = temperature;
}
} }
averageTempForAll();
emit(ACsTempChanged(temperature)); emit(ACsTempChanged(temperature));
} }
void increaseACTemp(int index) { void increaseACTemp(int index) {
DevicesCubit.categories[0].devices[index].temperature += .5; var device = DevicesCubit.categories[0].devices[index];
averageTempForAll(); if (device is ACModel) {
emit(ACsTempChanged(DevicesCubit.categories[0].devices[index].temperature)); device.temperature += 0.5;
emit(ACsTempChanged(device.temperature));
}
} }
void decreaseACTemp(int index) { void decreaseACTemp(int index) {
DevicesCubit.categories[0].devices[index].temperature -= .5; var device = DevicesCubit.categories[0].devices[index];
averageTempForAll(); if (device is ACModel) {
emit(ACsTempChanged(DevicesCubit.categories[0].devices[index].temperature)); device.temperature -= 0.5;
emit(ACsTempChanged(device.temperature));
}
} }
void setACTemp(ACModel model, double temp) { void setACTemp(ACModel model, double temp) {
model.temperature = temp; model.temperature = temp;
averageTempForAll();
emit(ACsTempChanged(temp)); emit(ACsTempChanged(temp));
} }
double getTemp(int index) { double getTemp(int index) {
return DevicesCubit.categories[0].devices[index].temperature; var device = DevicesCubit.categories[0].devices[index];
if (device is ACModel) {
return device.temperature;
}
return 0.0; // or any default value you prefer
} }
static double averageTemp = 0; static double averageTemp = 0;
void averageTempForAll() {
double tempSum = 0;
for (var ac in DevicesCubit.categories[0].devices) {
tempSum += ac.temperature;
}
averageTemp = tempSum / DevicesCubit.categories[0].devices.length;
averageTemp = (averageTemp * 2).round() / 2;
emit(ACsAverageTemp());
}
/// implement the fan speed and temp mode change /// implement the fan speed and temp mode change
} }

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart'; import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/model/light_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/screens/screens_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/screens/screens_view.dart';
@ -28,7 +29,7 @@ class DevicesCubit extends Cubit<DevicesState> {
static DevicesCubit get(context) => BlocProvider.of(context); static DevicesCubit get(context) => BlocProvider.of(context);
static var categories = <DevicesCategoryModel>[ static List<DevicesCategoryModel> categories = [
DevicesCategoryModel( DevicesCategoryModel(
devices: [ devices: [
ACModel( ACModel(
@ -38,6 +39,10 @@ class DevicesCubit extends Cubit<DevicesState> {
temperature: 20, temperature: 20,
fanSpeed: 0, fanSpeed: 0,
tempMode: 0, tempMode: 0,
type: '',
location: '',
image: '',
timer: null,
), ),
ACModel( ACModel(
name: "Master Bedroom AC", name: "Master Bedroom AC",
@ -46,6 +51,10 @@ class DevicesCubit extends Cubit<DevicesState> {
temperature: 20, temperature: 20,
fanSpeed: 0, fanSpeed: 0,
tempMode: 0, tempMode: 0,
type: '',
location: '',
image: '',
timer: null,
), ),
], ],
icon: Assets.iconsAC, icon: Assets.iconsAC,
@ -54,7 +63,32 @@ class DevicesCubit extends Cubit<DevicesState> {
page: const ACsView(), page: const ACsView(),
), ),
DevicesCategoryModel( DevicesCategoryModel(
devices: [], devices: [
LightModel(
name: "Living Room Light",
id: '0',
status: false,
color: 0,
brightness: 20,
lightingMode: 1,
timer: null,
type: '',
location: '',
image: '',
),
LightModel(
name: "Master Bedroom Light",
id: '1',
status: false,
color: 2,
brightness: 40,
lightingMode: 1,
timer: null,
type: '',
location: '',
image: '',
),
],
icon: Assets.iconsLight, icon: Assets.iconsLight,
name: 'Lights', name: 'Lights',
type: DeviceType.Lights, type: DeviceType.Lights,
@ -101,7 +135,7 @@ class DevicesCubit extends Cubit<DevicesState> {
void areAllDevicesOff(DevicesCategoryModel category) { void areAllDevicesOff(DevicesCategoryModel category) {
for (var device in category.devices) { for (var device in category.devices) {
if (device.status) { if (device.status ?? false) {
category.devicesStatus = false; category.devicesStatus = false;
emit(CategorySwitchChanged()); emit(CategorySwitchChanged());
return; return;

View File

@ -0,0 +1,9 @@
import 'package:flutter_bloc/flutter_bloc.dart';
part 'lights_state.dart';
class LightsCubit extends Cubit<LightsState> {
LightsCubit() : super(LightsInitial());
static LightsCubit get(context) => BlocProvider.of(context);
}

View File

@ -0,0 +1,5 @@
part of 'lights_cubit.dart';
abstract class LightsState {}
class LightsInitial extends LightsState {}

View File

@ -1,21 +1,51 @@
class ACModel { import 'package:syncrow_app/features/devices/model/device_model.dart';
final String name;
final String id; class ACModel extends DeviceModel {
late bool status;
late double temperature; late double temperature;
late int fanSpeed; late int fanSpeed;
late int tempMode; late int tempMode;
bool isSelected = false;
ACModel({ ACModel({
required this.name,
required this.id,
required this.status,
required this.temperature, required this.temperature,
required this.fanSpeed, required this.fanSpeed,
required this.tempMode, required this.tempMode,
required super.id,
required super.name,
required super.type,
required super.status,
required super.location,
required super.image,
required super.timer,
}); });
Map<String, dynamic> toJson() {
return {
'temperature': temperature,
'fanSpeed': fanSpeed,
'tempMode': tempMode,
'id': id,
'name': name,
'status': status,
'type': type,
'location': location,
'image': image,
};
}
factory ACModel.fromJson(Map<String, dynamic> json) {
return ACModel(
id: json['id'],
name: json['name'],
status: json['status'],
temperature: json['temperature'],
fanSpeed: json['fanSpeed'],
tempMode: json['tempMode'],
type: json['type'],
location: json['location'],
image: json['image'],
timer: json['timer'],
);
}
} }

View File

@ -1,6 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'ac_model.dart';
class DevicesCategoryModel { class DevicesCategoryModel {
final String name; final String name;
@ -9,7 +8,7 @@ class DevicesCategoryModel {
final Widget page; final Widget page;
bool devicesStatus = false; bool devicesStatus = false;
final List<ACModel> devices; final List<DeviceModel> devices;
final DeviceType type; final DeviceType type;
bool isSelected; bool isSelected;
@ -23,7 +22,7 @@ class DevicesCategoryModel {
required this.devices}) { required this.devices}) {
//sets the initial status of the devices //sets the initial status of the devices
if (devices.isNotEmpty) { if (devices.isNotEmpty) {
bool tempStatus = devices.first.status; bool tempStatus = devices.first.status ?? false;
for (var device in devices) { for (var device in devices) {
if (device.status != tempStatus) { if (device.status != tempStatus) {
devicesStatus = false; devicesStatus = false;

View File

@ -0,0 +1,20 @@
abstract class DeviceModel {
final String? id;
final String? name;
final String? type;
bool? status;
final String? location;
final String? image;
final double? timer;
bool isSelected = false;
DeviceModel({
required this.id,
required this.name,
required this.type,
required this.status,
required this.location,
required this.image,
required this.timer,
});
}

View File

@ -0,0 +1,51 @@
import 'package:syncrow_app/features/devices/model/device_model.dart';
class LightModel extends DeviceModel {
final double brightness;
final int color;
final int lightingMode;
LightModel({
required this.brightness,
required this.color,
required this.lightingMode,
required super.id,
required super.name,
required super.type,
required super.status,
required super.location,
required super.image,
required super.timer,
});
Map<String, dynamic> toJson() {
return {
'luminance': brightness,
'color': color,
'lightingMode': lightingMode,
'timer': timer,
'id': id,
'name': name,
'status': status,
'type': type,
'location': location,
'image': image,
};
}
factory LightModel.fromJson(Map<String, dynamic> json) {
return LightModel(
id: json['id'],
name: json['name'],
status: json['status'],
brightness: json['luminance'],
color: json['color'],
lightingMode: json['lightingMode'],
timer: json['timer'],
type: json['type'],
location: json['location'],
image: json['image'],
);
}
}

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:sleek_circular_slider/sleek_circular_slider.dart'; import 'package:sleek_circular_slider/sleek_circular_slider.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.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_large.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.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_large.dart';
import 'package:syncrow_app/utils/context_extension.dart'; import 'package:syncrow_app/utils/context_extension.dart';

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_unit.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_unit.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_temp_widget.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_temp_widget.dart';
@ -8,6 +8,8 @@ import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_ac_temp.
import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'; import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import '../../../model/ac_model.dart';
class ACsList extends StatelessWidget { class ACsList extends StatelessWidget {
const ACsList({ const ACsList({
super.key, super.key,
@ -43,11 +45,16 @@ class ACsList extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
BodySmall( BodySmall(
text: DevicesCubit.categories[0].devices[index].name), text:
DevicesCubit.categories[0].devices[index].name ??
""),
IconButton( IconButton(
onPressed: () { onPressed: () {
AcCubit.get(context).selectAC( var device =
DevicesCubit.categories[0].devices[index]); DevicesCubit.categories[0].devices[index];
if (device is ACModel) {
AcCubit.get(context).selectAC(device);
}
}, },
icon: const Icon( icon: const Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
@ -63,17 +70,21 @@ class ACsList extends StatelessWidget {
], ],
), ),
const SizedBox(height: 5), const SizedBox(height: 5),
DevicesDefaultSwitch( if (DevicesCubit.categories[0].devices[index] is ACModel)
model: DevicesCubit.categories[0].devices[index], DevicesDefaultSwitch(
), model:
DevicesCubit.categories[0].devices[index] as ACModel,
),
const SizedBox(height: 10), const SizedBox(height: 10),
ACTempWidget( ACTempWidget(
index, index,
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
ACModeControlUnit( if (DevicesCubit.categories[0].devices[index] is ACModel)
model: DevicesCubit.categories[0].devices[index], ACModeControlUnit(
), model:
DevicesCubit.categories[0].devices[index] as ACModel,
),
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
); );

View File

@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/view/widgets/default_app_bar.dart'; import 'package:syncrow_app/features/app_layout/view/widgets/default_app_bar.dart';
import 'package:syncrow_app/features/app_layout/view/widgets/default_nav_bar.dart'; import 'package:syncrow_app/features/app_layout/view/widgets/default_nav_bar.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart'; import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_list.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_list.dart';

View File

@ -4,7 +4,7 @@ import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import '../../../../../utils/resource_manager/color_manager.dart'; import '../../../../../utils/resource_manager/color_manager.dart';
import '../../../../shared_widgets/text_widgets/body_medium.dart'; import '../../../../shared_widgets/text_widgets/body_medium.dart';
import '../../../bloc/ac_cubit.dart'; import '../../../bloc/AC/ac_cubit.dart';
class UniversalACSwitch extends StatelessWidget { class UniversalACSwitch extends StatelessWidget {
const UniversalACSwitch({ const UniversalACSwitch({

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
import 'package:syncrow_app/utils/context_extension.dart'; import 'package:syncrow_app/utils/context_extension.dart';
import '../../../../../generated/assets.dart'; import '../../../../../generated/assets.dart';

View File

@ -1,10 +1,20 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../bloc/lights/lights_cubit.dart';
class LightsView extends StatelessWidget { class LightsView extends StatelessWidget {
const LightsView({super.key}); const LightsView({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Placeholder(); return BlocProvider(
create: (context) => LightsCubit(),
child: BlocBuilder<LightsCubit, LightsState>(
builder: (context, state) => const Center(
child: Text('LightsView'),
),
),
);
} }
} }

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart'; import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
@ -27,7 +27,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
child: Container( child: Container(
height: 60, height: 60,
decoration: BoxDecoration( decoration: BoxDecoration(
color: model.status color: model.status ?? false
? ColorsManager.primaryColor ? ColorsManager.primaryColor
: Colors.white, : Colors.white,
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
@ -38,7 +38,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
child: Center( child: Center(
child: BodyMedium( child: BodyMedium(
text: "ON", text: "ON",
fontColor: model.status ? Colors.white : null, fontColor: model.status ?? false ? Colors.white : null,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@ -53,7 +53,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
child: Container( child: Container(
height: 60, height: 60,
decoration: BoxDecoration( decoration: BoxDecoration(
color: model.status color: model.status ?? false
? Colors.white ? Colors.white
: ColorsManager.primaryColor, : ColorsManager.primaryColor,
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
@ -64,7 +64,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
child: Center( child: Center(
child: BodyMedium( child: BodyMedium(
text: "OFF", text: "OFF",
fontColor: model.status ? null : Colors.white, fontColor: model.status ?? false ? null : Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),