mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 09:45:22 +00:00
schedule for one gang and two gang and three gange
This commit is contained in:
@ -1,16 +1,20 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/one_gang_model.dart';
|
import 'package:syncrow_app/features/devices/model/one_gang_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||||
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
import 'one_gang_event.dart';
|
import 'one_gang_event.dart';
|
||||||
|
|
||||||
class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
||||||
final String oneGangId;
|
final String oneGangId;
|
||||||
|
final String switchCode;
|
||||||
OneGangModel deviceStatus = OneGangModel(
|
OneGangModel deviceStatus = OneGangModel(
|
||||||
firstSwitch: false,
|
firstSwitch: false,
|
||||||
firstCountDown: 0,
|
firstCountDown: 0,
|
||||||
@ -21,7 +25,7 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
List<DeviceModel> devicesList = [];
|
List<DeviceModel> devicesList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
OneGangBloc({required this.oneGangId}) : super(InitialState()) {
|
OneGangBloc({required this.oneGangId,required this.switchCode}) : super(InitialState()) {
|
||||||
on<InitialEvent>(_fetchTwoGangStatus);
|
on<InitialEvent>(_fetchTwoGangStatus);
|
||||||
on<OneGangUpdated>(_oneGangUpdated);
|
on<OneGangUpdated>(_oneGangUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -30,6 +34,15 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
on<GetCounterEvent>(_getCounterValue);
|
on<GetCounterEvent>(_getCounterValue);
|
||||||
on<TickTimer>(_onTickTimer);
|
on<TickTimer>(_onTickTimer);
|
||||||
on<OnClose>(_onClose);
|
on<OnClose>(_onClose);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||||
|
on<ThreeGangSave>(saveSchedule);
|
||||||
|
on<GetScheduleEvent>(getSchedule);
|
||||||
|
on<ToggleScheduleEvent>(toggleChange);
|
||||||
|
on<DeleteScheduleEvent>(deleteSchedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchTwoGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
|
void _fetchTwoGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
|
||||||
@ -176,4 +189,141 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
emit(TimerRunComplete());
|
emit(TimerRunComplete());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Map<String, String>> days = [
|
||||||
|
{"day": "Sun", "key": "Sun"},
|
||||||
|
{"day": "Mon", "key": "Mon"},
|
||||||
|
{"day": "Tue", "key": "Tue"},
|
||||||
|
{"day": "Wed", "key": "Wed"},
|
||||||
|
{"day": "Thu", "key": "Thu"},
|
||||||
|
{"day": "Fri", "key": "Fri"},
|
||||||
|
{"day": "Sat", "key": "Sat"},
|
||||||
|
];
|
||||||
|
|
||||||
|
Future<void> saveSchedule(ThreeGangSave event, Emitter<OneGangState> emit,) async {
|
||||||
|
try {
|
||||||
|
if(selectedDays.isNotEmpty) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.postSchedule(
|
||||||
|
category: switchCode,
|
||||||
|
deviceId: oneGangId,
|
||||||
|
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||||
|
code: switchCode,
|
||||||
|
value: toggleSchedule,
|
||||||
|
days: selectedDays);
|
||||||
|
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
emit(ThreeGangSaveSchedule());
|
||||||
|
toggleCreateSchedule();
|
||||||
|
}else{
|
||||||
|
CustomSnackBar.displaySnackBar('Please select days');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(error: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> getSchedule(GetScheduleEvent event, Emitter<OneGangState> emit,) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.getSchedule(
|
||||||
|
category: switchCode,
|
||||||
|
deviceId: oneGangId ,
|
||||||
|
);
|
||||||
|
List<dynamic> jsonData = response;
|
||||||
|
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
|
emit(InitialState());
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
|
print(dateTime);
|
||||||
|
if (dateTime == null) return null;
|
||||||
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.changeSchedule(
|
||||||
|
scheduleId: event.id, deviceUuid: oneGangId, enable: event.toggle);
|
||||||
|
if (response == true) {
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
toggleSchedule = event.toggle;
|
||||||
|
return toggleSchedule;
|
||||||
|
}
|
||||||
|
emit(IsToggleState(onOff: toggleSchedule));
|
||||||
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
// debugPrint('errorMessage=${errorMessage}');
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future deleteSchedule(
|
||||||
|
DeleteScheduleEvent event, Emitter<OneGangState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.deleteSchedule(
|
||||||
|
scheduleId: event.id,
|
||||||
|
deviceUuid: oneGangId, );
|
||||||
|
if (response == true) {
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
return toggleSchedule;
|
||||||
|
}
|
||||||
|
emit(IsToggleState(onOff: toggleSchedule));
|
||||||
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleCreateSchedule() {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
createSchedule = !createSchedule;
|
||||||
|
selectedDays.clear();
|
||||||
|
selectedTime=DateTime.now();
|
||||||
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
|
emit(ChangeSlidingSegmentState(value: 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool toggleSchedule = true;
|
||||||
|
List<String> selectedDays = [];
|
||||||
|
bool createSchedule = false;
|
||||||
|
List<ScheduleModel> listSchedule = [];
|
||||||
|
DateTime? selectedTime=DateTime.now();
|
||||||
|
Future<void> toggleDaySelection(
|
||||||
|
ToggleDaySelectionEvent event,
|
||||||
|
Emitter<OneGangState> emit,
|
||||||
|
) async {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
if (selectedDays.contains(event.key)) {
|
||||||
|
selectedDays.remove(event.key);
|
||||||
|
} else {
|
||||||
|
selectedDays.add(event.key);
|
||||||
|
}
|
||||||
|
emit(ChangeTimeState());
|
||||||
|
add(ChangeSlidingSegment(value: 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
|
void toggleSelectedIndex(index) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
selectedTabIndex = index;
|
||||||
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -86,3 +86,31 @@ class TickTimer extends OneGangEvent {
|
|||||||
class StopTimer extends OneGangEvent {}
|
class StopTimer extends OneGangEvent {}
|
||||||
|
|
||||||
class OnClose extends OneGangEvent {}
|
class OnClose extends OneGangEvent {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------- Schedule ----------=---------
|
||||||
|
class GetScheduleEvent extends OneGangEvent {}
|
||||||
|
class ThreeGangSave extends OneGangEvent {}
|
||||||
|
class ToggleScheduleEvent extends OneGangEvent {
|
||||||
|
final String id;
|
||||||
|
final bool toggle;
|
||||||
|
const ToggleScheduleEvent({required this.toggle,required this.id});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [toggle,id];
|
||||||
|
}
|
||||||
|
class ToggleDaySelectionEvent extends OneGangEvent {
|
||||||
|
|
||||||
|
final String key;
|
||||||
|
|
||||||
|
const ToggleDaySelectionEvent({required this.key});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [key];
|
||||||
|
}
|
||||||
|
class DeleteScheduleEvent extends OneGangEvent {
|
||||||
|
final String id;
|
||||||
|
const DeleteScheduleEvent({required this.id});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [id];
|
||||||
|
}
|
||||||
|
@ -77,3 +77,13 @@ class TimerRunInProgress extends OneGangState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TimerRunComplete extends OneGangState {}
|
class TimerRunComplete extends OneGangState {}
|
||||||
|
class ThreeGangSaveSchedule extends OneGangState {}
|
||||||
|
class IsToggleState extends OneGangState {
|
||||||
|
final bool? onOff;
|
||||||
|
const IsToggleState({this.onOff});
|
||||||
|
}
|
||||||
|
class ChangeTimeState extends OneGangState {}
|
||||||
|
class UpdateCreateScheduleState extends OneGangState {
|
||||||
|
final bool createSchedule;
|
||||||
|
UpdateCreateScheduleState(this.createSchedule);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
@ -7,12 +8,16 @@ import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_sta
|
|||||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
|
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
|
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
|
||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||||
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
|
|
||||||
|
|
||||||
class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
||||||
final String threeGangId;
|
final String threeGangId;
|
||||||
|
final String switchCode;
|
||||||
ThreeGangModel deviceStatus = ThreeGangModel(
|
ThreeGangModel deviceStatus = ThreeGangModel(
|
||||||
firstSwitch: false,
|
firstSwitch: false,
|
||||||
secondSwitch: false,
|
secondSwitch: false,
|
||||||
@ -30,7 +35,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
List<GroupThreeGangModel> groupThreeGangList = [];
|
List<GroupThreeGangModel> groupThreeGangList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
ThreeGangBloc({required this.threeGangId}) : super(InitialState()) {
|
ThreeGangBloc({required this.threeGangId,required this.switchCode}) : super(InitialState()) {
|
||||||
on<InitialEvent>(_fetchThreeGangStatus);
|
on<InitialEvent>(_fetchThreeGangStatus);
|
||||||
on<ThreeGangUpdated>(_threeGangUpdated);
|
on<ThreeGangUpdated>(_threeGangUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -45,6 +50,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
on<OnClose>(_onClose);
|
on<OnClose>(_onClose);
|
||||||
on<GroupAllOnEvent>(_groupAllOn);
|
on<GroupAllOnEvent>(_groupAllOn);
|
||||||
on<GroupAllOffEvent>(_groupAllOff);
|
on<GroupAllOffEvent>(_groupAllOff);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||||
|
on<ThreeGangSave>(saveSchedule);
|
||||||
|
on<GetScheduleEvent>(getSchedule);
|
||||||
|
on<ToggleScheduleEvent>(toggleChange);
|
||||||
|
on<DeleteScheduleEvent>(deleteSchedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
|
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
|
||||||
@ -479,4 +492,145 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
emit(TimerRunComplete());
|
emit(TimerRunComplete());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<Map<String, String>> days = [
|
||||||
|
{"day": "Sun", "key": "Sun"},
|
||||||
|
{"day": "Mon", "key": "Mon"},
|
||||||
|
{"day": "Tue", "key": "Tue"},
|
||||||
|
{"day": "Wed", "key": "Wed"},
|
||||||
|
{"day": "Thu", "key": "Thu"},
|
||||||
|
{"day": "Fri", "key": "Fri"},
|
||||||
|
{"day": "Sat", "key": "Sat"},
|
||||||
|
];
|
||||||
|
|
||||||
|
Future<void> toggleDaySelection(
|
||||||
|
ToggleDaySelectionEvent event,
|
||||||
|
Emitter<ThreeGangState> emit,
|
||||||
|
) async {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
if (selectedDays.contains(event.key)) {
|
||||||
|
selectedDays.remove(event.key);
|
||||||
|
} else {
|
||||||
|
selectedDays.add(event.key);
|
||||||
|
}
|
||||||
|
emit(ChangeTimeState());
|
||||||
|
add(ChangeSlidingSegment(value: 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> saveSchedule(ThreeGangSave event, Emitter<ThreeGangState> emit,) async {
|
||||||
|
try {
|
||||||
|
if(selectedDays.isNotEmpty) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.postSchedule(
|
||||||
|
category: switchCode,
|
||||||
|
deviceId: threeGangId,
|
||||||
|
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||||
|
code: switchCode,
|
||||||
|
value: toggleSchedule,
|
||||||
|
days: selectedDays);
|
||||||
|
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
emit(ThreeGangSaveSchedule());
|
||||||
|
toggleCreateSchedule();
|
||||||
|
}else{
|
||||||
|
CustomSnackBar.displaySnackBar('Please select days');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(error: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> getSchedule(GetScheduleEvent event, Emitter<ThreeGangState> emit,) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.getSchedule(
|
||||||
|
category: switchCode,
|
||||||
|
deviceId: threeGangId ,
|
||||||
|
);
|
||||||
|
List<dynamic> jsonData = response;
|
||||||
|
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
|
emit(InitialState());
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
|
print(dateTime);
|
||||||
|
if (dateTime == null) return null;
|
||||||
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future toggleChange(
|
||||||
|
ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.changeSchedule(
|
||||||
|
scheduleId: event.id, deviceUuid: threeGangId, enable: event.toggle);
|
||||||
|
if (response == true) {
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
toggleSchedule = event.toggle;
|
||||||
|
return toggleSchedule;
|
||||||
|
}
|
||||||
|
emit(IsToggleState(onOff: toggleSchedule));
|
||||||
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
// debugPrint('errorMessage=${errorMessage}');
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future deleteSchedule(
|
||||||
|
DeleteScheduleEvent event, Emitter<ThreeGangState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.deleteSchedule(
|
||||||
|
scheduleId: event.id,
|
||||||
|
deviceUuid: threeGangId, );
|
||||||
|
if (response == true) {
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
return toggleSchedule;
|
||||||
|
}
|
||||||
|
emit(IsToggleState(onOff: toggleSchedule));
|
||||||
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleCreateSchedule() {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
createSchedule = !createSchedule;
|
||||||
|
selectedDays.clear();
|
||||||
|
selectedTime=DateTime.now();
|
||||||
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
|
emit(ChangeSlidingSegmentState(value: 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
|
void toggleSelectedIndex(index) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
selectedTabIndex = index;
|
||||||
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool toggleSchedule = true;
|
||||||
|
List<String> selectedDays = [];
|
||||||
|
bool createSchedule = false;
|
||||||
|
List<ScheduleModel> listSchedule = [];
|
||||||
|
DateTime? selectedTime=DateTime.now();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -93,3 +93,29 @@ class TickTimer extends ThreeGangEvent {
|
|||||||
class StopTimer extends ThreeGangEvent {}
|
class StopTimer extends ThreeGangEvent {}
|
||||||
|
|
||||||
class OnClose extends ThreeGangEvent {}
|
class OnClose extends ThreeGangEvent {}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------- Schedule ----------=---------
|
||||||
|
class GetScheduleEvent extends ThreeGangEvent {}
|
||||||
|
class ThreeGangSave extends ThreeGangEvent {}
|
||||||
|
class ToggleScheduleEvent extends ThreeGangEvent {
|
||||||
|
final String id;
|
||||||
|
final bool toggle;
|
||||||
|
const ToggleScheduleEvent({required this.toggle,required this.id});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [toggle,id];
|
||||||
|
}
|
||||||
|
class ToggleDaySelectionEvent extends ThreeGangEvent {
|
||||||
|
|
||||||
|
final String key;
|
||||||
|
|
||||||
|
const ToggleDaySelectionEvent({required this.key});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [key];
|
||||||
|
}
|
||||||
|
class DeleteScheduleEvent extends ThreeGangEvent {
|
||||||
|
final String id;
|
||||||
|
const DeleteScheduleEvent({required this.id});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [id];
|
||||||
|
}
|
||||||
|
@ -75,3 +75,15 @@ class TimerRunInProgress extends ThreeGangState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TimerRunComplete extends ThreeGangState {}
|
class TimerRunComplete extends ThreeGangState {}
|
||||||
|
|
||||||
|
|
||||||
|
class ThreeGangSaveSchedule extends ThreeGangState {}
|
||||||
|
class IsToggleState extends ThreeGangState {
|
||||||
|
final bool? onOff;
|
||||||
|
const IsToggleState({this.onOff});
|
||||||
|
}
|
||||||
|
class ChangeTimeState extends ThreeGangState {}
|
||||||
|
class UpdateCreateScheduleState extends ThreeGangState {
|
||||||
|
final bool createSchedule;
|
||||||
|
UpdateCreateScheduleState(this.createSchedule);
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:firebase_database/firebase_database.dart';
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||||
@ -11,9 +12,11 @@ import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
|||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
|
import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
|
||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||||
|
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||||
|
|
||||||
class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
||||||
final String twoGangId;
|
final String twoGangId;
|
||||||
|
final String switchCode;
|
||||||
TwoGangModel deviceStatus = TwoGangModel(
|
TwoGangModel deviceStatus = TwoGangModel(
|
||||||
firstSwitch: false,
|
firstSwitch: false,
|
||||||
secondSwitch: false,
|
secondSwitch: false,
|
||||||
@ -21,30 +24,18 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
secondCountDown: 0,
|
secondCountDown: 0,
|
||||||
);
|
);
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
// Timer? _firstSwitchTimer;
|
|
||||||
// Timer? _secondSwitchTimer;
|
|
||||||
// Timer? _thirdSwitchTimer;
|
|
||||||
|
|
||||||
bool twoGangGroup = false;
|
bool twoGangGroup = false;
|
||||||
List<DeviceModel> devicesList = [];
|
List<DeviceModel> devicesList = [];
|
||||||
List<GroupTwoGangModel> groupTwoGangList = [];
|
List<GroupTwoGangModel> groupTwoGangList = [];
|
||||||
bool allSwitchesOn = true;
|
bool allSwitchesOn = true;
|
||||||
|
bool toggleSchedule = true;
|
||||||
List<String> selectedDays = [];
|
List<String> selectedDays = [];
|
||||||
|
|
||||||
bool createSchedule = false;
|
bool createSchedule = false;
|
||||||
List<ScheduleModel> listSchedule = [
|
List<ScheduleModel> listSchedule = [];
|
||||||
ScheduleModel(
|
|
||||||
id: '1',
|
|
||||||
category: 'category',
|
|
||||||
enable: true,
|
|
||||||
function: FunctionModel(code: 'code', value: true),
|
|
||||||
time: 'time',
|
|
||||||
timerId: 'timerId',
|
|
||||||
timezoneId: 'timezoneId',
|
|
||||||
days: ['S'])
|
|
||||||
];
|
|
||||||
|
|
||||||
TwoGangBloc({required this.twoGangId}) : super(InitialState()) {
|
TwoGangBloc({required this.twoGangId,required this.switchCode}) : super(InitialState()) {
|
||||||
on<InitialEvent>(_fetchTwoGangStatus);
|
on<InitialEvent>(_fetchTwoGangStatus);
|
||||||
on<TwoGangUpdated>(_twoGangUpdated);
|
on<TwoGangUpdated>(_twoGangUpdated);
|
||||||
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
|
||||||
@ -59,19 +50,32 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
on<GroupAllOnEvent>(_groupAllOn);
|
on<GroupAllOnEvent>(_groupAllOn);
|
||||||
on<GroupAllOffEvent>(_groupAllOff);
|
on<GroupAllOffEvent>(_groupAllOff);
|
||||||
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
on<ToggleDaySelectionEvent>(toggleDaySelection);
|
||||||
|
on<TwoGangSave>(saveSchedule);
|
||||||
|
on<GetScheduleEvent>(getSchedule);
|
||||||
|
on<ToggleScheduleEvent>(toggleRepeat);
|
||||||
|
on<DeleteScheduleEvent>(deleteSchedule);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime? selectedTime;
|
DateTime? selectedTime = DateTime.now();
|
||||||
|
|
||||||
void toggleCreateSchedule() {
|
void toggleCreateSchedule() {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
|
selectedDays.clear();
|
||||||
|
selectedTime=DateTime.now();
|
||||||
emit(UpdateCreateScheduleState(createSchedule));
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
emit(ChangeSlidingSegmentState(value: 1));
|
emit(ChangeSlidingSegmentState(value: 1));
|
||||||
}
|
}
|
||||||
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
void _fetchTwoGangStatus(
|
void toggleSelectedIndex(index) {
|
||||||
InitialEvent event, Emitter<TwoGangState> emit) async {
|
emit(LoadingInitialState());
|
||||||
|
selectedTabIndex = index;
|
||||||
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _fetchTwoGangStatus(InitialEvent event, Emitter<TwoGangState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
twoGangGroup = event.groupScreen;
|
twoGangGroup = event.groupScreen;
|
||||||
@ -359,13 +363,16 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoGangId, code: event.deviceCode, value: seconds),
|
deviceId: twoGangId,
|
||||||
|
code: event.deviceCode,
|
||||||
|
value: seconds),
|
||||||
twoGangId);
|
twoGangId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
if (event.deviceCode == 'countdown_1') {
|
if (event.deviceCode == 'countdown_1') {
|
||||||
deviceStatus.firstCountDown = seconds;
|
deviceStatus.firstCountDown = seconds;
|
||||||
} else if (event.deviceCode == 'countdown_2') {
|
}
|
||||||
|
else if (event.deviceCode == 'countdown_2') {
|
||||||
deviceStatus.secondCountDown = seconds;
|
deviceStatus.secondCountDown = seconds;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -388,6 +395,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
GetCounterEvent event, Emitter<TwoGangState> emit) async {
|
GetCounterEvent event, Emitter<TwoGangState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
|
add(GetScheduleEvent());
|
||||||
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
||||||
List<StatusModel> statusModelList = [];
|
List<StatusModel> statusModelList = [];
|
||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
@ -457,13 +465,96 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
add(ChangeSlidingSegment(value: 1));
|
add(ChangeSlidingSegment(value: 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSchedule() async {
|
Future<void> saveSchedule(TwoGangSave event, Emitter<TwoGangState> emit,) async {
|
||||||
final response = await DevicesAPI.postSchedule(
|
try {
|
||||||
category: 'switch_1',
|
if(selectedDays.isNotEmpty) {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.postSchedule(
|
||||||
|
category: switchCode,
|
||||||
|
deviceId: twoGangId,
|
||||||
|
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||||
|
code: switchCode,
|
||||||
|
value: toggleSchedule,
|
||||||
|
days: selectedDays);
|
||||||
|
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
emit(TwoGangSaveSchedule());
|
||||||
|
toggleCreateSchedule();
|
||||||
|
}else{
|
||||||
|
CustomSnackBar.displaySnackBar('Please select days');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(error: e.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getSchedule(GetScheduleEvent event, Emitter<TwoGangState> emit,) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.getSchedule(
|
||||||
|
category: switchCode,
|
||||||
deviceId: twoGangId,
|
deviceId: twoGangId,
|
||||||
time: 'selectedTime',
|
);
|
||||||
code: 'switch_1',
|
List<dynamic> jsonData = response;
|
||||||
value: true,
|
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
days: selectedDays);
|
emit(InitialState());
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int? getTimeStampWithoutSeconds(DateTime? dateTime) {
|
||||||
|
print(dateTime);
|
||||||
|
if (dateTime == null) return null;
|
||||||
|
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month,
|
||||||
|
dateTime.day, dateTime.hour, dateTime.minute);
|
||||||
|
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future toggleRepeat(
|
||||||
|
ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.changeSchedule(
|
||||||
|
scheduleId: event.id,
|
||||||
|
deviceUuid: twoGangId,
|
||||||
|
enable: event.toggle);
|
||||||
|
if (response == true) {
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
toggleSchedule = event.toggle;
|
||||||
|
return toggleSchedule;
|
||||||
|
}
|
||||||
|
emit(IsToggleState(onOff: toggleSchedule));
|
||||||
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
// debugPrint('errorMessage=${errorMessage}');
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future deleteSchedule(
|
||||||
|
DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
|
||||||
|
try {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
final response = await DevicesAPI.deleteSchedule(
|
||||||
|
scheduleId: event.id,
|
||||||
|
deviceUuid: twoGangId, );
|
||||||
|
if (response == true) {
|
||||||
|
add(GetScheduleEvent());
|
||||||
|
// toggleSchedule = event.id;
|
||||||
|
return toggleSchedule;
|
||||||
|
}
|
||||||
|
emit(IsToggleState(onOff: toggleSchedule));
|
||||||
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
final errorData = e.response!.data;
|
||||||
|
String errorMessage = errorData['message'];
|
||||||
|
print('errorMessage=${errorMessage}');
|
||||||
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,15 @@ abstract class TwoGangEvent extends Equatable {
|
|||||||
class LoadingEvent extends TwoGangEvent {}
|
class LoadingEvent extends TwoGangEvent {}
|
||||||
|
|
||||||
class TwoGangUpdated extends TwoGangEvent {}
|
class TwoGangUpdated extends TwoGangEvent {}
|
||||||
|
class TwoGangSave extends TwoGangEvent {}
|
||||||
|
class ToggleScheduleEvent extends TwoGangEvent {
|
||||||
|
final String id;
|
||||||
|
final bool toggle;
|
||||||
|
const ToggleScheduleEvent({required this.toggle,required this.id});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [toggle,id];
|
||||||
|
}
|
||||||
|
class errorMessage extends TwoGangEvent {}
|
||||||
class ToggleDaySelectionEvent extends TwoGangEvent {
|
class ToggleDaySelectionEvent extends TwoGangEvent {
|
||||||
|
|
||||||
final String key;
|
final String key;
|
||||||
@ -101,3 +110,21 @@ class TickTimer extends TwoGangEvent {
|
|||||||
class StopTimer extends TwoGangEvent {}
|
class StopTimer extends TwoGangEvent {}
|
||||||
|
|
||||||
class OnClose extends TwoGangEvent {}
|
class OnClose extends TwoGangEvent {}
|
||||||
|
|
||||||
|
|
||||||
|
class GetScheduleEvent extends TwoGangEvent {}
|
||||||
|
class DeleteScheduleEvent extends TwoGangEvent {
|
||||||
|
final String id;
|
||||||
|
const DeleteScheduleEvent({required this.id});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [id];
|
||||||
|
}
|
||||||
|
class TabChangedEvent extends TwoGangEvent {
|
||||||
|
final int index;
|
||||||
|
TabChangedEvent({required this.index});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ class TwoGangState extends Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InitialState extends TwoGangState {}
|
class InitialState extends TwoGangState {}
|
||||||
|
class TwoGangSaveSchedule extends TwoGangState {}
|
||||||
class ChangeTimeState extends TwoGangState {}
|
class ChangeTimeState extends TwoGangState {}
|
||||||
|
|
||||||
class LoadingInitialState extends TwoGangState {}
|
class LoadingInitialState extends TwoGangState {}
|
||||||
@ -77,6 +78,10 @@ class TimerRunInProgress extends TwoGangState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TimerRunComplete extends TwoGangState {}
|
class TimerRunComplete extends TwoGangState {}
|
||||||
|
class IsToggleState extends TwoGangState {
|
||||||
|
final bool? onOff;
|
||||||
|
const IsToggleState({this.onOff});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,21 +1,69 @@
|
|||||||
class FunctionModel {
|
import 'package:intl/intl.dart';
|
||||||
final String code;
|
|
||||||
final bool value;
|
|
||||||
|
|
||||||
FunctionModel({
|
class ScheduleModel {
|
||||||
|
String category;
|
||||||
|
bool enable;
|
||||||
|
ScheduleFunctionData function;
|
||||||
|
String time;
|
||||||
|
String scheduleId;
|
||||||
|
String timezoneId;
|
||||||
|
List<String> days;
|
||||||
|
|
||||||
|
ScheduleModel({
|
||||||
|
required this.category,
|
||||||
|
required this.enable,
|
||||||
|
required this.function,
|
||||||
|
required this.time,
|
||||||
|
required this.scheduleId,
|
||||||
|
required this.timezoneId,
|
||||||
|
required this.days,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Factory method to create an instance from JSON
|
||||||
|
factory ScheduleModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ScheduleModel(
|
||||||
|
category: json['category'],
|
||||||
|
enable: json['enable'],
|
||||||
|
function: ScheduleFunctionData.fromJson(json['function']),
|
||||||
|
time:getTimeIn12HourFormat( json['time']),
|
||||||
|
scheduleId: json['scheduleId'],
|
||||||
|
timezoneId: json['timezoneId'],
|
||||||
|
days: List<String>.from(json['days']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to convert an instance into JSON
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'category': category,
|
||||||
|
'enable': enable,
|
||||||
|
'function': function.toJson(),
|
||||||
|
'time': time,
|
||||||
|
'scheduleId': scheduleId,
|
||||||
|
'timezoneId': timezoneId,
|
||||||
|
'days': days,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScheduleFunctionData {
|
||||||
|
String code;
|
||||||
|
bool value;
|
||||||
|
|
||||||
|
ScheduleFunctionData({
|
||||||
required this.code,
|
required this.code,
|
||||||
required this.value,
|
required this.value,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Convert a JSON object to a FunctionModel instance
|
// Factory method to create an instance from JSON
|
||||||
factory FunctionModel.fromJson(Map<String, dynamic> json) {
|
factory ScheduleFunctionData.fromJson(Map<String, dynamic> json) {
|
||||||
return FunctionModel(
|
return ScheduleFunctionData(
|
||||||
code: json['code'],
|
code: json['code'],
|
||||||
value: json['value'],
|
value: json['value'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a FunctionModel instance to a JSON object
|
// Method to convert an instance into JSON
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'code': code,
|
'code': code,
|
||||||
@ -24,51 +72,12 @@ class FunctionModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScheduleModel {
|
String getTimeIn12HourFormat(time) {
|
||||||
final String id;
|
// Parse the time string (in HH:mm format)
|
||||||
final String category;
|
final DateFormat inputFormat = DateFormat("HH:mm");
|
||||||
final bool enable;
|
final DateFormat outputFormat = DateFormat("h:mm a"); // 12-hour format with AM/PM
|
||||||
final FunctionModel function;
|
|
||||||
final String time;
|
|
||||||
final String timerId;
|
|
||||||
final String timezoneId;
|
|
||||||
final List<String> days;
|
|
||||||
|
|
||||||
ScheduleModel({
|
// Convert the time string
|
||||||
required this.id,
|
DateTime parsedTime = inputFormat.parse(time);
|
||||||
required this.category,
|
return outputFormat.format(parsedTime);
|
||||||
required this.enable,
|
}
|
||||||
required this.function,
|
|
||||||
required this.time,
|
|
||||||
required this.timerId,
|
|
||||||
required this.timezoneId,
|
|
||||||
required this.days,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Convert a JSON object to a Schedule instance
|
|
||||||
factory ScheduleModel.fromJson(Map<String, dynamic> json) {
|
|
||||||
return ScheduleModel(
|
|
||||||
id: json['id'],
|
|
||||||
category: json['category'],
|
|
||||||
enable: json['enable'],
|
|
||||||
function: FunctionModel.fromJson(json['function']),
|
|
||||||
time: json['time'],
|
|
||||||
timerId: json['timerId'],
|
|
||||||
timezoneId: json['timezoneId'],
|
|
||||||
days: List<String>.from(json['days']),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a Schedule instance to a JSON object
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {
|
|
||||||
'category': category,
|
|
||||||
'enable': enable,
|
|
||||||
'function': function.toJson(),
|
|
||||||
'time': time,
|
|
||||||
'timerId': timerId,
|
|
||||||
'timezoneId': timezoneId,
|
|
||||||
'days': days,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -20,7 +20,9 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => OneGangBloc(oneGangId : device?.uuid ?? '')
|
create: (context) => OneGangBloc(
|
||||||
|
switchCode: 'switch_1',
|
||||||
|
oneGangId : device?.uuid ?? '')
|
||||||
..add(const InitialEvent(groupScreen:false)),
|
..add(const InitialEvent(groupScreen:false)),
|
||||||
child: BlocBuilder<OneGangBloc, OneGangState>(
|
child: BlocBuilder<OneGangBloc, OneGangState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
@ -104,8 +106,9 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => OneGangTimerScreen(
|
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||||
device: device,
|
switchCode:'switch_1' ,
|
||||||
|
device: device!,
|
||||||
deviceCode: 'countdown_1',
|
deviceCode: 'countdown_1',
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
|
@ -7,7 +7,10 @@ import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_bloc.da
|
|||||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/create_schedule.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/schedule_list.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
@ -15,10 +18,186 @@ import 'package:syncrow_app/utils/context_extension.dart';
|
|||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
class OneGangTimerScreen extends StatelessWidget {
|
// class OneGangTimerScreen extends StatelessWidget {
|
||||||
final DeviceModel? device;
|
// final DeviceModel? device;
|
||||||
final String? deviceCode;
|
// final String? deviceCode;
|
||||||
const OneGangTimerScreen({super.key,this.device,this.deviceCode});
|
// const OneGangTimerScreen({super.key,this.device,this.deviceCode});
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return AnnotatedRegion(
|
||||||
|
// value: SystemUiOverlayStyle(
|
||||||
|
// statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||||
|
// statusBarIconBrightness: Brightness.light,
|
||||||
|
// ),
|
||||||
|
// child: Scaffold(
|
||||||
|
// backgroundColor: ColorsManager.backgroundColor,
|
||||||
|
// extendBodyBehindAppBar: true,
|
||||||
|
// extendBody: true,
|
||||||
|
// appBar: AppBar(
|
||||||
|
// backgroundColor: Colors.transparent,
|
||||||
|
// centerTitle: true,
|
||||||
|
// title: const BodyLarge(
|
||||||
|
// text: 'Schedule',
|
||||||
|
// fontColor: ColorsManager.primaryColor,
|
||||||
|
// fontWeight: FontsManager.bold,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// body: SafeArea(
|
||||||
|
// child: BlocProvider(
|
||||||
|
// create: (context) => OneGangBloc(
|
||||||
|
// switchCode: 'switch_1',
|
||||||
|
// oneGangId: device!.uuid ?? '')..
|
||||||
|
// ..add(GetCounterEvent(deviceCode: deviceCode!)),
|
||||||
|
// child: BlocBuilder<OneGangBloc, OneGangState>(
|
||||||
|
// builder: (context, state) {
|
||||||
|
// Duration duration = Duration.zero;
|
||||||
|
// int countNum = 0;
|
||||||
|
// int tabNum = 0;
|
||||||
|
// if (state is UpdateTimerState) {
|
||||||
|
// countNum = state.seconds;
|
||||||
|
// } else if (state is TimerRunInProgress) {
|
||||||
|
// countNum = state.remainingTime;
|
||||||
|
// } else if (state is TimerRunComplete) {
|
||||||
|
// countNum = 0;
|
||||||
|
// } else if (state is LoadingNewSate) {
|
||||||
|
// countNum = 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (state is ChangeSlidingSegmentState) {
|
||||||
|
// tabNum = state.value;
|
||||||
|
// }
|
||||||
|
// return PopScope(
|
||||||
|
// canPop: false,
|
||||||
|
// onPopInvoked: (didPop) {
|
||||||
|
// if (!didPop) {
|
||||||
|
// BlocProvider.of<OneGangBloc>(context).add(OnClose());
|
||||||
|
// Navigator.pop(context);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// child: Container(
|
||||||
|
// width: MediaQuery.sizeOf(context).width,
|
||||||
|
// height: MediaQuery.sizeOf(context).height,
|
||||||
|
// padding: const EdgeInsets.all(24),
|
||||||
|
// decoration: const BoxDecoration(
|
||||||
|
// image: DecorationImage(
|
||||||
|
// image: AssetImage(
|
||||||
|
// Assets.assetsImagesBackground,
|
||||||
|
// ),
|
||||||
|
// fit: BoxFit.cover,
|
||||||
|
// opacity: 0.4,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: state is LoadingInitialState || state is LoadingNewSate
|
||||||
|
// ? const Center(
|
||||||
|
// child: DefaultContainer(
|
||||||
|
// width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
|
// )
|
||||||
|
// : Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: [
|
||||||
|
// Container(
|
||||||
|
// width: MediaQuery.sizeOf(context).width,
|
||||||
|
// decoration: const ShapeDecoration(
|
||||||
|
// color: ColorsManager.slidingBlueColor,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: CupertinoSlidingSegmentedControl<int>(
|
||||||
|
// thumbColor: ColorsManager.slidingBlueColor,
|
||||||
|
// onValueChanged: (value) {
|
||||||
|
// BlocProvider.of<OneGangBloc>(context)
|
||||||
|
// .add(ChangeSlidingSegment(value: value ?? 0));
|
||||||
|
// },
|
||||||
|
// groupValue:
|
||||||
|
// state is ChangeSlidingSegmentState ? state.value : 0,
|
||||||
|
// backgroundColor: Colors.white,
|
||||||
|
// children: <int, Widget>{
|
||||||
|
// 0: Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
// child: BodySmall(
|
||||||
|
// text: 'Countdown',
|
||||||
|
// style: context.bodySmall.copyWith(
|
||||||
|
// color: ColorsManager.blackColor,
|
||||||
|
// fontSize: 12,
|
||||||
|
// fontWeight: FontWeight.w400,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// 1: Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
// child: Text(
|
||||||
|
// 'Schedule',
|
||||||
|
// style: context.bodySmall.copyWith(
|
||||||
|
// color: ColorsManager.blackColor,
|
||||||
|
// fontSize: 12,
|
||||||
|
// fontWeight: FontWeight.w400,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// if (tabNum == 0)
|
||||||
|
// countNum > 0
|
||||||
|
// ? BodyLarge(
|
||||||
|
// text: _formatDuration(countNum),
|
||||||
|
// fontColor: ColorsManager.slidingBlueColor,
|
||||||
|
// fontSize: 40,
|
||||||
|
// )
|
||||||
|
// : CupertinoTimerPicker(
|
||||||
|
// mode: CupertinoTimerPickerMode.hm,
|
||||||
|
// onTimerDurationChanged: (Duration newDuration) {
|
||||||
|
// duration = newDuration;
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// if (tabNum == 0)
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () {
|
||||||
|
// if (state is LoadingNewSate) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (countNum > 0) {
|
||||||
|
// BlocProvider.of<OneGangBloc>(context).add(
|
||||||
|
// SetCounterValue(
|
||||||
|
// deviceCode: deviceCode!,
|
||||||
|
// duration: Duration.zero));
|
||||||
|
// } else if (duration != Duration.zero) {
|
||||||
|
// BlocProvider.of<OneGangBloc>(context).add(
|
||||||
|
// SetCounterValue(
|
||||||
|
// deviceCode: deviceCode!, duration: duration));
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// child: SvgPicture.asset(
|
||||||
|
// countNum > 0 ? Assets.pauseIcon : Assets.playIcon))
|
||||||
|
// ],
|
||||||
|
// )));
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// String _formatDuration(int seconds) {
|
||||||
|
// final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
||||||
|
// final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||||
|
// final secs = (seconds % 60).toString().padLeft(2, '0');
|
||||||
|
// return '$hours:$minutes:$secs';
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
class TimerScheduleScreen extends StatelessWidget {
|
||||||
|
final DeviceModel device;
|
||||||
|
final String deviceCode;
|
||||||
|
final String switchCode;
|
||||||
|
const TimerScheduleScreen(
|
||||||
|
{required this.device,
|
||||||
|
required this.deviceCode,
|
||||||
|
required this.switchCode,
|
||||||
|
super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -27,90 +206,102 @@ class OneGangTimerScreen extends StatelessWidget {
|
|||||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||||
statusBarIconBrightness: Brightness.light,
|
statusBarIconBrightness: Brightness.light,
|
||||||
),
|
),
|
||||||
child: Scaffold(
|
child: BlocProvider(
|
||||||
backgroundColor: ColorsManager.backgroundColor,
|
create: (context) =>
|
||||||
extendBodyBehindAppBar: true,
|
OneGangBloc(switchCode: switchCode, oneGangId: device.uuid ?? '')
|
||||||
extendBody: true,
|
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||||
appBar: AppBar(
|
..add(GetScheduleEvent()),
|
||||||
backgroundColor: Colors.transparent,
|
child: BlocBuilder<OneGangBloc, OneGangState>(
|
||||||
centerTitle: true,
|
builder: (context, state) {
|
||||||
title: const BodyLarge(
|
final oneGangBloc = BlocProvider.of<OneGangBloc>(context);
|
||||||
text: 'Schedule',
|
Duration duration = Duration.zero;
|
||||||
fontColor: ColorsManager.primaryColor,
|
int countNum = 0;
|
||||||
fontWeight: FontsManager.bold,
|
if (state is UpdateTimerState) {
|
||||||
),
|
countNum = state.seconds;
|
||||||
),
|
} else if (state is TimerRunInProgress) {
|
||||||
body: SafeArea(
|
countNum = state.remainingTime;
|
||||||
child: BlocProvider(
|
} else if (state is TimerRunComplete) {
|
||||||
create: (context) => OneGangBloc(oneGangId: device!.uuid ?? '')
|
countNum = 0;
|
||||||
..add(GetCounterEvent(deviceCode: deviceCode!)),
|
} else if (state is LoadingNewSate) {
|
||||||
child: BlocBuilder<OneGangBloc, OneGangState>(
|
countNum = 0;
|
||||||
builder: (context, state) {
|
}
|
||||||
Duration duration = Duration.zero;
|
return PopScope(
|
||||||
int countNum = 0;
|
canPop: false,
|
||||||
int tabNum = 0;
|
onPopInvoked: (didPop) {
|
||||||
if (state is UpdateTimerState) {
|
if (!didPop) {
|
||||||
countNum = state.seconds;
|
oneGangBloc.add(OnClose());
|
||||||
} else if (state is TimerRunInProgress) {
|
Navigator.pop(context);
|
||||||
countNum = state.remainingTime;
|
}
|
||||||
} else if (state is TimerRunComplete) {
|
},
|
||||||
countNum = 0;
|
child: DefaultTabController(
|
||||||
} else if (state is LoadingNewSate) {
|
length: 2,
|
||||||
countNum = 0;
|
child: DefaultScaffold(
|
||||||
}
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
if (state is ChangeSlidingSegmentState) {
|
centerTitle: true,
|
||||||
tabNum = state.value;
|
title: const BodyLarge(
|
||||||
}
|
text: 'Schedule',
|
||||||
return PopScope(
|
fontColor: ColorsManager.primaryColor,
|
||||||
canPop: false,
|
fontWeight: FontsManager.bold,
|
||||||
onPopInvoked: (didPop) {
|
|
||||||
if (!didPop) {
|
|
||||||
BlocProvider.of<OneGangBloc>(context).add(OnClose());
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: MediaQuery.sizeOf(context).width,
|
|
||||||
height: MediaQuery.sizeOf(context).height,
|
|
||||||
padding: const EdgeInsets.all(24),
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image: AssetImage(
|
|
||||||
Assets.assetsImagesBackground,
|
|
||||||
),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
opacity: 0.4,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: state is LoadingInitialState || state is LoadingNewSate
|
actions: [
|
||||||
? const Center(
|
oneGangBloc.createSchedule == true ?
|
||||||
child: DefaultContainer(
|
TextButton(
|
||||||
width: 50, height: 50, child: CircularProgressIndicator()),
|
onPressed: () {
|
||||||
)
|
oneGangBloc.add(ThreeGangSave());
|
||||||
: Column(
|
},
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
child: const Text('Save')
|
||||||
children: [
|
) :
|
||||||
Container(
|
oneGangBloc.selectedTabIndex==1? IconButton(
|
||||||
width: MediaQuery.sizeOf(context).width,
|
onPressed: () {
|
||||||
decoration: const ShapeDecoration(
|
oneGangBloc.toggleCreateSchedule();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
):SizedBox(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child:
|
||||||
|
state is LoadingInitialState?
|
||||||
|
const Center(child: CircularProgressIndicator()):
|
||||||
|
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) {
|
||||||
|
if(value==0){
|
||||||
|
if(oneGangBloc.createSchedule == true){
|
||||||
|
oneGangBloc.toggleCreateSchedule();
|
||||||
|
}
|
||||||
|
oneGangBloc.toggleSelectedIndex(0);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
oneGangBloc.toggleSelectedIndex(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
indicatorColor: Colors.white, // Customize the indicator
|
||||||
|
dividerHeight: 0,
|
||||||
|
// indicatorWeight: MediaQuery.of(context).size.width,
|
||||||
|
// indicatorSize: ,
|
||||||
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
|
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)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: CupertinoSlidingSegmentedControl<int>(
|
tabs: [
|
||||||
thumbColor: ColorsManager.slidingBlueColor,
|
Tab(
|
||||||
onValueChanged: (value) {
|
child: Container(
|
||||||
BlocProvider.of<OneGangBloc>(context)
|
padding: const EdgeInsets.symmetric(
|
||||||
.add(ChangeSlidingSegment(value: value ?? 0));
|
vertical: 10),
|
||||||
},
|
|
||||||
groupValue:
|
|
||||||
state is ChangeSlidingSegmentState ? state.value : 0,
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
children: <int, Widget>{
|
|
||||||
0: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
||||||
child: BodySmall(
|
child: BodySmall(
|
||||||
text: 'Countdown',
|
text: 'Countdown',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
@ -120,7 +311,9 @@ class OneGangTimerScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
1: Container(
|
),
|
||||||
|
Tab(
|
||||||
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Schedule',
|
'Schedule',
|
||||||
@ -131,50 +324,106 @@ class OneGangTimerScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
if (tabNum == 0)
|
|
||||||
countNum > 0
|
),
|
||||||
? BodyLarge(
|
Expanded(
|
||||||
text: _formatDuration(countNum),
|
child: TabBarView(
|
||||||
fontColor: ColorsManager.slidingBlueColor,
|
children: [
|
||||||
fontSize: 40,
|
Center(
|
||||||
)
|
child: Container(
|
||||||
: CupertinoTimerPicker(
|
child: Column(
|
||||||
mode: CupertinoTimerPickerMode.hm,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
onTimerDurationChanged: (Duration newDuration) {
|
children: [
|
||||||
duration = newDuration;
|
countNum > 0
|
||||||
},
|
? BodyLarge(
|
||||||
),
|
text: _formatDuration(countNum),
|
||||||
if (tabNum == 0)
|
fontColor:
|
||||||
GestureDetector(
|
ColorsManager.slidingBlueColor,
|
||||||
onTap: () {
|
fontSize: 40,
|
||||||
if (state is LoadingNewSate) {
|
)
|
||||||
return;
|
: CupertinoTimerPicker(
|
||||||
}
|
mode: CupertinoTimerPickerMode.hm,
|
||||||
if (countNum > 0) {
|
onTimerDurationChanged:
|
||||||
BlocProvider.of<OneGangBloc>(context).add(
|
(Duration newDuration) {
|
||||||
SetCounterValue(
|
duration = newDuration;
|
||||||
deviceCode: deviceCode!,
|
},
|
||||||
duration: Duration.zero));
|
),
|
||||||
} else if (duration != Duration.zero) {
|
GestureDetector(
|
||||||
BlocProvider.of<OneGangBloc>(context).add(
|
onTap: () {
|
||||||
SetCounterValue(
|
if (state is LoadingNewSate) {
|
||||||
deviceCode: deviceCode!, duration: duration));
|
return;
|
||||||
}
|
}
|
||||||
},
|
if (countNum > 0) {
|
||||||
child: SvgPicture.asset(
|
oneGangBloc.add(SetCounterValue(
|
||||||
countNum > 0 ? Assets.pauseIcon : Assets.playIcon))
|
deviceCode: deviceCode,
|
||||||
],
|
duration: Duration.zero));
|
||||||
)));
|
} else if (duration != Duration.zero) {
|
||||||
},
|
oneGangBloc.add(SetCounterValue(
|
||||||
),
|
deviceCode: deviceCode,
|
||||||
),
|
duration: duration));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(countNum > 0
|
||||||
|
? Assets.pauseIcon
|
||||||
|
: Assets.playIcon)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment:oneGangBloc.listSchedule.isNotEmpty?
|
||||||
|
MainAxisAlignment.start:MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
child: oneGangBloc.createSchedule == true ?
|
||||||
|
CreateSchedule(
|
||||||
|
onToggleChanged: (bool isOn) {
|
||||||
|
oneGangBloc.toggleSchedule = isOn;
|
||||||
|
},
|
||||||
|
onDateTimeChanged: (DateTime dateTime) {
|
||||||
|
oneGangBloc.selectedTime=dateTime;
|
||||||
|
},
|
||||||
|
days: oneGangBloc.days,
|
||||||
|
selectDays: (List<String> selectedDays) {
|
||||||
|
oneGangBloc.selectedDays = selectedDays;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: ScheduleListView(
|
||||||
|
listSchedule: oneGangBloc.listSchedule, // Pass the schedule list here
|
||||||
|
onDismissed: (scheduleId) {
|
||||||
|
oneGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
||||||
|
oneGangBloc.add(DeleteScheduleEvent(id: scheduleId));
|
||||||
|
},
|
||||||
|
onToggleSchedule: (scheduleId, isEnabled) {
|
||||||
|
oneGangBloc.add(ToggleScheduleEvent(
|
||||||
|
id: scheduleId,
|
||||||
|
toggle: isEnabled,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _formatDuration(int seconds) {
|
String _formatDuration(int seconds) {
|
||||||
final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
||||||
final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||||
|
@ -63,7 +63,8 @@ class ScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TimerScreen(
|
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||||
|
switchCode :"switch_1",
|
||||||
device: device,
|
device: device,
|
||||||
deviceCode: 'countdown_1',
|
deviceCode: 'countdown_1',
|
||||||
)));
|
)));
|
||||||
@ -99,10 +100,11 @@ class ScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TimerScreen(
|
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||||
device: device,
|
switchCode :"switch_2",
|
||||||
deviceCode: 'countdown_2',
|
device: device,
|
||||||
)));
|
deviceCode: 'countdown_2',
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding:
|
padding:
|
||||||
@ -135,8 +137,9 @@ class ScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TimerScreen(
|
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||||
device: device,
|
switchCode :"switch_3",
|
||||||
|
device: device,
|
||||||
deviceCode: 'countdown_3',
|
deviceCode: 'countdown_3',
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,9 @@ class ThreeGangScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => ThreeGangBloc(threeGangId: device?.uuid ?? '')
|
create: (context) => ThreeGangBloc(
|
||||||
|
switchCode: '',
|
||||||
|
threeGangId: device?.uuid ?? '')
|
||||||
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
||||||
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
@ -7,7 +7,10 @@ import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_blo
|
|||||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/create_schedule.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/schedule_list.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
@ -15,10 +18,254 @@ import 'package:syncrow_app/utils/context_extension.dart';
|
|||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
class TimerScreen extends StatelessWidget {
|
// class TimerScreen extends StatelessWidget {
|
||||||
|
// final DeviceModel device;
|
||||||
|
// final String deviceCode;
|
||||||
|
// final String switchCode;
|
||||||
|
// const TimerScreen(
|
||||||
|
// {required this.device,
|
||||||
|
// required this.deviceCode,
|
||||||
|
// required this.switchCode,
|
||||||
|
// super.key});
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return AnnotatedRegion(
|
||||||
|
// value: SystemUiOverlayStyle(
|
||||||
|
// statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||||
|
// statusBarIconBrightness: Brightness.light,
|
||||||
|
// ),
|
||||||
|
// child:
|
||||||
|
//
|
||||||
|
// BlocProvider(
|
||||||
|
// create: (context) => ThreeGangBloc(
|
||||||
|
// switchCode: switchCode, threeGangId: device.uuid ?? '')..add(GetScheduleEvent())
|
||||||
|
// ..add(GetCounterEvent(deviceCode: deviceCode)),
|
||||||
|
// child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||||
|
// builder: (context, state) {
|
||||||
|
// final threeGangBloc = BlocProvider.of<ThreeGangBloc>(context);
|
||||||
|
//
|
||||||
|
// Duration duration = Duration.zero;
|
||||||
|
// int countNum = 0;
|
||||||
|
// int tabNum = 0;
|
||||||
|
// if (state is UpdateTimerState) {
|
||||||
|
// countNum = state.seconds;
|
||||||
|
// } else if (state is TimerRunInProgress) {
|
||||||
|
// countNum = state.remainingTime;
|
||||||
|
// } else if (state is TimerRunComplete) {
|
||||||
|
// countNum = 0;
|
||||||
|
// } else if (state is LoadingNewSate) {
|
||||||
|
// countNum = 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (state is ChangeSlidingSegmentState) {
|
||||||
|
// tabNum = state.value;
|
||||||
|
// }
|
||||||
|
// return Scaffold(
|
||||||
|
// backgroundColor: ColorsManager.backgroundColor,
|
||||||
|
// extendBodyBehindAppBar: true,
|
||||||
|
// extendBody: true,
|
||||||
|
// appBar: AppBar(
|
||||||
|
// backgroundColor: Colors.transparent,
|
||||||
|
// centerTitle: true,
|
||||||
|
// title: const BodyLarge(
|
||||||
|
// text: 'Schedule',
|
||||||
|
// fontColor: ColorsManager.primaryColor,
|
||||||
|
// fontWeight: FontsManager.bold,
|
||||||
|
// ),
|
||||||
|
// actions: [
|
||||||
|
// if (tabNum == 1)
|
||||||
|
// threeGangBloc.createSchedule == true
|
||||||
|
// ? TextButton(onPressed: () {
|
||||||
|
// threeGangBloc.add(ThreeGangSave() );
|
||||||
|
// }, child: const Text('Save'))
|
||||||
|
// : IconButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// threeGangBloc.toggleCreateSchedule();
|
||||||
|
// },
|
||||||
|
// icon: const Icon(Icons.add),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// body: SafeArea(
|
||||||
|
// child:PopScope(
|
||||||
|
// canPop: false,
|
||||||
|
// onPopInvoked: (didPop) {
|
||||||
|
// if (!didPop) {
|
||||||
|
// BlocProvider.of<ThreeGangBloc>(context).add(OnClose());
|
||||||
|
// Navigator.pop(context);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// child: Container(
|
||||||
|
// width: MediaQuery.sizeOf(context).width,
|
||||||
|
// padding: const EdgeInsets.all(24),
|
||||||
|
// decoration: const BoxDecoration(
|
||||||
|
// image: DecorationImage(
|
||||||
|
// image: AssetImage(
|
||||||
|
// Assets.assetsImagesBackground,
|
||||||
|
// ),
|
||||||
|
// fit: BoxFit.cover,
|
||||||
|
// opacity: 0.4,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: state is LoadingInitialState ||
|
||||||
|
// state is LoadingNewSate
|
||||||
|
// ? const Center(
|
||||||
|
// child: DefaultContainer(
|
||||||
|
// width: 50,
|
||||||
|
// height: 50,
|
||||||
|
// child: CircularProgressIndicator()),
|
||||||
|
// )
|
||||||
|
// : Column(
|
||||||
|
// children: [
|
||||||
|
// Container(
|
||||||
|
// width: MediaQuery.sizeOf(context).width,
|
||||||
|
// decoration: const ShapeDecoration(
|
||||||
|
// color: ColorsManager.slidingBlueColor,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.all(
|
||||||
|
// Radius.circular(20)),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child:
|
||||||
|
// CupertinoSlidingSegmentedControl<int>(
|
||||||
|
// thumbColor:
|
||||||
|
// ColorsManager.slidingBlueColor,
|
||||||
|
// onValueChanged: (value) {
|
||||||
|
// BlocProvider.of<ThreeGangBloc>(context)
|
||||||
|
// .add(ChangeSlidingSegment(
|
||||||
|
// value: value ?? 0));
|
||||||
|
// },
|
||||||
|
// groupValue:
|
||||||
|
// state is ChangeSlidingSegmentState
|
||||||
|
// ? state.value
|
||||||
|
// : 0,
|
||||||
|
// backgroundColor: Colors.white,
|
||||||
|
// children: <int, Widget>{
|
||||||
|
// 0: Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(
|
||||||
|
// vertical: 10),
|
||||||
|
// child: BodySmall(
|
||||||
|
// text: 'Countdown',
|
||||||
|
// style: context.bodySmall.copyWith(
|
||||||
|
// color: ColorsManager.blackColor,
|
||||||
|
// fontSize: 12,
|
||||||
|
// fontWeight: FontWeight.w400,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// 1: Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(
|
||||||
|
// vertical: 10),
|
||||||
|
// child: Text(
|
||||||
|
// 'Schedule',
|
||||||
|
// style: context.bodySmall.copyWith(
|
||||||
|
// color: ColorsManager.blackColor,
|
||||||
|
// fontSize: 12,
|
||||||
|
// fontWeight: FontWeight.w400,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// if (tabNum == 0)
|
||||||
|
// countNum > 0
|
||||||
|
// ? BodyLarge(
|
||||||
|
// text: _formatDuration(countNum),
|
||||||
|
// fontColor:
|
||||||
|
// ColorsManager.slidingBlueColor,
|
||||||
|
// fontSize: 40,
|
||||||
|
// )
|
||||||
|
// : CupertinoTimerPicker(
|
||||||
|
// mode: CupertinoTimerPickerMode.hm,
|
||||||
|
// onTimerDurationChanged:
|
||||||
|
// (Duration newDuration) {
|
||||||
|
// duration = newDuration;
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// if (tabNum == 0)
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () {
|
||||||
|
// if (state is LoadingNewSate) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (countNum > 0) {
|
||||||
|
// BlocProvider.of<ThreeGangBloc>(
|
||||||
|
// context)
|
||||||
|
// .add(SetCounterValue(
|
||||||
|
// deviceCode: deviceCode,
|
||||||
|
// duration: Duration.zero));
|
||||||
|
// } else if (duration !=
|
||||||
|
// Duration.zero) {
|
||||||
|
// BlocProvider.of<ThreeGangBloc>(
|
||||||
|
// context)
|
||||||
|
// .add(SetCounterValue(
|
||||||
|
// deviceCode: deviceCode,
|
||||||
|
// duration: duration));
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// child: SvgPicture.asset(countNum > 0
|
||||||
|
// ? Assets.pauseIcon
|
||||||
|
// : Assets.playIcon)),
|
||||||
|
// if (tabNum == 1)
|
||||||
|
// SizedBox(
|
||||||
|
// child: threeGangBloc.createSchedule == true
|
||||||
|
// ? CreateSchedule(
|
||||||
|
// onToggleChanged: (bool isOn) {
|
||||||
|
// threeGangBloc.toggleSchedule = isOn;
|
||||||
|
// },
|
||||||
|
// onDateTimeChanged: (DateTime dateTime) {
|
||||||
|
// threeGangBloc.selectedTime = dateTime;
|
||||||
|
// },
|
||||||
|
// days: threeGangBloc.days,
|
||||||
|
// selectDays: (List<String>selectedDays) {
|
||||||
|
// threeGangBloc.selectedDays = selectedDays;
|
||||||
|
// },
|
||||||
|
// ) : SizedBox(
|
||||||
|
// height: MediaQuery.of(context).size.height/1.9,
|
||||||
|
// child: ScheduleListView(
|
||||||
|
// listSchedule: threeGangBloc.listSchedule, // Pass the schedule list here
|
||||||
|
// onDismissed: (scheduleId) {
|
||||||
|
// threeGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
||||||
|
// threeGangBloc.add(DeleteScheduleEvent(id: scheduleId));
|
||||||
|
// },
|
||||||
|
// onToggleSchedule: (scheduleId, isEnabled) {
|
||||||
|
// threeGangBloc.add(ToggleScheduleEvent(
|
||||||
|
// id: scheduleId,
|
||||||
|
// toggle: isEnabled,
|
||||||
|
// ));
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ))
|
||||||
|
// ],
|
||||||
|
// )))
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// String _formatDuration(int seconds) {
|
||||||
|
// final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
||||||
|
// final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||||
|
// final secs = (seconds % 60).toString().padLeft(2, '0');
|
||||||
|
// return '$hours:$minutes:$secs';
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
class TimerScheduleScreen extends StatelessWidget {
|
||||||
final DeviceModel device;
|
final DeviceModel device;
|
||||||
final String deviceCode;
|
final String deviceCode;
|
||||||
const TimerScreen({required this.device, required this.deviceCode, super.key});
|
final String switchCode;
|
||||||
|
const TimerScheduleScreen(
|
||||||
|
{required this.device,
|
||||||
|
required this.deviceCode,
|
||||||
|
required this.switchCode,
|
||||||
|
super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -27,150 +274,219 @@ class TimerScreen extends StatelessWidget {
|
|||||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||||
statusBarIconBrightness: Brightness.light,
|
statusBarIconBrightness: Brightness.light,
|
||||||
),
|
),
|
||||||
child: Scaffold(
|
child: BlocProvider(
|
||||||
backgroundColor: ColorsManager.backgroundColor,
|
create: (context) =>
|
||||||
extendBodyBehindAppBar: true,
|
ThreeGangBloc(switchCode: switchCode, threeGangId: device.uuid ?? '')
|
||||||
extendBody: true,
|
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||||
appBar: AppBar(
|
..add(GetScheduleEvent()),
|
||||||
backgroundColor: Colors.transparent,
|
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||||
centerTitle: true,
|
builder: (context, state) {
|
||||||
title: const BodyLarge(
|
final threeGangBloc = BlocProvider.of<ThreeGangBloc>(context);
|
||||||
text: 'Schedule',
|
Duration duration = Duration.zero;
|
||||||
fontColor: ColorsManager.primaryColor,
|
int countNum = 0;
|
||||||
fontWeight: FontsManager.bold,
|
if (state is UpdateTimerState) {
|
||||||
),
|
countNum = state.seconds;
|
||||||
),
|
} else if (state is TimerRunInProgress) {
|
||||||
body: SafeArea(
|
countNum = state.remainingTime;
|
||||||
child: BlocProvider(
|
} else if (state is TimerRunComplete) {
|
||||||
create: (context) => ThreeGangBloc(threeGangId: device.uuid ?? '')
|
countNum = 0;
|
||||||
..add(GetCounterEvent(deviceCode: deviceCode)),
|
} else if (state is LoadingNewSate) {
|
||||||
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
countNum = 0;
|
||||||
builder: (context, state) {
|
}
|
||||||
Duration duration = Duration.zero;
|
return PopScope(
|
||||||
int countNum = 0;
|
canPop: false,
|
||||||
int tabNum = 0;
|
onPopInvoked: (didPop) {
|
||||||
if (state is UpdateTimerState) {
|
if (!didPop) {
|
||||||
countNum = state.seconds;
|
threeGangBloc.add(OnClose());
|
||||||
} else if (state is TimerRunInProgress) {
|
Navigator.pop(context);
|
||||||
countNum = state.remainingTime;
|
}
|
||||||
} else if (state is TimerRunComplete) {
|
},
|
||||||
countNum = 0;
|
child: DefaultTabController(
|
||||||
} else if (state is LoadingNewSate) {
|
length: 2,
|
||||||
countNum = 0;
|
child: DefaultScaffold(
|
||||||
}
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
if (state is ChangeSlidingSegmentState) {
|
centerTitle: true,
|
||||||
tabNum = state.value;
|
title: const BodyLarge(
|
||||||
}
|
text: 'Schedule',
|
||||||
return PopScope(
|
fontColor: ColorsManager.primaryColor,
|
||||||
canPop: false,
|
fontWeight: FontsManager.bold,
|
||||||
onPopInvoked: (didPop) {
|
|
||||||
if (!didPop) {
|
|
||||||
BlocProvider.of<ThreeGangBloc>(context).add(OnClose());
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: MediaQuery.sizeOf(context).width,
|
|
||||||
height: MediaQuery.sizeOf(context).height,
|
|
||||||
padding: const EdgeInsets.all(24),
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image: AssetImage(
|
|
||||||
Assets.assetsImagesBackground,
|
|
||||||
),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
opacity: 0.4,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: state is LoadingInitialState || state is LoadingNewSate
|
actions: [
|
||||||
? const Center(
|
threeGangBloc.createSchedule == true ?
|
||||||
child: DefaultContainer(
|
TextButton(
|
||||||
width: 50, height: 50, child: CircularProgressIndicator()),
|
onPressed: () {
|
||||||
)
|
threeGangBloc.add(ThreeGangSave());
|
||||||
: Column(
|
},
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
child: const Text('Save')
|
||||||
children: [
|
) :
|
||||||
Container(
|
threeGangBloc.selectedTabIndex==1? IconButton(
|
||||||
width: MediaQuery.sizeOf(context).width,
|
onPressed: () {
|
||||||
decoration: const ShapeDecoration(
|
threeGangBloc.toggleCreateSchedule();
|
||||||
color: ColorsManager.slidingBlueColor,
|
},
|
||||||
shape: RoundedRectangleBorder(
|
icon: const Icon(Icons.add),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
):SizedBox(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child:
|
||||||
|
state is LoadingInitialState?
|
||||||
|
const Center(child: CircularProgressIndicator()):
|
||||||
|
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) {
|
||||||
|
if(value==0){
|
||||||
|
if(threeGangBloc.createSchedule == true){
|
||||||
|
threeGangBloc.toggleCreateSchedule();
|
||||||
|
}
|
||||||
|
threeGangBloc.toggleSelectedIndex(0);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
threeGangBloc.toggleSelectedIndex(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
indicatorColor: Colors.white, // Customize the indicator
|
||||||
|
dividerHeight: 0,
|
||||||
|
// indicatorWeight: MediaQuery.of(context).size.width,
|
||||||
|
// indicatorSize: ,
|
||||||
|
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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: CupertinoSlidingSegmentedControl<int>(
|
),
|
||||||
thumbColor: ColorsManager.slidingBlueColor,
|
),
|
||||||
onValueChanged: (value) {
|
Tab(
|
||||||
BlocProvider.of<ThreeGangBloc>(context)
|
child: Container(
|
||||||
.add(ChangeSlidingSegment(value: value ?? 0));
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
},
|
child: Text(
|
||||||
groupValue:
|
'Schedule',
|
||||||
state is ChangeSlidingSegmentState ? state.value : 0,
|
style: context.bodySmall.copyWith(
|
||||||
backgroundColor: Colors.white,
|
color: ColorsManager.blackColor,
|
||||||
children: <int, Widget>{
|
fontSize: 12,
|
||||||
0: Container(
|
fontWeight: FontWeight.w400,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
),
|
||||||
child: BodySmall(
|
|
||||||
text: 'Countdown',
|
|
||||||
style: context.bodySmall.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
1: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
|
||||||
child: Text(
|
|
||||||
'Schedule',
|
|
||||||
style: context.bodySmall.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (tabNum == 0)
|
),
|
||||||
countNum > 0
|
],
|
||||||
? BodyLarge(
|
),
|
||||||
text: _formatDuration(countNum),
|
|
||||||
fontColor: ColorsManager.slidingBlueColor,
|
),
|
||||||
fontSize: 40,
|
Expanded(
|
||||||
)
|
child: TabBarView(
|
||||||
: CupertinoTimerPicker(
|
children: [
|
||||||
mode: CupertinoTimerPickerMode.hm,
|
Center(
|
||||||
onTimerDurationChanged: (Duration newDuration) {
|
child: Container(
|
||||||
duration = newDuration;
|
child: Column(
|
||||||
},
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
),
|
children: [
|
||||||
if (tabNum == 0)
|
countNum > 0
|
||||||
GestureDetector(
|
? BodyLarge(
|
||||||
onTap: () {
|
text: _formatDuration(countNum),
|
||||||
if (state is LoadingNewSate) {
|
fontColor:
|
||||||
return;
|
ColorsManager.slidingBlueColor,
|
||||||
}
|
fontSize: 40,
|
||||||
if (countNum > 0) {
|
)
|
||||||
BlocProvider.of<ThreeGangBloc>(context).add(
|
: CupertinoTimerPicker(
|
||||||
SetCounterValue(
|
mode: CupertinoTimerPickerMode.hm,
|
||||||
|
onTimerDurationChanged:
|
||||||
|
(Duration newDuration) {
|
||||||
|
duration = newDuration;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (state is LoadingNewSate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (countNum > 0) {
|
||||||
|
threeGangBloc.add(SetCounterValue(
|
||||||
deviceCode: deviceCode,
|
deviceCode: deviceCode,
|
||||||
duration: Duration.zero));
|
duration: Duration.zero));
|
||||||
} else if (duration != Duration.zero) {
|
} else if (duration != Duration.zero) {
|
||||||
BlocProvider.of<ThreeGangBloc>(context).add(
|
threeGangBloc.add(SetCounterValue(
|
||||||
SetCounterValue(
|
deviceCode: deviceCode,
|
||||||
deviceCode: deviceCode, duration: duration));
|
duration: duration));
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
child: SvgPicture.asset(countNum > 0
|
||||||
|
? Assets.pauseIcon
|
||||||
|
: Assets.playIcon)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment:threeGangBloc.listSchedule.isNotEmpty?
|
||||||
|
MainAxisAlignment.start:MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
child: threeGangBloc.createSchedule == true ?
|
||||||
|
CreateSchedule(
|
||||||
|
onToggleChanged: (bool isOn) {
|
||||||
|
threeGangBloc.toggleSchedule = isOn;
|
||||||
},
|
},
|
||||||
child: SvgPicture.asset(
|
onDateTimeChanged: (DateTime dateTime) {
|
||||||
countNum > 0 ? Assets.pauseIcon : Assets.playIcon))
|
threeGangBloc.selectedTime=dateTime;
|
||||||
],
|
},
|
||||||
)));
|
days: threeGangBloc.days,
|
||||||
},
|
selectDays: (List<String> selectedDays) {
|
||||||
),
|
threeGangBloc.selectedDays = selectedDays;
|
||||||
),
|
},
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: ScheduleListView(
|
||||||
|
listSchedule: threeGangBloc.listSchedule, // Pass the schedule list here
|
||||||
|
onDismissed: (scheduleId) {
|
||||||
|
threeGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId);
|
||||||
|
threeGangBloc.add(DeleteScheduleEvent(id: scheduleId));
|
||||||
|
},
|
||||||
|
onToggleSchedule: (scheduleId, isEnabled) {
|
||||||
|
threeGangBloc.add(ToggleScheduleEvent(
|
||||||
|
id: scheduleId,
|
||||||
|
toggle: isEnabled,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -15,14 +15,16 @@ import 'package:syncrow_app/utils/context_extension.dart';
|
|||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class TwoGangScreen extends StatelessWidget {
|
class TwoGangScreen extends StatelessWidget {
|
||||||
const TwoGangScreen({super.key, this.device});
|
const TwoGangScreen({super.key, this.device, this.switchCode});
|
||||||
|
|
||||||
final DeviceModel? device;
|
final DeviceModel? device;
|
||||||
|
final String? switchCode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => TwoGangBloc(twoGangId: device?.uuid ?? '')
|
create: (context) => TwoGangBloc(
|
||||||
|
switchCode: switchCode??'',
|
||||||
|
twoGangId: device?.uuid ?? '')
|
||||||
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
||||||
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
@ -35,7 +37,6 @@ class TwoGangScreen extends StatelessWidget {
|
|||||||
|
|
||||||
List<GroupTwoGangModel> groupTwoGangModel = [];
|
List<GroupTwoGangModel> groupTwoGangModel = [];
|
||||||
bool allSwitchesOn = false;
|
bool allSwitchesOn = false;
|
||||||
|
|
||||||
if (state is LoadingNewSate) {
|
if (state is LoadingNewSate) {
|
||||||
twoGangModel = state.twoGangModel;
|
twoGangModel = state.twoGangModel;
|
||||||
} else if (state is UpdateState) {
|
} else if (state is UpdateState) {
|
||||||
@ -46,9 +47,7 @@ class TwoGangScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
return state is LoadingInitialState
|
return state is LoadingInitialState
|
||||||
? const Center(
|
? const Center(
|
||||||
child:
|
child: DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),)
|
||||||
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
|
||||||
)
|
|
||||||
: device == null
|
: device == null
|
||||||
? TwoGangList(
|
? TwoGangList(
|
||||||
twoGangList: groupTwoGangModel,
|
twoGangList: groupTwoGangModel,
|
||||||
|
@ -63,9 +63,10 @@ class TwoGangScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TwoTimerScreen(
|
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||||
device: device,
|
device: device,
|
||||||
deviceCode: 'countdown_1',
|
deviceCode: 'countdown_1',
|
||||||
|
switchCode:'switch_1' ,
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -75,7 +76,7 @@ class TwoGangScheduleScreen extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
BodySmall(
|
BodySmall(
|
||||||
text: "Bedside Light",
|
text: "Cove Light",
|
||||||
style: context.bodyMedium.copyWith(
|
style: context.bodyMedium.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager.textPrimaryColor,
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
@ -99,9 +100,10 @@ class TwoGangScheduleScreen extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => TwoTimerScreen(
|
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen(
|
||||||
device: device,
|
device: device,
|
||||||
deviceCode: 'countdown_2',
|
deviceCode: 'countdown_2',
|
||||||
|
switchCode:'switch_2' ,
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -111,7 +113,7 @@ class TwoGangScheduleScreen extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
BodySmall(
|
BodySmall(
|
||||||
text: "Ceiling Light",
|
text: "Chandelier",
|
||||||
style: context.bodyMedium.copyWith(
|
style: context.bodyMedium.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager.textPrimaryColor,
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
|
@ -7,10 +7,9 @@ import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_bloc.da
|
|||||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/create_schedule.dart';
|
import 'package:syncrow_app/features/shared_widgets/create_schedule.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/empty_schedule.dart';
|
import 'package:syncrow_app/features/shared_widgets/schedule_list.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
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_small.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
@ -18,11 +17,15 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|||||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.dart';
|
||||||
|
|
||||||
class TwoTimerScreen extends StatelessWidget {
|
class TimerScheduleScreen extends StatelessWidget {
|
||||||
final DeviceModel device;
|
final DeviceModel device;
|
||||||
final String deviceCode;
|
final String deviceCode;
|
||||||
const TwoTimerScreen(
|
final String switchCode;
|
||||||
{required this.device, required this.deviceCode, super.key});
|
const TimerScheduleScreen(
|
||||||
|
{required this.device,
|
||||||
|
required this.deviceCode,
|
||||||
|
required this.switchCode,
|
||||||
|
super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -32,15 +35,15 @@ class TwoTimerScreen extends StatelessWidget {
|
|||||||
statusBarIconBrightness: Brightness.light,
|
statusBarIconBrightness: Brightness.light,
|
||||||
),
|
),
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => TwoGangBloc(twoGangId: device.uuid ?? '')
|
create: (context) =>
|
||||||
..add(GetCounterEvent(deviceCode: deviceCode)),
|
TwoGangBloc(switchCode: switchCode, twoGangId: device.uuid ?? '')
|
||||||
|
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||||
|
..add(GetScheduleEvent()),
|
||||||
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final twoGangBloc = BlocProvider.of<TwoGangBloc>(context);
|
final twoGangBloc = BlocProvider.of<TwoGangBloc>(context);
|
||||||
|
|
||||||
Duration duration = Duration.zero;
|
Duration duration = Duration.zero;
|
||||||
int countNum = 0;
|
int countNum = 0;
|
||||||
int tabNum = 0;
|
|
||||||
if (state is UpdateTimerState) {
|
if (state is UpdateTimerState) {
|
||||||
countNum = state.seconds;
|
countNum = state.seconds;
|
||||||
} else if (state is TimerRunInProgress) {
|
} else if (state is TimerRunInProgress) {
|
||||||
@ -49,228 +52,197 @@ class TwoTimerScreen extends StatelessWidget {
|
|||||||
countNum = 0;
|
countNum = 0;
|
||||||
} else if (state is LoadingNewSate) {
|
} else if (state is LoadingNewSate) {
|
||||||
countNum = 0;
|
countNum = 0;
|
||||||
} else if (state is ChangeSlidingSegmentState) {
|
|
||||||
tabNum = state.value;
|
|
||||||
}
|
}
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
backgroundColor: ColorsManager.backgroundColor,
|
canPop: false,
|
||||||
extendBodyBehindAppBar: true,
|
onPopInvoked: (didPop) {
|
||||||
extendBody: true,
|
if (!didPop) {
|
||||||
appBar: AppBar(
|
twoGangBloc.add(OnClose());
|
||||||
backgroundColor: Colors.transparent,
|
Navigator.pop(context);
|
||||||
centerTitle: true,
|
}
|
||||||
title: const BodyLarge(
|
},
|
||||||
text: 'Schedule',
|
child: DefaultTabController(
|
||||||
fontColor: ColorsManager.primaryColor,
|
length: 2,
|
||||||
fontWeight: FontsManager.bold,
|
child: DefaultScaffold(
|
||||||
),
|
appBar: AppBar(
|
||||||
actions: [
|
backgroundColor: Colors.transparent,
|
||||||
if (tabNum == 1)
|
centerTitle: true,
|
||||||
twoGangBloc.createSchedule == true
|
title: const BodyLarge(
|
||||||
? TextButton(onPressed: () {}, child: const Text('Save'))
|
text: 'Schedule',
|
||||||
: IconButton(
|
fontColor: ColorsManager.primaryColor,
|
||||||
|
fontWeight: FontsManager.bold,
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
twoGangBloc.createSchedule == true ?
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
twoGangBloc.add(TwoGangSave());
|
||||||
|
},
|
||||||
|
child: const Text('Save')
|
||||||
|
) :
|
||||||
|
twoGangBloc.selectedTabIndex==1? IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
twoGangBloc.toggleCreateSchedule();
|
twoGangBloc.toggleCreateSchedule();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
),
|
):SizedBox(),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
body: SafeArea(
|
|
||||||
child: PopScope(
|
|
||||||
canPop: false,
|
|
||||||
onPopInvoked: (didPop) {
|
|
||||||
if (!didPop) {
|
|
||||||
BlocProvider.of<TwoGangBloc>(context).add(OnClose());
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: MediaQuery.sizeOf(context).width,
|
|
||||||
height: MediaQuery.sizeOf(context).height,
|
|
||||||
padding: const EdgeInsets.all(24),
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image: AssetImage(Assets.assetsImagesBackground),
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
opacity: 0.4,
|
|
||||||
),
|
),
|
||||||
),
|
child:
|
||||||
child: state is LoadingInitialState ||
|
state is LoadingInitialState?
|
||||||
state is LoadingNewSate
|
const Center(child: CircularProgressIndicator()):
|
||||||
? const Center(
|
Column(
|
||||||
child: DefaultContainer(
|
children: [
|
||||||
width: 50,
|
Container(
|
||||||
height: 50,
|
width: MediaQuery.of(context).size.width,
|
||||||
child: CircularProgressIndicator(),
|
decoration: const ShapeDecoration(
|
||||||
|
color: ColorsManager.onPrimaryColor,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
child: TabBar(
|
||||||
: Column(
|
onTap: (value) {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
print(value);
|
||||||
children: [
|
if(value==0){
|
||||||
Container(
|
if(twoGangBloc.createSchedule == true){
|
||||||
width: MediaQuery.sizeOf(context).width,
|
twoGangBloc.toggleCreateSchedule();
|
||||||
decoration: const ShapeDecoration(
|
}
|
||||||
color: ColorsManager.slidingBlueColor,
|
twoGangBloc.toggleSelectedIndex(0);
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius:
|
}else{
|
||||||
BorderRadius.all(Radius.circular(20)),
|
twoGangBloc.toggleSelectedIndex(1);
|
||||||
),
|
}
|
||||||
),
|
},
|
||||||
child: CupertinoSlidingSegmentedControl<int>(
|
indicatorColor: Colors.white, // Customize the indicator
|
||||||
thumbColor: ColorsManager.slidingBlueColor,
|
dividerHeight: 0,
|
||||||
onValueChanged: (value) {
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
BlocProvider.of<TwoGangBloc>(context).add(
|
indicator: const ShapeDecoration(
|
||||||
ChangeSlidingSegment(
|
color: ColorsManager.slidingBlueColor,
|
||||||
value: value ?? 0));
|
shape: RoundedRectangleBorder(
|
||||||
},
|
borderRadius:
|
||||||
groupValue: state is ChangeSlidingSegmentState
|
BorderRadius.all(Radius.circular(20)),
|
||||||
? state.value
|
|
||||||
: 0,
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
children: <int, Widget>{
|
|
||||||
0: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 10),
|
|
||||||
child: BodySmall(
|
|
||||||
text: 'Countdown',
|
|
||||||
style: context.bodySmall.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
1: Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 10),
|
|
||||||
child: Text(
|
|
||||||
'Schedule',
|
|
||||||
style: context.bodySmall.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (tabNum == 0)
|
tabs: [
|
||||||
countNum > 0
|
Tab(
|
||||||
? BodyLarge(
|
child: Container(
|
||||||
text: _formatDuration(countNum),
|
padding: const EdgeInsets.symmetric(
|
||||||
fontColor:
|
vertical: 10),
|
||||||
ColorsManager.slidingBlueColor,
|
child: BodySmall(
|
||||||
fontSize: 40,
|
text: 'Countdown',
|
||||||
)
|
style: context.bodySmall.copyWith(
|
||||||
: CupertinoTimerPicker(
|
color: ColorsManager.blackColor,
|
||||||
mode: CupertinoTimerPickerMode.hm,
|
fontSize: 12,
|
||||||
onTimerDurationChanged:
|
fontWeight: FontWeight.w400,
|
||||||
(Duration newDuration) {
|
|
||||||
duration = newDuration;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
if (tabNum == 0)
|
),
|
||||||
GestureDetector(
|
),
|
||||||
onTap: () {
|
),
|
||||||
if (state is LoadingNewSate) {
|
Tab(
|
||||||
return;
|
child: Container(
|
||||||
}
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
if (countNum > 0) {
|
child: Text(
|
||||||
BlocProvider.of<TwoGangBloc>(context)
|
'Schedule',
|
||||||
.add(SetCounterValue(
|
style: context.bodySmall.copyWith(
|
||||||
deviceCode: deviceCode,
|
color: ColorsManager.blackColor,
|
||||||
duration: Duration.zero));
|
fontSize: 12,
|
||||||
} else if (duration != Duration.zero) {
|
fontWeight: FontWeight.w400,
|
||||||
BlocProvider.of<TwoGangBloc>(context)
|
),
|
||||||
.add(SetCounterValue(
|
),
|
||||||
deviceCode: deviceCode,
|
),
|
||||||
duration: duration));
|
),
|
||||||
}
|
],
|
||||||
},
|
),
|
||||||
child: SvgPicture.asset(countNum > 0
|
|
||||||
? Assets.pauseIcon
|
|
||||||
: Assets.playIcon)),
|
|
||||||
if (tabNum == 1)
|
|
||||||
SizedBox(
|
|
||||||
height:
|
|
||||||
MediaQuery.of(context).size.height / 2,
|
|
||||||
child: twoGangBloc.createSchedule == true
|
|
||||||
? CreateSchedule(
|
|
||||||
onToggleChanged: (bool isOn) {
|
|
||||||
print(
|
|
||||||
'Toggle is now: ${isOn ? "ON" : "OFF"}');
|
|
||||||
},
|
|
||||||
onDateTimeChanged:
|
|
||||||
(DateTime dateTime) {
|
|
||||||
print('Selected Time: $dateTime');
|
|
||||||
},
|
|
||||||
days: twoGangBloc.days,
|
|
||||||
selectDays:
|
|
||||||
(List<String> selectedDays) {
|
|
||||||
twoGangBloc.selectedDays =
|
|
||||||
selectedDays;
|
|
||||||
print(
|
|
||||||
'Selected Days: ${twoGangBloc.selectedDays}');
|
|
||||||
},
|
|
||||||
)
|
|
||||||
: Center(
|
|
||||||
child: twoGangBloc.listSchedule.isNotEmpty?
|
|
||||||
Container(
|
|
||||||
height: MediaQuery.of(context).size.height / 2,
|
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: twoGangBloc.listSchedule.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return
|
|
||||||
|
|
||||||
Dismissible(
|
|
||||||
key: Key( twoGangBloc.listSchedule[index].id),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {},
|
|
||||||
child:
|
|
||||||
DefaultContainer(
|
|
||||||
padding: EdgeInsets.all(20),
|
|
||||||
height: MediaQuery.of(context).size.height / 8,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(twoGangBloc.listSchedule[index].time),
|
|
||||||
Text(twoGangBloc.listSchedule[index].days.toString()),
|
|
||||||
Text(twoGangBloc.listSchedule[index].enable.toString())
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(child:ListTile(
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
leading: const BodyMedium(
|
|
||||||
text: '',
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
),
|
|
||||||
trailing: Transform.scale(
|
|
||||||
scale: .8,
|
|
||||||
child: CupertinoSwitch(
|
|
||||||
value: true,
|
|
||||||
onChanged: (value) {
|
|
||||||
// smartDoorBloc.add(ToggleRepeatEvent());
|
|
||||||
},
|
|
||||||
applyTheme: true,
|
|
||||||
)),
|
|
||||||
),)
|
|
||||||
],
|
|
||||||
))));
|
|
||||||
},),
|
|
||||||
):
|
|
||||||
EmptySchedule()),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
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)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment:twoGangBloc.listSchedule.isNotEmpty?
|
||||||
|
MainAxisAlignment.start:MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
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: 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,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -23,7 +23,7 @@ class CreateSchedule extends StatefulWidget {
|
|||||||
|
|
||||||
class _CreateScheduleState extends State<CreateSchedule> {
|
class _CreateScheduleState extends State<CreateSchedule> {
|
||||||
List<String> selectedDays = []; // List of selected days
|
List<String> selectedDays = []; // List of selected days
|
||||||
bool isOn = false; // Boolean state for the ON/OFF toggle
|
bool isOn = true; // Boolean state for the ON/OFF toggle
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -114,19 +114,18 @@ class _CreateScheduleState extends State<CreateSchedule> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
isOn ? 'ON' : 'OFF', // Change text based on state
|
isOn ? 'ON' : 'OFF', // Change text based on state
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: isOn ? Colors.green : Colors.red, // Change color based on state
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
backgroundColor: isOn
|
backgroundColor: isOn
|
||||||
? ColorsManager.secondaryColor.withOpacity(0.6)
|
? ColorsManager.secondaryColor.withOpacity(0.6)
|
||||||
: Colors.red.withOpacity(0.6), // Change background color based on state
|
: Colors.red.withOpacity(0.6), // Change background color based on state
|
||||||
child: Icon(
|
child: const Icon(
|
||||||
Icons.power_settings_new,
|
Icons.power_settings_new,
|
||||||
color: isOn ? Colors.green : Colors.red, // Change icon color
|
color: ColorsManager.onPrimaryColor, // Change icon color
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -9,43 +9,43 @@ class EmptySchedule extends StatelessWidget {
|
|||||||
const EmptySchedule({super.key});
|
const EmptySchedule({super.key});
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Center(child: Column(
|
return SizedBox(
|
||||||
mainAxisAlignment:
|
height: 180,
|
||||||
MainAxisAlignment.center,
|
width: 180,
|
||||||
crossAxisAlignment:
|
child: Center(child: Column(
|
||||||
CrossAxisAlignment.center,
|
children: [
|
||||||
children: [
|
Center(
|
||||||
Center(
|
child: SvgPicture.asset(
|
||||||
child: SvgPicture.asset(
|
height: 100,
|
||||||
height: 100,
|
width: 100,
|
||||||
width: 100,
|
Assets.emptySchedule),
|
||||||
Assets.emptySchedule),
|
),
|
||||||
),
|
Column(
|
||||||
Column(
|
children: [
|
||||||
children: [
|
Center(
|
||||||
Center(
|
child: Text(
|
||||||
child: Text(
|
'Please add',
|
||||||
'Please add',
|
style: context.displaySmall
|
||||||
style: context.displaySmall
|
.copyWith(
|
||||||
.copyWith(
|
color: const Color(
|
||||||
color: const Color(
|
0XFFD5D5D5),
|
||||||
0XFFD5D5D5),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Center(
|
||||||
Center(
|
child: Text(
|
||||||
child: Text(
|
'a new schedule',
|
||||||
'a new schedule',
|
style: context.displaySmall
|
||||||
style: context.displaySmall
|
.copyWith(
|
||||||
.copyWith(
|
color: const Color(
|
||||||
color: const Color(
|
0XFFD5D5D5),
|
||||||
0XFFD5D5D5),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
],
|
),),
|
||||||
),);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
120
lib/features/shared_widgets/schedule_list.dart
Normal file
120
lib/features/shared_widgets/schedule_list.dart
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
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/generated/assets.dart';
|
||||||
|
import 'empty_schedule.dart'; // for SVG icons
|
||||||
|
|
||||||
|
|
||||||
|
class ScheduleListView extends StatelessWidget {
|
||||||
|
final List<ScheduleModel> listSchedule;
|
||||||
|
final Function(String) onDismissed;
|
||||||
|
final Function(String, bool) onToggleSchedule;
|
||||||
|
const ScheduleListView({
|
||||||
|
Key? key,
|
||||||
|
required this.listSchedule,
|
||||||
|
required this.onDismissed,
|
||||||
|
required this.onToggleSchedule,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: listSchedule.isNotEmpty
|
||||||
|
? SizedBox(
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: listSchedule.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Dismissible(
|
||||||
|
key: Key(listSchedule[index].scheduleId),
|
||||||
|
background: Container(
|
||||||
|
padding: const EdgeInsets.only(right: 10),
|
||||||
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
|
decoration: const ShapeDecoration(
|
||||||
|
color: Color(0xFFFF0000),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
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) {
|
||||||
|
|
||||||
|
onDismissed(listSchedule[index].scheduleId);
|
||||||
|
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
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].enable ? "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 EmptySchedule()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ void main() {
|
|||||||
//to catch all the errors in the app and send them to firebase
|
//to catch all the errors in the app and send them to firebase
|
||||||
runZonedGuarded(() async {
|
runZonedGuarded(() async {
|
||||||
//to load the environment variables
|
//to load the environment variables
|
||||||
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'production');
|
||||||
await dotenv.load(fileName: '.env.$environment');
|
await dotenv.load(fileName: '.env.$environment');
|
||||||
|
|
||||||
// //this is to make the app work with the self-signed certificate
|
// //this is to make the app work with the self-signed certificate
|
||||||
|
@ -175,4 +175,12 @@ abstract class ApiEndpoints {
|
|||||||
//multiple-time offline
|
//multiple-time offline
|
||||||
static const String deleteTemporaryPassword =
|
static const String deleteTemporaryPassword =
|
||||||
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
||||||
|
|
||||||
|
|
||||||
|
static const String saveSchedule = '/schedule/{deviceUuid}';
|
||||||
|
static const String getSchedule = '/schedule/{deviceUuid}?category={category}';
|
||||||
|
static const String changeSchedule = '/schedule/enable/{deviceUuid}';
|
||||||
|
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||||
import 'package:syncrow_app/services/api/http_service.dart';
|
import 'package:syncrow_app/services/api/http_service.dart';
|
||||||
|
|
||||||
import '../../features/devices/model/create_temporary_password_model.dart';
|
import '../../features/devices/model/create_temporary_password_model.dart';
|
||||||
|
|
||||||
class DevicesAPI {
|
class DevicesAPI {
|
||||||
@ -280,11 +280,20 @@ class DevicesAPI {
|
|||||||
required List<String> days,
|
required List<String> days,
|
||||||
|
|
||||||
}) async {
|
}) async {
|
||||||
|
print( {
|
||||||
|
"category": category,
|
||||||
|
"time": time,
|
||||||
|
"function":{
|
||||||
|
"code": code,
|
||||||
|
"value":value,
|
||||||
|
},
|
||||||
|
"days": days
|
||||||
|
});
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.deleteTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
path: ApiEndpoints.saveSchedule.replaceAll('{deviceUuid}', deviceId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
body:
|
body:
|
||||||
{
|
jsonEncode({
|
||||||
"category": category,
|
"category": category,
|
||||||
"time": time,
|
"time": time,
|
||||||
"function":{
|
"function":{
|
||||||
@ -292,7 +301,54 @@ class DevicesAPI {
|
|||||||
"value":value,
|
"value":value,
|
||||||
},
|
},
|
||||||
"days": days
|
"days": days
|
||||||
|
},),
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future getSchedule({
|
||||||
|
required String category,
|
||||||
|
required String deviceId,
|
||||||
|
}) async {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: ApiEndpoints.getSchedule.replaceAll('{deviceUuid}', deviceId).replaceAll('{category}', category),
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<bool> changeSchedule({
|
||||||
|
required String deviceUuid,
|
||||||
|
required String scheduleId,
|
||||||
|
required bool enable,
|
||||||
|
}) async {
|
||||||
|
final response = await _httpService.put(
|
||||||
|
path: ApiEndpoints.changeSchedule.replaceAll('{deviceUuid}', deviceUuid),
|
||||||
|
body: {
|
||||||
|
"scheduleId": scheduleId,
|
||||||
|
"enable": enable
|
||||||
|
},
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
print('object===-=-=-$json');
|
||||||
|
return json['success'];
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future deleteSchedule({
|
||||||
|
required String deviceUuid,
|
||||||
|
required String scheduleId,
|
||||||
|
}) async {
|
||||||
|
print( ApiEndpoints.deleteSchedule.replaceAll('{deviceUuid}', deviceUuid).replaceAll('{scheduleId}', scheduleId));
|
||||||
|
final response = await _httpService.delete(
|
||||||
|
path: ApiEndpoints.deleteSchedule.replaceAll('{deviceUuid}', deviceUuid).replaceAll('{scheduleId}', scheduleId),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user