mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-10-25 13:17:56 +00:00
Merged Auth branch & Curtains branch
This commit is contained in:
@@ -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'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user