Update
Logging data Try-catch function
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:showWhenLocked="true"
|
android:showWhenLocked="true"
|
||||||
android:turnScreenOn="true"
|
android:turnScreenOn="true"
|
||||||
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
the Android process has started. This theme is visible to the user
|
the Android process has started. This theme is visible to the user
|
||||||
|
|||||||
3
devtools_options.yaml
Normal file
3
devtools_options.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
description: This file stores settings for Dart & Flutter DevTools.
|
||||||
|
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||||
|
extensions:
|
||||||
@@ -4,7 +4,6 @@ import '../product/base/bloc/base_bloc.dart';
|
|||||||
import '../feature/bell/bell_model.dart';
|
import '../feature/bell/bell_model.dart';
|
||||||
|
|
||||||
class BellBloc extends BlocBase {
|
class BellBloc extends BlocBase {
|
||||||
|
|
||||||
final bellItems = StreamController<List<BellItems>>.broadcast();
|
final bellItems = StreamController<List<BellItems>>.broadcast();
|
||||||
StreamSink<List<BellItems>> get sinkBellItems => bellItems.sink;
|
StreamSink<List<BellItems>> get sinkBellItems => bellItems.sink;
|
||||||
Stream<List<BellItems>> get streamBellItems => bellItems.stream;
|
Stream<List<BellItems>> get streamBellItems => bellItems.stream;
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:sfm_app/product/services/api_services.dart';
|
|
||||||
import 'package:sfm_app/product/utils/device_utils.dart';
|
|
||||||
|
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
import '../product/services/api_services.dart';
|
||||||
import '../product/utils/date_time_utils.dart';
|
import '../product/utils/date_time_utils.dart';
|
||||||
import '../feature/device_log/device_logs_model.dart';
|
import '../feature/device_log/device_logs_model.dart';
|
||||||
import '../feature/devices/device_model.dart';
|
import '../feature/devices/device_model.dart';
|
||||||
|
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
|
import '../product/utils/device_utils.dart';
|
||||||
|
|
||||||
class DetailDeviceBloc extends BlocBase {
|
class DetailDeviceBloc extends BlocBase {
|
||||||
APIServices apiServices = APIServices();
|
APIServices apiServices = APIServices();
|
||||||
@@ -43,7 +40,7 @@ class DetailDeviceBloc extends BlocBase {
|
|||||||
String thingID,
|
String thingID,
|
||||||
Completer<GoogleMapController> controller,
|
Completer<GoogleMapController> controller,
|
||||||
) async {
|
) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
Device device = await apiServices.getDeviceInformation(thingID);
|
Device device = await apiServices.getDeviceInformation(thingID);
|
||||||
sinkDeviceInfo.add(device);
|
sinkDeviceInfo.add(device);
|
||||||
if (device.areaPath != null) {
|
if (device.areaPath != null) {
|
||||||
@@ -73,10 +70,41 @@ class DetailDeviceBloc extends BlocBase {
|
|||||||
mapController
|
mapController
|
||||||
.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
|
.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
// Device device = await apiServices.getDeviceInformation(thingID);
|
||||||
}
|
// sinkDeviceInfo.add(device);
|
||||||
|
// if (device.areaPath != null) {
|
||||||
|
// String fullLocation = await DeviceUtils.instance
|
||||||
|
// .getFullDeviceLocation(context, device.areaPath!, "");
|
||||||
|
// log("Location: $fullLocation");
|
||||||
|
// sinkDeviceLocation.add(fullLocation);
|
||||||
|
// }
|
||||||
|
// Map<String, dynamic> sensorMap = {};
|
||||||
|
// if (device.status!.sensors != null) {
|
||||||
|
// sensorMap = DeviceUtils.instance
|
||||||
|
// .getDeviceSensors(context, device.status!.sensors!);
|
||||||
|
// } else {
|
||||||
|
// sensorMap = DeviceUtils.instance.getDeviceSensors(context, []);
|
||||||
|
// }
|
||||||
|
// sinkDeviceSensor.add(sensorMap);
|
||||||
|
// if (device.settings!.latitude! != "" &&
|
||||||
|
// device.settings!.longitude! != "") {
|
||||||
|
// final CameraPosition cameraPosition = CameraPosition(
|
||||||
|
// target: LatLng(
|
||||||
|
// double.parse(device.settings!.latitude!),
|
||||||
|
// double.parse(device.settings!.longitude!),
|
||||||
|
// ),
|
||||||
|
// zoom: 13,
|
||||||
|
// );
|
||||||
|
// final GoogleMapController mapController = await controller.future;
|
||||||
|
// mapController
|
||||||
|
// .animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void findLocation(BuildContext context, String areaPath) async {
|
void findLocation(BuildContext context, String areaPath) async {
|
||||||
@@ -85,12 +113,13 @@ class DetailDeviceBloc extends BlocBase {
|
|||||||
sinkDeviceLocation.add(fullLocation);
|
sinkDeviceLocation.add(fullLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getNearerSensorValue(BuildContext context,String thingID) async {
|
void getNearerSensorValue(BuildContext context, String thingID) async {
|
||||||
try {
|
apiServices.execute(context, () async {
|
||||||
List<SensorLogs> sensorTemps = [];
|
List<SensorLogs> sensorTemps = [];
|
||||||
DateTime twoDaysAgo = DateTime.now().subtract(const Duration(days: 2));
|
DateTime twoDaysAgo = DateTime.now().subtract(const Duration(days: 2));
|
||||||
String from = DateTimeUtils.instance.formatDateTimeToString(twoDaysAgo);
|
String from = DateTimeUtils.instance.formatDateTimeToString(twoDaysAgo);
|
||||||
String now = DateTimeUtils.instance.formatDateTimeToString(DateTime.now());
|
String now =
|
||||||
|
DateTimeUtils.instance.formatDateTimeToString(DateTime.now());
|
||||||
Map<String, dynamic> params = {
|
Map<String, dynamic> params = {
|
||||||
'thing_id': thingID,
|
'thing_id': thingID,
|
||||||
'from': from,
|
'from': from,
|
||||||
@@ -98,7 +127,8 @@ class DetailDeviceBloc extends BlocBase {
|
|||||||
'limit': '100',
|
'limit': '100',
|
||||||
'n': '7',
|
'n': '7',
|
||||||
};
|
};
|
||||||
DeviceLog devicesListLog = await apiServices.getLogsOfDevice(thingID, params);
|
DeviceLog devicesListLog =
|
||||||
|
await apiServices.getLogsOfDevice(thingID, params);
|
||||||
if (devicesListLog.sensors!.isNotEmpty) {
|
if (devicesListLog.sensors!.isNotEmpty) {
|
||||||
for (var sensor in devicesListLog.sensors!) {
|
for (var sensor in devicesListLog.sensors!) {
|
||||||
sensorTemps.add(sensor);
|
sensorTemps.add(sensor);
|
||||||
@@ -108,11 +138,35 @@ class DetailDeviceBloc extends BlocBase {
|
|||||||
} else {
|
} else {
|
||||||
sinkSensorTemps.add([]);
|
sinkSensorTemps.add([]);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// List<SensorLogs> sensorTemps = [];
|
||||||
context, e.toString());
|
// DateTime twoDaysAgo = DateTime.now().subtract(const Duration(days: 2));
|
||||||
sinkSensorTemps.add([]);
|
// String from = DateTimeUtils.instance.formatDateTimeToString(twoDaysAgo);
|
||||||
}
|
// String now =
|
||||||
|
// DateTimeUtils.instance.formatDateTimeToString(DateTime.now());
|
||||||
|
// Map<String, dynamic> params = {
|
||||||
|
// 'thing_id': thingID,
|
||||||
|
// 'from': from,
|
||||||
|
// 'to': now,
|
||||||
|
// 'limit': '100',
|
||||||
|
// 'n': '7',
|
||||||
|
// };
|
||||||
|
// DeviceLog devicesListLog =
|
||||||
|
// await apiServices.getLogsOfDevice(thingID, params);
|
||||||
|
// if (devicesListLog.sensors!.isNotEmpty) {
|
||||||
|
// for (var sensor in devicesListLog.sensors!) {
|
||||||
|
// sensorTemps.add(sensor);
|
||||||
|
// }
|
||||||
|
// sensorTemps = sensorTemps.reversed.toList();
|
||||||
|
// sinkSensorTemps.add(sensorTemps);
|
||||||
|
// } else {
|
||||||
|
// sinkSensorTemps.add([]);
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// sinkSensorTemps.add([]);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../feature/devices/device_model.dart';
|
import '../feature/devices/device_model.dart';
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
import '../product/constant/app/app_constants.dart';
|
import '../product/constant/app/app_constants.dart';
|
||||||
import '../product/services/api_services.dart';
|
import '../product/services/api_services.dart';
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
|
||||||
import '../product/utils/date_time_utils.dart';
|
import '../product/utils/date_time_utils.dart';
|
||||||
|
|
||||||
import '../product/utils/device_utils.dart';
|
import '../product/utils/device_utils.dart';
|
||||||
@@ -39,15 +36,12 @@ class DeviceLogsBloc extends BlocBase {
|
|||||||
void dispose() {}
|
void dispose() {}
|
||||||
|
|
||||||
void getAllDevices(BuildContext context) async {
|
void getAllDevices(BuildContext context) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
List<Device> originalDevices = await apiServices.getOwnerDevices();
|
List<Device> originalDevices = await apiServices.getOwnerDevices();
|
||||||
List<Device> devices =
|
List<Device> devices =
|
||||||
DeviceUtils.instance.sortDeviceByState(originalDevices);
|
DeviceUtils.instance.sortDeviceByState(originalDevices);
|
||||||
sinkAllDevices.add(devices);
|
sinkAllDevices.add(devices);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void getDeviceLogByThingID(
|
void getDeviceLogByThingID(
|
||||||
@@ -57,7 +51,7 @@ class DeviceLogsBloc extends BlocBase {
|
|||||||
DateTime fromDate,
|
DateTime fromDate,
|
||||||
List<SensorLogs> sensors,
|
List<SensorLogs> sensors,
|
||||||
) async {
|
) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
sinkmessage.add(ApplicationConstants.LOADING);
|
sinkmessage.add(ApplicationConstants.LOADING);
|
||||||
String fromDateString =
|
String fromDateString =
|
||||||
DateTimeUtils.instance.formatDateTimeToString(fromDate);
|
DateTimeUtils.instance.formatDateTimeToString(fromDate);
|
||||||
@@ -85,9 +79,38 @@ class DeviceLogsBloc extends BlocBase {
|
|||||||
sinkmessage.add(ApplicationConstants.NO_DATA);
|
sinkmessage.add(ApplicationConstants.NO_DATA);
|
||||||
}
|
}
|
||||||
sinkSensors.add(sensors);
|
sinkSensors.add(sensors);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
// sinkmessage.add(ApplicationConstants.LOADING);
|
||||||
}
|
// String fromDateString =
|
||||||
|
// DateTimeUtils.instance.formatDateTimeToString(fromDate);
|
||||||
|
// String now =
|
||||||
|
// DateTimeUtils.instance.formatDateTimeToString(DateTime.now());
|
||||||
|
// Map<String, dynamic> params = {
|
||||||
|
// 'thing_id': thingID,
|
||||||
|
// 'from': fromDateString,
|
||||||
|
// 'to': now,
|
||||||
|
// 'limit': '30',
|
||||||
|
// "offset": offset.toString(),
|
||||||
|
// "asc": "true"
|
||||||
|
// };
|
||||||
|
// DeviceLog devicesListLog =
|
||||||
|
// await apiServices.getLogsOfDevice(thingID, params);
|
||||||
|
// if (devicesListLog.sensors!.isEmpty) {
|
||||||
|
// bool hasMore = false;
|
||||||
|
// sinkHasMore.add(hasMore);
|
||||||
|
// }
|
||||||
|
// if (devicesListLog.sensors!.isNotEmpty) {
|
||||||
|
// for (var sensor in devicesListLog.sensors!) {
|
||||||
|
// sensors.add(sensor);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// sinkmessage.add(ApplicationConstants.NO_DATA);
|
||||||
|
// }
|
||||||
|
// sinkSensors.add(sensors);
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ class DeviceNotificationSettingsBloc extends BlocBase {
|
|||||||
StreamSink<String> get sinkMessageChange => messageChange.sink;
|
StreamSink<String> get sinkMessageChange => messageChange.sink;
|
||||||
Stream<String> get streaMmessageChange => messageChange.stream;
|
Stream<String> get streaMmessageChange => messageChange.stream;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {}
|
void dispose() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import '../product/services/api_services.dart';
|
import '../product/services/api_services.dart';
|
||||||
import '../product/services/language_services.dart';
|
import '../product/services/language_services.dart';
|
||||||
import '../product/shared/model/ward_model.dart';
|
import '../product/shared/model/ward_model.dart';
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
import '../product/shared/shared_snack_bar.dart';
|
||||||
import '../product/utils/response_status_utils.dart';
|
import '../product/utils/response_status_utils.dart';
|
||||||
|
|
||||||
import '../product/shared/model/district_model.dart';
|
import '../product/shared/model/district_model.dart';
|
||||||
import '../product/shared/model/province_model.dart';
|
import '../product/shared/model/province_model.dart';
|
||||||
import '../feature/devices/device_model.dart';
|
import '../feature/devices/device_model.dart';
|
||||||
@@ -80,56 +80,42 @@ class DeviceUpdateBloc extends BlocBase {
|
|||||||
List<DropdownMenuItem<Province>> provincesData = [];
|
List<DropdownMenuItem<Province>> provincesData = [];
|
||||||
provincesData.clear();
|
provincesData.clear();
|
||||||
sinkListProvinces.add(provincesData);
|
sinkListProvinces.add(provincesData);
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
List<Province> provinces = await apiServices.getAllProvinces();
|
List<Province> provinces = await apiServices.getAllProvinces();
|
||||||
for (var province in provinces) {
|
for (var province in provinces) {
|
||||||
provincesData.add(
|
provincesData.add(
|
||||||
DropdownMenuItem(value: province, child: Text(province.fullName!)));
|
DropdownMenuItem(value: province, child: Text(province.fullName!)));
|
||||||
}
|
}
|
||||||
sinkListProvinces.add(provincesData);
|
sinkListProvinces.add(provincesData);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getAllDistricts(BuildContext context, String provinceID) async {
|
Future<void> getAllDistricts(BuildContext context, String provinceID) async {
|
||||||
List<DropdownMenuItem<District>> districtsData = [];
|
List<DropdownMenuItem<District>> districtsData = [];
|
||||||
districtsData.clear();
|
districtsData.clear();
|
||||||
sinkListDistricts.add(districtsData);
|
sinkListDistricts.add(districtsData);
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
final districts = await apiServices.getAllDistricts(provinceID);
|
final districts = await apiServices.getAllDistricts(provinceID);
|
||||||
for (var district in districts) {
|
for (var district in districts) {
|
||||||
districtsData.add(
|
districtsData.add(
|
||||||
DropdownMenuItem(value: district, child: Text(district.fullName!)));
|
DropdownMenuItem(value: district, child: Text(district.fullName!)));
|
||||||
}
|
}
|
||||||
sinkListDistricts.add(districtsData);
|
sinkListDistricts.add(districtsData);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getAllWards(BuildContext context, String districtID) async {
|
Future<void> getAllWards(BuildContext context, String districtID) async {
|
||||||
List<DropdownMenuItem<Ward>> wardsData = [];
|
List<DropdownMenuItem<Ward>> wardsData = [];
|
||||||
wardsData.clear();
|
wardsData.clear();
|
||||||
sinkListWards.add(wardsData);
|
sinkListWards.add(wardsData);
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
final wards = await apiServices.getAllWards(districtID);
|
final wards = await apiServices.getAllWards(districtID);
|
||||||
for (var ward in wards) {
|
for (var ward in wards) {
|
||||||
wardsData.add(DropdownMenuItem(value: ward, child: Text(ward.fullName!)));
|
wardsData
|
||||||
|
.add(DropdownMenuItem(value: ward, child: Text(ward.fullName!)));
|
||||||
}
|
}
|
||||||
sinkListWards.add(wardsData);
|
sinkListWards.add(wardsData);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getDeviceInformation(
|
Future<void> getDeviceInformation(
|
||||||
@@ -138,7 +124,7 @@ class DeviceUpdateBloc extends BlocBase {
|
|||||||
TextEditingController deviceNameController,
|
TextEditingController deviceNameController,
|
||||||
TextEditingController latitudeController,
|
TextEditingController latitudeController,
|
||||||
TextEditingController longitudeController) async {
|
TextEditingController longitudeController) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
Device device = await apiServices.getDeviceInformation(thingID);
|
Device device = await apiServices.getDeviceInformation(thingID);
|
||||||
sinkDeviceInfo.add(device);
|
sinkDeviceInfo.add(device);
|
||||||
deviceNameController.text = device.name ?? "";
|
deviceNameController.text = device.name ?? "";
|
||||||
@@ -155,23 +141,24 @@ class DeviceUpdateBloc extends BlocBase {
|
|||||||
String wardCode = areaPath[2];
|
String wardCode = areaPath[2];
|
||||||
|
|
||||||
// Kiểm tra các mã có hợp lệ không (không rỗng)
|
// Kiểm tra các mã có hợp lệ không (không rỗng)
|
||||||
if (provinceCode.isNotEmpty && districtCode.isNotEmpty && wardCode.isNotEmpty) {
|
if (provinceCode.isNotEmpty &&
|
||||||
|
districtCode.isNotEmpty &&
|
||||||
|
wardCode.isNotEmpty) {
|
||||||
try {
|
try {
|
||||||
// Lấy danh sách districts và wards
|
// Lấy danh sách districts và wards
|
||||||
await getAllDistricts(context,provinceCode);
|
await getAllDistricts(context, provinceCode);
|
||||||
await getAllWards(context,districtCode);
|
await getAllWards(context, districtCode);
|
||||||
|
|
||||||
// Xử lý Province
|
// Xử lý Province
|
||||||
try {
|
try {
|
||||||
Province province = await apiServices.getProvinceByID(provinceCode);
|
Province province =
|
||||||
Map<String, String> provinceData = {
|
await apiServices.getProvinceByID(provinceCode);
|
||||||
"name": province.fullName ?? "Unknown Province",
|
Map<String, String> provinceData = {
|
||||||
"code": province.code ?? provinceCode
|
"name": province.fullName ?? "Unknown Province",
|
||||||
};
|
"code": province.code ?? provinceCode
|
||||||
sinkProvinceData.add(provinceData);
|
};
|
||||||
|
sinkProvinceData.add(provinceData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
// Thêm dữ liệu mặc định khi lỗi
|
// Thêm dữ liệu mặc định khi lỗi
|
||||||
Map<String, String> provinceData = {
|
Map<String, String> provinceData = {
|
||||||
"name": "Error Loading Province",
|
"name": "Error Loading Province",
|
||||||
@@ -179,20 +166,20 @@ class DeviceUpdateBloc extends BlocBase {
|
|||||||
};
|
};
|
||||||
sinkProvinceData.add(provinceData);
|
sinkProvinceData.add(provinceData);
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
showErrorTopSnackBarCustom(
|
showErrorTopSnackBarCustom(context, e.toString());
|
||||||
context, e.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Xử lý District
|
// Xử lý District
|
||||||
try {
|
try {
|
||||||
District district = await apiServices.getDistrictByID(districtCode);
|
District district =
|
||||||
Map<String, String> districData = {
|
await apiServices.getDistrictByID(districtCode);
|
||||||
"name": district.fullName ?? "Unknown District",
|
Map<String, String> districData = {
|
||||||
"code": district.code ?? districtCode,
|
"name": district.fullName ?? "Unknown District",
|
||||||
};
|
"code": district.code ?? districtCode,
|
||||||
sinkDistrictData.add(districData);
|
};
|
||||||
|
sinkDistrictData.add(districData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Lỗi khi lấy thông tin district ($districtCode): $e");
|
log("Lỗi khi lấy thông tin district ($districtCode): $e");
|
||||||
Map<String, String> districData = {
|
Map<String, String> districData = {
|
||||||
"name": "Error Loading District",
|
"name": "Error Loading District",
|
||||||
"code": districtCode,
|
"code": districtCode,
|
||||||
@@ -202,84 +189,168 @@ class DeviceUpdateBloc extends BlocBase {
|
|||||||
|
|
||||||
// Xử lý Ward
|
// Xử lý Ward
|
||||||
try {
|
try {
|
||||||
Ward ward = await apiServices.getWardByID(wardCode);
|
Ward ward = await apiServices.getWardByID(wardCode);
|
||||||
Map<String, String> wardMap = {
|
Map<String, String> wardMap = {
|
||||||
"name": ward.fullName ?? "Unknown Ward",
|
"name": ward.fullName ?? "Unknown Ward",
|
||||||
"code": ward.code ?? wardCode,
|
"code": ward.code ?? wardCode,
|
||||||
};
|
};
|
||||||
sinkWardData.add(wardMap);
|
sinkWardData.add(wardMap);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Lỗi khi lấy thông tin ward ($wardCode): $e");
|
log("Lỗi khi lấy thông tin ward ($wardCode): $e");
|
||||||
Map<String, String> wardMap = {
|
Map<String, String> wardMap = {
|
||||||
"name": "Error Loading Ward",
|
"name": "Error Loading Ward",
|
||||||
"code": wardCode,
|
"code": wardCode,
|
||||||
};
|
};
|
||||||
sinkWardData.add(wardMap);
|
sinkWardData.add(wardMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Lỗi khi gọi getAllDistricts hoặc getAllWards: $e");
|
log("Lỗi khi gọi getAllDistricts hoặc getAllWards: $e");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await getAllProvinces(context);
|
await getAllProvinces(context);
|
||||||
print("Một hoặc nhiều mã địa phương trống: Province: $provinceCode, District: $districtCode, Ward: $wardCode");
|
log("Một hoặc nhiều mã địa phương trống: Province: $provinceCode, District: $districtCode, Ward: $wardCode");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showNoIconTopSnackBar(context,"AreaPath không đủ thông tin: ${device.areaPath}",Colors.orangeAccent, Colors.white);
|
showNoIconTopSnackBar(
|
||||||
|
context,
|
||||||
|
"AreaPath không đủ thông tin: ${device.areaPath}",
|
||||||
|
Colors.orangeAccent,
|
||||||
|
Colors.white);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
showNoIconTopSnackBar(context,"Lỗi trong getDeviceInfomation: $e",Colors.orangeAccent, Colors.white);
|
// try {
|
||||||
}
|
// Device device = await apiServices.getDeviceInformation(thingID);
|
||||||
|
// sinkDeviceInfo.add(device);
|
||||||
|
// deviceNameController.text = device.name ?? "";
|
||||||
|
// latitudeController.text = device.settings!.latitude ?? "";
|
||||||
|
// longitudeController.text = device.settings!.longitude ?? "";
|
||||||
|
|
||||||
|
// if (device.areaPath != null && device.areaPath!.isNotEmpty) {
|
||||||
|
// List<String> areaPath = device.areaPath!.split('_');
|
||||||
|
|
||||||
|
// // Kiểm tra độ dài của areaPath
|
||||||
|
// if (areaPath.length >= 3) {
|
||||||
|
// String provinceCode = areaPath[0];
|
||||||
|
// String districtCode = areaPath[1];
|
||||||
|
// String wardCode = areaPath[2];
|
||||||
|
|
||||||
|
// // Kiểm tra các mã có hợp lệ không (không rỗng)
|
||||||
|
// if (provinceCode.isNotEmpty &&
|
||||||
|
// districtCode.isNotEmpty &&
|
||||||
|
// wardCode.isNotEmpty) {
|
||||||
|
// try {
|
||||||
|
// // Lấy danh sách districts và wards
|
||||||
|
// await getAllDistricts(context, provinceCode);
|
||||||
|
// await getAllWards(context, districtCode);
|
||||||
|
|
||||||
|
// // Xử lý Province
|
||||||
|
// try {
|
||||||
|
// Province province =
|
||||||
|
// await apiServices.getProvinceByID(provinceCode);
|
||||||
|
// Map<String, String> provinceData = {
|
||||||
|
// "name": province.fullName ?? "Unknown Province",
|
||||||
|
// "code": province.code ?? provinceCode
|
||||||
|
// };
|
||||||
|
// sinkProvinceData.add(provinceData);
|
||||||
|
// } catch (e) {
|
||||||
|
// // Thêm dữ liệu mặc định khi lỗi
|
||||||
|
// Map<String, String> provinceData = {
|
||||||
|
// "name": "Error Loading Province",
|
||||||
|
// "code": provinceCode
|
||||||
|
// };
|
||||||
|
// sinkProvinceData.add(provinceData);
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Xử lý District
|
||||||
|
// try {
|
||||||
|
// District district =
|
||||||
|
// await apiServices.getDistrictByID(districtCode);
|
||||||
|
// Map<String, String> districData = {
|
||||||
|
// "name": district.fullName ?? "Unknown District",
|
||||||
|
// "code": district.code ?? districtCode,
|
||||||
|
// };
|
||||||
|
// sinkDistrictData.add(districData);
|
||||||
|
// } catch (e) {
|
||||||
|
// log("Lỗi khi lấy thông tin district ($districtCode): $e");
|
||||||
|
// Map<String, String> districData = {
|
||||||
|
// "name": "Error Loading District",
|
||||||
|
// "code": districtCode,
|
||||||
|
// };
|
||||||
|
// sinkDistrictData.add(districData);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Xử lý Ward
|
||||||
|
// try {
|
||||||
|
// Ward ward = await apiServices.getWardByID(wardCode);
|
||||||
|
// Map<String, String> wardMap = {
|
||||||
|
// "name": ward.fullName ?? "Unknown Ward",
|
||||||
|
// "code": ward.code ?? wardCode,
|
||||||
|
// };
|
||||||
|
// sinkWardData.add(wardMap);
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Lỗi khi lấy thông tin ward ($wardCode): $e");
|
||||||
|
// Map<String, String> wardMap = {
|
||||||
|
// "name": "Error Loading Ward",
|
||||||
|
// "code": wardCode,
|
||||||
|
// };
|
||||||
|
// sinkWardData.add(wardMap);
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Lỗi khi gọi getAllDistricts hoặc getAllWards: $e");
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// await getAllProvinces(context);
|
||||||
|
// print(
|
||||||
|
// "Một hoặc nhiều mã địa phương trống: Province: $provinceCode, District: $districtCode, Ward: $wardCode");
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// showNoIconTopSnackBar(
|
||||||
|
// context,
|
||||||
|
// "AreaPath không đủ thông tin: ${device.areaPath}",
|
||||||
|
// Colors.orangeAccent,
|
||||||
|
// Colors.white);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// showNoIconTopSnackBar(context, "Lỗi trong getDeviceInfomation: $e",
|
||||||
|
// Colors.orangeAccent, Colors.white);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Province> getProvinceByName(BuildContext context, String name) async {
|
Future<Province> getProvinceByName(BuildContext context, String name) async {
|
||||||
try {
|
return await apiServices.execute(context, () async {
|
||||||
List<Province> provinces = await apiServices.getProvincesByName(name);
|
List<Province> provinces = await apiServices.getProvincesByName(name);
|
||||||
if (provinces.isNotEmpty) {
|
if (provinces.isNotEmpty) {
|
||||||
return provinces[0];
|
return provinces[0];
|
||||||
} else {
|
} else {
|
||||||
return Province(name: "null");
|
return Province(name: "null");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
if (context.mounted) {
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
return Province(name: "null");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<District> getDistrictByName(
|
Future<District> getDistrictByName(
|
||||||
BuildContext context, String name, String provinceCode) async {
|
BuildContext context, String name, String provinceCode) async {
|
||||||
try {
|
return apiServices.execute(context, () async {
|
||||||
final districts = await apiServices.getDistrictsByName(name);
|
final districts = await apiServices.getDistrictsByName(name);
|
||||||
return districts.firstWhere(
|
return districts.firstWhere(
|
||||||
(district) => district.provinceCode == provinceCode,
|
(district) => district.provinceCode == provinceCode,
|
||||||
orElse: () => District(name: "null"),
|
orElse: () => District(name: "null"),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
});
|
||||||
if (context.mounted) {
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
return District(name: "null");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Ward> getWardByName(
|
Future<Ward> getWardByName(
|
||||||
BuildContext context, String name, String districtCode) async {
|
BuildContext context, String name, String districtCode) async {
|
||||||
try {
|
return apiServices.execute(context, () async {
|
||||||
final wards = await apiServices.getWardsByName(name);
|
final wards = await apiServices.getWardsByName(name);
|
||||||
return wards.firstWhere(
|
return wards.firstWhere(
|
||||||
(ward) => ward.districtCode == districtCode,
|
(ward) => ward.districtCode == districtCode,
|
||||||
orElse: () => Ward(name: "null"),
|
orElse: () => Ward(name: "null"),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
});
|
||||||
if (context.mounted) {
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
return Ward(name: "null");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateDevice(
|
Future<void> updateDevice(
|
||||||
@@ -292,10 +363,10 @@ class DeviceUpdateBloc extends BlocBase {
|
|||||||
String districtCode,
|
String districtCode,
|
||||||
String wardCode,
|
String wardCode,
|
||||||
) async {
|
) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
DateTime dateTime = DateTime.now();
|
DateTime dateTime = DateTime.now();
|
||||||
String formattedDateTime =
|
String formattedDateTime =
|
||||||
DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime);
|
DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime);
|
||||||
Map<String, dynamic> body = {
|
Map<String, dynamic> body = {
|
||||||
"name": name,
|
"name": name,
|
||||||
"area_province": provinceCode,
|
"area_province": provinceCode,
|
||||||
@@ -312,11 +383,30 @@ class DeviceUpdateBloc extends BlocBase {
|
|||||||
appLocalization(context).notification_update_device_success,
|
appLocalization(context).notification_update_device_success,
|
||||||
appLocalization(context).notification_update_device_failed,
|
appLocalization(context).notification_update_device_failed,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// DateTime dateTime = DateTime.now();
|
||||||
context, e.toString());
|
// String formattedDateTime =
|
||||||
}
|
// DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime);
|
||||||
|
// Map<String, dynamic> body = {
|
||||||
|
// "name": name,
|
||||||
|
// "area_province": provinceCode,
|
||||||
|
// "area_district": districtCode,
|
||||||
|
// "area_ward": wardCode,
|
||||||
|
// "latitude": latitude,
|
||||||
|
// "longitude": longitude,
|
||||||
|
// "note": "User updated device infomation at $formattedDateTime",
|
||||||
|
// };
|
||||||
|
// int statusCode = await apiServices.updateOwnerDevice(thingID, body);
|
||||||
|
// showSnackBarResponseByStatusCodeNoIcon(
|
||||||
|
// context,
|
||||||
|
// statusCode,
|
||||||
|
// appLocalization(context).notification_update_device_success,
|
||||||
|
// appLocalization(context).notification_update_device_failed,
|
||||||
|
// );
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
import '../feature/devices/device_model.dart';
|
import '../feature/devices/device_model.dart';
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
import '../product/constant/app/app_constants.dart';
|
import '../product/constant/app/app_constants.dart';
|
||||||
import '../product/services/api_services.dart';
|
import '../product/services/api_services.dart';
|
||||||
|
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
import '../product/shared/shared_snack_bar.dart';
|
||||||
import '../product/utils/device_utils.dart';
|
import '../product/utils/device_utils.dart';
|
||||||
|
|
||||||
@@ -76,7 +73,7 @@ class DevicesManagerBloc extends BlocBase {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
void getDeviceByState(BuildContext context,int state) async {
|
void getDeviceByState(BuildContext context, int state) async {
|
||||||
try {
|
try {
|
||||||
sinkTagStates.add([state]);
|
sinkTagStates.add([state]);
|
||||||
|
|
||||||
@@ -91,16 +88,16 @@ class DevicesManagerBloc extends BlocBase {
|
|||||||
List<Device> devices = [];
|
List<Device> devices = [];
|
||||||
List<Device> originalDevices = [];
|
List<Device> originalDevices = [];
|
||||||
if (state != -2) {
|
if (state != -2) {
|
||||||
originalDevices =
|
originalDevices = await apiServices
|
||||||
await apiServices.getOwnerDeviceByState({"state": state.toString()});
|
.getOwnerDeviceByState({"state": state.toString()});
|
||||||
} else {
|
} else {
|
||||||
originalDevices = await apiServices.getOwnerDevices();
|
originalDevices = await apiServices.getOwnerDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Device> publicDevices = [];
|
List<Device> publicDevices = [];
|
||||||
|
|
||||||
for(var device in originalDevices){
|
for (var device in originalDevices) {
|
||||||
if(device.visibility == "PUBLIC"){
|
if (device.visibility == "PUBLIC") {
|
||||||
publicDevices.add(device);
|
publicDevices.add(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,10 +116,8 @@ class DevicesManagerBloc extends BlocBase {
|
|||||||
sinkAllDevices.add(devices);
|
sinkAllDevices.add(devices);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
showErrorTopSnackBarCustom(
|
showErrorTopSnackBarCustom(context, e.toString());
|
||||||
context, e.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getStateKey(int state) {
|
String _getStateKey(int state) {
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import '../feature/devices/device_model.dart';
|
import '../feature/devices/device_model.dart';
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
import '../product/services/api_services.dart';
|
import '../product/services/api_services.dart';
|
||||||
import '../product/services/language_services.dart';
|
import '../product/services/language_services.dart';
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
|
||||||
import '../product/utils/response_status_utils.dart';
|
import '../product/utils/response_status_utils.dart';
|
||||||
|
|
||||||
import '../feature/inter_family/group_detail/group_detail_model.dart';
|
import '../feature/inter_family/group_detail/group_detail_model.dart';
|
||||||
|
|
||||||
class DetailGroupBloc extends BlocBase {
|
class DetailGroupBloc extends BlocBase {
|
||||||
@@ -30,86 +27,117 @@ class DetailGroupBloc extends BlocBase {
|
|||||||
@override
|
@override
|
||||||
void dispose() {}
|
void dispose() {}
|
||||||
|
|
||||||
Future<void> getGroupDetail(BuildContext context,String groupID) async {
|
Future<void> getGroupDetail(BuildContext context, String groupID) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
List<DeviceOfGroup> warningDevices = [];
|
List<DeviceOfGroup> warningDevices = [];
|
||||||
GroupDetail group = await apiServices.getGroupDetail(groupID);
|
GroupDetail group = await apiServices.getGroupDetail(groupID);
|
||||||
sinkDetailGroup.add(group);
|
sinkDetailGroup.add(group);
|
||||||
if (group.devices != null) {
|
if (group.devices != null) {
|
||||||
for (var device in group.devices!) {
|
for (var device in group.devices!) {
|
||||||
if (device.state == 1) {
|
if (device.state == 1) {
|
||||||
warningDevices.add(device);
|
warningDevices.add(device);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sinkWarningDevice.add(warningDevices);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
sinkWarningDevice.add(warningDevices);
|
||||||
if (!context.mounted) return;
|
}
|
||||||
showErrorTopSnackBarCustom(
|
});
|
||||||
context, e.toString());
|
// try {
|
||||||
}
|
// List<DeviceOfGroup> warningDevices = [];
|
||||||
|
// GroupDetail group = await apiServices.getGroupDetail(groupID);
|
||||||
|
// sinkDetailGroup.add(group);
|
||||||
|
// if (group.devices != null) {
|
||||||
|
// for (var device in group.devices!) {
|
||||||
|
// if (device.state == 1) {
|
||||||
|
// warningDevices.add(device);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// sinkWarningDevice.add(warningDevices);
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> approveUserToGroup(BuildContext context, String groupID,
|
Future<void> approveUserToGroup(BuildContext context, String groupID,
|
||||||
String userID, String userName) async {
|
String userID, String userName) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
Map<String, dynamic> body = {"group_id": groupID, "user_id": userID};
|
Map<String, dynamic> body = {"group_id": groupID, "user_id": userID};
|
||||||
int statusCode = await apiServices.approveGroup(body);
|
int statusCode = await apiServices.approveGroup(body);
|
||||||
showSnackBarResponseByStatusCode(context, statusCode,
|
showSnackBarResponseByStatusCode(context, statusCode,
|
||||||
"Đã duyệt $userName vào nhóm!", "Duyệt $userName thất bại!");
|
"Đã duyệt $userName vào nhóm!", "Duyệt $userName thất bại!");
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// Map<String, dynamic> body = {"group_id": groupID, "user_id": userID};
|
||||||
context, e.toString());
|
// int statusCode = await apiServices.approveGroup(body);
|
||||||
}
|
// showSnackBarResponseByStatusCode(context, statusCode,
|
||||||
|
// "Đã duyệt $userName vào nhóm!", "Duyệt $userName thất bại!");
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteOrUnapproveUser(BuildContext context, String groupID,
|
Future<void> deleteOrUnapproveUser(BuildContext context, String groupID,
|
||||||
String userID, String userName) async {
|
String userID, String userName) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.deleteUserInGroup(groupID, userID);
|
int statusCode = await apiServices.deleteUserInGroup(groupID, userID);
|
||||||
showSnackBarResponseByStatusCode(context, statusCode,
|
showSnackBarResponseByStatusCode(context, statusCode,
|
||||||
"Đã xóa người dùng $userName", "Xóa người dùng $userName thất bại");
|
"Đã xóa người dùng $userName", "Xóa người dùng $userName thất bại");
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// int statusCode = await apiServices.deleteUserInGroup(groupID, userID);
|
||||||
context, e.toString());
|
// showSnackBarResponseByStatusCode(context, statusCode,
|
||||||
}
|
// "Đã xóa người dùng $userName", "Xóa người dùng $userName thất bại");
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteDevice(BuildContext context, String groupID,
|
Future<void> deleteDevice(BuildContext context, String groupID,
|
||||||
String thingID, String deviceName) async {
|
String thingID, String deviceName) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.deleteDeviceInGroup(groupID, thingID);
|
int statusCode = await apiServices.deleteDeviceInGroup(groupID, thingID);
|
||||||
showSnackBarResponseByStatusCode(context, statusCode,
|
showSnackBarResponseByStatusCode(context, statusCode,
|
||||||
"Đã xóa thiết bị $deviceName", "Xóa thiết bị $deviceName thất bại");
|
"Đã xóa thiết bị $deviceName", "Xóa thiết bị $deviceName thất bại");
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// int statusCode = await apiServices.deleteDeviceInGroup(groupID, thingID);
|
||||||
context, e.toString());
|
// showSnackBarResponseByStatusCode(context, statusCode,
|
||||||
}
|
// "Đã xóa thiết bị $deviceName", "Xóa thiết bị $deviceName thất bại");
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> leaveGroup(
|
Future<void> leaveGroup(
|
||||||
BuildContext context, String groupID, String userID) async {
|
BuildContext context, String groupID, String userID) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.deleteUserInGroup(groupID, userID);
|
int statusCode = await apiServices.deleteUserInGroup(groupID, userID);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
context,
|
context,
|
||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_leave_group_success,
|
appLocalization(context).notification_leave_group_success,
|
||||||
appLocalization(context).notification_leave_group_failed);
|
appLocalization(context).notification_leave_group_failed);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// int statusCode = await apiServices.deleteUserInGroup(groupID, userID);
|
||||||
context, e.toString());
|
// showSnackBarResponseByStatusCode(
|
||||||
}
|
// context,
|
||||||
|
// statusCode,
|
||||||
|
// appLocalization(context).notification_leave_group_success,
|
||||||
|
// appLocalization(context).notification_leave_group_failed);
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateDeviceNameInGroup(
|
Future<void> updateDeviceNameInGroup(
|
||||||
BuildContext context, String thingID, String newAlias) async {
|
BuildContext context, String thingID, String newAlias) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
Map<String, dynamic> body = {"thing_id": thingID, "alias": newAlias};
|
Map<String, dynamic> body = {"thing_id": thingID, "alias": newAlias};
|
||||||
int statusCode = await apiServices.updateDeviceAlias(body);
|
int statusCode = await apiServices.updateDeviceAlias(body);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
@@ -118,26 +146,29 @@ class DetailGroupBloc extends BlocBase {
|
|||||||
appLocalization(context).notification_update_device_success,
|
appLocalization(context).notification_update_device_success,
|
||||||
appLocalization(context).notification_update_device_failed,
|
appLocalization(context).notification_update_device_failed,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// Map<String, dynamic> body = {"thing_id": thingID, "alias": newAlias};
|
||||||
context, e.toString());
|
// int statusCode = await apiServices.updateDeviceAlias(body);
|
||||||
}
|
// showSnackBarResponseByStatusCode(
|
||||||
|
// context,
|
||||||
|
// statusCode,
|
||||||
|
// appLocalization(context).notification_update_device_success,
|
||||||
|
// appLocalization(context).notification_update_device_failed,
|
||||||
|
// );
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Device>> getOwnerDevices(BuildContext context) async {
|
Future<List<Device>> getOwnerDevices(BuildContext context) {
|
||||||
List<Device> allDevices = [];
|
return apiServices.execute(context, () async {
|
||||||
try {
|
|
||||||
final originalDevices = await apiServices.getOwnerDevices();
|
final originalDevices = await apiServices.getOwnerDevices();
|
||||||
allDevices = originalDevices.where((device) => device.visibility == "PUBLIC").toList();
|
return originalDevices
|
||||||
|
.where((device) => device.visibility == "PUBLIC")
|
||||||
return allDevices;
|
.toList();
|
||||||
} catch (e) {
|
});
|
||||||
if (context.mounted) {
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
return allDevices;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addDeviceToGroup(
|
Future<void> addDeviceToGroup(
|
||||||
@@ -145,7 +176,7 @@ class DetailGroupBloc extends BlocBase {
|
|||||||
Map<String, dynamic> body = {
|
Map<String, dynamic> body = {
|
||||||
"thing_id": thingID,
|
"thing_id": thingID,
|
||||||
};
|
};
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.addDeviceToGroup(groupID, body);
|
int statusCode = await apiServices.addDeviceToGroup(groupID, body);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
context,
|
context,
|
||||||
@@ -153,10 +184,18 @@ class DetailGroupBloc extends BlocBase {
|
|||||||
appLocalization(context).notification_add_device_success,
|
appLocalization(context).notification_add_device_success,
|
||||||
appLocalization(context).notification_add_device_failed,
|
appLocalization(context).notification_add_device_failed,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// int statusCode = await apiServices.addDeviceToGroup(groupID, body);
|
||||||
context, e.toString());
|
// showSnackBarResponseByStatusCode(
|
||||||
}
|
// context,
|
||||||
|
// statusCode,
|
||||||
|
// appLocalization(context).notification_add_device_success,
|
||||||
|
// appLocalization(context).notification_add_device_failed,
|
||||||
|
// );
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,19 @@ import '../feature/home/device_alias_model.dart';
|
|||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
|
|
||||||
class HomeBloc extends BlocBase {
|
class HomeBloc extends BlocBase {
|
||||||
|
final allDevicesAliasMap =
|
||||||
final allDevicesAliasMap = StreamController<Map<String,List<DeviceWithAlias>>>.broadcast();
|
StreamController<Map<String, List<DeviceWithAlias>>>.broadcast();
|
||||||
StreamSink<Map<String,List<DeviceWithAlias>>> get sinkAllDevicesAliasMap =>
|
StreamSink<Map<String, List<DeviceWithAlias>>> get sinkAllDevicesAliasMap =>
|
||||||
allDevicesAliasMap.sink;
|
allDevicesAliasMap.sink;
|
||||||
Stream<Map<String,List<DeviceWithAlias>>> get streamAllDevicesAliasMap =>
|
Stream<Map<String, List<DeviceWithAlias>>> get streamAllDevicesAliasMap =>
|
||||||
allDevicesAliasMap.stream;
|
allDevicesAliasMap.stream;
|
||||||
|
|
||||||
final allDevicesAliasJoinedMap = StreamController<Map<String,List<DeviceWithAlias>>>.broadcast();
|
final allDevicesAliasJoinedMap =
|
||||||
StreamSink<Map<String,List<DeviceWithAlias>>> get sinkAllDevicesAliasJoinedMap =>
|
StreamController<Map<String, List<DeviceWithAlias>>>.broadcast();
|
||||||
allDevicesAliasJoinedMap.sink;
|
StreamSink<Map<String, List<DeviceWithAlias>>>
|
||||||
Stream<Map<String,List<DeviceWithAlias>>> get streamAllDevicesAliasJoinedMap =>
|
get sinkAllDevicesAliasJoinedMap => allDevicesAliasJoinedMap.sink;
|
||||||
allDevicesAliasJoinedMap.stream;
|
Stream<Map<String, List<DeviceWithAlias>>>
|
||||||
|
get streamAllDevicesAliasJoinedMap => allDevicesAliasJoinedMap.stream;
|
||||||
|
|
||||||
final countNotification = StreamController<int>.broadcast();
|
final countNotification = StreamController<int>.broadcast();
|
||||||
StreamSink<int> get sinkCountNotification => countNotification.sink;
|
StreamSink<int> get sinkCountNotification => countNotification.sink;
|
||||||
@@ -26,13 +27,19 @@ class HomeBloc extends BlocBase {
|
|||||||
StreamSink<bool?> get sinkHasJoinedDevice => hasJoinedDevice.sink;
|
StreamSink<bool?> get sinkHasJoinedDevice => hasJoinedDevice.sink;
|
||||||
Stream<bool?> get streamHasJoinedDevice => hasJoinedDevice.stream;
|
Stream<bool?> get streamHasJoinedDevice => hasJoinedDevice.stream;
|
||||||
|
|
||||||
final ownerDevicesStatus =
|
final ownerDevicesStatus =
|
||||||
StreamController<Map<String, List<DeviceWithAlias>>>.broadcast();
|
StreamController<Map<String, List<DeviceWithAlias>>>.broadcast();
|
||||||
StreamSink<Map<String, List<DeviceWithAlias>>>
|
StreamSink<Map<String, List<DeviceWithAlias>>> get sinkOwnerDevicesStatus =>
|
||||||
get sinkOwnerDevicesStatus => ownerDevicesStatus.sink;
|
ownerDevicesStatus.sink;
|
||||||
Stream<Map<String, List<DeviceWithAlias>>> get streamOwnerDevicesStatus =>
|
Stream<Map<String, List<DeviceWithAlias>>> get streamOwnerDevicesStatus =>
|
||||||
ownerDevicesStatus.stream;
|
ownerDevicesStatus.stream;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {}
|
void dispose() {
|
||||||
|
allDevicesAliasMap.close();
|
||||||
|
allDevicesAliasJoinedMap.close();
|
||||||
|
countNotification.close();
|
||||||
|
hasJoinedDevice.close();
|
||||||
|
ownerDevicesStatus.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../product/constant/app/app_constants.dart';
|
|
||||||
|
|
||||||
|
import '../product/constant/app/app_constants.dart';
|
||||||
import '../product/services/api_services.dart';
|
import '../product/services/api_services.dart';
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
import '../product/services/language_services.dart';
|
import '../product/services/language_services.dart';
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
|
||||||
import '../product/utils/response_status_utils.dart';
|
import '../product/utils/response_status_utils.dart';
|
||||||
import '../feature/inter_family/groups/groups_model.dart';
|
import '../feature/inter_family/groups/groups_model.dart';
|
||||||
|
|
||||||
@@ -36,10 +33,10 @@ class InterFamilyBloc extends BlocBase {
|
|||||||
@override
|
@override
|
||||||
void dispose() {}
|
void dispose() {}
|
||||||
|
|
||||||
void getAllGroup(String role) async {
|
void getAllGroup(BuildContext context, String role) async {
|
||||||
List<Group> groups = [];
|
List<Group> groups = [];
|
||||||
sinkCurrentGroups.add(groups);
|
sinkCurrentGroups.add(groups);
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
groups = await apiServices.getAllGroups();
|
groups = await apiServices.getAllGroups();
|
||||||
groups = sortGroupByName(groups);
|
groups = sortGroupByName(groups);
|
||||||
|
|
||||||
@@ -55,19 +52,13 @@ class InterFamilyBloc extends BlocBase {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
).toList();
|
).toList();
|
||||||
|
|
||||||
sinkCurrentGroups.add(currentGroups);
|
sinkCurrentGroups.add(currentGroups);
|
||||||
} catch (e) {
|
});
|
||||||
// Xử lý lỗi khi jsonDecode thất bại
|
|
||||||
log("Error decoding JSON: $e");
|
|
||||||
sinkCurrentGroups.add([]);
|
|
||||||
}
|
|
||||||
log("Inter Family Role: $role");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createGroup(
|
Future<void> createGroup(
|
||||||
BuildContext context, String name, String description) async {
|
BuildContext context, String name, String description) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
Map<String, dynamic> body = {"name": name, "description": description};
|
Map<String, dynamic> body = {"name": name, "description": description};
|
||||||
int? statusCode = await apiServices.createGroup(body);
|
int? statusCode = await apiServices.createGroup(body);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
@@ -75,17 +66,12 @@ class InterFamilyBloc extends BlocBase {
|
|||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_add_group_success,
|
appLocalization(context).notification_add_group_success,
|
||||||
appLocalization(context).notification_add_group_failed);
|
appLocalization(context).notification_add_group_failed);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changeGroupInformation(BuildContext context, String groupID,
|
Future<void> changeGroupInformation(BuildContext context, String groupID,
|
||||||
String name, String description) async {
|
String name, String description) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
Map<String, dynamic> body = {"name": name, "description": description};
|
Map<String, dynamic> body = {"name": name, "description": description};
|
||||||
int statusCode = await apiServices.updateGroup(body, groupID);
|
int statusCode = await apiServices.updateGroup(body, groupID);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
@@ -93,44 +79,32 @@ class InterFamilyBloc extends BlocBase {
|
|||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_update_group_success,
|
appLocalization(context).notification_update_group_success,
|
||||||
appLocalization(context).notification_update_group_failed);
|
appLocalization(context).notification_update_group_failed);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> joinGroup(BuildContext context, String groupID) async {
|
Future<void> joinGroup(BuildContext context, String groupID) async {
|
||||||
try {
|
Map<String, dynamic> body = {
|
||||||
Map<String, dynamic> body = {
|
"group_id": groupID,
|
||||||
"group_id": groupID,
|
};
|
||||||
};
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.joinGroup(groupID, body);
|
int statusCode = await apiServices.joinGroup(groupID, body);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
context,
|
context,
|
||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_join_request_group_success,
|
appLocalization(context).notification_join_request_group_success,
|
||||||
appLocalization(context).notification_join_request_group_failed);
|
appLocalization(context).notification_join_request_group_failed);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteGroup(BuildContext context, String groupID) async {
|
Future<void> deleteGroup(BuildContext context, String groupID) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.deleteGroup(groupID);
|
int statusCode = await apiServices.deleteGroup(groupID);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
context,
|
context,
|
||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_delete_group_success,
|
appLocalization(context).notification_delete_group_success,
|
||||||
appLocalization(context).notification_delete_group_failed);
|
appLocalization(context).notification_delete_group_failed);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Group> sortGroupByName(List<Group> groups) {
|
List<Group> sortGroupByName(List<Group> groups) {
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
|
|
||||||
class LoginBloc extends BlocBase{
|
class LoginBloc extends BlocBase {
|
||||||
|
final loginRequest = StreamController<Map<String, dynamic>>.broadcast();
|
||||||
final loginRequest = StreamController<Map<String,dynamic>>.broadcast();
|
StreamSink<Map<String, dynamic>> get sinkLoginRequest => loginRequest.sink;
|
||||||
StreamSink<Map<String,dynamic>> get sinkLoginRequest => loginRequest.sink;
|
Stream<Map<String, dynamic>> get streamLoginRequest => loginRequest.stream;
|
||||||
Stream<Map<String,dynamic>> get streamLoginRequest => loginRequest.stream;
|
|
||||||
|
|
||||||
final isShowPassword = StreamController<bool>.broadcast();
|
final isShowPassword = StreamController<bool>.broadcast();
|
||||||
StreamSink<bool> get sinkIsShowPassword => isShowPassword.sink;
|
StreamSink<bool> get sinkIsShowPassword => isShowPassword.sink;
|
||||||
Stream<bool> get streamIsShowPassword => isShowPassword.stream;
|
Stream<bool> get streamIsShowPassword => isShowPassword.stream;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sfm_app/product/cache/local_manager.dart';
|
|
||||||
import 'package:sfm_app/product/constant/app/api_path_constant.dart';
|
import '../product/cache/local_manager.dart';
|
||||||
import 'package:sfm_app/product/constant/enums/local_keys_enums.dart';
|
import '../product/constant/app/api_path_constant.dart';
|
||||||
import 'package:sfm_app/product/network/network_manager.dart';
|
import '../product/constant/enums/local_keys_enums.dart';
|
||||||
|
import '../product/network/network_manager.dart';
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
import '../product/services/api_services.dart';
|
import '../product/services/api_services.dart';
|
||||||
import '../feature/bell/bell_model.dart';
|
import '../feature/bell/bell_model.dart';
|
||||||
import '../feature/settings/profile/profile_model.dart';
|
import '../feature/settings/profile/profile_model.dart';
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
|
||||||
|
|
||||||
class MainBloc extends BlocBase {
|
class MainBloc extends BlocBase {
|
||||||
APIServices apiServices = APIServices();
|
APIServices apiServices = APIServices();
|
||||||
@@ -44,19 +42,13 @@ class MainBloc extends BlocBase {
|
|||||||
void dispose() {}
|
void dispose() {}
|
||||||
|
|
||||||
void getUserProfile(BuildContext context) async {
|
void getUserProfile(BuildContext context) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
User user = await apiServices.getUserDetail();
|
User user = await apiServices.getUserDetail();
|
||||||
sinkUserProfile.add(user);
|
sinkUserProfile.add(user);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getFCMTokenAndPresentations() async {
|
getFCMTokenAndPresentations() async {
|
||||||
|
|
||||||
String? firebaseAppToken = await FirebaseMessaging.instance.getToken();
|
String? firebaseAppToken = await FirebaseMessaging.instance.getToken();
|
||||||
|
|
||||||
if (firebaseAppToken != null) {
|
if (firebaseAppToken != null) {
|
||||||
@@ -67,14 +59,11 @@ class MainBloc extends BlocBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> sendNotificationToken(String token) async{
|
Future<int> sendNotificationToken(String token) async {
|
||||||
String uid = await getUID();
|
String uid = await getUID();
|
||||||
Map<String,dynamic> body = {
|
Map<String, dynamic> body = {"user_id": uid, "app_token": token};
|
||||||
"user_id": uid,
|
int statusCode = await NetworkManager.instance!
|
||||||
"app_token": token
|
.updateDataInServer(APIPathConstants.NOTIFICATION_TOKEN_PATH, body);
|
||||||
};
|
|
||||||
int statusCode = await NetworkManager.instance!.updateDataInServer(
|
|
||||||
APIPathConstants.NOTIFICATION_TOKEN_PATH, body);
|
|
||||||
return statusCode;
|
return statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
|
|
||||||
import '../product/services/map_services.dart';
|
import '../product/services/map_services.dart';
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
import '../product/shared/shared_snack_bar.dart';
|
||||||
import '../feature/devices/device_model.dart';
|
import '../feature/devices/device_model.dart';
|
||||||
@@ -75,6 +75,4 @@ class MapBloc extends BlocBase {
|
|||||||
context, "Không tìm thấy đường", Colors.orange, Colors.white);
|
context, "Không tìm thấy đường", Colors.orange, Colors.white);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:sfm_app/product/services/api_services.dart';
|
|
||||||
|
|
||||||
|
import '../product/services/api_services.dart';
|
||||||
import '../feature/settings/profile/profile_model.dart';
|
import '../feature/settings/profile/profile_model.dart';
|
||||||
import '../product/base/bloc/base_bloc.dart';
|
import '../product/base/bloc/base_bloc.dart';
|
||||||
import '../product/shared/shared_snack_bar.dart';
|
|
||||||
|
|
||||||
class SettingsBloc extends BlocBase {
|
class SettingsBloc extends BlocBase {
|
||||||
// Settings Screen
|
// Settings Screen
|
||||||
@@ -14,7 +12,6 @@ class SettingsBloc extends BlocBase {
|
|||||||
StreamSink<User> get sinkUserProfile => userProfile.sink;
|
StreamSink<User> get sinkUserProfile => userProfile.sink;
|
||||||
Stream<User> get streamUserProfile => userProfile.stream;
|
Stream<User> get streamUserProfile => userProfile.stream;
|
||||||
|
|
||||||
|
|
||||||
// Profile Screen
|
// Profile Screen
|
||||||
final isChangeProfileInfomation = StreamController<bool>.broadcast();
|
final isChangeProfileInfomation = StreamController<bool>.broadcast();
|
||||||
StreamSink<bool> get sinkIsChangeProfileInfomation =>
|
StreamSink<bool> get sinkIsChangeProfileInfomation =>
|
||||||
@@ -22,20 +19,13 @@ class SettingsBloc extends BlocBase {
|
|||||||
Stream<bool> get streamIsChangeProfileInfomation =>
|
Stream<bool> get streamIsChangeProfileInfomation =>
|
||||||
isChangeProfileInfomation.stream;
|
isChangeProfileInfomation.stream;
|
||||||
|
|
||||||
|
void getUserProfile(BuildContext context) async {
|
||||||
void getUserProfile(BuildContext context) async {
|
await apiServices.execute(context, () async {
|
||||||
try {
|
|
||||||
User user = await apiServices.getUserDetail();
|
User user = await apiServices.getUserDetail();
|
||||||
sinkUserProfile.add(user);
|
sinkUserProfile.add(user);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sfm_app/product/shared/shared_snack_bar.dart';
|
|
||||||
import '../../product/extension/context_extension.dart';
|
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
import '../../bloc/bell_bloc.dart';
|
import '../../bloc/bell_bloc.dart';
|
||||||
import '../../product/base/bloc/base_bloc.dart';
|
import '../../product/base/bloc/base_bloc.dart';
|
||||||
@@ -77,7 +76,8 @@ class _BellScreenState extends State<BellScreen> {
|
|||||||
if (index < bellSnapshot.data!.length) {
|
if (index < bellSnapshot.data!.length) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
readNotification(bellSnapshot.data![index].id!);
|
readNotification(
|
||||||
|
bellSnapshot.data![index].id!);
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -163,24 +163,18 @@ class _BellScreenState extends State<BellScreen> {
|
|||||||
getBellNotification(offset);
|
getBellNotification(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void readNotification(String id) async{
|
void readNotification(String id) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
List<String> read = [];
|
List<String> read = [];
|
||||||
read.add(id);
|
read.add(id);
|
||||||
await apiServices
|
await apiServices.updateStatusOfNotification(read);
|
||||||
.updateStatusOfNotification(read);
|
|
||||||
read.clear();
|
read.clear();
|
||||||
} catch (e) {
|
});
|
||||||
if (mounted){
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getBellNotification(int offset) async {
|
Future<void> getBellNotification(int offset) async {
|
||||||
try {
|
apiServices.execute(context, () async {
|
||||||
bell = await apiServices.getBellNotifications(
|
bell = await apiServices.getBellNotifications(
|
||||||
offset.toString(), (offset + 20).toString());
|
offset.toString(), (offset + 20).toString());
|
||||||
if (bell.items!.isEmpty) {
|
if (bell.items!.isEmpty) {
|
||||||
@@ -193,10 +187,7 @@ class _BellScreenState extends State<BellScreen> {
|
|||||||
}
|
}
|
||||||
bellBloc.bellItems.add(items);
|
bellBloc.bellItems.add(items);
|
||||||
check = false;
|
check = false;
|
||||||
} catch (e) {
|
});
|
||||||
if (!mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String timeAgo(BuildContext context, DateTime dateTime) {
|
String timeAgo(BuildContext context, DateTime dateTime) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sfm_app/bloc/devices_manager_bloc.dart';
|
|
||||||
import 'package:sfm_app/product/shared/shared_snack_bar.dart';
|
import '../../bloc/devices_manager_bloc.dart';
|
||||||
|
import '../../product/shared/shared_snack_bar.dart';
|
||||||
import '../../product/utils/response_status_utils.dart';
|
import '../../product/utils/response_status_utils.dart';
|
||||||
import '../../product/constant/enums/role_enums.dart';
|
import '../../product/constant/enums/role_enums.dart';
|
||||||
import '../../product/services/api_services.dart';
|
import '../../product/services/api_services.dart';
|
||||||
@@ -11,7 +12,8 @@ import '../../product/constant/icon/icon_constants.dart';
|
|||||||
import '../../product/extension/context_extension.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
|
|
||||||
addNewDevice(BuildContext context, String role, DevicesManagerBloc deviceManagerBloc) async {
|
addNewDevice(BuildContext context, String role,
|
||||||
|
DevicesManagerBloc deviceManagerBloc) async {
|
||||||
TextEditingController extIDController = TextEditingController(text: "");
|
TextEditingController extIDController = TextEditingController(text: "");
|
||||||
TextEditingController deviceNameController = TextEditingController(text: "");
|
TextEditingController deviceNameController = TextEditingController(text: "");
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
@@ -77,7 +79,8 @@ addNewDevice(BuildContext context, String role, DevicesManagerBloc deviceManager
|
|||||||
Colors.white);
|
Colors.white);
|
||||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||||
} else {
|
} else {
|
||||||
addDevices(context, role, extID, deviceName, deviceManagerBloc);
|
addDevices(
|
||||||
|
context, role, extID, deviceName, deviceManagerBloc);
|
||||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -90,12 +93,12 @@ addNewDevice(BuildContext context, String role, DevicesManagerBloc deviceManager
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDevices(
|
void addDevices(BuildContext context, String role, String extID,
|
||||||
BuildContext context, String role, String extID, String deviceName, DevicesManagerBloc deviceManagerBloc) async {
|
String deviceName, DevicesManagerBloc deviceManagerBloc) async {
|
||||||
APIServices apiServices = APIServices();
|
APIServices apiServices = APIServices();
|
||||||
Map<String, dynamic> body = {};
|
Map<String, dynamic> body = {};
|
||||||
if (role == RoleEnums.ADMIN.name) {
|
if (role == RoleEnums.ADMIN.name) {
|
||||||
try {
|
await apiServices.execute(context,() async {
|
||||||
body = {"ext_id": extID, "name": deviceName};
|
body = {"ext_id": extID, "name": deviceName};
|
||||||
int statusCode = await apiServices.createDeviceByAdmin(body);
|
int statusCode = await apiServices.createDeviceByAdmin(body);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
@@ -103,15 +106,10 @@ void addDevices(
|
|||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_create_device_success,
|
appLocalization(context).notification_create_device_success,
|
||||||
appLocalization(context).notification_create_device_failed);
|
appLocalization(context).notification_create_device_failed);
|
||||||
deviceManagerBloc.getDeviceByState(context,-2);
|
deviceManagerBloc.getDeviceByState(context, -2);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
await apiServices.execute(context,() async {
|
||||||
body = {"ext_id": extID};
|
body = {"ext_id": extID};
|
||||||
int statusCode = await apiServices.registerDevice(body);
|
int statusCode = await apiServices.registerDevice(body);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
@@ -119,12 +117,7 @@ void addDevices(
|
|||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_add_device_success,
|
appLocalization(context).notification_add_device_success,
|
||||||
appLocalization(context).notification_device_not_exist);
|
appLocalization(context).notification_device_not_exist);
|
||||||
deviceManagerBloc.getDeviceByState(context,-2);
|
deviceManagerBloc.getDeviceByState(context, -2);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import '../../bloc/devices_manager_bloc.dart';
|
|||||||
import '../../product/constant/enums/role_enums.dart';
|
import '../../product/constant/enums/role_enums.dart';
|
||||||
import '../../product/services/api_services.dart';
|
import '../../product/services/api_services.dart';
|
||||||
import '../../product/services/language_services.dart';
|
import '../../product/services/language_services.dart';
|
||||||
import '../../product/shared/shared_snack_bar.dart';
|
|
||||||
import '../../product/utils/response_status_utils.dart';
|
import '../../product/utils/response_status_utils.dart';
|
||||||
|
|
||||||
handleDeleteDevice(BuildContext context, DevicesManagerBloc devicesManagerBloc,
|
handleDeleteDevice(BuildContext context, DevicesManagerBloc devicesManagerBloc,
|
||||||
@@ -48,27 +47,24 @@ deleteOrUnregisterDevice(BuildContext context, DevicesManagerBloc devicesBloc,
|
|||||||
Map<String, dynamic> body = {
|
Map<String, dynamic> body = {
|
||||||
"ext_id": extID,
|
"ext_id": extID,
|
||||||
};
|
};
|
||||||
int statusCode = await apiServices.unregisterDevice(body);
|
await apiServices.execute(context, () async {
|
||||||
showSnackBarResponseByStatusCode(
|
int statusCode = await apiServices.unregisterDevice(body);
|
||||||
context,
|
showSnackBarResponseByStatusCode(
|
||||||
statusCode,
|
context,
|
||||||
appLocalization(context).notification_delete_device_success,
|
statusCode,
|
||||||
appLocalization(context).notification_delete_device_failed);
|
appLocalization(context).notification_delete_device_success,
|
||||||
devicesBloc.getDeviceByState(context,-2);
|
appLocalization(context).notification_delete_device_failed);
|
||||||
|
devicesBloc.getDeviceByState(context, -2);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.deleteDeviceByAdmin(extID);
|
int statusCode = await apiServices.deleteDeviceByAdmin(extID);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
context,
|
context,
|
||||||
statusCode,
|
statusCode,
|
||||||
appLocalization(context).notification_delete_device_success,
|
appLocalization(context).notification_delete_device_success,
|
||||||
appLocalization(context).notification_delete_device_failed);
|
appLocalization(context).notification_delete_device_failed);
|
||||||
devicesBloc.getDeviceByState(context,-2);
|
devicesBloc.getDeviceByState(context, -2);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
|
||||||
|
|
||||||
import '../../product/shared/shared_component_loading_animation.dart';
|
import '../../product/shared/shared_component_loading_animation.dart';
|
||||||
import '../../product/shared/shared_loading_animation.dart';
|
import '../../product/utils/app_logger_utils.dart';
|
||||||
import '../../product/shared/shared_snack_bar.dart';
|
|
||||||
import 'shared/alert_card.dart';
|
import 'shared/alert_card.dart';
|
||||||
import 'shared/warning_card.dart';
|
import 'shared/warning_card.dart';
|
||||||
import '../../product/utils/device_utils.dart';
|
import '../../product/utils/device_utils.dart';
|
||||||
@@ -19,8 +18,8 @@ import '../../bloc/home_bloc.dart';
|
|||||||
import '../../product/base/bloc/base_bloc.dart';
|
import '../../product/base/bloc/base_bloc.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
const HomeScreen({super.key});
|
const HomeScreen({super.key, required this.persistentTabController});
|
||||||
|
final PersistentTabController persistentTabController;
|
||||||
@override
|
@override
|
||||||
State<HomeScreen> createState() => _HomeScreenState();
|
State<HomeScreen> createState() => _HomeScreenState();
|
||||||
}
|
}
|
||||||
@@ -29,7 +28,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
late HomeBloc homeBloc;
|
late HomeBloc homeBloc;
|
||||||
APIServices apiServices = APIServices();
|
APIServices apiServices = APIServices();
|
||||||
Map<String, List<DeviceWithAlias>> allDevicesAliasMap = {};
|
Map<String, List<DeviceWithAlias>> allDevicesAliasMap = {};
|
||||||
Map<String, List<DeviceWithAlias>> allDevicesAliasJoinedMap = {};
|
|
||||||
List<DeviceWithAlias> devices = [];
|
List<DeviceWithAlias> devices = [];
|
||||||
bool isFunctionCall = false;
|
bool isFunctionCall = false;
|
||||||
Timer? getAllDevicesTimer;
|
Timer? getAllDevicesTimer;
|
||||||
@@ -41,6 +39,8 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
homeBloc = BlocProvider.of(context);
|
homeBloc = BlocProvider.of(context);
|
||||||
|
getAllDevicesTimer?.cancel();
|
||||||
|
AppLoggerUtils.debug("Init State HomeScreen");
|
||||||
getOwnerAndJoinedDevices();
|
getOwnerAndJoinedDevices();
|
||||||
const duration = Duration(seconds: 10);
|
const duration = Duration(seconds: 10);
|
||||||
getAllDevicesTimer =
|
getAllDevicesTimer =
|
||||||
@@ -50,6 +50,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
getAllDevicesTimer?.cancel();
|
getAllDevicesTimer?.cancel();
|
||||||
|
homeBloc.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,107 +199,23 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
StreamBuilder<bool?>(
|
StreamBuilder<Map<String, List<DeviceWithAlias>>>(
|
||||||
stream: homeBloc.streamHasJoinedDevice,
|
stream: homeBloc.streamAllDevicesAliasMap,
|
||||||
initialData: null,
|
builder: (context, allDevicesAliasMapSnapshot) {
|
||||||
builder: (context, hasJoinedDeviceSnapshot) {
|
if(allDevicesAliasMapSnapshot.data == null){
|
||||||
return StreamBuilder<Map<String, List<DeviceWithAlias>>>(
|
return const SharedComponentLoadingAnimation();
|
||||||
stream: homeBloc.streamAllDevicesAliasMap,
|
}else{
|
||||||
builder: (context, allDevicesAliasMapSnapshot) {
|
final data = allDevicesAliasMapSnapshot.data!;
|
||||||
return StreamBuilder<Map<String, List<DeviceWithAlias>>>(
|
return OverviewCard(
|
||||||
stream: homeBloc.streamAllDevicesAliasJoinedMap,
|
isOwner: true,
|
||||||
builder: (context, allDevicesAliasJoinedMapSnapshot) {
|
total: data['all']?.length ?? 0,
|
||||||
if (hasJoinedDeviceSnapshot.data == null) {
|
active: data['online']?.length ?? 0,
|
||||||
return const SharedComponentLoadingAnimation();
|
inactive: data['offline']?.length ?? 0,
|
||||||
} else {
|
warning: data['warn']?.length ?? 0,
|
||||||
final data = allDevicesAliasMapSnapshot.data!;
|
unused: data['not-use']?.length ?? 0,
|
||||||
final dataJoined =
|
showUnused: false,
|
||||||
allDevicesAliasJoinedMapSnapshot.data!;
|
);
|
||||||
if (hasJoinedDeviceSnapshot.data == false) {
|
}
|
||||||
if (!allDevicesAliasMapSnapshot.hasData ||
|
|
||||||
allDevicesAliasMapSnapshot.data == null) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
|
|
||||||
return OverviewCard(
|
|
||||||
isOwner: true,
|
|
||||||
total: data['all']?.length ?? 0,
|
|
||||||
active: data['online']?.length ?? 0,
|
|
||||||
inactive: data['offline']?.length ?? 0,
|
|
||||||
warning: data['warn']?.length ?? 0,
|
|
||||||
unused: data['not-use']?.length ?? 0,
|
|
||||||
showUnused: false,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return DefaultTabController(
|
|
||||||
length: 2,
|
|
||||||
child: Column(
|
|
||||||
// mainAxisSize: MainAxisSize.min,
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
TabBar(
|
|
||||||
tabs: [
|
|
||||||
Tab(
|
|
||||||
text: appLocalization(context)
|
|
||||||
.over_view_owner_devices),
|
|
||||||
Tab(
|
|
||||||
text: appLocalization(context)
|
|
||||||
.over_view_joined_devices),
|
|
||||||
],
|
|
||||||
labelColor: Colors.blue,
|
|
||||||
unselectedLabelColor: Colors.grey,
|
|
||||||
indicatorColor: Colors.blue,
|
|
||||||
),
|
|
||||||
ConstrainedBox(
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
maxHeight: context.dynamicHeight(0.5),
|
|
||||||
minHeight: context.dynamicHeight(0.3),
|
|
||||||
),
|
|
||||||
child: TabBarView(
|
|
||||||
children: [
|
|
||||||
OverviewCard(
|
|
||||||
isOwner: true,
|
|
||||||
total: data['all']?.length ?? 0,
|
|
||||||
active: data['online']?.length ?? 0,
|
|
||||||
inactive:
|
|
||||||
data['offline']?.length ?? 0,
|
|
||||||
warning: data['warn']?.length ?? 0,
|
|
||||||
unused:
|
|
||||||
data['not-use']?.length ?? 0,
|
|
||||||
showUnused: false,
|
|
||||||
),
|
|
||||||
OverviewCard(
|
|
||||||
isOwner: false,
|
|
||||||
total:
|
|
||||||
dataJoined['all']?.length ?? 0,
|
|
||||||
active:
|
|
||||||
dataJoined['online']?.length ??
|
|
||||||
0,
|
|
||||||
inactive:
|
|
||||||
dataJoined['offline']?.length ??
|
|
||||||
0,
|
|
||||||
warning:
|
|
||||||
dataJoined['warn']?.length ?? 0,
|
|
||||||
unused:
|
|
||||||
dataJoined['not-use']?.length ??
|
|
||||||
0,
|
|
||||||
showUnused: false,
|
|
||||||
showActive: false,
|
|
||||||
showInactive: false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -309,8 +226,8 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void getOwnerAndJoinedDevices() async {
|
void getOwnerAndJoinedDevices() async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
devices = await apiServices.getDashBoardDevices();
|
devices = await apiServices.getDashBoardDevices().handleApiError();
|
||||||
List<DeviceWithAlias> publicDevices = [];
|
List<DeviceWithAlias> publicDevices = [];
|
||||||
for (var device in devices) {
|
for (var device in devices) {
|
||||||
if (device.visibility == "PUBLIC") {
|
if (device.visibility == "PUBLIC") {
|
||||||
@@ -320,10 +237,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
getOwnerDeviceState(publicDevices);
|
getOwnerDeviceState(publicDevices);
|
||||||
checkSettingDevice(publicDevices);
|
checkSettingDevice(publicDevices);
|
||||||
getDeviceStatusAliasMap(publicDevices);
|
getDeviceStatusAliasMap(publicDevices);
|
||||||
} catch (e) {
|
});
|
||||||
if (!mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void getOwnerDeviceState(List<DeviceWithAlias> allDevices) async {
|
void getOwnerDeviceState(List<DeviceWithAlias> allDevices) async {
|
||||||
@@ -335,7 +249,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (var device in allDevices) {
|
for (var device in allDevices) {
|
||||||
if (device.isOwner != true) continue;
|
// if (device.isOwner != true) continue;
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Map<String, dynamic> sensorMap = DeviceUtils.instance
|
Map<String, dynamic> sensorMap = DeviceUtils.instance
|
||||||
@@ -368,55 +282,34 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
|
|
||||||
void getDeviceStatusAliasMap(List<DeviceWithAlias> devices) {
|
void getDeviceStatusAliasMap(List<DeviceWithAlias> devices) {
|
||||||
allDevicesAliasMap.clear();
|
allDevicesAliasMap.clear();
|
||||||
allDevicesAliasJoinedMap.clear();
|
|
||||||
bool check = false;
|
|
||||||
for (var key in ['all', 'online', 'offline', 'warning', 'not-use']) {
|
for (var key in ['all', 'online', 'offline', 'warning', 'not-use']) {
|
||||||
allDevicesAliasMap[key] = [];
|
allDevicesAliasMap[key] = [];
|
||||||
allDevicesAliasJoinedMap[key] = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DeviceWithAlias device in devices) {
|
for (DeviceWithAlias device in devices) {
|
||||||
if (device.isOwner == true) {
|
allDevicesAliasMap['all']!.add(device);
|
||||||
allDevicesAliasMap['all']!.add(device);
|
if (device.state == 0 || device.state == 1) {
|
||||||
if (device.state == 0 || device.state == 1) {
|
allDevicesAliasMap['online']!.add(device);
|
||||||
allDevicesAliasMap['online']!.add(device);
|
|
||||||
}
|
|
||||||
if (device.state == -1) {
|
|
||||||
allDevicesAliasMap['offline']!.add(device);
|
|
||||||
}
|
|
||||||
if (device.state == 1) {
|
|
||||||
allDevicesAliasMap['warning']!.add(device);
|
|
||||||
}
|
|
||||||
if (device.state == -2) {
|
|
||||||
allDevicesAliasMap['not-use']!.add(device);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
check = true;
|
|
||||||
allDevicesAliasJoinedMap['all']!.add(device);
|
|
||||||
if (device.state == 0 || device.state == 1) {
|
|
||||||
allDevicesAliasJoinedMap['online']!.add(device);
|
|
||||||
}
|
|
||||||
if (device.state == -1) {
|
|
||||||
allDevicesAliasJoinedMap['offline']!.add(device);
|
|
||||||
}
|
|
||||||
if (device.state == 1) {
|
|
||||||
allDevicesAliasJoinedMap['warning']!.add(device);
|
|
||||||
}
|
|
||||||
if (device.state == -2) {
|
|
||||||
allDevicesAliasJoinedMap['not-use']!.add(device);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (device.state == -1) {
|
||||||
|
allDevicesAliasMap['offline']!.add(device);
|
||||||
|
}
|
||||||
|
if (device.state == 1) {
|
||||||
|
allDevicesAliasMap['warning']!.add(device);
|
||||||
|
}
|
||||||
|
if (device.state == -2) {
|
||||||
|
allDevicesAliasMap['not-use']!.add(device);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
homeBloc.sinkHasJoinedDevice.add(check);
|
|
||||||
homeBloc.sinkAllDevicesAliasMap.add(allDevicesAliasMap);
|
homeBloc.sinkAllDevicesAliasMap.add(allDevicesAliasMap);
|
||||||
homeBloc.sinkAllDevicesAliasJoinedMap.add(allDevicesAliasJoinedMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkSettingDevice(List<DeviceWithAlias> devices) async {
|
void checkSettingDevice(List<DeviceWithAlias> devices) async {
|
||||||
try {
|
if (isFunctionCall) {
|
||||||
if (isFunctionCall) {
|
log("Ham check setting da duoc goi");
|
||||||
log("Ham check setting da duoc goi");
|
} else {
|
||||||
} else {
|
await apiServices.execute(context, () async {
|
||||||
List<DeviceNotificationSettings> list =
|
List<DeviceNotificationSettings> list =
|
||||||
await apiServices.getAllSettingsNotificationOfDevices();
|
await apiServices.getAllSettingsNotificationOfDevices();
|
||||||
// log("List: $list");
|
// log("List: $list");
|
||||||
@@ -425,24 +318,16 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
for (var device in devices) {
|
for (var device in devices) {
|
||||||
if (!thingIdsInList.contains(device.thingId)) {
|
if (!thingIdsInList.contains(device.thingId)) {
|
||||||
log("Device with Thing ID ${device.thingId} is not in the notification settings list.");
|
log("Device with Thing ID ${device.thingId} is not in the notification settings list.");
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
await apiServices.setupDeviceNotification(
|
await apiServices.setupDeviceNotification(
|
||||||
device.thingId!, device.name!);
|
device.thingId!, device.name!);
|
||||||
} catch (e) {
|
});
|
||||||
if (!mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log("All devices are in the notification settings list.");
|
log("All devices are in the notification settings list.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
isFunctionCall = true;
|
|
||||||
} catch (e) {
|
|
||||||
if (!mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
}
|
||||||
|
isFunctionCall = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:sfm_app/feature/home/device_alias_model.dart';
|
import '../../../product/shared/shared_rocket_container.dart';
|
||||||
import '../../../product/constant/enums/app_route_enums.dart';
|
import '../../../product/constant/enums/app_route_enums.dart';
|
||||||
import '../../../product/constant/image/image_constants.dart';
|
import '../../../product/constant/image/image_constants.dart';
|
||||||
import '../../../product/extension/context_extension.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
@@ -11,16 +11,16 @@ import '../../../product/services/language_services.dart';
|
|||||||
import '../../../product/utils/device_utils.dart';
|
import '../../../product/utils/device_utils.dart';
|
||||||
|
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
|
import '../device_alias_model.dart';
|
||||||
|
|
||||||
Future<Widget> notificationCard(BuildContext context, String notiticationType,
|
Future<Widget> notificationCard(BuildContext context, String notificationType,
|
||||||
String notificationTitle, DeviceWithAlias device) async {
|
String notificationTitle, DeviceWithAlias device) async {
|
||||||
String location = "";
|
String location = "";
|
||||||
if (device.areaPath != "") {
|
if (device.areaPath != "") {
|
||||||
location = await DeviceUtils.instance
|
location = await DeviceUtils.instance
|
||||||
.getFullDeviceLocation(context, device.areaPath!,"");
|
.getFullDeviceLocation(context, device.areaPath!, "");
|
||||||
}
|
}
|
||||||
String path = "";
|
String path = "";
|
||||||
// DateTime time = DateTime.now();
|
|
||||||
String time = "";
|
String time = "";
|
||||||
for (var sensor in device.status!.sensors!) {
|
for (var sensor in device.status!.sensors!) {
|
||||||
if (sensor.name! == "7") {
|
if (sensor.name! == "7") {
|
||||||
@@ -29,7 +29,7 @@ Future<Widget> notificationCard(BuildContext context, String notiticationType,
|
|||||||
time = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime);
|
time = DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (notiticationType == "lowBattery") {
|
if (notificationType == "lowBattery") {
|
||||||
path = ImageConstants.instance.getImage("low_battery");
|
path = ImageConstants.instance.getImage("low_battery");
|
||||||
}
|
}
|
||||||
return Card(
|
return Card(
|
||||||
@@ -117,24 +117,57 @@ Future<Widget> notificationCard(BuildContext context, String notiticationType,
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Align(
|
device.isOwner!
|
||||||
alignment: Alignment.centerRight,
|
? Align(
|
||||||
child: OutlinedButton(
|
alignment: Alignment.centerRight,
|
||||||
style: const ButtonStyle(
|
child: OutlinedButton(
|
||||||
backgroundColor: WidgetStatePropertyAll(Colors.blueAccent),
|
style: const ButtonStyle(
|
||||||
),
|
backgroundColor:
|
||||||
onPressed: () {
|
WidgetStatePropertyAll(Colors.blueAccent),
|
||||||
context.pushNamed(AppRoutes.DEVICE_DETAIL.name,
|
),
|
||||||
pathParameters: {'thingID': device.thingId!});
|
onPressed: () {
|
||||||
},
|
context.pushNamed(AppRoutes.DEVICE_DETAIL.name,
|
||||||
child: Text(
|
pathParameters: {'thingID': device.thingId!});
|
||||||
appLocalization(context).detail_message,
|
},
|
||||||
style: const TextStyle(
|
child: Text(
|
||||||
color: Colors.white,
|
appLocalization(context).detail_message,
|
||||||
|
style: const TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
ClipPath(
|
||||||
|
clipper: SharedRocketContainer(),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(context.lowValue),
|
||||||
|
height: context.mediumValue,
|
||||||
|
width: context.dynamicWidth(0.22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green[300],
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
appLocalization(context).interfamily_page_name,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
OutlinedButton(
|
||||||
|
style: const ButtonStyle(
|
||||||
|
backgroundColor:
|
||||||
|
WidgetStatePropertyAll(Colors.blueAccent),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
context.pushNamed(AppRoutes.DEVICE_DETAIL.name,
|
||||||
|
pathParameters: {'thingID': device.thingId!});
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
appLocalization(context).detail_message,
|
||||||
|
style: const TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:maps_launcher/maps_launcher.dart';
|
import 'package:maps_launcher/maps_launcher.dart';
|
||||||
import 'package:badges/badges.dart' as badges;
|
import 'package:badges/badges.dart' as badges;
|
||||||
|
|
||||||
|
import '../../../product/shared/shared_rocket_container.dart';
|
||||||
import '../device_alias_model.dart';
|
import '../device_alias_model.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/constant/image/image_constants.dart';
|
import '../../../product/constant/image/image_constants.dart';
|
||||||
@@ -21,7 +23,7 @@ Future<Widget> warningCard(BuildContext context, APIServices apiServices,
|
|||||||
String fullLocation = "";
|
String fullLocation = "";
|
||||||
if (device.areaPath != "") {
|
if (device.areaPath != "") {
|
||||||
fullLocation = await DeviceUtils.instance
|
fullLocation = await DeviceUtils.instance
|
||||||
.getFullDeviceLocation(context, device.areaPath!,"");
|
.getFullDeviceLocation(context, device.areaPath!, "");
|
||||||
}
|
}
|
||||||
String time = "";
|
String time = "";
|
||||||
for (var sensor in device.status!.sensors!) {
|
for (var sensor in device.status!.sensors!) {
|
||||||
@@ -187,84 +189,185 @@ Future<Widget> warningCard(BuildContext context, APIServices apiServices,
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: context.mediumValue),
|
SizedBox(width: context.mediumValue),
|
||||||
Expanded(
|
device.isOwner!
|
||||||
child: Align(
|
? Expanded(
|
||||||
alignment: Alignment.centerRight,
|
child: Align(
|
||||||
child: OutlinedButton(
|
alignment: Alignment.centerRight,
|
||||||
style: ButtonStyle(
|
child: OutlinedButton(
|
||||||
backgroundColor:
|
style: ButtonStyle(
|
||||||
WidgetStatePropertyAll(backgroundColor)),
|
backgroundColor:
|
||||||
onPressed: () async {
|
WidgetStatePropertyAll(backgroundColor)),
|
||||||
if (message ==
|
onPressed: () async {
|
||||||
appLocalization(context).button_fake_fire_message) {
|
if (message ==
|
||||||
await showDialog(
|
appLocalization(context)
|
||||||
context: context,
|
.button_fake_fire_message) {
|
||||||
builder: (context) => AlertDialog(
|
await showDialog(
|
||||||
icon: const Icon(Icons.warning),
|
context: context,
|
||||||
iconColor: Colors.red,
|
builder: (context) => AlertDialog(
|
||||||
title: Text(appLocalization(context)
|
icon: const Icon(Icons.warning),
|
||||||
.confirm_fake_fire_message),
|
iconColor: Colors.red,
|
||||||
content: Text(appLocalization(context)
|
title: Text(appLocalization(context)
|
||||||
.confirm_fake_fire_body),
|
.confirm_fake_fire_message),
|
||||||
actions: [
|
content: Text(appLocalization(context)
|
||||||
TextButton(
|
.confirm_fake_fire_body),
|
||||||
onPressed: () async {
|
actions: [
|
||||||
try {
|
TextButton(
|
||||||
int statusCode = await apiServices
|
onPressed: () async {
|
||||||
.confirmFakeFireByUser(device.thingId!);
|
await apiServices.execute(context,
|
||||||
if (statusCode == 200) {
|
() async {
|
||||||
showNoIconTopSnackBar(
|
int statusCode = await apiServices
|
||||||
context,
|
.confirmFakeFireByUser(
|
||||||
|
device.thingId!);
|
||||||
|
if (statusCode == 200) {
|
||||||
|
showNoIconTopSnackBar(
|
||||||
|
context,
|
||||||
|
appLocalization(context)
|
||||||
|
.notification_confirm_fake_fire_success,
|
||||||
|
Colors.green,
|
||||||
|
Colors.white);
|
||||||
|
} else {
|
||||||
|
showNoIconTopSnackBar(
|
||||||
|
context,
|
||||||
|
appLocalization(context)
|
||||||
|
.notification_confirm_fake_fire_failed,
|
||||||
|
Colors.red,
|
||||||
|
Colors.red);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
appLocalization(context)
|
appLocalization(context)
|
||||||
.notification_confirm_fake_fire_success,
|
.confirm_fake_fire_sure_message,
|
||||||
Colors.green,
|
style: const TextStyle(
|
||||||
Colors.white);
|
color: Colors.red)),
|
||||||
} else {
|
),
|
||||||
showNoIconTopSnackBar(
|
TextButton(
|
||||||
context,
|
onPressed: () {
|
||||||
appLocalization(context)
|
Navigator.of(context).pop();
|
||||||
.notification_confirm_fake_fire_failed,
|
},
|
||||||
Colors.red,
|
child: Text(appLocalization(context)
|
||||||
Colors.red);
|
.cancel_button_content),
|
||||||
}
|
),
|
||||||
} catch (e) {
|
],
|
||||||
if (!context.mounted) return;
|
),
|
||||||
showErrorTopSnackBarCustom(
|
);
|
||||||
context, e.toString());
|
} else {
|
||||||
}
|
showNoIconTopSnackBar(
|
||||||
Navigator.of(context).pop();
|
context,
|
||||||
},
|
appLocalization(context)
|
||||||
child: Text(
|
.let_PCCC_handle_message,
|
||||||
appLocalization(context)
|
Colors.orange,
|
||||||
.confirm_fake_fire_sure_message,
|
Colors.white);
|
||||||
style:
|
}
|
||||||
const TextStyle(color: Colors.red)),
|
},
|
||||||
),
|
child: Text(
|
||||||
TextButton(
|
message,
|
||||||
onPressed: () {
|
style: TextStyle(color: textColor),
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
child: Text(appLocalization(context)
|
|
||||||
.cancel_button_content),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
} else {
|
),
|
||||||
showNoIconTopSnackBar(
|
)
|
||||||
context,
|
: Row(
|
||||||
appLocalization(context).let_PCCC_handle_message,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
Colors.orange,
|
children: [
|
||||||
Colors.white);
|
ClipPath(
|
||||||
}
|
clipper: SharedRocketContainer(),
|
||||||
},
|
child: Container(
|
||||||
child: Text(
|
padding: EdgeInsets.all(context.lowValue),
|
||||||
message,
|
height: context.mediumValue,
|
||||||
style: TextStyle(color: textColor),
|
width: context.dynamicWidth(0.22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green[300],
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
appLocalization(context).interfamily_page_name,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: OutlinedButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
|
backgroundColor)),
|
||||||
|
onPressed: () async {
|
||||||
|
if (message ==
|
||||||
|
appLocalization(context)
|
||||||
|
.button_fake_fire_message) {
|
||||||
|
await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
icon: const Icon(Icons.warning),
|
||||||
|
iconColor: Colors.red,
|
||||||
|
title: Text(appLocalization(context)
|
||||||
|
.confirm_fake_fire_message),
|
||||||
|
content: Text(appLocalization(context)
|
||||||
|
.confirm_fake_fire_body),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await apiServices.execute(context,
|
||||||
|
() async {
|
||||||
|
int statusCode =
|
||||||
|
await apiServices
|
||||||
|
.confirmFakeFireByUser(
|
||||||
|
device.thingId!);
|
||||||
|
if (statusCode == 200) {
|
||||||
|
showNoIconTopSnackBar(
|
||||||
|
context,
|
||||||
|
appLocalization(context)
|
||||||
|
.notification_confirm_fake_fire_success,
|
||||||
|
Colors.green,
|
||||||
|
Colors.white);
|
||||||
|
} else {
|
||||||
|
showNoIconTopSnackBar(
|
||||||
|
context,
|
||||||
|
appLocalization(context)
|
||||||
|
.notification_confirm_fake_fire_failed,
|
||||||
|
Colors.red,
|
||||||
|
Colors.red);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
appLocalization(context)
|
||||||
|
.confirm_fake_fire_sure_message,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.red)),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(appLocalization(context)
|
||||||
|
.cancel_button_content),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
showNoIconTopSnackBar(
|
||||||
|
context,
|
||||||
|
appLocalization(context)
|
||||||
|
.let_PCCC_handle_message,
|
||||||
|
Colors.orange,
|
||||||
|
Colors.white);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
message,
|
||||||
|
style: TextStyle(color: textColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../../../bloc/group_detail_bloc.dart';
|
import '../../../bloc/group_detail_bloc.dart';
|
||||||
import '../../../product/shared/shared_loading_animation.dart';
|
import '../../../product/shared/shared_loading_animation.dart';
|
||||||
import '../../../product/shared/shared_snack_bar.dart';
|
|
||||||
import 'group_detail_model.dart';
|
import 'group_detail_model.dart';
|
||||||
import '../../../product/base/bloc/base_bloc.dart';
|
import '../../../product/base/bloc/base_bloc.dart';
|
||||||
import '../../../product/constant/app/app_constants.dart';
|
import '../../../product/constant/app/app_constants.dart';
|
||||||
@@ -325,7 +324,7 @@ class _DetailGroupScreenState extends State<DetailGroupScreen> {
|
|||||||
Future.delayed(context.lowDuration).then(
|
Future.delayed(context.lowDuration).then(
|
||||||
(value) => Navigator.pop(context),
|
(value) => Navigator.pop(context),
|
||||||
);
|
);
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices
|
int statusCode = await apiServices
|
||||||
.deleteGroup(widget.group);
|
.deleteGroup(widget.group);
|
||||||
showSnackBarResponseByStatusCode(
|
showSnackBarResponseByStatusCode(
|
||||||
@@ -335,11 +334,7 @@ class _DetailGroupScreenState extends State<DetailGroupScreen> {
|
|||||||
.notification_delete_group_success,
|
.notification_delete_group_success,
|
||||||
appLocalization(context)
|
appLocalization(context)
|
||||||
.notification_delete_group_failed);
|
.notification_delete_group_failed);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
appLocalization(context)
|
appLocalization(context)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class _GroupsScreenState extends State<GroupsScreen> {
|
|||||||
const duration = Duration(seconds: 5);
|
const duration = Duration(seconds: 5);
|
||||||
getAllGroupsTimer = Timer.periodic(
|
getAllGroupsTimer = Timer.periodic(
|
||||||
duration,
|
duration,
|
||||||
(Timer t) => interFamilyBloc.getAllGroup(widget.role),
|
(Timer t) => interFamilyBloc.getAllGroup(context, widget.role),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ class _GroupsScreenState extends State<GroupsScreen> {
|
|||||||
stream: interFamilyBloc.streamCurrentGroups,
|
stream: interFamilyBloc.streamCurrentGroups,
|
||||||
builder: (context, groupsSnapshot) {
|
builder: (context, groupsSnapshot) {
|
||||||
if (groupsSnapshot.data == null) {
|
if (groupsSnapshot.data == null) {
|
||||||
interFamilyBloc.getAllGroup(widget.role);
|
interFamilyBloc.getAllGroup(context,widget.role);
|
||||||
return const SharedLoadingAnimation();
|
return const SharedLoadingAnimation();
|
||||||
} else if (groupsSnapshot.data!.isEmpty) {
|
} else if (groupsSnapshot.data!.isEmpty) {
|
||||||
return Center(
|
return Center(
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
|
|
||||||
import '../../../bloc/inter_family_bloc.dart';
|
import '../../../bloc/inter_family_bloc.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/extension/context_extension.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
import 'groups_model.dart';
|
import 'groups_model.dart';
|
||||||
|
|
||||||
shareGroup(BuildContext context, Group group) {
|
shareGroup(BuildContext context, Group group) {
|
||||||
@@ -80,7 +80,8 @@ showActionDialog(
|
|||||||
if (dialogTitle == appLocalization(context).delete_group_title) {
|
if (dialogTitle == appLocalization(context).delete_group_title) {
|
||||||
Navigator.of(dialogContext).pop();
|
Navigator.of(dialogContext).pop();
|
||||||
await interFamilyBloc.deleteGroup(context, group.id!);
|
await interFamilyBloc.deleteGroup(context, group.id!);
|
||||||
interFamilyBloc.getAllGroup(role);
|
// ignore: use_build_context_synchronously
|
||||||
|
interFamilyBloc.getAllGroup(context,role);
|
||||||
} else {}
|
} else {}
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ createOrJoinGroupDialog(
|
|||||||
try {
|
try {
|
||||||
await interFamilyBloc.createGroup(
|
await interFamilyBloc.createGroup(
|
||||||
context, groupName, description);
|
context, groupName, description);
|
||||||
interFamilyBloc.getAllGroup(role);
|
interFamilyBloc.getAllGroup(context, role);
|
||||||
Navigator.of(dialogContext).pop();
|
Navigator.of(dialogContext).pop();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// log("Lỗi khi tạo nhóm: $e");
|
// log("Lỗi khi tạo nhóm: $e");
|
||||||
@@ -133,7 +133,7 @@ createOrJoinGroupDialog(
|
|||||||
try {
|
try {
|
||||||
await interFamilyBloc.changeGroupInformation(
|
await interFamilyBloc.changeGroupInformation(
|
||||||
context, groupID, groupName, description);
|
context, groupID, groupName, description);
|
||||||
interFamilyBloc.getAllGroup(role);
|
interFamilyBloc.getAllGroup(context, role);
|
||||||
Navigator.of(dialogContext).pop();
|
Navigator.of(dialogContext).pop();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// log("Lỗi khi sửa nhóm: $e");
|
// log("Lỗi khi sửa nhóm: $e");
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -10,16 +8,14 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:badges/badges.dart' as badges;
|
import 'package:badges/badges.dart' as badges;
|
||||||
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
|
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
|
||||||
import 'package:sfm_app/product/shared/shared_snack_bar.dart';
|
|
||||||
import 'package:sfm_app/product/utils/permission_handler.dart';
|
import '../../product/utils/permission_handler.dart';
|
||||||
import '../../product/permission/notification_permission.dart';
|
import '../../product/permission/notification_permission.dart';
|
||||||
import '../../product/services/notification_services.dart';
|
|
||||||
import '../settings/profile/profile_model.dart';
|
import '../settings/profile/profile_model.dart';
|
||||||
import '../../product/extension/context_extension.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
import '../../bloc/home_bloc.dart';
|
import '../../bloc/home_bloc.dart';
|
||||||
import '../../product/constant/app/app_constants.dart';
|
import '../../product/constant/app/app_constants.dart';
|
||||||
import '../../product/constant/enums/app_route_enums.dart';
|
import '../../product/constant/enums/app_route_enums.dart';
|
||||||
import '../../product/permission/location_permission.dart';
|
|
||||||
import '../../product/services/theme_services.dart';
|
import '../../product/services/theme_services.dart';
|
||||||
import '../../bloc/devices_manager_bloc.dart';
|
import '../../bloc/devices_manager_bloc.dart';
|
||||||
import '../devices/devices_manager_screen.dart';
|
import '../devices/devices_manager_screen.dart';
|
||||||
@@ -47,8 +43,6 @@ class MainScreen extends StatefulWidget {
|
|||||||
State<MainScreen> createState() => _MainScreenState();
|
State<MainScreen> createState() => _MainScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistentTabController controller = PersistentTabController(initialIndex: 0);
|
|
||||||
|
|
||||||
// @pragma('vm:entry-point')
|
// @pragma('vm:entry-point')
|
||||||
// Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
// Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||||
// log("Full background message payload: ${message.toMap()}");
|
// log("Full background message payload: ${message.toMap()}");
|
||||||
@@ -59,8 +53,8 @@ PersistentTabController controller = PersistentTabController(initialIndex: 0);
|
|||||||
// log("Background message handled: ${message.data['title']}");
|
// log("Background message handled: ${message.data['title']}");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
||||||
|
PersistentTabController controller = PersistentTabController(initialIndex: 0);
|
||||||
APIServices apiServices = APIServices();
|
APIServices apiServices = APIServices();
|
||||||
// final NotificationServices notificationServices = NotificationServices();
|
// final NotificationServices notificationServices = NotificationServices();
|
||||||
late MainBloc mainBloc;
|
late MainBloc mainBloc;
|
||||||
@@ -112,17 +106,19 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
|||||||
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||||
RemoteNotification? notification = message.notification;
|
RemoteNotification? notification = message.notification;
|
||||||
AndroidNotification? android = message.notification?.android;
|
AndroidNotification? android = message.notification?.android;
|
||||||
if (notification != null && android != null ) {
|
if (notification != null && android != null) {
|
||||||
const AndroidNotificationDetails androidPlatformChannelSpecifics =
|
const AndroidNotificationDetails androidPlatformChannelSpecifics =
|
||||||
AndroidNotificationDetails(
|
AndroidNotificationDetails('your channel id', 'your channel name',
|
||||||
'your channel id', 'your channel name',
|
importance: Importance.max,
|
||||||
importance: Importance.max,
|
priority: Priority.high,
|
||||||
priority: Priority.high,
|
ticker: 'ticker');
|
||||||
ticker: 'ticker');
|
|
||||||
const NotificationDetails platformChannelSpecifics =
|
const NotificationDetails platformChannelSpecifics =
|
||||||
NotificationDetails(android: androidPlatformChannelSpecifics);
|
NotificationDetails(android: androidPlatformChannelSpecifics);
|
||||||
flutterLocalNotificationsPlugin.show(
|
flutterLocalNotificationsPlugin.show(
|
||||||
notification.hashCode, notification.title, notification.body, platformChannelSpecifics,
|
notification.hashCode,
|
||||||
|
notification.title,
|
||||||
|
notification.body,
|
||||||
|
platformChannelSpecifics,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -151,7 +147,6 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
|||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<PersistentBottomNavBarItem> _navBarsItems() {
|
List<PersistentBottomNavBarItem> _navBarsItems() {
|
||||||
return [
|
return [
|
||||||
PersistentBottomNavBarItem(
|
PersistentBottomNavBarItem(
|
||||||
@@ -200,7 +195,9 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
|||||||
List<Widget> _buildScreens() {
|
List<Widget> _buildScreens() {
|
||||||
return [
|
return [
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
child: const HomeScreen(),
|
child: HomeScreen(
|
||||||
|
persistentTabController: controller,
|
||||||
|
),
|
||||||
blocBuilder: () => HomeBloc(),
|
blocBuilder: () => HomeBloc(),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
@@ -238,7 +235,7 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: context.lowValue,
|
width: context.lowValue,
|
||||||
),
|
),
|
||||||
Flexible( child: Text(userSnapshot.data?.name ?? ""))
|
Flexible(child: Text(userSnapshot.data?.name ?? ""))
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
@@ -404,12 +401,10 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getBellNotification() async {
|
Future<void> getBellNotification() async {
|
||||||
try{
|
await apiServices.execute(context, () async {
|
||||||
bell = await apiServices.getBellNotifications("0", "20");
|
bell = await apiServices.getBellNotifications("0", "20");
|
||||||
mainBloc.bellBloc.add(bell);
|
mainBloc.bellBloc.add(bell);
|
||||||
}catch(e){
|
});
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkStatus(List<BellItems> bells) {
|
bool checkStatus(List<BellItems> bells) {
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:google_maps_cluster_manager_2/google_maps_cluster_manager_2.dart';
|
import 'package:google_maps_cluster_manager_2/google_maps_cluster_manager_2.dart';
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart'
|
import 'package:google_maps_flutter/google_maps_flutter.dart'
|
||||||
hide ClusterManager, Cluster;
|
hide ClusterManager, Cluster;
|
||||||
import 'package:sfm_app/feature/devices/device_model.dart';
|
|
||||||
import 'package:sfm_app/bloc/map_bloc.dart';
|
import '../../bloc/map_bloc.dart';
|
||||||
import 'package:sfm_app/feature/map/widget/on_tap_marker_widget.dart';
|
import '../../product/base/bloc/base_bloc.dart';
|
||||||
import 'package:sfm_app/product/base/bloc/base_bloc.dart';
|
|
||||||
import 'package:sfm_app/product/constant/icon/icon_constants.dart';
|
|
||||||
import 'package:sfm_app/product/permission/location_permission.dart';
|
|
||||||
import 'package:sfm_app/product/services/api_services.dart';
|
|
||||||
import 'package:sfm_app/product/utils/permission_handler.dart';
|
|
||||||
import '../../product/constant/enums/app_theme_enums.dart';
|
import '../../product/constant/enums/app_theme_enums.dart';
|
||||||
import '../../product/shared/shared_snack_bar.dart';
|
import '../../product/constant/icon/icon_constants.dart';
|
||||||
|
import '../../product/services/api_services.dart';
|
||||||
|
import '../../product/utils/permission_handler.dart';
|
||||||
|
import '../devices/device_model.dart';
|
||||||
|
import 'widget/on_tap_marker_widget.dart';
|
||||||
|
|
||||||
class MapScreen extends StatefulWidget {
|
class MapScreen extends StatefulWidget {
|
||||||
const MapScreen({super.key});
|
const MapScreen({super.key});
|
||||||
@@ -39,7 +36,7 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
|
|||||||
APIServices apiServices = APIServices();
|
APIServices apiServices = APIServices();
|
||||||
final streamController = StreamController<GoogleMapController>.broadcast();
|
final streamController = StreamController<GoogleMapController>.broadcast();
|
||||||
List<Device> devices = [];
|
List<Device> devices = [];
|
||||||
Completer<GoogleMapController> _controller = Completer();
|
final Completer<GoogleMapController> _controller = Completer();
|
||||||
List<String> imageAssets = [
|
List<String> imageAssets = [
|
||||||
IconConstants.instance.getIcon("normal_icon"),
|
IconConstants.instance.getIcon("normal_icon"),
|
||||||
IconConstants.instance.getIcon("offline_icon"),
|
IconConstants.instance.getIcon("offline_icon"),
|
||||||
@@ -121,7 +118,8 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
|
|||||||
clusterManager.updateMap();
|
clusterManager.updateMap();
|
||||||
},
|
},
|
||||||
polylines: {
|
polylines: {
|
||||||
if (polylinesSnapshot.data != null && polylinesSnapshot.data!.isNotEmpty) ... [
|
if (polylinesSnapshot.data != null &&
|
||||||
|
polylinesSnapshot.data!.isNotEmpty) ...[
|
||||||
Polyline(
|
Polyline(
|
||||||
polylineId: const PolylineId('router'),
|
polylineId: const PolylineId('router'),
|
||||||
points: polylinesSnapshot.data!,
|
points: polylinesSnapshot.data!,
|
||||||
@@ -189,7 +187,8 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
|
|||||||
position: cluster.location,
|
position: cluster.location,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
LocationPermission permission = await checkAndRequestPermission();
|
LocationPermission permission = await checkAndRequestPermission();
|
||||||
if (permission == LocationPermission.whileInUse || permission == LocationPermission.always) {
|
if (permission == LocationPermission.whileInUse ||
|
||||||
|
permission == LocationPermission.always) {
|
||||||
Position position = await Geolocator.getCurrentPosition();
|
Position position = await Geolocator.getCurrentPosition();
|
||||||
onTapMarker(
|
onTapMarker(
|
||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
@@ -277,23 +276,12 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void getAllMarkers() async {
|
void getAllMarkers() async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
devices.clear();
|
devices.clear();
|
||||||
final devicesList = await apiServices.getOwnerDevices();
|
final devicesList = await apiServices.getOwnerDevices();
|
||||||
for (var device in devicesList) {
|
for (var device in devicesList) {
|
||||||
devices.add(device);
|
devices.add(device);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
if (!mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<bool> checkLocationPermission(context) async {
|
|
||||||
// bool check = await LocationPermissionRequest.instance
|
|
||||||
// .checkLocationPermission(context);
|
|
||||||
// return check;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../../../product/shared/shared_snack_bar.dart';
|
import '../../../product/shared/shared_snack_bar.dart';
|
||||||
import '../../../bloc/device_notification_settings_bloc.dart';
|
import '../../../bloc/device_notification_settings_bloc.dart';
|
||||||
import 'device_notification_settings_model.dart';
|
import 'device_notification_settings_model.dart';
|
||||||
@@ -111,15 +111,12 @@ class _DeviceNotificationSettingsScreenState
|
|||||||
}
|
}
|
||||||
|
|
||||||
void getNotificationSetting() async {
|
void getNotificationSetting() async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
deviceNotifications =
|
deviceNotifications =
|
||||||
await apiServices.getAllSettingsNotificationOfDevices();
|
await apiServices.getAllSettingsNotificationOfDevices();
|
||||||
deviceNotificationSettingsBloc.sinkListNotifications
|
deviceNotificationSettingsBloc.sinkListNotifications
|
||||||
.add(deviceNotifications);
|
.add(deviceNotifications);
|
||||||
} catch (e) {
|
});
|
||||||
if (!mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget listNotificationSetting(
|
Widget listNotificationSetting(
|
||||||
@@ -293,13 +290,14 @@ class _DeviceNotificationSettingsScreenState
|
|||||||
|
|
||||||
void updateDeviceNotification(String thingID, Map<String, int> notifiSettings,
|
void updateDeviceNotification(String thingID, Map<String, int> notifiSettings,
|
||||||
bool isDataChange) async {
|
bool isDataChange) async {
|
||||||
try {
|
await apiServices.execute(context, () async {
|
||||||
int statusCode = await apiServices.updateDeviceNotificationSettings(
|
int statusCode = await apiServices.updateDeviceNotificationSettings(
|
||||||
thingID, notifiSettings);
|
thingID, notifiSettings);
|
||||||
if (statusCode == 200) {
|
if (statusCode == 200) {
|
||||||
showNoIconTopSnackBar(
|
showNoIconTopSnackBar(
|
||||||
context,
|
context,
|
||||||
appLocalization(context).notification_update_device_settings_success,
|
appLocalization(context)
|
||||||
|
.notification_update_device_settings_success,
|
||||||
Colors.green,
|
Colors.green,
|
||||||
Colors.white);
|
Colors.white);
|
||||||
} else {
|
} else {
|
||||||
@@ -311,11 +309,6 @@ class _DeviceNotificationSettingsScreenState
|
|||||||
}
|
}
|
||||||
isDataChange = false;
|
isDataChange = false;
|
||||||
deviceNotificationSettingsBloc.sinkIsDataChange.add(isDataChange);
|
deviceNotificationSettingsBloc.sinkIsDataChange.add(isDataChange);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../../../product/shared/shared_snack_bar.dart';
|
import '../../../product/shared/shared_snack_bar.dart';
|
||||||
import '../../../product/constant/icon/icon_constants.dart';
|
import '../../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../../product/services/api_services.dart';
|
import '../../../product/services/api_services.dart';
|
||||||
@@ -8,7 +9,6 @@ import '../../../bloc/settings_bloc.dart';
|
|||||||
import '../../../product/shared/shared_input_decoration.dart';
|
import '../../../product/shared/shared_input_decoration.dart';
|
||||||
import '../../../product/extension/context_extension.dart';
|
import '../../../product/extension/context_extension.dart';
|
||||||
import '../../../product/services/language_services.dart';
|
import '../../../product/services/language_services.dart';
|
||||||
|
|
||||||
import 'profile_model.dart';
|
import 'profile_model.dart';
|
||||||
|
|
||||||
changeUserInfomation(
|
changeUserInfomation(
|
||||||
@@ -38,7 +38,7 @@ changeUserInfomation(
|
|||||||
? IconButton(
|
? IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (formKey.currentState!.validate()) {
|
if (formKey.currentState!.validate()) {
|
||||||
try {
|
await apiServices.execute(context,() async {
|
||||||
formKey.currentState!.save();
|
formKey.currentState!.save();
|
||||||
String latitude = user.latitude ?? "";
|
String latitude = user.latitude ?? "";
|
||||||
String longitude = user.longitude ?? "";
|
String longitude = user.longitude ?? "";
|
||||||
@@ -51,7 +51,7 @@ changeUserInfomation(
|
|||||||
"longitude": longitude
|
"longitude": longitude
|
||||||
};
|
};
|
||||||
int statusCode =
|
int statusCode =
|
||||||
await apiServices.updateUserProfile(body);
|
await apiServices.updateUserProfile(body);
|
||||||
if (statusCode == 200) {
|
if (statusCode == 200) {
|
||||||
showNoIconTopSnackBar(
|
showNoIconTopSnackBar(
|
||||||
modalBottomSheetContext,
|
modalBottomSheetContext,
|
||||||
@@ -69,11 +69,42 @@ changeUserInfomation(
|
|||||||
}
|
}
|
||||||
settingsBloc.getUserProfile(context);
|
settingsBloc.getUserProfile(context);
|
||||||
Navigator.pop(modalBottomSheetContext);
|
Navigator.pop(modalBottomSheetContext);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// formKey.currentState!.save();
|
||||||
context, e.toString());
|
// String latitude = user.latitude ?? "";
|
||||||
}
|
// String longitude = user.longitude ?? "";
|
||||||
|
// Map<String, dynamic> body = {
|
||||||
|
// "name": username,
|
||||||
|
// "email": email,
|
||||||
|
// "phone": tel,
|
||||||
|
// "address": address,
|
||||||
|
// "latitude": latitude,
|
||||||
|
// "longitude": longitude
|
||||||
|
// };
|
||||||
|
// int statusCode =
|
||||||
|
// await apiServices.updateUserProfile(body);
|
||||||
|
// if (statusCode == 200) {
|
||||||
|
// showNoIconTopSnackBar(
|
||||||
|
// modalBottomSheetContext,
|
||||||
|
// appLocalization(context)
|
||||||
|
// .notification_update_profile_success,
|
||||||
|
// Colors.green,
|
||||||
|
// Colors.white);
|
||||||
|
// } else {
|
||||||
|
// showNoIconTopSnackBar(
|
||||||
|
// modalBottomSheetContext,
|
||||||
|
// appLocalization(context)
|
||||||
|
// .notification_update_profile_failed,
|
||||||
|
// Colors.redAccent,
|
||||||
|
// Colors.white);
|
||||||
|
// }
|
||||||
|
// settingsBloc.getUserProfile(context);
|
||||||
|
// Navigator.pop(modalBottomSheetContext);
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(context, e.toString());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon:
|
icon:
|
||||||
@@ -212,7 +243,7 @@ changeUserInfomation(
|
|||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (formKey.currentState!.validate()) {
|
if (formKey.currentState!.validate()) {
|
||||||
try {
|
await apiServices.execute(context,() async {
|
||||||
formKey.currentState!.save();
|
formKey.currentState!.save();
|
||||||
String latitude = user.latitude ?? "";
|
String latitude = user.latitude ?? "";
|
||||||
String longitude = user.longitude ?? "";
|
String longitude = user.longitude ?? "";
|
||||||
@@ -224,8 +255,8 @@ changeUserInfomation(
|
|||||||
"latitude": latitude,
|
"latitude": latitude,
|
||||||
"longitude": longitude
|
"longitude": longitude
|
||||||
};
|
};
|
||||||
int statusCode =
|
int statusCode = await apiServices
|
||||||
await apiServices.updateUserProfile(body);
|
.updateUserProfile(body);
|
||||||
if (statusCode == 200) {
|
if (statusCode == 200) {
|
||||||
showNoIconTopSnackBar(
|
showNoIconTopSnackBar(
|
||||||
modalBottomSheetContext,
|
modalBottomSheetContext,
|
||||||
@@ -243,11 +274,7 @@ changeUserInfomation(
|
|||||||
}
|
}
|
||||||
settingsBloc.getUserProfile(context);
|
settingsBloc.getUserProfile(context);
|
||||||
Navigator.pop(modalBottomSheetContext);
|
Navigator.pop(modalBottomSheetContext);
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
style: const ButtonStyle(
|
style: const ButtonStyle(
|
||||||
@@ -296,15 +323,15 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
|
|||||||
isChangeSnapshot.data ?? isChange
|
isChangeSnapshot.data ?? isChange
|
||||||
? IconButton(
|
? IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
try {
|
if (formKey.currentState!.validate()) {
|
||||||
if (formKey.currentState!.validate()) {
|
await apiServices.execute(context,() async {
|
||||||
formKey.currentState!.save();
|
formKey.currentState!.save();
|
||||||
Map<String, dynamic> body = {
|
Map<String, dynamic> body = {
|
||||||
"password_old": oldPass,
|
"password_old": oldPass,
|
||||||
"password_new": newPass,
|
"password_new": newPass,
|
||||||
};
|
};
|
||||||
int statusCode =
|
int statusCode =
|
||||||
await apiServices.updateUserPassword(body);
|
await apiServices.updateUserPassword(body);
|
||||||
if (statusCode == 200) {
|
if (statusCode == 200) {
|
||||||
showNoIconTopSnackBar(
|
showNoIconTopSnackBar(
|
||||||
modalBottomSheetContext,
|
modalBottomSheetContext,
|
||||||
@@ -321,11 +348,7 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
|
|||||||
Colors.white);
|
Colors.white);
|
||||||
}
|
}
|
||||||
Navigator.pop(modalBottomSheetContext);
|
Navigator.pop(modalBottomSheetContext);
|
||||||
}
|
});
|
||||||
} catch (e) {
|
|
||||||
if (!context.mounted) return;
|
|
||||||
showErrorTopSnackBarCustom(
|
|
||||||
context, e.toString());
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon:
|
icon:
|
||||||
@@ -410,15 +433,15 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
|
|||||||
? Center(
|
? Center(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
try {
|
await apiServices.execute(context,() async {
|
||||||
if (formKey.currentState!.validate()) {
|
if (formKey.currentState!.validate()) {
|
||||||
formKey.currentState!.save();
|
formKey.currentState!.save();
|
||||||
Map<String, dynamic> body = {
|
Map<String, dynamic> body = {
|
||||||
"password_old": oldPass,
|
"password_old": oldPass,
|
||||||
"password_new": newPass,
|
"password_new": newPass,
|
||||||
};
|
};
|
||||||
int statusCode =
|
int statusCode = await apiServices
|
||||||
await apiServices.updateUserPassword(body);
|
.updateUserPassword(body);
|
||||||
if (statusCode == 200) {
|
if (statusCode == 200) {
|
||||||
showNoIconTopSnackBar(
|
showNoIconTopSnackBar(
|
||||||
modalBottomSheetContext,
|
modalBottomSheetContext,
|
||||||
@@ -436,11 +459,38 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
|
|||||||
}
|
}
|
||||||
Navigator.pop(modalBottomSheetContext);
|
Navigator.pop(modalBottomSheetContext);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
if (!context.mounted) return;
|
// try {
|
||||||
showErrorTopSnackBarCustom(
|
// if (formKey.currentState!.validate()) {
|
||||||
context, e.toString());
|
// formKey.currentState!.save();
|
||||||
}
|
// Map<String, dynamic> body = {
|
||||||
|
// "password_old": oldPass,
|
||||||
|
// "password_new": newPass,
|
||||||
|
// };
|
||||||
|
// int statusCode = await apiServices
|
||||||
|
// .updateUserPassword(body);
|
||||||
|
// if (statusCode == 200) {
|
||||||
|
// showNoIconTopSnackBar(
|
||||||
|
// modalBottomSheetContext,
|
||||||
|
// appLocalization(context)
|
||||||
|
// .notification_update_password_success,
|
||||||
|
// Colors.green,
|
||||||
|
// Colors.white);
|
||||||
|
// } else {
|
||||||
|
// showNoIconTopSnackBar(
|
||||||
|
// modalBottomSheetContext,
|
||||||
|
// appLocalization(context)
|
||||||
|
// .notification_update_password_failed,
|
||||||
|
// Colors.redAccent,
|
||||||
|
// Colors.white);
|
||||||
|
// }
|
||||||
|
// Navigator.pop(modalBottomSheetContext);
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// if (!context.mounted) return;
|
||||||
|
// showErrorTopSnackBarCustom(
|
||||||
|
// context, e.toString());
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
style: const ButtonStyle(
|
style: const ButtonStyle(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../../product/constant/app/app_constants.dart';
|
import '../../product/constant/app/app_constants.dart';
|
||||||
import '../../product/shared/shared_loading_animation.dart';
|
import '../../product/shared/shared_loading_animation.dart';
|
||||||
import '../../product/shared/shared_snack_bar.dart';
|
|
||||||
import 'profile/profile_screen.dart';
|
import 'profile/profile_screen.dart';
|
||||||
import '../../product/constant/icon/icon_constants.dart';
|
import '../../product/constant/icon/icon_constants.dart';
|
||||||
import '../../product/extension/context_extension.dart';
|
import '../../product/extension/context_extension.dart';
|
||||||
@@ -29,7 +27,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
settingsBloc = BlocProvider.of(context);
|
settingsBloc = BlocProvider.of(context);
|
||||||
// getUserProfile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -41,7 +38,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
),
|
),
|
||||||
body: StreamBuilder<User>(
|
body: StreamBuilder<User>(
|
||||||
stream: settingsBloc.streamUserProfile,
|
stream: settingsBloc.streamUserProfile,
|
||||||
// initialData: user,
|
|
||||||
builder: (context, userSnapshot) {
|
builder: (context, userSnapshot) {
|
||||||
if (userSnapshot.data == null) {
|
if (userSnapshot.data == null) {
|
||||||
settingsBloc.getUserProfile(context);
|
settingsBloc.getUserProfile(context);
|
||||||
@@ -139,17 +135,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void getUserProfile() async {
|
|
||||||
// try {
|
|
||||||
// user = await apiServices.getUserDetail();
|
|
||||||
// settingsBloc.sinkUserProfile.add(user);
|
|
||||||
// } catch (e) {
|
|
||||||
// if (!mounted) return;
|
|
||||||
// showErrorTopSnackBarCustom(
|
|
||||||
// context, e.toString());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
String getAvatarContent(String username) {
|
String getAvatarContent(String username) {
|
||||||
String name = "";
|
String name = "";
|
||||||
if (username.isNotEmpty) {
|
if (username.isNotEmpty) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:sfm_app/product/utils/app_logger_utils.dart';
|
||||||
import 'package:sfm_app/product/utils/responsive_text_utils.dart';
|
import 'package:sfm_app/product/utils/responsive_text_utils.dart';
|
||||||
|
|
||||||
import '../theme/app_theme_light.dart';
|
import '../theme/app_theme_light.dart';
|
||||||
@@ -169,3 +170,15 @@ extension TextStyleExtention on BuildContext {
|
|||||||
TextStyle get headlineLargeTextStyle =>
|
TextStyle get headlineLargeTextStyle =>
|
||||||
Theme.of(this).textTheme.headlineLarge!;
|
Theme.of(this).textTheme.headlineLarge!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension FutureExtension<T> on Future<T> {
|
||||||
|
Future<T> handleApiError() async {
|
||||||
|
try {
|
||||||
|
return await this;
|
||||||
|
} catch (e) {
|
||||||
|
AppLoggerUtils.error(e.toString());
|
||||||
|
return Future.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import '../utils/app_logger_utils.dart';
|
||||||
|
|
||||||
import '../constant/status_code/status_code_constants.dart';
|
import '../constant/status_code/status_code_constants.dart';
|
||||||
|
|
||||||
import '../cache/local_manager.dart';
|
import '../cache/local_manager.dart';
|
||||||
@@ -39,7 +41,8 @@ class NetworkManager {
|
|||||||
Future<String> getDataFromServer(String path) async {
|
Future<String> getDataFromServer(String path) async {
|
||||||
try {
|
try {
|
||||||
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
||||||
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET url: $url");
|
AppLoggerUtils.info("GET url: $url");
|
||||||
|
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET url: $url");
|
||||||
final headers = await getHeaders();
|
final headers = await getHeaders();
|
||||||
final response = await http.get(url, headers: headers).timeout(
|
final response = await http.get(url, headers: headers).timeout(
|
||||||
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
||||||
@@ -53,7 +56,8 @@ class NetworkManager {
|
|||||||
throw Exception('Lỗi server: ${response.statusCode}');
|
throw Exception('Lỗi server: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
log('Lỗi khi lấy dữ liệu: $e, StackTrace: $stackTrace');
|
// AppLoggerUtils.error(message)
|
||||||
|
// log('Lỗi khi lấy dữ liệu: $e, StackTrace: $stackTrace');
|
||||||
throw Exception('Lỗi khi lấy dữ liệu: $e');
|
throw Exception('Lỗi khi lấy dữ liệu: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +77,8 @@ class NetworkManager {
|
|||||||
String path, Map<String, dynamic> params) async {
|
String path, Map<String, dynamic> params) async {
|
||||||
try {
|
try {
|
||||||
final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
|
final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
|
||||||
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
|
AppLoggerUtils.info("GET Params url: $url");
|
||||||
|
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
|
||||||
final headers = await getHeaders();
|
final headers = await getHeaders();
|
||||||
final response = await http.get(url, headers: headers).timeout(
|
final response = await http.get(url, headers: headers).timeout(
|
||||||
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
||||||
@@ -90,16 +95,16 @@ class NetworkManager {
|
|||||||
log('Lỗi khi lấy dữ liệu: $e, StackTrace: $stackTrace');
|
log('Lỗi khi lấy dữ liệu: $e, StackTrace: $stackTrace');
|
||||||
throw Exception('Lỗi khi lấy dữ liệu: $e');
|
throw Exception('Lỗi khi lấy dữ liệu: $e');
|
||||||
}
|
}
|
||||||
final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
|
// final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
|
||||||
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
|
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
|
||||||
final headers = await getHeaders();
|
// final headers = await getHeaders();
|
||||||
final response = await http.get(url, headers: headers);
|
// final response = await http.get(url, headers: headers);
|
||||||
if (response.statusCode == StatusCodeConstants.CREATED ||
|
// if (response.statusCode == StatusCodeConstants.CREATED ||
|
||||||
response.statusCode == StatusCodeConstants.OK) {
|
// response.statusCode == StatusCodeConstants.OK) {
|
||||||
return response.body;
|
// return response.body;
|
||||||
} else {
|
// } else {
|
||||||
return "";
|
// return "";
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates new data on the server using a POST request.
|
/// Creates new data on the server using a POST request.
|
||||||
@@ -109,7 +114,8 @@ class NetworkManager {
|
|||||||
Future<int> createDataInServer(String path, Map<String, dynamic> body) async {
|
Future<int> createDataInServer(String path, Map<String, dynamic> body) async {
|
||||||
try {
|
try {
|
||||||
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
||||||
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] POST url: $url");
|
AppLoggerUtils.info("POST url: $url");
|
||||||
|
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] POST url: $url");
|
||||||
final headers = await getHeaders();
|
final headers = await getHeaders();
|
||||||
final response = await http
|
final response = await http
|
||||||
.post(url, headers: headers, body: jsonEncode(body))
|
.post(url, headers: headers, body: jsonEncode(body))
|
||||||
@@ -137,7 +143,8 @@ class NetworkManager {
|
|||||||
Future<int> updateDataInServer(String path, Map<String, dynamic> body) async {
|
Future<int> updateDataInServer(String path, Map<String, dynamic> body) async {
|
||||||
try {
|
try {
|
||||||
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
||||||
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] PUT url: $url");
|
AppLoggerUtils.info("PUT url: $url");
|
||||||
|
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] PUT url: $url");
|
||||||
final headers = await getHeaders();
|
final headers = await getHeaders();
|
||||||
final response =
|
final response =
|
||||||
await http.put(url, headers: headers, body: jsonEncode(body)).timeout(
|
await http.put(url, headers: headers, body: jsonEncode(body)).timeout(
|
||||||
@@ -166,7 +173,8 @@ class NetworkManager {
|
|||||||
Future<int> deleteDataInServer(String path) async {
|
Future<int> deleteDataInServer(String path) async {
|
||||||
try {
|
try {
|
||||||
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
||||||
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] DELETE url: $url");
|
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] DELETE url: $url");
|
||||||
|
AppLoggerUtils.info("DELETE url: $url");
|
||||||
final headers = await getHeaders();
|
final headers = await getHeaders();
|
||||||
final response = await http.delete(url, headers: headers).timeout(
|
final response = await http.delete(url, headers: headers).timeout(
|
||||||
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import 'dart:convert';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:sfm_app/product/shared/model/province_model.dart';
|
import '../shared/model/province_model.dart';
|
||||||
|
import '../utils/app_logger_utils.dart';
|
||||||
import '../../feature/device_log/device_logs_model.dart';
|
import '../../feature/device_log/device_logs_model.dart';
|
||||||
import '../../feature/devices/device_model.dart';
|
import '../../feature/devices/device_model.dart';
|
||||||
import '../../feature/home/device_alias_model.dart';
|
import '../../feature/home/device_alias_model.dart';
|
||||||
@@ -26,6 +27,8 @@ import '../constant/enums/local_keys_enums.dart';
|
|||||||
import '../network/network_manager.dart';
|
import '../network/network_manager.dart';
|
||||||
|
|
||||||
class APIServices {
|
class APIServices {
|
||||||
|
|
||||||
|
|
||||||
Map<String, String> headers = {
|
Map<String, String> headers = {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -52,12 +55,10 @@ class APIServices {
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<T> executeApiCall<T>(
|
Future<T> executeApiCall<T>(Future<dynamic> Function() apiCall,
|
||||||
Future<dynamic> Function() apiCall, {
|
{T Function(dynamic)? parser,
|
||||||
T Function(dynamic)? parser,
|
String errorMessage = 'Lỗi khi gọi API',
|
||||||
String errorMessage = 'Lỗi khi gọi API',
|
T Function(int)? statusCodeHandler}) async {
|
||||||
T Function(int)? statusCodeHandler, // Thêm handler cho statusCode
|
|
||||||
}) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await apiCall().timeout(
|
final response = await apiCall().timeout(
|
||||||
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
|
||||||
@@ -81,11 +82,38 @@ class APIServices {
|
|||||||
throw Exception('Dữ liệu trả về rỗng');
|
throw Exception('Dữ liệu trả về rỗng');
|
||||||
}
|
}
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
// log('Lỗi API: $e, StackTrace: $stackTrace');
|
AppLoggerUtils.error("Lỗi gọi API", e, stackTrace);
|
||||||
throw Exception('$errorMessage: $e');
|
throw Exception('$errorMessage: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Most Used Function
|
||||||
|
// Future<T> execute<T>(Future<T> Function() apiCall) async {
|
||||||
|
// try {
|
||||||
|
// return await apiCall();
|
||||||
|
// } catch (e) {
|
||||||
|
|
||||||
|
// AppLoggerUtils.error(e.toString());
|
||||||
|
// return Future.error(e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<T> execute<T>(
|
||||||
|
BuildContext context,
|
||||||
|
Future<T> Function() apiCall, {
|
||||||
|
bool checkMounted = true,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
return await apiCall();
|
||||||
|
} catch (e) {
|
||||||
|
if (checkMounted && !context.mounted) {
|
||||||
|
return Future.error('Widget not mounted');
|
||||||
|
}
|
||||||
|
showErrorTopSnackBarCustom(context, "Lỗi hệ thống");
|
||||||
|
return Future.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> login(String path, Map<String, dynamic> loginRequest) async {
|
Future<String> login(String path, Map<String, dynamic> loginRequest) async {
|
||||||
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
final url = Uri.https(ApplicationConstants.DOMAIN, path);
|
||||||
final headers = await getHeaders();
|
final headers = await getHeaders();
|
||||||
@@ -229,7 +257,8 @@ class APIServices {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> updateDeviceNotificationSettings(String thingID, Map<String, int> data) async {
|
Future<int> updateDeviceNotificationSettings(
|
||||||
|
String thingID, Map<String, int> data) async {
|
||||||
Map<String, dynamic> body = {"thing_id": thingID, "notifi_settings": data};
|
Map<String, dynamic> body = {"thing_id": thingID, "notifi_settings": data};
|
||||||
return executeApiCall(
|
return executeApiCall(
|
||||||
() => NetworkManager.instance!.updateDataInServer(
|
() => NetworkManager.instance!.updateDataInServer(
|
||||||
@@ -279,7 +308,7 @@ class APIServices {
|
|||||||
.getDataFromServer(APIPathConstants.PROVINCES_PATH),
|
.getDataFromServer(APIPathConstants.PROVINCES_PATH),
|
||||||
parser: (json) => Province.fromJsonDynamicList(json['items']),
|
parser: (json) => Province.fromJsonDynamicList(json['items']),
|
||||||
errorMessage: 'Lỗi khi GET /${APIPathConstants.PROVINCES_PATH}');
|
errorMessage: 'Lỗi khi GET /${APIPathConstants.PROVINCES_PATH}');
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Province>> getProvincesByName(String name) async {
|
Future<List<Province>> getProvincesByName(String name) async {
|
||||||
@@ -290,7 +319,7 @@ class APIServices {
|
|||||||
parser: (json) => Province.fromJsonDynamicList(json['items']),
|
parser: (json) => Province.fromJsonDynamicList(json['items']),
|
||||||
errorMessage: 'Lỗi khi GET /${APIPathConstants.PROVINCES_PATH}/$name',
|
errorMessage: 'Lỗi khi GET /${APIPathConstants.PROVINCES_PATH}/$name',
|
||||||
);
|
);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Province> getProvinceByID(String provinceID) async {
|
Future<Province> getProvinceByID(String provinceID) async {
|
||||||
|
|||||||
26
lib/product/shared/shared_rocket_container.dart
Normal file
26
lib/product/shared/shared_rocket_container.dart
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SharedRocketContainer extends CustomClipper<Path> {
|
||||||
|
@override
|
||||||
|
Path getClip(Size size) {
|
||||||
|
final double width = size.width;
|
||||||
|
final double height = size.height;
|
||||||
|
|
||||||
|
const double pointyWidth = 20.0;
|
||||||
|
|
||||||
|
Path path = Path();
|
||||||
|
path.moveTo(0, 0);
|
||||||
|
path.lineTo(width - pointyWidth, 0);
|
||||||
|
path.lineTo(width, height / 2);
|
||||||
|
path.lineTo(width - pointyWidth, height);
|
||||||
|
path.lineTo(0, height);
|
||||||
|
path.close();
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldReclip(CustomClipper<Path> oldClipper) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ class AppThemeDark extends AppTheme {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
ThemeData get theme => FlexThemeData.dark(
|
ThemeData get theme => FlexThemeData.dark(
|
||||||
|
scaffoldBackground: Colors.black,
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
scheme: FlexScheme.flutterDash,
|
scheme: FlexScheme.flutterDash,
|
||||||
subThemesData: const FlexSubThemesData(
|
subThemesData: const FlexSubThemesData(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class AppThemeLight extends AppTheme {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
ThemeData get theme => FlexThemeData.light(
|
ThemeData get theme => FlexThemeData.light(
|
||||||
|
scaffoldBackground: Colors.white,
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
scheme: FlexScheme.flutterDash,
|
scheme: FlexScheme.flutterDash,
|
||||||
bottomAppBarElevation: 20.0,
|
bottomAppBarElevation: 20.0,
|
||||||
|
|||||||
39
lib/product/utils/app_logger_utils.dart
Normal file
39
lib/product/utils/app_logger_utils.dart
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import 'package:logger/logger.dart';
|
||||||
|
|
||||||
|
class AppLoggerUtils{
|
||||||
|
static final Logger _logger = Logger(
|
||||||
|
printer: PrettyPrinter(
|
||||||
|
methodCount: 2,
|
||||||
|
errorMethodCount: 8,
|
||||||
|
lineLength: 120,
|
||||||
|
colors: true,
|
||||||
|
printEmojis: true,
|
||||||
|
dateTimeFormat: (DateTime dateTime) {
|
||||||
|
// Tùy chỉnh định dạng thời gian
|
||||||
|
return '[${DateTime.now().toLocal().toString().split(' ')[1]}]';
|
||||||
|
},
|
||||||
|
// dateTimeFormat: DateTimeFormat.dateAndTime
|
||||||
|
),
|
||||||
|
level: Level.debug, // Cấp độ log tối thiểu (có thể thay đổi trong môi trường production)
|
||||||
|
);
|
||||||
|
|
||||||
|
static void debug(String message, [dynamic error, StackTrace? stackTrace]) {
|
||||||
|
_logger.d(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void info(String message, [dynamic error, StackTrace? stackTrace]) {
|
||||||
|
_logger.i(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void warning(String message, [dynamic error, StackTrace? stackTrace]) {
|
||||||
|
_logger.w(message, error: error, stackTrace: stackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void error(String message, [dynamic error, StackTrace? stackTrace]) {
|
||||||
|
_logger.e(message, error: error, stackTrace: stackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void trace(String message, [dynamic error, StackTrace? stackTrace]) {
|
||||||
|
_logger.t(message, error: error, stackTrace: stackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -557,6 +557,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
logger:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: logger
|
||||||
|
sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ dependencies:
|
|||||||
url_launcher: ^6.3.1
|
url_launcher: ^6.3.1
|
||||||
app_settings: ^5.1.1
|
app_settings: ^5.1.1
|
||||||
lottie: ^3.3.1
|
lottie: ^3.3.1
|
||||||
|
logger: ^2.5.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user