mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 09:45:22 +00:00
bug fixes 2
This commit is contained in:
@ -8,7 +8,6 @@ import 'package:syncrow_app/features/auth/model/user_model.dart';
|
|||||||
import 'package:syncrow_app/navigation/navigation_service.dart';
|
import 'package:syncrow_app/navigation/navigation_service.dart';
|
||||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
import 'package:syncrow_app/services/api/authentication_api.dart';
|
import 'package:syncrow_app/services/api/authentication_api.dart';
|
||||||
import 'package:syncrow_app/services/api/profile_api.dart';
|
|
||||||
import 'package:syncrow_app/utils/helpers/shared_preferences_helper.dart';
|
import 'package:syncrow_app/utils/helpers/shared_preferences_helper.dart';
|
||||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||||
|
@ -16,7 +16,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
DoorSensorBloc({
|
DoorSensorBloc({
|
||||||
required this.DSId,
|
required this.DSId,
|
||||||
}) : super(const DoorSensorState()) {
|
}) : super(const DoorSensorState()) {
|
||||||
on<DoorSensorInitial>(_fetchWaterHeaterStatus);
|
on<DoorSensorInitial>(_fetchStatus);
|
||||||
on<ReportLogsInitial>(fetchLogsForLastMonth);
|
on<ReportLogsInitial>(fetchLogsForLastMonth);
|
||||||
on<ToggleLowBatteryEvent>(_toggleLowBattery);
|
on<ToggleLowBatteryEvent>(_toggleLowBattery);
|
||||||
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
||||||
@ -26,9 +26,11 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
bool lowBattery = false;
|
bool lowBattery = false;
|
||||||
bool closingReminder = false;
|
bool closingReminder = false;
|
||||||
bool doorAlarm = false;
|
bool doorAlarm = false;
|
||||||
DoorSensorModel deviceStatus = DoorSensorModel(doorContactState: false, batteryPercentage: 0);
|
DoorSensorModel deviceStatus =
|
||||||
|
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
|
||||||
|
|
||||||
void _fetchWaterHeaterStatus(DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
|
void _fetchStatus(
|
||||||
|
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
|
||||||
emit(DoorSensorLoadingState());
|
emit(DoorSensorLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(DSId);
|
var response = await DevicesAPI.getDeviceStatus(DSId);
|
||||||
@ -49,7 +51,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Toggle functions for each switch
|
// Toggle functions for each switch
|
||||||
void _toggleLowBattery(ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
|
void _toggleLowBattery(
|
||||||
|
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
lowBattery = event.isLowBatteryEnabled;
|
lowBattery = event.isLowBatteryEnabled;
|
||||||
@ -90,7 +93,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
|
void _toggleDoorAlarm(
|
||||||
|
ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||||
try {
|
try {
|
||||||
doorAlarm = event.isDoorAlarmEnabled;
|
doorAlarm = event.isDoorAlarmEnabled;
|
||||||
@ -110,9 +114,11 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []);
|
DeviceReport recordGroups =
|
||||||
|
DeviceReport(startTime: '0', endTime: '0', data: []);
|
||||||
|
|
||||||
Future<void> fetchLogsForLastMonth(ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
|
Future<void> fetchLogsForLastMonth(
|
||||||
|
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
|
||||||
// Get the current date and time
|
// Get the current date and time
|
||||||
DateTime now = DateTime.now();
|
DateTime now = DateTime.now();
|
||||||
|
|
||||||
@ -123,15 +129,18 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
int startTime = lastMonth.millisecondsSinceEpoch;
|
int startTime = lastMonth.millisecondsSinceEpoch;
|
||||||
int endTime = now.millisecondsSinceEpoch;
|
int endTime = now.millisecondsSinceEpoch;
|
||||||
try {
|
try {
|
||||||
|
emit(DoorSensorLoadingState());
|
||||||
var response = await DevicesAPI.getReportLogs(
|
var response = await DevicesAPI.getReportLogs(
|
||||||
startTime: startTime.toString(), // Convert to String if the API expects it
|
startTime:
|
||||||
|
startTime.toString(), // Convert to String if the API expects it
|
||||||
endTime: endTime.toString(), // Convert to String if the API expects it
|
endTime: endTime.toString(), // Convert to String if the API expects it
|
||||||
deviceUuid: DSId,
|
deviceUuid: DSId,
|
||||||
code: 'doorcontact_state',
|
code: 'doorcontact_state',
|
||||||
);
|
);
|
||||||
|
print('response======${response}');
|
||||||
recordGroups = response;
|
recordGroups = response;
|
||||||
// Process response here
|
// Process response here
|
||||||
print(response);
|
emit(UpdateState(doorSensor: deviceStatus));
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
String errorMessage = errorData['message'];
|
String errorMessage = errorData['message'];
|
||||||
@ -142,14 +151,16 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
|
|
||||||
_listenToChanges() {
|
_listenToChanges() {
|
||||||
try {
|
try {
|
||||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$DSId');
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$DSId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
}
|
}
|
||||||
Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
class DeviceReport {
|
class DeviceReport {
|
||||||
final String? deviceUuid;
|
final dynamic deviceUuid;
|
||||||
final String? startTime;
|
final dynamic startTime;
|
||||||
final String? endTime;
|
final dynamic endTime;
|
||||||
final List<DeviceEvent>? data;
|
final List<DeviceEvent>? data;
|
||||||
|
|
||||||
DeviceReport({
|
DeviceReport({
|
||||||
|
@ -4,27 +4,10 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
|
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
// // class DoorRecordsScreen extends StatelessWidget {
|
|
||||||
// final String DSId;
|
|
||||||
// const DoorRecordsScreen({super.key, required this.DSId});
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// return DefaultScaffold(
|
|
||||||
// title: 'Records',
|
|
||||||
// child: BlocProvider(
|
|
||||||
// create: (context) =>
|
|
||||||
// DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
|
|
||||||
// child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
|
||||||
// builder: (context, state) {
|
|
||||||
// final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
|
||||||
// return SizedBox(
|
|
||||||
// child: ListView.builder(
|
|
||||||
// itemCount: doorSensorBloc.recordGroups!.data!.length,
|
|
||||||
// itemBuilder: (context, index) {
|
|
||||||
// final recordGroup = doorSensorBloc.recordGroups!.data![index];
|
|
||||||
|
|
||||||
class DoorRecordsScreen extends StatelessWidget {
|
class DoorRecordsScreen extends StatelessWidget {
|
||||||
final String DSId;
|
final String DSId;
|
||||||
@ -35,36 +18,43 @@ class DoorRecordsScreen extends StatelessWidget {
|
|||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
title: 'Records',
|
title: 'Records',
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
|
create: (context) =>
|
||||||
|
DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
|
||||||
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
||||||
|
|
||||||
if (state is DoorSensorLoadingState) {
|
if (state is DoorSensorLoadingState) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(
|
||||||
}
|
child: DefaultContainer(
|
||||||
|
width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
if (state is DoorSensorFailedState) {
|
|
||||||
return Center(
|
|
||||||
child: Text('Failed to load data: ${state.errorMessage}'),
|
|
||||||
);
|
);
|
||||||
}
|
} else if (state is UpdateState) {
|
||||||
|
// Group records by formatted date
|
||||||
|
final Map<String, List<DeviceEvent>> groupedRecords = {};
|
||||||
|
|
||||||
if (state is UpdateState) {
|
// Iterate over the data list in DeviceReport
|
||||||
final recordGroups = context.read<DoorSensorBloc>().recordGroups;
|
for (var record in doorSensorBloc.recordGroups.data!) {
|
||||||
|
final DateTime eventDateTime =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
|
||||||
|
final String formattedDate =
|
||||||
|
DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
|
||||||
|
|
||||||
if (recordGroups.data == null || recordGroups.data!.isEmpty) {
|
// Group by formatted date
|
||||||
return const Center(child: Text('No records available.'));
|
if (groupedRecords.containsKey(formattedDate)) {
|
||||||
|
groupedRecords[formattedDate]!.add(record);
|
||||||
|
} else {
|
||||||
|
groupedRecords[formattedDate] = [record];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build the ListView with grouped data
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
itemCount: recordGroups.data!.length,
|
itemCount: groupedRecords.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final record = recordGroups.data![index];
|
final String date = groupedRecords.keys.elementAt(index);
|
||||||
|
final List<DeviceEvent> recordsForDate =
|
||||||
// Convert eventTime to a human-readable format
|
groupedRecords[date]!;
|
||||||
final DateTime eventDateTime =
|
|
||||||
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
|
|
||||||
final String formattedDate = DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
|
|
||||||
final String formattedTime = DateFormat('HH:mm:ss').format(eventDateTime);
|
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -73,30 +63,57 @@ class DoorRecordsScreen extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
formattedDate,
|
date,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 18,
|
color: ColorsManager.grayColor,
|
||||||
fontWeight: FontWeight.bold,
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Display the event details in DefaultContainer
|
// List of records for the specific date
|
||||||
|
|
||||||
DefaultContainer(
|
DefaultContainer(
|
||||||
child: ListTile(
|
child: Column(
|
||||||
leading: Icon(
|
children: [
|
||||||
record.value == 'true'
|
...recordsForDate.map((record) {
|
||||||
? Icons.radio_button_checked
|
final DateTime eventDateTime =
|
||||||
: Icons.radio_button_unchecked,
|
DateTime.fromMillisecondsSinceEpoch(
|
||||||
color: record.value == 'true' ? Colors.blue : Colors.grey,
|
record.eventTime!);
|
||||||
),
|
final String formattedTime =
|
||||||
title: Text(
|
DateFormat('HH:mm:ss').format(eventDateTime);
|
||||||
'Status: ${record.value}',
|
|
||||||
style: const TextStyle(
|
return Column(
|
||||||
fontWeight: FontWeight.bold,
|
children: [
|
||||||
fontSize: 18,
|
Container(
|
||||||
),
|
child: ListTile(
|
||||||
),
|
leading: Icon(
|
||||||
subtitle: Text('Time: $formattedTime'),
|
record.value == 'true'
|
||||||
|
? Icons.radio_button_checked
|
||||||
|
: Icons.radio_button_unchecked,
|
||||||
|
color: record.value == 'true'
|
||||||
|
? Colors.blue
|
||||||
|
: Colors.grey,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
record.value == 'true'
|
||||||
|
? "Opened"
|
||||||
|
: "Closed",
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text('$formattedTime'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
color: ColorsManager.graysColor,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -104,7 +121,6 @@ class DoorRecordsScreen extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return const Center(child: Text('No data available.'));
|
return const Center(child: Text('No data available.'));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -63,17 +63,20 @@ class ScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
pageBuilder:
|
||||||
switchCode :"switch_1",
|
(context, animation1, animation2) =>
|
||||||
device: device,
|
TimerScheduleScreen(
|
||||||
deviceCode: 'countdown_1',
|
switchCode: "switch_1",
|
||||||
)));
|
device: device,
|
||||||
|
deviceCode: 'countdown_1',
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding:
|
padding: const EdgeInsets.only(
|
||||||
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
|
left: 25, right: 15, top: 20, bottom: 20),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
BodySmall(
|
BodySmall(
|
||||||
text: "Bedside Light",
|
text: "Bedside Light",
|
||||||
@ -100,17 +103,20 @@ class ScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
pageBuilder:
|
||||||
switchCode :"switch_2",
|
(context, animation1, animation2) =>
|
||||||
device: device,
|
TimerScheduleScreen(
|
||||||
deviceCode: 'countdown_2',
|
switchCode: "switch_2",
|
||||||
)));
|
device: device,
|
||||||
|
deviceCode: 'countdown_2',
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding:
|
padding: const EdgeInsets.only(
|
||||||
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
|
left: 25, right: 15, top: 20, bottom: 20),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
BodySmall(
|
BodySmall(
|
||||||
text: "Ceiling Light",
|
text: "Ceiling Light",
|
||||||
@ -137,17 +143,20 @@ class ScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
pageBuilder:
|
||||||
switchCode :"switch_3",
|
(context, animation1, animation2) =>
|
||||||
device: device,
|
TimerScheduleScreen(
|
||||||
deviceCode: 'countdown_3',
|
switchCode: "switch_3",
|
||||||
)));
|
device: device,
|
||||||
|
deviceCode: 'countdown_3',
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding:
|
padding: const EdgeInsets.only(
|
||||||
const EdgeInsets.only(left: 25, right: 15, top: 20, bottom: 20),
|
left: 25, right: 15, top: 20, bottom: 20),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
BodySmall(
|
BodySmall(
|
||||||
text: "Spotlight",
|
text: "Spotlight",
|
||||||
|
@ -22,7 +22,10 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
final String deviceCode;
|
final String deviceCode;
|
||||||
final String switchCode;
|
final String switchCode;
|
||||||
const TimerScheduleScreen(
|
const TimerScheduleScreen(
|
||||||
{required this.device, required this.deviceCode, required this.switchCode, super.key});
|
{required this.device,
|
||||||
|
required this.deviceCode,
|
||||||
|
required this.switchCode,
|
||||||
|
super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -32,7 +35,8 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
statusBarIconBrightness: Brightness.light,
|
statusBarIconBrightness: Brightness.light,
|
||||||
),
|
),
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => ThreeGangBloc(switchCode: switchCode, threeGangId: device.uuid ?? '')
|
create: (context) => ThreeGangBloc(
|
||||||
|
switchCode: switchCode, threeGangId: device.uuid ?? '')
|
||||||
..add(GetCounterEvent(deviceCode: deviceCode))
|
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||||
..add(GetScheduleEvent()),
|
..add(GetScheduleEvent()),
|
||||||
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||||
@ -94,13 +98,15 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
decoration: const ShapeDecoration(
|
decoration: const ShapeDecoration(
|
||||||
color: ColorsManager.onPrimaryColor,
|
color: ColorsManager.onPrimaryColor,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(30)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: TabBar(
|
child: TabBar(
|
||||||
onTap: (value) {
|
onTap: (value) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
if (threeGangBloc.createSchedule == true) {
|
if (threeGangBloc.createSchedule ==
|
||||||
|
true) {
|
||||||
threeGangBloc.toggleCreateSchedule();
|
threeGangBloc.toggleCreateSchedule();
|
||||||
}
|
}
|
||||||
threeGangBloc.toggleSelectedIndex(0);
|
threeGangBloc.toggleSelectedIndex(0);
|
||||||
@ -108,19 +114,21 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
threeGangBloc.toggleSelectedIndex(1);
|
threeGangBloc.toggleSelectedIndex(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
indicatorColor: Colors.white, // Customize the indicator
|
indicatorColor: Colors.white,
|
||||||
dividerHeight: 0,
|
dividerHeight: 0,
|
||||||
indicatorSize: TabBarIndicatorSize.tab,
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
indicator: const ShapeDecoration(
|
indicator: const ShapeDecoration(
|
||||||
color: ColorsManager.slidingBlueColor,
|
color: ColorsManager.slidingBlueColor,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(20)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(
|
Tab(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 10),
|
||||||
child: BodySmall(
|
child: BodySmall(
|
||||||
text: 'Countdown',
|
text: 'Countdown',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
@ -133,7 +141,8 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Schedule',
|
'Schedule',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
@ -153,84 +162,118 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
countNum > 0
|
countNum > 0
|
||||||
? BodyLarge(
|
? BodyLarge(
|
||||||
text: _formatDuration(countNum),
|
text: _formatDuration(
|
||||||
fontColor: ColorsManager.slidingBlueColor,
|
countNum),
|
||||||
|
fontColor: ColorsManager
|
||||||
|
.slidingBlueColor,
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
)
|
)
|
||||||
: CupertinoTimerPicker(
|
: CupertinoTimerPicker(
|
||||||
mode: CupertinoTimerPickerMode.hm,
|
mode:
|
||||||
|
CupertinoTimerPickerMode
|
||||||
|
.hm,
|
||||||
onTimerDurationChanged:
|
onTimerDurationChanged:
|
||||||
(Duration newDuration) {
|
(Duration
|
||||||
|
newDuration) {
|
||||||
duration = newDuration;
|
duration = newDuration;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (state is LoadingNewSate) {
|
if (state
|
||||||
|
is LoadingNewSate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (countNum > 0) {
|
if (countNum > 0) {
|
||||||
threeGangBloc.add(SetCounterValue(
|
threeGangBloc.add(
|
||||||
deviceCode: deviceCode,
|
SetCounterValue(
|
||||||
duration: Duration.zero));
|
deviceCode:
|
||||||
} else if (duration != Duration.zero) {
|
deviceCode,
|
||||||
threeGangBloc.add(SetCounterValue(
|
duration: Duration
|
||||||
deviceCode: deviceCode,
|
.zero));
|
||||||
duration: duration));
|
} else if (duration !=
|
||||||
|
Duration.zero) {
|
||||||
|
threeGangBloc.add(
|
||||||
|
SetCounterValue(
|
||||||
|
deviceCode:
|
||||||
|
deviceCode,
|
||||||
|
duration:
|
||||||
|
duration));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: SvgPicture.asset(countNum > 0
|
child: SvgPicture.asset(
|
||||||
? Assets.pauseIcon
|
countNum > 0
|
||||||
: Assets.playIcon)),
|
? Assets.pauseIcon
|
||||||
|
: Assets.playIcon)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Column(
|
SizedBox(
|
||||||
mainAxisAlignment: threeGangBloc.listSchedule.isNotEmpty
|
child: threeGangBloc.createSchedule ==
|
||||||
? MainAxisAlignment.start
|
true
|
||||||
: MainAxisAlignment.center,
|
? CreateSchedule(
|
||||||
children: [
|
onToggleChanged: (bool isOn) {
|
||||||
SizedBox(
|
threeGangBloc.toggleSchedule =
|
||||||
child: threeGangBloc.createSchedule == true
|
isOn;
|
||||||
? CreateSchedule(
|
},
|
||||||
onToggleChanged: (bool isOn) {
|
onDateTimeChanged:
|
||||||
threeGangBloc.toggleSchedule = isOn;
|
(DateTime dateTime) {
|
||||||
},
|
threeGangBloc.selectedTime =
|
||||||
onDateTimeChanged: (DateTime dateTime) {
|
dateTime;
|
||||||
threeGangBloc.selectedTime = dateTime;
|
},
|
||||||
},
|
days: threeGangBloc.days,
|
||||||
days: threeGangBloc.days,
|
selectDays: (List<String>
|
||||||
selectDays: (List<String> selectedDays) {
|
selectedDays) {
|
||||||
threeGangBloc.selectedDays = selectedDays;
|
threeGangBloc.selectedDays =
|
||||||
},
|
selectedDays;
|
||||||
)
|
},
|
||||||
: Padding(
|
)
|
||||||
padding: const EdgeInsets.only(top: 10),
|
: Padding(
|
||||||
child: ScheduleListView(
|
padding: const EdgeInsets.only(
|
||||||
listSchedule: threeGangBloc
|
top: 10),
|
||||||
.listSchedule, // Pass the schedule list here
|
child: Column(
|
||||||
onDismissed: (scheduleId) {
|
mainAxisAlignment:
|
||||||
threeGangBloc.listSchedule.removeWhere(
|
MainAxisAlignment.start,
|
||||||
(schedule) =>
|
crossAxisAlignment:
|
||||||
schedule.scheduleId == scheduleId);
|
CrossAxisAlignment.start,
|
||||||
threeGangBloc.add(
|
children: [
|
||||||
DeleteScheduleEvent(id: scheduleId));
|
Expanded(
|
||||||
},
|
child: ScheduleListView(
|
||||||
onToggleSchedule: (scheduleId, isEnabled) {
|
listSchedule: threeGangBloc
|
||||||
threeGangBloc.add(ToggleScheduleEvent(
|
.listSchedule, // Pass the schedule list here
|
||||||
id: scheduleId,
|
onDismissed:
|
||||||
toggle: isEnabled,
|
(scheduleId) {
|
||||||
));
|
threeGangBloc
|
||||||
},
|
.listSchedule
|
||||||
|
.removeWhere(
|
||||||
|
(schedule) =>
|
||||||
|
schedule
|
||||||
|
.scheduleId ==
|
||||||
|
scheduleId);
|
||||||
|
threeGangBloc.add(
|
||||||
|
DeleteScheduleEvent(
|
||||||
|
id: scheduleId));
|
||||||
|
},
|
||||||
|
onToggleSchedule:
|
||||||
|
(scheduleId,
|
||||||
|
isEnabled) {
|
||||||
|
threeGangBloc.add(
|
||||||
|
ToggleScheduleEvent(
|
||||||
|
id: scheduleId,
|
||||||
|
toggle: isEnabled,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -63,7 +63,7 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: DefaultTabController(
|
child: DefaultTabController(
|
||||||
length: 2,
|
length: 2,
|
||||||
child: DefaultScaffold(
|
child: DefaultScaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
@ -73,177 +73,204 @@ class TimerScheduleScreen extends StatelessWidget {
|
|||||||
fontWeight: FontsManager.bold,
|
fontWeight: FontsManager.bold,
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
twoGangBloc.createSchedule == true ?
|
twoGangBloc.createSchedule == true
|
||||||
TextButton(
|
? TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
twoGangBloc.add(TwoGangSave());
|
twoGangBloc.add(TwoGangSave());
|
||||||
},
|
},
|
||||||
child: const Text('Save')
|
child: const Text('Save'))
|
||||||
) :
|
: twoGangBloc.selectedTabIndex == 1
|
||||||
twoGangBloc.selectedTabIndex==1? IconButton(
|
? IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
twoGangBloc.toggleCreateSchedule();
|
twoGangBloc.toggleCreateSchedule();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
):SizedBox(),
|
)
|
||||||
|
: SizedBox(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child:
|
child: state is LoadingInitialState
|
||||||
state is LoadingInitialState?
|
? const Center(child: CircularProgressIndicator())
|
||||||
const Center(child: CircularProgressIndicator()):
|
: Column(
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
decoration: const ShapeDecoration(
|
|
||||||
color: ColorsManager.onPrimaryColor,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: TabBar(
|
|
||||||
onTap: (value) {
|
|
||||||
print(value);
|
|
||||||
if(value==0){
|
|
||||||
if(twoGangBloc.createSchedule == true){
|
|
||||||
twoGangBloc.toggleCreateSchedule();
|
|
||||||
}
|
|
||||||
twoGangBloc.toggleSelectedIndex(0);
|
|
||||||
|
|
||||||
}else{
|
|
||||||
twoGangBloc.toggleSelectedIndex(1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
indicatorColor: Colors.white, // Customize the indicator
|
|
||||||
dividerHeight: 0,
|
|
||||||
indicatorSize: TabBarIndicatorSize.tab,
|
|
||||||
indicator: const ShapeDecoration(
|
|
||||||
color: ColorsManager.slidingBlueColor,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.all(Radius.circular(20)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
tabs: [
|
|
||||||
Tab(
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 10),
|
|
||||||
child: BodySmall(
|
|
||||||
text: 'Countdown',
|
|
||||||
style: context.bodySmall.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Tab(
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
||||||
child: Text(
|
|
||||||
'Schedule',
|
|
||||||
style: context.bodySmall.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: TabBarView(
|
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Container(
|
||||||
child: Container(
|
width: MediaQuery.of(context).size.width,
|
||||||
child: Column(
|
decoration: const ShapeDecoration(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
color: ColorsManager.onPrimaryColor,
|
||||||
children: [
|
shape: RoundedRectangleBorder(
|
||||||
countNum > 0
|
borderRadius:
|
||||||
? BodyLarge(
|
BorderRadius.all(Radius.circular(30)),
|
||||||
text: _formatDuration(countNum),
|
|
||||||
fontColor:
|
|
||||||
ColorsManager.slidingBlueColor,
|
|
||||||
fontSize: 40,
|
|
||||||
)
|
|
||||||
: CupertinoTimerPicker(
|
|
||||||
mode: CupertinoTimerPickerMode.hm,
|
|
||||||
onTimerDurationChanged:
|
|
||||||
(Duration newDuration) {
|
|
||||||
duration = newDuration;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
if (state is LoadingNewSate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (countNum > 0) {
|
|
||||||
twoGangBloc.add(SetCounterValue(
|
|
||||||
deviceCode: deviceCode,
|
|
||||||
duration: Duration.zero));
|
|
||||||
} else if (duration != Duration.zero) {
|
|
||||||
twoGangBloc.add(SetCounterValue(
|
|
||||||
deviceCode: deviceCode,
|
|
||||||
duration: duration));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: SvgPicture.asset(countNum > 0
|
|
||||||
? Assets.pauseIcon
|
|
||||||
: Assets.playIcon)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
child: TabBar(
|
||||||
Column(
|
onTap: (value) {
|
||||||
mainAxisAlignment:twoGangBloc.listSchedule.isNotEmpty?
|
print(value);
|
||||||
MainAxisAlignment.start:MainAxisAlignment.center,
|
if (value == 0) {
|
||||||
children: [
|
if (twoGangBloc.createSchedule ==
|
||||||
SizedBox(
|
true) {
|
||||||
child: twoGangBloc.createSchedule == true ?
|
twoGangBloc.toggleCreateSchedule();
|
||||||
CreateSchedule(
|
}
|
||||||
onToggleChanged: (bool isOn) {
|
twoGangBloc.toggleSelectedIndex(0);
|
||||||
twoGangBloc.toggleSchedule = isOn;
|
} else {
|
||||||
},
|
twoGangBloc.toggleSelectedIndex(1);
|
||||||
onDateTimeChanged: (DateTime dateTime) {
|
}
|
||||||
twoGangBloc.selectedTime=dateTime;
|
},
|
||||||
},
|
indicatorColor:
|
||||||
days: twoGangBloc.days,
|
Colors.white, // Customize the indicator
|
||||||
selectDays: (List<String> selectedDays) {
|
dividerHeight: 0,
|
||||||
twoGangBloc.selectedDays = selectedDays;
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
},
|
indicator: const ShapeDecoration(
|
||||||
)
|
color: ColorsManager.slidingBlueColor,
|
||||||
:
|
shape: RoundedRectangleBorder(
|
||||||
Padding(
|
borderRadius: BorderRadius.all(
|
||||||
padding: const EdgeInsets.only(top: 10),
|
Radius.circular(20)),
|
||||||
child: ScheduleListView(
|
|
||||||
listSchedule: twoGangBloc.listSchedule, // Pass the schedule list here
|
|
||||||
onDismissed: (scheduleId) {
|
|
||||||
twoGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
|
||||||
twoGangBloc.add(DeleteScheduleEvent(id: scheduleId));
|
|
||||||
},
|
|
||||||
onToggleSchedule: (scheduleId, isEnabled) {
|
|
||||||
twoGangBloc.add(ToggleScheduleEvent(
|
|
||||||
id: scheduleId,
|
|
||||||
toggle: isEnabled,
|
|
||||||
));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
tabs: [
|
||||||
|
Tab(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 10),
|
||||||
|
child: BodySmall(
|
||||||
|
text: 'Countdown',
|
||||||
|
style: context.bodySmall.copyWith(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 10),
|
||||||
|
child: Text(
|
||||||
|
'Schedule',
|
||||||
|
style: context.bodySmall.copyWith(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TabBarView(
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
countNum > 0
|
||||||
|
? BodyLarge(
|
||||||
|
text: _formatDuration(
|
||||||
|
countNum),
|
||||||
|
fontColor: ColorsManager
|
||||||
|
.slidingBlueColor,
|
||||||
|
fontSize: 40,
|
||||||
|
)
|
||||||
|
: CupertinoTimerPicker(
|
||||||
|
mode:
|
||||||
|
CupertinoTimerPickerMode
|
||||||
|
.hm,
|
||||||
|
onTimerDurationChanged:
|
||||||
|
(Duration
|
||||||
|
newDuration) {
|
||||||
|
duration = newDuration;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (state
|
||||||
|
is LoadingNewSate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (countNum > 0) {
|
||||||
|
twoGangBloc.add(
|
||||||
|
SetCounterValue(
|
||||||
|
deviceCode:
|
||||||
|
deviceCode,
|
||||||
|
duration: Duration
|
||||||
|
.zero));
|
||||||
|
} else if (duration !=
|
||||||
|
Duration.zero) {
|
||||||
|
twoGangBloc.add(
|
||||||
|
SetCounterValue(
|
||||||
|
deviceCode:
|
||||||
|
deviceCode,
|
||||||
|
duration:
|
||||||
|
duration));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
countNum > 0
|
||||||
|
? Assets.pauseIcon
|
||||||
|
: Assets.playIcon)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
child: twoGangBloc.createSchedule ==
|
||||||
|
true
|
||||||
|
? CreateSchedule(
|
||||||
|
onToggleChanged: (bool isOn) {
|
||||||
|
twoGangBloc.toggleSchedule =
|
||||||
|
isOn;
|
||||||
|
},
|
||||||
|
onDateTimeChanged:
|
||||||
|
(DateTime dateTime) {
|
||||||
|
twoGangBloc.selectedTime =
|
||||||
|
dateTime;
|
||||||
|
},
|
||||||
|
days: twoGangBloc.days,
|
||||||
|
selectDays: (List<String>
|
||||||
|
selectedDays) {
|
||||||
|
twoGangBloc.selectedDays =
|
||||||
|
selectedDays;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 10),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ScheduleListView(
|
||||||
|
listSchedule: twoGangBloc.listSchedule, // Pass the schedule list here
|
||||||
|
onDismissed:(scheduleId) {
|
||||||
|
twoGangBloc .listSchedule
|
||||||
|
.removeWhere( (schedule) => schedule .scheduleId == scheduleId);
|
||||||
|
twoGangBloc.add(
|
||||||
|
DeleteScheduleEvent( id: scheduleId));
|
||||||
|
},
|
||||||
|
onToggleSchedule:
|
||||||
|
(scheduleId,
|
||||||
|
isEnabled) {
|
||||||
|
twoGangBloc.add(
|
||||||
|
ToggleScheduleEvent(
|
||||||
|
id: scheduleId,
|
||||||
|
toggle: isEnabled,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
)));
|
||||||
],
|
|
||||||
),
|
|
||||||
))
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
@ -13,7 +8,6 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart
|
|||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
|
||||||
|
|
||||||
class CirculateListView extends StatelessWidget {
|
class CirculateListView extends StatelessWidget {
|
||||||
final List<ScheduleModel> listSchedule;
|
final List<ScheduleModel> listSchedule;
|
||||||
final Function(String) onDismissed;
|
final Function(String) onDismissed;
|
||||||
@ -30,96 +24,98 @@ class CirculateListView extends StatelessWidget {
|
|||||||
return Center(
|
return Center(
|
||||||
child: listSchedule.isNotEmpty
|
child: listSchedule.isNotEmpty
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: listSchedule.length,
|
itemCount: listSchedule.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return Dismissible(
|
return Dismissible(
|
||||||
key: Key(listSchedule[index].scheduleId),
|
key: Key(listSchedule[index].scheduleId),
|
||||||
background: Container(
|
background: Container(
|
||||||
padding: const EdgeInsets.only(right: 10),
|
padding: const EdgeInsets.only(right: 10),
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
decoration: const ShapeDecoration(
|
decoration: const ShapeDecoration(
|
||||||
color: Color(0xFFFF0000),
|
color: Color(0xFFFF0000),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 10, right: 10),
|
padding: const EdgeInsets.only(bottom: 10, right: 10),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.assetsDeleteIcon,
|
Assets.assetsDeleteIcon,
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 22,
|
height: 22,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
direction: DismissDirection.endToStart,
|
direction: DismissDirection.endToStart,
|
||||||
onDismissed: (direction) {
|
onDismissed: (direction) {
|
||||||
|
onDismissed(listSchedule[index].scheduleId);
|
||||||
|
|
||||||
onDismissed(listSchedule[index].scheduleId);
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('Schedule removed')),
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
);
|
||||||
const SnackBar(content: Text('Schedule removed')),
|
},
|
||||||
);
|
child: InkWell(
|
||||||
},
|
onTap: () {},
|
||||||
child: InkWell(
|
child: DefaultContainer(
|
||||||
onTap: () {
|
padding: const EdgeInsets.all(20),
|
||||||
|
height: MediaQuery.of(context).size.height / 6.5,
|
||||||
},
|
child: Row(
|
||||||
child: DefaultContainer(
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
height: MediaQuery.of(context).size.height / 6.4,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
BodyLarge(
|
Expanded(
|
||||||
text: '12:30 AM - 01:30 PM',
|
flex: 2,
|
||||||
// text: listSchedule[index].time,
|
child: Column(
|
||||||
fontWeight: FontWeight.w500,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
fontColor: Colors.black,
|
children: [
|
||||||
fontSize: 22,
|
Row(
|
||||||
|
children: [
|
||||||
|
BodyLarge(
|
||||||
|
text: '12:30 AM - 01:30 PM',
|
||||||
|
// text: listSchedule[index].time,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontColor: Colors.black,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(listSchedule[index].days.join(' ')),
|
||||||
|
// Text('Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
|
||||||
|
Text(
|
||||||
|
'Start Duration: 0h 10m End Duration: 0h 15m'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
leading: const BodyMedium(
|
||||||
|
text: '',
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
trailing: Transform.scale(
|
||||||
|
scale: .8,
|
||||||
|
child: CupertinoSwitch(
|
||||||
|
value: listSchedule[index].enable,
|
||||||
|
onChanged: (value) {
|
||||||
|
onToggleSchedule(
|
||||||
|
listSchedule[index].scheduleId,
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
applyTheme: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Text(listSchedule[index].days.join(' ')),
|
|
||||||
// Text('Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
|
|
||||||
Text('Start Duration: 0h 10m End Duration: 0h 15m'),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: ListTile(
|
);
|
||||||
contentPadding: EdgeInsets.zero,
|
},
|
||||||
leading: const BodyMedium(
|
|
||||||
text: '',
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
),
|
|
||||||
trailing: Transform.scale(
|
|
||||||
scale: .8,
|
|
||||||
child: CupertinoSwitch(
|
|
||||||
value: listSchedule[index].enable,
|
|
||||||
onChanged: (value) {
|
|
||||||
onToggleSchedule(
|
|
||||||
listSchedule[index].scheduleId,
|
|
||||||
value,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
applyTheme: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
)
|
||||||
},
|
: const EmptySchedule());
|
||||||
),
|
|
||||||
)
|
|
||||||
: const EmptySchedule()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,33 +76,36 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
fontWeight: FontsManager.bold,
|
fontWeight: FontsManager.bold,
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
waterHeaterBloc.createSchedule == true && waterHeaterBloc.selectedTabIndex == 1 ?
|
waterHeaterBloc.createSchedule == true &&
|
||||||
TextButton(
|
waterHeaterBloc.selectedTabIndex == 1
|
||||||
onPressed: () {
|
? TextButton(
|
||||||
waterHeaterBloc.add(ScheduleSave());
|
onPressed: () {
|
||||||
},
|
waterHeaterBloc.add(ScheduleSave());
|
||||||
child: const Text('Save')) : waterHeaterBloc.selectedTabIndex == 1
|
|
||||||
? IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
waterHeaterBloc.toggleCreateSchedule();
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.add),
|
|
||||||
)
|
|
||||||
: const SizedBox(),
|
|
||||||
waterHeaterBloc.createCirculate == true &&waterHeaterBloc.selectedTabIndex==2 ?
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
waterHeaterBloc.add(ScheduleSave());
|
|
||||||
},
|
|
||||||
child: const Text('Save'))
|
|
||||||
: waterHeaterBloc.selectedTabIndex == 2
|
|
||||||
? IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
waterHeaterBloc.toggleCreateCirculate();
|
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
child: const Text('Save'))
|
||||||
)
|
: waterHeaterBloc.selectedTabIndex == 1
|
||||||
: const SizedBox(),
|
? IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
waterHeaterBloc.toggleCreateSchedule();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
waterHeaterBloc.createCirculate == true &&
|
||||||
|
waterHeaterBloc.selectedTabIndex == 2
|
||||||
|
? TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
waterHeaterBloc.add(ScheduleSave());
|
||||||
|
},
|
||||||
|
child: const Text('Save'))
|
||||||
|
: waterHeaterBloc.selectedTabIndex == 2
|
||||||
|
? IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
waterHeaterBloc.toggleCreateCirculate();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: state is WHLoadingState
|
child: state is WHLoadingState
|
||||||
@ -124,20 +127,29 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
labelPadding: EdgeInsets.zero,
|
labelPadding: EdgeInsets.zero,
|
||||||
onTap: (value) {
|
onTap: (value) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
if (waterHeaterBloc.createSchedule == true) {
|
if (waterHeaterBloc.createSchedule ==
|
||||||
waterHeaterBloc.toggleCreateSchedule();
|
true) {
|
||||||
|
waterHeaterBloc
|
||||||
|
.toggleCreateSchedule();
|
||||||
}
|
}
|
||||||
waterHeaterBloc.toggleSelectedIndex(value);
|
waterHeaterBloc
|
||||||
} else if (value == 2) {
|
.toggleSelectedIndex(value);
|
||||||
if (waterHeaterBloc.createCirculate == true) {
|
} else if (value == 2) {
|
||||||
waterHeaterBloc.toggleCreateCirculate();
|
if (waterHeaterBloc.createCirculate ==
|
||||||
|
true) {
|
||||||
|
waterHeaterBloc
|
||||||
|
.toggleCreateCirculate();
|
||||||
}
|
}
|
||||||
waterHeaterBloc.toggleSelectedIndex(value);
|
waterHeaterBloc
|
||||||
|
.toggleSelectedIndex(value);
|
||||||
} else {
|
} else {
|
||||||
if (waterHeaterBloc.createSchedule == true) {
|
if (waterHeaterBloc.createSchedule ==
|
||||||
waterHeaterBloc.toggleCreateSchedule();
|
true) {
|
||||||
|
waterHeaterBloc
|
||||||
|
.toggleCreateSchedule();
|
||||||
}
|
}
|
||||||
waterHeaterBloc.toggleSelectedIndex(value);
|
waterHeaterBloc
|
||||||
|
.toggleSelectedIndex(value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
indicatorColor: Colors.white,
|
indicatorColor: Colors.white,
|
||||||
@ -151,96 +163,128 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
isScrollable: false,
|
isScrollable: false,
|
||||||
labelColor: Colors.white, // Text color when selected
|
labelColor: Colors
|
||||||
unselectedLabelColor: ColorsManager.blackColor, // Text color when not selected
|
.white, // Text color when selected
|
||||||
|
unselectedLabelColor: ColorsManager
|
||||||
|
.blackColor, // Text color when not selected
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(
|
Tab(
|
||||||
icon: SvgPicture.asset(
|
icon: Padding(
|
||||||
Assets.scheduleTimeIcon,
|
padding: const EdgeInsets.only(
|
||||||
color: waterHeaterBloc.selectedTabIndex == 0
|
top: 10.0),
|
||||||
? Colors.white
|
child: SvgPicture.asset(
|
||||||
: ColorsManager.blackColor, // Change icon color based on selectedIndex
|
Assets.scheduleTimeIcon,
|
||||||
|
color: waterHeaterBloc
|
||||||
|
.selectedTabIndex ==
|
||||||
|
0
|
||||||
|
? Colors.white
|
||||||
|
: ColorsManager
|
||||||
|
.blackColor, // Change icon color based on selectedIndex
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 10),
|
vertical: 5),
|
||||||
child: BodySmall(
|
child: BodySmall(
|
||||||
text: 'Countdown',
|
text: 'Countdown',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc.selectedTabIndex == 0
|
color: waterHeaterBloc
|
||||||
|
.selectedTabIndex ==
|
||||||
|
0
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager
|
: ColorsManager
|
||||||
.blackColor, // Text color based on selectedTabIndex
|
.blackColor, // Text color based on selectedTabIndex
|
||||||
fontSize: 8,
|
fontSize: 10,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: SvgPicture.asset(
|
icon: Padding(
|
||||||
Assets.scheduleCelenderIcon,
|
padding:
|
||||||
color: waterHeaterBloc.selectedTabIndex == 1
|
const EdgeInsets.only(top: 10),
|
||||||
? Colors.white
|
child: SvgPicture.asset(
|
||||||
: ColorsManager.blackColor,
|
Assets.scheduleCelenderIcon,
|
||||||
|
color: waterHeaterBloc
|
||||||
|
.selectedTabIndex ==
|
||||||
|
1
|
||||||
|
? Colors.white
|
||||||
|
: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 10),
|
vertical: 5),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Schedule',
|
'Schedule',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc.selectedTabIndex == 1
|
color: waterHeaterBloc
|
||||||
|
.selectedTabIndex ==
|
||||||
|
1
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
fontSize: 8,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: SvgPicture.asset(
|
icon: Padding(
|
||||||
Assets.scheduleCirculateIcon,
|
padding:
|
||||||
color: waterHeaterBloc.selectedTabIndex == 2
|
const EdgeInsets.only(top: 10),
|
||||||
? Colors.white
|
child: SvgPicture.asset(
|
||||||
: ColorsManager.blackColor,
|
Assets.scheduleCirculateIcon,
|
||||||
|
color: waterHeaterBloc
|
||||||
|
.selectedTabIndex ==
|
||||||
|
2
|
||||||
|
? Colors.white
|
||||||
|
: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 10),
|
vertical: 5),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Circulate',
|
'Circulate',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc
|
||||||
.selectedTabIndex == 2
|
.selectedTabIndex ==
|
||||||
|
2
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
fontSize: 8,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: SvgPicture.asset(
|
icon: Padding(
|
||||||
Assets.scheduleInchingIcon,
|
padding:
|
||||||
color: waterHeaterBloc
|
const EdgeInsets.only(top: 10),
|
||||||
.selectedTabIndex == 3
|
child: SvgPicture.asset(
|
||||||
? Colors.white
|
Assets.scheduleInchingIcon,
|
||||||
: ColorsManager.blackColor,
|
color: waterHeaterBloc
|
||||||
|
.selectedTabIndex ==
|
||||||
|
3
|
||||||
|
? Colors.white
|
||||||
|
: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 10),
|
vertical: 5),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Inching',
|
'Inching',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc
|
||||||
.selectedTabIndex == 3
|
.selectedTabIndex ==
|
||||||
|
3
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
fontSize: 8,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -308,93 +352,132 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Column(
|
SizedBox(
|
||||||
mainAxisAlignment: waterHeaterBloc
|
child: waterHeaterBloc.createSchedule ==
|
||||||
.listSchedule.isNotEmpty
|
true
|
||||||
? MainAxisAlignment.start
|
? CreateSchedule(
|
||||||
: MainAxisAlignment.center,
|
onToggleChanged: (bool isOn) {
|
||||||
children: [
|
waterHeaterBloc
|
||||||
SizedBox(
|
.toggleSchedule = isOn;
|
||||||
child: waterHeaterBloc.createSchedule == true
|
},
|
||||||
? CreateSchedule(
|
onDateTimeChanged:
|
||||||
onToggleChanged: (bool isOn) {
|
(DateTime dateTime) {
|
||||||
waterHeaterBloc.toggleSchedule = isOn;
|
waterHeaterBloc.selectedTime =
|
||||||
},
|
dateTime;
|
||||||
onDateTimeChanged: (DateTime dateTime) {
|
},
|
||||||
waterHeaterBloc.selectedTime = dateTime;
|
days: waterHeaterBloc.days,
|
||||||
},
|
selectDays: (List<String>
|
||||||
days: waterHeaterBloc.days,
|
selectedDays) {
|
||||||
selectDays: (List<String>
|
waterHeaterBloc.selectedDays =
|
||||||
selectedDays) {
|
selectedDays;
|
||||||
waterHeaterBloc
|
},
|
||||||
.selectedDays =
|
)
|
||||||
selectedDays;
|
: Padding(
|
||||||
},
|
padding: const EdgeInsets.only(
|
||||||
)
|
top: 10),
|
||||||
: Padding(
|
child: Column(
|
||||||
padding: const EdgeInsets.only(top: 10),
|
children: [
|
||||||
child: ScheduleListView(
|
Expanded(
|
||||||
listSchedule: waterHeaterBloc.listSchedule, // Pass the schedule list here
|
child: ScheduleListView(
|
||||||
onDismissed:
|
listSchedule:
|
||||||
(scheduleId) {
|
waterHeaterBloc
|
||||||
waterHeaterBloc.listSchedule.removeWhere(
|
.listSchedule, // Pass the schedule list here
|
||||||
(schedule) => schedule.scheduleId == scheduleId);
|
onDismissed:
|
||||||
waterHeaterBloc.add(
|
(scheduleId) {
|
||||||
DeleteScheduleEvent(id: scheduleId));
|
waterHeaterBloc
|
||||||
},
|
.listSchedule
|
||||||
onToggleSchedule: (scheduleId, isEnabled) {
|
.removeWhere(
|
||||||
|
(schedule) =>
|
||||||
waterHeaterBloc.add(ToggleScheduleEvent(
|
schedule
|
||||||
id: scheduleId, toggle: isEnabled,
|
.scheduleId ==
|
||||||
));
|
scheduleId);
|
||||||
},
|
waterHeaterBloc.add(
|
||||||
|
DeleteScheduleEvent(
|
||||||
|
id: scheduleId));
|
||||||
|
},
|
||||||
|
onToggleSchedule:
|
||||||
|
(scheduleId,
|
||||||
|
isEnabled) {
|
||||||
|
waterHeaterBloc.add(
|
||||||
|
ToggleScheduleEvent(
|
||||||
|
id: scheduleId,
|
||||||
|
toggle: isEnabled,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment:
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
waterHeaterBloc.createCirculate == true
|
waterHeaterBloc.createCirculate ==
|
||||||
?
|
true
|
||||||
CirculateWidget(
|
? CirculateWidget(
|
||||||
endDuration: () {
|
endDuration: () {
|
||||||
waterHeaterBloc.add(SelectTimeEvent(context: context, isEffective: false));
|
waterHeaterBloc.add(
|
||||||
},
|
SelectTimeEvent(
|
||||||
startDuration: () {
|
context: context,
|
||||||
waterHeaterBloc.add(SelectTimeEvent(context: context, isEffective: false));
|
isEffective:
|
||||||
|
false));
|
||||||
},
|
},
|
||||||
isStartEndTime: true,
|
startDuration: () {
|
||||||
startTime: DateTime.now(),
|
waterHeaterBloc.add(
|
||||||
endTime: DateTime.now(),
|
SelectTimeEvent(
|
||||||
days: waterHeaterBloc.days,
|
context: context,
|
||||||
selectedDays: [],
|
isEffective:
|
||||||
onToggleStartEndTime: (c) {},
|
false));
|
||||||
onTimeChanged: (x, f) {
|
},
|
||||||
},
|
isStartEndTime: true,
|
||||||
onDaySelected: (p0) {},
|
startTime: DateTime.now(),
|
||||||
):CirculateListView(
|
endTime: DateTime.now(),
|
||||||
listSchedule: waterHeaterBloc.listSchedule, // Pass the schedule list here
|
days: waterHeaterBloc.days,
|
||||||
onDismissed: (scheduleId) {
|
selectedDays: [],
|
||||||
waterHeaterBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
onToggleStartEndTime:
|
||||||
waterHeaterBloc.add(DeleteScheduleEvent(id: scheduleId));
|
(c) {},
|
||||||
},
|
onTimeChanged: (x, f) {},
|
||||||
onToggleSchedule: (scheduleId, isEnabled) {
|
onDaySelected: (p0) {},
|
||||||
waterHeaterBloc.add(ToggleScheduleEvent(
|
)
|
||||||
id: scheduleId, toggle: isEnabled,
|
: CirculateListView(
|
||||||
));
|
listSchedule: [], // Pass the schedule list here
|
||||||
},
|
onDismissed: (scheduleId) {
|
||||||
)
|
waterHeaterBloc
|
||||||
|
.listSchedule
|
||||||
|
.removeWhere((schedule) =>
|
||||||
|
schedule
|
||||||
|
.scheduleId ==
|
||||||
|
scheduleId);
|
||||||
|
waterHeaterBloc.add(
|
||||||
|
DeleteScheduleEvent(
|
||||||
|
id: scheduleId));
|
||||||
|
},
|
||||||
|
onToggleSchedule:
|
||||||
|
(scheduleId,
|
||||||
|
isEnabled) {
|
||||||
|
waterHeaterBloc.add(
|
||||||
|
ToggleScheduleEvent(
|
||||||
|
id: scheduleId,
|
||||||
|
toggle: isEnabled,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Column(children: [
|
Column(
|
||||||
SizedBox(height: 20),
|
children: [
|
||||||
Container(child: InchingWidget(),),],)
|
SizedBox(height: 20),
|
||||||
|
Container(
|
||||||
|
child: InchingWidget(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -21,94 +21,98 @@ class ScheduleListView extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Center(
|
return listSchedule.isNotEmpty
|
||||||
child: listSchedule.isNotEmpty
|
? SizedBox(
|
||||||
? SizedBox(
|
child: ListView.builder(
|
||||||
child: ListView.builder(
|
shrinkWrap: true,
|
||||||
shrinkWrap: true,
|
itemCount: listSchedule.length,
|
||||||
itemCount: listSchedule.length,
|
itemBuilder: (context, index) {
|
||||||
itemBuilder: (context, index) {
|
return Dismissible(
|
||||||
return Dismissible(
|
key: Key(listSchedule[index].scheduleId),
|
||||||
key: Key(listSchedule[index].scheduleId),
|
background: Container(
|
||||||
background: Container(
|
padding: const EdgeInsets.only(right: 10),
|
||||||
padding: const EdgeInsets.only(right: 10),
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
decoration: const ShapeDecoration(
|
||||||
decoration: const ShapeDecoration(
|
color: Color(0xFFFF0000),
|
||||||
color: Color(0xFFFF0000),
|
shape: RoundedRectangleBorder(
|
||||||
shape: RoundedRectangleBorder(
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 10, right: 10),
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.assetsDeleteIcon,
|
|
||||||
width: 20,
|
|
||||||
height: 22,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
direction: DismissDirection.endToStart,
|
),
|
||||||
onDismissed: (direction) {
|
child: Padding(
|
||||||
onDismissed(listSchedule[index].scheduleId);
|
padding: const EdgeInsets.only(bottom: 10, right: 10),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.assetsDeleteIcon,
|
||||||
|
width: 20,
|
||||||
|
height: 22,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
direction: DismissDirection.endToStart,
|
||||||
|
onDismissed: (direction) {
|
||||||
|
onDismissed(listSchedule[index].scheduleId);
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Schedule removed')),
|
const SnackBar(content: Text('Schedule removed')),
|
||||||
);
|
|
||||||
},
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {},
|
|
||||||
child: DefaultContainer(
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
height: MediaQuery.of(context).size.height / 6.4,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
BodyLarge(
|
|
||||||
text: listSchedule[index].time,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontColor: Colors.black,
|
|
||||||
fontSize: 22,
|
|
||||||
),
|
|
||||||
Text(listSchedule[index].days.join(' ')),
|
|
||||||
Text(
|
|
||||||
'Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: ListTile(
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
leading: const BodyMedium(
|
|
||||||
text: '',
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
),
|
|
||||||
trailing: Transform.scale(
|
|
||||||
scale: .8,
|
|
||||||
child: CupertinoSwitch(
|
|
||||||
value: listSchedule[index].enable,
|
|
||||||
onChanged: (value) {
|
|
||||||
onToggleSchedule(
|
|
||||||
listSchedule[index].scheduleId,
|
|
||||||
value,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
applyTheme: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
child: InkWell(
|
||||||
)
|
onTap: () {},
|
||||||
: const EmptySchedule());
|
child: DefaultContainer(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
height: MediaQuery.of(context).size.height / 6.4,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
BodyLarge(
|
||||||
|
text: listSchedule[index].time,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontColor: Colors.black,
|
||||||
|
fontSize: 22,
|
||||||
|
),
|
||||||
|
Text(listSchedule[index].days.join(' ')),
|
||||||
|
Text(
|
||||||
|
'Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
leading: const BodyMedium(
|
||||||
|
text: '',
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
),
|
||||||
|
trailing: Transform.scale(
|
||||||
|
scale: .8,
|
||||||
|
child: CupertinoSwitch(
|
||||||
|
value: listSchedule[index].enable,
|
||||||
|
onChanged: (value) {
|
||||||
|
onToggleSchedule(
|
||||||
|
listSchedule[index].scheduleId,
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
applyTheme: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Center(child: EmptySchedule()),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
|
path: ApiEndpoints.deviceFunctionsStatus
|
||||||
|
.replaceAll('{deviceUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -82,7 +83,9 @@ class DevicesAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> renamePass(
|
static Future<Map<String, dynamic>> renamePass(
|
||||||
{required String name, required String doorLockUuid, required String passwordId}) async {
|
{required String name,
|
||||||
|
required String doorLockUuid,
|
||||||
|
required String passwordId}) async {
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
path: ApiEndpoints.renamePassword
|
path: ApiEndpoints.renamePassword
|
||||||
.replaceAll('{doorLockUuid}', doorLockUuid)
|
.replaceAll('{doorLockUuid}', doorLockUuid)
|
||||||
@ -107,7 +110,8 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDeviceByGroupName(String unitId, String groupName) async {
|
static Future<List<DeviceModel>> getDeviceByGroupName(
|
||||||
|
String unitId, String groupName) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.devicesByGroupName
|
path: ApiEndpoints.devicesByGroupName
|
||||||
.replaceAll('{unitUuid}', unitId)
|
.replaceAll('{unitUuid}', unitId)
|
||||||
@ -146,7 +150,8 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
|
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
||||||
|
String gatewayId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
@ -168,7 +173,8 @@ class DevicesAPI {
|
|||||||
String deviceId,
|
String deviceId,
|
||||||
) async {
|
) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.getTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -179,7 +185,8 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future getOneTimePasswords(String deviceId) async {
|
static Future getOneTimePasswords(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.getOneTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -190,7 +197,8 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future getTimeLimitPasswords(String deviceId) async {
|
static Future getTimeLimitPasswords(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.getMultipleTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -215,10 +223,12 @@ class DevicesAPI {
|
|||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
};
|
};
|
||||||
if (scheduleList != null) {
|
if (scheduleList != null) {
|
||||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
body["scheduleList"] =
|
||||||
|
scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
}
|
}
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
body: body,
|
body: body,
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => json,
|
expectedResponseModel: (json) => json,
|
||||||
@ -229,7 +239,8 @@ class DevicesAPI {
|
|||||||
static Future generateOneTimePassword({deviceId}) async {
|
static Future generateOneTimePassword({deviceId}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addOneTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -241,10 +252,12 @@ class DevicesAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
|
static Future generateMultiTimePassword(
|
||||||
|
{deviceId, effectiveTime, invalidTime}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.addMultipleTimeTemporaryPassword
|
||||||
|
.replaceAll('{doorLockUuid}', deviceId),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
@ -361,6 +374,7 @@ class DevicesAPI {
|
|||||||
.replaceAll('{startTime}', startTime)
|
.replaceAll('{startTime}', startTime)
|
||||||
.replaceAll('{endTime}', endTime),
|
.replaceAll('{endTime}', endTime),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
|
print('json-=-=-=-=-=-=-=${json}');
|
||||||
return DeviceReport.fromJson(json);
|
return DeviceReport.fromJson(json);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user