Files
sfm_app_final/lib/feature/device_log/device_logs_screen.dart
2025-02-11 11:51:58 +07:00

341 lines
14 KiB
Dart

import 'dart:developer';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:sfm_app/product/constant/app/app_constants.dart';
import 'widgets/tag_widget.dart';
import '../devices/device_model.dart';
import '../../bloc/device_logs_bloc.dart';
import '../../product/constant/icon/icon_constants.dart';
import '../../product/extention/context_extention.dart';
import '../../product/services/language_services.dart';
import '../../product/shared/shared_snack_bar.dart';
import '../../product/utils/date_time_utils.dart';
import '../../product/utils/device_utils.dart';
import '../../product/base/bloc/base_bloc.dart';
import 'device_logs_model.dart';
class DeviceLogsScreen extends StatefulWidget {
const DeviceLogsScreen({super.key});
@override
State<DeviceLogsScreen> createState() => _DeviceLogsScreenState();
}
class _DeviceLogsScreenState extends State<DeviceLogsScreen> {
TextEditingController fromDate = TextEditingController();
String fromDateApi = '';
DateTime? dateTime;
String thingID = "";
late DeviceLogsBloc deviceLogsBloc;
List<Device> allDevices = [];
List<SensorLogs> sensors = [];
int offset = 0;
final controller = ScrollController();
bool hasMore = true;
@override
void initState() {
super.initState();
deviceLogsBloc = BlocProvider.of(context);
controller.addListener(
() {
if (controller.position.maxScrollExtent == controller.offset) {
offset += 30;
deviceLogsBloc.getDeviceLogByThingID(
offset, thingID, dateTime!, sensors);
}
},
);
}
@override
void dispose() {
controller.dispose();
sensors.clear();
deviceLogsBloc.sinkSensors.add(sensors);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<List<Device>>(
stream: deviceLogsBloc.streamAllDevices,
builder: (context, allDevicesSnapshot) {
if (allDevicesSnapshot.data?[0].thingId == null) {
deviceLogsBloc.getAllDevices();
return const Center(
child: CircularProgressIndicator(),
);
} else {
return StreamBuilder<List<SensorLogs>>(
stream: deviceLogsBloc.streamSensors,
initialData: sensors,
builder: (context, sensorsSnapshot) {
return Padding(
padding: context.paddingLow,
child: Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
DropdownButtonFormField2<String>(
isExpanded: true,
decoration: InputDecoration(
contentPadding: context.paddingLowVertical,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
),
),
hint: Text(
appLocalization(context)
.choose_device_dropdownButton,
style: const TextStyle(
fontSize: 14,
),
),
items: allDevicesSnapshot.data?.isNotEmpty ?? false
? allDevicesSnapshot.data!
.map(
(device) => DropdownMenuItem<String>(
value: device.thingId,
child: Text(
device.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList()
: [],
buttonStyleData: const ButtonStyleData(
padding: EdgeInsets.only(right: 8),
),
onChanged: (value) {
thingID = value!;
setState(() {});
},
onSaved: (value) {},
iconStyleData: const IconStyleData(
icon: Icon(
Icons.arrow_drop_down,
),
iconSize: 24,
),
dropdownStyleData: DropdownStyleData(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
),
),
menuItemStyleData: const MenuItemStyleData(
padding: EdgeInsets.symmetric(horizontal: 16),
),
),
Padding(
padding: context.paddingLowVertical,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: context.dynamicWidth(0.6),
child: TextField(
controller: fromDate,
decoration: InputDecoration(
icon: IconConstants.instance
.getMaterialIcon(
Icons.calendar_month_outlined,
),
labelText: appLocalization(context)
.choose_date_start_datePicker,
),
readOnly: true,
onTap: () async {
DateTime? datePicker =
await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2023),
lastDate: DateTime(2050),
);
dateTime = datePicker;
if (datePicker != null) {
fromDateApi = DateTimeUtils.instance
.formatDateTimeToString(datePicker);
setState(
() {
fromDate.text =
DateFormat('yyyy-MM-dd')
.format(datePicker);
},
);
}
},
),
),
Center(
child: TextButton.icon(
style: const ButtonStyle(
backgroundColor:
WidgetStatePropertyAll(Colors.green),
foregroundColor:
WidgetStatePropertyAll(Colors.white),
),
onPressed: () {
if (fromDateApi.isEmpty) {
showNoIconTopSnackBar(
context,
appLocalization(context)
.notification_enter_all_inf,
Colors.red,
Colors.white,
);
} else {
deviceLogsBloc.getDeviceLogByThingID(
offset,
thingID,
dateTime!,
sensors);
}
// log("ThingID: $thingID");
// log("From Date: ${DateTimeUtils.instance.formatDateTimeToString(dateTime!)}");
},
icon: IconConstants.instance
.getMaterialIcon(Icons.search),
label: Text(
appLocalization(context)
.find_button_content,
),
),
),
],
),
),
Divider(
height: context.lowValue,
),
Expanded(
child: (() {
if (sensorsSnapshot.data?.isEmpty ?? false) {
return StreamBuilder<String>(
stream: deviceLogsBloc.streammessage,
builder: (context, messageSnapshot) {
return Center(
child: Text(getMessageData(
messageSnapshot.data ?? '',
)),
);
},
);
} else {
return RefreshIndicator(
onRefresh: refresh,
child: ListView.builder(
controller: controller,
itemCount: sensorsSnapshot.data!.length + 1,
itemBuilder: (context, index) {
if (index <
sensorsSnapshot.data!.length) {
return logDetail(
sensorsSnapshot.data![index],
index,
);
} else {
return Padding(
padding: context.paddingLow,
child: StreamBuilder<bool>(
stream:
deviceLogsBloc.streamHasMore,
builder:
(context, hasMoreSnapshot) {
return Center(
child: hasMoreSnapshot.data ??
hasMore
? const CircularProgressIndicator()
: Text(
appLocalization(context)
.main_no_data),
);
},
),
);
}
},
),
);
}
})(),
),
],
),
),
),
);
},
);
}
},
),
);
}
String getMessageData(String data) {
if (data == ApplicationConstants.LOADING) {
return appLocalization(context).loading_message;
} else if (data == ApplicationConstants.NO_DATA) {
return appLocalization(context).main_no_data;
} else {
return appLocalization(context).no_data_message;
}
}
Widget logDetail(SensorLogs sensor, int index) {
return Column(
children: [
ListTile(
subtitle:
Text(DeviceUtils.instance.getDeviceSensorsLog(context, sensor)),
title: Text(
DateTimeUtils.instance
.convertCurrentMillisToDateTimeString(sensor.time ?? 0),
),
),
const Divider(
thickness: 0.5,
indent: 50,
endIndent: 100,
),
],
);
}
Future<void> refresh() async {
offset = 0;
sensors.clear();
deviceLogsBloc.sensors.add(sensors);
hasMore = true;
deviceLogsBloc.sinkHasMore.add(hasMore);
deviceLogsBloc.getDeviceLogByThingID(offset, thingID, dateTime!, sensors);
}
Widget leadingList(SensorLogs sensor) {
Color boxColor;
String content;
if (sensor.name == "1" || sensor.name == "11") {
boxColor = Colors.blue;
content = "Điều khiển";
} else {
boxColor = Colors.lightGreen;
content = appLocalization(context).event_tag_title;
}
return TagWidgetShared(
boxColor: boxColor,
tagContent: content,
boxHeight: context.mediumValue,
boxWidth: context.dynamicWidth(0.2),
);
}
}