diff --git a/assets/icons/automated_clock.svg b/assets/icons/automated_clock.svg new file mode 100644 index 0000000..f537623 --- /dev/null +++ b/assets/icons/automated_clock.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icons/lock.svg b/assets/icons/lock.svg new file mode 100644 index 0000000..23e3db3 --- /dev/null +++ b/assets/icons/lock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/logo.png b/assets/icons/logo.png new file mode 100644 index 0000000..417841e Binary files /dev/null and b/assets/icons/logo.png differ diff --git a/ios/Runner/AppIcon.appiconset/1024.png b/ios/Runner/AppIcon.appiconset/1024.png new file mode 100644 index 0000000..5cc0985 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/1024.png differ diff --git a/ios/Runner/AppIcon.appiconset/114.png b/ios/Runner/AppIcon.appiconset/114.png new file mode 100644 index 0000000..4002c14 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/114.png differ diff --git a/ios/Runner/AppIcon.appiconset/120.png b/ios/Runner/AppIcon.appiconset/120.png new file mode 100644 index 0000000..ddee75b Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/120.png differ diff --git a/ios/Runner/AppIcon.appiconset/180.png b/ios/Runner/AppIcon.appiconset/180.png new file mode 100644 index 0000000..357cd0b Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/180.png differ diff --git a/ios/Runner/AppIcon.appiconset/29.png b/ios/Runner/AppIcon.appiconset/29.png new file mode 100644 index 0000000..2a93116 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/29.png differ diff --git a/ios/Runner/AppIcon.appiconset/40.png b/ios/Runner/AppIcon.appiconset/40.png new file mode 100644 index 0000000..9ecf032 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/40.png differ diff --git a/ios/Runner/AppIcon.appiconset/57.png b/ios/Runner/AppIcon.appiconset/57.png new file mode 100644 index 0000000..a0767a3 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/57.png differ diff --git a/ios/Runner/AppIcon.appiconset/58.png b/ios/Runner/AppIcon.appiconset/58.png new file mode 100644 index 0000000..af3366d Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/58.png differ diff --git a/ios/Runner/AppIcon.appiconset/60.png b/ios/Runner/AppIcon.appiconset/60.png new file mode 100644 index 0000000..de657d6 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/60.png differ diff --git a/ios/Runner/AppIcon.appiconset/80.png b/ios/Runner/AppIcon.appiconset/80.png new file mode 100644 index 0000000..4739c0f Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/80.png differ diff --git a/ios/Runner/AppIcon.appiconset/87.png b/ios/Runner/AppIcon.appiconset/87.png new file mode 100644 index 0000000..3757b16 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/87.png differ diff --git a/ios/Runner/AppIcon.appiconset/Contents.json b/ios/Runner/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..8a28773 --- /dev/null +++ b/ios/Runner/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom": "iphone", + "filename" : "logo-20@2x.png", + "scale": "2x" + }, + { + "size" : "20x20", + "idiom": "iphone", + "filename" : "logo-20@3x.png", + "scale": "3x" + }, + { + "size" : "20x20", + "idiom": "ipad", + "filename" : "logo-20.png", + "scale": "1x" + }, + { + "size" : "20x20", + "idiom": "ipad", + "filename" : "logo-20@2x.png", + "scale": "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "logo-29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "logo-29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "logo-40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "logo-40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "logo-60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "logo-60@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "logo-29.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "logo-29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "logo-40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "logo-40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "logo-76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "logo-76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "logo-83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "logo-1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/AppIcon.appiconset/logo-1024.png b/ios/Runner/AppIcon.appiconset/logo-1024.png new file mode 100644 index 0000000..20102d9 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-1024.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-20.png b/ios/Runner/AppIcon.appiconset/logo-20.png new file mode 100644 index 0000000..03f60c3 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-20.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-20@2x.png b/ios/Runner/AppIcon.appiconset/logo-20@2x.png new file mode 100644 index 0000000..fe27f08 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-20@2x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-20@3x.png b/ios/Runner/AppIcon.appiconset/logo-20@3x.png new file mode 100644 index 0000000..1d09d46 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-20@3x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-29.png b/ios/Runner/AppIcon.appiconset/logo-29.png new file mode 100644 index 0000000..490fd47 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-29.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-29@2x.png b/ios/Runner/AppIcon.appiconset/logo-29@2x.png new file mode 100644 index 0000000..90ce766 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-29@2x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-29@3x.png b/ios/Runner/AppIcon.appiconset/logo-29@3x.png new file mode 100644 index 0000000..b33e6bc Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-29@3x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-40.png b/ios/Runner/AppIcon.appiconset/logo-40.png new file mode 100644 index 0000000..fe27f08 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-40.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-40@2x.png b/ios/Runner/AppIcon.appiconset/logo-40@2x.png new file mode 100644 index 0000000..240758a Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-40@2x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-40@3x.png b/ios/Runner/AppIcon.appiconset/logo-40@3x.png new file mode 100644 index 0000000..dc30e8e Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-40@3x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-60@2x.png b/ios/Runner/AppIcon.appiconset/logo-60@2x.png new file mode 100644 index 0000000..dc30e8e Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-60@2x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-60@3x.png b/ios/Runner/AppIcon.appiconset/logo-60@3x.png new file mode 100644 index 0000000..dbaf1a7 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-60@3x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-76.png b/ios/Runner/AppIcon.appiconset/logo-76.png new file mode 100644 index 0000000..93043c1 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-76.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-76@2x.png b/ios/Runner/AppIcon.appiconset/logo-76@2x.png new file mode 100644 index 0000000..92107f2 Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-76@2x.png differ diff --git a/ios/Runner/AppIcon.appiconset/logo-83.5@2x.png b/ios/Runner/AppIcon.appiconset/logo-83.5@2x.png new file mode 100644 index 0000000..039243c Binary files /dev/null and b/ios/Runner/AppIcon.appiconset/logo-83.5@2x.png differ diff --git a/lib/features/app_layout/view/app_layout.dart b/lib/features/app_layout/view/app_layout.dart index 39605f8..1d2e3a4 100644 --- a/lib/features/app_layout/view/app_layout.dart +++ b/lib/features/app_layout/view/app_layout.dart @@ -23,7 +23,7 @@ class AppLayout extends StatelessWidget { child: Scaffold( backgroundColor: ColorsManager.backgroundColor, extendBodyBehindAppBar: true, - extendBody: true, + // extendBody: true, appBar: DefaultAppBar(), body: AppBody(), bottomNavigationBar: DefaultNavBar(), diff --git a/lib/features/app_layout/view/widgets/app_body.dart b/lib/features/app_layout/view/widgets/app_body.dart index d8bcfe4..4db97a2 100644 --- a/lib/features/app_layout/view/widgets/app_body.dart +++ b/lib/features/app_layout/view/widgets/app_body.dart @@ -26,8 +26,7 @@ class AppBody extends StatelessWidget { ), ), child: Padding( - padding: const EdgeInsets.only( - top: 60, right: 15, left: 15, bottom: 100), + padding: const EdgeInsets.only(top: 60, right: 15, left: 15), child: NavCubit.of(context).currentPage, ), ); diff --git a/lib/features/app_layout/view/widgets/default_nav_bar.dart b/lib/features/app_layout/view/widgets/default_nav_bar.dart index 86ff70a..7d517d3 100644 --- a/lib/features/app_layout/view/widgets/default_nav_bar.dart +++ b/lib/features/app_layout/view/widgets/default_nav_bar.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/nav_cubit.dart'; +import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; class DefaultNavBar extends StatelessWidget { @@ -17,7 +18,12 @@ class DefaultNavBar extends StatelessWidget { padding: const EdgeInsets.only(bottom: 27), child: BottomNavigationBar( backgroundColor: Colors.transparent, - onTap: (int index) => cubit.updatePageIndex(index, context), + onTap: (int index) { + cubit.updatePageIndex(index, context); + if (DevicesCubit.get(context).chosenCategoryView != null) { + Navigator.pop(context); + } + }, currentIndex: cubit.getPageIndex, selectedItemColor: ColorsManager.primaryColor, selectedLabelStyle: const TextStyle( diff --git a/lib/features/devices/bloc/ac_cubit.dart b/lib/features/devices/bloc/ac_cubit.dart index e1c67c0..e6a0a1f 100644 --- a/lib/features/devices/bloc/ac_cubit.dart +++ b/lib/features/devices/bloc/ac_cubit.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:meta/meta.dart'; import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; @@ -13,6 +14,20 @@ class AcCubit extends Cubit { static AcCubit get(context) => BlocProvider.of(context); + void selectAC(ACModel model) { + model.isSelected = !model.isSelected; + emit(ACSelected()); + } + + ACModel? getSelectedAC() { + for (var ac in DevicesCubit.categories[0].devices) { + if (ac.isSelected) { + return ac; + } + } + return null; + } + void turnACOn(ACModel model) { if (!model.status) { model.status = true; @@ -47,6 +62,7 @@ class AcCubit extends Cubit { for (var ac in DevicesCubit.categories[0].devices) { ac.status = false; } + updateACsStatus(); emit(SwitchACsOff()); } @@ -54,6 +70,7 @@ class AcCubit extends Cubit { for (var ac in DevicesCubit.categories[0].devices) { ac.status = true; } + updateACsStatus(); emit(SwitchACsOn()); } @@ -65,12 +82,6 @@ class AcCubit extends Cubit { emit(ACsTempChanged(temperature)); } - // void setACTemp(int index, double temperature) { - // DevicesCubit.categories[0].devices[index].temperature = temperature; - // averageTempForAll(); - // emit(ACsTempChanged(temperature)); - // } - void increaseACTemp(int index) { DevicesCubit.categories[0].devices[index].temperature += .5; averageTempForAll(); @@ -83,6 +94,12 @@ class AcCubit extends Cubit { emit(ACsTempChanged(DevicesCubit.categories[0].devices[index].temperature)); } + void setACTemp(ACModel model, double temp) { + model.temperature = temp; + averageTempForAll(); + emit(ACsTempChanged(temp)); + } + double getTemp(int index) { return DevicesCubit.categories[0].devices[index].temperature; } diff --git a/lib/features/devices/bloc/ac_state.dart b/lib/features/devices/bloc/ac_state.dart index 14ded7d..4031a13 100644 --- a/lib/features/devices/bloc/ac_state.dart +++ b/lib/features/devices/bloc/ac_state.dart @@ -26,3 +26,5 @@ class ACsTempModeChanged extends AcState {} class ACTurnedOn extends AcState {} class ACTurnedOff extends AcState {} + +class ACSelected extends AcState {} diff --git a/lib/features/devices/bloc/devices_cubit.dart b/lib/features/devices/bloc/devices_cubit.dart index e45a6d6..7fe69cf 100644 --- a/lib/features/devices/bloc/devices_cubit.dart +++ b/lib/features/devices/bloc/devices_cubit.dart @@ -8,7 +8,7 @@ import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_view.d import 'package:syncrow_app/generated/assets.dart'; import '../model/device_category_model.dart'; -import '../view/widgets/ACs/ac_view.dart'; +import '../view/widgets/ACs/acs_view.dart'; import '../view/widgets/lights/lights_view.dart'; part 'devices_state.dart'; @@ -24,7 +24,6 @@ class DevicesCubit extends Cubit { device.status = category.devicesStatus; } emit(CategorySwitchChanged()); - print('${category.name} switch value: ${category.devicesStatus} '); } static DevicesCubit get(context) => BlocProvider.of(context); @@ -52,7 +51,7 @@ class DevicesCubit extends Cubit { icon: Assets.iconsAC, name: 'ACs', type: DeviceType.AC, - page: const ACView(), + page: const ACsView(), ), DevicesCategoryModel( devices: [], @@ -124,6 +123,9 @@ class DevicesCubit extends Cubit { static void clearCategoriesSelection() { for (var category in categories) { category.isSelected = false; + for (var device in category.devices) { + device.isSelected = false; + } } } } diff --git a/lib/features/devices/model/ac_model.dart b/lib/features/devices/model/ac_model.dart index 2f95f39..cf342a8 100644 --- a/lib/features/devices/model/ac_model.dart +++ b/lib/features/devices/model/ac_model.dart @@ -8,6 +8,8 @@ class ACModel { late int tempMode; + bool isSelected = false; + ACModel({ required this.name, required this.id, diff --git a/lib/features/devices/view/widgets/ACs/ac_interface.dart b/lib/features/devices/view/widgets/ACs/ac_interface.dart new file mode 100644 index 0000000..5bf5be2 --- /dev/null +++ b/lib/features/devices/view/widgets/ACs/ac_interface.dart @@ -0,0 +1,41 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:gap/gap.dart'; +import 'package:syncrow_app/features/devices/model/ac_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'; + +class AcInterface extends StatelessWidget { + const AcInterface({super.key, required this.acModel}); + + final ACModel acModel; + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const Gap(20), + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 400, + ), + child: AcInterfaceTempUnit( + acModel: acModel, + ), + ), + ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 130, + ), + child: AcInterfaceControls( + acModel: acModel, + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/ACs/ac_interface_controls.dart b/lib/features/devices/view/widgets/ACs/ac_interface_controls.dart new file mode 100644 index 0000000..b22d69d --- /dev/null +++ b/lib/features/devices/view/widgets/ACs/ac_interface_controls.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:gap/gap.dart'; +import 'package:syncrow_app/features/devices/model/ac_model.dart'; +import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_unit.dart'; +import 'package:syncrow_app/features/shared_widgets/default_container.dart'; + +import '../../../../../generated/assets.dart'; + +class AcInterfaceControls extends StatelessWidget { + const AcInterfaceControls({ + super.key, + required this.acModel, + }); + + final ACModel acModel; + + @override + Widget build(BuildContext context) { + return Expanded( + flex: 3, + child: Column( + children: [ + const Gap(10), + ACModeControlUnit(model: acModel), + Gap(10), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () {}, + child: DefaultContainer( + height: 55, + child: Center( + child: SvgPicture.asset(Assets.iconsAutomatedClock), + ), + ), + ), + ), + const Gap(10), + Expanded( + child: InkWell( + onTap: () {}, + child: DefaultContainer( + height: 55, + child: Center( + child: SvgPicture.asset(Assets.iconsLock), + ), + ), + ), + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/ACs/ac_interface_temp_unit.dart b/lib/features/devices/view/widgets/ACs/ac_interface_temp_unit.dart new file mode 100644 index 0000000..298689b --- /dev/null +++ b/lib/features/devices/view/widgets/ACs/ac_interface_temp_unit.dart @@ -0,0 +1,148 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.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/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/generated/assets.dart'; +import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; +import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; + +import '../../../model/ac_model.dart'; + +class AcInterfaceTempUnit extends StatelessWidget { + const AcInterfaceTempUnit({ + super.key, + required this.acModel, + }); + + final ACModel acModel; + + @override + Widget build(BuildContext context) { + double coolTo = acModel.temperature; + return BlocBuilder( + builder: (context, state) { + return DefaultContainer( + child: Column( + children: [ + Expanded( + flex: 8, + child: SizedBox( + width: 300, + child: SleekCircularSlider( + appearance: CircularSliderAppearance( + customWidths: CustomSliderWidths( + progressBarWidth: 15, + trackWidth: 15, + shadowWidth: 0, + ), + customColors: CustomSliderColors( + progressBarColor: + ColorsManager.primaryColor.withOpacity(.6), + trackColor: ColorsManager.greyColor, + dotColor: Colors.transparent, + ), + infoProperties: InfoProperties( + bottomLabelText: 'CURRENT TEMP', + bottomLabelStyle: context.bodyLarge.copyWith( + color: Colors.grey, + fontWeight: FontsManager.regular, + ), + modifier: (double value) { + return '${acModel.temperature.toStringAsFixed(1)}°C'; + }, + mainLabelStyle: context.titleLarge.copyWith( + height: 0, + letterSpacing: -3, + color: Colors.black, + fontSize: 60, + shadows: [ + Shadow( + color: Colors.black.withOpacity(0.5), + offset: const Offset(0, 3), + blurRadius: 6, + ), + ], + ), + ), + ), + min: 20, + max: 30, + initialValue: 20, + onChange: (value) { + String valueAsString = value.toStringAsFixed(1); + if (valueAsString.endsWith(".0") || + valueAsString.endsWith(".5")) { + value = double.parse(valueAsString); + if (value != acModel.temperature) { + AcCubit.get(context).setTempToAll(value); + } + } + }, + ), + ), + ), + Expanded( + flex: 2, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox.square( + dimension: 24, + child: InkWell( + onTap: () { + // AcCubit.get(context).setACTemp(acModel, coolTo - .5); + AcCubit.get(context).setACTemp(acModel, coolTo); + coolTo = coolTo - .5; + }, + child: SvgPicture.asset( + Assets.iconsMinus, + ), + ), + ), + Column( + children: [ + BodyLarge( + text: "$coolTo° C", + style: context.bodyLarge.copyWith( + color: + ColorsManager.primaryColor.withOpacity(0.6), + fontWeight: FontsManager.bold, + fontSize: 30, + height: 0), + ), + const BodyMedium( + text: 'COOL TO', + fontSize: 18, + ) + ], + ), + SizedBox.square( + dimension: 24, + child: InkWell( + onTap: () { + // AcCubit.get(context).setACTemp(acModel, coolTo + .5); + AcCubit.get(context).setACTemp(acModel, coolTo); + coolTo = coolTo + .5; + }, + child: SvgPicture.asset( + Assets.iconsPlus, + height: 24, + width: 24, + ), + ), + ), + ], + ), + ) + ], + ), + ); + }, + ); + } +} diff --git a/lib/features/devices/view/widgets/ACs/a_c_control_unit.dart b/lib/features/devices/view/widgets/ACs/ac_mode_control_unit.dart similarity index 86% rename from lib/features/devices/view/widgets/ACs/a_c_control_unit.dart rename to lib/features/devices/view/widgets/ACs/ac_mode_control_unit.dart index 1df4fc9..c87e977 100644 --- a/lib/features/devices/view/widgets/ACs/a_c_control_unit.dart +++ b/lib/features/devices/view/widgets/ACs/ac_mode_control_unit.dart @@ -6,8 +6,8 @@ import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import '../../../../../generated/assets.dart'; -class ACControlUnit extends StatefulWidget { - const ACControlUnit({ +class ACModeControlUnit extends StatefulWidget { + const ACModeControlUnit({ super.key, required this.model, }); @@ -15,10 +15,10 @@ class ACControlUnit extends StatefulWidget { final ACModel model; @override - State createState() => _ACControlUnitState(); + State createState() => _ACModeControlUnitState(); } -class _ACControlUnitState extends State { +class _ACModeControlUnitState extends State { var fanSpeeds = [ Assets.iconsFan0, Assets.iconsFan1, @@ -34,6 +34,7 @@ class _ACControlUnitState extends State { @override Widget build(BuildContext context) { + //TODO Move the fanSpeeds and tempModes to the Cubit return Row( children: [ Expanded( diff --git a/lib/features/devices/view/widgets/ACs/ac_temp_widget.dart b/lib/features/devices/view/widgets/ACs/ac_temp_widget.dart new file mode 100644 index 0000000..daa72c1 --- /dev/null +++ b/lib/features/devices/view/widgets/ACs/ac_temp_widget.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:syncrow_app/features/devices/bloc/ac_cubit.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/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; + +import '../../../../../generated/assets.dart'; + +class ACTempWidget extends StatelessWidget { + const ACTempWidget( + this.index, { + super.key, + }); + + final int index; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return DefaultContainer( + height: 60, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox.square( + dimension: 24, + child: InkWell( + onTap: () { + AcCubit.get(context).decreaseACTemp(index); + }, + child: SvgPicture.asset( + Assets.iconsMinus, + ), + ), + ), + BodyLarge( + text: "${AcCubit.get(context).getTemp(index)}° C", + style: context.bodyLarge.copyWith( + color: ColorsManager.primaryColor.withOpacity(0.6), + fontSize: 23, + ), + ), + SizedBox.square( + dimension: 24, + child: InkWell( + onTap: () { + AcCubit.get(context).increaseACTemp(index); + }, + child: SvgPicture.asset( + Assets.iconsPlus, + height: 24, + width: 24, + ), + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/features/devices/view/widgets/ACs/ac_view.dart b/lib/features/devices/view/widgets/ACs/ac_view.dart deleted file mode 100644 index a456836..0000000 --- a/lib/features/devices/view/widgets/ACs/ac_view.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:gap/gap.dart'; -import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart'; -import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart'; -import 'package:syncrow_app/features/devices/view/widgets/ACs/a_c_control_unit.dart'; -import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_a_c_switch.dart'; -import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_a_c_temp.dart'; -import 'package:syncrow_app/features/devices/view/widgets/devices_temp_widget.dart'; -import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'; -import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; - -class ACView extends StatelessWidget { - const ACView({super.key}); - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (context) => AcCubit(), - child: BlocBuilder( - builder: (context, state) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - // universal AC controller - const Gap(10), - const BodySmall(text: "All ACs"), - const Gap(5), - const UniversalACSwitch(), - const Gap(10), - const UniversalACTemp(), - const Gap(10), - - // other ACs controller - ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - itemCount: DevicesCubit.categories[0].devices.length, - itemBuilder: (context, index) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BodySmall( - text: - DevicesCubit.categories[0].devices[index].name), - const Gap(5), - DevicesDefaultSwitch( - model: DevicesCubit.categories[0].devices[index], - ), - const Gap(10), - DevicesTempWidget( - index, - ), - const Gap(10), - ACControlUnit( - model: DevicesCubit.categories[0].devices[index], - ), - const Gap(10), - ], - ); - }, - ), - ], - ), - ); - }, - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/ACs/acs_list.dart b/lib/features/devices/view/widgets/ACs/acs_list.dart new file mode 100644 index 0000000..8079fcb --- /dev/null +++ b/lib/features/devices/view/widgets/ACs/acs_list.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:syncrow_app/features/devices/bloc/ac_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_temp_widget.dart'; +import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_ac_switch.dart'; +import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_ac_temp.dart'; +import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'; +import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart'; + +class ACsList extends StatelessWidget { + const ACsList({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // universal AC controller + const Gap(10), + const BodySmall(text: "All ACs"), + const Gap(5), + const UniversalACSwitch(), + const Gap(10), + const UniversalACTemp(), + const Gap(10), + + // other ACs controls + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.all(0), + itemCount: DevicesCubit.categories[0].devices.length, + itemBuilder: (context, index) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + BodySmall( + text: DevicesCubit.categories[0].devices[index].name), + IconButton( + onPressed: () { + AcCubit.get(context).selectAC( + DevicesCubit.categories[0].devices[index]); + }, + icon: const Icon( + Icons.arrow_forward_ios, + ), + style: ButtonStyle( + padding: MaterialStateProperty.all( + const EdgeInsets.all(0), + ), + iconSize: MaterialStateProperty.all(15), + alignment: Alignment.bottomRight, + ), + ), + ], + ), + const Gap(5), + DevicesDefaultSwitch( + model: DevicesCubit.categories[0].devices[index], + ), + const Gap(10), + ACTempWidget( + index, + ), + const Gap(10), + ACModeControlUnit( + model: DevicesCubit.categories[0].devices[index], + ), + const Gap(10), + ], + ); + }, + ), + ], + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/ACs/acs_view.dart b/lib/features/devices/view/widgets/ACs/acs_view.dart new file mode 100644 index 0000000..0df5a6e --- /dev/null +++ b/lib/features/devices/view/widgets/ACs/acs_view.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.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_nav_bar.dart'; +import 'package:syncrow_app/features/devices/bloc/ac_cubit.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/acs_list.dart'; + +import '../../../../../generated/assets.dart'; +import '../../../../../utils/resource_manager/color_manager.dart'; + +class ACsView extends StatelessWidget { + const ACsView({super.key}); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => AcCubit(), + child: BlocBuilder( + builder: (context, state) { + ACModel? selectedAC = AcCubit.get(context).getSelectedAC(); + 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: const DefaultAppBar(), + body: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + Assets.imagesBackground, + ), + fit: BoxFit.cover, + opacity: 0.4, + ), + ), + child: Padding( + padding: const EdgeInsets.only( + top: 60, right: 15, left: 15, bottom: 80), + child: SizedBox.expand( + child: selectedAC != null + ? AcInterface(acModel: selectedAC) + : const ACsList(), + ), + ), + ), + bottomNavigationBar: const DefaultNavBar(), + ), + ), + ); + }, + ), + ); + } +} diff --git a/lib/features/devices/view/widgets/ACs/universal_a_c_switch.dart b/lib/features/devices/view/widgets/ACs/universal_ac_switch.dart similarity index 100% rename from lib/features/devices/view/widgets/ACs/universal_a_c_switch.dart rename to lib/features/devices/view/widgets/ACs/universal_ac_switch.dart diff --git a/lib/features/devices/view/widgets/ACs/universal_a_c_temp.dart b/lib/features/devices/view/widgets/ACs/universal_ac_temp.dart similarity index 100% rename from lib/features/devices/view/widgets/ACs/universal_a_c_temp.dart rename to lib/features/devices/view/widgets/ACs/universal_ac_temp.dart diff --git a/lib/features/devices/view/widgets/devices_temp_widget.dart b/lib/features/devices/view/widgets/devices_temp_widget.dart deleted file mode 100644 index 25e78e2..0000000 --- a/lib/features/devices/view/widgets/devices_temp_widget.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:syncrow_app/features/devices/bloc/ac_cubit.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/utils/context_extension.dart'; -import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; - -import '../../../../generated/assets.dart'; - -class DevicesTempWidget extends StatelessWidget { - const DevicesTempWidget( - this.index, { - super.key, - }); - - final int index; - - // double temp = widget.model.temperature; - @override - Widget build(BuildContext context) { - return DefaultContainer( - height: 60, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - SizedBox.square( - dimension: 24, - child: InkWell( - onTap: () { - AcCubit.get(context).decreaseACTemp(index); - }, - child: SvgPicture.asset( - Assets.iconsMinus, - ), - ), - ), - BodyLarge( - text: "${AcCubit.get(context).getTemp(index)}° C", - style: context.bodyLarge.copyWith( - color: ColorsManager.primaryColor.withOpacity(0.6), - fontSize: 23, - ), - ), - SizedBox.square( - dimension: 24, - child: InkWell( - onTap: () { - AcCubit.get(context).increaseACTemp(index); - }, - child: SvgPicture.asset( - Assets.iconsPlus, - height: 24, - width: 24, - ), - ), - ), - ], - ), - ); - } -} diff --git a/lib/features/devices/view/widgets/devices_view_body.dart b/lib/features/devices/view/widgets/devices_view_body.dart index 45b950e..e2e28e6 100644 --- a/lib/features/devices/view/widgets/devices_view_body.dart +++ b/lib/features/devices/view/widgets/devices_view_body.dart @@ -17,8 +17,7 @@ class DevicesViewBody extends StatelessWidget { builder: (context, state) { return state is DevicesLoading ? const Center(child: CircularProgressIndicator()) - : DevicesCubit.get(context).chosenCategoryView ?? - const CategoriesView(); + : const CategoriesView(); }, ), ); diff --git a/lib/features/devices/view/widgets/switches.dart b/lib/features/devices/view/widgets/switches.dart index f5b0cc0..1324bed 100644 --- a/lib/features/devices/view/widgets/switches.dart +++ b/lib/features/devices/view/widgets/switches.dart @@ -30,7 +30,12 @@ class Switches extends StatelessWidget { itemCount: DevicesCubit.categories.length, itemBuilder: (_, index) { return InkWell( - onTap: () => DevicesCubit.get(context).selectCategory(index), + onTap: () { + DevicesCubit.get(context).selectCategory(index); + Navigator.push(context, MaterialPageRoute(builder: (context) { + return DevicesCubit.get(context).chosenCategoryView!; + })); + }, child: DefaultContainer( child: Padding( padding: const EdgeInsets.only(top: 10, right: 10, left: 10), diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart index 2a4bff4..fa1a4b2 100644 --- a/lib/generated/assets.dart +++ b/lib/generated/assets.dart @@ -5,6 +5,7 @@ class Assets { static const String fontsAftikaRegular = 'assets/fonts/AftikaRegular.ttf'; static const String iconsAC = 'assets/icons/AC.svg'; static const String iconsActive = 'assets/icons/active.svg'; + static const String iconsAutomatedClock = 'assets/icons/automated_clock.svg'; static const String iconsCO2 = 'assets/icons/CO2.svg'; static const String iconsColdMode = 'assets/icons/coldMode.svg'; static const String iconsCurtain = 'assets/icons/Curtain.svg'; @@ -24,6 +25,7 @@ class Assets { static const String iconsLayout = 'assets/icons/Layout.svg'; static const String iconsLayoutFill = 'assets/icons/Layout-fill.svg'; static const String iconsLight = 'assets/icons/Light.svg'; + static const String iconsLock = 'assets/icons/lock.svg'; static const String iconsLogo = 'assets/icons/logo.png'; static const String iconsMenu = 'assets/icons/Menu.svg'; static const String iconsMenuFill = 'assets/icons/Menu-fill.svg'; diff --git a/lib/my_app.dart b/lib/my_app.dart index 838deff..e5f7209 100644 --- a/lib/my_app.dart +++ b/lib/my_app.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart'; import 'package:syncrow_app/features/app_layout/bloc/nav_cubit.dart'; +import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/theme_manager.dart'; +import 'features/devices/bloc/devices_cubit.dart'; import 'navigation/router.dart' as router; import 'navigation/routing_constants.dart'; @@ -23,6 +24,9 @@ class MyApp extends StatelessWidget { BlocProvider( create: (context) => NavCubit(), ), + BlocProvider( + create: (context) => DevicesCubit(), + ), ], child: MaterialApp( debugShowCheckedModeBanner: false, diff --git a/lib/utils/resource_manager/color_manager.dart b/lib/utils/resource_manager/color_manager.dart index 3f66b50..72321fa 100644 --- a/lib/utils/resource_manager/color_manager.dart +++ b/lib/utils/resource_manager/color_manager.dart @@ -8,6 +8,6 @@ abstract class ColorsManager { static const Color onSecondaryColor = Color(0xFF023DFE); static const Color primaryTextColor = Colors.black; - static const Color greyColor = Color(0xFFd9d9d9); + static const Color greyColor = Color(0xFFd5d5d5); static const Color backgroundColor = Color(0xFFececec); } diff --git a/pubspec.lock b/pubspec.lock index 8236457..cfe04c8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -113,6 +113,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.1" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -209,6 +217,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: "00b74ae680df6b1135bdbea00a7d1fc072a9180b7c3f3702e4b19a9943f5ed7d" + url: "https://pub.dev" + source: hosted + version: "0.66.2" flutter: dependency: "direct main" description: flutter @@ -618,6 +634,14 @@ packages: description: flutter source: sdk version: "0.0.99" + sleek_circular_slider: + dependency: "direct main" + description: + name: sleek_circular_slider + sha256: "8844d036269a13e60dda4e16534d30d27cacaff8d2f10d042d9d61d111468b13" + url: "https://pub.dev" + source: hosted + version: "2.0.1" source_span: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d830539..123e500 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,6 +19,8 @@ dependencies: flutter_animated_dialog: ^2.0.1 gap: ^3.0.1 flutter_svg: ^2.0.9 + sleek_circular_slider: ^2.0.1 + fl_chart: ^0.66.2 # Utility Packages flutter_secure_storage: ^9.0.0