Files
syncrow-app/lib/features/app_layout/bloc/home_cubit.dart
Mohammad Salameh df13c66b1a Refactor API error handling and add try-catch blocks
Added try-catch blocks for error handling in API's files to rethrow the errors to the cubit so cubits can update the UI based on them.

Refactored error handling in HTTPInterceptor and HTTPService classes.
2024-04-15 15:47:13 +03:00

298 lines
7.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/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';
import 'package:syncrow_app/features/scene/view/scene_view.dart';
import 'package:syncrow_app/generated/assets.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/color_manager.dart';
part 'home_state.dart';
class HomeCubit extends Cubit<HomeState> {
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);
}
}
@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 ////////////////////////////////////////
fetchSpaces() async {
emitSafe(GetSpacesLoading());
try {
spaces = await SpacesAPI.getSpaces();
} catch (failure) {
emitSafe(GetSpacesError(failure.toString()));
return;
}
if (spaces != null && spaces!.isNotEmpty) {
selectedSpace = spaces!.first;
emitSafe(GetSpacesSuccess(spaces!));
fetchRooms(selectedSpace!);
} else {
emitSafe(GetSpacesError("No spaces found"));
}
}
fetchRooms(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: () {},
),
],
'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.iconsFilter,
// height: 20,
// width: 20,
// ),
// onPressed: () {},
// ),
IconButton(
icon: const Icon(
Icons.add,
size: 25,
),
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.more_vert,
size: 25,
),
style: ButtonStyle(
foregroundColor:
MaterialStateProperty.all(ColorsManager.textPrimaryColor),
),
onPressed: () {},
),
],
'Menu': [
IconButton(
icon: SvgPicture.asset(
Assets.iconsScan,
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.imagesLogoHorizontal,
height: 15,
width: 100,
fit: BoxFit.scaleDown,
),
),
};
static var bottomNavItems = [
defaultBottomNavBarItem(icon: Assets.iconsDashboard, label: 'Dashboard'),
// defaultBottomNavBarItem(icon: Assets.iconslayout, label: 'Layout'),
defaultBottomNavBarItem(icon: Assets.iconsDevices, label: 'Devices'),
defaultBottomNavBarItem(icon: Assets.iconsRoutines, label: 'Routine'),
defaultBottomNavBarItem(icon: Assets.iconsMenu, 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,
);
}