mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-11-26 10:44:55 +00:00
Merge pull request #12 from SyncrowIOT/Configure_devices_statuses
Configure devices statuses
This commit is contained in:
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@ -11,6 +11,12 @@
|
||||
"type": "dart",
|
||||
"deviceId": "0147FC23-3D6C-406A-BE2C-9E67BAF3DA9B"
|
||||
},
|
||||
{
|
||||
"name": "Iphone 15 Pro",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"deviceId": "9C9E6EEF-0E9C-4FA9-B201-CBA8AFB0D1D8"
|
||||
},
|
||||
{
|
||||
"name": "Iphone SE",
|
||||
"request": "launch",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#Wed Apr 03 23:37:40 EET 2024
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/app_layout/model/space_model.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/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
||||
import 'package:syncrow_app/features/menu/view/menu_view.dart';
|
||||
@ -17,26 +18,35 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
part 'home_state.dart';
|
||||
|
||||
class HomeCubit extends Cubit<HomeState> {
|
||||
HomeCubit() : super(SpacesInitial()) {
|
||||
if (HomeCubit.spaces != null) {
|
||||
if (selectedSpace == null) {
|
||||
fetchSpaces().then((value) {
|
||||
if (selectedSpace != null) {
|
||||
print('selectedSpace: ${selectedSpace!.name}');
|
||||
fetchRooms(selectedSpace!);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
fetchSpaces(); // this is for the first time
|
||||
HomeCubit._() : super(HomeInitial()) {
|
||||
if (selectedSpace == null) {
|
||||
fetchSpaces().then((value) {
|
||||
if (selectedSpace != null) {
|
||||
fetchRooms(selectedSpace!);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static HomeCubit? _instance;
|
||||
static HomeCubit getInstance() {
|
||||
// If an instance already exists, return it
|
||||
_instance ??= HomeCubit._();
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
void emitSafe(HomeState newState) {
|
||||
final cubit = this;
|
||||
if (!cubit.isClosed) {
|
||||
cubit.emit(newState);
|
||||
}
|
||||
}
|
||||
|
||||
static HomeCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
static List<SpaceModel>? spaces;
|
||||
List<SpaceModel>? spaces;
|
||||
|
||||
static SpaceModel? selectedSpace;
|
||||
SpaceModel? selectedSpace;
|
||||
|
||||
RoomModel? selectedRoom;
|
||||
|
||||
@ -46,9 +56,14 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
|
||||
var duration = const Duration(milliseconds: 300);
|
||||
|
||||
selectSpace(SpaceModel space) {
|
||||
// selectSpace(SpaceModel space) async {
|
||||
// selectedSpace = space;
|
||||
// emit(SpaceSelected(space));
|
||||
// }
|
||||
|
||||
changeSelectedSpace(SpaceModel space) {
|
||||
selectedSpace = space;
|
||||
emit(SpaceSelected(space));
|
||||
emitSafe(SpaceSelected(space));
|
||||
}
|
||||
|
||||
roomSliderPageChanged(int index) {
|
||||
@ -62,7 +77,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
unselectRoom();
|
||||
} else {
|
||||
selectedRoom = selectedSpace!.rooms![index - 1];
|
||||
emit(RoomSelected(selectedRoom!));
|
||||
emitSafe(RoomSelected(selectedRoom!));
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,12 +92,12 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
unselectRoom();
|
||||
} else {
|
||||
selectedRoom = selectedSpace!.rooms![index - 1];
|
||||
emit(RoomSelected(selectedRoom!));
|
||||
emitSafe(RoomSelected(selectedRoom!));
|
||||
}
|
||||
}
|
||||
|
||||
unselectRoom() {
|
||||
selectedRoom = null;
|
||||
// selectedRoom = null;
|
||||
devicesPageController.animateToPage(
|
||||
0,
|
||||
duration: duration,
|
||||
@ -95,35 +110,40 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
curve: Curves.linear,
|
||||
);
|
||||
|
||||
emit(RoomUnSelected());
|
||||
emitSafe(RoomUnSelected());
|
||||
}
|
||||
|
||||
//////////////////////////////////////// API ////////////////////////////////////////
|
||||
fetchSpaces() async {
|
||||
emit(GetSpacesLoading());
|
||||
emitSafe(GetSpacesLoading());
|
||||
try {
|
||||
spaces = await SpacesAPI.getSpaces();
|
||||
selectedSpace = spaces!.isNotEmpty ? selectSpace(spaces!.first) : null;
|
||||
emit(GetSpacesLoaded(spaces!));
|
||||
selectedSpace = spaces!.isNotEmpty
|
||||
?
|
||||
// selectSpace(spaces!.first)
|
||||
selectedSpace = spaces!.first
|
||||
: null;
|
||||
emitSafe(GetSpacesLoaded(spaces!));
|
||||
} on DioException catch (e) {
|
||||
emit(GetSpacesError(ServerFailure.fromDioError(e).errMessage));
|
||||
emitSafe(GetSpacesError(ServerFailure.fromDioError(e).errMessage));
|
||||
}
|
||||
}
|
||||
|
||||
fetchRooms(SpaceModel space) async {
|
||||
emit(GetSpaceRoomsLoading());
|
||||
emitSafe(GetSpaceRoomsLoading());
|
||||
try {
|
||||
space.rooms = await SpacesAPI.getRooms(space.id!);
|
||||
space.rooms = await SpacesAPI.getRoomsBySpaceId(space.id!);
|
||||
if (space.rooms != null) {
|
||||
emit(GetSpaceRoomsLoaded(space.rooms!));
|
||||
emitSafe(GetSpaceRoomsLoaded(space.rooms!));
|
||||
} else {
|
||||
emit(GetSpaceRoomsError("No rooms found"));
|
||||
emitSafe(GetSpaceRoomsError("No rooms found"));
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
emit(GetSpacesError(ServerFailure.fromDioError(e).errMessage));
|
||||
emitSafe(GetSpacesError(ServerFailure.fromDioError(e).errMessage));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////Nav////////////////////////////////////////
|
||||
/////////////////////////////////////// Nav ///////////////////////////////////////
|
||||
|
||||
static clear() {
|
||||
pageIndex = 0;
|
||||
@ -247,7 +267,10 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
final List<Widget> pages = [
|
||||
const DashboardView(),
|
||||
// const LayoutPage(),
|
||||
const DevicesViewBody(),
|
||||
BlocProvider(
|
||||
create: (context) => DevicesCubit.getInstance(),
|
||||
child: const DevicesViewBody(),
|
||||
),
|
||||
const SceneView(),
|
||||
const MenuView(),
|
||||
];
|
||||
@ -255,7 +278,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
void updatePageIndex(int index) {
|
||||
pageIndex = index;
|
||||
|
||||
emit(NavChangePage());
|
||||
emitSafe(NavChangePage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ part of 'home_cubit.dart';
|
||||
|
||||
abstract class HomeState {}
|
||||
|
||||
class SpacesInitial extends HomeState {}
|
||||
class HomeInitial extends HomeState {}
|
||||
|
||||
class GetSpacesLoading extends HomeState {}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@ import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/app_layout/view/widgets/app_body.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/devices_cubit.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
@ -15,16 +14,9 @@ class AppLayout extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) => HomeCubit(),
|
||||
),
|
||||
BlocProvider(
|
||||
create: (context) => DevicesCubit(),
|
||||
),
|
||||
],
|
||||
child: BlocListener<HomeCubit, HomeState>(
|
||||
return BlocProvider(
|
||||
create: (context) => HomeCubit.getInstance(),
|
||||
child: BlocConsumer<HomeCubit, HomeState>(
|
||||
listener: (context, state) {
|
||||
if (state is GetSpacesError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@ -36,30 +28,38 @@ class AppLayout extends StatelessWidget {
|
||||
.popUntil((route) => route.settings.name == Routes.authLogin);
|
||||
}
|
||||
},
|
||||
child: BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
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: HomeCubit.getInstance().spaces != null
|
||||
? const DefaultAppBar()
|
||||
: null,
|
||||
body: const AppBody(),
|
||||
bottomNavigationBar: const DefaultNavBar(),
|
||||
// floatingActionButton: FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// CustomPageRoute(
|
||||
// builder: (context) =>
|
||||
// const ThreeGangSwitchesView(),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// child: const Icon(Icons.arrow_forward_ios_sharp),
|
||||
// ),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return const Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: DefaultAppBar(),
|
||||
body: AppBody(),
|
||||
bottomNavigationBar: DefaultNavBar(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,76 +3,73 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../../../../generated/assets.dart';
|
||||
|
||||
class AppBarHomeDropdown extends StatelessWidget {
|
||||
const AppBarHomeDropdown({
|
||||
super.key,
|
||||
});
|
||||
const AppBarHomeDropdown({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return HomeCubit.selectedSpace == null
|
||||
? const Center(child: BodyMedium(text: 'No Home Selected'))
|
||||
: 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: HomeCubit.selectedSpace!.id,
|
||||
items: HomeCubit.spaces!.map((space) {
|
||||
return DropdownMenuItem(
|
||||
value: space.id,
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
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: HomeCubit.getInstance().selectedSpace!.id,
|
||||
items: HomeCubit.getInstance().spaces!.map((space) {
|
||||
return DropdownMenuItem(
|
||||
value: space.id,
|
||||
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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
HomeCubit.get(context).selectSpace(HomeCubit.spaces!
|
||||
.firstWhere((element) => element.id == value));
|
||||
}
|
||||
},
|
||||
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) {
|
||||
if (value != null) {
|
||||
HomeCubit.getInstance().changeSelectedSpace(
|
||||
HomeCubit.getInstance()
|
||||
.spaces!
|
||||
.firstWhere((element) => element.id == value));
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
|
||||
import '../../../../generated/assets.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
class AppBody extends StatelessWidget {
|
||||
const AppBody({
|
||||
@ -37,9 +37,10 @@ class AppBody extends StatelessWidget {
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return state is! GetSpacesLoading ||
|
||||
state is! GetSpaceRoomsLoading
|
||||
? HomeCubit.get(context).pages[HomeCubit.pageIndex]
|
||||
return state is! GetSpacesLoading
|
||||
? state is! GetSpaceRoomsLoading
|
||||
? HomeCubit.getInstance().pages[HomeCubit.pageIndex]
|
||||
: const Center(child: CircularProgressIndicator())
|
||||
: const Center(child: CircularProgressIndicator());
|
||||
},
|
||||
),
|
||||
|
||||
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
@ -20,11 +19,9 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
backgroundColor: Colors.transparent,
|
||||
leadingWidth: 150,
|
||||
toolbarHeight: Constants.appBarHeight,
|
||||
leading: HomeCubit.spaces != null
|
||||
? HomeCubit.spaces!.isNotEmpty
|
||||
? HomeCubit.appBarLeading[
|
||||
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]
|
||||
: const Center(child: BodySmall(text: 'Create Home'))
|
||||
leading: HomeCubit.getInstance().spaces!.isNotEmpty
|
||||
? HomeCubit.appBarLeading[
|
||||
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]
|
||||
: null,
|
||||
actions: HomeCubit.appBarActions[
|
||||
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label],
|
||||
|
||||
@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.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';
|
||||
|
||||
@ -15,19 +16,22 @@ class DefaultNavBar extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
var cubit = HomeCubit.get(context);
|
||||
var cubit = HomeCubit.getInstance();
|
||||
return SizedBox(
|
||||
height: Constants.bottomNavBarHeight,
|
||||
child: BottomNavigationBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
onTap: (int index) {
|
||||
cubit.updatePageIndex(index);
|
||||
if (DevicesCubit.get(context).chosenCategoryView != null) {
|
||||
DevicesCubit().clearCategoriesSelection(context);
|
||||
}
|
||||
if (HomeCubit.get(context).selectedRoom != null) {
|
||||
HomeCubit.get(context).unselectRoom();
|
||||
}
|
||||
// if (DevicesCubit.getInstance().chosenCategoryView != null) {
|
||||
// DevicesCubit.getInstance()
|
||||
// .clearCategoriesSelection(context);
|
||||
// }
|
||||
// if (HomeCubit.getInstance().selectedRoom != null) {
|
||||
// HomeCubit.getInstance().unselectRoom();
|
||||
// }
|
||||
|
||||
HomeCubit.getInstance().updatePageIndex(index);
|
||||
},
|
||||
currentIndex: HomeCubit.pageIndex,
|
||||
selectedItemColor: ColorsManager.primaryColor,
|
||||
|
||||
@ -30,15 +30,17 @@ class LoginForm extends StatelessWidget {
|
||||
TextFormField(
|
||||
controller: AuthCubit.get(context).emailController,
|
||||
validator: (value) {
|
||||
if (value != null) {
|
||||
if (value.isEmpty) {
|
||||
return 'Please enter your email';
|
||||
}
|
||||
//Regex for email validation
|
||||
if (!RegExp(
|
||||
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$')
|
||||
.hasMatch(value)) {
|
||||
return 'Please enter a valid email';
|
||||
if (state is! AuthTokenError) {
|
||||
if (value != null) {
|
||||
if (value.isEmpty) {
|
||||
return 'Please enter your email';
|
||||
}
|
||||
//Regex for email validation
|
||||
if (!RegExp(
|
||||
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$')
|
||||
.hasMatch(value)) {
|
||||
return 'Please enter a valid email';
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -57,13 +59,15 @@ class LoginForm extends StatelessWidget {
|
||||
TextFormField(
|
||||
controller: AuthCubit.get(context).passwordController,
|
||||
validator: (value) {
|
||||
if (value != null) {
|
||||
if (value.isNotEmpty) {
|
||||
if (value.length < 6) {
|
||||
return 'Password must be at least 8 characters';
|
||||
if (state is! AuthTokenError) {
|
||||
if (value != null) {
|
||||
if (value.isNotEmpty) {
|
||||
if (value.length < 6) {
|
||||
return 'Password must be at least 8 characters';
|
||||
}
|
||||
} else {
|
||||
return 'Please enter your password';
|
||||
}
|
||||
} else {
|
||||
return 'Please enter your password';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@ -3,7 +3,7 @@ import 'package:syncrow_app/features/dashboard/view/widgets/card_title.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/united_text.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
import '../../../../generated/assets.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
class Consumption extends StatelessWidget {
|
||||
const Consumption({
|
||||
|
||||
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/live_monitor_widget.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
import '../../../../generated/assets.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
class LiveMonitorTab extends StatelessWidget {
|
||||
const LiveMonitorTab({
|
||||
|
||||
51
lib/features/devices/bloc/cubit/ac_cubit.dart
Normal file
51
lib/features/devices/bloc/cubit/ac_cubit.dart
Normal file
@ -0,0 +1,51 @@
|
||||
// import 'package:bloc/bloc.dart';
|
||||
// import 'package:flutter/foundation.dart';
|
||||
// import 'package:meta/meta.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';
|
||||
|
||||
// part 'ac_state.dart';
|
||||
|
||||
// class AcCubit extends Cubit<AcState> {
|
||||
// AcCubit() : super(AcInitial());
|
||||
// DeviceModel? getSelectedAC() {
|
||||
// DevicesCategoryModel category = DevicesCubit.allCategories![0];
|
||||
// for (var device in category.devices) {
|
||||
// if (device is && device.isSelected) {
|
||||
// return device;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// void setTempToAll(double temperature) {
|
||||
// for (DeviceModel ac in category.devices) {
|
||||
// if (ac is DeviceModel) {
|
||||
// if (ac.temperature != temperature &&
|
||||
// ac.bounds.min <= temperature &&
|
||||
// temperature <= ac.bounds.max) {
|
||||
// setACTemp(ac, temperature);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// universalACTemp = temperature;
|
||||
// emit(ACsTempChanged(temperature));
|
||||
// }
|
||||
|
||||
// void setACTemp(DeviceModel model, double temp) {
|
||||
// if (model.bounds.min <= temp && temp <= model.bounds.max) {
|
||||
// model.temperature = temp;
|
||||
// }
|
||||
// emit(ACsTempChanged(temp));
|
||||
// }
|
||||
|
||||
// double getTemp(int index) {
|
||||
// var device = category.devices[index];
|
||||
// if (device is DeviceModel) {
|
||||
// return device.temperature;
|
||||
// }
|
||||
// return 0.0; // or any default value you prefer
|
||||
// }
|
||||
|
||||
// }
|
||||
6
lib/features/devices/bloc/cubit/ac_state.dart
Normal file
6
lib/features/devices/bloc/cubit/ac_state.dart
Normal file
@ -0,0 +1,6 @@
|
||||
// part of 'ac_cubit.dart';
|
||||
|
||||
// @immutable
|
||||
// sealed class AcState {}
|
||||
|
||||
// final class AcInitial extends AcState {}
|
||||
@ -8,32 +8,54 @@ import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/status_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/lights_switches/light_switches.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_view.dart';
|
||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||
import 'package:syncrow_app/services/api/network_exception.dart';
|
||||
import 'package:syncrow_app/services/api/spaces_api.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
part 'devices_state.dart';
|
||||
|
||||
class DevicesCubit extends Cubit<DevicesState> {
|
||||
DevicesCubit() : super(DevicesInitial()) {
|
||||
if (HomeCubit.selectedSpace != null) {
|
||||
fetchGroups(HomeCubit.selectedSpace!.id!);
|
||||
DevicesCubit._() : super(DevicesInitial()) {
|
||||
if (HomeCubit.getInstance().selectedSpace != null) {
|
||||
fetchGroups(HomeCubit.getInstance().selectedSpace!.id!);
|
||||
for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) {
|
||||
fetchDevicesByRoomId(room.id!);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool _isClosed = false;
|
||||
|
||||
static DevicesCubit? _instance;
|
||||
static DevicesCubit getInstance() {
|
||||
print('device cubit instance found : ${_instance != null}');
|
||||
print('selected space : ${HomeCubit.getInstance().selectedSpace != null}');
|
||||
return _instance ??= DevicesCubit._();
|
||||
}
|
||||
|
||||
DeviceModel? selectedDevice;
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
_isClosed = true;
|
||||
_instance = null;
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void emitSafe(DevicesState newState) {
|
||||
final cubit = this;
|
||||
if (!cubit.isClosed) {
|
||||
cubit.emit(newState);
|
||||
}
|
||||
}
|
||||
|
||||
static DevicesCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
static List<DevicesCategoryModel>? allCategories;
|
||||
@ -46,14 +68,14 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
allCategories![i].isSelected = false;
|
||||
}
|
||||
}
|
||||
emit(DevicesCategoryChanged());
|
||||
emitSafe(DevicesCategoryChanged());
|
||||
}
|
||||
|
||||
unselectAllCategories() {
|
||||
for (var category in allCategories!) {
|
||||
category.isSelected = false;
|
||||
}
|
||||
emit(DevicesCategoryChanged());
|
||||
emitSafe(DevicesCategoryChanged());
|
||||
}
|
||||
|
||||
Widget? get chosenCategoryView {
|
||||
@ -63,14 +85,14 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
switch (category.type) {
|
||||
case DeviceType.AC:
|
||||
return const ACsView();
|
||||
case DeviceType.Lights:
|
||||
case DeviceType.LightBulb:
|
||||
return const LightsView();
|
||||
case DeviceType.DoorLock:
|
||||
return const DoorView();
|
||||
case DeviceType.Curtain:
|
||||
return const CurtainView();
|
||||
case DeviceType.ThreeGang:
|
||||
return const LightSwitchesView();
|
||||
// case DeviceType.ThreeGang:
|
||||
// return const ThreeGangSwitchesView();
|
||||
case DeviceType.Gateway:
|
||||
return const GateWayView();
|
||||
default:
|
||||
@ -97,14 +119,14 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
for (var device in category.devices!) {
|
||||
if (device.isSelected) {
|
||||
category.isSelected = false;
|
||||
emit(DeviceSelected());
|
||||
emitSafe(DeviceSelected());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
device.isSelected = !device.isSelected;
|
||||
emit(DeviceSelected());
|
||||
emitSafe(DeviceSelected());
|
||||
}
|
||||
|
||||
DeviceModel? getSelectedDevice() {
|
||||
@ -125,24 +147,24 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
category.devicesStatus = !category.devicesStatus!;
|
||||
if (category.devices != null) {
|
||||
for (var device in category.devices!) {
|
||||
device.status = category.devicesStatus;
|
||||
device.isOnline = category.devicesStatus;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
category.devicesStatus = true;
|
||||
if (category.devices != null) {
|
||||
for (var device in category.devices!) {
|
||||
device.status = true;
|
||||
device.isOnline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateDevicesStatus(category);
|
||||
|
||||
emit(CategorySwitchChanged());
|
||||
emitSafe(CategorySwitchChanged());
|
||||
}
|
||||
|
||||
turnOnOffDevice(DeviceModel device) {
|
||||
device.status = !device.status!;
|
||||
device.isOnline = !device.isOnline!;
|
||||
DevicesCategoryModel category = allCategories!.firstWhere((category) {
|
||||
if (category.devices != null) {
|
||||
return category.devices!.contains(device);
|
||||
@ -151,26 +173,26 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
}
|
||||
});
|
||||
updateDevicesStatus(category);
|
||||
emit(DeviceSwitchChanged());
|
||||
emitSafe(DeviceSwitchChanged());
|
||||
}
|
||||
|
||||
updateDevicesStatus(DevicesCategoryModel category) {
|
||||
if (category.devices != null) {
|
||||
if (category.devices!.isNotEmpty) {
|
||||
bool? tempStatus = category.devices![0].status;
|
||||
bool? tempStatus = category.devices![0].isOnline;
|
||||
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) {
|
||||
if (ac.isOnline != tempStatus) {
|
||||
category.devicesStatus = null;
|
||||
emit(DeviceSwitchChanged());
|
||||
emitSafe(DeviceSwitchChanged());
|
||||
return;
|
||||
}
|
||||
category.devicesStatus = tempStatus;
|
||||
emit(DeviceSwitchChanged());
|
||||
emitSafe(DeviceSwitchChanged());
|
||||
}
|
||||
} else {
|
||||
category.devicesStatus = null;
|
||||
emit(DeviceSwitchChanged());
|
||||
emitSafe(DeviceSwitchChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,11 +201,11 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
if (category.devices != null) {
|
||||
if (category.devices!.isNotEmpty) {
|
||||
for (var device in category.devices!) {
|
||||
device.status = false;
|
||||
device.isOnline = false;
|
||||
}
|
||||
changeCategorySwitchValue(category);
|
||||
updateDevicesStatus(category);
|
||||
emit(CategorySwitchChanged());
|
||||
emitSafe(CategorySwitchChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,11 +214,11 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
if (category.devices != null) {
|
||||
if (category.devices!.isNotEmpty) {
|
||||
for (var device in category.devices!) {
|
||||
device.status = true;
|
||||
device.isOnline = true;
|
||||
}
|
||||
changeCategorySwitchValue(category);
|
||||
updateDevicesStatus(category);
|
||||
emit(CategorySwitchChanged());
|
||||
emitSafe(CategorySwitchChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,9 +226,9 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
areAllDevicesOff(DevicesCategoryModel category) {
|
||||
if (category.devices != null) {
|
||||
for (var device in category.devices!) {
|
||||
if (device.status ?? false) {
|
||||
if (device.isOnline ?? false) {
|
||||
category.devicesStatus = false;
|
||||
emit(CategorySwitchChanged());
|
||||
emitSafe(CategorySwitchChanged());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -224,16 +246,34 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
}
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
|
||||
emit(DevicesCategoryChanged());
|
||||
emitSafe(DevicesCategoryChanged());
|
||||
}
|
||||
|
||||
deviceControl(DeviceControlModel control) async {
|
||||
emit(DeviceControlLoading());
|
||||
///////////////////////// API CALLS //////////////////////////
|
||||
deviceControl(DeviceControlModel control, String deviceId) async {
|
||||
emitSafe(DeviceControlLoading(
|
||||
code: control.code,
|
||||
));
|
||||
try {
|
||||
await DevicesAPI.controlDevice(control);
|
||||
emit(DeviceControlSuccess());
|
||||
await DevicesAPI.controlDevice(control).then((response) {
|
||||
emitSafe(DeviceControlSuccess(
|
||||
code: control.code,
|
||||
));
|
||||
if (response['success'] ?? false) {
|
||||
Future.delayed(const Duration(milliseconds: 400), () {
|
||||
getDevicesStatues(
|
||||
deviceId,
|
||||
HomeCubit.getInstance().selectedSpace!.rooms!.indexOf(
|
||||
HomeCubit.getInstance().selectedRoom!,
|
||||
),
|
||||
code: control.code);
|
||||
});
|
||||
} else {
|
||||
emitSafe(DeviceControlError('Failed to control the device'));
|
||||
}
|
||||
});
|
||||
} on DioException catch (e) {
|
||||
emit(DeviceControlError(ServerFailure.fromDioError(e).errMessage));
|
||||
emitSafe(DeviceControlError(ServerFailure.fromDioError(e).errMessage));
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,16 +281,77 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
if (_isClosed) return;
|
||||
|
||||
try {
|
||||
emit(DevicesCategoriesLoading());
|
||||
emitSafe(DevicesCategoriesLoading());
|
||||
allCategories = await DevicesAPI.fetchGroups(spaceId);
|
||||
emit(DevicesCategoriesSuccess());
|
||||
emitSafe(DevicesCategoriesSuccess());
|
||||
} on DioException catch (error) {
|
||||
emit(
|
||||
emitSafe(
|
||||
DevicesCategoriesError(ServerFailure.fromDioError(error).errMessage),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fetchDevicesByRoomId(int? roomId) async {
|
||||
if (_isClosed) return;
|
||||
if (roomId == null) return;
|
||||
|
||||
try {
|
||||
emitSafe(GetDevicesLoading());
|
||||
int roomIndex = HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.rooms!
|
||||
.indexWhere((element) => element.id == roomId);
|
||||
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices =
|
||||
await SpacesAPI.getDevicesByRoomId(roomId);
|
||||
//get status for each device
|
||||
for (var device in HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.rooms![roomIndex]
|
||||
.devices!) {
|
||||
getDevicesStatues(device.id!, roomIndex);
|
||||
}
|
||||
|
||||
emitSafe(GetDevicesSuccess());
|
||||
} on DioException catch (error) {
|
||||
emitSafe(
|
||||
GetDevicesError(ServerFailure.fromDioError(error).errMessage),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getDevicesStatues(String deviceId, int roomIndex, {String? code}) async {
|
||||
if (_isClosed) return;
|
||||
|
||||
try {
|
||||
emitSafe(GetDeviceStatusLoading(code: code));
|
||||
int deviceIndex = HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.rooms![roomIndex]
|
||||
.devices!
|
||||
.indexWhere((element) => element.id == deviceId);
|
||||
|
||||
List<StatusModel> statuses = [];
|
||||
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
||||
// if (response['result']['status'].length > 4)
|
||||
// print('response : ${response['result']['status'][4]}');
|
||||
|
||||
for (var status in response['result']['status']) {
|
||||
statuses.add(StatusModel.fromJson(status));
|
||||
}
|
||||
|
||||
HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.rooms![roomIndex]
|
||||
.devices![deviceIndex]
|
||||
.status = statuses;
|
||||
emitSafe(GetDeviceStatusSuccess(code: code));
|
||||
} on DioException catch (error) {
|
||||
emitSafe(
|
||||
GetDeviceStatusError(ServerFailure.fromDioError(error).errMessage),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///Lights
|
||||
onHorizontalDragUpdate(DeviceModel light, double dx, double screenWidth) {
|
||||
double newBrightness = (dx / (screenWidth - 15) * 100);
|
||||
@ -272,17 +373,17 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
// setLightingMode(DeviceModel light, LightMode mode) {
|
||||
// light.lightingMode =
|
||||
// lightModes.entries.firstWhere((element) => element.value == mode).key;
|
||||
// emit(LightModeChanged(mode));
|
||||
// emitSafe(LightModeChanged(mode));
|
||||
// }
|
||||
//
|
||||
// toggleLight(DeviceModel light) {
|
||||
// light.status != null ? light.status = !light.status! : light.status = true;
|
||||
// emit(LightToggled(light));
|
||||
// light.isOnline != null ? light.isOnline = !light.isOnline! : light.isOnline = true;
|
||||
// emitSafe(LightToggled(light));
|
||||
// }
|
||||
//
|
||||
// setColor(DeviceModel light, int color) {
|
||||
// light.color = color;
|
||||
// emit(LightColorChanged(color));
|
||||
// emitSafe(LightColorChanged(color));
|
||||
// }
|
||||
//
|
||||
// int getBrightness(DeviceModel light) {
|
||||
@ -293,48 +394,9 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
// value = (value / 5).ceil() * 5;
|
||||
// if (value != light.brightness) {
|
||||
// light.brightness = value;
|
||||
// emit(LightBrightnessChanged(value));
|
||||
// emitSafe(LightBrightnessChanged(value));
|
||||
// }
|
||||
// }
|
||||
|
||||
///ACs
|
||||
// DeviceModel? getSelectedAC() {
|
||||
// for (var ac in category.devices) {
|
||||
// if (ac is DeviceModel && ac.isSelected) {
|
||||
// return ac;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// void setTempToAll(double temperature) {
|
||||
// for (DeviceModel ac in category.devices) {
|
||||
// if (ac is DeviceModel) {
|
||||
// if (ac.temperature != temperature &&
|
||||
// ac.bounds.min <= temperature &&
|
||||
// temperature <= ac.bounds.max) {
|
||||
// setACTemp(ac, temperature);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// universalACTemp = temperature;
|
||||
// emit(ACsTempChanged(temperature));
|
||||
// }
|
||||
//
|
||||
// void setACTemp(DeviceModel model, double temp) {
|
||||
// if (model.bounds.min <= temp && temp <= model.bounds.max) {
|
||||
// model.temperature = temp;
|
||||
// }
|
||||
// emit(ACsTempChanged(temp));
|
||||
// }
|
||||
//
|
||||
// double getTemp(int index) {
|
||||
// var device = category.devices[index];
|
||||
// if (device is DeviceModel) {
|
||||
// return device.temperature;
|
||||
// }
|
||||
// return 0.0; // or any default value you prefer
|
||||
// }
|
||||
}
|
||||
|
||||
enum LightMode {
|
||||
|
||||
@ -14,6 +14,35 @@ class DevicesFailure extends DevicesState {}
|
||||
class ChangeIndex extends DevicesState {}
|
||||
|
||||
// Devices
|
||||
|
||||
class GetDeviceStatusLoading extends DevicesState {
|
||||
final String? code;
|
||||
|
||||
GetDeviceStatusLoading({this.code});
|
||||
}
|
||||
|
||||
class GetDeviceStatusSuccess extends DevicesState {
|
||||
final String? code;
|
||||
|
||||
GetDeviceStatusSuccess({this.code});
|
||||
}
|
||||
|
||||
class GetDeviceStatusError extends DevicesState {
|
||||
final String errorMsg;
|
||||
|
||||
GetDeviceStatusError(this.errorMsg);
|
||||
}
|
||||
|
||||
class GetDevicesLoading extends DevicesState {}
|
||||
|
||||
class GetDevicesSuccess extends DevicesState {}
|
||||
|
||||
class GetDevicesError extends DevicesState {
|
||||
final String errorMsg;
|
||||
|
||||
GetDevicesError(this.errorMsg);
|
||||
}
|
||||
|
||||
class DevicesCategoryChanged extends DevicesState {}
|
||||
|
||||
class CategorySwitchChanged extends DevicesState {}
|
||||
@ -23,9 +52,17 @@ class DeviceSwitchChanged extends DevicesState {}
|
||||
class DeviceSelected extends DevicesState {}
|
||||
|
||||
// Device Control
|
||||
class DeviceControlLoading extends DevicesState {}
|
||||
class DeviceControlLoading extends DevicesState {
|
||||
final String? code;
|
||||
|
||||
class DeviceControlSuccess extends DevicesState {}
|
||||
DeviceControlLoading({this.code});
|
||||
}
|
||||
|
||||
class DeviceControlSuccess extends DevicesState {
|
||||
final String? code;
|
||||
|
||||
DeviceControlSuccess({this.code});
|
||||
}
|
||||
|
||||
class DeviceControlError extends DevicesState {
|
||||
final String errorMsg;
|
||||
|
||||
@ -24,9 +24,9 @@ class DevicesCategoryModel {
|
||||
//sets the initial status of the devices
|
||||
if (devices != null) {
|
||||
if (devices!.isNotEmpty) {
|
||||
bool tempStatus = devices!.first.status ?? false;
|
||||
bool tempStatus = devices!.first.isOnline ?? false;
|
||||
for (var device in devices!) {
|
||||
if (device.status != tempStatus) {
|
||||
if (device.isOnline != tempStatus) {
|
||||
devicesStatus = false;
|
||||
break;
|
||||
}
|
||||
@ -41,9 +41,9 @@ class DevicesCategoryModel {
|
||||
DevicesCategoryModel.fromJson(Map<String, dynamic> json)
|
||||
: name = json['groupName'],
|
||||
id = json['groupId'],
|
||||
type = deviceTypeMap[json['groupName']] ?? DeviceType.Other,
|
||||
type = devicesTypesMap[json['productType']] ?? DeviceType.Other,
|
||||
icon = deviceTypeIconMap[
|
||||
deviceTypeMap[json['groupName']] ?? DeviceType.Other] ??
|
||||
devicesTypesMap[json['productType']] ?? DeviceType.Other] ??
|
||||
'',
|
||||
devices = [],
|
||||
isSelected = false;
|
||||
@ -53,22 +53,14 @@ class DevicesCategoryModel {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, DeviceType> deviceTypeMap = {
|
||||
'Ceiling Presence Sensors': DeviceType.Sensors,
|
||||
'Wall presence sensor': DeviceType.Sensors,
|
||||
'Door Locks': DeviceType.DoorLock,
|
||||
'Gateways': DeviceType.Gateway,
|
||||
'ACs': DeviceType.AC,
|
||||
'3Gang': DeviceType.Gang,
|
||||
};
|
||||
|
||||
Map<DeviceType, String> deviceTypeIconMap = {
|
||||
DeviceType.AC: Assets.iconsAC,
|
||||
DeviceType.Lights: Assets.iconsLight,
|
||||
DeviceType.LightBulb: Assets.iconsLight,
|
||||
DeviceType.DoorLock: Assets.iconsDoorLock,
|
||||
DeviceType.Curtain: Assets.iconsCurtain,
|
||||
DeviceType.Gateway: Assets.iconsGateway,
|
||||
DeviceType.Sensors: Assets.iconsSensors,
|
||||
DeviceType.Gang: Assets.iconsGang,
|
||||
DeviceType.CeilingSensor: Assets.iconsSensors,
|
||||
DeviceType.WallSensor: Assets.iconsSensors,
|
||||
DeviceType.ThreeGang: Assets.iconsGang,
|
||||
DeviceType.Other: Assets.iconsAC,
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
class DeviceControlModel {
|
||||
String? deviceId;
|
||||
String? code;
|
||||
bool? value;
|
||||
dynamic value;
|
||||
|
||||
DeviceControlModel({
|
||||
required this.deviceId,
|
||||
|
||||
@ -1,46 +1,146 @@
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
class DeviceModel {
|
||||
final int? id;
|
||||
final String? name;
|
||||
final DeviceType? type;
|
||||
bool? status;
|
||||
final String? image;
|
||||
final double? timer;
|
||||
late final String icon;
|
||||
int? activeTime;
|
||||
String? category; //unused
|
||||
String? categoryName; //unused
|
||||
int? createTime; //unused
|
||||
String? gatewayId; //unused
|
||||
String? icon; //unused
|
||||
String? id;
|
||||
String? ip; //unused
|
||||
double? lat; //unused
|
||||
String? localKey;
|
||||
double? lon; //unused
|
||||
String? model;
|
||||
String? name;
|
||||
String? nodeId; //remove
|
||||
bool? isOnline;
|
||||
List<StatusModel> status = [];
|
||||
String? ownerId; //unused
|
||||
String? productId; //unused
|
||||
String? productName;
|
||||
bool? isSub; //unused
|
||||
String? timeZone;
|
||||
int? updateTime;
|
||||
String? uuid;
|
||||
DeviceType? productType;
|
||||
bool isSelected = false;
|
||||
|
||||
late List<FunctionModel> functions;
|
||||
|
||||
DeviceModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.type,
|
||||
this.activeTime,
|
||||
this.category,
|
||||
this.categoryName,
|
||||
this.createTime,
|
||||
this.gatewayId,
|
||||
this.icon,
|
||||
this.id,
|
||||
this.ip,
|
||||
this.lat,
|
||||
this.localKey,
|
||||
this.lon,
|
||||
this.model,
|
||||
this.name,
|
||||
this.nodeId,
|
||||
this.isOnline,
|
||||
required this.status,
|
||||
required this.image,
|
||||
required this.timer,
|
||||
required this.functions,
|
||||
this.ownerId,
|
||||
this.productId,
|
||||
this.productName,
|
||||
this.isSub,
|
||||
this.timeZone,
|
||||
this.updateTime,
|
||||
this.uuid,
|
||||
this.productType,
|
||||
}) {
|
||||
switch (type) {
|
||||
case DeviceType.AC:
|
||||
icon = Assets.iconsAC;
|
||||
break;
|
||||
case DeviceType.Lights:
|
||||
icon = Assets.iconsLight;
|
||||
break;
|
||||
case DeviceType.DoorLock:
|
||||
icon = Assets.iconsDoorLock;
|
||||
break;
|
||||
case DeviceType.Curtain:
|
||||
icon = Assets.iconsCurtain;
|
||||
break;
|
||||
case DeviceType.Gateway:
|
||||
icon = Assets.iconsGateway;
|
||||
break;
|
||||
default:
|
||||
icon = '';
|
||||
}
|
||||
functions = getFunctions(productType!);
|
||||
}
|
||||
|
||||
factory DeviceModel.fromJson(Map<String, dynamic> json) {
|
||||
String icon = '';
|
||||
DeviceType type = devicesTypesMap[json['productId']] ?? DeviceType.Other;
|
||||
|
||||
if (type == DeviceType.LightBulb) {
|
||||
icon = Assets.iconsLight;
|
||||
} else if (type == DeviceType.CeilingSensor ||
|
||||
type == DeviceType.WallSensor) {
|
||||
icon = Assets.iconsSensors;
|
||||
} else if (type == DeviceType.AC) {
|
||||
icon = Assets.iconsAC;
|
||||
} else if (type == DeviceType.DoorLock) {
|
||||
icon = Assets.iconsDoorLock;
|
||||
} else if (type == DeviceType.Curtain) {
|
||||
icon = Assets.iconsCurtain;
|
||||
} else if (type == DeviceType.ThreeGang) {
|
||||
icon = Assets.icons3GangSwitch;
|
||||
} else if (type == DeviceType.Gateway) {
|
||||
icon = Assets.iconsGateway;
|
||||
} else {
|
||||
icon = Assets.iconsLogo;
|
||||
}
|
||||
return DeviceModel(
|
||||
activeTime: json['activeTime'],
|
||||
category: json['category'],
|
||||
categoryName: json['categoryName'],
|
||||
createTime: json['createTime'],
|
||||
gatewayId: json['gatewayId'],
|
||||
icon: icon,
|
||||
id: json['id'],
|
||||
ip: json['ip'],
|
||||
lat: double.tryParse(json['lat']),
|
||||
localKey: json['localKey'],
|
||||
lon: double.tryParse(json['lon']),
|
||||
model: json['model'],
|
||||
name: json['name'],
|
||||
nodeId: json['nodeId'],
|
||||
isOnline: json['online'],
|
||||
ownerId: json['ownerId'],
|
||||
productId: json['productId'],
|
||||
productName: json['productName'],
|
||||
isSub: json['sub'],
|
||||
timeZone: json['timeZone'],
|
||||
updateTime: json['updateTime'],
|
||||
uuid: json['uuid'],
|
||||
productType: type,
|
||||
status: [],
|
||||
// json['status']
|
||||
// .map<StatusModel>((e) => StatusModel.fromJson(e))
|
||||
// .toList(),
|
||||
// devicesTypesMap[json['productName']] ?? DeviceType.Other,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'activeTime': activeTime,
|
||||
'category': category,
|
||||
'categoryName': categoryName,
|
||||
'createTime': createTime,
|
||||
'gatewayId': gatewayId,
|
||||
'icon': icon,
|
||||
'id': id,
|
||||
'ip': ip,
|
||||
'lat': lat,
|
||||
'localKey': localKey,
|
||||
'lon': lon,
|
||||
'model': model,
|
||||
'name': name,
|
||||
'nodeId': nodeId,
|
||||
'online': isOnline,
|
||||
'ownerId': ownerId,
|
||||
'productId': productId,
|
||||
'productName': productName,
|
||||
'sub': isSub,
|
||||
'timeZone': timeZone,
|
||||
'updateTime': updateTime,
|
||||
'uuid': uuid,
|
||||
'productType': productType,
|
||||
};
|
||||
}
|
||||
|
||||
List<FunctionModel> getFunctions(DeviceType type) =>
|
||||
devicesFunctionsMap[productType] ?? [];
|
||||
}
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
//{
|
||||
// "code": "switch_1",
|
||||
// "desc": "switch 1",
|
||||
// "name": "switch 1",
|
||||
// "type": "Boolean",
|
||||
// "values": "{}"
|
||||
// }
|
||||
class FunctionModel {
|
||||
String? code;
|
||||
String? desc;
|
||||
String? name;
|
||||
String? type;
|
||||
String? values;
|
||||
|
||||
FunctionModel({
|
||||
required this.code,
|
||||
required this.desc,
|
||||
required this.name,
|
||||
required this.type,
|
||||
required this.values,
|
||||
});
|
||||
@ -23,8 +12,6 @@ class FunctionModel {
|
||||
factory FunctionModel.fromJson(Map<String, dynamic> json) {
|
||||
return FunctionModel(
|
||||
code: json['code'],
|
||||
desc: json['desc'],
|
||||
name: json['name'],
|
||||
type: json['type'],
|
||||
values: json['values'],
|
||||
);
|
||||
@ -33,8 +20,6 @@ class FunctionModel {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'code': code,
|
||||
'desc': desc,
|
||||
'name': name,
|
||||
'type': type,
|
||||
'values': values,
|
||||
};
|
||||
|
||||
@ -1,30 +1,36 @@
|
||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
|
||||
class RoomModel {
|
||||
final int? id;
|
||||
final String? name;
|
||||
|
||||
final List<DevicesCategoryModel>? categories;
|
||||
List<DeviceModel>? devices;
|
||||
|
||||
RoomModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.categories,
|
||||
required this.devices,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'devices': categories,
|
||||
'devices': devices,
|
||||
};
|
||||
}
|
||||
|
||||
factory RoomModel.fromJson(Map<String, dynamic> json) {
|
||||
List<DeviceModel> devices = [];
|
||||
if (json['devices'] != null) {
|
||||
for (var device in json['devices']) {
|
||||
devices.add(DeviceModel.fromJson(device));
|
||||
}
|
||||
}
|
||||
return RoomModel(
|
||||
id: json['roomId'],
|
||||
name: json['roomName'],
|
||||
categories: json['devices'],
|
||||
devices: devices,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
23
lib/features/devices/model/status_model.dart
Normal file
23
lib/features/devices/model/status_model.dart
Normal file
@ -0,0 +1,23 @@
|
||||
class StatusModel {
|
||||
String? code;
|
||||
dynamic value;
|
||||
|
||||
StatusModel({
|
||||
required this.code,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
factory StatusModel.fromJson(Map<String, dynamic> json) {
|
||||
return StatusModel(
|
||||
code: json['code'],
|
||||
value: json['value'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'code': code,
|
||||
'value': value,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,17 @@
|
||||
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/view/widgets/devices_view_body.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
||||
|
||||
class DevicesView extends StatelessWidget {
|
||||
const DevicesView({super.key});
|
||||
// class DevicesView extends StatelessWidget {
|
||||
// const DevicesView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) => Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
child: const DevicesViewBody(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// print('built DevicesView');
|
||||
// return Container(
|
||||
// padding: const EdgeInsets.all(8),
|
||||
// width: MediaQuery.of(context).size.width,
|
||||
// height: MediaQuery.of(context).size.height,
|
||||
// child: const DevicesViewBody(),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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/view/widgets/ACs/ac_interface_controls.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_temp_unit.dart';
|
||||
@ -22,65 +24,78 @@ class AcInterface extends StatelessWidget {
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: BodyLarge(
|
||||
text: deviceModel.name ?? "",
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.imagesBackground,
|
||||
child: BlocConsumer<DevicesCubit, DevicesState>(
|
||||
listener: (context, state) {
|
||||
if (state is DeviceControlError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.errorMsg),
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
),
|
||||
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(
|
||||
deviceModel: deviceModel,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: 120,
|
||||
),
|
||||
child: AcInterfaceControls(
|
||||
deviceModel: deviceModel,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: BodyLarge(
|
||||
text: deviceModel.name ?? "",
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: 380,
|
||||
),
|
||||
child: AcInterfaceTempUnit(
|
||||
acDevice: deviceModel,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: 120,
|
||||
),
|
||||
child: AcInterfaceControls(
|
||||
deviceModel: deviceModel,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_unit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
class AcInterfaceControls extends StatelessWidget {
|
||||
const AcInterfaceControls({
|
||||
@ -16,38 +17,42 @@ class AcInterfaceControls extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
ACModeControlUnit(model: deviceModel),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
children: [
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsAutomatedClock),
|
||||
ACModeControlUnit(acDevice: deviceModel),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsAutomatedClock),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsLock),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsLock),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:sleek_circular_slider/sleek_circular_slider.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
@ -10,20 +11,25 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class AcInterfaceTempUnit extends StatelessWidget {
|
||||
const AcInterfaceTempUnit({
|
||||
super.key,
|
||||
required this.deviceModel,
|
||||
required this.acDevice,
|
||||
});
|
||||
|
||||
final DeviceModel deviceModel;
|
||||
final DeviceModel acDevice;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
double setToTemp = acDevice.status
|
||||
.firstWhere((element) => element.code == 'temp_set')
|
||||
.value /
|
||||
10;
|
||||
return DefaultContainer(
|
||||
child: Column(
|
||||
children: [
|
||||
@ -72,14 +78,24 @@ class AcInterfaceTempUnit extends StatelessWidget {
|
||||
),
|
||||
// min: DeviceModel.bounds.min,
|
||||
// max: DeviceModel.bounds.max,
|
||||
// initialValue: DeviceModel.temperature,
|
||||
min: 20,
|
||||
max: 30,
|
||||
initialValue: acDevice.status
|
||||
.firstWhere(
|
||||
(element) => element.code == 'temp_current')
|
||||
.value /
|
||||
10,
|
||||
onChange: (value) {
|
||||
String valueAsString = value.toStringAsFixed(1);
|
||||
if (valueAsString.endsWith(".0") ||
|
||||
valueAsString.endsWith(".5")) {
|
||||
value = double.parse(valueAsString);
|
||||
// DevicesCubit.get(context)
|
||||
// .setACTemp(DeviceModel, value);
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: acDevice.id,
|
||||
code: 'temp_set',
|
||||
value: value * 10),
|
||||
acDevice.id!);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -94,9 +110,23 @@ class AcInterfaceTempUnit extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// DevicesCubit.get(context)
|
||||
// .setACTemp(DeviceModel, DeviceModel.coolTo);
|
||||
// DeviceModel.coolTo -= .5;
|
||||
//TODO refactor the loading check
|
||||
if (state is GetDeviceStatusLoading &&
|
||||
state.code == 'temp_set' ||
|
||||
state is DeviceControlSuccess &&
|
||||
state.code == 'temp_set' ||
|
||||
state is DeviceControlLoading &&
|
||||
state.code == 'temp_set') {
|
||||
return;
|
||||
}
|
||||
if (setToTemp > 20) {
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: acDevice.id,
|
||||
code: 'temp_set',
|
||||
value: (setToTemp - 0.5) * 10),
|
||||
acDevice.id!);
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconsMinus,
|
||||
@ -107,10 +137,16 @@ class AcInterfaceTempUnit extends StatelessWidget {
|
||||
children: [
|
||||
BodyLarge(
|
||||
// text: "${DeviceModel.coolTo}° C",
|
||||
text: '24° C',
|
||||
text: '$setToTemp° C',
|
||||
style: context.bodyLarge.copyWith(
|
||||
color:
|
||||
ColorsManager.primaryColor.withOpacity(0.6),
|
||||
color: state is GetDeviceStatusLoading &&
|
||||
state.code == 'temp_set' ||
|
||||
state is DeviceControlSuccess &&
|
||||
state.code == 'temp_set' ||
|
||||
state is DeviceControlLoading &&
|
||||
state.code == 'temp_set'
|
||||
? Colors.grey
|
||||
: ColorsManager.primaryColor.withOpacity(0.6),
|
||||
fontWeight: FontsManager.bold,
|
||||
fontSize: 30,
|
||||
height: 0),
|
||||
@ -125,9 +161,22 @@ class AcInterfaceTempUnit extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// DevicesCubit.get(context)
|
||||
// .setACTemp(DeviceModel, DeviceModel.coolTo);
|
||||
// DeviceModel.coolTo += .5;
|
||||
if (state is GetDeviceStatusLoading &&
|
||||
state.code == 'temp_set' ||
|
||||
state is DeviceControlSuccess &&
|
||||
state.code == 'temp_set' ||
|
||||
state is DeviceControlLoading &&
|
||||
state.code == 'temp_set') {
|
||||
return;
|
||||
}
|
||||
if (setToTemp < 30) {
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: acDevice.id,
|
||||
code: 'temp_set',
|
||||
value: (setToTemp + 0.5) * 10),
|
||||
acDevice.id!);
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconsPlus,
|
||||
|
||||
@ -1,75 +1,96 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
class ACModeControlUnit extends StatefulWidget {
|
||||
const ACModeControlUnit({
|
||||
super.key,
|
||||
required this.model,
|
||||
required this.acDevice,
|
||||
});
|
||||
|
||||
final DeviceModel model;
|
||||
final DeviceModel acDevice;
|
||||
|
||||
@override
|
||||
State<ACModeControlUnit> createState() => _ACModeControlUnitState();
|
||||
}
|
||||
|
||||
class _ACModeControlUnitState extends State<ACModeControlUnit> {
|
||||
var fanSpeeds = [
|
||||
Assets.iconsFan0,
|
||||
Assets.iconsFan1,
|
||||
Assets.iconsFan2,
|
||||
Assets.iconsFan3,
|
||||
];
|
||||
|
||||
var tempModes = [
|
||||
Assets.iconsSunnyMode,
|
||||
Assets.iconsColdMode,
|
||||
Assets.iconsWindyMode,
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//TODO Move the fanSpeeds and tempModes to the Cubit
|
||||
return Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
// widget.model.fanSpeed =
|
||||
// widget.model.fanSpeed == 3 ? 0 : widget.model.fanSpeed + 1;
|
||||
});
|
||||
},
|
||||
child: const DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
// child: SvgPicture.asset(fanSpeeds[widget.model.fanSpeed]),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
// widget.model.tempMode =
|
||||
// widget.model.tempMode == 2 ? 0 : widget.model.tempMode + 1;
|
||||
});
|
||||
},
|
||||
child: const DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
// child: SvgPicture.asset(tempModes[widget.model.tempMode]),
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
FanSpeeds fanSpeed = fanSpeedsMap[widget.acDevice.status
|
||||
.firstWhere((element) => element.code == 'level')
|
||||
.value]!;
|
||||
TempModes tempMode = tempModesMap[widget.acDevice.status
|
||||
.firstWhere((element) => element.code == 'mode')
|
||||
.value]!;
|
||||
return Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// print(
|
||||
// '\n\ncurrentFanSpeed:$fanSpeed \nchanged to:\t${fanSpeedsMap[getNextFanSpeedKey(fanSpeed)]!}\nKey:\t\t\"${reversedFanSpeedsMap[fanSpeedsMap[getNextFanSpeedKey(fanSpeed)]!]!}\"');
|
||||
|
||||
),
|
||||
fanSpeed = fanSpeedsMap[getNextFanSpeedKey(fanSpeed)]!;
|
||||
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: widget.acDevice.id,
|
||||
code: 'level',
|
||||
value: reversedFanSpeedsMap[fanSpeed]!),
|
||||
widget.acDevice.id!);
|
||||
},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: state is GetDeviceStatusLoading &&
|
||||
state.code == 'level' ||
|
||||
state is DeviceControlSuccess &&
|
||||
state.code == 'level' ||
|
||||
state is DeviceControlLoading &&
|
||||
state.code == 'level'
|
||||
? const CircularProgressIndicator()
|
||||
: SvgPicture.asset(fanSpeedsIconMap[fanSpeed]!)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
tempMode = tempModesMap[getNextItem(tempModesMap, tempMode)]!;
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: widget.acDevice.id,
|
||||
code: 'mode',
|
||||
value: reversedTempModesMap[tempMode]!),
|
||||
widget.acDevice.id!);
|
||||
},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: state is GetDeviceStatusLoading &&
|
||||
state.code == 'mode' ||
|
||||
state is DeviceControlSuccess &&
|
||||
state.code == 'mode' ||
|
||||
state is DeviceControlLoading &&
|
||||
state.code == 'mode'
|
||||
? const CircularProgressIndicator()
|
||||
: SvgPicture.asset(tempModesIconMap[tempMode]!),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
class ACTempWidget extends StatelessWidget {
|
||||
const ACTempWidget(
|
||||
@ -31,7 +31,7 @@ class ACTempWidget extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// DevicesCubit.get(context)
|
||||
// DevicesCubit.getInstance()
|
||||
// .setACTemp(DeviceModel, DeviceModel.temperature - 0.5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
@ -51,7 +51,7 @@ class ACTempWidget extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// DevicesCubit.get(context)
|
||||
// DevicesCubit.getInstance()
|
||||
// .setACTemp(DeviceModel, DeviceModel.temperature + 0.5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
|
||||
@ -27,7 +27,7 @@ class ACsList extends StatelessWidget {
|
||||
const BodySmall(text: "All ACs"),
|
||||
const SizedBox(height: 5),
|
||||
UniversalSwitch(
|
||||
category: DevicesCubit.get(context).chosenCategory!,
|
||||
category: DevicesCubit.getInstance().chosenCategory!,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const UniversalACTemp(),
|
||||
@ -39,9 +39,9 @@ class ACsList extends StatelessWidget {
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.all(0),
|
||||
itemCount:
|
||||
DevicesCubit.get(context).chosenCategory!.devices!.length,
|
||||
DevicesCubit.getInstance().chosenCategory!.devices!.length,
|
||||
itemBuilder: (context, index) {
|
||||
DeviceModel ac = DevicesCubit.get(context)
|
||||
DeviceModel ac = DevicesCubit.getInstance()
|
||||
.chosenCategory!
|
||||
.devices![index];
|
||||
return Column(
|
||||
@ -52,14 +52,14 @@ class ACsList extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
BodySmall(
|
||||
text: DevicesCubit.get(context)
|
||||
text: DevicesCubit.getInstance()
|
||||
.chosenCategory!
|
||||
.devices![index]
|
||||
.name ??
|
||||
""),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
DevicesCubit.get(context).selectDevice(ac);
|
||||
DevicesCubit.getInstance().selectDevice(ac);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
@ -84,7 +84,7 @@ class ACsList extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ACModeControlUnit(
|
||||
model: ac,
|
||||
acDevice: ac,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
|
||||
@ -6,10 +6,9 @@ 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/devices/view/widgets/ACs/acs_list.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/category_view_app_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
import '../../../../../utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
class ACsView extends StatelessWidget {
|
||||
const ACsView({super.key});
|
||||
@ -21,9 +20,9 @@ class ACsView extends StatelessWidget {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
DeviceModel? selectedAC;
|
||||
if (DevicesCubit.get(context).getSelectedDevice() is DeviceModel) {
|
||||
if (DevicesCubit.getInstance().getSelectedDevice() is DeviceModel) {
|
||||
selectedAC =
|
||||
DevicesCubit.get(context).getSelectedDevice() as DeviceModel;
|
||||
DevicesCubit.getInstance().getSelectedDevice() as DeviceModel;
|
||||
}
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
|
||||
@ -2,10 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/display_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/constants.dart';
|
||||
|
||||
import '../../../../../utils/resource_manager/color_manager.dart';
|
||||
|
||||
class CategoryViewAppBar extends StatelessWidget
|
||||
implements PreferredSizeWidget {
|
||||
const CategoryViewAppBar({
|
||||
@ -20,7 +19,7 @@ class CategoryViewAppBar extends StatelessWidget
|
||||
toolbarHeight: Constants.appBarHeight,
|
||||
centerTitle: true,
|
||||
title: DisplayMedium(
|
||||
text: DevicesCubit.get(context).chosenCategory!.name!,
|
||||
text: DevicesCubit.getInstance().chosenCategory!.name!,
|
||||
style: context.displayMedium.copyWith(
|
||||
color: ColorsManager.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -32,7 +31,7 @@ class CategoryViewAppBar extends StatelessWidget
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
DevicesCubit.get(context).clearCategoriesSelection(context);
|
||||
DevicesCubit.getInstance().clearCategoriesSelection(context);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@ -2,12 +2,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
import '../../../../../utils/resource_manager/color_manager.dart';
|
||||
import '../../../../shared_widgets/default_container.dart';
|
||||
import '../../../../shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class UniversalACTemp extends StatelessWidget {
|
||||
const UniversalACTemp({
|
||||
@ -27,7 +26,7 @@ class UniversalACTemp extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// DevicesCubit.get(context)
|
||||
// DevicesCubit.getInstance()
|
||||
// .setTempToAll(DevicesCubit.universalACTemp - .5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
@ -47,7 +46,7 @@ class UniversalACTemp extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// DevicesCubit.get(context)
|
||||
// DevicesCubit.getInstance()
|
||||
// .setTempToAll(DevicesCubit.universalACTemp + .5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
|
||||
@ -25,7 +25,7 @@ class CurtainList extends StatelessWidget {
|
||||
const BodySmall(text: "All Curtains"),
|
||||
const SizedBox(height: 5),
|
||||
UniversalSwitch(
|
||||
category: DevicesCubit.get(context).chosenCategory!,
|
||||
category: DevicesCubit.getInstance().chosenCategory!,
|
||||
),
|
||||
|
||||
// other ACs controls
|
||||
@ -34,16 +34,17 @@ class CurtainList extends StatelessWidget {
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.all(0),
|
||||
itemCount:
|
||||
DevicesCubit.get(context).chosenCategory!.devices!.length,
|
||||
DevicesCubit.getInstance().chosenCategory!.devices!.length,
|
||||
itemBuilder: (context, index) {
|
||||
DeviceModel curtain =
|
||||
DevicesCubit.get(context).chosenCategory!.devices![index];
|
||||
DeviceModel curtain = DevicesCubit.getInstance()
|
||||
.chosenCategory!
|
||||
.devices![index];
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
BodySmall(
|
||||
text: DevicesCubit.get(context)
|
||||
text: DevicesCubit.getInstance()
|
||||
.chosenCategory!
|
||||
.devices![index]
|
||||
.name ??
|
||||
|
||||
@ -20,13 +20,13 @@ class CurtainView extends StatelessWidget {
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: const CategoryViewAppBar(),
|
||||
body: Container(
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: const CategoryViewAppBar(),
|
||||
body: SafeArea(
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
|
||||
@ -2,6 +2,7 @@ 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/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_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';
|
||||
@ -9,8 +10,6 @@ import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
import '../../bloc/devices_cubit.dart';
|
||||
|
||||
class DevicesViewBody extends StatelessWidget {
|
||||
const DevicesViewBody({
|
||||
super.key,
|
||||
@ -18,73 +17,95 @@ class DevicesViewBody extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<HomeCubit, HomeState>(
|
||||
return BlocConsumer<DevicesCubit, DevicesState>(
|
||||
listener: (context, state) {
|
||||
if (state is GetDevicesError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.errorMsg),
|
||||
),
|
||||
);
|
||||
} else if (state is DevicesCategoriesError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.errorMsg),
|
||||
),
|
||||
);
|
||||
} else if (state is DeviceControlError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(state.errorMsg),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
//TODO : move to NavigationCubit
|
||||
if (state is DevicesLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: Constants.appBarHeight,
|
||||
bottom: Constants.bottomNavBarHeight,
|
||||
if (state is DevicesLoading ||
|
||||
state is GetDevicesLoading ||
|
||||
state is DevicesCategoriesLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: Constants.appBarHeight,
|
||||
bottom: Constants.bottomNavBarHeight,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const DevicesViewHeader(),
|
||||
const RoomsSlider(),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const DevicesViewHeader(),
|
||||
const RoomsSlider(),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: PageView(
|
||||
controller:
|
||||
HomeCubit.get(context).devicesPageController,
|
||||
onPageChanged: (index) {
|
||||
HomeCubit.get(context).devicesPageChanged(index);
|
||||
},
|
||||
children: [
|
||||
const WizardPage(),
|
||||
if (HomeCubit.selectedSpace != null)
|
||||
if (HomeCubit.selectedSpace!.rooms != null)
|
||||
...HomeCubit.selectedSpace!.rooms!.map(
|
||||
(room) {
|
||||
return RoomPage(
|
||||
room: room,
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
HomeCubit.selectedSpace != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 7,
|
||||
),
|
||||
child: SmoothPageIndicator(
|
||||
controller:
|
||||
HomeCubit.get(context).devicesPageController,
|
||||
count: HomeCubit.selectedSpace!.rooms!.length + 1,
|
||||
effect: const WormEffect(
|
||||
paintStyle: PaintingStyle.stroke,
|
||||
dotHeight: 8,
|
||||
dotWidth: 8,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: PageView(
|
||||
controller: HomeCubit.getInstance().devicesPageController,
|
||||
onPageChanged: (index) {
|
||||
HomeCubit.getInstance().devicesPageChanged(index);
|
||||
},
|
||||
children: [
|
||||
const WizardPage(),
|
||||
if (HomeCubit.getInstance().selectedSpace != null)
|
||||
if (HomeCubit.getInstance().selectedSpace!.rooms !=
|
||||
null)
|
||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map(
|
||||
(room) {
|
||||
return RoomPage(
|
||||
room: room,
|
||||
);
|
||||
},
|
||||
)
|
||||
: const Center(
|
||||
child: BodyLarge(text: 'No Home Found'),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
HomeCubit.getInstance().selectedSpace != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 7,
|
||||
),
|
||||
child: SmoothPageIndicator(
|
||||
controller:
|
||||
HomeCubit.getInstance().devicesPageController,
|
||||
count: HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.rooms!
|
||||
.length +
|
||||
1,
|
||||
effect: const WormEffect(
|
||||
paintStyle: PaintingStyle.stroke,
|
||||
dotHeight: 8,
|
||||
dotWidth: 8,
|
||||
),
|
||||
),
|
||||
)
|
||||
: const Center(
|
||||
child: BodyLarge(text: 'No Home Found'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ class LightBrightness extends StatelessWidget {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
// onHorizontalDragUpdate: (details) => DevicesCubit().get(context)
|
||||
// onHorizontalDragUpdate: (details) => DevicesCubit.getInstance().get(context)
|
||||
// .onHorizontalDragUpdate(light, details.localPosition.dx,
|
||||
// MediaQuery.of(context).size.width - 15),
|
||||
child: Stack(
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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/view/widgets/lights/light_interface_contols.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface_switch.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface_timer.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
|
||||
class LightInterface extends StatelessWidget {
|
||||
const LightInterface({super.key, required this.light});
|
||||
@ -15,16 +19,36 @@ class LightInterface extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 70, right: 20, left: 20),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
LightInterfaceSwitch(light: light),
|
||||
LightInterfaceContols(light: light),
|
||||
const LightInterfaceTimer(),
|
||||
],
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
title: BodyLarge(
|
||||
text: light.name ?? "",
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(top: 70, right: 20, left: 20),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
LightInterfaceSwitch(light: light),
|
||||
LightInterfaceContols(light: light),
|
||||
const LightInterfaceTimer(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -27,10 +27,10 @@ class LightInterfaceModes extends StatelessWidget {
|
||||
Wrap(
|
||||
spacing: 25,
|
||||
children: List.generate(
|
||||
DevicesCubit.get(context).lightModes.length,
|
||||
DevicesCubit.getInstance().lightModes.length,
|
||||
(index) => InkWell(
|
||||
// onTap: () => DevicesCubit.get(context).setLightingMode(
|
||||
// light, DevicesCubit.get(context).lightModes[index]!),
|
||||
// onTap: () => DevicesCubit.getInstance().setLightingMode(
|
||||
// light, DevicesCubit.getInstance().lightModes[index]!),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.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 '../../../../../utils/resource_manager/strings_manager.dart';
|
||||
import '../../../../shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
class LightInterfaceRecentColor extends StatelessWidget {
|
||||
const LightInterfaceRecentColor({
|
||||
@ -34,7 +34,7 @@ class LightInterfaceRecentColor extends StatelessWidget {
|
||||
4,
|
||||
(index) => InkWell(
|
||||
// onTap: () {
|
||||
// DevicesCubit.get(context)
|
||||
// DevicesCubit.getInstance()
|
||||
// .setColor(light, light.recentColors[index]);
|
||||
// },
|
||||
child: Container(
|
||||
|
||||
@ -60,7 +60,7 @@ class LightInterfaceSlider extends StatelessWidget {
|
||||
// value: light.brightness,
|
||||
value: 100,
|
||||
onChanged: (value) {
|
||||
// DevicesCubit.get(context).setBrightness(light, value);
|
||||
// DevicesCubit.getInstance().setBrightness(light, value);
|
||||
},
|
||||
min: 0,
|
||||
max: 100,
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
import '../../../../shared_widgets/default_container.dart';
|
||||
|
||||
class LightInterfaceSwitch extends StatelessWidget {
|
||||
const LightInterfaceSwitch({
|
||||
super.key,
|
||||
@ -28,7 +27,7 @@ class LightInterfaceSwitch extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodyLarge(
|
||||
text: light.status ?? false
|
||||
text: light.isOnline ?? false
|
||||
? StringsManager.on
|
||||
: StringsManager.off,
|
||||
style:
|
||||
@ -37,7 +36,7 @@ class LightInterfaceSwitch extends StatelessWidget {
|
||||
Container(
|
||||
width: 35,
|
||||
decoration: ShapeDecoration(
|
||||
color: light.status ?? false
|
||||
color: light.isOnline ?? false
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: Colors.grey,
|
||||
shape: const CircleBorder(),
|
||||
@ -51,7 +50,7 @@ class LightInterfaceSwitch extends StatelessWidget {
|
||||
iconSize: MaterialStateProperty.all(25),
|
||||
),
|
||||
onPressed: () {
|
||||
// DevicesCubit.get(context).toggleLight(light);
|
||||
// DevicesCubit.getInstance().toggleLight(light);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.power_settings_new,
|
||||
|
||||
@ -3,7 +3,7 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
import '../../../../shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
|
||||
class LightInterfaceTimer extends StatelessWidget {
|
||||
const LightInterfaceTimer({
|
||||
|
||||
@ -2,9 +2,8 @@ import 'package:flutter/material.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/view/widgets/lights/light_brightness.dart';
|
||||
|
||||
import '../../../../shared_widgets/devices_default_switch.dart';
|
||||
import '../../../../shared_widgets/text_widgets/body_small.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 LightsList extends StatelessWidget {
|
||||
const LightsList({
|
||||
@ -32,7 +31,7 @@ class LightsList extends StatelessWidget {
|
||||
BodySmall(text: lights[index].name ?? ""),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
DevicesCubit.get(context).selectDevice(lights[index]);
|
||||
DevicesCubit.getInstance().selectDevice(lights[index]);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
|
||||
@ -19,9 +19,9 @@ class LightsView extends StatelessWidget {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
DeviceModel? selectedLight;
|
||||
if (DevicesCubit.get(context).getSelectedDevice() is DeviceModel) {
|
||||
if (DevicesCubit.getInstance().getSelectedDevice() is DeviceModel) {
|
||||
selectedLight =
|
||||
DevicesCubit.get(context).getSelectedDevice() as DeviceModel;
|
||||
DevicesCubit.getInstance().getSelectedDevice() as DeviceModel;
|
||||
}
|
||||
List<DeviceModel> lights = [];
|
||||
if (DevicesCubit.allCategories![1].devices != null) {
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import 'package:flutter/material.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/view/widgets/lights/lights_list.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/universal_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
import '../../../../shared_widgets/text_widgets/body_small.dart';
|
||||
import '../../../bloc/devices_cubit.dart';
|
||||
import '../universal_switch.dart';
|
||||
|
||||
class LightsViewList extends StatelessWidget {
|
||||
const LightsViewList({
|
||||
super.key,
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class LightSwitch extends StatelessWidget {
|
||||
const LightSwitch({
|
||||
super.key,
|
||||
required this.control,
|
||||
});
|
||||
|
||||
final DeviceControlModel control;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
return state is DeviceControlLoading
|
||||
? const CircularProgressIndicator()
|
||||
: InkWell(
|
||||
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||
onTap: () {
|
||||
DevicesCubit.get(context)
|
||||
.deviceControl(control)
|
||||
.then((value) {
|
||||
print('Device control response: $value');
|
||||
if (control.value ?? true) {
|
||||
control.value = false;
|
||||
} else {
|
||||
control.value = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Stack(
|
||||
alignment: !control.value!
|
||||
? Alignment.topCenter
|
||||
: Alignment.bottomCenter,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(100.0)),
|
||||
color: !control.value!
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: ColorsManager.switchOffColor,
|
||||
),
|
||||
width: 60,
|
||||
height: 115,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: SizedBox.square(
|
||||
dimension: 60,
|
||||
child: SvgPicture.asset(
|
||||
!control.value!
|
||||
? Assets.iconsLightSwitchOn
|
||||
: Assets.iconsLightSwitchOff,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,87 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/category_view_app_bar.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights_switches/light_switches_body.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 LightSwitchesView extends StatelessWidget {
|
||||
const LightSwitchesView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: const CategoryViewAppBar(),
|
||||
body: BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return 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,
|
||||
bottom: Constants.bottomNavBarHeight,
|
||||
),
|
||||
child: LightSwitchesBody(
|
||||
device: DeviceModel(
|
||||
id: 2,
|
||||
name: 'Bedroom Light',
|
||||
type: DeviceType.Lights,
|
||||
status: true,
|
||||
timer: 0,
|
||||
image: '',
|
||||
functions: [
|
||||
FunctionModel(
|
||||
code: 'switch_1',
|
||||
desc: 'switch 1',
|
||||
name: 'switch 1',
|
||||
type: 'Boolean',
|
||||
values: '{}'),
|
||||
FunctionModel(
|
||||
code: 'switch_2',
|
||||
desc: 'switch 2',
|
||||
name: 'switch 2',
|
||||
type: 'Boolean',
|
||||
values: '{}'),
|
||||
FunctionModel(
|
||||
code: 'switch_3',
|
||||
desc: 'switch 3',
|
||||
name: 'switch 3',
|
||||
type: 'Boolean',
|
||||
values: '{}'),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,260 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights_switches/light_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class LightSwitchesBody extends StatelessWidget {
|
||||
const LightSwitchesBody({
|
||||
super.key,
|
||||
required this.device,
|
||||
});
|
||||
|
||||
final DeviceModel device;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Expanded(child: SizedBox.shrink()),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
LightSwitch(
|
||||
control: DeviceControlModel(
|
||||
deviceId: 'bfe10693d4fd263206ocq9',
|
||||
code: 'switch_1',
|
||||
value: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 70,
|
||||
child: BodySmall(
|
||||
text: "Bedside Light",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
LightSwitch(
|
||||
control: DeviceControlModel(
|
||||
deviceId: 'bfe10693d4fd263206ocq9',
|
||||
code: 'switch_2',
|
||||
value: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 70,
|
||||
child: BodySmall(
|
||||
text: "Ceiling Light",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
LightSwitch(
|
||||
control: DeviceControlModel(
|
||||
deviceId: 'bfe10693d4fd263206ocq9',
|
||||
code: 'switch_3',
|
||||
value: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 70,
|
||||
child: BodySmall(
|
||||
text: "Spotlight",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: BodySmall(
|
||||
text: "On",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "All On",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.access_time,
|
||||
color: ColorsManager.primaryColorWithOpacity,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "Timer",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: BodySmall(
|
||||
text: "Off",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "All Off",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
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';
|
||||
@ -13,10 +12,6 @@ class RoomPage extends StatelessWidget {
|
||||
|
||||
@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(
|
||||
@ -32,9 +27,9 @@ class RoomPage extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: devices.length,
|
||||
itemBuilder: (_, index) {
|
||||
return RoomPageSwitch(device: devices[index]);
|
||||
itemCount: room.devices!.length,
|
||||
itemBuilder: (context, index) {
|
||||
return RoomPageSwitch(device: room.devices![index]);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.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/devices/view/widgets/lights/light_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_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';
|
||||
@ -21,25 +25,57 @@ class RoomPageSwitch extends StatelessWidget {
|
||||
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(deviceModel: device),
|
||||
),
|
||||
);
|
||||
switch (device.productType) {
|
||||
case DeviceType.AC:
|
||||
{
|
||||
print("AC");
|
||||
Navigator.push(
|
||||
context,
|
||||
CustomPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (context) => DevicesCubit.getInstance(),
|
||||
child: AcInterface(deviceModel: device),
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case DeviceType.WallSensor:
|
||||
break;
|
||||
case DeviceType.CeilingSensor:
|
||||
break;
|
||||
case DeviceType.Curtain:
|
||||
break;
|
||||
case DeviceType.Blind:
|
||||
break;
|
||||
case DeviceType.DoorLock:
|
||||
break;
|
||||
case DeviceType.Gateway:
|
||||
break;
|
||||
case DeviceType.LightBulb:
|
||||
Navigator.push(
|
||||
context,
|
||||
CustomPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (context) => DevicesCubit.getInstance(),
|
||||
child: LightInterface(light: device),
|
||||
),
|
||||
),
|
||||
);
|
||||
case DeviceType.ThreeGang:
|
||||
Navigator.push(
|
||||
context,
|
||||
CustomPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (context) => DevicesCubit.getInstance(),
|
||||
child: ThreeGangInterface(
|
||||
gangSwitch: device,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
},
|
||||
child: DefaultContainer(
|
||||
@ -54,7 +90,7 @@ class RoomPageSwitch extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
device.icon,
|
||||
device.icon!,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
CustomSwitch(
|
||||
|
||||
@ -18,51 +18,55 @@ class RoomsSlider extends StatelessWidget {
|
||||
return SizedBox(
|
||||
height: 40,
|
||||
child: PageView(
|
||||
controller: HomeCubit.get(context).roomsPageController,
|
||||
controller: HomeCubit.getInstance().roomsPageController,
|
||||
onPageChanged: (index) {
|
||||
HomeCubit.get(context).roomSliderPageChanged(index);
|
||||
HomeCubit.getInstance().roomSliderPageChanged(index);
|
||||
},
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
HomeCubit.get(context).unselectRoom();
|
||||
HomeCubit.getInstance().unselectRoom();
|
||||
},
|
||||
child: TitleMedium(
|
||||
text: StringsManager.wizard,
|
||||
style: context.titleMedium.copyWith(
|
||||
fontSize: 25,
|
||||
color: HomeCubit.get(context).selectedRoom == null
|
||||
color: HomeCubit.getInstance().selectedRoom == null
|
||||
? ColorsManager.textPrimaryColor
|
||||
: ColorsManager.textPrimaryColor.withOpacity(.2),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (HomeCubit.selectedSpace != null)
|
||||
if (HomeCubit.selectedSpace!.rooms != null)
|
||||
...HomeCubit.selectedSpace!.rooms!.map(
|
||||
(room) => Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
HomeCubit.get(context).roomSliderPageChanged(
|
||||
HomeCubit.selectedSpace!.rooms!.indexOf(room));
|
||||
},
|
||||
child: TitleMedium(
|
||||
text: room.name!,
|
||||
style: context.titleMedium.copyWith(
|
||||
fontSize: 25,
|
||||
color: HomeCubit.get(context).selectedRoom == room
|
||||
? ColorsManager.textPrimaryColor
|
||||
: ColorsManager.textPrimaryColor
|
||||
.withOpacity(.2),
|
||||
if (HomeCubit.getInstance().selectedSpace != null)
|
||||
if (HomeCubit.getInstance().selectedSpace!.rooms != null)
|
||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map(
|
||||
(room) => Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
HomeCubit.getInstance().roomSliderPageChanged(
|
||||
HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.rooms!
|
||||
.indexOf(room));
|
||||
},
|
||||
child: TitleMedium(
|
||||
text: room.name!,
|
||||
style: context.titleMedium.copyWith(
|
||||
fontSize: 25,
|
||||
color:
|
||||
HomeCubit.getInstance().selectedRoom == room
|
||||
? ColorsManager.textPrimaryColor
|
||||
: ColorsManager.textPrimaryColor
|
||||
.withOpacity(.2),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class GangSwitch extends StatelessWidget {
|
||||
const GangSwitch({
|
||||
super.key,
|
||||
required this.threeGangSwitch,
|
||||
required this.control,
|
||||
});
|
||||
|
||||
final DeviceModel threeGangSwitch;
|
||||
|
||||
final DeviceControlModel control;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
return InkWell(
|
||||
overlayColor: MaterialStateProperty.all(Colors.transparent),
|
||||
onTap: () {
|
||||
var tempControl = DeviceControlModel(
|
||||
deviceId: control.deviceId,
|
||||
code: control.code!,
|
||||
value: !control.value!);
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
tempControl,
|
||||
control.deviceId!,
|
||||
);
|
||||
},
|
||||
child: Stack(
|
||||
alignment:
|
||||
!control.value! ? Alignment.topCenter : Alignment.bottomCenter,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(100.0)),
|
||||
color: threeGangSwitch.status
|
||||
.firstWhere((element) => element.code == control.code)
|
||||
.value!
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: ColorsManager.switchOffColor,
|
||||
),
|
||||
width: 60,
|
||||
height: 115,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
child: SizedBox.square(
|
||||
dimension: 60,
|
||||
child: state is GetDeviceStatusLoading &&
|
||||
state.code == control.code ||
|
||||
state is DeviceControlSuccess &&
|
||||
state.code == control.code ||
|
||||
state is DeviceControlLoading &&
|
||||
state.code == control.code
|
||||
? const SizedBox(
|
||||
width: 10,
|
||||
height: 10,
|
||||
child: Center(child: CircularProgressIndicator()))
|
||||
: SvgPicture.asset(
|
||||
control.value!
|
||||
? Assets.iconsLightSwitchOn
|
||||
: Assets.iconsLightSwitchOff,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface_body.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 ThreeGangInterface extends StatelessWidget {
|
||||
const ThreeGangInterface({super.key, required this.gangSwitch});
|
||||
|
||||
final DeviceModel gangSwitch;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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: gangSwitch.name ?? "",
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontWeight: FontsManager.bold,
|
||||
),
|
||||
),
|
||||
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,
|
||||
bottom: Constants.bottomNavBarHeight,
|
||||
),
|
||||
child: ThreeGangInterfaceBody(
|
||||
device: gangSwitch,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,328 @@
|
||||
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_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/gang_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class ThreeGangInterfaceBody extends StatelessWidget {
|
||||
const ThreeGangInterfaceBody({
|
||||
super.key,
|
||||
required this.device,
|
||||
});
|
||||
|
||||
final DeviceModel device;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Expanded(child: SizedBox.shrink()),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
GangSwitch(
|
||||
threeGangSwitch: device,
|
||||
control: DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
// code: 'switch_1',
|
||||
code: device.status[0].code,
|
||||
// value: true,
|
||||
value: device.status[0].value,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 70,
|
||||
child: BodySmall(
|
||||
text: "Bedside Light",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
GangSwitch(
|
||||
threeGangSwitch: device,
|
||||
control: DeviceControlModel(
|
||||
// deviceId: 'bfe10693d4fd263206ocq9',
|
||||
// code: 'switch_2',
|
||||
// value: true,
|
||||
deviceId: device.id,
|
||||
code: device.status[1].code,
|
||||
value: device.status[1].value,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 70,
|
||||
child: BodySmall(
|
||||
text: "Ceiling Light",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
GangSwitch(
|
||||
threeGangSwitch: device,
|
||||
control: DeviceControlModel(
|
||||
// deviceId: 'bfe10693d4fd263206ocq9',
|
||||
// code: 'switch_3',
|
||||
// value: true,
|
||||
deviceId: device.id,
|
||||
code: device.status[2].code,
|
||||
value: device.status[2].value,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(
|
||||
width: 70,
|
||||
child: BodySmall(
|
||||
text: "Spotlight",
|
||||
fontColor: ColorsManager.textPrimaryColor,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
code: 'switch_1',
|
||||
value: true,
|
||||
),
|
||||
device.id!,
|
||||
);
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
code: 'switch_2',
|
||||
value: true,
|
||||
),
|
||||
device.id!,
|
||||
);
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
code: 'switch_3',
|
||||
value: true,
|
||||
),
|
||||
device.id!,
|
||||
);
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: BodySmall(
|
||||
text: "On",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager
|
||||
.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "All On",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.access_time,
|
||||
color:
|
||||
ColorsManager.primaryColorWithOpacity,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "Timer",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
code: 'switch_1',
|
||||
value: false,
|
||||
),
|
||||
device.id!,
|
||||
);
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
code: 'switch_2',
|
||||
value: false,
|
||||
),
|
||||
device.id!,
|
||||
);
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
code: 'switch_3',
|
||||
value: false,
|
||||
),
|
||||
device.id!,
|
||||
);
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Center(
|
||||
child: BodySmall(
|
||||
text: "Off",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager
|
||||
.primaryColorWithOpacity,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BodySmall(
|
||||
text: "All Off",
|
||||
style: context.bodyMedium.copyWith(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2,11 +2,10 @@ 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/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
import '../../../../utils/resource_manager/color_manager.dart';
|
||||
import '../../../shared_widgets/text_widgets/body_medium.dart';
|
||||
|
||||
class UniversalSwitch extends StatelessWidget {
|
||||
const UniversalSwitch({
|
||||
super.key,
|
||||
@ -25,7 +24,7 @@ class UniversalSwitch extends StatelessWidget {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.get(context).turnAllDevicesOn(category);
|
||||
DevicesCubit.getInstance().turnAllDevicesOn(category);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
@ -57,7 +56,7 @@ class UniversalSwitch extends StatelessWidget {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.get(context).turnAllDevicesOff(category);
|
||||
DevicesCubit.getInstance().turnAllDevicesOff(category);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
||||
|
||||
import '../../bloc/devices_cubit.dart';
|
||||
|
||||
class WizartSwitches extends StatelessWidget {
|
||||
const WizartSwitches({
|
||||
super.key,
|
||||
@ -35,12 +33,12 @@ class WizartSwitches extends StatelessWidget {
|
||||
itemBuilder: (_, index) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.get(context).selectCategory(index);
|
||||
// DevicesCubit.getInstance().selectCategory(index);
|
||||
//Navigate to the chosen category view without animation
|
||||
|
||||
Navigator.push(context,
|
||||
CustomPageRoute(builder: (context) {
|
||||
return DevicesCubit.get(context)
|
||||
return DevicesCubit.getInstance()
|
||||
.chosenCategoryView!;
|
||||
}));
|
||||
},
|
||||
@ -61,10 +59,7 @@ class WizartSwitches extends StatelessWidget {
|
||||
DevicesCubit.allCategories![index].icon!,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
CustomSwitch(
|
||||
category:
|
||||
DevicesCubit.allCategories![index],
|
||||
),
|
||||
// CustomSwitch(
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../model/list_item_model.dart';
|
||||
import '../model/menu_list_model.dart';
|
||||
import 'package:syncrow_app/features/menu/model/list_item_model.dart';
|
||||
import 'package:syncrow_app/features/menu/model/menu_list_model.dart';
|
||||
|
||||
part 'menu_state.dart';
|
||||
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/syncrow_logo.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
|
||||
import '../../../shared_widgets/syncrow_logo.dart';
|
||||
|
||||
class ProfileTab extends StatelessWidget {
|
||||
const ProfileTab({
|
||||
super.key,
|
||||
|
||||
@ -2,80 +2,87 @@ 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_control_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class CustomSwitch extends StatelessWidget {
|
||||
const CustomSwitch({super.key, this.category, this.device})
|
||||
: assert(category != null || device != null);
|
||||
|
||||
final DevicesCategoryModel? category;
|
||||
|
||||
final DeviceModel? device;
|
||||
const CustomSwitch({super.key, required this.device});
|
||||
|
||||
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;
|
||||
if (device.status.isNotEmpty) {
|
||||
status = device.status
|
||||
.firstWhereOrNull((status) => status.code == "switch")
|
||||
?.value;
|
||||
}
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
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: status != null
|
||||
? status
|
||||
? ColorsManager.primaryColor
|
||||
: const Color(0xFFD9D9D9)
|
||||
: const Color(0xFFD9D9D9),
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 40.0,
|
||||
height: 23.0,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: Container(
|
||||
alignment: status != null
|
||||
return status == null
|
||||
? const SizedBox()
|
||||
: GestureDetector(
|
||||
onTap: () {
|
||||
DevicesCubit.getInstance().deviceControl(
|
||||
DeviceControlModel(
|
||||
deviceId: device.id,
|
||||
code: device.status
|
||||
.firstWhere((status) => status.code == "switch")
|
||||
.code,
|
||||
value: !device.status
|
||||
.firstWhere((status) => status.code == "switch")
|
||||
.value!,
|
||||
),
|
||||
device.id!,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: 45.0,
|
||||
height: 28.0,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
color: status != null
|
||||
? status
|
||||
? Alignment.centerRight
|
||||
: Alignment.centerLeft
|
||||
: Alignment.centerLeft,
|
||||
? ColorsManager.primaryColor
|
||||
: const Color(0xFFD9D9D9)
|
||||
: const Color(0xFFD9D9D9),
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
width: 40.0,
|
||||
height: 23.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: status != null
|
||||
? status
|
||||
? ColorsManager.primaryColor
|
||||
: Colors.grey
|
||||
: Colors.grey,
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: Container(
|
||||
alignment: status != null
|
||||
? status
|
||||
? Alignment.centerRight
|
||||
: Alignment.centerLeft
|
||||
: Alignment.centerLeft,
|
||||
child: Container(
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: status != null
|
||||
? status
|
||||
? ColorsManager.primaryColor
|
||||
: Colors.grey
|
||||
: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
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/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../devices/bloc/devices_cubit.dart';
|
||||
|
||||
class DevicesDefaultSwitch extends StatelessWidget {
|
||||
const DevicesDefaultSwitch({
|
||||
super.key,
|
||||
@ -23,12 +22,12 @@ class DevicesDefaultSwitch extends StatelessWidget {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.get(context).turnOnOffDevice(model);
|
||||
DevicesCubit.getInstance().turnOnOffDevice(model);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: model.status ?? false
|
||||
color: model.isOnline ?? false
|
||||
? ColorsManager.primaryColor
|
||||
: Colors.white,
|
||||
borderRadius: const BorderRadius.only(
|
||||
@ -39,7 +38,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: "ON",
|
||||
fontColor: model.status ?? false ? Colors.white : null,
|
||||
fontColor: model.isOnline ?? false ? Colors.white : null,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -49,12 +48,12 @@ class DevicesDefaultSwitch extends StatelessWidget {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.get(context).turnOnOffDevice(model);
|
||||
DevicesCubit.getInstance().turnOnOffDevice(model);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: model.status ?? false
|
||||
color: model.isOnline ?? false
|
||||
? Colors.white
|
||||
: ColorsManager.primaryColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
@ -65,7 +64,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: "OFF",
|
||||
fontColor: model.status ?? false ? null : Colors.white,
|
||||
fontColor: model.isOnline ?? false ? null : Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
@ -18,12 +18,8 @@ class MyApp extends StatelessWidget {
|
||||
MediaQuery.sizeOf(context).height * Constants.appBarHeightPercentage;
|
||||
Constants.bottomNavBarHeight = MediaQuery.sizeOf(context).height *
|
||||
Constants.bottomNavBarHeightPercentage;
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) => AuthCubit(),
|
||||
),
|
||||
],
|
||||
return BlocProvider(
|
||||
create: (context) => AuthCubit(),
|
||||
child: MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
color: ColorsManager.primaryColor,
|
||||
|
||||
@ -7,7 +7,6 @@ import 'package:syncrow_app/features/auth/view/widgets/privacy_policy/privacy_po
|
||||
import 'package:syncrow_app/features/auth/view/widgets/sign_up/sign_up_view.dart';
|
||||
import 'package:syncrow_app/features/auth/view/widgets/user_agreement/user_agreement_view.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/devices_view.dart';
|
||||
import 'package:syncrow_app/features/layout/view/layout_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/menu_view.dart';
|
||||
import 'package:syncrow_app/features/profile/view/profile_view.dart';
|
||||
@ -23,9 +22,9 @@ class Router {
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const SplashView(), settings: settings);
|
||||
|
||||
case Routes.devicesRoute:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const DevicesView(), settings: settings);
|
||||
// case Routes.devicesRoute:
|
||||
// return MaterialPageRoute(
|
||||
// builder: (_) => const DevicesView(), settings: settings);
|
||||
|
||||
case Routes.profileRoute:
|
||||
return MaterialPageRoute(
|
||||
|
||||
@ -16,6 +16,9 @@ abstract class ApiEndpoints {
|
||||
|
||||
// Devices
|
||||
static const String control = '$baseUrl/device/control';
|
||||
static const String devicesByRoom = '$baseUrl/device/room';
|
||||
// static const String deviceStatus = '$baseUrl/device/status/';
|
||||
static const String deviceStatus = '$baseUrl/device/';
|
||||
|
||||
//groups
|
||||
static const String groups = '$baseUrl/group';
|
||||
|
||||
@ -8,6 +8,8 @@ class DevicesAPI {
|
||||
|
||||
static Future<Map<String, dynamic>> controlDevice(
|
||||
DeviceControlModel controlModel) async {
|
||||
// print(
|
||||
// 'contoling [${controlModel.deviceId}] with code [${controlModel.code}] and value [${controlModel.value}');
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.control,
|
||||
body: controlModel.toJson(),
|
||||
@ -34,4 +36,15 @@ class DevicesAPI {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: '${ApiEndpoints.deviceStatus}/$deviceId/functions/status',
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,9 +37,6 @@ class HTTPService {
|
||||
path,
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
|
||||
// debugPrint("status code is ${response.statusCode}");
|
||||
// debugPrint("response data is ${response.data}");
|
||||
return expectedResponseModel(response.data);
|
||||
} catch (error) {
|
||||
debugPrint("******* Error");
|
||||
|
||||
@ -28,8 +28,14 @@ class ServerFailure extends Failure {
|
||||
return ServerFailure("Bad certificate!");
|
||||
|
||||
case DioExceptionType.badResponse:
|
||||
return ServerFailure.fromResponse(dioError.response!.statusCode!,
|
||||
dioError.response!.data!["message"]);
|
||||
{
|
||||
// var document = parser.parse(dioError.response!.data.toString());
|
||||
// var message = document.body!.text;
|
||||
return ServerFailure.fromResponse(dioError.response!.statusCode!,
|
||||
dioError.response!.data['message'].toString()
|
||||
// message
|
||||
);
|
||||
}
|
||||
case DioExceptionType.cancel:
|
||||
return ServerFailure("The request to ApiServer was canceled");
|
||||
|
||||
@ -45,8 +51,15 @@ class ServerFailure extends Failure {
|
||||
}
|
||||
|
||||
factory ServerFailure.fromResponse(int statusCode, dynamic response) {
|
||||
if (statusCode == 400 || statusCode == 401 || statusCode == 403) {
|
||||
if (statusCode == 401 || statusCode == 403) {
|
||||
return ServerFailure(response);
|
||||
} else if (statusCode == 400) {
|
||||
//response is list of errors
|
||||
List<String> errors = [];
|
||||
response.forEach((element) {
|
||||
errors.add(element);
|
||||
});
|
||||
return ServerFailure(errors.join('\n'));
|
||||
} else if (statusCode == 404) {
|
||||
return ServerFailure("Your request not found, Please try later!");
|
||||
} else if (statusCode == 500) {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||
import 'package:syncrow_app/features/auth/model/user_model.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/services/api/api_links_endpoints.dart';
|
||||
import 'package:syncrow_app/services/api/http_service.dart';
|
||||
@ -23,7 +24,7 @@ class SpacesAPI {
|
||||
}
|
||||
|
||||
//get rooms by space id
|
||||
static Future<List<RoomModel>> getRooms(int spaceId) async {
|
||||
static Future<List<RoomModel>> getRoomsBySpaceId(int spaceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.rooms,
|
||||
queryParameters: {"homeId": spaceId},
|
||||
@ -38,4 +39,20 @@ class SpacesAPI {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<List<DeviceModel>> getDevicesByRoomId(int roomId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.devicesByRoom,
|
||||
queryParameters: {"roomId": roomId, "pageSize": 10},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
List<DeviceModel> devices = [];
|
||||
for (var device in json['devices']) {
|
||||
devices.add(DeviceModel.fromJson(device));
|
||||
}
|
||||
return devices;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ class MyBlocObserver extends BlocObserver {
|
||||
|
||||
@override
|
||||
void onClose(BlocBase bloc) {
|
||||
super.onClose(bloc);
|
||||
print('onClose -- ${bloc.runtimeType}');
|
||||
super.onClose(bloc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
//ignore_for_file: constant_identifier_names
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
abstract class Constants {
|
||||
static const String languageCode = "en";
|
||||
|
||||
@ -16,12 +19,182 @@ abstract class Constants {
|
||||
|
||||
enum DeviceType {
|
||||
AC,
|
||||
Lights,
|
||||
LightBulb,
|
||||
DoorLock,
|
||||
Curtain,
|
||||
Blind,
|
||||
ThreeGang,
|
||||
Gateway,
|
||||
Sensors,
|
||||
Gang,
|
||||
CeilingSensor,
|
||||
WallSensor,
|
||||
Other,
|
||||
}
|
||||
|
||||
// Map<String, DeviceType> devicesTypesMap = {
|
||||
// "AC": DeviceType.AC,
|
||||
// "LB": DeviceType.LightBulb,
|
||||
// "DL": DeviceType.DoorLock,
|
||||
// "WC": DeviceType.Curtain,
|
||||
// "WB": DeviceType.Blind,
|
||||
// "3G": DeviceType.ThreeGang,
|
||||
// "GW": DeviceType.Gateway,
|
||||
// "CPS": DeviceType.CeilingSensor,
|
||||
// "WPS": DeviceType.WallSensor,
|
||||
// "Other": DeviceType.Other,
|
||||
// };
|
||||
//AC wzdcrqh0
|
||||
// GW wp8ticoo2bhumwgb
|
||||
// CPS d3ci7gcn
|
||||
// DL awu7anehyu5q1iu8
|
||||
// WPS awarhusb
|
||||
// 3G 1a6vgvyi
|
||||
|
||||
Map<String, DeviceType> devicesTypesMap = {
|
||||
"wzdcrqh0": DeviceType.AC,
|
||||
"wp8ticoo2bhumwgb": DeviceType.Gateway,
|
||||
"d3ci7gcn": DeviceType.CeilingSensor,
|
||||
"awu7anehyu5q1iu8": DeviceType.DoorLock,
|
||||
"awarhusb": DeviceType.WallSensor,
|
||||
"1a6vgvyi": DeviceType.ThreeGang,
|
||||
};
|
||||
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
DeviceType.AC: [
|
||||
FunctionModel(code: 'switch', type: 'Boolean', values: '{}'),
|
||||
FunctionModel(
|
||||
code: 'mode', type: 'Enum', values: '{"range":["cold","hot","wind"]}'),
|
||||
FunctionModel(
|
||||
code: 'temp_set',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"℃","min":200,"max":300,"scale":1,"step":5}'),
|
||||
FunctionModel(
|
||||
code: 'level',
|
||||
type: 'Enum',
|
||||
values: '{"range":["low","middle","high","auto"]}'),
|
||||
FunctionModel(code: 'child_lock', type: 'Boolean', values: '{}'),
|
||||
],
|
||||
DeviceType.Gateway: [
|
||||
FunctionModel(code: 'switch_alarm_sound', type: 'Boolean', values: '{}'),
|
||||
FunctionModel(
|
||||
code: 'master_state',
|
||||
type: 'Enum',
|
||||
values: '{"range":["normal","alarm"]}'),
|
||||
FunctionModel(code: 'factory_reset', type: 'Boolean', values: '{}'),
|
||||
FunctionModel(
|
||||
code: 'alarm_active', type: 'String', values: '{"maxlen":255}'),
|
||||
],
|
||||
DeviceType.CeilingSensor: [
|
||||
FunctionModel(
|
||||
code: 'sensitivity',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"","min":1,"max":10,"scale":0,"step":1}'),
|
||||
],
|
||||
DeviceType.DoorLock: [
|
||||
FunctionModel(code: 'remote_no_pd_setkey', type: 'Raw', values: '{}'),
|
||||
FunctionModel(code: 'remote_no_dp_key', type: 'Raw', values: '{}'),
|
||||
FunctionModel(code: 'normal_open_switch', type: 'Boolean', values: '{}'),
|
||||
],
|
||||
DeviceType.WallSensor: [
|
||||
FunctionModel(
|
||||
code: 'far_detection',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"cm","min":75,"max":600,"scale":0,"step":75}'),
|
||||
FunctionModel(
|
||||
code: 'presence_time',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"Min","min":0,"max":65535,"scale":0,"step":1}'),
|
||||
FunctionModel(
|
||||
code: 'motion_sensitivity_value',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"","min":1,"max":5,"scale":0,"step":1}'),
|
||||
FunctionModel(
|
||||
code: 'motionless_sensitivity',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"","min":1,"max":5,"scale":0,"step":1}'),
|
||||
FunctionModel(code: 'indicator', type: 'Boolean', values: '{}'),
|
||||
],
|
||||
DeviceType.ThreeGang: [
|
||||
FunctionModel(code: 'switch_1', type: 'Boolean', values: '{}'),
|
||||
FunctionModel(code: 'switch_2', type: 'Boolean', values: '{}'),
|
||||
FunctionModel(code: 'switch_3', type: 'Boolean', values: '{}'),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"s","min":0,"max":43200,"scale":0,"step":1}'),
|
||||
FunctionModel(
|
||||
code: 'countdown_2',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"s","min":0,"max":43200,"scale":0,"step":1}'),
|
||||
FunctionModel(
|
||||
code: 'countdown_3',
|
||||
type: 'Integer',
|
||||
values: '{"unit":"s","min":0,"max":43200,"scale":0,"step":1}'),
|
||||
],
|
||||
};
|
||||
|
||||
enum TempModes { hot, cold, wind }
|
||||
|
||||
enum FanSpeeds { auto, low, middle, high }
|
||||
|
||||
final Map<FanSpeeds, String> fanSpeedsIconMap = {
|
||||
FanSpeeds.auto: Assets.iconsFan0,
|
||||
FanSpeeds.low: Assets.iconsFan1,
|
||||
FanSpeeds.middle: Assets.iconsFan2,
|
||||
FanSpeeds.high: Assets.iconsFan3,
|
||||
};
|
||||
|
||||
final Map<TempModes, String> tempModesIconMap = {
|
||||
TempModes.hot: Assets.iconsSunnyMode,
|
||||
TempModes.cold: Assets.iconsColdMode,
|
||||
TempModes.wind: Assets.iconsWindyMode,
|
||||
};
|
||||
|
||||
final Map<String, FanSpeeds> fanSpeedsMap = {
|
||||
'auto': FanSpeeds.auto,
|
||||
'low': FanSpeeds.low,
|
||||
'middle': FanSpeeds.middle,
|
||||
'high': FanSpeeds.high,
|
||||
};
|
||||
|
||||
final Map<String, TempModes> tempModesMap = {
|
||||
'hot': TempModes.hot,
|
||||
'cold': TempModes.cold,
|
||||
'wind': TempModes.wind,
|
||||
};
|
||||
|
||||
final Map<FanSpeeds, String> reversedFanSpeedsMap =
|
||||
fanSpeedsMap.map((key, value) => MapEntry(value, key));
|
||||
|
||||
final Map<TempModes, String> reversedTempModesMap =
|
||||
tempModesMap.map((key, value) => MapEntry(value, key));
|
||||
|
||||
String getNextFanSpeedKey(FanSpeeds currentFanSpeed) {
|
||||
const List<FanSpeeds> speeds = FanSpeeds.values;
|
||||
final int currentIndex = speeds.indexOf(currentFanSpeed);
|
||||
|
||||
// Return null if currentFanSpeed is the last value
|
||||
if (currentIndex == speeds.length - 1) {
|
||||
return reversedFanSpeedsMap[FanSpeeds.auto]!;
|
||||
}
|
||||
|
||||
final FanSpeeds nextSpeed = speeds[currentIndex + 1];
|
||||
return reversedFanSpeedsMap[nextSpeed]!;
|
||||
}
|
||||
|
||||
K? getNextItem<K, V>(Map<K, V> map, V value) {
|
||||
// Iterate over the map entries
|
||||
for (var entry in map.entries) {
|
||||
// If the current value matches the provided value
|
||||
if (entry.value == value) {
|
||||
// Get the index of the current entry
|
||||
final index = map.keys.toList().indexOf(entry.key);
|
||||
// If the index is not the last item, return the next item
|
||||
if (index < map.length - 1) {
|
||||
return map.keys.elementAt(index + 1);
|
||||
}
|
||||
// If it's the last item, return null
|
||||
return map.keys.elementAt(0);
|
||||
}
|
||||
}
|
||||
// If the value is not found, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
16
pubspec.lock
16
pubspec.lock
@ -97,6 +97,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -357,6 +365,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.6.7"
|
||||
html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: html
|
||||
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.4"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -36,6 +36,7 @@ dependencies:
|
||||
firebase_analytics: ^10.8.7
|
||||
firebase_crashlytics: ^3.4.16
|
||||
smooth_page_indicator: ^1.1.0
|
||||
html: ^0.15.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user