mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-11-26 10:44:55 +00:00
@ -2,9 +2,11 @@ import 'dart:async';
|
|||||||
import 'package:dio/dio.dart';
|
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/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/group_one_gang_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/schedule_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
@ -41,6 +43,10 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
on<DeleteScheduleEvent>(deleteSchedule);
|
on<DeleteScheduleEvent>(deleteSchedule);
|
||||||
on<ToggleSelectedEvent>(toggleSelectedIndex);
|
on<ToggleSelectedEvent>(toggleSelectedIndex);
|
||||||
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
||||||
|
on<InitialWizardEvent>(_fetchOneGangWizardStatus);
|
||||||
|
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
|
||||||
|
on<GroupAllOnEvent>(_groupAllOn);
|
||||||
|
on<GroupAllOffEvent>(_groupAllOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchOneGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
|
void _fetchOneGangStatus(InitialEvent event, Emitter<OneGangState> emit) async {
|
||||||
@ -215,7 +221,7 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
add(GetScheduleEvent());
|
add(GetScheduleEvent());
|
||||||
emit(SaveSchedule());
|
emit(SaveSchedule());
|
||||||
|
|
||||||
add(const ToggleCreateScheduleEvent(index:1 ));
|
add(const ToggleCreateScheduleEvent(index: 1));
|
||||||
} else {
|
} else {
|
||||||
CustomSnackBar.displaySnackBar('Please select days');
|
CustomSnackBar.displaySnackBar('Please select days');
|
||||||
}
|
}
|
||||||
@ -290,23 +296,14 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void toggleCreateSchedule() {
|
|
||||||
// emit(LoadingInitialState());
|
|
||||||
// createSchedule = !createSchedule;
|
|
||||||
// selectedDays.clear();
|
|
||||||
// selectedTime = DateTime.now();
|
|
||||||
// emit(UpdateCreateScheduleState(createSchedule));
|
|
||||||
// emit(ChangeSlidingSegmentState(value: 1));
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<OneGangState> emit) {
|
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<OneGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
selectedTime = DateTime.now();
|
selectedTime = DateTime.now();
|
||||||
emit(UpdateCreateScheduleState(createSchedule));
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool toggleSchedule = true;
|
bool toggleSchedule = true;
|
||||||
List<String> selectedDays = [];
|
List<String> selectedDays = [];
|
||||||
@ -324,14 +321,150 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
|
|||||||
selectedDays.add(event.key);
|
selectedDays.add(event.key);
|
||||||
}
|
}
|
||||||
emit(ChangeTimeState());
|
emit(ChangeTimeState());
|
||||||
add(ChangeSlidingSegment(value: 1));
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
void toggleSelectedIndex( ToggleSelectedEvent event, Emitter<OneGangState> emit) {
|
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<OneGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex =event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<GroupOneGangModel> groupOneGangList = [];
|
||||||
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
|
void _fetchOneGangWizardStatus(InitialWizardEvent event, Emitter<OneGangState> emit) async {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
try {
|
||||||
|
devicesList = [];
|
||||||
|
groupOneGangList = [];
|
||||||
|
allSwitchesOn = true;
|
||||||
|
devicesList = await DevicesAPI.getDeviceByGroupName(
|
||||||
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '1G');
|
||||||
|
|
||||||
|
for (int i = 0; i < devicesList.length; i++) {
|
||||||
|
var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||||
|
List<StatusModel> statusModelList = [];
|
||||||
|
for (var status in response['status']) {
|
||||||
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
|
}
|
||||||
|
deviceStatus = OneGangModel.fromJson(statusModelList);
|
||||||
|
groupOneGangList.add(GroupOneGangModel(
|
||||||
|
deviceId: devicesList[i].uuid ?? '',
|
||||||
|
deviceName: devicesList[i].name ?? '',
|
||||||
|
firstSwitch: deviceStatus.firstSwitch,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupOneGangList.isNotEmpty) {
|
||||||
|
groupOneGangList.firstWhere((element) {
|
||||||
|
if (!element.firstSwitch) {
|
||||||
|
allSwitchesOn = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesOn));
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(error: e.toString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _changeFirstWizardSwitch(
|
||||||
|
ChangeFirstWizardSwitchStatusEvent event, Emitter<OneGangState> emit) async {
|
||||||
|
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
bool allSwitchesValue = true;
|
||||||
|
groupOneGangList.forEach((element) {
|
||||||
|
if (element.deviceId == event.deviceId) {
|
||||||
|
element.firstSwitch = !event.value;
|
||||||
|
}
|
||||||
|
if (!element.firstSwitch) {
|
||||||
|
allSwitchesValue = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_1',
|
||||||
|
devicesUuid: [event.deviceId],
|
||||||
|
value: !event.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
add(InitialEvent(groupScreen: oneGangGroup));
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
add(InitialEvent(groupScreen: oneGangGroup));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _groupAllOn(GroupAllOnEvent event, Emitter<OneGangState> emit) async {
|
||||||
|
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
|
||||||
|
for (int i = 0; i < groupOneGangList.length; i++) {
|
||||||
|
groupOneGangList[i].firstSwitch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit the state with updated values
|
||||||
|
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: true));
|
||||||
|
|
||||||
|
// Get a list of all device IDs
|
||||||
|
List<String> allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
|
// First call for switch_1
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_1', // Controls first switch for all devices
|
||||||
|
devicesUuid: allDeviceIds,
|
||||||
|
value: true, // true (on) or false (off) depending on the event value
|
||||||
|
);
|
||||||
|
// Check if either response is unsuccessful, then reset to initial state
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(const InitialEvent(groupScreen: true));
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
// In case of an error, delay and reset the screen to initial state
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(const InitialEvent(groupScreen: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _groupAllOff(GroupAllOffEvent event, Emitter<OneGangState> emit) async {
|
||||||
|
emit(LoadingNewSate(oneGangModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
// Set all switches (firstSwitch and secondSwitch) based on the event value (on/off)
|
||||||
|
for (int i = 0; i < groupOneGangList.length; i++) {
|
||||||
|
groupOneGangList[i].firstSwitch = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit the state with updated values
|
||||||
|
emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: false));
|
||||||
|
|
||||||
|
// Get a list of all device IDs
|
||||||
|
List<String> allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
|
// First call for switch_1
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_1', // Controls first switch for all devices
|
||||||
|
devicesUuid: allDeviceIds,
|
||||||
|
value: false, // true (on) or false (off) depending on the event value
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if either response is unsuccessful, then reset to initial state
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(const InitialEvent(groupScreen: true));
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
// In case of an error, delay and reset the screen to initial state
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(const InitialEvent(groupScreen: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,12 +29,12 @@ class ChangeFirstSwitchStatusEvent extends OneGangEvent {
|
|||||||
class ChangeSecondSwitchStatusEvent extends OneGangEvent {
|
class ChangeSecondSwitchStatusEvent extends OneGangEvent {
|
||||||
final bool value;
|
final bool value;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
const ChangeSecondSwitchStatusEvent({required this.value, this.deviceId = ''});
|
const ChangeSecondSwitchStatusEvent(
|
||||||
|
{required this.value, this.deviceId = ''});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [value, deviceId];
|
List<Object> get props => [value, deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AllOffEvent extends OneGangEvent {}
|
class AllOffEvent extends OneGangEvent {}
|
||||||
|
|
||||||
class AllOnEvent extends OneGangEvent {}
|
class AllOnEvent extends OneGangEvent {}
|
||||||
@ -87,27 +87,29 @@ class StopTimer extends OneGangEvent {}
|
|||||||
|
|
||||||
class OnClose extends OneGangEvent {}
|
class OnClose extends OneGangEvent {}
|
||||||
|
|
||||||
|
class InitialWizardEvent extends OneGangEvent {}
|
||||||
|
|
||||||
|
|
||||||
//------------------- Schedule ----------=---------
|
//------------------- Schedule ----------=---------
|
||||||
class GetScheduleEvent extends OneGangEvent {}
|
class GetScheduleEvent extends OneGangEvent {}
|
||||||
|
|
||||||
class ScheduleSave extends OneGangEvent {}
|
class ScheduleSave extends OneGangEvent {}
|
||||||
|
|
||||||
class ToggleScheduleEvent extends OneGangEvent {
|
class ToggleScheduleEvent extends OneGangEvent {
|
||||||
final String id;
|
final String id;
|
||||||
final bool toggle;
|
final bool toggle;
|
||||||
const ToggleScheduleEvent({required this.toggle,required this.id});
|
const ToggleScheduleEvent({required this.toggle, required this.id});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [toggle,id];
|
List<Object> get props => [toggle, id];
|
||||||
}
|
}
|
||||||
class ToggleDaySelectionEvent extends OneGangEvent {
|
|
||||||
|
|
||||||
|
class ToggleDaySelectionEvent extends OneGangEvent {
|
||||||
final String key;
|
final String key;
|
||||||
|
|
||||||
const ToggleDaySelectionEvent({required this.key});
|
const ToggleDaySelectionEvent({required this.key});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [key];
|
List<Object> get props => [key];
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteScheduleEvent extends OneGangEvent {
|
class DeleteScheduleEvent extends OneGangEvent {
|
||||||
final String id;
|
final String id;
|
||||||
const DeleteScheduleEvent({required this.id});
|
const DeleteScheduleEvent({required this.id});
|
||||||
@ -115,7 +117,6 @@ class DeleteScheduleEvent extends OneGangEvent {
|
|||||||
List<Object> get props => [id];
|
List<Object> get props => [id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ToggleSelectedEvent extends OneGangEvent {
|
class ToggleSelectedEvent extends OneGangEvent {
|
||||||
final int index;
|
final int index;
|
||||||
const ToggleSelectedEvent({required this.index});
|
const ToggleSelectedEvent({required this.index});
|
||||||
@ -123,10 +124,18 @@ class ToggleSelectedEvent extends OneGangEvent {
|
|||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ToggleCreateScheduleEvent extends OneGangEvent {
|
class ToggleCreateScheduleEvent extends OneGangEvent {
|
||||||
final int index;
|
final int index;
|
||||||
const ToggleCreateScheduleEvent({required this.index});
|
const ToggleCreateScheduleEvent({required this.index});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ChangeFirstWizardSwitchStatusEvent extends OneGangEvent {
|
||||||
|
final bool value;
|
||||||
|
final String deviceId;
|
||||||
|
const ChangeFirstWizardSwitchStatusEvent(
|
||||||
|
{required this.value, this.deviceId = ''});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [value, deviceId];
|
||||||
|
}
|
||||||
|
|||||||
@ -25,9 +25,6 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
secondCountDown: 0,
|
secondCountDown: 0,
|
||||||
thirdCountDown: 0);
|
thirdCountDown: 0);
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
// Timer? _firstSwitchTimer;
|
|
||||||
// Timer? _secondSwitchTimer;
|
|
||||||
// Timer? _thirdSwitchTimer;
|
|
||||||
|
|
||||||
bool threeGangGroup = false;
|
bool threeGangGroup = false;
|
||||||
List<DeviceModel> devicesList = [];
|
List<DeviceModel> devicesList = [];
|
||||||
@ -117,7 +114,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeGangId');
|
DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeGangId');
|
||||||
Stream<DatabaseEvent> stream = ref.onValue;
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
stream.listen((DatabaseEvent event) async {
|
stream.listen((DatabaseEvent event) async {
|
||||||
if (_timer != null) {
|
if (_timer != null) {
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
}
|
}
|
||||||
@ -531,7 +528,7 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||||
add(GetScheduleEvent());
|
add(GetScheduleEvent());
|
||||||
emit(ThreeGangSaveSchedule());
|
emit(ThreeGangSaveSchedule());
|
||||||
add(const ToggleCreateScheduleEvent(index:1 ));
|
add(const ToggleCreateScheduleEvent(index: 1));
|
||||||
} else {
|
} else {
|
||||||
CustomSnackBar.displaySnackBar('Please select days');
|
CustomSnackBar.displaySnackBar('Please select days');
|
||||||
}
|
}
|
||||||
@ -606,38 +603,19 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void toggleCreateSchedule() {
|
void toggleSelectedIndex(ToggleSelectedEvent event, Emitter<ThreeGangState> emit) {
|
||||||
// emit(LoadingInitialState());
|
|
||||||
// createSchedule = !createSchedule;
|
|
||||||
// selectedDays.clear();
|
|
||||||
// selectedTime = DateTime.now();
|
|
||||||
// emit(UpdateCreateScheduleState(createSchedule));
|
|
||||||
// emit(ChangeSlidingSegmentState(value: 1));
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// void toggleSelectedIndex(index) {
|
|
||||||
// emit(LoadingInitialState());
|
|
||||||
// selectedTabIndex = index;
|
|
||||||
// emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void toggleSelectedIndex( ToggleSelectedEvent event, Emitter<ThreeGangState> emit) {
|
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
selectedTabIndex =event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
|
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<ThreeGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
selectedTime = DateTime.now();
|
selectedTime = DateTime.now();
|
||||||
emit(UpdateCreateScheduleState(createSchedule));
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
bool toggleSchedule = true;
|
bool toggleSchedule = true;
|
||||||
|
|||||||
@ -135,4 +135,6 @@ class ToggleCreateScheduleEvent extends ThreeGangEvent {
|
|||||||
const ToggleCreateScheduleEvent({required this.index});
|
const ToggleCreateScheduleEvent({required this.index});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InitialWizardDevises extends ThreeGangEvent {}
|
||||||
|
|||||||
@ -57,27 +57,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
on<DeleteScheduleEvent>(deleteSchedule);
|
on<DeleteScheduleEvent>(deleteSchedule);
|
||||||
on<ToggleSelectedEvent>(toggleSelectedIndex);
|
on<ToggleSelectedEvent>(toggleSelectedIndex);
|
||||||
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
||||||
|
on<InitialWizardEvent>(_fetchTwoGangWizardStatus);
|
||||||
|
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
|
||||||
|
on<ChangeSecondWizardSwitchStatusEvent>(_changeSecondWizardSwitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime? selectedTime = DateTime.now();
|
DateTime? selectedTime = DateTime.now();
|
||||||
|
|
||||||
// void toggleCreateSchedule() {
|
|
||||||
// emit(LoadingInitialState());
|
|
||||||
// createSchedule = !createSchedule;
|
|
||||||
// selectedDays.clear();
|
|
||||||
// selectedTime = DateTime.now();
|
|
||||||
// emit(UpdateCreateScheduleState(createSchedule));
|
|
||||||
// emit(ChangeSlidingSegmentState(value: 1));
|
|
||||||
// }
|
|
||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
// void toggleSelectedIndex(index) {
|
|
||||||
// emit(LoadingInitialState());
|
|
||||||
// selectedTabIndex = index;
|
|
||||||
// emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
|
||||||
// }
|
|
||||||
|
|
||||||
void toggleSelectedIndex(
|
void toggleSelectedIndex(
|
||||||
ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
|
ToggleSelectedEvent event, Emitter<TwoGangState> emit) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
@ -98,51 +86,14 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
InitialEvent event, Emitter<TwoGangState> emit) async {
|
InitialEvent event, Emitter<TwoGangState> emit) async {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
try {
|
try {
|
||||||
twoGangGroup = event.groupScreen;
|
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
||||||
if (twoGangGroup) {
|
List<StatusModel> statusModelList = [];
|
||||||
devicesList = [];
|
for (var status in response['status']) {
|
||||||
groupTwoGangList = [];
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
allSwitchesOn = true;
|
|
||||||
devicesList = await DevicesAPI.getDeviceByGroupName(
|
|
||||||
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
|
|
||||||
|
|
||||||
for (int i = 0; i < devicesList.length; i++) {
|
|
||||||
var response =
|
|
||||||
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
|
||||||
List<StatusModel> statusModelList = [];
|
|
||||||
for (var status in response['status']) {
|
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
|
||||||
}
|
|
||||||
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
|
||||||
|
|
||||||
groupTwoGangList.add(GroupTwoGangModel(
|
|
||||||
deviceId: devicesList[i].uuid ?? '',
|
|
||||||
deviceName: devicesList[i].name ?? '',
|
|
||||||
firstSwitch: deviceStatus.firstSwitch,
|
|
||||||
secondSwitch: deviceStatus.secondSwitch,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (groupTwoGangList.isNotEmpty) {
|
|
||||||
groupTwoGangList.firstWhere((element) {
|
|
||||||
if (!element.firstSwitch || !element.secondSwitch) {
|
|
||||||
allSwitchesOn = false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
emit(UpdateGroupState(
|
|
||||||
twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
|
|
||||||
} else {
|
|
||||||
var response = await DevicesAPI.getDeviceStatus(twoGangId);
|
|
||||||
List<StatusModel> statusModelList = [];
|
|
||||||
for (var status in response['status']) {
|
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
|
||||||
}
|
|
||||||
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
|
||||||
emit(UpdateState(twoGangModel: deviceStatus));
|
|
||||||
_listenToChanges();
|
|
||||||
}
|
}
|
||||||
|
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
||||||
|
emit(UpdateState(twoGangModel: deviceStatus));
|
||||||
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(FailedState(error: e.toString()));
|
emit(FailedState(error: e.toString()));
|
||||||
return;
|
return;
|
||||||
@ -193,17 +144,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoGangGroup ? event.deviceId : twoGangId,
|
deviceId: twoGangId, code: 'switch_1', value: !event.value),
|
||||||
code: 'switch_1',
|
twoGangId);
|
||||||
value: !event.value),
|
|
||||||
twoGangGroup ? event.deviceId : twoGangId);
|
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
add(InitialEvent(groupScreen: twoGangGroup));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
add(InitialEvent(groupScreen: twoGangGroup));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,17 +168,15 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: twoGangGroup ? event.deviceId : twoGangId,
|
deviceId: twoGangId, code: 'switch_2', value: !event.value),
|
||||||
code: 'switch_2',
|
twoGangId);
|
||||||
value: !event.value),
|
|
||||||
twoGangGroup ? event.deviceId : twoGangId);
|
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
add(InitialEvent(groupScreen: twoGangGroup));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
add(InitialEvent(groupScreen: twoGangGroup));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,11 +205,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
|
|
||||||
if (response.every((element) => !element['success'])) {
|
if (response.every((element) => !element['success'])) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
add(const InitialEvent(groupScreen: false));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
add(const InitialEvent(groupScreen: false));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,11 +235,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
]);
|
]);
|
||||||
if (response.every((element) => !element['success'])) {
|
if (response.every((element) => !element['success'])) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
add(const InitialEvent(groupScreen: false));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
add(const InitialEvent(groupScreen: false));
|
add(const InitialEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,32 +251,29 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
groupTwoGangList[i].secondSwitch = true;
|
groupTwoGangList[i].secondSwitch = true;
|
||||||
}
|
}
|
||||||
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: true));
|
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: true));
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupTwoGangList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
for (int i = 0; i < groupTwoGangList.length; i++) {
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
final response = await Future.wait([
|
code: 'switch_1',
|
||||||
DevicesAPI.controlDevice(
|
devicesUuid: allDeviceIds,
|
||||||
DeviceControlModel(
|
value: true,
|
||||||
deviceId: groupTwoGangList[i].deviceId,
|
);
|
||||||
code: 'switch_1',
|
|
||||||
value: true),
|
|
||||||
groupTwoGangList[i].deviceId),
|
|
||||||
DevicesAPI.controlDevice(
|
|
||||||
DeviceControlModel(
|
|
||||||
deviceId: groupTwoGangList[i].deviceId,
|
|
||||||
code: 'switch_2',
|
|
||||||
value: true),
|
|
||||||
groupTwoGangList[i].deviceId),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (response.every((element) => !element['success'])) {
|
final response2 = await DevicesAPI.deviceBatchController(
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
code: 'switch_2',
|
||||||
add(const InitialEvent(groupScreen: true));
|
devicesUuid: allDeviceIds,
|
||||||
break;
|
value: true,
|
||||||
}
|
);
|
||||||
|
|
||||||
|
if (response1['failedResults'].toString() != '[]' ||
|
||||||
|
response2['failedResults'].toString() != '[]') {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(InitialWizardEvent());
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
add(const InitialEvent(groupScreen: true));
|
add(InitialWizardEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,33 +284,32 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
groupTwoGangList[i].firstSwitch = false;
|
groupTwoGangList[i].firstSwitch = false;
|
||||||
groupTwoGangList[i].secondSwitch = false;
|
groupTwoGangList[i].secondSwitch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: false));
|
emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: false));
|
||||||
|
|
||||||
for (int i = 0; i < groupTwoGangList.length; i++) {
|
List<String> allDeviceIds =
|
||||||
final response = await Future.wait([
|
groupTwoGangList.map((device) => device.deviceId).toList();
|
||||||
DevicesAPI.controlDevice(
|
|
||||||
DeviceControlModel(
|
|
||||||
deviceId: groupTwoGangList[i].deviceId,
|
|
||||||
code: 'switch_1',
|
|
||||||
value: false),
|
|
||||||
groupTwoGangList[i].deviceId),
|
|
||||||
DevicesAPI.controlDevice(
|
|
||||||
DeviceControlModel(
|
|
||||||
deviceId: groupTwoGangList[i].deviceId,
|
|
||||||
code: 'switch_2',
|
|
||||||
value: false),
|
|
||||||
groupTwoGangList[i].deviceId),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (response.every((element) => !element['success'])) {
|
final response1 = await DevicesAPI.deviceBatchController(
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
code: 'switch_1',
|
||||||
add(const InitialEvent(groupScreen: true));
|
devicesUuid: allDeviceIds,
|
||||||
break;
|
value: false,
|
||||||
}
|
);
|
||||||
|
|
||||||
|
final response2 = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_2',
|
||||||
|
devicesUuid: allDeviceIds,
|
||||||
|
value: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response1['failedResults'].toString() != '[]' ||
|
||||||
|
response2['failedResults'].toString() != '[]') {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(InitialWizardEvent());
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
add(const InitialEvent(groupScreen: true));
|
add(InitialWizardEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +419,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
selectedDays.add(event.key);
|
selectedDays.add(event.key);
|
||||||
}
|
}
|
||||||
emit(ChangeTimeState());
|
emit(ChangeTimeState());
|
||||||
add(ChangeSlidingSegment(value: 1));
|
add(const ChangeSlidingSegment(value: 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveSchedule(
|
Future<void> saveSchedule(
|
||||||
@ -486,7 +429,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
try {
|
try {
|
||||||
if (selectedDays.isNotEmpty) {
|
if (selectedDays.isNotEmpty) {
|
||||||
emit(LoadingInitialState());
|
emit(LoadingInitialState());
|
||||||
final response = await DevicesAPI.postSchedule(
|
await DevicesAPI.postSchedule(
|
||||||
category: switchCode,
|
category: switchCode,
|
||||||
deviceId: twoGangId,
|
deviceId: twoGangId,
|
||||||
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||||
@ -574,4 +517,113 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
|
|||||||
emit(FailedState(error: errorMessage.toString()));
|
emit(FailedState(error: errorMessage.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _fetchTwoGangWizardStatus(
|
||||||
|
InitialWizardEvent event, Emitter<TwoGangState> emit) async {
|
||||||
|
emit(LoadingInitialState());
|
||||||
|
try {
|
||||||
|
devicesList = [];
|
||||||
|
groupTwoGangList = [];
|
||||||
|
allSwitchesOn = true;
|
||||||
|
devicesList = await DevicesAPI.getDeviceByGroupName(
|
||||||
|
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
|
||||||
|
|
||||||
|
for (int i = 0; i < devicesList.length; i++) {
|
||||||
|
var response =
|
||||||
|
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||||
|
List<StatusModel> statusModelList = [];
|
||||||
|
for (var status in response['status']) {
|
||||||
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
|
}
|
||||||
|
deviceStatus = TwoGangModel.fromJson(statusModelList);
|
||||||
|
|
||||||
|
groupTwoGangList.add(GroupTwoGangModel(
|
||||||
|
deviceId: devicesList[i].uuid ?? '',
|
||||||
|
deviceName: devicesList[i].name ?? '',
|
||||||
|
firstSwitch: deviceStatus.firstSwitch,
|
||||||
|
secondSwitch: deviceStatus.secondSwitch,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupTwoGangList.isNotEmpty) {
|
||||||
|
groupTwoGangList.firstWhere((element) {
|
||||||
|
if (!element.firstSwitch || !element.secondSwitch) {
|
||||||
|
allSwitchesOn = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
|
||||||
|
} catch (e) {
|
||||||
|
emit(FailedState(error: e.toString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
|
Emitter<TwoGangState> emit) async {
|
||||||
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
bool allSwitchesValue = true;
|
||||||
|
groupTwoGangList.forEach((element) {
|
||||||
|
if (element.deviceId == event.deviceId) {
|
||||||
|
element.firstSwitch = !event.value;
|
||||||
|
}
|
||||||
|
if (!element.firstSwitch || !element.secondSwitch) {
|
||||||
|
allSwitchesValue = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupTwoGangList.map((device) => device.deviceId).toList();
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_1',
|
||||||
|
devicesUuid: allDeviceIds,
|
||||||
|
value: !event.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _changeSecondWizardSwitch(ChangeSecondWizardSwitchStatusEvent event,
|
||||||
|
Emitter<TwoGangState> emit) async {
|
||||||
|
emit(LoadingNewSate(twoGangModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
bool allSwitchesValue = true;
|
||||||
|
groupTwoGangList.forEach((element) {
|
||||||
|
if (element.deviceId == event.deviceId) {
|
||||||
|
element.secondSwitch = !event.value;
|
||||||
|
}
|
||||||
|
if (!element.firstSwitch || !element.secondSwitch) {
|
||||||
|
allSwitchesValue = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupTwoGangList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupTwoGangList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_2',
|
||||||
|
devicesUuid: allDeviceIds,
|
||||||
|
value: !event.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,17 +10,20 @@ 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 TwoGangSave extends TwoGangEvent {}
|
||||||
|
|
||||||
class ToggleScheduleEvent extends TwoGangEvent {
|
class ToggleScheduleEvent extends TwoGangEvent {
|
||||||
final String id;
|
final String id;
|
||||||
final bool toggle;
|
final bool toggle;
|
||||||
const ToggleScheduleEvent({required this.toggle,required this.id});
|
const ToggleScheduleEvent({required this.toggle, required this.id});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [toggle,id];
|
List<Object> get props => [toggle, id];
|
||||||
}
|
}
|
||||||
class errorMessage extends TwoGangEvent {}
|
|
||||||
class ToggleDaySelectionEvent extends TwoGangEvent {
|
|
||||||
|
|
||||||
|
class errorMessage extends TwoGangEvent {}
|
||||||
|
|
||||||
|
class ToggleDaySelectionEvent extends TwoGangEvent {
|
||||||
final String key;
|
final String key;
|
||||||
|
|
||||||
const ToggleDaySelectionEvent({required this.key});
|
const ToggleDaySelectionEvent({required this.key});
|
||||||
@ -29,10 +32,9 @@ class ToggleDaySelectionEvent extends TwoGangEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InitialEvent extends TwoGangEvent {
|
class InitialEvent extends TwoGangEvent {
|
||||||
final bool groupScreen;
|
const InitialEvent();
|
||||||
const InitialEvent({required this.groupScreen});
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [groupScreen];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChangeFirstSwitchStatusEvent extends TwoGangEvent {
|
class ChangeFirstSwitchStatusEvent extends TwoGangEvent {
|
||||||
@ -51,7 +53,6 @@ class ChangeSecondSwitchStatusEvent extends TwoGangEvent {
|
|||||||
List<Object> get props => [value, deviceId];
|
List<Object> get props => [value, deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AllOffEvent extends TwoGangEvent {}
|
class AllOffEvent extends TwoGangEvent {}
|
||||||
|
|
||||||
class AllOnEvent extends TwoGangEvent {}
|
class AllOnEvent extends TwoGangEvent {}
|
||||||
@ -60,13 +61,9 @@ class GroupAllOnEvent extends TwoGangEvent {}
|
|||||||
|
|
||||||
class GroupAllOffEvent extends TwoGangEvent {}
|
class GroupAllOffEvent extends TwoGangEvent {}
|
||||||
|
|
||||||
|
|
||||||
// two_gang_event.dart
|
// two_gang_event.dart
|
||||||
// class ToggleCreateScheduleEvent extends TwoGangEvent {}
|
// class ToggleCreateScheduleEvent extends TwoGangEvent {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ChangeSlidingSegment extends TwoGangEvent {
|
class ChangeSlidingSegment extends TwoGangEvent {
|
||||||
final int value;
|
final int value;
|
||||||
const ChangeSlidingSegment({required this.value});
|
const ChangeSlidingSegment({required this.value});
|
||||||
@ -111,20 +108,20 @@ class StopTimer extends TwoGangEvent {}
|
|||||||
|
|
||||||
class OnClose extends TwoGangEvent {}
|
class OnClose extends TwoGangEvent {}
|
||||||
|
|
||||||
|
|
||||||
class GetScheduleEvent extends TwoGangEvent {}
|
class GetScheduleEvent extends TwoGangEvent {}
|
||||||
|
|
||||||
class DeleteScheduleEvent extends TwoGangEvent {
|
class DeleteScheduleEvent extends TwoGangEvent {
|
||||||
final String id;
|
final String id;
|
||||||
const DeleteScheduleEvent({required this.id});
|
const DeleteScheduleEvent({required this.id});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [id];
|
List<Object> get props => [id];
|
||||||
}
|
}
|
||||||
|
|
||||||
class TabChangedEvent extends TwoGangEvent {
|
class TabChangedEvent extends TwoGangEvent {
|
||||||
final int index;
|
final int index;
|
||||||
TabChangedEvent({required this.index});
|
TabChangedEvent({required this.index});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ToggleSelectedEvent extends TwoGangEvent {
|
class ToggleSelectedEvent extends TwoGangEvent {
|
||||||
final int index;
|
final int index;
|
||||||
const ToggleSelectedEvent({required this.index});
|
const ToggleSelectedEvent({required this.index});
|
||||||
@ -132,7 +129,6 @@ class ToggleSelectedEvent extends TwoGangEvent {
|
|||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ToggleCreateScheduleEvent extends TwoGangEvent {
|
class ToggleCreateScheduleEvent extends TwoGangEvent {
|
||||||
final int index;
|
final int index;
|
||||||
const ToggleCreateScheduleEvent({required this.index});
|
const ToggleCreateScheduleEvent({required this.index});
|
||||||
@ -140,5 +136,20 @@ class ToggleCreateScheduleEvent extends TwoGangEvent {
|
|||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InitialWizardEvent extends TwoGangEvent {}
|
||||||
|
|
||||||
|
class ChangeFirstWizardSwitchStatusEvent extends TwoGangEvent {
|
||||||
|
final bool value;
|
||||||
|
final String deviceId;
|
||||||
|
const ChangeFirstWizardSwitchStatusEvent({required this.value, this.deviceId = ''});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [value, deviceId];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangeSecondWizardSwitchStatusEvent extends TwoGangEvent {
|
||||||
|
final bool value;
|
||||||
|
final String deviceId;
|
||||||
|
const ChangeSecondWizardSwitchStatusEvent({required this.value, this.deviceId = ''});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [value, deviceId];
|
||||||
|
}
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:firebase_database/firebase_database.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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/devices/bloc/water_heater_bloc/water_heater_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/GroupWHModel.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/schedule_model.dart';
|
import 'package:syncrow_app/features/devices/model/schedule_model.dart';
|
||||||
@ -16,9 +19,7 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
|||||||
class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
||||||
final String whId;
|
final String whId;
|
||||||
final String switchCode;
|
final String switchCode;
|
||||||
WHModel deviceStatus = WHModel(
|
WHModel deviceStatus = WHModel(firstSwitch: false, firstCountDown: 0);
|
||||||
firstSwitch: false,firstCountDown: 0
|
|
||||||
);
|
|
||||||
List<WHModel> deviceStatusList = [];
|
List<WHModel> deviceStatusList = [];
|
||||||
List<DeviceModel> devicesList = [];
|
List<DeviceModel> devicesList = [];
|
||||||
bool allAcsPage = false;
|
bool allAcsPage = false;
|
||||||
@ -27,15 +28,15 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
int globalTemp = 25;
|
int globalTemp = 25;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
|
|
||||||
bool toggleSchedule = true;
|
bool toggleSchedule = true;
|
||||||
List<String> selectedDays = [];
|
List<String> selectedDays = [];
|
||||||
bool createSchedule = false;
|
bool createSchedule = false;
|
||||||
bool createCirculate = false;
|
bool createCirculate = false;
|
||||||
List<ScheduleModel> listSchedule = [];
|
List<ScheduleModel> listSchedule = [];
|
||||||
DateTime? selectedTime=DateTime.now();
|
DateTime? selectedTime = DateTime.now();
|
||||||
|
|
||||||
WaterHeaterBloc({required this.whId,required this.switchCode}) : super(WHInitialState()) {
|
WaterHeaterBloc({required this.whId, required this.switchCode})
|
||||||
|
: super(WHInitialState()) {
|
||||||
on<WaterHeaterInitial>(_fetchWaterHeaterStatus);
|
on<WaterHeaterInitial>(_fetchWaterHeaterStatus);
|
||||||
on<WaterHeaterSwitch>(_changeFirstSwitch);
|
on<WaterHeaterSwitch>(_changeFirstSwitch);
|
||||||
on<SetCounterValue>(_setCounterValue);
|
on<SetCounterValue>(_setCounterValue);
|
||||||
@ -49,11 +50,19 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
on<OnClose>(_onClose);
|
on<OnClose>(_onClose);
|
||||||
on<SelectTimeEvent>(showTime);
|
on<SelectTimeEvent>(showTime);
|
||||||
|
|
||||||
on<ToggleSelectedEvent>(toggleSelectedIndex);
|
on<ToggleSelectedEvent>(toggleSelectedIndex);
|
||||||
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
on<ToggleCreateScheduleEvent>(toggleCreateSchedule);
|
||||||
|
on<InitialWizardEvent>(_fetchWHWizardStatus);
|
||||||
|
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
|
||||||
|
|
||||||
|
on<GroupAllOnEvent>(_groupAllOn);
|
||||||
|
on<GroupAllOffEvent>(_groupAllOff);
|
||||||
|
on<ToggleCreateCirculate>(_toggleCreateCirculate);
|
||||||
|
on<WaterHeaterUpdated>(_waterHeaterUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchWaterHeaterStatus(WaterHeaterInitial event, Emitter<WaterHeaterState> emit) async {
|
void _fetchWaterHeaterStatus(
|
||||||
|
WaterHeaterInitial event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(whId);
|
var response = await DevicesAPI.getDeviceStatus(whId);
|
||||||
@ -61,18 +70,52 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
for (var status in response['status']) {
|
for (var status in response['status']) {
|
||||||
statusModelList.add(StatusModel.fromJson(status));
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
}
|
}
|
||||||
deviceStatus = WHModel.fromJson(statusModelList, );
|
deviceStatus = WHModel.fromJson(
|
||||||
|
statusModelList,
|
||||||
|
);
|
||||||
emit(UpdateState(whModel: deviceStatus));
|
emit(UpdateState(whModel: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
_listenToChanges();
|
||||||
// _listenToChanges();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(WHFailedState(errorMessage: e.toString()));
|
emit(WHFailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_listenToChanges() {
|
||||||
|
try {
|
||||||
|
DatabaseReference ref =
|
||||||
|
FirebaseDatabase.instance.ref('device-status/$whId');
|
||||||
|
Stream<DatabaseEvent> stream = ref.onValue;
|
||||||
|
|
||||||
void _changeFirstSwitch(WaterHeaterSwitch event, Emitter<WaterHeaterState> emit) async {
|
stream.listen((DatabaseEvent event) async {
|
||||||
|
if (_timer != null) {
|
||||||
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
|
}
|
||||||
|
Map<dynamic, dynamic> usersMap =
|
||||||
|
event.snapshot.value as Map<dynamic, dynamic>;
|
||||||
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
|
usersMap['status'].forEach((element) {
|
||||||
|
statusList
|
||||||
|
.add(StatusModel(code: element['code'], value: element['value']));
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceStatus = WHModel.fromJson(statusList);
|
||||||
|
if (!isClosed) {
|
||||||
|
add(WaterHeaterUpdated());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
_waterHeaterUpdated(
|
||||||
|
WaterHeaterUpdated event, Emitter<WaterHeaterState> emit) async {
|
||||||
|
emit(WHLoadingState());
|
||||||
|
emit(UpdateState(whModel: deviceStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _changeFirstSwitch(
|
||||||
|
WaterHeaterSwitch event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(LoadingNewSate(whModel: deviceStatus));
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
try {
|
try {
|
||||||
deviceStatus.firstSwitch = !event.whSwitch;
|
deviceStatus.firstSwitch = !event.whSwitch;
|
||||||
@ -83,13 +126,13 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
_timer = Timer(const Duration(milliseconds: 500), () async {
|
_timer = Timer(const Duration(milliseconds: 500), () async {
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(
|
DeviceControlModel(
|
||||||
deviceId: whId,
|
deviceId: whId,
|
||||||
code: 'switch_1',
|
code: 'switch_1',
|
||||||
value: deviceStatus.firstSwitch ),
|
value: deviceStatus.firstSwitch),
|
||||||
whId);
|
whId);
|
||||||
|
|
||||||
if (!response['success']) {
|
if (!response['success']) {
|
||||||
// add(InitialEvent(groupScreen: oneGangGroup));
|
// add(InitialEvent(groupScreen: oneGangGroup));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
@ -97,19 +140,17 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=====================---------- timer ----------------------------------------
|
//=====================---------- timer ----------------------------------------
|
||||||
|
|
||||||
void _setCounterValue(SetCounterValue event, Emitter<WaterHeaterState> emit) async {
|
void _setCounterValue(
|
||||||
|
SetCounterValue event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(LoadingNewSate(whModel: deviceStatus));
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
int seconds = 0;
|
int seconds = 0;
|
||||||
try {
|
try {
|
||||||
seconds = event.duration.inSeconds;
|
seconds = event.duration.inSeconds;
|
||||||
final response = await DevicesAPI.controlDevice(
|
final response = await DevicesAPI.controlDevice(
|
||||||
DeviceControlModel(deviceId: whId, code: event.deviceCode, value: seconds),
|
DeviceControlModel(
|
||||||
|
deviceId: whId, code: event.deviceCode, value: seconds),
|
||||||
whId);
|
whId);
|
||||||
|
|
||||||
if (response['success'] ?? false) {
|
if (response['success'] ?? false) {
|
||||||
@ -132,7 +173,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getCounterValue(GetCounterEvent event, Emitter<WaterHeaterState> emit) async {
|
void _getCounterValue(
|
||||||
|
GetCounterEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getDeviceStatus(whId);
|
var response = await DevicesAPI.getDeviceStatus(whId);
|
||||||
@ -148,7 +190,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
|
: emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
WHFailedState(errorMessage: e.toString());
|
WHFailedState(errorMessage: e.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,13 +215,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=====================---------- Schedule ----------------------------------------
|
//=====================---------- Schedule ----------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Map<String, String>> days = [
|
List<Map<String, String>> days = [
|
||||||
{"day": "Sun", "key": "Sun"},
|
{"day": "Sun", "key": "Sun"},
|
||||||
{"day": "Mon", "key": "Mon"},
|
{"day": "Mon", "key": "Mon"},
|
||||||
@ -190,11 +227,14 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
{"day": "Sat", "key": "Sat"},
|
{"day": "Sat", "key": "Sat"},
|
||||||
];
|
];
|
||||||
|
|
||||||
Future<void> saveSchedule(ScheduleSave event, Emitter<WaterHeaterState> emit,) async {
|
Future<void> saveSchedule(
|
||||||
|
ScheduleSave event,
|
||||||
|
Emitter<WaterHeaterState> emit,
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
if(selectedDays.isNotEmpty) {
|
if (selectedDays.isNotEmpty) {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
final response = await DevicesAPI.postSchedule(
|
await DevicesAPI.postSchedule(
|
||||||
category: switchCode,
|
category: switchCode,
|
||||||
deviceId: whId,
|
deviceId: whId,
|
||||||
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
time: getTimeStampWithoutSeconds(selectedTime).toString(),
|
||||||
@ -204,24 +244,28 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||||
add(GetScheduleEvent());
|
add(GetScheduleEvent());
|
||||||
emit(SaveSchedule());
|
emit(SaveSchedule());
|
||||||
add(const ToggleCreateScheduleEvent(index:1 ));
|
add(const ToggleCreateScheduleEvent(index: 1));
|
||||||
}else{
|
} else {
|
||||||
CustomSnackBar.displaySnackBar('Please select days');
|
CustomSnackBar.displaySnackBar('Please select days');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(WHFailedState(errorMessage:e.toString()));
|
emit(WHFailedState(errorMessage: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getSchedule(GetScheduleEvent event, Emitter<WaterHeaterState> emit,) async {
|
Future<void> getSchedule(
|
||||||
|
GetScheduleEvent event,
|
||||||
|
Emitter<WaterHeaterState> emit,
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
final response = await DevicesAPI.getSchedule(
|
final response = await DevicesAPI.getSchedule(
|
||||||
category: switchCode,
|
category: switchCode,
|
||||||
deviceId: whId ,
|
deviceId: whId,
|
||||||
);
|
);
|
||||||
List<dynamic> jsonData = response;
|
List<dynamic> jsonData = response;
|
||||||
listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
listSchedule =
|
||||||
|
jsonData.map((item) => ScheduleModel.fromJson(item)).toList();
|
||||||
emit(WHInitialState());
|
emit(WHInitialState());
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
@ -252,7 +296,7 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
final errorData = e.response!.data;
|
final errorData = e.response!.data;
|
||||||
String errorMessage = errorData['message'];
|
String errorMessage = errorData['message'];
|
||||||
emit(WHFailedState(errorMessage: errorMessage.toString()));
|
emit(WHFailedState(errorMessage: errorMessage.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +306,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
final response = await DevicesAPI.deleteSchedule(
|
final response = await DevicesAPI.deleteSchedule(
|
||||||
scheduleId: event.id,
|
scheduleId: event.id,
|
||||||
deviceUuid: whId, );
|
deviceUuid: whId,
|
||||||
|
);
|
||||||
if (response == true) {
|
if (response == true) {
|
||||||
add(GetScheduleEvent());
|
add(GetScheduleEvent());
|
||||||
return toggleSchedule;
|
return toggleSchedule;
|
||||||
@ -275,47 +320,35 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void toggleCreateSchedule() {
|
void _toggleCreateCirculate(
|
||||||
// emit(WHLoadingState());
|
ToggleCreateCirculate event, Emitter<WaterHeaterState> emit) {
|
||||||
// createSchedule = !createSchedule;
|
emit(WHLoadingState());
|
||||||
// selectedDays.clear();
|
|
||||||
// selectedTime=DateTime.now();
|
|
||||||
// emit(UpdateCreateScheduleState(createSchedule));
|
|
||||||
// }
|
|
||||||
|
|
||||||
void toggleCreateCirculate() {
|
|
||||||
emit(WHLoadingState());
|
|
||||||
createCirculate = !createCirculate;
|
createCirculate = !createCirculate;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
selectedTime=DateTime.now();
|
selectedTime = DateTime.now();
|
||||||
emit(UpdateCreateScheduleState(createCirculate));
|
emit(UpdateCreateScheduleState(createCirculate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggleSelectedIndex(
|
||||||
// void toggleSelectedIndex(index) {
|
ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
|
||||||
// emit(WHLoadingState());
|
|
||||||
// selectedTabIndex = index;
|
|
||||||
// emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
|
||||||
// }
|
|
||||||
void toggleSelectedIndex( ToggleSelectedEvent event, Emitter<WaterHeaterState> emit) {
|
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
selectedTabIndex =event.index;
|
selectedTabIndex = event.index;
|
||||||
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
emit(ChangeSlidingSegmentState(value: selectedTabIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggleCreateSchedule(
|
||||||
void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
|
ToggleCreateScheduleEvent event, Emitter<WaterHeaterState> emit) {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
createSchedule = !createSchedule;
|
createSchedule = !createSchedule;
|
||||||
selectedDays.clear();
|
selectedDays.clear();
|
||||||
selectedTime = DateTime.now();
|
selectedTime = DateTime.now();
|
||||||
emit(UpdateCreateScheduleState(createSchedule));
|
emit(UpdateCreateScheduleState(createSchedule));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> toggleDaySelection(
|
Future<void> toggleDaySelection(
|
||||||
ToggleDaySelectionEvent event,
|
ToggleDaySelectionEvent event,
|
||||||
Emitter<WaterHeaterState> emit,
|
Emitter<WaterHeaterState> emit,
|
||||||
) async {
|
) async {
|
||||||
emit(WHLoadingState());
|
emit(WHLoadingState());
|
||||||
if (selectedDays.contains(event.key)) {
|
if (selectedDays.contains(event.key)) {
|
||||||
selectedDays.remove(event.key);
|
selectedDays.remove(event.key);
|
||||||
@ -327,9 +360,8 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
|
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
|
|
||||||
showTime(SelectTimeEvent event, Emitter<WaterHeaterState> emit) async {
|
showTime(SelectTimeEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
final TimeOfDay? timePicked = await showTimePicker(
|
await showTimePicker(
|
||||||
context: event.context,
|
context: event.context,
|
||||||
initialTime: TimeOfDay.now(),
|
initialTime: TimeOfDay.now(),
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
@ -350,4 +382,137 @@ class WaterHeaterBloc extends Bloc<WaterHeaterEvent, WaterHeaterState> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<GroupWHModel> groupWaterHeaterList = [];
|
||||||
|
bool allSwitchesOn = true;
|
||||||
|
|
||||||
|
void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event,
|
||||||
|
Emitter<WaterHeaterState> emit) async {
|
||||||
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
bool allSwitchesValue = true;
|
||||||
|
groupWaterHeaterList.forEach((element) {
|
||||||
|
if (element.deviceId == event.deviceId) {
|
||||||
|
element.firstSwitch = !event.value;
|
||||||
|
}
|
||||||
|
if (!element.firstSwitch) {
|
||||||
|
allSwitchesValue = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue));
|
||||||
|
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_1',
|
||||||
|
devicesUuid: [event.deviceId],
|
||||||
|
value: !event.value,
|
||||||
|
);
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _fetchWHWizardStatus(
|
||||||
|
InitialWizardEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
|
emit(WHLoadingState());
|
||||||
|
try {
|
||||||
|
devicesList = [];
|
||||||
|
groupWaterHeaterList = [];
|
||||||
|
allSwitchesOn = true;
|
||||||
|
devicesList = await DevicesAPI.getDeviceByGroupName(
|
||||||
|
HomeCubit.getInstance().selectedSpace?.id ?? '', 'WH');
|
||||||
|
|
||||||
|
for (int i = 0; i < devicesList.length; i++) {
|
||||||
|
var response =
|
||||||
|
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
|
||||||
|
List<StatusModel> statusModelList = [];
|
||||||
|
for (var status in response['status']) {
|
||||||
|
statusModelList.add(StatusModel.fromJson(status));
|
||||||
|
}
|
||||||
|
deviceStatus = WHModel.fromJson(statusModelList);
|
||||||
|
|
||||||
|
groupWaterHeaterList.add(GroupWHModel(
|
||||||
|
deviceId: devicesList[i].uuid ?? '',
|
||||||
|
deviceName: devicesList[i].name ?? '',
|
||||||
|
firstSwitch: deviceStatus.firstSwitch,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupWaterHeaterList.isNotEmpty) {
|
||||||
|
groupWaterHeaterList.firstWhere((element) {
|
||||||
|
if (!element.firstSwitch) {
|
||||||
|
allSwitchesOn = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn));
|
||||||
|
} catch (e) {
|
||||||
|
// emit(FailedState(error: e.toString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _groupAllOn(
|
||||||
|
GroupAllOnEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < groupWaterHeaterList.length; i++) {
|
||||||
|
groupWaterHeaterList[i].firstSwitch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupWaterHeaterList, allSwitches: true));
|
||||||
|
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupWaterHeaterList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_1',
|
||||||
|
devicesUuid: allDeviceIds,
|
||||||
|
value: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _groupAllOff(
|
||||||
|
GroupAllOffEvent event, Emitter<WaterHeaterState> emit) async {
|
||||||
|
emit(LoadingNewSate(whModel: deviceStatus));
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < groupWaterHeaterList.length; i++) {
|
||||||
|
groupWaterHeaterList[i].firstSwitch = false;
|
||||||
|
}
|
||||||
|
emit(UpdateGroupState(
|
||||||
|
twoGangList: groupWaterHeaterList, allSwitches: false));
|
||||||
|
|
||||||
|
List<String> allDeviceIds =
|
||||||
|
groupWaterHeaterList.map((device) => device.deviceId).toList();
|
||||||
|
|
||||||
|
final response = await DevicesAPI.deviceBatchController(
|
||||||
|
code: 'switch_1',
|
||||||
|
devicesUuid: allDeviceIds,
|
||||||
|
value: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response['failedResults'].toString() != '[]') {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
add(InitialWizardEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,6 @@ class WaterHeaterInitial extends WaterHeaterEvent {
|
|||||||
|
|
||||||
class WaterHeaterChangeStatus extends WaterHeaterEvent {}
|
class WaterHeaterChangeStatus extends WaterHeaterEvent {}
|
||||||
|
|
||||||
|
|
||||||
class GetCounterEvent extends WaterHeaterEvent {
|
class GetCounterEvent extends WaterHeaterEvent {
|
||||||
final String deviceCode;
|
final String deviceCode;
|
||||||
const GetCounterEvent({required this.deviceCode});
|
const GetCounterEvent({required this.deviceCode});
|
||||||
@ -66,25 +65,27 @@ class StopTimer extends WaterHeaterEvent {}
|
|||||||
|
|
||||||
class OnClose extends WaterHeaterEvent {}
|
class OnClose extends WaterHeaterEvent {}
|
||||||
|
|
||||||
|
|
||||||
//------------------- Schedule ----------=---------
|
//------------------- Schedule ----------=---------
|
||||||
class GetScheduleEvent extends WaterHeaterEvent {}
|
class GetScheduleEvent extends WaterHeaterEvent {}
|
||||||
|
|
||||||
class ScheduleSave extends WaterHeaterEvent {}
|
class ScheduleSave extends WaterHeaterEvent {}
|
||||||
|
|
||||||
class ToggleScheduleEvent extends WaterHeaterEvent {
|
class ToggleScheduleEvent extends WaterHeaterEvent {
|
||||||
final String id;
|
final String id;
|
||||||
final bool toggle;
|
final bool toggle;
|
||||||
const ToggleScheduleEvent({required this.toggle,required this.id});
|
const ToggleScheduleEvent({required this.toggle, required this.id});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [toggle,id];
|
List<Object> get props => [toggle, id];
|
||||||
}
|
}
|
||||||
class ToggleDaySelectionEvent extends WaterHeaterEvent {
|
|
||||||
|
|
||||||
|
class ToggleDaySelectionEvent extends WaterHeaterEvent {
|
||||||
final String key;
|
final String key;
|
||||||
|
|
||||||
const ToggleDaySelectionEvent({required this.key});
|
const ToggleDaySelectionEvent({required this.key});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [key];
|
List<Object> get props => [key];
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteScheduleEvent extends WaterHeaterEvent {
|
class DeleteScheduleEvent extends WaterHeaterEvent {
|
||||||
final String id;
|
final String id;
|
||||||
const DeleteScheduleEvent({required this.id});
|
const DeleteScheduleEvent({required this.id});
|
||||||
@ -100,7 +101,6 @@ class SelectTimeEvent extends WaterHeaterEvent {
|
|||||||
List<Object> get props => [context, isEffective];
|
List<Object> get props => [context, isEffective];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ToggleSelectedEvent extends WaterHeaterEvent {
|
class ToggleSelectedEvent extends WaterHeaterEvent {
|
||||||
final int index;
|
final int index;
|
||||||
const ToggleSelectedEvent({required this.index});
|
const ToggleSelectedEvent({required this.index});
|
||||||
@ -108,7 +108,6 @@ class ToggleSelectedEvent extends WaterHeaterEvent {
|
|||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ToggleCreateScheduleEvent extends WaterHeaterEvent {
|
class ToggleCreateScheduleEvent extends WaterHeaterEvent {
|
||||||
final int index;
|
final int index;
|
||||||
const ToggleCreateScheduleEvent({required this.index});
|
const ToggleCreateScheduleEvent({required this.index});
|
||||||
@ -116,10 +115,25 @@ class ToggleCreateScheduleEvent extends WaterHeaterEvent {
|
|||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ToggleCreateCirculateEvent extends WaterHeaterEvent {
|
||||||
class ToggleCreateCirculateEvent extends WaterHeaterEvent {
|
|
||||||
final int index;
|
final int index;
|
||||||
const ToggleCreateCirculateEvent({required this.index});
|
const ToggleCreateCirculateEvent({required this.index});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [index];
|
List<Object> get props => [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InitialWizardEvent extends WaterHeaterEvent {}
|
||||||
|
|
||||||
|
class ChangeFirstWizardSwitchStatusEvent extends WaterHeaterEvent {
|
||||||
|
final bool value;
|
||||||
|
final String deviceId;
|
||||||
|
const ChangeFirstWizardSwitchStatusEvent({required this.value, this.deviceId = ''});
|
||||||
|
@override
|
||||||
|
List<Object> get props => [value, deviceId];
|
||||||
|
}
|
||||||
|
|
||||||
|
class GroupAllOnEvent extends WaterHeaterEvent {}
|
||||||
|
|
||||||
|
class GroupAllOffEvent extends WaterHeaterEvent {}
|
||||||
|
|
||||||
|
class ToggleCreateCirculate extends WaterHeaterEvent {}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/GroupWHModel.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/water_heater.dart';
|
import 'package:syncrow_app/features/devices/model/water_heater.dart';
|
||||||
|
|
||||||
abstract class WaterHeaterState extends Equatable {
|
abstract class WaterHeaterState extends Equatable {
|
||||||
@ -13,13 +14,8 @@ class WHInitialState extends WaterHeaterState {}
|
|||||||
class WHLoadingState extends WaterHeaterState {}
|
class WHLoadingState extends WaterHeaterState {}
|
||||||
|
|
||||||
class WHChangeLoading extends WaterHeaterState {
|
class WHChangeLoading extends WaterHeaterState {
|
||||||
// final WHStatusModel WHStatusModel;
|
|
||||||
const WHChangeLoading(
|
const WHChangeLoading(
|
||||||
// {required this. WHStatusModel}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// @override
|
|
||||||
// List<Object> get props => [acStatusModel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WHModifyingState extends WaterHeaterState {
|
class WHModifyingState extends WaterHeaterState {
|
||||||
@ -110,4 +106,17 @@ class ChangeSlidingSegmentState extends WaterHeaterState {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [value];
|
List<Object> get props => [value];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateGroupState extends WaterHeaterState {
|
||||||
|
final List<GroupWHModel> twoGangList;
|
||||||
|
final bool allSwitches;
|
||||||
|
|
||||||
|
const UpdateGroupState({required this.twoGangList, required this.allSwitches});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [twoGangList, allSwitches];
|
||||||
|
}
|
||||||
|
|||||||
11
lib/features/devices/model/GroupWHModel.dart
Normal file
11
lib/features/devices/model/GroupWHModel.dart
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
class GroupWHModel {
|
||||||
|
final String deviceId;
|
||||||
|
final String deviceName;
|
||||||
|
bool firstSwitch;
|
||||||
|
|
||||||
|
GroupWHModel({
|
||||||
|
required this.deviceId,
|
||||||
|
required this.deviceName,
|
||||||
|
required this.firstSwitch,
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -8,7 +8,8 @@ import 'package:syncrow_app/features/shared_widgets/devices_default_switch.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';
|
||||||
|
|
||||||
class OneGangList extends StatelessWidget {
|
class OneGangList extends StatelessWidget {
|
||||||
const OneGangList({super.key, required this.oneGangList, required this.allSwitches});
|
const OneGangList(
|
||||||
|
{super.key, required this.oneGangList, required this.allSwitches});
|
||||||
|
|
||||||
final List<GroupOneGangModel> oneGangList;
|
final List<GroupOneGangModel> oneGangList;
|
||||||
final bool allSwitches;
|
final bool allSwitches;
|
||||||
@ -48,9 +49,10 @@ class OneGangList extends StatelessWidget {
|
|||||||
DevicesDefaultSwitch(
|
DevicesDefaultSwitch(
|
||||||
switchValue: oneGangList[index].firstSwitch,
|
switchValue: oneGangList[index].firstSwitch,
|
||||||
action: () {
|
action: () {
|
||||||
BlocProvider.of<OneGangBloc>(context).add(ChangeFirstSwitchStatusEvent(
|
BlocProvider.of<OneGangBloc>(context).add(
|
||||||
value: oneGangList[index].firstSwitch,
|
ChangeFirstWizardSwitchStatusEvent(
|
||||||
deviceId: oneGangList[index].deviceId));
|
value: oneGangList[index].firstSwitch,
|
||||||
|
deviceId: oneGangList[index].deviceId));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -3,9 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart';
|
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_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_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/group_one_gang_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/view/widgets/one_gang/one_gang_list.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_timer_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_timer_screen.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/gang_switch.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/gang_switch.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
@ -22,9 +20,8 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) =>
|
create: (context) => OneGangBloc(switchCode: 'switch_1', oneGangId: device?.uuid ?? '')
|
||||||
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) {
|
||||||
OneGangModel oneGangModel = OneGangModel(
|
OneGangModel oneGangModel = OneGangModel(
|
||||||
@ -32,164 +29,135 @@ class OneGangScreen extends StatelessWidget {
|
|||||||
firstCountDown: 0,
|
firstCountDown: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
List<GroupOneGangModel> groupOneGangModel = [];
|
|
||||||
bool allSwitchesOn = false;
|
|
||||||
|
|
||||||
if (state is LoadingNewSate) {
|
if (state is LoadingNewSate) {
|
||||||
oneGangModel = state.oneGangModel;
|
oneGangModel = state.oneGangModel;
|
||||||
} else if (state is UpdateState) {
|
} else if (state is UpdateState) {
|
||||||
oneGangModel = state.oneGangModel;
|
oneGangModel = state.oneGangModel;
|
||||||
} else if (state is UpdateGroupState) {
|
|
||||||
groupOneGangModel = state.oneGangList;
|
|
||||||
allSwitchesOn = state.allSwitches;
|
|
||||||
}
|
}
|
||||||
return state is LoadingInitialState
|
return state is LoadingInitialState
|
||||||
? const Center(
|
? const Center(
|
||||||
child: DefaultContainer(
|
child:
|
||||||
width: 50,
|
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
height: 50,
|
|
||||||
child: CircularProgressIndicator()),
|
|
||||||
)
|
)
|
||||||
: device == null
|
: RefreshIndicator(
|
||||||
? OneGangList(
|
onRefresh: () async {
|
||||||
oneGangList: groupOneGangModel,
|
BlocProvider.of<OneGangBloc>(context)
|
||||||
allSwitches: allSwitchesOn)
|
.add(InitialEvent(groupScreen: device != null ? false : true));
|
||||||
: RefreshIndicator(
|
},
|
||||||
onRefresh: () async {
|
child: ListView(
|
||||||
BlocProvider.of<OneGangBloc>(context).add(InitialEvent(
|
children: [
|
||||||
groupScreen: device != null ? false : true));
|
SizedBox(
|
||||||
},
|
height: MediaQuery.of(context).size.height,
|
||||||
child: ListView(
|
child: Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
SizedBox(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
height: MediaQuery.of(context).size.height,
|
children: [
|
||||||
child: Column(
|
const Expanded(child: SizedBox.shrink()),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
Expanded(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
child: Row(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
const Expanded(child: SizedBox.shrink()),
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
Expanded(
|
children: [
|
||||||
child: Row(
|
Column(
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.spaceAround,
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Column(
|
GangSwitch(
|
||||||
children: [
|
threeGangSwitch: device!,
|
||||||
GangSwitch(
|
value: oneGangModel.firstSwitch,
|
||||||
threeGangSwitch: device!,
|
action: () {
|
||||||
value: oneGangModel.firstSwitch,
|
BlocProvider.of<OneGangBloc>(context).add(
|
||||||
action: () {
|
ChangeFirstSwitchStatusEvent(
|
||||||
BlocProvider.of<OneGangBloc>(
|
value: oneGangModel.firstSwitch));
|
||||||
context)
|
},
|
||||||
.add(
|
),
|
||||||
ChangeFirstSwitchStatusEvent(
|
const SizedBox(height: 20),
|
||||||
value: oneGangModel
|
const SizedBox(
|
||||||
.firstSwitch));
|
width: 70,
|
||||||
},
|
child: BodySmall(
|
||||||
),
|
text: " Entrance Light",
|
||||||
const SizedBox(height: 20),
|
fontColor: ColorsManager.textPrimaryColor,
|
||||||
const SizedBox(
|
textAlign: TextAlign.center,
|
||||||
width: 70,
|
),
|
||||||
child: BodySmall(
|
|
||||||
text: " Entrance Light",
|
|
||||||
fontColor: ColorsManager
|
|
||||||
.textPrimaryColor,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
Center(
|
),
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Card(
|
|
||||||
elevation: 3,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
PageRouteBuilder(
|
|
||||||
pageBuilder: (context,
|
|
||||||
animation1,
|
|
||||||
animation2) =>
|
|
||||||
TimerScheduleScreen(
|
|
||||||
switchCode:
|
|
||||||
'switch_1',
|
|
||||||
device: device!,
|
|
||||||
deviceCode:
|
|
||||||
'countdown_1',
|
|
||||||
)));
|
|
||||||
},
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.circular(
|
|
||||||
100),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.circular(
|
|
||||||
100),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Icon(
|
|
||||||
Icons.access_time,
|
|
||||||
color: ColorsManager
|
|
||||||
.primaryColorWithOpacity,
|
|
||||||
size: 25,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
BodySmall(
|
|
||||||
text: "Timer",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager
|
|
||||||
.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(child: SizedBox())
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
Center(
|
||||||
],
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
PageRouteBuilder(
|
||||||
|
pageBuilder:
|
||||||
|
(context, animation1, animation2) =>
|
||||||
|
TimerScheduleScreen(
|
||||||
|
switchCode: 'switch_1',
|
||||||
|
device: device!,
|
||||||
|
deviceCode: 'countdown_1',
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.access_time,
|
||||||
|
color: ColorsManager.primaryColorWithOpacity,
|
||||||
|
size: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
BodySmall(
|
||||||
|
text: "Timer",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(child: SizedBox())
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_bloc.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/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/group_one_gang_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_list.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
|
||||||
|
class OneGangWizard extends StatelessWidget {
|
||||||
|
const OneGangWizard({super.key, this.device});
|
||||||
|
|
||||||
|
final DeviceModel? device;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<GroupOneGangModel> groupOneGangModel = [];
|
||||||
|
|
||||||
|
return DefaultScaffold(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
OneGangBloc(switchCode: '', oneGangId: device?.uuid ?? '')..add(InitialWizardEvent()),
|
||||||
|
child: BlocBuilder<OneGangBloc, OneGangState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
bool allSwitchesOn = false;
|
||||||
|
|
||||||
|
if (state is UpdateGroupState) {
|
||||||
|
groupOneGangModel = state.oneGangList;
|
||||||
|
allSwitchesOn = state.allSwitches;
|
||||||
|
}
|
||||||
|
return state is LoadingInitialState
|
||||||
|
? const Center(
|
||||||
|
child:
|
||||||
|
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
|
)
|
||||||
|
: OneGangList(
|
||||||
|
oneGangList: groupOneGangModel,
|
||||||
|
allSwitches: allSwitchesOn,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,11 +4,9 @@ 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/devices/model/group_three_gang_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/features/devices/view/widgets/three_gang/gang_switch.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/gang_switch.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/schedule_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/schedule_screen.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_list.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/text_widgets/body_small.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
@ -22,9 +20,7 @@ class ThreeGangScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => ThreeGangBloc(
|
create: (context) => ThreeGangBloc(switchCode: '', threeGangId: device?.uuid ?? '')
|
||||||
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) {
|
||||||
@ -36,366 +32,354 @@ class ThreeGangScreen extends StatelessWidget {
|
|||||||
secondCountDown: 0,
|
secondCountDown: 0,
|
||||||
thirdCountDown: 0);
|
thirdCountDown: 0);
|
||||||
|
|
||||||
List<GroupThreeGangModel> groupThreeGangModel = [];
|
|
||||||
bool allSwitchesOn = false;
|
|
||||||
|
|
||||||
if (state is LoadingNewSate) {
|
if (state is LoadingNewSate) {
|
||||||
threeGangModel = state.threeGangModel;
|
threeGangModel = state.threeGangModel;
|
||||||
} else if (state is UpdateState) {
|
} else if (state is UpdateState) {
|
||||||
threeGangModel = state.threeGangModel;
|
threeGangModel = state.threeGangModel;
|
||||||
} else if (state is UpdateGroupState) {
|
|
||||||
groupThreeGangModel = state.threeGangList;
|
|
||||||
allSwitchesOn = state.allSwitches;
|
|
||||||
}
|
}
|
||||||
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
|
: RefreshIndicator(
|
||||||
? ThreeGangList(
|
onRefresh: () async {
|
||||||
threeGangList: groupThreeGangModel,
|
BlocProvider.of<ThreeGangBloc>(context)
|
||||||
allSwitches: allSwitchesOn,
|
.add(InitialEvent(groupScreen: device != null ? false : true));
|
||||||
)
|
},
|
||||||
: RefreshIndicator(
|
child: ListView(
|
||||||
onRefresh: () async {
|
children: [
|
||||||
BlocProvider.of<ThreeGangBloc>(context)
|
SizedBox(
|
||||||
.add(InitialEvent(groupScreen: device != null ? false : true));
|
height: MediaQuery.of(context).size.height,
|
||||||
},
|
child: Column(
|
||||||
child: ListView(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
SizedBox(
|
children: [
|
||||||
height: MediaQuery.of(context).size.height,
|
const Expanded(child: SizedBox.shrink()),
|
||||||
child: Column(
|
Expanded(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
const Expanded(child: SizedBox.shrink()),
|
children: [
|
||||||
Expanded(
|
Column(
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Column(
|
GangSwitch(
|
||||||
children: [
|
threeGangSwitch: device!,
|
||||||
GangSwitch(
|
value: threeGangModel.firstSwitch,
|
||||||
threeGangSwitch: device!,
|
action: () {
|
||||||
value: threeGangModel.firstSwitch,
|
BlocProvider.of<ThreeGangBloc>(context).add(
|
||||||
action: () {
|
ChangeFirstSwitchStatusEvent(
|
||||||
BlocProvider.of<ThreeGangBloc>(context).add(
|
value: threeGangModel.firstSwitch));
|
||||||
ChangeFirstSwitchStatusEvent(
|
},
|
||||||
value: threeGangModel.firstSwitch));
|
// control: DeviceControlModel(
|
||||||
},
|
// deviceId: device.uuid,
|
||||||
// control: DeviceControlModel(
|
// // code: 'switch_1',
|
||||||
// deviceId: device.uuid,
|
// code: device.status[0].code,
|
||||||
// // code: 'switch_1',
|
// // value: true,
|
||||||
// code: device.status[0].code,
|
// value: device.status[0].value,
|
||||||
// // value: true,
|
// ),
|
||||||
// value: device.status[0].value,
|
|
||||||
// ),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
const SizedBox(
|
|
||||||
width: 70,
|
|
||||||
child: BodySmall(
|
|
||||||
text: "Bedside Light",
|
|
||||||
fontColor: ColorsManager.textPrimaryColor,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
Column(
|
const SizedBox(height: 20),
|
||||||
children: [
|
const SizedBox(
|
||||||
GangSwitch(
|
width: 70,
|
||||||
threeGangSwitch: device!,
|
child: BodySmall(
|
||||||
value: threeGangModel.secondSwitch,
|
text: "Bedside Light",
|
||||||
action: () {
|
fontColor: ColorsManager.textPrimaryColor,
|
||||||
BlocProvider.of<ThreeGangBloc>(context).add(
|
textAlign: TextAlign.center,
|
||||||
ChangeSecondSwitchStatusEvent(
|
),
|
||||||
value: threeGangModel.secondSwitch));
|
|
||||||
},
|
|
||||||
// control: DeviceControlModel(
|
|
||||||
// // deviceId: 'bfe10693d4fd263206ocq9',
|
|
||||||
// // code: 'switch_2',
|
|
||||||
// // value: true,
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: device.status[1].code,
|
|
||||||
// value: device.status[1].value,
|
|
||||||
// ),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
const SizedBox(
|
|
||||||
width: 70,
|
|
||||||
child: BodySmall(
|
|
||||||
text: "Ceiling Light",
|
|
||||||
fontColor: ColorsManager.textPrimaryColor,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
GangSwitch(
|
|
||||||
threeGangSwitch: device!,
|
|
||||||
value: threeGangModel.thirdSwitch,
|
|
||||||
action: () {
|
|
||||||
BlocProvider.of<ThreeGangBloc>(context).add(
|
|
||||||
ChangeThirdSwitchStatusEvent(
|
|
||||||
value: threeGangModel.thirdSwitch));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
const SizedBox(
|
|
||||||
width: 70,
|
|
||||||
child: BodySmall(
|
|
||||||
text: "Spotlight",
|
|
||||||
fontColor: ColorsManager.textPrimaryColor,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
Column(
|
||||||
Center(
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Column(
|
GangSwitch(
|
||||||
mainAxisSize: MainAxisSize.min,
|
threeGangSwitch: device!,
|
||||||
children: [
|
value: threeGangModel.secondSwitch,
|
||||||
Card(
|
action: () {
|
||||||
elevation: 3,
|
BlocProvider.of<ThreeGangBloc>(context).add(
|
||||||
shape: RoundedRectangleBorder(
|
ChangeSecondSwitchStatusEvent(
|
||||||
borderRadius: BorderRadius.circular(100),
|
value: threeGangModel.secondSwitch));
|
||||||
),
|
},
|
||||||
child: GestureDetector(
|
// control: DeviceControlModel(
|
||||||
onTap: () {
|
// // deviceId: 'bfe10693d4fd263206ocq9',
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
// // code: 'switch_2',
|
||||||
// DeviceControlModel(
|
// // value: true,
|
||||||
// deviceId: device.uuid,
|
// deviceId: device.uuid,
|
||||||
// code: 'switch_1',
|
// code: device.status[1].code,
|
||||||
// value: true,
|
// value: device.status[1].value,
|
||||||
// ),
|
// ),
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_2',
|
|
||||||
// value: true,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_3',
|
|
||||||
// value: true,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
BlocProvider.of<ThreeGangBloc>(context)
|
|
||||||
.add(AllOnEvent());
|
|
||||||
},
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: BodySmall(
|
|
||||||
text: "On",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager
|
|
||||||
.primaryColorWithOpacity,
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
BodySmall(
|
|
||||||
text: "All On",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 20,
|
width: 70,
|
||||||
|
child: BodySmall(
|
||||||
|
text: "Ceiling Light",
|
||||||
|
fontColor: ColorsManager.textPrimaryColor,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Column(
|
],
|
||||||
mainAxisSize: MainAxisSize.min,
|
),
|
||||||
children: [
|
Column(
|
||||||
Card(
|
children: [
|
||||||
elevation: 3,
|
GangSwitch(
|
||||||
shape: RoundedRectangleBorder(
|
threeGangSwitch: device!,
|
||||||
borderRadius: BorderRadius.circular(100),
|
value: threeGangModel.thirdSwitch,
|
||||||
),
|
action: () {
|
||||||
child: GestureDetector(
|
BlocProvider.of<ThreeGangBloc>(context).add(
|
||||||
onTap: () {
|
ChangeThirdSwitchStatusEvent(
|
||||||
Navigator.push(
|
value: threeGangModel.thirdSwitch));
|
||||||
context,
|
},
|
||||||
PageRouteBuilder(
|
),
|
||||||
pageBuilder:
|
const SizedBox(height: 20),
|
||||||
(context, animation1, animation2) =>
|
const SizedBox(
|
||||||
ScheduleScreen(
|
width: 70,
|
||||||
device: device!,
|
child: BodySmall(
|
||||||
)));
|
text: "Spotlight",
|
||||||
},
|
fontColor: ColorsManager.textPrimaryColor,
|
||||||
child: Stack(
|
textAlign: TextAlign.center,
|
||||||
alignment: Alignment.center,
|
),
|
||||||
children: [
|
),
|
||||||
Container(
|
],
|
||||||
width: 60,
|
),
|
||||||
height: 60,
|
],
|
||||||
decoration: BoxDecoration(
|
),
|
||||||
color: Colors.grey[300],
|
),
|
||||||
borderRadius: BorderRadius.circular(100),
|
Center(
|
||||||
),
|
child: Row(
|
||||||
),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
Container(
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
width: 40,
|
children: [
|
||||||
height: 40,
|
Column(
|
||||||
decoration: BoxDecoration(
|
mainAxisSize: MainAxisSize.min,
|
||||||
color: Colors.white,
|
children: [
|
||||||
borderRadius: BorderRadius.circular(100),
|
Card(
|
||||||
),
|
elevation: 3,
|
||||||
child: Center(
|
shape: RoundedRectangleBorder(
|
||||||
child: Icon(
|
borderRadius: BorderRadius.circular(100),
|
||||||
Icons.access_time,
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_1',
|
||||||
|
// value: true,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_2',
|
||||||
|
// value: true,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_3',
|
||||||
|
// value: true,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
BlocProvider.of<ThreeGangBloc>(context)
|
||||||
|
.add(AllOnEvent());
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: BodySmall(
|
||||||
|
text: "On",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
color:
|
color:
|
||||||
ColorsManager.primaryColorWithOpacity,
|
ColorsManager.primaryColorWithOpacity,
|
||||||
size: 25,
|
fontWeight: FontWeight.bold),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
),
|
||||||
BodySmall(
|
|
||||||
text: "Timer",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(height: 10),
|
||||||
width: 20,
|
BodySmall(
|
||||||
),
|
text: "All On",
|
||||||
Column(
|
style: context.bodyMedium.copyWith(
|
||||||
mainAxisSize: MainAxisSize.min,
|
color: ColorsManager.textPrimaryColor,
|
||||||
children: [
|
),
|
||||||
Card(
|
|
||||||
elevation: 3,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_1',
|
|
||||||
// value: false,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_2',
|
|
||||||
// value: false,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_3',
|
|
||||||
// value: false,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
BlocProvider.of<ThreeGangBloc>(context)
|
|
||||||
.add(AllOffEvent());
|
|
||||||
},
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: BodySmall(
|
|
||||||
text: "Off",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager
|
|
||||||
.primaryColorWithOpacity,
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
BodySmall(
|
|
||||||
text: "All Off",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
Expanded(child: SizedBox())
|
width: 20,
|
||||||
],
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
PageRouteBuilder(
|
||||||
|
pageBuilder:
|
||||||
|
(context, animation1, animation2) =>
|
||||||
|
ScheduleScreen(
|
||||||
|
device: device!,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.access_time,
|
||||||
|
color: ColorsManager.primaryColorWithOpacity,
|
||||||
|
size: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
BodySmall(
|
||||||
|
text: "Timer",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_1',
|
||||||
|
// value: false,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_2',
|
||||||
|
// value: false,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_3',
|
||||||
|
// value: false,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
BlocProvider.of<ThreeGangBloc>(context)
|
||||||
|
.add(AllOffEvent());
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: BodySmall(
|
||||||
|
text: "Off",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color:
|
||||||
|
ColorsManager.primaryColorWithOpacity,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
BodySmall(
|
||||||
|
text: "All Off",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(child: SizedBox())
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_bloc.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/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_list.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
|
||||||
|
class ThreeGangWizard extends StatelessWidget {
|
||||||
|
const ThreeGangWizard({super.key, this.device});
|
||||||
|
|
||||||
|
final DeviceModel? device;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DefaultScaffold(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) => ThreeGangBloc(switchCode: '', threeGangId: device?.uuid ?? '')
|
||||||
|
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
||||||
|
child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
List<GroupThreeGangModel> groupThreeGangModel = [];
|
||||||
|
bool allSwitchesOn = false;
|
||||||
|
|
||||||
|
if (state is UpdateGroupState) {
|
||||||
|
groupThreeGangModel = state.threeGangList;
|
||||||
|
allSwitchesOn = state.allSwitches;
|
||||||
|
}
|
||||||
|
return state is LoadingInitialState
|
||||||
|
? const Center(
|
||||||
|
child:
|
||||||
|
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
|
)
|
||||||
|
: ThreeGangList(
|
||||||
|
threeGangList: groupThreeGangModel,
|
||||||
|
allSwitches: allSwitchesOn,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,7 +8,8 @@ import 'package:syncrow_app/features/shared_widgets/devices_default_switch.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';
|
||||||
|
|
||||||
class TwoGangList extends StatelessWidget {
|
class TwoGangList extends StatelessWidget {
|
||||||
const TwoGangList({super.key, required this.twoGangList, required this.allSwitches});
|
const TwoGangList(
|
||||||
|
{super.key, required this.twoGangList, required this.allSwitches});
|
||||||
|
|
||||||
final List<GroupTwoGangModel> twoGangList;
|
final List<GroupTwoGangModel> twoGangList;
|
||||||
final bool allSwitches;
|
final bool allSwitches;
|
||||||
@ -48,9 +49,10 @@ class TwoGangList extends StatelessWidget {
|
|||||||
DevicesDefaultSwitch(
|
DevicesDefaultSwitch(
|
||||||
switchValue: twoGangList[index].firstSwitch,
|
switchValue: twoGangList[index].firstSwitch,
|
||||||
action: () {
|
action: () {
|
||||||
BlocProvider.of<TwoGangBloc>(context).add(ChangeFirstSwitchStatusEvent(
|
BlocProvider.of<TwoGangBloc>(context).add(
|
||||||
value: twoGangList[index].firstSwitch,
|
ChangeFirstWizardSwitchStatusEvent(
|
||||||
deviceId: twoGangList[index].deviceId));
|
value: twoGangList[index].firstSwitch,
|
||||||
|
deviceId: twoGangList[index].deviceId));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
@ -59,9 +61,10 @@ class TwoGangList extends StatelessWidget {
|
|||||||
DevicesDefaultSwitch(
|
DevicesDefaultSwitch(
|
||||||
switchValue: twoGangList[index].secondSwitch,
|
switchValue: twoGangList[index].secondSwitch,
|
||||||
action: () {
|
action: () {
|
||||||
BlocProvider.of<TwoGangBloc>(context).add(ChangeSecondSwitchStatusEvent(
|
BlocProvider.of<TwoGangBloc>(context).add(
|
||||||
value: twoGangList[index].secondSwitch,
|
ChangeSecondWizardSwitchStatusEvent(
|
||||||
deviceId: twoGangList[index].deviceId));
|
value: twoGangList[index].secondSwitch,
|
||||||
|
deviceId: twoGangList[index].deviceId));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -4,10 +4,8 @@ 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_event.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_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/devices/model/group_two_gang_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/features/devices/view/widgets/three_gang/gang_switch.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/gang_switch.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_list.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_schedule_screen.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_schedule_screen.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/text_widgets/body_small.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
@ -23,7 +21,7 @@ class TwoGangScreen extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => TwoGangBloc(switchCode: switchCode ?? '', twoGangId: device?.uuid ?? '')
|
create: (context) => TwoGangBloc(switchCode: switchCode ?? '', twoGangId: device?.uuid ?? '')
|
||||||
..add(InitialEvent(groupScreen: device != null ? false : true)),
|
..add(const InitialEvent()),
|
||||||
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
TwoGangModel twoGangModel = TwoGangModel(
|
TwoGangModel twoGangModel = TwoGangModel(
|
||||||
@ -33,304 +31,292 @@ class TwoGangScreen extends StatelessWidget {
|
|||||||
secondCountDown: 0,
|
secondCountDown: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
List<GroupTwoGangModel> groupTwoGangModel = [];
|
|
||||||
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) {
|
||||||
twoGangModel = state.twoGangModel;
|
twoGangModel = state.twoGangModel;
|
||||||
} else if (state is UpdateGroupState) {
|
|
||||||
groupTwoGangModel = state.twoGangList;
|
|
||||||
allSwitchesOn = state.allSwitches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
: RefreshIndicator(
|
||||||
? TwoGangList(
|
onRefresh: () async {
|
||||||
twoGangList: groupTwoGangModel,
|
BlocProvider.of<TwoGangBloc>(context).add(const InitialEvent());
|
||||||
allSwitches: allSwitchesOn,
|
},
|
||||||
)
|
child: ListView(
|
||||||
: RefreshIndicator(
|
children: [
|
||||||
onRefresh: () async {
|
SizedBox(
|
||||||
BlocProvider.of<TwoGangBloc>(context)
|
height: MediaQuery.of(context).size.height,
|
||||||
.add(InitialEvent(groupScreen: device != null ? false : true));
|
child: Column(
|
||||||
},
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: ListView(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
const Expanded(child: SizedBox.shrink()),
|
||||||
height: MediaQuery.of(context).size.height,
|
Expanded(
|
||||||
child: Column(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Expanded(child: SizedBox.shrink()),
|
Column(
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Column(
|
GangSwitch(
|
||||||
children: [
|
threeGangSwitch: device!,
|
||||||
GangSwitch(
|
value: twoGangModel.firstSwitch,
|
||||||
threeGangSwitch: device!,
|
action: () {
|
||||||
value: twoGangModel.firstSwitch,
|
BlocProvider.of<TwoGangBloc>(context).add(
|
||||||
action: () {
|
ChangeFirstSwitchStatusEvent(
|
||||||
BlocProvider.of<TwoGangBloc>(context).add(
|
value: twoGangModel.firstSwitch));
|
||||||
ChangeFirstSwitchStatusEvent(
|
},
|
||||||
value: twoGangModel.firstSwitch));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
const SizedBox(
|
|
||||||
width: 77,
|
|
||||||
child: BodySmall(
|
|
||||||
text: "Cove Light",
|
|
||||||
fontColor: ColorsManager.textPrimaryColor,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
Column(
|
const SizedBox(height: 20),
|
||||||
children: [
|
const SizedBox(
|
||||||
GangSwitch(
|
width: 77,
|
||||||
threeGangSwitch: device!,
|
child: BodySmall(
|
||||||
value: twoGangModel.secondSwitch,
|
text: "Cove Light",
|
||||||
action: () {
|
fontColor: ColorsManager.textPrimaryColor,
|
||||||
BlocProvider.of<TwoGangBloc>(context).add(
|
textAlign: TextAlign.center,
|
||||||
ChangeSecondSwitchStatusEvent(
|
),
|
||||||
value: twoGangModel.secondSwitch));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
const SizedBox(
|
|
||||||
width: 77,
|
|
||||||
child: BodySmall(
|
|
||||||
text: "Chandelier",
|
|
||||||
fontColor: ColorsManager.textPrimaryColor,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
Column(
|
||||||
Center(
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Column(
|
GangSwitch(
|
||||||
mainAxisSize: MainAxisSize.min,
|
threeGangSwitch: device!,
|
||||||
children: [
|
value: twoGangModel.secondSwitch,
|
||||||
Card(
|
action: () {
|
||||||
elevation: 3,
|
BlocProvider.of<TwoGangBloc>(context).add(
|
||||||
shape: RoundedRectangleBorder(
|
ChangeSecondSwitchStatusEvent(
|
||||||
borderRadius: BorderRadius.circular(100),
|
value: twoGangModel.secondSwitch));
|
||||||
),
|
},
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
BlocProvider.of<TwoGangBloc>(context)
|
|
||||||
.add(AllOnEvent());
|
|
||||||
},
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: BodySmall(
|
|
||||||
text: "On",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager
|
|
||||||
.primaryColorWithOpacity,
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
BodySmall(
|
|
||||||
text: "All On",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 20,
|
width: 77,
|
||||||
|
child: BodySmall(
|
||||||
|
text: "Chandelier",
|
||||||
|
fontColor: ColorsManager.textPrimaryColor,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Column(
|
],
|
||||||
mainAxisSize: MainAxisSize.min,
|
),
|
||||||
children: [
|
],
|
||||||
Card(
|
),
|
||||||
elevation: 3,
|
),
|
||||||
shape: RoundedRectangleBorder(
|
Center(
|
||||||
borderRadius: BorderRadius.circular(100),
|
child: Row(
|
||||||
),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: GestureDetector(
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
onTap: () {
|
children: [
|
||||||
Navigator.push(
|
Column(
|
||||||
context,
|
mainAxisSize: MainAxisSize.min,
|
||||||
PageRouteBuilder(
|
children: [
|
||||||
pageBuilder:
|
Card(
|
||||||
(context, animation1, animation2) =>
|
elevation: 3,
|
||||||
TwoGangScheduleScreen(
|
shape: RoundedRectangleBorder(
|
||||||
device: device!,
|
borderRadius: BorderRadius.circular(100),
|
||||||
)));
|
),
|
||||||
},
|
child: GestureDetector(
|
||||||
child: Stack(
|
onTap: () {
|
||||||
alignment: Alignment.center,
|
BlocProvider.of<TwoGangBloc>(context).add(AllOnEvent());
|
||||||
children: [
|
},
|
||||||
Container(
|
child: Stack(
|
||||||
width: 60,
|
alignment: Alignment.center,
|
||||||
height: 60,
|
children: [
|
||||||
decoration: BoxDecoration(
|
Container(
|
||||||
color: Colors.grey[300],
|
width: 60,
|
||||||
borderRadius: BorderRadius.circular(100),
|
height: 60,
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
),
|
color: Colors.grey[300],
|
||||||
Container(
|
borderRadius: BorderRadius.circular(100),
|
||||||
width: 40,
|
),
|
||||||
height: 40,
|
),
|
||||||
decoration: BoxDecoration(
|
Container(
|
||||||
color: Colors.white,
|
width: 40,
|
||||||
borderRadius: BorderRadius.circular(100),
|
height: 40,
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
child: Center(
|
color: Colors.white,
|
||||||
child: Icon(
|
borderRadius: BorderRadius.circular(100),
|
||||||
Icons.access_time,
|
),
|
||||||
|
child: Center(
|
||||||
|
child: BodySmall(
|
||||||
|
text: "On",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
color:
|
color:
|
||||||
ColorsManager.primaryColorWithOpacity,
|
ColorsManager.primaryColorWithOpacity,
|
||||||
size: 25,
|
fontWeight: FontWeight.bold),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
),
|
||||||
BodySmall(
|
|
||||||
text: "Timer",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(height: 10),
|
||||||
width: 20,
|
BodySmall(
|
||||||
),
|
text: "All On",
|
||||||
Column(
|
style: context.bodyMedium.copyWith(
|
||||||
mainAxisSize: MainAxisSize.min,
|
color: ColorsManager.textPrimaryColor,
|
||||||
children: [
|
),
|
||||||
Card(
|
|
||||||
elevation: 3,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_1',
|
|
||||||
// value: false,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_2',
|
|
||||||
// value: false,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
// DevicesCubit.getInstance().deviceControl(
|
|
||||||
// DeviceControlModel(
|
|
||||||
// deviceId: device.uuid,
|
|
||||||
// code: 'switch_3',
|
|
||||||
// value: false,
|
|
||||||
// ),
|
|
||||||
// device.uuid!,
|
|
||||||
// );
|
|
||||||
BlocProvider.of<TwoGangBloc>(context)
|
|
||||||
.add(AllOffEvent());
|
|
||||||
},
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 60,
|
|
||||||
height: 60,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[300],
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: BodySmall(
|
|
||||||
text: "Off",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager
|
|
||||||
.primaryColorWithOpacity,
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
BodySmall(
|
|
||||||
text: "All Off",
|
|
||||||
style: context.bodyMedium.copyWith(
|
|
||||||
color: ColorsManager.textPrimaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
Expanded(child: SizedBox())
|
width: 20,
|
||||||
],
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
PageRouteBuilder(
|
||||||
|
pageBuilder:
|
||||||
|
(context, animation1, animation2) =>
|
||||||
|
TwoGangScheduleScreen(
|
||||||
|
device: device!,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Icon(
|
||||||
|
Icons.access_time,
|
||||||
|
color: ColorsManager.primaryColorWithOpacity,
|
||||||
|
size: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
BodySmall(
|
||||||
|
text: "Timer",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_1',
|
||||||
|
// value: false,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_2',
|
||||||
|
// value: false,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
// DevicesCubit.getInstance().deviceControl(
|
||||||
|
// DeviceControlModel(
|
||||||
|
// deviceId: device.uuid,
|
||||||
|
// code: 'switch_3',
|
||||||
|
// value: false,
|
||||||
|
// ),
|
||||||
|
// device.uuid!,
|
||||||
|
// );
|
||||||
|
BlocProvider.of<TwoGangBloc>(context)
|
||||||
|
.add(AllOffEvent());
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 60,
|
||||||
|
height: 60,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: BodySmall(
|
||||||
|
text: "Off",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color:
|
||||||
|
ColorsManager.primaryColorWithOpacity,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
BodySmall(
|
||||||
|
text: "All Off",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(child: SizedBox())
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_bloc.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_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/group_two_gang_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_list.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
|
||||||
|
class TwoGangWizard extends StatelessWidget {
|
||||||
|
const TwoGangWizard({super.key, this.device});
|
||||||
|
|
||||||
|
final DeviceModel? device;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<GroupTwoGangModel> groupTwoGangModel = [];
|
||||||
|
|
||||||
|
return DefaultScaffold(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
TwoGangBloc(switchCode: '', twoGangId: device?.uuid ?? '')..add(InitialWizardEvent()),
|
||||||
|
child: BlocBuilder<TwoGangBloc, TwoGangState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
bool allSwitchesOn = false;
|
||||||
|
|
||||||
|
if (state is UpdateGroupState) {
|
||||||
|
groupTwoGangModel = state.twoGangList;
|
||||||
|
allSwitchesOn = state.allSwitches;
|
||||||
|
}
|
||||||
|
return state is LoadingInitialState
|
||||||
|
? const Center(
|
||||||
|
child:
|
||||||
|
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
|
)
|
||||||
|
: TwoGangList(
|
||||||
|
twoGangList: groupTwoGangModel,
|
||||||
|
allSwitches: allSwitchesOn,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
69
lib/features/devices/view/widgets/water_heater/wh_list.dart
Normal file
69
lib/features/devices/view/widgets/water_heater/wh_list.dart
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_event.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/GroupWHModel.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
|
|
||||||
|
class WHList extends StatelessWidget {
|
||||||
|
const WHList({super.key, required this.whList, required this.allSwitches});
|
||||||
|
|
||||||
|
final List<GroupWHModel> whList;
|
||||||
|
final bool allSwitches;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<WaterHeaterBloc, WaterHeaterState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
const BodySmall(text: 'All Lights'),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
DevicesDefaultSwitch(
|
||||||
|
switchValue: allSwitches,
|
||||||
|
action: () {
|
||||||
|
BlocProvider.of<WaterHeaterBloc>(context)
|
||||||
|
.add(GroupAllOnEvent());
|
||||||
|
},
|
||||||
|
secondAction: () {
|
||||||
|
BlocProvider.of<WaterHeaterBloc>(context)
|
||||||
|
.add(GroupAllOffEvent());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
padding: const EdgeInsets.all(0),
|
||||||
|
itemCount: whList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
BodySmall(text: whList[index].deviceName),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
DevicesDefaultSwitch(
|
||||||
|
switchValue: whList[index].firstSwitch,
|
||||||
|
action: () {
|
||||||
|
BlocProvider.of<WaterHeaterBloc>(context).add(
|
||||||
|
ChangeFirstWizardSwitchStatusEvent(
|
||||||
|
value: whList[index].firstSwitch,
|
||||||
|
deviceId: whList[index].deviceId));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,10 +25,7 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
final String deviceCode;
|
final String deviceCode;
|
||||||
final String switchCode;
|
final String switchCode;
|
||||||
const WHTimerScheduleScreen(
|
const WHTimerScheduleScreen(
|
||||||
{required this.device,
|
{required this.device, required this.deviceCode, required this.switchCode, super.key});
|
||||||
required this.deviceCode,
|
|
||||||
required this.switchCode,
|
|
||||||
super.key});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -38,10 +35,9 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
statusBarIconBrightness: Brightness.light,
|
statusBarIconBrightness: Brightness.light,
|
||||||
),
|
),
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) =>
|
create: (context) => WaterHeaterBloc(switchCode: switchCode, whId: device.uuid ?? '')
|
||||||
WaterHeaterBloc(switchCode: switchCode, whId: device.uuid ?? '')
|
..add(GetCounterEvent(deviceCode: deviceCode))
|
||||||
..add(GetCounterEvent(deviceCode: deviceCode))
|
..add(GetScheduleEvent()),
|
||||||
..add(GetScheduleEvent()),
|
|
||||||
child: BlocBuilder<WaterHeaterBloc, WaterHeaterState>(
|
child: BlocBuilder<WaterHeaterBloc, WaterHeaterState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final waterHeaterBloc = BlocProvider.of<WaterHeaterBloc>(context);
|
final waterHeaterBloc = BlocProvider.of<WaterHeaterBloc>(context);
|
||||||
@ -87,9 +83,8 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
? IconButton(
|
? IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// waterHeaterBloc.toggleCreateSchedule();
|
// waterHeaterBloc.toggleCreateSchedule();
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc
|
||||||
const ToggleCreateScheduleEvent(
|
.add(const ToggleCreateScheduleEvent(index: 1));
|
||||||
index: 1));
|
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
)
|
)
|
||||||
@ -104,7 +99,7 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
: waterHeaterBloc.selectedTabIndex == 2
|
: waterHeaterBloc.selectedTabIndex == 2
|
||||||
? IconButton(
|
? IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
waterHeaterBloc.toggleCreateCirculate();
|
waterHeaterBloc.add(ToggleCreateCirculate());
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
)
|
)
|
||||||
@ -120,8 +115,7 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
decoration: const ShapeDecoration(
|
decoration: const ShapeDecoration(
|
||||||
color: ColorsManager.onPrimaryColor,
|
color: ColorsManager.onPrimaryColor,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||||
Radius.circular(30)),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: TabBar(
|
child: TabBar(
|
||||||
@ -130,49 +124,34 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
labelPadding: EdgeInsets.zero,
|
labelPadding: EdgeInsets.zero,
|
||||||
onTap: (value) {
|
onTap: (value) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
if (waterHeaterBloc.createSchedule ==
|
if (waterHeaterBloc.createSchedule == true) {
|
||||||
true) {
|
|
||||||
// waterHeaterBloc
|
// waterHeaterBloc
|
||||||
// .toggleCreateSchedule();
|
// .toggleCreateSchedule();
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc
|
||||||
const ToggleCreateScheduleEvent(
|
.add(const ToggleCreateScheduleEvent(index: 1));
|
||||||
index: 1));
|
|
||||||
}
|
}
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc.add(ToggleSelectedEvent(index: value));
|
||||||
ToggleSelectedEvent(
|
|
||||||
index: value));
|
|
||||||
// waterHeaterBloc
|
// waterHeaterBloc
|
||||||
// .toggleSelectedIndex(value);
|
// .toggleSelectedIndex(value);
|
||||||
} else if (value == 2) {
|
} else if (value == 2) {
|
||||||
if (waterHeaterBloc.createCirculate ==
|
if (waterHeaterBloc.createCirculate == true) {
|
||||||
true) {
|
waterHeaterBloc
|
||||||
waterHeaterBloc.add(
|
.add(ToggleCreateCirculateEvent(index: value));
|
||||||
ToggleCreateCirculateEvent(
|
|
||||||
index: value));
|
|
||||||
// waterHeaterBloc
|
// waterHeaterBloc
|
||||||
// .toggleCreateCirculate();
|
// .toggleCreateCirculate();
|
||||||
}
|
}
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc.add(ToggleSelectedEvent(index: value));
|
||||||
ToggleSelectedEvent(
|
|
||||||
index: value));
|
|
||||||
// waterHeaterBloc
|
// waterHeaterBloc
|
||||||
// .toggleSelectedIndex(value);
|
// .toggleSelectedIndex(value);
|
||||||
} else {
|
} else {
|
||||||
if (waterHeaterBloc.createSchedule ==
|
if (waterHeaterBloc.createSchedule == true) {
|
||||||
true) {
|
waterHeaterBloc.add(ToggleSelectedEvent(index: value));
|
||||||
waterHeaterBloc.add(
|
|
||||||
ToggleSelectedEvent(
|
|
||||||
index: value));
|
|
||||||
// waterHeaterBloc
|
// waterHeaterBloc
|
||||||
// .toggleCreateSchedule();
|
// .toggleCreateSchedule();
|
||||||
}
|
}
|
||||||
waterHeaterBloc.createCirculate =
|
waterHeaterBloc.createCirculate = false;
|
||||||
false;
|
waterHeaterBloc.createSchedule = false;
|
||||||
waterHeaterBloc.createSchedule =
|
waterHeaterBloc.add(ToggleSelectedEvent(index: value));
|
||||||
false;
|
|
||||||
waterHeaterBloc.add(
|
|
||||||
ToggleSelectedEvent(
|
|
||||||
index: value));
|
|
||||||
// waterHeaterBloc
|
// waterHeaterBloc
|
||||||
// .toggleSelectedIndex(value);
|
// .toggleSelectedIndex(value);
|
||||||
}
|
}
|
||||||
@ -183,39 +162,31 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
indicator: const ShapeDecoration(
|
indicator: const ShapeDecoration(
|
||||||
color: ColorsManager.slidingBlueColor,
|
color: ColorsManager.slidingBlueColor,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||||
Radius.circular(20)),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
isScrollable: false,
|
isScrollable: false,
|
||||||
labelColor: Colors
|
labelColor: Colors.white, // Text color when selected
|
||||||
.white, // Text color when selected
|
unselectedLabelColor:
|
||||||
unselectedLabelColor: ColorsManager
|
ColorsManager.blackColor, // Text color when not selected
|
||||||
.blackColor, // Text color when not selected
|
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(
|
Tab(
|
||||||
icon: Padding(
|
icon: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(top: 10.0),
|
||||||
top: 10.0),
|
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.scheduleTimeIcon,
|
Assets.scheduleTimeIcon,
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 0
|
||||||
.selectedTabIndex ==
|
|
||||||
0
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager
|
: ColorsManager
|
||||||
.blackColor, // Change icon color based on selectedIndex
|
.blackColor, // Change icon color based on selectedIndex
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
vertical: 5),
|
|
||||||
child: BodySmall(
|
child: BodySmall(
|
||||||
text: 'Countdown',
|
text: 'Countdown',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 0
|
||||||
.selectedTabIndex ==
|
|
||||||
0
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager
|
: ColorsManager
|
||||||
.blackColor, // Text color based on selectedTabIndex
|
.blackColor, // Text color based on selectedTabIndex
|
||||||
@ -227,26 +198,20 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Padding(
|
icon: Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(top: 10),
|
||||||
const EdgeInsets.only(top: 10),
|
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.scheduleCelenderIcon,
|
Assets.scheduleCelenderIcon,
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 1
|
||||||
.selectedTabIndex ==
|
|
||||||
1
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
vertical: 5),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'Schedule',
|
'Schedule',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 1
|
||||||
.selectedTabIndex ==
|
|
||||||
1
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -257,26 +222,20 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Padding(
|
icon: Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(top: 10),
|
||||||
const EdgeInsets.only(top: 10),
|
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.scheduleCirculateIcon,
|
Assets.scheduleCirculateIcon,
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 2
|
||||||
.selectedTabIndex ==
|
|
||||||
2
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
vertical: 5),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'Circulate',
|
'Circulate',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 2
|
||||||
.selectedTabIndex ==
|
|
||||||
2
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -287,26 +246,20 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Padding(
|
icon: Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(top: 10),
|
||||||
const EdgeInsets.only(top: 10),
|
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
Assets.scheduleInchingIcon,
|
Assets.scheduleInchingIcon,
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 3
|
||||||
.selectedTabIndex ==
|
|
||||||
3
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
vertical: 5),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'Inching',
|
'Inching',
|
||||||
style: context.bodySmall.copyWith(
|
style: context.bodySmall.copyWith(
|
||||||
color: waterHeaterBloc
|
color: waterHeaterBloc.selectedTabIndex == 3
|
||||||
.selectedTabIndex ==
|
|
||||||
3
|
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: ColorsManager.blackColor,
|
: ColorsManager.blackColor,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -325,106 +278,75 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
MainAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
countNum > 0
|
countNum > 0
|
||||||
? BodyLarge(
|
? BodyLarge(
|
||||||
text: _formatDuration(
|
text: _formatDuration(countNum),
|
||||||
countNum),
|
fontColor: ColorsManager.slidingBlueColor,
|
||||||
fontColor: ColorsManager
|
|
||||||
.slidingBlueColor,
|
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
)
|
)
|
||||||
: CupertinoTimerPicker(
|
: CupertinoTimerPicker(
|
||||||
mode:
|
mode: CupertinoTimerPickerMode.hm,
|
||||||
CupertinoTimerPickerMode
|
|
||||||
.hm,
|
|
||||||
onTimerDurationChanged:
|
onTimerDurationChanged:
|
||||||
(Duration
|
(Duration newDuration) {
|
||||||
newDuration) {
|
|
||||||
duration = newDuration;
|
duration = newDuration;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (state
|
if (state is LoadingNewSate) {
|
||||||
is LoadingNewSate) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (countNum > 0) {
|
if (countNum > 0) {
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc.add(SetCounterValue(
|
||||||
SetCounterValue(
|
deviceCode: deviceCode,
|
||||||
deviceCode:
|
duration: Duration.zero));
|
||||||
deviceCode,
|
} else if (duration != Duration.zero) {
|
||||||
duration: Duration
|
waterHeaterBloc.add(SetCounterValue(
|
||||||
.zero));
|
deviceCode: deviceCode,
|
||||||
} else if (duration !=
|
duration: duration));
|
||||||
Duration.zero) {
|
|
||||||
waterHeaterBloc.add(
|
|
||||||
SetCounterValue(
|
|
||||||
deviceCode:
|
|
||||||
deviceCode,
|
|
||||||
duration:
|
|
||||||
duration));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(countNum > 0
|
||||||
countNum > 0
|
? Assets.pauseIcon
|
||||||
? Assets.pauseIcon
|
: Assets.playIcon)),
|
||||||
: Assets.playIcon)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
child: waterHeaterBloc.createSchedule ==
|
child: waterHeaterBloc.createSchedule == true
|
||||||
true
|
|
||||||
? CreateSchedule(
|
? CreateSchedule(
|
||||||
onToggleChanged: (bool isOn) {
|
onToggleChanged: (bool isOn) {
|
||||||
waterHeaterBloc
|
waterHeaterBloc.toggleSchedule = isOn;
|
||||||
.toggleSchedule = isOn;
|
|
||||||
},
|
},
|
||||||
onDateTimeChanged:
|
onDateTimeChanged: (DateTime dateTime) {
|
||||||
(DateTime dateTime) {
|
waterHeaterBloc.selectedTime = dateTime;
|
||||||
waterHeaterBloc.selectedTime =
|
|
||||||
dateTime;
|
|
||||||
},
|
},
|
||||||
days: waterHeaterBloc.days,
|
days: waterHeaterBloc.days,
|
||||||
selectDays: (List<String>
|
selectDays: (List<String> selectedDays) {
|
||||||
selectedDays) {
|
waterHeaterBloc.selectedDays = selectedDays;
|
||||||
waterHeaterBloc.selectedDays =
|
|
||||||
selectedDays;
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: Padding(
|
: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(top: 10),
|
||||||
top: 10),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ScheduleListView(
|
child: ScheduleListView(
|
||||||
listSchedule:
|
listSchedule: waterHeaterBloc
|
||||||
waterHeaterBloc
|
.listSchedule, // Pass the schedule list here
|
||||||
.listSchedule, // Pass the schedule list here
|
onDismissed: (scheduleId) {
|
||||||
onDismissed:
|
waterHeaterBloc.listSchedule.removeWhere(
|
||||||
(scheduleId) {
|
(schedule) =>
|
||||||
waterHeaterBloc
|
schedule.scheduleId ==
|
||||||
.listSchedule
|
scheduleId);
|
||||||
.removeWhere(
|
|
||||||
(schedule) =>
|
|
||||||
schedule
|
|
||||||
.scheduleId ==
|
|
||||||
scheduleId);
|
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc.add(
|
||||||
DeleteScheduleEvent(
|
DeleteScheduleEvent(id: scheduleId));
|
||||||
id: scheduleId));
|
|
||||||
},
|
},
|
||||||
onToggleSchedule:
|
onToggleSchedule: (scheduleId, isEnabled) {
|
||||||
(scheduleId,
|
waterHeaterBloc.add(ToggleScheduleEvent(
|
||||||
isEnabled) {
|
|
||||||
waterHeaterBloc.add(
|
|
||||||
ToggleScheduleEvent(
|
|
||||||
id: scheduleId,
|
id: scheduleId,
|
||||||
toggle: isEnabled,
|
toggle: isEnabled,
|
||||||
));
|
));
|
||||||
@ -437,56 +359,39 @@ class WHTimerScheduleScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment:
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
CrossAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
waterHeaterBloc.createCirculate ==
|
waterHeaterBloc.createCirculate == true
|
||||||
true
|
|
||||||
? CirculateWidget(
|
? CirculateWidget(
|
||||||
endDuration: () {
|
endDuration: () {
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc.add(SelectTimeEvent(
|
||||||
SelectTimeEvent(
|
context: context, isEffective: false));
|
||||||
context: context,
|
|
||||||
isEffective:
|
|
||||||
false));
|
|
||||||
},
|
},
|
||||||
startDuration: () {
|
startDuration: () {
|
||||||
waterHeaterBloc.add(
|
waterHeaterBloc.add(SelectTimeEvent(
|
||||||
SelectTimeEvent(
|
context: context, isEffective: false));
|
||||||
context: context,
|
|
||||||
isEffective:
|
|
||||||
false));
|
|
||||||
},
|
},
|
||||||
isStartEndTime: true,
|
isStartEndTime: true,
|
||||||
startTime: DateTime.now(),
|
startTime: DateTime.now(),
|
||||||
endTime: DateTime.now(),
|
endTime: DateTime.now(),
|
||||||
days: waterHeaterBloc.days,
|
days: waterHeaterBloc.days,
|
||||||
selectedDays: [],
|
selectedDays: [],
|
||||||
onToggleStartEndTime:
|
onToggleStartEndTime: (c) {},
|
||||||
(c) {},
|
|
||||||
onTimeChanged: (x, f) {},
|
onTimeChanged: (x, f) {},
|
||||||
onDaySelected: (p0) {},
|
onDaySelected: (p0) {},
|
||||||
)
|
)
|
||||||
: CirculateListView(
|
: CirculateListView(
|
||||||
listSchedule: [], // Pass the schedule list here
|
listSchedule: [], // Pass the schedule list here
|
||||||
onDismissed: (scheduleId) {
|
onDismissed: (scheduleId) {
|
||||||
|
waterHeaterBloc.listSchedule.removeWhere(
|
||||||
|
(schedule) =>
|
||||||
|
schedule.scheduleId == scheduleId);
|
||||||
waterHeaterBloc
|
waterHeaterBloc
|
||||||
.listSchedule
|
.add(DeleteScheduleEvent(id: scheduleId));
|
||||||
.removeWhere((schedule) =>
|
|
||||||
schedule
|
|
||||||
.scheduleId ==
|
|
||||||
scheduleId);
|
|
||||||
waterHeaterBloc.add(
|
|
||||||
DeleteScheduleEvent(
|
|
||||||
id: scheduleId));
|
|
||||||
},
|
},
|
||||||
onToggleSchedule:
|
onToggleSchedule: (scheduleId, isEnabled) {
|
||||||
(scheduleId,
|
waterHeaterBloc.add(ToggleScheduleEvent(
|
||||||
isEnabled) {
|
|
||||||
waterHeaterBloc.add(
|
|
||||||
ToggleScheduleEvent(
|
|
||||||
id: scheduleId,
|
id: scheduleId,
|
||||||
toggle: isEnabled,
|
toggle: isEnabled,
|
||||||
));
|
));
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_event.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/water_heater_bloc/water_heater_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/GroupWHModel.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/water_heater/wh_list.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
|
||||||
|
class WHWizard extends StatelessWidget {
|
||||||
|
const WHWizard({super.key, this.device});
|
||||||
|
|
||||||
|
final DeviceModel? device;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<GroupWHModel> groupModel = [];
|
||||||
|
|
||||||
|
return DefaultScaffold(
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
WaterHeaterBloc(switchCode: '', whId: device?.uuid ?? '')..add(InitialWizardEvent()),
|
||||||
|
child: BlocBuilder<WaterHeaterBloc, WaterHeaterState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
bool allSwitchesOn = false;
|
||||||
|
|
||||||
|
if (state is UpdateGroupState) {
|
||||||
|
groupModel = state.twoGangList;
|
||||||
|
allSwitchesOn = state.allSwitches;
|
||||||
|
}
|
||||||
|
return state is WHLoadingState
|
||||||
|
? const Center(
|
||||||
|
child:
|
||||||
|
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||||
|
)
|
||||||
|
: WHList(
|
||||||
|
whList: groupModel,
|
||||||
|
allSwitches: allSwitchesOn,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,9 +2,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
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/view/widgets/ACs/acs_view.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_wizard.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_wizard.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_wizard.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/water_heater/wh_wizard.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/text_widgets/body_large.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
import 'package:syncrow_app/utils/context_extension.dart';
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
@ -32,26 +33,36 @@ class WizardPage extends StatelessWidget {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => const ACsView()));
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
|
const ACsView()));
|
||||||
}
|
}
|
||||||
if (groupsList[index].name == '3G') {
|
if (groupsList[index].name == '3G') {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) =>
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
const ThreeGangInterface()));
|
const ThreeGangWizard()));
|
||||||
}
|
}
|
||||||
if (groupsList[index].name == '2G') {
|
if (groupsList[index].name == '2G') {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => const TwoGangInterface()));
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
|
const TwoGangWizard()));
|
||||||
}
|
}
|
||||||
if (groupsList[index].name == '1G') {
|
if (groupsList[index].name == '1G') {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
PageRouteBuilder(
|
PageRouteBuilder(
|
||||||
pageBuilder: (context, animation1, animation2) => const OneGangInterface()));
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
|
const OneGangWizard()));
|
||||||
|
}
|
||||||
|
if (groupsList[index].name == 'WH') {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
PageRouteBuilder(
|
||||||
|
pageBuilder: (context, animation1, animation2) =>
|
||||||
|
const WHWizard()));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: DefaultContainer(
|
child: DefaultContainer(
|
||||||
|
|||||||
@ -81,8 +81,7 @@ abstract class ApiEndpoints {
|
|||||||
static const String controlGroup = '/group/control';
|
static const String controlGroup = '/group/control';
|
||||||
//GET
|
//GET
|
||||||
static const String groupBySpace = '/group/{unitUuid}';
|
static const String groupBySpace = '/group/{unitUuid}';
|
||||||
static const String devicesByGroupName =
|
static const String devicesByGroupName = '/group/{unitUuid}/devices/{groupName}';
|
||||||
'/group/{unitUuid}/devices/{groupName}';
|
|
||||||
|
|
||||||
static const String groupByUuid = '/group/{groupUuid}';
|
static const String groupByUuid = '/group/{groupUuid}';
|
||||||
//DELETE
|
//DELETE
|
||||||
@ -94,8 +93,7 @@ abstract class ApiEndpoints {
|
|||||||
static const String addDeviceToRoom = '/device/room';
|
static const String addDeviceToRoom = '/device/room';
|
||||||
static const String addDeviceToGroup = '/device/group';
|
static const String addDeviceToGroup = '/device/group';
|
||||||
static const String controlDevice = '/device/{deviceUuid}/control';
|
static const String controlDevice = '/device/{deviceUuid}/control';
|
||||||
static const String firmwareDevice =
|
static const String firmwareDevice = '/device/{deviceUuid}/firmware/{firmwareVersion}';
|
||||||
'/device/{deviceUuid}/firmware/{firmwareVersion}';
|
|
||||||
static const String getDevicesByUserId = '/device/user/{userId}';
|
static const String getDevicesByUserId = '/device/user/{userId}';
|
||||||
static const String getDevicesByUnitId = '/device/unit/{unitUuid}';
|
static const String getDevicesByUnitId = '/device/unit/{unitUuid}';
|
||||||
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
||||||
@ -105,8 +103,7 @@ abstract class ApiEndpoints {
|
|||||||
static const String deviceByUuid = '/device/{deviceUuid}';
|
static const String deviceByUuid = '/device/{deviceUuid}';
|
||||||
static const String deviceFunctions = '/device/{deviceUuid}/functions';
|
static const String deviceFunctions = '/device/{deviceUuid}/functions';
|
||||||
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
||||||
static const String deviceFunctionsStatus =
|
static const String deviceFunctionsStatus = '/device/{deviceUuid}/functions/status';
|
||||||
'/device/{deviceUuid}/functions/status';
|
|
||||||
|
|
||||||
///Device Permission Module
|
///Device Permission Module
|
||||||
//POST
|
//POST
|
||||||
@ -131,29 +128,24 @@ abstract class ApiEndpoints {
|
|||||||
|
|
||||||
static const String getUnitAutomation = '/automation/{unitUuid}';
|
static const String getUnitAutomation = '/automation/{unitUuid}';
|
||||||
|
|
||||||
static const String getAutomationDetails =
|
static const String getAutomationDetails = '/automation/details/{automationId}';
|
||||||
'/automation/details/{automationId}';
|
|
||||||
|
|
||||||
/// PUT
|
/// PUT
|
||||||
static const String updateScene = '/scene/tap-to-run/{sceneId}';
|
static const String updateScene = '/scene/tap-to-run/{sceneId}';
|
||||||
|
|
||||||
static const String updateAutomation = '/automation/{automationId}';
|
static const String updateAutomation = '/automation/{automationId}';
|
||||||
|
|
||||||
static const String updateAutomationStatus =
|
static const String updateAutomationStatus = '/automation/status/{automationId}';
|
||||||
'/automation/status/{automationId}';
|
|
||||||
|
|
||||||
/// DELETE
|
/// DELETE
|
||||||
static const String deleteScene = '/scene/tap-to-run/{unitUuid}/{sceneId}';
|
static const String deleteScene = '/scene/tap-to-run/{unitUuid}/{sceneId}';
|
||||||
|
|
||||||
static const String deleteAutomation =
|
static const String deleteAutomation = '/automation/{unitUuid}/{automationId}';
|
||||||
'/automation/{unitUuid}/{automationId}';
|
|
||||||
|
|
||||||
//////////////////////Door Lock //////////////////////
|
//////////////////////Door Lock //////////////////////
|
||||||
//online
|
//online
|
||||||
static const String addTemporaryPassword =
|
static const String addTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
|
||||||
'/door-lock/temporary-password/online/{doorLockUuid}';
|
static const String getTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
|
||||||
static const String getTemporaryPassword =
|
|
||||||
'/door-lock/temporary-password/online/{doorLockUuid}';
|
|
||||||
|
|
||||||
//one-time offline
|
//one-time offline
|
||||||
static const String addOneTimeTemporaryPassword =
|
static const String addOneTimeTemporaryPassword =
|
||||||
@ -185,9 +177,11 @@ abstract class ApiEndpoints {
|
|||||||
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
||||||
|
|
||||||
static const String saveSchedule = '/schedule/{deviceUuid}';
|
static const String saveSchedule = '/schedule/{deviceUuid}';
|
||||||
static const String getSchedule =
|
static const String getSchedule = '/schedule/{deviceUuid}?category={category}';
|
||||||
'/schedule/{deviceUuid}?category={category}';
|
|
||||||
static const String changeSchedule = '/schedule/enable/{deviceUuid}';
|
static const String changeSchedule = '/schedule/enable/{deviceUuid}';
|
||||||
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
|
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
|
||||||
static const String reportLogs = '/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
static const String reportLogs =
|
||||||
|
'/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
||||||
|
static const String controlBatch = '/device/control/batch';
|
||||||
|
static const String statusBatch = '/device/status/batch';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,8 +72,7 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.deviceFunctionsStatus
|
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
|
||||||
.replaceAll('{deviceUuid}', deviceId),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -83,9 +82,7 @@ class DevicesAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String, dynamic>> renamePass(
|
static Future<Map<String, dynamic>> renamePass(
|
||||||
{required String name,
|
{required String name, required String doorLockUuid, required String passwordId}) async {
|
||||||
required String doorLockUuid,
|
|
||||||
required String passwordId}) async {
|
|
||||||
final response = await _httpService.put(
|
final response = await _httpService.put(
|
||||||
path: ApiEndpoints.renamePassword
|
path: ApiEndpoints.renamePassword
|
||||||
.replaceAll('{doorLockUuid}', doorLockUuid)
|
.replaceAll('{doorLockUuid}', doorLockUuid)
|
||||||
@ -110,8 +107,7 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDeviceByGroupName(
|
static Future<List<DeviceModel>> getDeviceByGroupName(String unitId, String groupName) async {
|
||||||
String unitId, String groupName) async {
|
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.devicesByGroupName
|
path: ApiEndpoints.devicesByGroupName
|
||||||
.replaceAll('{unitUuid}', unitId)
|
.replaceAll('{unitUuid}', unitId)
|
||||||
@ -150,8 +146,7 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
|
||||||
String gatewayId) async {
|
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
@ -173,8 +168,7 @@ class DevicesAPI {
|
|||||||
String deviceId,
|
String deviceId,
|
||||||
) async {
|
) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getTemporaryPassword
|
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
.replaceAll('{doorLockUuid}', deviceId),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -185,8 +179,7 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future getOneTimePasswords(String deviceId) async {
|
static Future getOneTimePasswords(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getOneTimeTemporaryPassword
|
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
.replaceAll('{doorLockUuid}', deviceId),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -197,8 +190,7 @@ class DevicesAPI {
|
|||||||
|
|
||||||
static Future getTimeLimitPasswords(String deviceId) async {
|
static Future getTimeLimitPasswords(String deviceId) async {
|
||||||
final response = await _httpService.get(
|
final response = await _httpService.get(
|
||||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword
|
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
.replaceAll('{doorLockUuid}', deviceId),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -223,12 +215,10 @@ class DevicesAPI {
|
|||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
};
|
};
|
||||||
if (scheduleList != null) {
|
if (scheduleList != null) {
|
||||||
body["scheduleList"] =
|
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
scheduleList.map((schedule) => schedule.toJson()).toList();
|
|
||||||
}
|
}
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addTemporaryPassword
|
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
.replaceAll('{doorLockUuid}', deviceId),
|
|
||||||
body: body,
|
body: body,
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) => json,
|
expectedResponseModel: (json) => json,
|
||||||
@ -239,8 +229,7 @@ class DevicesAPI {
|
|||||||
static Future generateOneTimePassword({deviceId}) async {
|
static Future generateOneTimePassword({deviceId}) async {
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addOneTimeTemporaryPassword
|
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
.replaceAll('{doorLockUuid}', deviceId),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@ -252,12 +241,10 @@ class DevicesAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future generateMultiTimePassword(
|
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
|
||||||
{deviceId, effectiveTime, invalidTime}) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword
|
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||||
.replaceAll('{doorLockUuid}', deviceId),
|
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
@ -378,4 +365,34 @@ class DevicesAPI {
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future deviceBatchController({
|
||||||
|
List<String>? devicesUuid,
|
||||||
|
String? code,
|
||||||
|
bool? value,
|
||||||
|
}) async {
|
||||||
|
final response = await _httpService.post(
|
||||||
|
path: ApiEndpoints.controlBatch,
|
||||||
|
body: {"devicesUuid": devicesUuid, "code": code, "value": value},
|
||||||
|
showServerMessage: true,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future deviceBatchStatus({
|
||||||
|
List<String>? devicesUuid,
|
||||||
|
}) async {
|
||||||
|
final response = await _httpService.get(
|
||||||
|
path: ApiEndpoints.statusBatch,
|
||||||
|
queryParameters: {"devicesUuid": devicesUuid},
|
||||||
|
showServerMessage: false,
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user