Refactor device control logic and add temperature and fan speed enums

- Refactor device control logic in the app to improve readability and maintainability.
- Add temperature modes (hot, cold, wind) and fan speeds (auto, low, middle, high) enums.
- Update icon mappings and utility functions for temperature modes and fan speeds.
This commit is contained in:
Mohammad Salameh
2024-04-03 18:54:21 +03:00
parent 6577652702
commit bff4b9493c
30 changed files with 183 additions and 107 deletions

View File

@ -18,8 +18,6 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
part 'home_state.dart';
class HomeCubit extends Cubit<HomeState> {
// Create a private static instance variable
HomeCubit._() : super(HomeInitial()) {
if (selectedSpace == null) {
fetchSpaces().then((value) {
@ -37,6 +35,13 @@ class HomeCubit extends Cubit<HomeState> {
return _instance!;
}
void emitSafe(HomeState newState) {
final cubit = this;
if (!cubit.isClosed) {
cubit.emit(newState);
}
}
static HomeCubit get(context) => BlocProvider.of(context);
List<SpaceModel>? spaces;
@ -58,7 +63,7 @@ class HomeCubit extends Cubit<HomeState> {
changeSelectedSpace(SpaceModel space) {
selectedSpace = space;
emit(SpaceSelected(space));
emitSafe(SpaceSelected(space));
}
roomSliderPageChanged(int index) {
@ -72,7 +77,7 @@ class HomeCubit extends Cubit<HomeState> {
unselectRoom();
} else {
selectedRoom = selectedSpace!.rooms![index - 1];
emit(RoomSelected(selectedRoom!));
emitSafe(RoomSelected(selectedRoom!));
}
}
@ -87,7 +92,7 @@ class HomeCubit extends Cubit<HomeState> {
unselectRoom();
} else {
selectedRoom = selectedSpace!.rooms![index - 1];
emit(RoomSelected(selectedRoom!));
emitSafe(RoomSelected(selectedRoom!));
}
}
@ -105,11 +110,11 @@ class HomeCubit extends Cubit<HomeState> {
curve: Curves.linear,
);
emit(RoomUnSelected());
emitSafe(RoomUnSelected());
}
fetchSpaces() async {
emit(GetSpacesLoading());
emitSafe(GetSpacesLoading());
try {
spaces = await SpacesAPI.getSpaces();
selectedSpace = spaces!.isNotEmpty
@ -117,23 +122,23 @@ class HomeCubit extends Cubit<HomeState> {
// selectSpace(spaces!.first)
selectedSpace = spaces!.first
: null;
emit(GetSpacesLoaded(spaces!));
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.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));
}
}
@ -262,7 +267,7 @@ class HomeCubit extends Cubit<HomeState> {
const DashboardView(),
// const LayoutPage(),
BlocProvider(
create: (context) => DevicesCubit(),
create: (context) => DevicesCubit.getInstance(),
child: const DevicesViewBody(),
),
const SceneView(),
@ -272,7 +277,7 @@ class HomeCubit extends Cubit<HomeState> {
void updatePageIndex(int index) {
pageIndex = index;
emit(NavChangePage());
emitSafe(NavChangePage());
}
}

View File

@ -14,7 +14,7 @@ class DefaultNavBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => DevicesCubit(),
create: (context) => DevicesCubit.getInstance(),
child: BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return BlocBuilder<HomeCubit, HomeState>(
@ -26,8 +26,8 @@ class DefaultNavBar extends StatelessWidget {
backgroundColor: Colors.transparent,
onTap: (int index) {
cubit.updatePageIndex(index);
if (DevicesCubit.get(context).chosenCategoryView != null) {
DevicesCubit.get(context)
if (DevicesCubit.getInstance().chosenCategoryView != null) {
DevicesCubit.getInstance()
.clearCategoriesSelection(context);
}
if (HomeCubit.getInstance().selectedRoom != null) {

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/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';
@ -16,9 +18,11 @@ class AcInterfaceControls extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return Column(
children: [
ACModeControlUnit(model: deviceModel),
ACModeControlUnit(acDevice: deviceModel),
const SizedBox(height: 10),
Row(
children: [
@ -49,5 +53,7 @@ class AcInterfaceControls extends StatelessWidget {
)
],
);
},
);
}
}

View File

@ -82,7 +82,7 @@ class AcInterfaceTempUnit extends StatelessWidget {
if (valueAsString.endsWith(".0") ||
valueAsString.endsWith(".5")) {
value = double.parse(valueAsString);
// DevicesCubit.get(context)
// DevicesCubit.getInstance()
// .setACTemp(DeviceModel, value);
}
},
@ -98,7 +98,7 @@ class AcInterfaceTempUnit extends StatelessWidget {
dimension: 24,
child: InkWell(
onTap: () {
// DevicesCubit.get(context)
// DevicesCubit.getInstance()
// .setACTemp(DeviceModel, DeviceModel.coolTo);
// DeviceModel.coolTo -= .5;
},
@ -130,7 +130,7 @@ class AcInterfaceTempUnit extends StatelessWidget {
dimension: 24,
child: InkWell(
onTap: () {
// DevicesCubit.get(context)
// DevicesCubit.getInstance()
// .setACTemp(DeviceModel, DeviceModel.coolTo);
// DeviceModel.coolTo += .5;
},

View File

@ -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(

View File

@ -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,10 +39,11 @@ 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).chosenCategory!.devices![index];
DeviceModel ac = DevicesCubit.getInstance()
.chosenCategory!
.devices![index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -51,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,
@ -83,7 +84,7 @@ class ACsList extends StatelessWidget {
),
const SizedBox(height: 10),
ACModeControlUnit(
model: ac,
acDevice: ac,
),
const SizedBox(height: 10),
],

View File

@ -21,9 +21,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(

View File

@ -20,7 +20,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 +32,7 @@ class CategoryViewAppBar extends StatelessWidget
color: ColorsManager.textPrimaryColor,
),
onPressed: () {
DevicesCubit.get(context).clearCategoriesSelection(context);
DevicesCubit.getInstance().clearCategoriesSelection(context);
},
),
);

View File

@ -27,7 +27,7 @@ class UniversalACTemp extends StatelessWidget {
dimension: 24,
child: InkWell(
onTap: () {
// DevicesCubit.get(context)
// DevicesCubit.getInstance()
// .setTempToAll(DevicesCubit.universalACTemp - .5);
},
child: SvgPicture.asset(
@ -47,7 +47,7 @@ class UniversalACTemp extends StatelessWidget {
dimension: 24,
child: InkWell(
onTap: () {
// DevicesCubit.get(context)
// DevicesCubit.getInstance()
// .setTempToAll(DevicesCubit.universalACTemp + .5);
},
child: SvgPicture.asset(

View File

@ -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 ??

View File

@ -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(

View File

@ -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(

View File

@ -34,7 +34,7 @@ class LightInterfaceRecentColor extends StatelessWidget {
4,
(index) => InkWell(
// onTap: () {
// DevicesCubit.get(context)
// DevicesCubit.getInstance()
// .setColor(light, light.recentColors[index]);
// },
child: Container(

View File

@ -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,

View File

@ -51,7 +51,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,

View File

@ -32,7 +32,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,

View File

@ -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) {

View File

@ -28,7 +28,7 @@ class RoomPage extends StatelessWidget {
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: room.devices!.length,
itemBuilder: (_, index) {
itemBuilder: (context, index) {
return RoomPageSwitch(device: room.devices![index]);
},
);

View File

@ -33,7 +33,7 @@ class RoomPageSwitch extends StatelessWidget {
context,
CustomPageRoute(
builder: (context) => BlocProvider(
create: (context) => DevicesCubit(),
create: (context) => DevicesCubit.getInstance(),
child: AcInterface(deviceModel: device),
),
),
@ -57,7 +57,7 @@ class RoomPageSwitch extends StatelessWidget {
context,
CustomPageRoute(
builder: (context) => BlocProvider(
create: (context) => DevicesCubit(),
create: (context) => DevicesCubit.getInstance(),
child: LightInterface(light: device),
),
),
@ -67,7 +67,7 @@ class RoomPageSwitch extends StatelessWidget {
context,
CustomPageRoute(
builder: (context) => BlocProvider(
create: (context) => DevicesCubit(),
create: (context) => DevicesCubit.getInstance(),
child: ThreeGangInterface(
gangSwitch: device,
),

View File

@ -23,16 +23,16 @@ class GangSwitch extends StatelessWidget {
: 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;
}
});
// DevicesCubit.getInstance()
// .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!

View File

@ -1,10 +1,7 @@
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/view/widgets/ACs/category_view_app_bar.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';

View File

@ -25,7 +25,7 @@ class UniversalSwitch extends StatelessWidget {
Expanded(
child: InkWell(
onTap: () {
DevicesCubit.get(context).turnAllDevicesOn(category);
DevicesCubit.getInstance().turnAllDevicesOn(category);
},
child: Container(
height: 60,
@ -57,7 +57,7 @@ class UniversalSwitch extends StatelessWidget {
Expanded(
child: InkWell(
onTap: () {
DevicesCubit.get(context).turnAllDevicesOff(category);
DevicesCubit.getInstance().turnAllDevicesOff(category);
},
child: Container(
height: 60,

View File

@ -34,12 +34,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!;
}));
},

View File

@ -26,9 +26,9 @@ class CustomSwitch extends StatelessWidget {
return GestureDetector(
onTap: () {
if (device != null) {
DevicesCubit.get(context).turnOnOffDevice(device!);
DevicesCubit.getInstance().turnOnOffDevice(device!);
} else if (category != null) {
DevicesCubit.get(context).changeCategorySwitchValue(category!);
DevicesCubit.getInstance().changeCategorySwitchValue(category!);
}
},
child: Container(

View File

@ -23,7 +23,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
Expanded(
child: InkWell(
onTap: () {
DevicesCubit.get(context).turnOnOffDevice(model);
DevicesCubit.getInstance().turnOnOffDevice(model);
},
child: Container(
height: 60,
@ -49,7 +49,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
Expanded(
child: InkWell(
onTap: () {
DevicesCubit.get(context).turnOnOffDevice(model);
DevicesCubit.getInstance().turnOnOffDevice(model);
},
child: Container(
height: 60,

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/theme_manager.dart';

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/view/app_layout.dart';
import 'package:syncrow_app/features/auth/view/widgets/didnt_get_code/didnt_get_code_view.dart';
import 'package:syncrow_app/features/auth/view/widgets/login/login_view.dart';
@ -8,8 +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/bloc/devices_cubit.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';

View File

@ -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(),

View File

@ -1,5 +1,4 @@
import 'package:dio/dio.dart';
import 'package:html/parser.dart' as parser;
abstract class Failure {
final String errMessage;

View File

@ -1,5 +1,6 @@
//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";
@ -129,3 +130,71 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
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;
}