Merged Auth branch & Curtains branch

This commit is contained in:
Mohammad Salameh
2024-03-10 15:06:04 +03:00
60 changed files with 1715 additions and 595 deletions
+111 -6
View File
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.dart';
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
import 'package:syncrow_app/features/menu/view/menu_view.dart';
@@ -17,13 +18,117 @@ class NavCubit extends Cubit<NavState> {
static NavCubit of(context) => BlocProvider.of<NavCubit>(context);
static int pageIndex = 0;
int get getPageIndex => pageIndex;
static Map<String, List<Widget>> appBarActions = {
'Dashboard': [
IconButton(
icon: const Icon(
Icons.add,
size: 25,
),
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
],
'Devices': [
IconButton(
icon: Image.asset(
Assets.iconsFilter,
height: 20,
width: 20,
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.add,
size: 25,
),
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.more_vert,
size: 25,
),
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
],
'Routine': [
IconButton(
icon: Image.asset(
Assets.iconsFilter,
height: 20,
width: 20,
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.add,
size: 25,
),
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.more_vert,
size: 25,
),
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
],
'Menu': [
IconButton(
icon: Image.asset(
Assets.iconsQrScan,
height: 20,
width: 20,
),
onPressed: () {},
),
IconButton(
icon: Image.asset(
Assets.iconsSettings,
height: 20,
width: 20,
),
onPressed: () {},
),
],
};
Map<String, List<Widget>> appBarActions = {
'Home': [],
'Scene': [],
'Smart': [],
'Profile': [],
static Map<String, Widget?> appBarLeading = {
'Dashboard': const AppBarHomeDropdown(),
'Devices': const AppBarHomeDropdown(),
'Routine': const AppBarHomeDropdown(),
'Menu': Padding(
padding: const EdgeInsets.only(left: 15),
child: Image.asset(
Assets.imagesLogoHorizontal,
height: 15,
width: 100,
fit: BoxFit.scaleDown,
),
),
};
var bottomNavItems = [
@@ -0,0 +1,270 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/model/curtain_model.dart';
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/light_model.dart';
import 'package:syncrow_app/features/devices/model/room_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_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/lights/lights_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_view.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
part 'spaces_state.dart';
class SpacesCubit extends Cubit<SpacesState> {
SpacesCubit() : super(SpacesInitial());
static SpacesCubit get(context) => BlocProvider.of(context);
static List<SpaceModel> spaces = [
SpaceModel(
id: '0',
name: 'Home',
rooms: [
RoomModel(id: '0', name: 'Living Room', categories: [
DevicesCategoryModel(
devices: [
ACModel(
name: "Living Room AC",
id: '0',
status: false,
temperature: 20,
fanSpeed: 0,
tempMode: 0,
coolTo: 20,
type: DeviceType.AC,
image: '',
timer: null,
bounds: Bounds(
min: 20,
max: 30,
),
),
],
icon: Assets.iconsAC,
name: 'ACs',
type: DeviceType.AC,
page: const ACsView(),
),
DevicesCategoryModel(
devices: [
LightModel(
name: "Living Room Light",
id: '0',
status: false,
color: 0,
brightness: 20,
lightingMode: 1,
timer: null,
type: DeviceType.Lights,
image: '',
recentColors: [
0xFF83D9FF,
0xFFFC3E81,
0xFFC0FF66,
0xFFFDC242,
],
),
],
icon: Assets.iconsLight,
name: 'Lights',
type: DeviceType.Lights,
page: const LightsView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsDoorLock,
name: 'Doors',
type: DeviceType.Door,
page: const DoorView(),
),
DevicesCategoryModel(
devices: [
CurtainModel(
openPercentage: 10,
id: "1",
name: "Living Room Curtain",
status: false,
type: DeviceType.Curtain,
image: '',
timer: null,
),
],
icon: Assets.iconsCurtain,
name: 'Curtains',
type: DeviceType.Curtain,
page: const CurtainView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsGateway,
name: 'Gateway',
type: DeviceType.Gateway,
page: const GateWayView(),
),
]),
RoomModel(id: '1', name: 'Bedroom', categories: [
DevicesCategoryModel(
devices: [
ACModel(
name: "Living Room AC",
id: '0',
status: false,
temperature: 20,
fanSpeed: 0,
tempMode: 0,
coolTo: 20,
type: DeviceType.AC,
image: '',
timer: null,
bounds: Bounds(
min: 20,
max: 30,
),
),
],
icon: Assets.iconsAC,
name: 'ACs',
type: DeviceType.AC,
page: const ACsView(),
),
DevicesCategoryModel(
devices: [
LightModel(
name: "Living Room Light",
id: '0',
status: false,
color: 0,
brightness: 20,
lightingMode: 1,
timer: null,
type: DeviceType.Lights,
image: '',
recentColors: [
0xFF83D9FF,
0xFFFC3E81,
0xFFC0FF66,
0xFFFDC242,
],
),
],
icon: Assets.iconsLight,
name: 'Lights',
type: DeviceType.Lights,
page: const LightsView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsDoorLock,
name: 'Doors',
type: DeviceType.Door,
page: const DoorView(),
),
DevicesCategoryModel(
devices: [
CurtainModel(
openPercentage: 10,
id: "1",
name: "Living Room Curtain",
status: false,
type: DeviceType.Curtain,
image: '',
timer: null,
),
],
icon: Assets.iconsCurtain,
name: 'Curtains',
type: DeviceType.Curtain,
page: const CurtainView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsGateway,
name: 'Gateway',
type: DeviceType.Gateway,
page: const GateWayView(),
),
]),
],
),
SpaceModel(
id: '1',
name: 'Office',
rooms: [],
),
SpaceModel(
id: '2',
name: 'Parent\'s House',
rooms: [],
),
];
SpaceModel selectedSpace = spaces.first;
RoomModel? selectedRoom;
PageController devicesPageController = PageController();
PageController roomsPageController = PageController();
var duration = const Duration(milliseconds: 300);
selectSpace(SpaceModel space) {
selectedSpace = space;
emit(SpacesSelected(space));
}
roomSliderPageChanged(int index) {
devicesPageController.animateToPage(
index,
duration: duration,
curve: Curves.linear,
);
if (index == 0) {
unselectRoom();
} else {
selectedRoom = selectedSpace.rooms[index - 1];
}
emit(RoomSelected(selectedRoom!));
}
devicesPageChanged(int index) {
roomsPageController.animateToPage(
index,
duration: const Duration(milliseconds: 300),
curve: Curves.linear,
);
if (index == 0) {
unselectRoom();
} else {
selectedRoom = selectedSpace.rooms[index - 1];
}
emit(RoomSelected(selectedRoom!));
}
unselectRoom() {
selectedRoom = null;
devicesPageController.animateToPage(
0,
duration: duration,
curve: Curves.linear,
);
roomsPageController.animateToPage(
0,
duration: duration,
curve: Curves.linear,
);
emit(RoomUnSelected());
}
//TODO implement the methods to fetch the spaces from the API
}
@@ -0,0 +1,27 @@
part of 'spaces_cubit.dart';
abstract class SpacesState {}
class SpacesInitial extends SpacesState {}
class SpacesLoading extends SpacesState {}
class SpacesLoaded extends SpacesState {
final List<SpaceModel> spaces;
SpacesLoaded(this.spaces);
}
class SpacesSelected extends SpacesState {
final SpaceModel space;
SpacesSelected(this.space);
}
class RoomSelected extends SpacesState {
final RoomModel room;
RoomSelected(this.room);
}
class RoomUnSelected extends SpacesState {}
@@ -0,0 +1,29 @@
import 'package:syncrow_app/features/devices/model/room_model.dart';
class SpaceModel {
final String id;
final String name;
final List<RoomModel> rooms;
SpaceModel({
required this.id,
required this.name,
required this.rooms,
});
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'rooms': rooms,
};
}
factory SpaceModel.fromJson(Map<String, dynamic> json) {
return SpaceModel(
id: json['id'],
name: json['name'],
rooms: json['rooms'],
);
}
}
+4 -4
View File
@@ -19,14 +19,14 @@ class AppLayout extends StatelessWidget {
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
statusBarIconBrightness: Brightness.light,
),
child: const SafeArea(
child: SafeArea(
child: Scaffold(
backgroundColor: ColorsManager.backgroundColor,
extendBodyBehindAppBar: true,
extendBody: true,
appBar: DefaultAppBar(),
body: AppBody(),
bottomNavigationBar: DefaultNavBar(),
appBar: DefaultAppBar(context),
body: const AppBody(),
bottomNavigationBar: const DefaultNavBar(),
),
),
);
@@ -1,9 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/app_layout/bloc/spaces_cubit.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import '../../../../generated/assets.dart';
import '../../../shared_widgets/text_widgets/body_large.dart';
class AppBarHomeDropdown extends StatelessWidget {
const AppBarHomeDropdown({
@@ -12,33 +15,60 @@ class AppBarHomeDropdown extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () {},
child: SizedBox(
width: 150,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SvgPicture.asset(
Assets.iconsHome,
width: 25,
height: 25,
colorFilter: const ColorFilter.mode(
ColorsManager.textPrimaryColor,
BlendMode.srcIn,
),
),
const SizedBox(width: 5),
const BodyLarge(text: 'Home'),
const SizedBox(width: 5),
const Icon(
return BlocBuilder<SpacesCubit, SpacesState>(
builder: (context, state) {
return Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: DropdownButton(
icon: const Icon(
Icons.expand_more,
color: Colors.black,
)
],
),
),
size: 25,
),
underline: const SizedBox.shrink(),
padding: const EdgeInsets.all(0),
borderRadius: BorderRadius.circular(20),
value: SpacesCubit.get(context).selectedSpace,
items: SpacesCubit.spaces.map((space) {
return DropdownMenuItem(
value: space,
child: SizedBox(
width: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SvgPicture.asset(
Assets.iconsHome,
width: 25,
height: 25,
colorFilter: const ColorFilter.mode(
ColorsManager.textPrimaryColor,
BlendMode.srcIn,
),
),
const SizedBox(width: 5),
Expanded(
child: BodyMedium(
text: space.name,
style: context.bodyMedium.copyWith(
fontSize: 15,
color: ColorsManager.textPrimaryColor,
overflow: TextOverflow.ellipsis,
),
),
),
],
),
),
);
}).toList(),
onChanged: (value) {
SpacesCubit.get(context).selectSpace(value!);
},
),
);
},
);
}
}
@@ -25,11 +25,7 @@ class AppBody extends StatelessWidget {
opacity: 0.4,
),
),
child: Padding(
padding:
const EdgeInsets.only(top: 60, right: 15, left: 15, bottom: 80),
child: NavCubit.of(context).currentPage,
),
child: NavCubit.of(context).currentPage,
);
},
);
@@ -1,10 +1,12 @@
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/app_layout/view/widgets/app_bar_home_dropdown.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
const DefaultAppBar({super.key});
const DefaultAppBar(this.context, {super.key});
final BuildContext context;
@override
Widget build(BuildContext context) {
@@ -17,16 +19,10 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
child: AppBar(
backgroundColor: Colors.transparent,
leadingWidth: 150,
leading: const AppBarHomeDropdown(),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.add,
size: 35,
),
onPressed: () {},
),
],
leading: NavCubit.appBarLeading[
NavCubit().bottomNavItems[NavCubit.pageIndex].label],
actions: NavCubit.appBarActions[
NavCubit().bottomNavItems[NavCubit.pageIndex].label],
),
);
},
@@ -34,5 +30,5 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
}
@override
Size get preferredSize => const Size.fromHeight(100);
Size get preferredSize => Size.fromHeight(Constants.appBarHeight);
}
@@ -3,6 +3,7 @@ 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';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class DefaultNavBar extends StatelessWidget {
const DefaultNavBar({
@@ -14,8 +15,8 @@ class DefaultNavBar extends StatelessWidget {
return BlocBuilder<NavCubit, NavState>(
builder: (context, state) {
var cubit = NavCubit.of(context);
return Padding(
padding: const EdgeInsets.only(bottom: 27),
return SizedBox(
height: Constants.bottomNavBarHeight,
child: BottomNavigationBar(
backgroundColor: Colors.transparent,
onTap: (int index) {
@@ -24,7 +25,7 @@ class DefaultNavBar extends StatelessWidget {
DevicesCubit().clearCategoriesSelection(context);
}
},
currentIndex: cubit.getPageIndex,
currentIndex: NavCubit.pageIndex,
selectedItemColor: ColorsManager.primaryColor,
selectedLabelStyle: const TextStyle(
color: ColorsManager.primaryColor,
+38 -29
View File
@@ -5,6 +5,7 @@ import 'package:syncrow_app/features/dashboard/view/widgets/carbon_emission.dart
import 'package:syncrow_app/features/dashboard/view/widgets/consumption.dart';
import 'package:syncrow_app/features/dashboard/view/widgets/live_monitor_tab.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
import 'widgets/energy_usage.dart';
@@ -14,37 +15,45 @@ class DashboardView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const TitleMedium(
text: StringsManager.dashboard,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
return Padding(
padding: EdgeInsets.only(
top: Constants.appBarHeight,
left: Constants.defaultPadding,
right: Constants.defaultPadding,
bottom: Constants.bottomNavBarHeight,
),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const TitleMedium(
text: StringsManager.dashboard,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
const LiveMonitorTab(),
const SizedBox(height: 10),
const EnergyUsage(),
Container(
padding: const EdgeInsets.only(top: 20),
constraints: const BoxConstraints(
minHeight: 220,
maxHeight: 240,
const LiveMonitorTab(),
const SizedBox(height: 10),
const EnergyUsage(),
Container(
padding: const EdgeInsets.only(top: 20),
constraints: const BoxConstraints(
minHeight: 220,
maxHeight: 240,
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Consumption(),
SizedBox(height: 20),
CarbonEmission(),
],
),
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Consumption(),
SizedBox(height: 20),
CarbonEmission(),
],
),
),
],
],
),
),
);
}
+11 -4
View File
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.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/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
part 'ac_state.dart';
@@ -11,8 +12,10 @@ class AcCubit extends Cubit<AcState> {
static AcCubit get(context) => BlocProvider.of(context);
static DevicesCategoryModel category = DevicesCubit.allCategories[0];
ACModel? getSelectedAC() {
for (var ac in DevicesCubit.categories[0].devices) {
for (var ac in category.devices) {
if (ac is ACModel && ac.isSelected) {
return ac;
}
@@ -21,9 +24,13 @@ class AcCubit extends Cubit<AcState> {
}
void setTempToAll(double temperature) {
for (DeviceModel ac in DevicesCubit.categories[0].devices) {
for (DeviceModel ac in category.devices) {
if (ac is ACModel) {
setACTemp(ac, temperature);
if (ac.temperature != temperature &&
ac.bounds.min <= temperature &&
temperature <= ac.bounds.max) {
setACTemp(ac, temperature);
}
}
}
universalACTemp = temperature;
@@ -38,7 +45,7 @@ class AcCubit extends Cubit<AcState> {
}
double getTemp(int index) {
var device = DevicesCubit.categories[0].devices[index];
var device = category.devices[index];
if (device is ACModel) {
return device.temperature;
}
@@ -0,0 +1,13 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
part 'curtains_state.dart';
class CurtainsCubit extends Cubit<CurtainsState> {
CurtainsCubit() : super(CurtainsInitial());
static CurtainsCubit get(context) => BlocProvider.of(context);
static DevicesCategoryModel category = DevicesCubit.allCategories[3];
}
@@ -0,0 +1,5 @@
part of 'curtains_cubit.dart';
abstract class CurtainsState {}
class CurtainsInitial extends CurtainsState {}
+71 -51
View File
@@ -1,17 +1,18 @@
import 'package:flutter/material.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/curtain_model.dart';
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/light_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_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/lights/lights_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/screens/screens_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_view.dart';
import 'package:syncrow_app/generated/assets.dart';
import '../model/device_category_model.dart';
import '../view/widgets/ACs/acs_view.dart';
import '../view/widgets/lights/lights_view.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
part 'devices_state.dart';
@@ -20,7 +21,7 @@ class DevicesCubit extends Cubit<DevicesState> {
static DevicesCubit get(context) => BlocProvider.of(context);
static List<DevicesCategoryModel> categories = [
static List<DevicesCategoryModel> allCategories = [
DevicesCategoryModel(
devices: [
ACModel(
@@ -31,8 +32,7 @@ class DevicesCubit extends Cubit<DevicesState> {
fanSpeed: 0,
tempMode: 0,
coolTo: 20,
type: '',
location: '',
type: DeviceType.AC,
image: '',
timer: null,
bounds: Bounds(
@@ -48,8 +48,7 @@ class DevicesCubit extends Cubit<DevicesState> {
fanSpeed: 0,
tempMode: 0,
coolTo: 20,
type: '',
location: '',
type: DeviceType.AC,
image: '',
timer: null,
bounds: Bounds(
@@ -65,8 +64,7 @@ class DevicesCubit extends Cubit<DevicesState> {
fanSpeed: 0,
tempMode: 0,
coolTo: 20,
type: '',
location: '',
type: DeviceType.AC,
image: '',
timer: null,
bounds: Bounds(
@@ -82,8 +80,7 @@ class DevicesCubit extends Cubit<DevicesState> {
fanSpeed: 0,
tempMode: 0,
coolTo: 20,
type: '',
location: '',
type: DeviceType.AC,
image: '',
timer: null,
bounds: Bounds(
@@ -107,8 +104,7 @@ class DevicesCubit extends Cubit<DevicesState> {
brightness: 20,
lightingMode: 1,
timer: null,
type: '',
location: '',
type: DeviceType.Lights,
image: '',
recentColors: [
0xFF83D9FF,
@@ -125,8 +121,7 @@ class DevicesCubit extends Cubit<DevicesState> {
brightness: 40,
lightingMode: 1,
timer: null,
type: '',
location: '',
type: DeviceType.Lights,
image: '',
recentColors: [
0xFF83D9FF,
@@ -143,8 +138,7 @@ class DevicesCubit extends Cubit<DevicesState> {
brightness: 60,
lightingMode: 1,
timer: null,
type: '',
location: '',
type: DeviceType.Lights,
image: '',
recentColors: [
0xFF83D9FF,
@@ -161,8 +155,7 @@ class DevicesCubit extends Cubit<DevicesState> {
brightness: 80,
lightingMode: 1,
timer: null,
type: '',
location: '',
type: DeviceType.Lights,
image: '',
recentColors: [
0xFF83D9FF,
@@ -179,8 +172,7 @@ class DevicesCubit extends Cubit<DevicesState> {
brightness: 100,
lightingMode: 1,
timer: null,
type: '',
location: '',
type: DeviceType.Lights,
image: '',
recentColors: [
0xFF83D9FF,
@@ -203,7 +195,26 @@ class DevicesCubit extends Cubit<DevicesState> {
page: const DoorView(),
),
DevicesCategoryModel(
devices: [],
devices: [
CurtainModel(
openPercentage: 10,
id: "1",
name: "Living Room Curtain",
status: false,
type: DeviceType.Curtain,
image: '',
timer: null,
),
CurtainModel(
openPercentage: 20,
id: "2",
name: "Master Bedroom Curtain",
status: false,
type: DeviceType.Curtain,
image: '',
timer: null,
),
],
icon: Assets.iconsCurtain,
name: 'Curtains',
type: DeviceType.Curtain,
@@ -226,25 +237,25 @@ class DevicesCubit extends Cubit<DevicesState> {
];
selectCategory(int index) {
for (var i = 0; i < categories.length; i++) {
for (var i = 0; i < allCategories.length; i++) {
if (i == index) {
categories[i].isSelected = true;
allCategories[i].isSelected = true;
} else {
categories[i].isSelected = false;
allCategories[i].isSelected = false;
}
}
emit(DevicesCategoryChanged());
}
unselectAllCategories() {
for (var category in categories) {
for (var category in allCategories) {
category.isSelected = false;
}
emit(DevicesCategoryChanged());
}
Widget? get chosenCategoryView {
for (var category in categories) {
for (var category in allCategories) {
if (category.isSelected) {
return category.page;
}
@@ -253,7 +264,7 @@ class DevicesCubit extends Cubit<DevicesState> {
}
selectDevice(DeviceModel device) {
for (var category in categories) {
for (var category in allCategories) {
for (var device in category.devices) {
if (device.isSelected) {
category.isSelected = false;
@@ -267,7 +278,7 @@ class DevicesCubit extends Cubit<DevicesState> {
}
DeviceModel? getSelectedDevice() {
for (var category in categories) {
for (var category in allCategories) {
for (var device in category.devices) {
if (device.isSelected) {
return device;
@@ -296,42 +307,51 @@ class DevicesCubit extends Cubit<DevicesState> {
turnOnOffDevice(DeviceModel device) {
device.status = !device.status!;
DevicesCategoryModel category =
categories.firstWhere((category) => category.devices.contains(device));
DevicesCategoryModel category = allCategories
.firstWhere((category) => category.devices.contains(device));
updateDevicesStatus(category);
emit(DeviceSwitchChanged());
}
updateDevicesStatus(DevicesCategoryModel category) {
bool? tempStatus = category.devices[0].status;
for (var ac in category.devices) {
//check if there any ac have a different status than the initial ==> turn off the universal switch
if (ac.status != tempStatus) {
category.devicesStatus = null;
if (category.devices.isNotEmpty) {
bool? tempStatus = category.devices[0].status;
for (var ac in category.devices) {
//check if there any ac have a different status than the initial ==> turn off the universal switch
if (ac.status != tempStatus) {
category.devicesStatus = null;
emit(DeviceSwitchChanged());
return;
}
category.devicesStatus = tempStatus;
emit(DeviceSwitchChanged());
return;
}
category.devicesStatus = tempStatus;
} else {
category.devicesStatus = null;
emit(DeviceSwitchChanged());
}
}
turnAllDevicesOff(DevicesCategoryModel category) {
for (var device in category.devices) {
device.status = false;
if (category.devices.isNotEmpty) {
for (var device in category.devices) {
device.status = false;
}
changeCategorySwitchValue(category);
updateDevicesStatus(category);
emit(CategorySwitchChanged());
}
changeCategorySwitchValue(category);
updateDevicesStatus(category);
emit(CategorySwitchChanged());
}
turnAllDevicesOn(DevicesCategoryModel category) {
for (var device in category.devices) {
device.status = true;
if (category.devices.isNotEmpty) {
for (var device in category.devices) {
device.status = true;
}
changeCategorySwitchValue(category);
updateDevicesStatus(category);
emit(CategorySwitchChanged());
}
changeCategorySwitchValue(category);
updateDevicesStatus(category);
emit(CategorySwitchChanged());
}
areAllDevicesOff(DevicesCategoryModel category) {
@@ -345,7 +365,7 @@ class DevicesCubit extends Cubit<DevicesState> {
}
clearCategoriesSelection(BuildContext context) {
for (var category in categories) {
for (var category in allCategories) {
category.isSelected = false;
for (var device in category.devices) {
device.isSelected = false;
-3
View File
@@ -21,7 +21,6 @@ class ACModel extends DeviceModel {
required super.name,
required super.type,
required super.status,
required super.location,
required super.image,
required super.timer,
});
@@ -36,7 +35,6 @@ class ACModel extends DeviceModel {
'name': name,
'status': status,
'type': type,
'location': location,
'image': image,
};
}
@@ -50,7 +48,6 @@ class ACModel extends DeviceModel {
fanSpeed: json['fanSpeed'],
tempMode: json['tempMode'],
type: json['type'],
location: json['location'],
image: json['image'],
timer: json['timer'],
coolTo: json['coolTo'],
@@ -0,0 +1,39 @@
import 'package:syncrow_app/features/devices/model/device_model.dart';
class CurtainModel extends DeviceModel {
late int openPercentage;
CurtainModel({
required this.openPercentage,
required super.id,
required super.name,
required super.type,
required super.status,
required super.image,
required super.timer,
});
Map<String, dynamic> toJson() {
return {
'openPercentage': openPercentage,
'timer': timer,
'id': id,
'name': name,
'status': status,
'type': type,
'image': image,
};
}
factory CurtainModel.fromJson(Map<String, dynamic> json) {
return CurtainModel(
id: json['id'],
name: json['name'],
status: json['status'],
openPercentage: json['openPercentage'],
timer: json['timer'],
type: json['type'],
image: json['image'],
);
}
}
@@ -2,6 +2,7 @@
import 'package:flutter/cupertino.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class DevicesCategoryModel {
final String name;
@@ -9,7 +10,7 @@ class DevicesCategoryModel {
final Widget page;
bool? devicesStatus = false;
bool? devicesStatus;
final List<DeviceModel> devices;
final DeviceType type;
@@ -32,17 +33,6 @@ class DevicesCategoryModel {
}
}
devicesStatus = tempStatus;
} else {
devicesStatus = false;
}
}
}
enum DeviceType {
AC,
Lights,
Door,
Curtain,
Screens,
Gateway,
}
+27 -4
View File
@@ -1,11 +1,15 @@
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
abstract class DeviceModel {
final String? id;
final String? name;
final String? type;
final DeviceType? type;
bool? status;
final String? location;
final String? image;
final double? timer;
late final String icon;
bool isSelected = false;
DeviceModel({
@@ -13,8 +17,27 @@ abstract class DeviceModel {
required this.name,
required this.type,
required this.status,
required this.location,
required this.image,
required this.timer,
});
}) {
switch (type) {
case DeviceType.AC:
icon = Assets.iconsAC;
break;
case DeviceType.Lights:
icon = Assets.iconsLight;
break;
case DeviceType.Door:
icon = Assets.iconsDoorLock;
break;
case DeviceType.Curtain:
icon = Assets.iconsCurtain;
break;
case DeviceType.Gateway:
icon = Assets.iconsGateway;
break;
default:
icon = '';
}
}
}
@@ -17,7 +17,6 @@ class LightModel extends DeviceModel {
required super.name,
required super.type,
required super.status,
required super.location,
required super.image,
required super.timer,
});
@@ -33,7 +32,6 @@ class LightModel extends DeviceModel {
'name': name,
'status': status,
'type': type,
'location': location,
'image': image,
};
}
@@ -48,7 +46,6 @@ class LightModel extends DeviceModel {
lightingMode: json['lightingMode'],
timer: json['timer'],
type: json['type'],
location: json['location'],
image: json['image'],
recentColors: json['recentColors'],
);
@@ -0,0 +1,30 @@
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
class RoomModel {
final String id;
final String name;
final List<DevicesCategoryModel> categories;
RoomModel({
required this.id,
required this.name,
required this.categories,
});
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'devices': categories,
};
}
factory RoomModel.fromJson(Map<String, dynamic> json) {
return RoomModel(
id: json['id'],
name: json['name'],
categories: json['devices'],
);
}
}
@@ -1,9 +1,13 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/services.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';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
class AcInterface extends StatelessWidget {
const AcInterface({super.key, required this.acModel});
@@ -12,28 +16,72 @@ class AcInterface extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 400,
),
child: AcInterfaceTempUnit(
acModel: acModel,
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: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
title: BodyLarge(
text: acModel.name ?? "",
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
),
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 130,
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: AcInterfaceControls(
acModel: acModel,
child: Padding(
padding: EdgeInsets.only(
top: Constants.appBarHeight,
left: Constants.defaultPadding,
right: Constants.defaultPadding,
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 380,
),
child: AcInterfaceTempUnit(
acModel: acModel,
),
),
const SizedBox(
height: 10,
),
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 120,
),
child: AcInterfaceControls(
acModel: acModel,
),
),
],
),
),
),
),
],
),
),
);
}
@@ -18,12 +18,11 @@ class AcInterfaceControls extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(height: 10),
ACModeControlUnit(model: acModel),
const SizedBox(height: 10),
Row(
children: [
Expanded(
Flexible(
child: InkWell(
onTap: () {},
child: DefaultContainer(
@@ -35,7 +34,7 @@ class AcInterfaceControls extends StatelessWidget {
),
),
const SizedBox(width: 10),
Expanded(
Flexible(
child: InkWell(
onTap: () {},
child: DefaultContainer(
@@ -23,127 +23,127 @@ class AcInterfaceTempUnit extends StatelessWidget {
@override
Widget build(BuildContext context) {
//TODO: use the coolTo value from the model
double coolTo = acModel.temperature;
return BlocBuilder<AcCubit, AcState>(
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,
return BlocProvider(
create: (context) => AcCubit(),
child: BlocBuilder<AcCubit, AcState>(
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,
),
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,
),
],
customColors: CustomSliderColors(
progressBarColor:
ColorsManager.primaryColor.withOpacity(.6),
trackColor: ColorsManager.greyColor,
dotColor: Colors.transparent,
),
infoProperties: InfoProperties(
//TODO: move to strings manager
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);
min: acModel.bounds.min,
max: acModel.bounds.max,
initialValue: acModel.temperature,
onChange: (value) {
String valueAsString = value.toStringAsFixed(1);
if (valueAsString.endsWith(".0") ||
valueAsString.endsWith(".5")) {
value = double.parse(valueAsString);
AcCubit.get(context).setACTemp(acModel, value);
}
}
},
},
),
),
),
),
Expanded(
flex: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
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,
Expanded(
flex: 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox.square(
dimension: 24,
child: InkWell(
onTap: () {
AcCubit.get(context)
.setACTemp(acModel, acModel.coolTo);
acModel.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,
Column(
children: [
BodyLarge(
text: "${acModel.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, acModel.coolTo);
acModel.coolTo += .5;
},
child: SvgPicture.asset(
Assets.iconsPlus,
height: 24,
width: 24,
),
),
),
),
],
),
)
],
),
);
},
],
),
)
],
),
);
},
),
);
}
}
@@ -36,7 +36,7 @@ class _ACModeControlUnitState extends State<ACModeControlUnit> {
//TODO Move the fanSpeeds and tempModes to the Cubit
return Row(
children: [
Expanded(
Flexible(
child: InkWell(
onTap: () {
setState(() {
@@ -53,7 +53,7 @@ class _ACModeControlUnitState extends State<ACModeControlUnit> {
),
),
const SizedBox(width: 10),
Expanded(
Flexible(
child: InkWell(
onTap: () {
setState(() {
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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/model/device_category_model.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_temp.dart';
@@ -18,7 +18,6 @@ class ACsList extends StatelessWidget {
@override
Widget build(BuildContext context) {
DevicesCategoryModel category = DevicesCubit.categories[0];
return BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return SingleChildScrollView(
@@ -30,7 +29,7 @@ class ACsList extends StatelessWidget {
const BodySmall(text: "All ACs"),
const SizedBox(height: 5),
UniversalSwitch(
category: category,
category: AcCubit.category,
),
const SizedBox(height: 10),
const UniversalACTemp(),
@@ -41,9 +40,9 @@ class ACsList extends StatelessWidget {
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(0),
itemCount: category.devices.length,
itemCount: AcCubit.category.devices.length,
itemBuilder: (context, index) {
ACModel ac = category.devices[index] as ACModel;
ACModel ac = AcCubit.category.devices[index] as ACModel;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -51,7 +50,8 @@ class ACsList extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
BodySmall(text: category.devices[index].name ?? ""),
BodySmall(
text: AcCubit.category.devices[index].name ?? ""),
IconButton(
onPressed: () {
DevicesCubit.get(context).selectDevice(ac);
@@ -70,7 +70,7 @@ class ACsList extends StatelessWidget {
],
),
const SizedBox(height: 5),
if (category.devices[index] is ACModel)
if (AcCubit.category.devices[index] is ACModel)
DevicesDefaultSwitch(
model: ac,
),
@@ -79,7 +79,7 @@ class ACsList extends StatelessWidget {
ac,
),
const SizedBox(height: 10),
if (category.devices[index] is ACModel)
if (AcCubit.category.devices[index] is ACModel)
ACModeControlUnit(
model: ac,
),
@@ -2,12 +2,12 @@ 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/ac_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/view/widgets/ACs/ac_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_list.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import '../../../../../generated/assets.dart';
import '../../../../../utils/resource_manager/color_manager.dart';
@@ -38,7 +38,7 @@ class ACsView extends StatelessWidget {
backgroundColor: ColorsManager.backgroundColor,
extendBodyBehindAppBar: true,
extendBody: true,
appBar: const DefaultAppBar(),
appBar: DefaultAppBar(context),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
@@ -52,8 +52,11 @@ class ACsView extends StatelessWidget {
),
),
child: Padding(
padding: const EdgeInsets.only(
top: 60, right: 15, left: 15, bottom: 80),
padding: EdgeInsets.only(
top: Constants.appBarHeight,
left: Constants.defaultPadding,
right: Constants.defaultPadding,
),
child: SizedBox.expand(
child: selectedAC != null
? AcInterface(acModel: selectedAC)
@@ -61,7 +64,6 @@ class ACsView extends StatelessWidget {
),
),
),
bottomNavigationBar: const DefaultNavBar(),
),
),
);
@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/curtains/curtains_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/curtain_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/universal_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';
class CurtainList extends StatelessWidget {
const CurtainList({
super.key,
});
@override
Widget build(BuildContext context) {
return BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// universal AC controller
const SizedBox(height: 10),
//TODO: move to strings manager
const BodySmall(text: "All Curtains"),
const SizedBox(height: 5),
UniversalSwitch(
category: CurtainsCubit.category,
),
// other ACs controls
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(0),
itemCount: CurtainsCubit.category.devices.length,
itemBuilder: (context, index) {
CurtainModel curtain =
CurtainsCubit.category.devices[index] as CurtainModel;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
BodySmall(
text:
CurtainsCubit.category.devices[index].name ?? ""),
const SizedBox(height: 5),
if (CurtainsCubit.category.devices[index] is CurtainModel)
DevicesDefaultSwitch(
model: curtain,
),
],
);
},
),
],
),
);
},
);
}
}
@@ -1,10 +1,64 @@
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/devices/bloc/curtains/curtains_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_list.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class CurtainView extends StatelessWidget {
const CurtainView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
return BlocProvider(
create: (context) => CurtainsCubit(),
child: BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return BlocBuilder<CurtainsCubit, CurtainsState>(
builder: (context, state) {
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: DefaultAppBar(context),
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: EdgeInsets.only(
top: Constants.appBarHeight,
left: Constants.defaultPadding,
right: Constants.defaultPadding,
),
child: const CurtainList(),
),
),
),
),
);
},
);
},
),
);
}
}
@@ -1,55 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_mode_tab.dart';
import 'package:syncrow_app/features/devices/view/widgets/switches.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class DevicesCategoriesView extends StatelessWidget {
const DevicesCategoriesView({
super.key,
});
@override
Widget build(BuildContext context) {
return const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TitleMedium(
text: StringsManager.devices,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
DevicesModeTab(),
],
),
),
Expanded(
flex: 11,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TitleMedium(
text: StringsManager.wizard,
style: TextStyle(
fontSize: 28,
),
),
Switches(),
],
),
),
)
],
);
}
}
@@ -1,12 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_categories_view.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/features/app_layout/bloc/spaces_cubit.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_view_header.dart';
import 'package:syncrow_app/features/devices/view/widgets/room_page.dart';
import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import '../../../../utils/resource_manager/strings_manager.dart';
import '../../bloc/devices_cubit.dart';
import 'switches.dart';
class DevicesViewBody extends StatelessWidget {
const DevicesViewBody({
@@ -20,109 +22,59 @@ class DevicesViewBody extends StatelessWidget {
child: BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
//TODO : move to NavigationCubit
PageController pageController = PageController();
return state is DevicesLoading
? const Center(child: CircularProgressIndicator())
: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: PageView(
controller: pageController,
children: const [
DevicesCategoriesView(),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TitleMedium(
text: "Home",
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
],
),
),
Expanded(
flex: 3,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
TitleMedium(
text: StringsManager.wizard,
style: TextStyle(
fontSize: 28,
),
),
Switches(),
],
),
),
)
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TitleMedium(
text: "Office",
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
],
),
),
Expanded(
flex: 3,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
TitleMedium(
text: StringsManager.wizard,
style: TextStyle(
fontSize: 28,
),
),
Switches(),
],
),
),
)
],
),
],
: Padding(
padding: EdgeInsets.only(
top: Constants.appBarHeight,
bottom: Constants.bottomNavBarHeight,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const DevicesViewHeader(),
const RoomsSlider(),
const SizedBox(
height: 10,
),
),
SmoothPageIndicator(
controller: pageController,
count: 3,
effect: const WormEffect(
dotHeight: 8,
dotWidth: 8,
Expanded(
child: PageView(
controller:
SpacesCubit.get(context).devicesPageController,
onPageChanged: (index) {
SpacesCubit.get(context).devicesPageChanged(index);
},
children: [
const WizardPage(),
...SpacesCubit.get(context).selectedSpace.rooms.map(
(room) {
return RoomPage(
room: room,
);
},
)
],
),
onDotClicked: (index) {
pageController.animateToPage(
index,
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
);
}),
],
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 7,
),
child: SmoothPageIndicator(
controller:
SpacesCubit.get(context).devicesPageController,
count: 3,
effect: const WormEffect(
dotHeight: 8,
dotWidth: 8,
),
onDotClicked: (index) {
SpacesCubit.get(context).unselectRoom();
},
),
),
],
),
);
},
),
@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_mode_tab.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class DevicesViewHeader extends StatelessWidget {
const DevicesViewHeader({
super.key,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: Constants.defaultPadding,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TitleMedium(
text: StringsManager.devices,
style: context.titleMedium.copyWith(
fontSize: 25,
),
),
const DevicesModeTab(),
const SizedBox(
height: 20,
),
],
),
);
}
}
@@ -39,7 +39,7 @@ class LightInterfaceSwitch extends StatelessWidget {
width: 35,
decoration: ShapeDecoration(
color: light.status ?? false
? ColorsManager.primaryWithOpacity
? ColorsManager.primaryColorWithOpacity
: Colors.grey,
shape: const CircleBorder(),
),
@@ -6,7 +6,6 @@ import 'package:syncrow_app/features/devices/view/widgets/lights/lights_view_lis
import '../../../../../generated/assets.dart';
import '../../../../../utils/resource_manager/color_manager.dart';
import '../../../../app_layout/view/widgets/default_app_bar.dart';
import '../../../../app_layout/view/widgets/default_nav_bar.dart';
import '../../../bloc/devices_cubit.dart';
import '../../../bloc/lights/lights_cubit.dart';
import '../../../model/light_model.dart';
@@ -29,7 +28,7 @@ class LightsView extends StatelessWidget {
DevicesCubit.get(context).getSelectedDevice() as LightModel;
}
List<LightModel> lights = [];
for (var device in DevicesCubit.categories[1].devices) {
for (var device in DevicesCubit.allCategories[1].devices) {
if (device is LightModel) {
lights.add(device);
}
@@ -44,7 +43,7 @@ class LightsView extends StatelessWidget {
backgroundColor: ColorsManager.backgroundColor,
extendBodyBehindAppBar: true,
extendBody: true,
appBar: const DefaultAppBar(),
appBar: DefaultAppBar(context),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
@@ -61,7 +60,6 @@ class LightsView extends StatelessWidget {
? LightInterface(light: selectedLight)
: LightsViewList(lights: lights),
),
bottomNavigationBar: const DefaultNavBar(),
),
),
);
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/view/widgets/lights/lights_list.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import '../../../../shared_widgets/text_widgets/body_small.dart';
import '../../../bloc/devices_cubit.dart';
@@ -17,7 +18,11 @@ class LightsViewList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 70, right: 15, left: 15, bottom: 80),
padding: EdgeInsets.only(
top: Constants.appBarHeight,
right: Constants.defaultPadding,
left: Constants.defaultPadding,
),
child: SizedBox.expand(
child: SingleChildScrollView(
child: Column(
@@ -25,7 +30,7 @@ class LightsViewList extends StatelessWidget {
children: [
const BodySmall(text: "All Lights"),
UniversalSwitch(
category: DevicesCubit.categories[1],
category: DevicesCubit.allCategories[1],
),
LightsList(lights: lights),
],
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/room_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class RoomPage extends StatelessWidget {
const RoomPage({super.key, required this.room});
final RoomModel room;
@override
Widget build(BuildContext context) {
List<DeviceModel> devices = [];
for (var category in room.categories) {
devices.addAll(category.devices);
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: Constants.defaultPadding),
child: SingleChildScrollView(
child: BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1.5,
),
padding: const EdgeInsets.only(top: 10),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: devices.length,
itemBuilder: (_, index) {
return RoomPageSwitch(device: devices[index]);
},
);
},
),
),
);
}
}
@@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface.dart';
import 'package:syncrow_app/features/shared_widgets/custom_switch.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/helpers/custom_page_route.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class RoomPageSwitch extends StatelessWidget {
const RoomPageSwitch({
super.key,
required this.device,
});
final DeviceModel device;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
//Navigate to the chosen category view without animation
// Navigator.push(
// context,
// CustomPageRoute(
// builder: (context) {
// return DevicesCubit.get(context)
// .chosenCategoryView!;
// },
// ),
// );
if (device.type == DeviceType.AC) {
Navigator.push(
context,
CustomPageRoute(
builder: (context) => AcInterface(acModel: device as ACModel),
),
);
}
},
child: DefaultContainer(
child: Padding(
padding: const EdgeInsets.only(top: 10, right: 10, left: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SvgPicture.asset(
device.icon,
fit: BoxFit.contain,
),
CustomSwitch(
device: device,
),
],
),
Expanded(
child: FittedBox(
fit: BoxFit.scaleDown,
child: BodyLarge(
text: device.name ?? "",
style: context.bodyLarge.copyWith(
fontWeight: FontWeight.bold,
height: 0,
fontSize: 24,
color: Colors.grey,
),
),
),
),
],
),
),
),
);
}
}
@@ -0,0 +1,125 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/spaces_cubit.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.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/strings_manager.dart';
class RoomsSlider extends StatelessWidget {
const RoomsSlider({
super.key,
});
@override
Widget build(BuildContext context) {
return BlocBuilder<SpacesCubit, SpacesState>(
builder: (context, state) {
return SizedBox(
height: 40,
child: PageView(
controller: SpacesCubit.get(context).roomsPageController,
onPageChanged: (index) {
SpacesCubit.get(context).roomSliderPageChanged(index);
},
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: InkWell(
onTap: () {
SpacesCubit.get(context).unselectRoom();
},
child: TitleMedium(
text: StringsManager.wizard,
style: context.titleMedium.copyWith(
fontSize: 25,
color: SpacesCubit.get(context).selectedRoom == null
? ColorsManager.textPrimaryColor
: ColorsManager.textPrimaryColor.withOpacity(.2),
),
),
),
),
...SpacesCubit.get(context).selectedSpace.rooms.map(
(room) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: InkWell(
onTap: () {
SpacesCubit.get(context).roomSliderPageChanged(
SpacesCubit.get(context)
.selectedSpace
.rooms
.indexOf(room));
},
child: TitleMedium(
text: room.name,
style: context.titleMedium.copyWith(
fontSize: 25,
color: SpacesCubit.get(context).selectedRoom == room
? ColorsManager.textPrimaryColor
: ColorsManager.textPrimaryColor
.withOpacity(.2),
),
),
),
),
)
],
),
);
// SingleChildScrollView(
// controller: SpacesCubit.get(context).roomsScrollController,
// scrollDirection: Axis.horizontal,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 15),
// child: InkWell(
// onTap: () {
// SpacesCubit.get(context).unselectRoom();
// },
// child: TitleMedium(
// text: StringsManager.wizard,
// style: context.titleMedium.copyWith(
// fontSize: 25,
// color: SpacesCubit.get(context).selectedRoom == null
// ? ColorsManager.textPrimaryColor
// : ColorsManager.textPrimaryColor.withOpacity(.2),
// ),
// ),
// ),
// ),
// ...SpacesCubit.get(context).selectedSpace.rooms.map(
// (room) => Padding(
// padding: const EdgeInsets.symmetric(horizontal: 15),
// child: InkWell(
// onTap: () {
// SpacesCubit.get(context).selectRoom(room);
// },
// child: TitleMedium(
// text: room.name,
// style: context.titleMedium.copyWith(
// fontSize: 25,
// color: SpacesCubit.get(context).selectedRoomIndex ==
// SpacesCubit.get(context)
// .selectedSpace
// .rooms
// .indexOf(room) +
// 1
// ? ColorsManager.textPrimaryColor
// : ColorsManager.textPrimaryColor
// .withOpacity(.2),
// ),
// ),
// ),
// ),
// )
// ],
// ),
// );
},
);
}
}
@@ -0,0 +1,21 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:syncrow_app/features/devices/view/widgets/wizard_switches.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class WizardPage extends StatelessWidget {
const WizardPage({
super.key,
});
@override
Widget build(BuildContext context) {
return const Padding(
padding: EdgeInsets.symmetric(horizontal: Constants.defaultPadding),
child: SingleChildScrollView(
child: WizartSwitches(),
),
);
}
}
@@ -9,8 +9,8 @@ import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
import '../../bloc/devices_cubit.dart';
class Switches extends StatelessWidget {
const Switches({
class WizartSwitches extends StatelessWidget {
const WizartSwitches({
super.key,
});
@@ -28,7 +28,7 @@ class Switches extends StatelessWidget {
padding: const EdgeInsets.only(top: 10),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: DevicesCubit.categories.length,
itemCount: DevicesCubit.allCategories.length,
itemBuilder: (_, index) {
return InkWell(
onTap: () {
@@ -51,11 +51,11 @@ class Switches extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SvgPicture.asset(
DevicesCubit.categories[index].icon,
DevicesCubit.allCategories[index].icon,
fit: BoxFit.contain,
),
CustomSwitch(
category: DevicesCubit.categories[index],
category: DevicesCubit.allCategories[index],
),
],
),
@@ -63,11 +63,12 @@ class Switches extends StatelessWidget {
child: FittedBox(
fit: BoxFit.scaleDown,
child: BodyLarge(
text: DevicesCubit.categories[index].name,
text: DevicesCubit.allCategories[index].name,
style: context.bodyLarge.copyWith(
fontWeight: FontWeight.bold,
height: 0,
fontSize: 24,
color: Colors.grey,
),
),
),
+19 -10
View File
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
import 'package:syncrow_app/features/menu/view/widgets/menu_list.dart';
import 'package:syncrow_app/features/menu/view/widgets/profile_tab.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class MenuView extends StatelessWidget {
const MenuView({super.key});
@@ -13,17 +14,25 @@ class MenuView extends StatelessWidget {
create: (BuildContext context) => MenuCubit(),
child: BlocBuilder<MenuCubit, MenuState>(
builder: (context, state) {
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: [
const ProfileTab(),
...MenuCubit.of(context).menuLists.map(
(list) => MenuList(
listModel: list,
return Padding(
padding: EdgeInsets.only(
top: Constants.appBarHeight,
bottom: Constants.bottomNavBarHeight,
left: Constants.defaultPadding,
right: Constants.defaultPadding,
),
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: [
const ProfileTab(),
...MenuCubit.of(context).menuLists.map(
(list) => MenuList(
listModel: list,
),
),
),
],
],
),
),
);
},
+97 -86
View File
@@ -6,6 +6,7 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class SceneView extends StatelessWidget {
@@ -17,99 +18,109 @@ class SceneView extends StatelessWidget {
create: (BuildContext context) => SceneCubit(),
child: BlocBuilder<SceneCubit, SceneState>(
builder: (context, state) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const TitleMedium(
text: StringsManager.routine,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
return Padding(
padding: EdgeInsets.only(
top: Constants.appBarHeight,
bottom: Constants.bottomNavBarHeight,
left: Constants.defaultPadding,
right: Constants.defaultPadding,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const TitleMedium(
text: StringsManager.routine,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 20),
const BodySmall(
text: StringsManager.tapToRunRoutine,
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
height: 50,
width: 50,
Assets.iconsHot1,
fit: BoxFit.contain,
),
const Icon(
Icons.play_circle,
size: 40,
color: Colors.grey,
)
],
),
const BodyMedium(
text: StringsManager.summerMode,
fontWeight: FontWeight.bold,
fontSize: 16,
)
],
const SizedBox(height: 20),
const BodySmall(
text: StringsManager.tapToRunRoutine,
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Image.asset(
height: 50,
width: 50,
Assets.iconsHot1,
fit: BoxFit.contain,
),
const Icon(
Icons.play_circle,
size: 40,
color: Colors.grey,
)
],
),
const BodyMedium(
text: StringsManager.summerMode,
fontWeight: FontWeight.bold,
fontSize: 16,
)
],
),
),
),
),
),
const SizedBox(width: 10),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
height: 50,
width: 50,
Assets.iconsWinter1,
fit: BoxFit.contain,
),
const Icon(
Icons.play_circle,
size: 40,
color: Colors.grey,
)
],
),
const BodyMedium(
text: StringsManager.winterMode,
fontWeight: FontWeight.bold,
fontSize: 16,
)
],
const SizedBox(width: 10),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
),
child: DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Image.asset(
height: 50,
width: 50,
Assets.iconsWinter1,
fit: BoxFit.contain,
),
const Icon(
Icons.play_circle,
size: 40,
color: Colors.grey,
)
],
),
const BodyMedium(
text: StringsManager.winterMode,
fontWeight: FontWeight.bold,
fontSize: 16,
)
],
),
),
),
),
),
],
)
],
],
)
],
),
);
},
),
+23 -9
View File
@@ -2,28 +2,42 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class CustomSwitch extends StatelessWidget {
const CustomSwitch({super.key, required this.category});
const CustomSwitch({super.key, this.category, this.device})
: assert(category != null || device != null);
final DevicesCategoryModel category;
final DevicesCategoryModel? category;
final DeviceModel? device;
@override
Widget build(BuildContext context) {
return BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
bool? status;
if (device != null) {
status = device!.status;
} else if (category != null) {
status = category!.devicesStatus;
}
return GestureDetector(
onTap: () {
DevicesCubit.get(context).changeCategorySwitchValue(category);
if (device != null) {
DevicesCubit.get(context).turnOnOffDevice(device!);
} else if (category != null) {
DevicesCubit.get(context).changeCategorySwitchValue(category!);
}
},
child: Container(
width: 45.0,
height: 28.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
color: category.devicesStatus != null
? category.devicesStatus!
color: status != null
? status
? ColorsManager.primaryColor
: const Color(0xFFD9D9D9)
: const Color(0xFFD9D9D9),
@@ -39,8 +53,8 @@ class CustomSwitch extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
alignment: category.devicesStatus != null
? category.devicesStatus!
alignment: status != null
? status
? Alignment.centerRight
: Alignment.centerLeft
: Alignment.centerLeft,
@@ -49,8 +63,8 @@ class CustomSwitch extends StatelessWidget {
height: 20.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: category.devicesStatus != null
? category.devicesStatus!
color: status != null
? status
? ColorsManager.primaryColor
: Colors.grey
: Colors.grey,
@@ -28,12 +28,13 @@ class CustomText extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SelectableText(
//was SelectableText
return Text(
text,
style: style,
textAlign: textAlign,
onTap: onTap,
minLines: minLines,
// onTap: onTap,
// minLines: minLines,
maxLines: maxLines,
textDirection: textDirection,
);