mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-08-26 05:49:40 +00:00
260 lines
8.6 KiB
Dart
260 lines
8.6 KiB
Dart
import 'dart:async';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_event.dart';
|
|
import 'package:syncrow_app/features/devices/bloc/sos_bloc/sos_state.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/device_report_model.dart';
|
|
import 'package:syncrow_app/features/devices/model/question_model.dart';
|
|
import 'package:syncrow_app/features/devices/model/sos_model.dart';
|
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
|
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
|
import 'package:syncrow_app/services/api/spaces_api.dart';
|
|
|
|
class SosBloc extends Bloc<SosEvent, SosState> {
|
|
final String sosId;
|
|
SosBloc({
|
|
required this.sosId,
|
|
}) : super(const SosState()) {
|
|
on<SosInitial>(_fetchStatus);
|
|
on<ReportLogsInitial>(fetchLogsForLastMonth);
|
|
on<ToggleEnableAlarmEvent>(_toggleLowBattery);
|
|
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
|
on<ChangeNameEvent>(_changeName);
|
|
on<SearchFaqEvent>(_onSearchFaq);
|
|
on<SosInitialQuestion>(_onSosInitial);
|
|
on<FetchRoomsEvent>(_fetchRoomsAndDevices);
|
|
on<SelectOptionEvent>(_onOptionSelected);
|
|
on<SaveSelectionEvent>(_onSaveSelection);
|
|
// on<ToggleWaterLeakAlarmEvent>(_toggleWaterLeakAlarm);
|
|
}
|
|
|
|
final TextEditingController nameController =
|
|
TextEditingController(text: '${'firstName'}');
|
|
bool isSaving = false;
|
|
bool editName = false;
|
|
final FocusNode focusNode = FocusNode();
|
|
Timer? _timer;
|
|
bool enableAlarm = false;
|
|
bool closingReminder = false;
|
|
bool waterAlarm = false;
|
|
SosModel deviceStatus =
|
|
SosModel(sosContactState: 'normal', batteryPercentage: 0);
|
|
|
|
void _fetchStatus(SosInitial event, Emitter<SosState> emit) async {
|
|
emit(SosLoadingState());
|
|
try {
|
|
var response = await DevicesAPI.getDeviceStatus(sosId);
|
|
List<StatusModel> statusModelList = [];
|
|
for (var status in response['status']) {
|
|
statusModelList.add(StatusModel.fromJson(status));
|
|
}
|
|
deviceStatus = SosModel.fromJson(
|
|
statusModelList,
|
|
);
|
|
emit(UpdateState(sensor: deviceStatus));
|
|
|
|
Future.delayed(const Duration(milliseconds: 500));
|
|
// _listenToChanges();
|
|
} catch (e) {
|
|
emit(SosFailedState(errorMessage: e.toString()));
|
|
return;
|
|
}
|
|
}
|
|
|
|
void _onSearchFaq(SearchFaqEvent event, Emitter<SosState> emit) {
|
|
emit(SosLoadingState());
|
|
List<QuestionModel> _faqQuestions = faqQuestions.where((question) {
|
|
return question.question
|
|
.toLowerCase()
|
|
.contains(event.query.toLowerCase());
|
|
}).toList();
|
|
emit(FaqSearchState(filteredFaqQuestions: _faqQuestions));
|
|
}
|
|
|
|
void _changeName(ChangeNameEvent event, Emitter<SosState> emit) {
|
|
emit(SosLoadingState());
|
|
editName = event.value!;
|
|
if (editName) {
|
|
Future.delayed(const Duration(milliseconds: 500), () {
|
|
focusNode.requestFocus();
|
|
});
|
|
} else {
|
|
focusNode.unfocus();
|
|
}
|
|
emit(NameEditingState(editName: editName));
|
|
}
|
|
|
|
void _toggleLowBattery(
|
|
ToggleEnableAlarmEvent event, Emitter<SosState> emit) async {
|
|
emit(LoadingNewSate(sosSensor: deviceStatus));
|
|
try {
|
|
enableAlarm = event.isLowBatteryEnabled;
|
|
emit(UpdateState(sensor: deviceStatus));
|
|
await DevicesAPI.controlDevice(
|
|
DeviceControlModel(
|
|
deviceId: sosId,
|
|
code: 'low_battery',
|
|
value: enableAlarm,
|
|
),
|
|
sosId,
|
|
);
|
|
} catch (e) {
|
|
emit(SosFailedState(errorMessage: e.toString()));
|
|
}
|
|
}
|
|
|
|
void _toggleClosingReminder(
|
|
ToggleClosingReminderEvent event, Emitter<SosState> emit) async {
|
|
emit(LoadingNewSate(sosSensor: deviceStatus));
|
|
try {
|
|
closingReminder = event.isClosingReminderEnabled;
|
|
emit(UpdateState(sensor: deviceStatus));
|
|
|
|
// API call to update the state, if necessary
|
|
// await DevicesAPI.controlDevice(
|
|
// DeviceControlModel(
|
|
// deviceId: sosId,
|
|
// code: 'closing_reminder',
|
|
// value: closingReminder,
|
|
// ),
|
|
// sosId,
|
|
// );
|
|
} catch (e) {
|
|
emit(SosFailedState(errorMessage: e.toString()));
|
|
}
|
|
}
|
|
|
|
DeviceReport recordGroups =
|
|
DeviceReport(startTime: '0', endTime: '0', data: []);
|
|
|
|
Future<void> fetchLogsForLastMonth(
|
|
ReportLogsInitial event, Emitter<SosState> emit) async {
|
|
DateTime now = DateTime.now();
|
|
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
|
|
int startTime = lastMonth.millisecondsSinceEpoch;
|
|
int endTime = now.millisecondsSinceEpoch;
|
|
try {
|
|
emit(SosLoadingState());
|
|
var response = await DevicesAPI.getReportLogs(
|
|
startTime: startTime.toString(),
|
|
endTime: endTime.toString(),
|
|
deviceUuid: sosId,
|
|
code: 'sossensor_state',
|
|
);
|
|
recordGroups = response;
|
|
emit(UpdateState(sensor: deviceStatus));
|
|
} on DioException catch (e) {
|
|
final errorData = e.response!.data;
|
|
String errorMessage = errorData['message'];
|
|
emit(SosFailedState(errorMessage: e.toString()));
|
|
}
|
|
}
|
|
|
|
// _listenToChanges() {
|
|
// try {
|
|
// DatabaseReference ref =
|
|
// FirebaseDatabase.instance.ref('device-status/$WLId');
|
|
// Stream<DatabaseEvent> stream = ref.onValue;
|
|
|
|
// stream.listen((DatabaseEvent event) async {
|
|
// if (_timer != null) {
|
|
// await Future.delayed(const Duration(seconds: 2));
|
|
// }
|
|
// Map<dynamic, dynamic> usersMap =
|
|
// event.snapshot.value as Map<dynamic, dynamic>;
|
|
// List<StatusModel> statusList = [];
|
|
|
|
// usersMap['status'].forEach((element) {
|
|
// statusList.add(StatusModel(code: element['code'], value: true));
|
|
// });
|
|
|
|
// deviceStatus = WaterLeakModel.fromJson(statusList);
|
|
// if (!isClosed) {
|
|
// add(
|
|
// WaterLeakSwitch(switchD: deviceStatus.waterContactState),
|
|
// );
|
|
// }
|
|
// });
|
|
// } catch (_) {}
|
|
// }
|
|
|
|
// Demo list of FAQ questions using the QuestionModel class
|
|
final List<QuestionModel> faqQuestions = [
|
|
QuestionModel(
|
|
id: 1,
|
|
question: 'How does an SOS emergency button work?',
|
|
answer:
|
|
'The SOS emergency button sends an alert to your contacts when pressed.',
|
|
),
|
|
QuestionModel(
|
|
id: 2,
|
|
question: 'How long will an SOS alarm persist?',
|
|
answer:
|
|
'The SOS alarm will persist until it is manually turned off or after a set time.',
|
|
),
|
|
QuestionModel(
|
|
id: 3,
|
|
question: 'What should I do if the SOS button is unresponsive?',
|
|
answer: 'Try restarting the device. If it persists, contact support.',
|
|
),
|
|
QuestionModel(
|
|
id: 4,
|
|
question: 'Can I use the SOS feature without a network connection?',
|
|
answer:
|
|
'No, a network connection is required to send the alert to your contacts.',
|
|
),
|
|
QuestionModel(
|
|
id: 5,
|
|
question: 'How often should I check the SOS battery?',
|
|
answer:
|
|
'Check the SOS battery at least once a month to ensure it is operational.',
|
|
),
|
|
];
|
|
Future<void> _onSosInitial(
|
|
SosInitialQuestion event, Emitter<SosState> emit) async {
|
|
emit(SosLoadingState());
|
|
// SosModel sosModel = await fetchSosData(sosId); // Define this function as needed
|
|
emit(FaqLoadedState(filteredFaqQuestions: faqQuestions));
|
|
}
|
|
|
|
List<DeviceModel> allDevices = [];
|
|
List<SubSpaceModel> roomsList = [];
|
|
|
|
void _fetchRoomsAndDevices(
|
|
FetchRoomsEvent event, Emitter<SosState> emit) async {
|
|
try {
|
|
emit(SosLoadingState());
|
|
roomsList = await SpacesAPI.getSubSpaceBySpaceId(
|
|
event.unit.community.uuid, event.unit.id);
|
|
emit(FetchRoomsState(devicesList: allDevices, roomsList: roomsList));
|
|
} catch (e) {
|
|
emit(const SosFailedState(errorMessage: 'Something went wrong'));
|
|
return;
|
|
}
|
|
}
|
|
|
|
String _selectedOption = '';
|
|
bool _hasSelectionChanged = false;
|
|
|
|
void _onOptionSelected(SelectOptionEvent event, Emitter<SosState> emit) {
|
|
emit(SosLoadingState());
|
|
_selectedOption = event.selectedOption;
|
|
_hasSelectionChanged = true;
|
|
emit(OptionSelectedState(
|
|
selectedOption: _selectedOption,
|
|
hasSelectionChanged: _hasSelectionChanged));
|
|
}
|
|
|
|
void _onSaveSelection(SaveSelectionEvent event, Emitter<SosState> emit) {
|
|
if (_hasSelectionChanged) {
|
|
print('Save button clicked with selected option: $_selectedOption');
|
|
_hasSelectionChanged = false;
|
|
emit(SaveSelectionSuccessState());
|
|
}
|
|
}
|
|
}
|