mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 17:47:28 +00:00

changed the method of generating assets to be more declrative when it comes to names of the assets. it now include the file path name e.g (asset in the path "assets/images/home-images/home.png" will be generated as this "String assetsImagesHomeImageshome = "path" ". this will be very helpful in the future when we want to orgnize the assets dir.
318 lines
8.5 KiB
Dart
318 lines
8.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:syncrow_app/features/app_layout/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/device_model.dart';
|
|
import 'package:syncrow_app/features/devices/model/room_model.dart';
|
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
|
import 'package:syncrow_app/features/devices/view/widgets/curtains/blind_view.dart';
|
|
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
|
|
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
|
import 'package:syncrow_app/features/menu/view/menu_view.dart';
|
|
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
|
import 'package:syncrow_app/generated/assets.dart';
|
|
import 'package:syncrow_app/navigation/navigation_service.dart';
|
|
import 'package:syncrow_app/services/api/spaces_api.dart';
|
|
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
|
|
|
part 'home_state.dart';
|
|
|
|
class HomeCubit extends Cubit<HomeState> {
|
|
HomeCubit._() : super(HomeInitial()) {
|
|
if (selectedSpace == null) {
|
|
fetchUnitsByUserId().then((value) {
|
|
if (selectedSpace != null) {
|
|
fetchRoomsByUnitId(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);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> close() {
|
|
_instance = null;
|
|
selectedSpace = null;
|
|
selectedRoom = null;
|
|
return super.close();
|
|
}
|
|
|
|
static HomeCubit get(context) => BlocProvider.of(context);
|
|
|
|
List<SpaceModel>? spaces;
|
|
|
|
SpaceModel? selectedSpace;
|
|
|
|
RoomModel? selectedRoom;
|
|
|
|
PageController devicesPageController = PageController();
|
|
|
|
PageController roomsPageController = PageController();
|
|
|
|
var duration = const Duration(milliseconds: 300);
|
|
|
|
// selectSpace(SpaceModel space) async {
|
|
// selectedSpace = space;
|
|
// emit(SpaceSelected(space));
|
|
// }
|
|
|
|
changeSelectedSpace(SpaceModel space) {
|
|
selectedSpace = space;
|
|
emitSafe(SpaceSelected(space));
|
|
}
|
|
|
|
roomSliderPageChanged(int index) {
|
|
devicesPageController.animateToPage(
|
|
index,
|
|
duration: duration,
|
|
curve: Curves.linear,
|
|
);
|
|
|
|
if (index == 0) {
|
|
unselectRoom();
|
|
} else {
|
|
selectedRoom = selectedSpace!.rooms![index - 1];
|
|
emitSafe(RoomSelected(selectedRoom!));
|
|
}
|
|
}
|
|
|
|
devicesPageChanged(int index) {
|
|
roomsPageController.animateToPage(
|
|
index,
|
|
duration: const Duration(milliseconds: 300),
|
|
curve: Curves.linear,
|
|
);
|
|
|
|
if (index <= 0) {
|
|
unselectRoom();
|
|
} else {
|
|
selectedRoom = selectedSpace!.rooms![index - 1];
|
|
emitSafe(RoomSelected(selectedRoom!));
|
|
}
|
|
}
|
|
|
|
unselectRoom() {
|
|
// selectedRoom = null;
|
|
devicesPageController.animateToPage(
|
|
0,
|
|
duration: duration,
|
|
curve: Curves.linear,
|
|
);
|
|
|
|
roomsPageController.animateToPage(
|
|
0,
|
|
duration: duration,
|
|
curve: Curves.linear,
|
|
);
|
|
|
|
emitSafe(RoomUnSelected());
|
|
}
|
|
|
|
//////////////////////////////////////// API ////////////////////////////////////////
|
|
fetchUnitsByUserId() async {
|
|
emitSafe(GetSpacesLoading());
|
|
try {
|
|
spaces = await SpacesAPI.getUnitsByUserId();
|
|
} catch (failure) {
|
|
emitSafe(GetSpacesError(failure.toString()));
|
|
return;
|
|
}
|
|
|
|
if (spaces != null && spaces!.isNotEmpty) {
|
|
selectedSpace = spaces!.first;
|
|
emitSafe(GetSpacesSuccess(spaces!));
|
|
// fetchRoomsByUnitId(selectedSpace!);
|
|
} else {
|
|
emitSafe(GetSpacesError("No spaces found"));
|
|
}
|
|
}
|
|
|
|
fetchRoomsByUnitId(SpaceModel space) async {
|
|
emitSafe(GetSpaceRoomsLoading());
|
|
try {
|
|
space.rooms = await SpacesAPI.getRoomsBySpaceId(space.id!);
|
|
} catch (failure) {
|
|
emitSafe(GetSpaceRoomsError(failure.toString()));
|
|
return;
|
|
}
|
|
if (space.rooms != null) {
|
|
emitSafe(GetSpaceRoomsSuccess(space.rooms!));
|
|
} else {
|
|
emitSafe(GetSpaceRoomsError("No rooms found"));
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////// Nav ///////////////////////////////////////
|
|
|
|
static int pageIndex = 0;
|
|
|
|
static Map<String, List<Widget>> appBarActions = {
|
|
'Dashboard': [
|
|
IconButton(
|
|
icon: const Icon(
|
|
Icons.add,
|
|
size: 25,
|
|
),
|
|
style: ButtonStyle(
|
|
foregroundColor:
|
|
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
|
|
),
|
|
onPressed: () {
|
|
Navigator.push(
|
|
NavigationService.navigatorKey.currentContext!,
|
|
CustomPageRoute(
|
|
builder: (context) => CurtainView(
|
|
curtain: DeviceModel(
|
|
name: "Curtain",
|
|
status: [StatusModel(code: "awd", value: 1)],
|
|
productType: DeviceType.Curtain,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
'Devices': [
|
|
IconButton(
|
|
icon: const Icon(
|
|
Icons.add,
|
|
size: 25,
|
|
),
|
|
style: ButtonStyle(
|
|
foregroundColor:
|
|
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
|
|
),
|
|
onPressed: () {},
|
|
),
|
|
IconButton(
|
|
icon: const Icon(
|
|
Icons.more_vert,
|
|
size: 25,
|
|
),
|
|
style: ButtonStyle(
|
|
foregroundColor:
|
|
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
|
|
),
|
|
onPressed: () {},
|
|
),
|
|
],
|
|
'Routine': [
|
|
// IconButton(
|
|
// icon: Image.asset(
|
|
// Assets.assetsIconsFilter,
|
|
// height: 20,
|
|
// width: 20,
|
|
// ),
|
|
// onPressed: () {},
|
|
// ),
|
|
IconButton(
|
|
icon: const Icon(
|
|
Icons.add,
|
|
size: 25,
|
|
),
|
|
style: ButtonStyle(
|
|
foregroundColor:
|
|
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
|
|
),
|
|
onPressed: () {},
|
|
),
|
|
IconButton(
|
|
icon: const Icon(
|
|
Icons.more_vert,
|
|
size: 25,
|
|
),
|
|
style: ButtonStyle(
|
|
foregroundColor:
|
|
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
|
|
),
|
|
onPressed: () {},
|
|
),
|
|
],
|
|
'Menu': [
|
|
IconButton(
|
|
icon: SvgPicture.asset(
|
|
Assets.assetsIconsScan,
|
|
height: 20,
|
|
width: 20,
|
|
),
|
|
onPressed: () {},
|
|
),
|
|
],
|
|
};
|
|
|
|
static Map<String, Widget?> appBarLeading = {
|
|
'Dashboard': const AppBarHomeDropdown(),
|
|
'Devices': const AppBarHomeDropdown(),
|
|
'Routine': const AppBarHomeDropdown(),
|
|
'Menu': Padding(
|
|
padding: const EdgeInsets.only(left: 15),
|
|
child: Image.asset(
|
|
Assets.assetsImagesLogoHorizontal,
|
|
height: 15,
|
|
width: 100,
|
|
fit: BoxFit.scaleDown,
|
|
),
|
|
),
|
|
};
|
|
|
|
static var bottomNavItems = [
|
|
defaultBottomNavBarItem(
|
|
icon: Assets.assetsIconsDashboard, label: 'Dashboard'),
|
|
// defaultBottomNavBarItem(icon: Assets.assetsIconslayout, label: 'Layout'),
|
|
defaultBottomNavBarItem(icon: Assets.assetsIconsDevices, label: 'Devices'),
|
|
defaultBottomNavBarItem(icon: Assets.assetsIconsRoutines, label: 'Routine'),
|
|
defaultBottomNavBarItem(icon: Assets.assetsIconsMenu, label: 'Menu'),
|
|
];
|
|
|
|
final List<Widget> pages = [
|
|
const DashboardView(),
|
|
// const LayoutPage(),
|
|
BlocProvider(
|
|
create: (context) => DevicesCubit.getInstance(),
|
|
child: const DevicesViewBody(),
|
|
),
|
|
const SceneView(),
|
|
const MenuView(),
|
|
];
|
|
|
|
void updatePageIndex(int index) {
|
|
pageIndex = index;
|
|
|
|
emitSafe(NavChangePage());
|
|
}
|
|
}
|
|
|
|
BottomNavigationBarItem defaultBottomNavBarItem(
|
|
{required String icon, required String label}) {
|
|
return BottomNavigationBarItem(
|
|
icon: SvgPicture.asset(icon),
|
|
activeIcon: SvgPicture.asset(
|
|
icon.replaceAll('.svg', '-fill.svg'),
|
|
colorFilter: const ColorFilter.mode(
|
|
ColorsManager.primaryColor,
|
|
BlendMode.srcIn,
|
|
),
|
|
),
|
|
label: label,
|
|
);
|
|
}
|