Logging data
Try-catch function
This commit is contained in:
anhtunz
2025-06-17 16:43:45 +07:00
parent 22fef0e0a8
commit 2d53f2cdd3
41 changed files with 1591 additions and 1299 deletions

View File

@@ -1,8 +1,7 @@
import 'dart:async';
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 '../../bloc/bell_bloc.dart';
import '../../product/base/bloc/base_bloc.dart';
@@ -77,7 +76,8 @@ class _BellScreenState extends State<BellScreen> {
if (index < bellSnapshot.data!.length) {
return GestureDetector(
onTap: () async {
readNotification(bellSnapshot.data![index].id!);
readNotification(
bellSnapshot.data![index].id!);
},
child: Column(
children: [
@@ -163,24 +163,18 @@ class _BellScreenState extends State<BellScreen> {
getBellNotification(offset);
}
void readNotification(String id) async{
try {
void readNotification(String id) async {
await apiServices.execute(context, () async {
List<String> read = [];
read.add(id);
await apiServices
.updateStatusOfNotification(read);
await apiServices.updateStatusOfNotification(read);
read.clear();
} catch (e) {
if (mounted){
showErrorTopSnackBarCustom(
context, e.toString());
}
}
});
refresh();
}
Future<void> getBellNotification(int offset) async {
try {
apiServices.execute(context, () async {
bell = await apiServices.getBellNotifications(
offset.toString(), (offset + 20).toString());
if (bell.items!.isEmpty) {
@@ -193,10 +187,7 @@ class _BellScreenState extends State<BellScreen> {
}
bellBloc.bellItems.add(items);
check = false;
} catch (e) {
if (!mounted) return;
showErrorTopSnackBarCustom(context, e.toString());
}
});
}
String timeAgo(BuildContext context, DateTime dateTime) {

View File

@@ -1,8 +1,9 @@
// ignore_for_file: use_build_context_synchronously
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/constant/enums/role_enums.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/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 deviceNameController = TextEditingController(text: "");
ScaffoldMessenger.of(context).showSnackBar(
@@ -77,7 +79,8 @@ addNewDevice(BuildContext context, String role, DevicesManagerBloc deviceManager
Colors.white);
ScaffoldMessenger.of(context).hideCurrentSnackBar();
} else {
addDevices(context, role, extID, deviceName, deviceManagerBloc);
addDevices(
context, role, extID, deviceName, deviceManagerBloc);
ScaffoldMessenger.of(context).hideCurrentSnackBar();
}
},
@@ -90,12 +93,12 @@ addNewDevice(BuildContext context, String role, DevicesManagerBloc deviceManager
);
}
void addDevices(
BuildContext context, String role, String extID, String deviceName, DevicesManagerBloc deviceManagerBloc) async {
void addDevices(BuildContext context, String role, String extID,
String deviceName, DevicesManagerBloc deviceManagerBloc) async {
APIServices apiServices = APIServices();
Map<String, dynamic> body = {};
if (role == RoleEnums.ADMIN.name) {
try {
await apiServices.execute(context,() async {
body = {"ext_id": extID, "name": deviceName};
int statusCode = await apiServices.createDeviceByAdmin(body);
showSnackBarResponseByStatusCode(
@@ -103,15 +106,10 @@ void addDevices(
statusCode,
appLocalization(context).notification_create_device_success,
appLocalization(context).notification_create_device_failed);
deviceManagerBloc.getDeviceByState(context,-2);
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
deviceManagerBloc.getDeviceByState(context, -2);
});
} else {
try {
await apiServices.execute(context,() async {
body = {"ext_id": extID};
int statusCode = await apiServices.registerDevice(body);
showSnackBarResponseByStatusCode(
@@ -119,12 +117,7 @@ void addDevices(
statusCode,
appLocalization(context).notification_add_device_success,
appLocalization(context).notification_device_not_exist);
deviceManagerBloc.getDeviceByState(context,-2);
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
deviceManagerBloc.getDeviceByState(context, -2);
});
}
}

View File

@@ -5,7 +5,6 @@ import '../../bloc/devices_manager_bloc.dart';
import '../../product/constant/enums/role_enums.dart';
import '../../product/services/api_services.dart';
import '../../product/services/language_services.dart';
import '../../product/shared/shared_snack_bar.dart';
import '../../product/utils/response_status_utils.dart';
handleDeleteDevice(BuildContext context, DevicesManagerBloc devicesManagerBloc,
@@ -48,27 +47,24 @@ deleteOrUnregisterDevice(BuildContext context, DevicesManagerBloc devicesBloc,
Map<String, dynamic> body = {
"ext_id": extID,
};
int statusCode = await apiServices.unregisterDevice(body);
showSnackBarResponseByStatusCode(
context,
statusCode,
appLocalization(context).notification_delete_device_success,
appLocalization(context).notification_delete_device_failed);
devicesBloc.getDeviceByState(context,-2);
await apiServices.execute(context, () async {
int statusCode = await apiServices.unregisterDevice(body);
showSnackBarResponseByStatusCode(
context,
statusCode,
appLocalization(context).notification_delete_device_success,
appLocalization(context).notification_delete_device_failed);
devicesBloc.getDeviceByState(context, -2);
});
} else {
try {
await apiServices.execute(context, () async {
int statusCode = await apiServices.deleteDeviceByAdmin(extID);
showSnackBarResponseByStatusCode(
context,
statusCode,
appLocalization(context).notification_delete_device_success,
appLocalization(context).notification_delete_device_failed);
devicesBloc.getDeviceByState(context,-2);
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
devicesBloc.getDeviceByState(context, -2);
});
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,10 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
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_loading_animation.dart';
import '../../product/shared/shared_snack_bar.dart';
import '../../product/utils/app_logger_utils.dart';
import 'shared/alert_card.dart';
import 'shared/warning_card.dart';
import '../../product/utils/device_utils.dart';
@@ -19,8 +18,8 @@ import '../../bloc/home_bloc.dart';
import '../../product/base/bloc/base_bloc.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
const HomeScreen({super.key, required this.persistentTabController});
final PersistentTabController persistentTabController;
@override
State<HomeScreen> createState() => _HomeScreenState();
}
@@ -29,7 +28,6 @@ class _HomeScreenState extends State<HomeScreen> {
late HomeBloc homeBloc;
APIServices apiServices = APIServices();
Map<String, List<DeviceWithAlias>> allDevicesAliasMap = {};
Map<String, List<DeviceWithAlias>> allDevicesAliasJoinedMap = {};
List<DeviceWithAlias> devices = [];
bool isFunctionCall = false;
Timer? getAllDevicesTimer;
@@ -41,6 +39,8 @@ class _HomeScreenState extends State<HomeScreen> {
void initState() {
super.initState();
homeBloc = BlocProvider.of(context);
getAllDevicesTimer?.cancel();
AppLoggerUtils.debug("Init State HomeScreen");
getOwnerAndJoinedDevices();
const duration = Duration(seconds: 10);
getAllDevicesTimer =
@@ -50,6 +50,7 @@ class _HomeScreenState extends State<HomeScreen> {
@override
void dispose() {
getAllDevicesTimer?.cancel();
homeBloc.dispose();
super.dispose();
}
@@ -198,107 +199,23 @@ class _HomeScreenState extends State<HomeScreen> {
),
),
),
StreamBuilder<bool?>(
stream: homeBloc.streamHasJoinedDevice,
initialData: null,
builder: (context, hasJoinedDeviceSnapshot) {
return StreamBuilder<Map<String, List<DeviceWithAlias>>>(
stream: homeBloc.streamAllDevicesAliasMap,
builder: (context, allDevicesAliasMapSnapshot) {
return StreamBuilder<Map<String, List<DeviceWithAlias>>>(
stream: homeBloc.streamAllDevicesAliasJoinedMap,
builder: (context, allDevicesAliasJoinedMapSnapshot) {
if (hasJoinedDeviceSnapshot.data == null) {
return const SharedComponentLoadingAnimation();
} else {
final data = allDevicesAliasMapSnapshot.data!;
final dataJoined =
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,
),
],
),
),
],
),
);
}
}
},
);
},
);
StreamBuilder<Map<String, List<DeviceWithAlias>>>(
stream: homeBloc.streamAllDevicesAliasMap,
builder: (context, allDevicesAliasMapSnapshot) {
if(allDevicesAliasMapSnapshot.data == null){
return const SharedComponentLoadingAnimation();
}else{
final data = allDevicesAliasMapSnapshot.data!;
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,
);
}
},
),
],
@@ -309,8 +226,8 @@ class _HomeScreenState extends State<HomeScreen> {
}
void getOwnerAndJoinedDevices() async {
try {
devices = await apiServices.getDashBoardDevices();
await apiServices.execute(context, () async {
devices = await apiServices.getDashBoardDevices().handleApiError();
List<DeviceWithAlias> publicDevices = [];
for (var device in devices) {
if (device.visibility == "PUBLIC") {
@@ -320,10 +237,7 @@ class _HomeScreenState extends State<HomeScreen> {
getOwnerDeviceState(publicDevices);
checkSettingDevice(publicDevices);
getDeviceStatusAliasMap(publicDevices);
} catch (e) {
if (!mounted) return;
showErrorTopSnackBarCustom(context, e.toString());
}
});
}
void getOwnerDeviceState(List<DeviceWithAlias> allDevices) async {
@@ -335,7 +249,7 @@ class _HomeScreenState extends State<HomeScreen> {
int count = 0;
for (var device in allDevices) {
if (device.isOwner != true) continue;
// if (device.isOwner != true) continue;
if (!mounted) return;
Map<String, dynamic> sensorMap = DeviceUtils.instance
@@ -368,55 +282,34 @@ class _HomeScreenState extends State<HomeScreen> {
void getDeviceStatusAliasMap(List<DeviceWithAlias> devices) {
allDevicesAliasMap.clear();
allDevicesAliasJoinedMap.clear();
bool check = false;
for (var key in ['all', 'online', 'offline', 'warning', 'not-use']) {
allDevicesAliasMap[key] = [];
allDevicesAliasJoinedMap[key] = [];
}
for (DeviceWithAlias device in devices) {
if (device.isOwner == true) {
allDevicesAliasMap['all']!.add(device);
if (device.state == 0 || device.state == 1) {
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);
}
allDevicesAliasMap['all']!.add(device);
if (device.state == 0 || device.state == 1) {
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);
}
}
homeBloc.sinkHasJoinedDevice.add(check);
homeBloc.sinkAllDevicesAliasMap.add(allDevicesAliasMap);
homeBloc.sinkAllDevicesAliasJoinedMap.add(allDevicesAliasJoinedMap);
}
void checkSettingDevice(List<DeviceWithAlias> devices) async {
try {
if (isFunctionCall) {
log("Ham check setting da duoc goi");
} else {
if (isFunctionCall) {
log("Ham check setting da duoc goi");
} else {
await apiServices.execute(context, () async {
List<DeviceNotificationSettings> list =
await apiServices.getAllSettingsNotificationOfDevices();
// log("List: $list");
@@ -425,24 +318,16 @@ class _HomeScreenState extends State<HomeScreen> {
for (var device in devices) {
if (!thingIdsInList.contains(device.thingId)) {
log("Device with Thing ID ${device.thingId} is not in the notification settings list.");
try {
await apiServices.execute(context, () async {
await apiServices.setupDeviceNotification(
device.thingId!, device.name!);
} catch (e) {
if (!mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
});
} else {
log("All devices are in the notification settings list.");
}
}
}
isFunctionCall = true;
} catch (e) {
if (!mounted) return;
showErrorTopSnackBarCustom(context, e.toString());
});
}
isFunctionCall = true;
}
}

View File

@@ -3,7 +3,7 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.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/image/image_constants.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/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 location = "";
if (device.areaPath != "") {
location = await DeviceUtils.instance
.getFullDeviceLocation(context, device.areaPath!,"");
.getFullDeviceLocation(context, device.areaPath!, "");
}
String path = "";
// DateTime time = DateTime.now();
String time = "";
for (var sensor in device.status!.sensors!) {
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);
}
}
if (notiticationType == "lowBattery") {
if (notificationType == "lowBattery") {
path = ImageConstants.instance.getImage("low_battery");
}
return Card(
@@ -117,24 +117,57 @@ Future<Widget> notificationCard(BuildContext context, String notiticationType,
),
],
),
Align(
alignment: Alignment.centerRight,
child: 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,
device.isOwner!
? Align(
alignment: Alignment.centerRight,
child: 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),
),
),
)
: 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),
),
),
],
),
),
),
),
],
),
),

View File

@@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:maps_launcher/maps_launcher.dart';
import 'package:badges/badges.dart' as badges;
import '../../../product/shared/shared_rocket_container.dart';
import '../device_alias_model.dart';
import '../../../product/constant/icon/icon_constants.dart';
import '../../../product/constant/image/image_constants.dart';
@@ -18,10 +20,10 @@ Future<Widget> warningCard(BuildContext context, APIServices apiServices,
Color backgroundColor = Colors.blue;
Color textColor = Colors.white;
String message = "";
String fullLocation = "";
String fullLocation = "";
if (device.areaPath != "") {
fullLocation = await DeviceUtils.instance
.getFullDeviceLocation(context, device.areaPath!,"");
.getFullDeviceLocation(context, device.areaPath!, "");
}
String time = "";
for (var sensor in device.status!.sensors!) {
@@ -187,84 +189,185 @@ Future<Widget> warningCard(BuildContext context, APIServices apiServices,
),
),
SizedBox(width: context.mediumValue),
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 {
try {
int statusCode = await apiServices
.confirmFakeFireByUser(device.thingId!);
if (statusCode == 200) {
showNoIconTopSnackBar(
context,
device.isOwner!
? 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)
.notification_confirm_fake_fire_success,
Colors.green,
Colors.white);
} else {
showNoIconTopSnackBar(
context,
appLocalization(context)
.notification_confirm_fake_fire_failed,
Colors.red,
Colors.red);
}
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
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),
),
],
.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),
),
);
} else {
showNoIconTopSnackBar(
context,
appLocalization(context).let_PCCC_handle_message,
Colors.orange,
Colors.white);
}
},
child: Text(
message,
style: TextStyle(color: textColor),
),
),
)
: 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,
),
),
),
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),
),
),
),
),
],
),
),
),
),
],
),
],

View File

@@ -5,7 +5,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import '../../../bloc/group_detail_bloc.dart';
import '../../../product/shared/shared_loading_animation.dart';
import '../../../product/shared/shared_snack_bar.dart';
import 'group_detail_model.dart';
import '../../../product/base/bloc/base_bloc.dart';
import '../../../product/constant/app/app_constants.dart';
@@ -325,7 +324,7 @@ class _DetailGroupScreenState extends State<DetailGroupScreen> {
Future.delayed(context.lowDuration).then(
(value) => Navigator.pop(context),
);
try {
await apiServices.execute(context, () async {
int statusCode = await apiServices
.deleteGroup(widget.group);
showSnackBarResponseByStatusCode(
@@ -335,11 +334,7 @@ class _DetailGroupScreenState extends State<DetailGroupScreen> {
.notification_delete_group_success,
appLocalization(context)
.notification_delete_group_failed);
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
});
},
child: Text(
appLocalization(context)

View File

@@ -39,7 +39,7 @@ class _GroupsScreenState extends State<GroupsScreen> {
const duration = Duration(seconds: 5);
getAllGroupsTimer = Timer.periodic(
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,
builder: (context, groupsSnapshot) {
if (groupsSnapshot.data == null) {
interFamilyBloc.getAllGroup(widget.role);
interFamilyBloc.getAllGroup(context,widget.role);
return const SharedLoadingAnimation();
} else if (groupsSnapshot.data!.isEmpty) {
return Center(

View File

@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
import '../../../bloc/inter_family_bloc.dart';
import '../../../product/constant/icon/icon_constants.dart';
import '../../../product/extension/context_extension.dart';
import '../../../product/services/language_services.dart';
import 'groups_model.dart';
shareGroup(BuildContext context, Group group) {
@@ -80,7 +80,8 @@ showActionDialog(
if (dialogTitle == appLocalization(context).delete_group_title) {
Navigator.of(dialogContext).pop();
await interFamilyBloc.deleteGroup(context, group.id!);
interFamilyBloc.getAllGroup(role);
// ignore: use_build_context_synchronously
interFamilyBloc.getAllGroup(context,role);
} else {}
},
child: Text(

View File

@@ -122,7 +122,7 @@ createOrJoinGroupDialog(
try {
await interFamilyBloc.createGroup(
context, groupName, description);
interFamilyBloc.getAllGroup(role);
interFamilyBloc.getAllGroup(context, role);
Navigator.of(dialogContext).pop();
} catch (e) {
// log("Lỗi khi tạo nhóm: $e");
@@ -133,7 +133,7 @@ createOrJoinGroupDialog(
try {
await interFamilyBloc.changeGroupInformation(
context, groupID, groupName, description);
interFamilyBloc.getAllGroup(role);
interFamilyBloc.getAllGroup(context, role);
Navigator.of(dialogContext).pop();
} catch (e) {
// log("Lỗi khi sửa nhóm: $e");

View File

@@ -1,8 +1,6 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:developer';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.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:badges/badges.dart' as badges;
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/services/notification_services.dart';
import '../settings/profile/profile_model.dart';
import '../../product/extension/context_extension.dart';
import '../../bloc/home_bloc.dart';
import '../../product/constant/app/app_constants.dart';
import '../../product/constant/enums/app_route_enums.dart';
import '../../product/permission/location_permission.dart';
import '../../product/services/theme_services.dart';
import '../../bloc/devices_manager_bloc.dart';
import '../devices/devices_manager_screen.dart';
@@ -47,8 +43,6 @@ class MainScreen extends StatefulWidget {
State<MainScreen> createState() => _MainScreenState();
}
PersistentTabController controller = PersistentTabController(initialIndex: 0);
// @pragma('vm:entry-point')
// Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// log("Full background message payload: ${message.toMap()}");
@@ -59,8 +53,8 @@ PersistentTabController controller = PersistentTabController(initialIndex: 0);
// log("Background message handled: ${message.data['title']}");
// }
class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
PersistentTabController controller = PersistentTabController(initialIndex: 0);
APIServices apiServices = APIServices();
// final NotificationServices notificationServices = NotificationServices();
late MainBloc mainBloc;
@@ -112,17 +106,19 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null ) {
if (notification != null && android != null) {
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'your channel id', 'your channel name',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
AndroidNotificationDetails('your channel id', 'your channel name',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
NotificationDetails(android: androidPlatformChannelSpecifics);
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);
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
@@ -200,7 +195,9 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
List<Widget> _buildScreens() {
return [
BlocProvider(
child: const HomeScreen(),
child: HomeScreen(
persistentTabController: controller,
),
blocBuilder: () => HomeBloc(),
),
BlocProvider(
@@ -238,7 +235,7 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
SizedBox(
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 {
try{
await apiServices.execute(context, () async {
bell = await apiServices.getBellNotifications("0", "20");
mainBloc.bellBloc.add(bell);
}catch(e){
showErrorTopSnackBarCustom(context, e.toString());
}
});
}
bool checkStatus(List<BellItems> bells) {

View File

@@ -1,23 +1,20 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_cluster_manager_2/google_maps_cluster_manager_2.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'
hide ClusterManager, Cluster;
import 'package:sfm_app/feature/devices/device_model.dart';
import 'package:sfm_app/bloc/map_bloc.dart';
import 'package:sfm_app/feature/map/widget/on_tap_marker_widget.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 '../../bloc/map_bloc.dart';
import '../../product/base/bloc/base_bloc.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 {
const MapScreen({super.key});
@@ -39,7 +36,7 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
APIServices apiServices = APIServices();
final streamController = StreamController<GoogleMapController>.broadcast();
List<Device> devices = [];
Completer<GoogleMapController> _controller = Completer();
final Completer<GoogleMapController> _controller = Completer();
List<String> imageAssets = [
IconConstants.instance.getIcon("normal_icon"),
IconConstants.instance.getIcon("offline_icon"),
@@ -121,7 +118,8 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
clusterManager.updateMap();
},
polylines: {
if (polylinesSnapshot.data != null && polylinesSnapshot.data!.isNotEmpty) ... [
if (polylinesSnapshot.data != null &&
polylinesSnapshot.data!.isNotEmpty) ...[
Polyline(
polylineId: const PolylineId('router'),
points: polylinesSnapshot.data!,
@@ -189,7 +187,8 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
position: cluster.location,
onTap: () async {
LocationPermission permission = await checkAndRequestPermission();
if (permission == LocationPermission.whileInUse || permission == LocationPermission.always) {
if (permission == LocationPermission.whileInUse ||
permission == LocationPermission.always) {
Position position = await Geolocator.getCurrentPosition();
onTapMarker(
// ignore: use_build_context_synchronously
@@ -277,23 +276,12 @@ class _MapScreenState extends State<MapScreen> with WidgetsBindingObserver {
}
void getAllMarkers() async {
try {
await apiServices.execute(context, () async {
devices.clear();
final devicesList = await apiServices.getOwnerDevices();
for (var device in devicesList) {
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;
// }
}

View File

@@ -1,8 +1,8 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:convert';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import '../../../product/shared/shared_snack_bar.dart';
import '../../../bloc/device_notification_settings_bloc.dart';
import 'device_notification_settings_model.dart';
@@ -111,15 +111,12 @@ class _DeviceNotificationSettingsScreenState
}
void getNotificationSetting() async {
try {
await apiServices.execute(context, () async {
deviceNotifications =
await apiServices.getAllSettingsNotificationOfDevices();
deviceNotificationSettingsBloc.sinkListNotifications
.add(deviceNotifications);
} catch (e) {
if (!mounted) return;
showErrorTopSnackBarCustom(context, e.toString());
}
});
}
Widget listNotificationSetting(
@@ -293,13 +290,14 @@ class _DeviceNotificationSettingsScreenState
void updateDeviceNotification(String thingID, Map<String, int> notifiSettings,
bool isDataChange) async {
try {
await apiServices.execute(context, () async {
int statusCode = await apiServices.updateDeviceNotificationSettings(
thingID, notifiSettings);
if (statusCode == 200) {
showNoIconTopSnackBar(
context,
appLocalization(context).notification_update_device_settings_success,
appLocalization(context)
.notification_update_device_settings_success,
Colors.green,
Colors.white);
} else {
@@ -311,11 +309,6 @@ class _DeviceNotificationSettingsScreenState
}
isDataChange = false;
deviceNotificationSettingsBloc.sinkIsDataChange.add(isDataChange);
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
});
}
}

View File

@@ -1,6 +1,7 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import '../../../product/shared/shared_snack_bar.dart';
import '../../../product/constant/icon/icon_constants.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/extension/context_extension.dart';
import '../../../product/services/language_services.dart';
import 'profile_model.dart';
changeUserInfomation(
@@ -38,7 +38,7 @@ changeUserInfomation(
? IconButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
try {
await apiServices.execute(context,() async {
formKey.currentState!.save();
String latitude = user.latitude ?? "";
String longitude = user.longitude ?? "";
@@ -51,7 +51,7 @@ changeUserInfomation(
"longitude": longitude
};
int statusCode =
await apiServices.updateUserProfile(body);
await apiServices.updateUserProfile(body);
if (statusCode == 200) {
showNoIconTopSnackBar(
modalBottomSheetContext,
@@ -69,11 +69,42 @@ changeUserInfomation(
}
settingsBloc.getUserProfile(context);
Navigator.pop(modalBottomSheetContext);
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
});
// try {
// formKey.currentState!.save();
// 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:
@@ -212,7 +243,7 @@ changeUserInfomation(
child: TextButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
try {
await apiServices.execute(context,() async {
formKey.currentState!.save();
String latitude = user.latitude ?? "";
String longitude = user.longitude ?? "";
@@ -224,8 +255,8 @@ changeUserInfomation(
"latitude": latitude,
"longitude": longitude
};
int statusCode =
await apiServices.updateUserProfile(body);
int statusCode = await apiServices
.updateUserProfile(body);
if (statusCode == 200) {
showNoIconTopSnackBar(
modalBottomSheetContext,
@@ -243,11 +274,7 @@ changeUserInfomation(
}
settingsBloc.getUserProfile(context);
Navigator.pop(modalBottomSheetContext);
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
});
}
},
style: const ButtonStyle(
@@ -296,15 +323,15 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
isChangeSnapshot.data ?? isChange
? IconButton(
onPressed: () async {
try {
if (formKey.currentState!.validate()) {
if (formKey.currentState!.validate()) {
await apiServices.execute(context,() async {
formKey.currentState!.save();
Map<String, dynamic> body = {
"password_old": oldPass,
"password_new": newPass,
};
int statusCode =
await apiServices.updateUserPassword(body);
await apiServices.updateUserPassword(body);
if (statusCode == 200) {
showNoIconTopSnackBar(
modalBottomSheetContext,
@@ -321,11 +348,7 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
Colors.white);
}
Navigator.pop(modalBottomSheetContext);
}
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
});
}
},
icon:
@@ -410,15 +433,15 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
? Center(
child: TextButton(
onPressed: () async {
try {
await apiServices.execute(context,() async {
if (formKey.currentState!.validate()) {
formKey.currentState!.save();
Map<String, dynamic> body = {
"password_old": oldPass,
"password_new": newPass,
};
int statusCode =
await apiServices.updateUserPassword(body);
int statusCode = await apiServices
.updateUserPassword(body);
if (statusCode == 200) {
showNoIconTopSnackBar(
modalBottomSheetContext,
@@ -436,11 +459,38 @@ changeUserPassword(BuildContext context, SettingsBloc settingsBloc) {
}
Navigator.pop(modalBottomSheetContext);
}
} catch (e) {
if (!context.mounted) return;
showErrorTopSnackBarCustom(
context, e.toString());
}
});
// try {
// if (formKey.currentState!.validate()) {
// 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(
backgroundColor:

View File

@@ -1,10 +1,8 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../../product/constant/app/app_constants.dart';
import '../../product/shared/shared_loading_animation.dart';
import '../../product/shared/shared_snack_bar.dart';
import 'profile/profile_screen.dart';
import '../../product/constant/icon/icon_constants.dart';
import '../../product/extension/context_extension.dart';
@@ -29,7 +27,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
void initState() {
super.initState();
settingsBloc = BlocProvider.of(context);
// getUserProfile();
}
@override
@@ -41,7 +38,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
),
body: StreamBuilder<User>(
stream: settingsBloc.streamUserProfile,
// initialData: user,
builder: (context, userSnapshot) {
if (userSnapshot.data == null) {
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 name = "";
if (username.isNotEmpty) {