Bug fixes

This commit is contained in:
Abdullah Alassaf
2024-09-23 00:35:07 +03:00
parent d97efe229d
commit 62e80c89a2
33 changed files with 1203 additions and 1192 deletions

View File

@ -26,11 +26,9 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
bool lowBattery = false; bool lowBattery = false;
bool closingReminder = false; bool closingReminder = false;
bool doorAlarm = false; bool doorAlarm = false;
DoorSensorModel deviceStatus = DoorSensorModel deviceStatus = DoorSensorModel(doorContactState: false, batteryPercentage: 0);
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
void _fetchWaterHeaterStatus( void _fetchWaterHeaterStatus(DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
emit(DoorSensorLoadingState()); emit(DoorSensorLoadingState());
try { try {
var response = await DevicesAPI.getDeviceStatus(DSId); var response = await DevicesAPI.getDeviceStatus(DSId);
@ -51,8 +49,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
} }
// Toggle functions for each switch // Toggle functions for each switch
void _toggleLowBattery( void _toggleLowBattery(ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus)); emit(LoadingNewSate(doorSensor: deviceStatus));
try { try {
lowBattery = event.isLowBatteryEnabled; lowBattery = event.isLowBatteryEnabled;
@ -93,8 +90,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
} }
} }
void _toggleDoorAlarm( void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus)); emit(LoadingNewSate(doorSensor: deviceStatus));
try { try {
doorAlarm = event.isDoorAlarmEnabled; doorAlarm = event.isDoorAlarmEnabled;
@ -114,11 +110,9 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
} }
} }
DeviceReport recordGroups = DeviceReport(startTime: 0, endTime: 0, data: []); DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []);
Future<void> fetchLogsForLastMonth(ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
// Get the current date and time // Get the current date and time
DateTime now = DateTime.now(); DateTime now = DateTime.now();
@ -130,8 +124,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
int endTime = now.millisecondsSinceEpoch; int endTime = now.millisecondsSinceEpoch;
try { try {
var response = await DevicesAPI.getReportLogs( var response = await DevicesAPI.getReportLogs(
startTime: startTime: startTime.toString(), // Convert to String if the API expects it
startTime.toString(), // Convert to String if the API expects it
endTime: endTime.toString(), // Convert to String if the API expects it endTime: endTime.toString(), // Convert to String if the API expects it
deviceUuid: DSId, deviceUuid: DSId,
code: 'doorcontact_state', code: 'doorcontact_state',
@ -149,16 +142,14 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
_listenToChanges() { _listenToChanges() {
try { try {
DatabaseReference ref = DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$DSId');
FirebaseDatabase.instance.ref('device-status/$DSId');
Stream<DatabaseEvent> stream = ref.onValue; Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async { stream.listen((DatabaseEvent event) async {
if (_timer != null) { if (_timer != null) {
await Future.delayed(const Duration(seconds: 2)); await Future.delayed(const Duration(seconds: 2));
} }
Map<dynamic, dynamic> usersMap = Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = []; List<StatusModel> statusList = [];
usersMap['status'].forEach((element) { usersMap['status'].forEach((element) {

View File

@ -34,9 +34,6 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
on<TickTimer>(_onTickTimer); on<TickTimer>(_onTickTimer);
on<OnClose>(_onClose); on<OnClose>(_onClose);
on<ToggleDaySelectionEvent>(toggleDaySelection); on<ToggleDaySelectionEvent>(toggleDaySelection);
on<ThreeGangSave>(saveSchedule); on<ThreeGangSave>(saveSchedule);
on<GetScheduleEvent>(getSchedule); on<GetScheduleEvent>(getSchedule);
@ -114,7 +111,6 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
} }
} }
void _changeSliding(ChangeSlidingSegment event, Emitter<OneGangState> emit) async { void _changeSliding(ChangeSlidingSegment event, Emitter<OneGangState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value)); emit(ChangeSlidingSegmentState(value: event.value));
} }
@ -199,11 +195,14 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
{"day": "Sat", "key": "Sat"}, {"day": "Sat", "key": "Sat"},
]; ];
Future<void> saveSchedule(ThreeGangSave event, Emitter<OneGangState> emit,) async { Future<void> saveSchedule(
ThreeGangSave event,
Emitter<OneGangState> emit,
) async {
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: oneGangId, deviceId: oneGangId,
time: getTimeStampWithoutSeconds(selectedTime).toString(), time: getTimeStampWithoutSeconds(selectedTime).toString(),
@ -222,8 +221,10 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
} }
} }
Future<void> getSchedule(
Future<void> getSchedule(GetScheduleEvent event, Emitter<OneGangState> emit,) async { GetScheduleEvent event,
Emitter<OneGangState> emit,
) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.getSchedule( final response = await DevicesAPI.getSchedule(
@ -242,13 +243,12 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) { int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null; if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, DateTime dateTimeWithoutSeconds =
dateTime.day, dateTime.hour, dateTime.minute); DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
} }
Future toggleChange( Future toggleChange(ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
ToggleScheduleEvent event, Emitter<OneGangState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule( final response = await DevicesAPI.changeSchedule(
@ -267,13 +267,13 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
} }
} }
Future deleteSchedule( Future deleteSchedule(DeleteScheduleEvent event, Emitter<OneGangState> emit) async {
DeleteScheduleEvent event, Emitter<OneGangState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule( final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id, scheduleId: event.id,
deviceUuid: oneGangId, ); deviceUuid: oneGangId,
);
if (response == true) { if (response == true) {
add(GetScheduleEvent()); add(GetScheduleEvent());
return toggleSchedule; return toggleSchedule;
@ -322,5 +322,4 @@ class OneGangBloc extends Bloc<OneGangEvent, OneGangState> {
selectedTabIndex = index; selectedTabIndex = index;
emit(ChangeSlidingSegmentState(value: selectedTabIndex)); emit(ChangeSlidingSegmentState(value: selectedTabIndex));
} }
} }

View File

@ -1,9 +1,8 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.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/two_gang_model.dart'; import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
class OneGangState extends Equatable { class OneGangState extends Equatable {
const OneGangState(); const OneGangState();
@ -32,13 +31,13 @@ class LoadingNewSate extends OneGangState {
} }
class UpdateGroupState extends OneGangState { class UpdateGroupState extends OneGangState {
final List<GroupTwoGangModel> twoGangList; final List<GroupOneGangModel> oneGangList;
final bool allSwitches; final bool allSwitches;
const UpdateGroupState({required this.twoGangList, required this.allSwitches}); const UpdateGroupState({required this.oneGangList, required this.allSwitches});
@override @override
List<Object> get props => [twoGangList, allSwitches]; List<Object> get props => [oneGangList, allSwitches];
} }
class FailedState extends OneGangState { class FailedState extends OneGangState {
@ -77,12 +76,16 @@ class TimerRunInProgress extends OneGangState {
} }
class TimerRunComplete extends OneGangState {} class TimerRunComplete extends OneGangState {}
class ThreeGangSaveSchedule extends OneGangState {} class ThreeGangSaveSchedule extends OneGangState {}
class IsToggleState extends OneGangState { class IsToggleState extends OneGangState {
final bool? onOff; final bool? onOff;
const IsToggleState({this.onOff}); const IsToggleState({this.onOff});
} }
class ChangeTimeState extends OneGangState {} class ChangeTimeState extends OneGangState {}
class UpdateCreateScheduleState extends OneGangState { class UpdateCreateScheduleState extends OneGangState {
final bool createSchedule; final bool createSchedule;
UpdateCreateScheduleState(this.createSchedule); UpdateCreateScheduleState(this.createSchedule);

View File

@ -14,7 +14,6 @@ import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/devices_api.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart'; import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> { class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
final String threeGangId; final String threeGangId;
final String switchCode; final String switchCode;
@ -51,8 +50,6 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
on<GroupAllOnEvent>(_groupAllOn); on<GroupAllOnEvent>(_groupAllOn);
on<GroupAllOffEvent>(_groupAllOff); on<GroupAllOffEvent>(_groupAllOff);
on<ToggleDaySelectionEvent>(toggleDaySelection); on<ToggleDaySelectionEvent>(toggleDaySelection);
on<ThreeGangSave>(saveSchedule); on<ThreeGangSave>(saveSchedule);
on<GetScheduleEvent>(getSchedule); on<GetScheduleEvent>(getSchedule);
@ -490,9 +487,6 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
} }
} }
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"},
@ -517,11 +511,14 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
add(ChangeSlidingSegment(value: 1)); add(ChangeSlidingSegment(value: 1));
} }
Future<void> saveSchedule(ThreeGangSave event, Emitter<ThreeGangState> emit,) async { Future<void> saveSchedule(
ThreeGangSave event,
Emitter<ThreeGangState> emit,
) async {
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: threeGangId, deviceId: threeGangId,
time: getTimeStampWithoutSeconds(selectedTime).toString(), time: getTimeStampWithoutSeconds(selectedTime).toString(),
@ -540,8 +537,10 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
} }
} }
Future<void> getSchedule(
Future<void> getSchedule(GetScheduleEvent event, Emitter<ThreeGangState> emit,) async { GetScheduleEvent event,
Emitter<ThreeGangState> emit,
) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.getSchedule( final response = await DevicesAPI.getSchedule(
@ -560,13 +559,12 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) { int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null; if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, DateTime dateTimeWithoutSeconds =
dateTime.day, dateTime.hour, dateTime.minute); DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
} }
Future toggleChange( Future toggleChange(ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
ToggleScheduleEvent event, Emitter<ThreeGangState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule( final response = await DevicesAPI.changeSchedule(
@ -585,13 +583,13 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
} }
} }
Future deleteSchedule( Future deleteSchedule(DeleteScheduleEvent event, Emitter<ThreeGangState> emit) async {
DeleteScheduleEvent event, Emitter<ThreeGangState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule( final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id, scheduleId: event.id,
deviceUuid: threeGangId, ); deviceUuid: threeGangId,
);
if (response == true) { if (response == true) {
add(GetScheduleEvent()); add(GetScheduleEvent());
return toggleSchedule; return toggleSchedule;
@ -627,5 +625,4 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
bool createSchedule = false; bool createSchedule = false;
List<ScheduleModel> listSchedule = []; List<ScheduleModel> listSchedule = [];
DateTime? selectedTime = DateTime.now(); DateTime? selectedTime = DateTime.now();
} }

View File

@ -7,7 +7,7 @@ import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.d
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_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/groupTwoGangModel.dart'; import 'package:syncrow_app/features/devices/model/group_two_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';
import 'package:syncrow_app/features/devices/model/two_gang_model.dart'; import 'package:syncrow_app/features/devices/model/two_gang_model.dart';
@ -54,7 +54,6 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
on<GetScheduleEvent>(getSchedule); on<GetScheduleEvent>(getSchedule);
on<ToggleScheduleEvent>(toggleRepeat); on<ToggleScheduleEvent>(toggleRepeat);
on<DeleteScheduleEvent>(deleteSchedule); on<DeleteScheduleEvent>(deleteSchedule);
} }
DateTime? selectedTime = DateTime.now(); DateTime? selectedTime = DateTime.now();
@ -67,6 +66,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
emit(UpdateCreateScheduleState(createSchedule)); emit(UpdateCreateScheduleState(createSchedule));
emit(ChangeSlidingSegmentState(value: 1)); emit(ChangeSlidingSegmentState(value: 1));
} }
int selectedTabIndex = 0; int selectedTabIndex = 0;
void toggleSelectedIndex(index) { void toggleSelectedIndex(index) {
@ -87,8 +87,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
HomeCubit.getInstance().selectedSpace?.id ?? '', '2G'); HomeCubit.getInstance().selectedSpace?.id ?? '', '2G');
for (int i = 0; i < devicesList.length; i++) { for (int i = 0; i < devicesList.length; i++) {
var response = var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? '');
List<StatusModel> statusModelList = []; List<StatusModel> statusModelList = [];
for (var status in response['status']) { for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status)); statusModelList.add(StatusModel.fromJson(status));
@ -111,8 +110,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
return true; return true;
}); });
} }
emit(UpdateGroupState( emit(UpdateGroupState(twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
twoGangList: groupTwoGangList, allSwitches: allSwitchesOn));
} else { } else {
var response = await DevicesAPI.getDeviceStatus(twoGangId); var response = await DevicesAPI.getDeviceStatus(twoGangId);
List<StatusModel> statusModelList = []; List<StatusModel> statusModelList = [];
@ -131,21 +129,18 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
_listenToChanges() { _listenToChanges() {
try { try {
DatabaseReference ref = DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoGangId');
FirebaseDatabase.instance.ref('device-status/$twoGangId');
Stream<DatabaseEvent> stream = ref.onValue; Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async { stream.listen((DatabaseEvent event) async {
if (_timer != null) { if (_timer != null) {
await Future.delayed(const Duration(seconds: 2)); await Future.delayed(const Duration(seconds: 2));
} }
Map<dynamic, dynamic> usersMap = Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
event.snapshot.value as Map<dynamic, dynamic>;
List<StatusModel> statusList = []; List<StatusModel> statusList = [];
usersMap['status'].forEach((element) { usersMap['status'].forEach((element) {
statusList statusList.add(StatusModel(code: element['code'], value: element['value']));
.add(StatusModel(code: element['code'], value: element['value']));
}); });
deviceStatus = TwoGangModel.fromJson(statusList); deviceStatus = TwoGangModel.fromJson(statusList);
@ -160,8 +155,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
emit(UpdateState(twoGangModel: deviceStatus)); emit(UpdateState(twoGangModel: deviceStatus));
} }
void _changeFirstSwitch( void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
ChangeFirstSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus)); emit(LoadingNewSate(twoGangModel: deviceStatus));
try { try {
deviceStatus.firstSwitch = !event.value; deviceStatus.firstSwitch = !event.value;
@ -187,8 +181,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
} }
} }
void _changeSecondSwitch( void _changeSecondSwitch(ChangeSecondSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
ChangeSecondSwitchStatusEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus)); emit(LoadingNewSate(twoGangModel: deviceStatus));
try { try {
deviceStatus.secondSwitch = !event.value; deviceStatus.secondSwitch = !event.value;
@ -224,15 +217,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([ final response = await Future.wait([
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: twoGangId, deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
code: 'switch_1',
value: deviceStatus.firstSwitch),
twoGangId), twoGangId),
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: twoGangId, deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
code: 'switch_2',
value: deviceStatus.secondSwitch),
twoGangId), twoGangId),
]); ]);
@ -255,15 +244,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([ final response = await Future.wait([
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: twoGangId, deviceId: twoGangId, code: 'switch_1', value: deviceStatus.firstSwitch),
code: 'switch_1',
value: deviceStatus.firstSwitch),
twoGangId), twoGangId),
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: twoGangId, deviceId: twoGangId, code: 'switch_2', value: deviceStatus.secondSwitch),
code: 'switch_2',
value: deviceStatus.secondSwitch),
twoGangId), twoGangId),
]); ]);
if (response.every((element) => !element['success'])) { if (response.every((element) => !element['success'])) {
@ -289,15 +274,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([ final response = await Future.wait([
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId, deviceId: groupTwoGangList[i].deviceId, code: 'switch_1', value: true),
code: 'switch_1',
value: true),
groupTwoGangList[i].deviceId), groupTwoGangList[i].deviceId),
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId, deviceId: groupTwoGangList[i].deviceId, code: 'switch_2', value: true),
code: 'switch_2',
value: true),
groupTwoGangList[i].deviceId), groupTwoGangList[i].deviceId),
]); ]);
@ -326,15 +307,11 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
final response = await Future.wait([ final response = await Future.wait([
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId, deviceId: groupTwoGangList[i].deviceId, code: 'switch_1', value: false),
code: 'switch_1',
value: false),
groupTwoGangList[i].deviceId), groupTwoGangList[i].deviceId),
DevicesAPI.controlDevice( DevicesAPI.controlDevice(
DeviceControlModel( DeviceControlModel(
deviceId: groupTwoGangList[i].deviceId, deviceId: groupTwoGangList[i].deviceId, code: 'switch_2', value: false),
code: 'switch_2',
value: false),
groupTwoGangList[i].deviceId), groupTwoGangList[i].deviceId),
]); ]);
@ -350,29 +327,23 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
} }
} }
void _changeSliding( void _changeSliding(ChangeSlidingSegment event, Emitter<TwoGangState> emit) async {
ChangeSlidingSegment event, Emitter<TwoGangState> emit) async {
emit(ChangeSlidingSegmentState(value: event.value)); emit(ChangeSlidingSegmentState(value: event.value));
} }
void _setCounterValue( void _setCounterValue(SetCounterValue event, Emitter<TwoGangState> emit) async {
SetCounterValue event, Emitter<TwoGangState> emit) async {
emit(LoadingNewSate(twoGangModel: deviceStatus)); emit(LoadingNewSate(twoGangModel: 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( DeviceControlModel(deviceId: twoGangId, code: event.deviceCode, value: seconds),
deviceId: twoGangId,
code: event.deviceCode,
value: seconds),
twoGangId); twoGangId);
if (response['success'] ?? false) { if (response['success'] ?? false) {
if (event.deviceCode == 'countdown_1') { if (event.deviceCode == 'countdown_1') {
deviceStatus.firstCountDown = seconds; deviceStatus.firstCountDown = seconds;
} } else if (event.deviceCode == 'countdown_2') {
else if (event.deviceCode == 'countdown_2') {
deviceStatus.secondCountDown = seconds; deviceStatus.secondCountDown = seconds;
} }
} else { } else {
@ -391,8 +362,7 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
} }
} }
void _getCounterValue( void _getCounterValue(GetCounterEvent event, Emitter<TwoGangState> emit) async {
GetCounterEvent event, Emitter<TwoGangState> emit) async {
emit(LoadingInitialState()); emit(LoadingInitialState());
try { try {
add(GetScheduleEvent()); add(GetScheduleEvent());
@ -462,7 +432,10 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
add(ChangeSlidingSegment(value: 1)); add(ChangeSlidingSegment(value: 1));
} }
Future<void> saveSchedule(TwoGangSave event, Emitter<TwoGangState> emit,) async { Future<void> saveSchedule(
TwoGangSave event,
Emitter<TwoGangState> emit,
) async {
try { try {
if (selectedDays.isNotEmpty) { if (selectedDays.isNotEmpty) {
emit(LoadingInitialState()); emit(LoadingInitialState());
@ -485,7 +458,10 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
} }
} }
Future<void> getSchedule(GetScheduleEvent event, Emitter<TwoGangState> emit,) async { Future<void> getSchedule(
GetScheduleEvent event,
Emitter<TwoGangState> emit,
) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.getSchedule( final response = await DevicesAPI.getSchedule(
@ -504,19 +480,16 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
int? getTimeStampWithoutSeconds(DateTime? dateTime) { int? getTimeStampWithoutSeconds(DateTime? dateTime) {
if (dateTime == null) return null; if (dateTime == null) return null;
DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, DateTime dateTimeWithoutSeconds =
dateTime.day, dateTime.hour, dateTime.minute); DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute);
return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000;
} }
Future toggleRepeat( Future toggleRepeat(ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
ToggleScheduleEvent event, Emitter<TwoGangState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.changeSchedule( final response = await DevicesAPI.changeSchedule(
scheduleId: event.id, scheduleId: event.id, deviceUuid: twoGangId, enable: event.toggle);
deviceUuid: twoGangId,
enable: event.toggle);
if (response == true) { if (response == true) {
add(GetScheduleEvent()); add(GetScheduleEvent());
toggleSchedule = event.toggle; toggleSchedule = event.toggle;
@ -531,13 +504,13 @@ class TwoGangBloc extends Bloc<TwoGangEvent, TwoGangState> {
} }
} }
Future deleteSchedule( Future deleteSchedule(DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
DeleteScheduleEvent event, Emitter<TwoGangState> emit) async {
try { try {
emit(LoadingInitialState()); emit(LoadingInitialState());
final response = await DevicesAPI.deleteSchedule( final response = await DevicesAPI.deleteSchedule(
scheduleId: event.id, scheduleId: event.id,
deviceUuid: twoGangId, ); deviceUuid: twoGangId,
);
if (response == true) { if (response == true) {
add(GetScheduleEvent()); add(GetScheduleEvent());
return toggleSchedule; return toggleSchedule;

View File

@ -1,8 +1,7 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.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';
class TwoGangState extends Equatable { class TwoGangState extends Equatable {
const TwoGangState(); const TwoGangState();
@ -11,7 +10,9 @@ class TwoGangState extends Equatable {
} }
class InitialState extends TwoGangState {} class InitialState extends TwoGangState {}
class TwoGangSaveSchedule extends TwoGangState {} class TwoGangSaveSchedule extends TwoGangState {}
class ChangeTimeState extends TwoGangState {} class ChangeTimeState extends TwoGangState {}
class LoadingInitialState extends TwoGangState {} class LoadingInitialState extends TwoGangState {}
@ -78,13 +79,12 @@ class TimerRunInProgress extends TwoGangState {
} }
class TimerRunComplete extends TwoGangState {} class TimerRunComplete extends TwoGangState {}
class IsToggleState extends TwoGangState { class IsToggleState extends TwoGangState {
final bool? onOff; final bool? onOff;
const IsToggleState({this.onOff}); const IsToggleState({this.onOff});
} }
// two_gang_state.dart // two_gang_state.dart
class UpdateCreateScheduleState extends TwoGangState { class UpdateCreateScheduleState extends TwoGangState {
final bool createSchedule; final bool createSchedule;

View File

@ -1,7 +1,7 @@
class DeviceReport { class DeviceReport {
final String? deviceUuid; final String? deviceUuid;
final int? startTime; final String? startTime;
final int? endTime; final String? endTime;
final List<DeviceEvent>? data; final List<DeviceEvent>? data;
DeviceReport({ DeviceReport({
@ -13,8 +13,8 @@ class DeviceReport {
DeviceReport.fromJson(Map<String, dynamic> json) DeviceReport.fromJson(Map<String, dynamic> json)
: deviceUuid = json['deviceUuid'] as String?, : deviceUuid = json['deviceUuid'] as String?,
startTime = json['startTime'] as int?, startTime = json['startTime'] as String?,
endTime = json['endTime'] as int?, endTime = json['endTime'] as String?,
data = (json['data'] as List<dynamic>?) data = (json['data'] as List<dynamic>?)
?.map((e) => DeviceEvent.fromJson(e as Map<String, dynamic>)) ?.map((e) => DeviceEvent.fromJson(e as Map<String, dynamic>))
.toList(); .toList();

View File

@ -0,0 +1,11 @@
class GroupOneGangModel {
final String deviceId;
final String deviceName;
bool firstSwitch;
GroupOneGangModel({
required this.deviceId,
required this.deviceName,
required this.firstSwitch,
});
}

View File

@ -1,9 +1,6 @@
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/devices/bloc/devices_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/universal_switch.dart';
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 CurtainList extends StatelessWidget { class CurtainList extends StatelessWidget {

View File

@ -20,16 +20,16 @@ class CurtainView extends StatelessWidget {
child: BlocBuilder<CurtainBloc, CurtainState>( child: BlocBuilder<CurtainBloc, CurtainState>(
builder: (context, state) { builder: (context, state) {
double curtainWidth = 270; double curtainWidth = 270;
double blindHeight = 310; // double blindHeight = 310;
if (state is CurtainsOpening) { if (state is CurtainsOpening) {
curtainWidth = state.curtainWidth; curtainWidth = state.curtainWidth;
blindHeight = state.blindHeight; // blindHeight = state.blindHeight;
} else if (state is CurtainsClosing) { } else if (state is CurtainsClosing) {
curtainWidth = state.curtainWidth; curtainWidth = state.curtainWidth;
blindHeight = state.blindHeight; // blindHeight = state.blindHeight;
} else if (state is CurtainsPaused) { } else if (state is CurtainsPaused) {
curtainWidth = state.curtainWidth; curtainWidth = state.curtainWidth;
blindHeight = state.blindHeight; // blindHeight = state.blindHeight;
} }
return DefaultScaffold( return DefaultScaffold(
title: curtain.name, title: curtain.name,
@ -58,7 +58,8 @@ class CurtainView extends StatelessWidget {
width: curtainWidth, width: curtainWidth,
child: Stack( child: Stack(
children: List.generate( children: List.generate(
10, (index) { 10,
(index) {
double spacing = curtainWidth / 9; double spacing = curtainWidth / 9;
double leftMostPosition = index * spacing; double leftMostPosition = index * spacing;
return AnimatedPositioned( return AnimatedPositioned(

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/devices/view/widgets/popup_menu_widget.dart'; import 'package:syncrow_app/features/devices/view/widgets/popup_menu_widget.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';
@ -11,7 +10,8 @@ class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget {
final String deviceUuid; final String deviceUuid;
final double appBarHeight = 56.0; final double appBarHeight = 56.0;
final void Function()? onPressed; final void Function()? onPressed;
const DeviceAppbar({super.key, required this.deviceName, required this.deviceUuid,this.onPressed}); const DeviceAppbar(
{super.key, required this.deviceName, required this.deviceUuid, this.onPressed});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -19,12 +19,13 @@ class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget {
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
centerTitle: true, centerTitle: true,
title: BodyLarge( title: BodyLarge(
text: deviceName ?? "", text: deviceName,
fontColor: ColorsManager.primaryColor, fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold, fontWeight: FontsManager.bold,
), ),
actions: [ actions: [
IconButton(onPressed: () { IconButton(
onPressed: () {
showPopupMenu(context: context, items: [ showPopupMenu(context: context, items: [
PopupMenuItem( PopupMenuItem(
onTap: () async { onTap: () async {
@ -34,7 +35,8 @@ class DeviceAppbar extends StatelessWidget implements PreferredSizeWidget {
child: const Text('Update'), child: const Text('Update'),
) )
]); ]);
}, icon: Icon(Icons.edit)) },
icon: Icon(Icons.edit))
], ],
); );
} }

View File

@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart'; import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart'; import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
import 'package:syncrow_app/features/devices/model/door_sensor_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
@ -16,24 +15,15 @@ class NotificationSettingsPage extends StatelessWidget {
return DefaultScaffold( return DefaultScaffold(
title: 'Notification Settings', title: 'Notification Settings',
child: BlocProvider( child: BlocProvider(
create: (context) => create: (context) => DoorSensorBloc(DSId: '')..add(const DoorSensorInitial()),
DoorSensorBloc(DSId: '')..add(const DoorSensorInitial()),
child: BlocBuilder<DoorSensorBloc, DoorSensorState>( child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
builder: (context, state) { builder: (context, state) {
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context); final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
DoorSensorModel model = DoorSensorModel(
batteryPercentage: 0, doorContactState: false);
if (state is LoadingNewSate) {
model = state.doorSensor;
} else if (state is UpdateState) {
model = state.doorSensor;
}
return state is DoorSensorLoadingState return state is DoorSensorLoadingState
? const Center( ? const Center(
child: DefaultContainer( child: DefaultContainer(
width: 50, width: 50, height: 50, child: CircularProgressIndicator()),
height: 50,
child: CircularProgressIndicator()),
) )
: Column( : Column(
children: [ children: [
@ -56,8 +46,9 @@ class NotificationSettingsPage extends StatelessWidget {
child: CupertinoSwitch( child: CupertinoSwitch(
value: doorSensorBloc.lowBattery, value: doorSensorBloc.lowBattery,
onChanged: (value) { onChanged: (value) {
context.read<DoorSensorBloc>().add( context
ToggleLowBatteryEvent(value)); .read<DoorSensorBloc>()
.add(ToggleLowBatteryEvent(value));
}, },
applyTheme: true, applyTheme: true,
)), )),
@ -79,9 +70,9 @@ class NotificationSettingsPage extends StatelessWidget {
child: CupertinoSwitch( child: CupertinoSwitch(
value: doorSensorBloc.closingReminder, value: doorSensorBloc.closingReminder,
onChanged: (value) { onChanged: (value) {
context.read<DoorSensorBloc>().add( context
ToggleClosingReminderEvent( .read<DoorSensorBloc>()
value)); .add(ToggleClosingReminderEvent(value));
}, },
applyTheme: true, applyTheme: true,
)), )),

View File

@ -35,8 +35,7 @@ class DoorRecordsScreen extends StatelessWidget {
return DefaultScaffold( return DefaultScaffold(
title: 'Records', title: 'Records',
child: BlocProvider( child: BlocProvider(
create: (context) => create: (context) => DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
child: BlocBuilder<DoorSensorBloc, DoorSensorState>( child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
builder: (context, state) { builder: (context, state) {
if (state is DoorSensorLoadingState) { if (state is DoorSensorLoadingState) {
@ -49,12 +48,10 @@ class DoorRecordsScreen extends StatelessWidget {
); );
} }
if (state is UpdateState && state.doorSensor != null) { if (state is UpdateState) {
final recordGroups = context.read<DoorSensorBloc>().recordGroups; final recordGroups = context.read<DoorSensorBloc>().recordGroups;
if (recordGroups == null || if (recordGroups.data == null || recordGroups.data!.isEmpty) {
recordGroups.data == null ||
recordGroups.data!.isEmpty) {
return const Center(child: Text('No records available.')); return const Center(child: Text('No records available.'));
} }
@ -66,10 +63,8 @@ class DoorRecordsScreen extends StatelessWidget {
// Convert eventTime to a human-readable format // Convert eventTime to a human-readable format
final DateTime eventDateTime = final DateTime eventDateTime =
DateTime.fromMillisecondsSinceEpoch(record.eventTime!); DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
final String formattedDate = final String formattedDate = DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime); final String formattedTime = DateFormat('HH:mm:ss').format(eventDateTime);
final String formattedTime =
DateFormat('HH:mm:ss').format(eventDateTime);
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -92,9 +87,7 @@ class DoorRecordsScreen extends StatelessWidget {
record.value == 'true' record.value == 'true'
? Icons.radio_button_checked ? Icons.radio_button_checked
: Icons.radio_button_unchecked, : Icons.radio_button_unchecked,
color: record.value == 'true' color: record.value == 'true' ? Colors.blue : Colors.grey,
? Colors.blue
: Colors.grey,
), ),
title: Text( title: Text(
'Status: ${record.value}', 'Status: ${record.value}',

View File

@ -8,12 +8,10 @@ import 'package:syncrow_app/features/devices/bloc/gateway_bloc/gateway_state.dar
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/view/widgets/device_appbar.dart'; import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart'; import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
class GateWayView extends StatelessWidget { class GateWayView extends StatelessWidget {
final DeviceModel gatewayObj; final DeviceModel gatewayObj;
@ -40,7 +38,8 @@ class GateWayView extends StatelessWidget {
extendBody: true, extendBody: true,
appBar: DeviceAppbar( appBar: DeviceAppbar(
deviceName: 'Gateway', deviceName: 'Gateway',
deviceUuid: gatewayObj.uuid!,), deviceUuid: gatewayObj.uuid!,
),
body: Container( body: Container(
width: MediaQuery.sizeOf(context).width, width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height, height: MediaQuery.sizeOf(context).height,
@ -56,10 +55,10 @@ class GateWayView extends StatelessWidget {
), ),
child: RefreshIndicator( child: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
BlocProvider.of<GatewayBloc>(context).add(GatewayInitial(gatewayId: gatewayObj.uuid ?? '')); BlocProvider.of<GatewayBloc>(context)
.add(GatewayInitial(gatewayId: gatewayObj.uuid ?? ''));
}, },
child: ListView( child: ListView(
children: [ children: [
Container( Container(
height: MediaQuery.of(context).size.height, height: MediaQuery.of(context).size.height,
@ -120,7 +119,8 @@ class GateWayView extends StatelessWidget {
) )
: Expanded( : Expanded(
child: GridView.builder( child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
crossAxisSpacing: 10, crossAxisSpacing: 10,
mainAxisSpacing: 10, mainAxisSpacing: 10,
@ -141,8 +141,7 @@ class GateWayView extends StatelessWidget {
], ],
), ),
), ),
) )));
));
})); }));
} }
} }

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.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/view/widgets/lights/lights_list.dart'; import 'package:syncrow_app/features/devices/view/widgets/lights/lights_list.dart';
import 'package:syncrow_app/features/devices/view/widgets/universal_switch.dart'; import 'package:syncrow_app/features/devices/view/widgets/universal_switch.dart';

View File

@ -1,5 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -7,7 +5,6 @@ import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_blo
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart'; import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_event.dart';
import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart'; import 'package:syncrow_app/features/devices/bloc/smart_door_bloc/smart_door_state.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/repeat_widget.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/repeat_widget.dart';
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart'; import 'package:syncrow_app/features/shared_widgets/door_lock_button.dart';
@ -29,9 +26,7 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!), create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) { child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
if (state is FailedState) { if (state is FailedState) {
CustomSnackBar.displaySnackBar( CustomSnackBar.displaySnackBar(state.errorMessage);
state.errorMessage
);
} }
if (state is IsRepeatState) { if (state is IsRepeatState) {
isRepeat = state.repeat; isRepeat = state.repeat;
@ -54,8 +49,7 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
}, },
icon: const Icon(Icons.arrow_back) icon: const Icon(Icons.arrow_back)),
),
), ),
child: state is LoadingInitialState child: state is LoadingInitialState
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
@ -65,7 +59,8 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const BodyMedium( const BodyMedium(
text: 'Save the password immediately. The password is not displayed in the app.', text:
'Save the password immediately. The password is not displayed in the app.',
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontColor: ColorsManager.grayColor, fontColor: ColorsManager.grayColor,
), ),
@ -88,21 +83,22 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
Flexible( Flexible(
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children:smartDoorBloc.passwordController.text.isEmpty? children: smartDoorBloc.passwordController.text.isEmpty
List.generate(10, (index) { ? List.generate(10, (index) {
return const Padding( return const Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0,vertical: 15), padding: EdgeInsets.symmetric(
horizontal: 4.0, vertical: 15),
child: Icon( child: Icon(
Icons.circle, Icons.circle,
size: 20.0, size: 20.0,
color: Colors.black, color: Colors.black,
), ),
); );
}) :[ })
: [
Expanded( Expanded(
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
child: BodyLarge( child: BodyLarge(
style: const TextStyle( style: const TextStyle(
@ -114,15 +110,15 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
textAlign: TextAlign.center, textAlign: TextAlign.center,
text: smartDoorBloc.passwordController.text, text: smartDoorBloc.passwordController.text,
fontSize: 23, fontSize: 23,
),), ),
),
IconButton( IconButton(
onPressed: () async { onPressed: () async {
await Clipboard.setData(ClipboardData( await Clipboard.setData(ClipboardData(
text: smartDoorBloc.passwordController.text)); text: smartDoorBloc
.passwordController.text));
}, },
icon: const Icon(Icons.copy) icon: const Icon(Icons.copy)),
),
], ],
), ),
), ),
@ -131,7 +127,6 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
const SizedBox( const SizedBox(
width: 10, width: 10,
), ),
], ],
), ),
if (smartDoorBloc.passwordController.text.isNotEmpty) if (smartDoorBloc.passwordController.text.isNotEmpty)
@ -155,7 +150,8 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
SizedBox( SizedBox(
width: MediaQuery.of(context).size.width / 2.6, width: MediaQuery.of(context).size.width / 2.6,
child: TextFormField( child: TextFormField(
controller: BlocProvider.of<SmartDoorBloc>(context).passwordNameController, controller: BlocProvider.of<SmartDoorBloc>(context)
.passwordNameController,
decoration: const InputDecoration( decoration: const InputDecoration(
hintText: 'Enter The Name', hintText: 'Enter The Name',
hintStyle: TextStyle( hintStyle: TextStyle(
@ -163,7 +159,6 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
)), )),
], ],
), ),
], ],
), ),
], ],
@ -174,7 +169,8 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
), ),
const BodyMedium( const BodyMedium(
textAlign: TextAlign.center, textAlign: TextAlign.center,
text: 'Save the password immediately. The password is not displayed in the app.', text:
'Save the password immediately. The password is not displayed in the app.',
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontColor: ColorsManager.grayColor, fontColor: ColorsManager.grayColor,
), ),
@ -193,7 +189,8 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
backgroundColor: ColorsManager.primaryColor, backgroundColor: ColorsManager.primaryColor,
onPressed: () async { onPressed: () async {
if (generated == false) { if (generated == false) {
smartDoorBloc.add(GenerateAndSavePasswordOneTimeEvent(context: context)); smartDoorBloc
.add(GenerateAndSavePasswordOneTimeEvent(context: context));
} else { } else {
if (smartDoorBloc.passwordNameController.text.isNotEmpty) { if (smartDoorBloc.passwordNameController.text.isNotEmpty) {
smartDoorBloc.add(RenamePasswordEvent()); smartDoorBloc.add(RenamePasswordEvent());
@ -205,7 +202,8 @@ class OfflineOneTimePasswordPage extends StatelessWidget {
text: 'Obtain Password', text: 'Obtain Password',
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontColor: Colors.white, fontColor: Colors.white,
),), ),
),
), ),
), ),
const SizedBox( const SizedBox(

View File

@ -3,7 +3,6 @@ import 'package:flutter/services.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/view/widgets/device_appbar.dart'; import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_screen.dart'; import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_screen.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/generated/assets.dart'; import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart';

View File

@ -0,0 +1,66 @@
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/group_one_gang_model.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 OneGangList extends StatelessWidget {
const OneGangList({super.key, required this.oneGangList, required this.allSwitches});
final List<GroupOneGangModel> oneGangList;
final bool allSwitches;
@override
Widget build(BuildContext context) {
return BlocBuilder<OneGangBloc, OneGangState>(
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<OneGangBloc>(context).add(GroupAllOnEvent());
},
secondAction: () {
BlocProvider.of<OneGangBloc>(context).add(GroupAllOffEvent());
},
),
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(0),
itemCount: oneGangList.length,
itemBuilder: (context, index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
BodySmall(text: oneGangList[index].deviceName),
const SizedBox(height: 5),
DevicesDefaultSwitch(
switchValue: oneGangList[index].firstSwitch,
action: () {
BlocProvider.of<OneGangBloc>(context).add(ChangeFirstSwitchStatusEvent(
value: oneGangList[index].firstSwitch,
deviceId: oneGangList[index].deviceId));
},
),
],
);
},
),
],
),
);
},
);
}
}

View File

@ -3,7 +3,9 @@ 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';
@ -20,9 +22,7 @@ class OneGangScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => OneGangBloc( create: (context) => OneGangBloc(switchCode: 'switch_1', oneGangId: device?.uuid ?? '')
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) {
@ -31,17 +31,25 @@ 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: child:
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()), DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
): )
RefreshIndicator( : device == null
? OneGangList(oneGangList: groupOneGangModel, allSwitches: allSwitchesOn)
: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
BlocProvider.of<OneGangBloc>(context) BlocProvider.of<OneGangBloc>(context)
.add(InitialEvent(groupScreen: device != null ? false : true)); .add(InitialEvent(groupScreen: device != null ? false : true));
@ -106,7 +114,9 @@ class OneGangScreen extends StatelessWidget {
Navigator.push( Navigator.push(
context, context,
PageRouteBuilder( PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => TimerScheduleScreen( pageBuilder:
(context, animation1, animation2) =>
TimerScheduleScreen(
switchCode: 'switch_1', switchCode: 'switch_1',
device: device!, device: device!,
deviceCode: 'countdown_1', deviceCode: 'countdown_1',
@ -152,7 +162,6 @@ class OneGangScreen extends StatelessWidget {
), ),
], ],
), ),
], ],
), ),
), ),
@ -166,6 +175,5 @@ class OneGangScreen extends StatelessWidget {
}, },
), ),
); );
} }
} }

View File

@ -1,6 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/room_model.dart'; import 'package:syncrow_app/features/devices/model/room_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart'; import 'package:syncrow_app/features/devices/view/widgets/room_page_switch.dart';

View File

@ -23,7 +23,7 @@ class CreateTemporaryPassword extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool isRepeat = false; bool isRepeat = false;
bool generated = false; // bool generated = false;
return BlocProvider( return BlocProvider(
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!), create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!),
child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) { child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
@ -39,7 +39,7 @@ class CreateTemporaryPassword extends StatelessWidget {
isRepeat = state.repeat; isRepeat = state.repeat;
} }
if (state is GeneratePasswordOneTimestate) { if (state is GeneratePasswordOneTimestate) {
generated = state.generated; // generated = state.generated;
} }
}, builder: (context, state) { }, builder: (context, state) {
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context); final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
@ -56,17 +56,16 @@ class CreateTemporaryPassword extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.of(context).pop(true); Navigator.of(context).pop(true);
}, },
icon: const Icon(Icons.arrow_back) icon: const Icon(Icons.arrow_back)),
), actions: type == 'Online Password'
actions: ? [
type == 'Online Password'?[
TextButton( TextButton(
onPressed: () { onPressed: () {
smartDoorBloc.add(SavePasswordEvent(context: context)); smartDoorBloc.add(SavePasswordEvent(context: context));
}, },
child: const Text('Save') child: const Text('Save'))
) ]
]:null, : null,
), ),
child: state is LoadingInitialState child: state is LoadingInitialState
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
@ -76,7 +75,8 @@ class CreateTemporaryPassword extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const BodyMedium( const BodyMedium(
text: 'Save the password immediately. The password is not displayed in the app.', text:
'Save the password immediately. The password is not displayed in the app.',
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontColor: ColorsManager.grayColor, fontColor: ColorsManager.grayColor,
), ),
@ -91,7 +91,8 @@ class CreateTemporaryPassword extends StatelessWidget {
DefaultContainer( DefaultContainer(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: type == 'Online Password'?0:25), padding: EdgeInsets.symmetric(
horizontal: type == 'Online Password' ? 0 : 25),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@ -102,7 +103,8 @@ class CreateTemporaryPassword extends StatelessWidget {
onCompleted: (value) { onCompleted: (value) {
if (value.split('').every((char) => char == '1')) { if (value.split('').every((char) => char == '1')) {
smartDoorBloc.passwordController.clear(); smartDoorBloc.passwordController.clear();
CustomSnackBar.displaySnackBar('All characters cannot be 1.'); CustomSnackBar.displaySnackBar(
'All characters cannot be 1.');
} }
}, },
autoDisposeControllers: false, autoDisposeControllers: false,
@ -150,11 +152,10 @@ class CreateTemporaryPassword extends StatelessWidget {
if (smartDoorBloc.passwordController.text.isNotEmpty) if (smartDoorBloc.passwordController.text.isNotEmpty)
TextButton( TextButton(
onPressed: () async { onPressed: () async {
await Clipboard.setData(ClipboardData( await Clipboard.setData(
text: smartDoorBloc.passwordController.text)); ClipboardData(text: smartDoorBloc.passwordController.text));
}, },
child: const Text('Copy') child: const Text('Copy')),
),
const SizedBox( const SizedBox(
height: 20, height: 20,
), ),

View File

@ -31,16 +31,18 @@ class DoorDialogState extends State<DoorDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final effectiveTime = widget.temporaryPassword?.effectiveTime ??int.parse( widget.offline?.gmtStart); final effectiveTime =
final invalidTime = widget.temporaryPassword?.invalidTime ?? int.parse(widget.offline?.gmtExpired); widget.temporaryPassword?.effectiveTime ?? int.parse(widget.offline?.gmtStart);
final invalidTime =
widget.temporaryPassword?.invalidTime ?? int.parse(widget.offline?.gmtExpired);
final DateTime effectiveDateTime = final DateTime effectiveDateTime =
DateTime.fromMillisecondsSinceEpoch(effectiveTime! * 1000, isUtc: false); DateTime.fromMillisecondsSinceEpoch(effectiveTime * 1000, isUtc: false);
String formattedDateEffectiveTime = DateFormat('yyyy-MM-dd').format(effectiveDateTime); String formattedDateEffectiveTime = DateFormat('yyyy-MM-dd').format(effectiveDateTime);
String formattedTimeEffectiveTime = DateFormat('hh:mm a').format(effectiveDateTime); String formattedTimeEffectiveTime = DateFormat('hh:mm a').format(effectiveDateTime);
final DateTime expiredDateTime = final DateTime expiredDateTime =
DateTime.fromMillisecondsSinceEpoch(invalidTime! * 1000, isUtc: false); DateTime.fromMillisecondsSinceEpoch(invalidTime * 1000, isUtc: false);
String formattedDateExpiredDateTime = DateFormat('yyyy-MM-dd').format(expiredDateTime); String formattedDateExpiredDateTime = DateFormat('yyyy-MM-dd').format(expiredDateTime);
String formattedTimeExpiredDateTime = DateFormat('hh:mm a').format(expiredDateTime); String formattedTimeExpiredDateTime = DateFormat('hh:mm a').format(expiredDateTime);
return Dialog( return Dialog(
@ -116,8 +118,8 @@ class DoorDialogState extends State<DoorDialog> {
width: double.infinity, width: double.infinity,
color: ColorsManager.greyColor, color: ColorsManager.greyColor,
), ),
widget.temporaryPassword?.effectiveTime!=null? widget.temporaryPassword?.effectiveTime != null
Row( ? Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
InkWell( InkWell(
@ -143,13 +145,14 @@ class DoorDialogState extends State<DoorDialog> {
child: Center( child: Center(
child: BodyMedium( child: BodyMedium(
text: 'Delete Password', text: 'Delete Password',
style: context.bodyMedium.copyWith(color: ColorsManager.primaryColorWithOpacity), style: context.bodyMedium
.copyWith(color: ColorsManager.primaryColorWithOpacity),
), ),
), ),
), ),
], ],
): )
Row( : Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
Container( Container(
@ -165,9 +168,7 @@ class DoorDialogState extends State<DoorDialog> {
), ),
), ),
), ),
), ),
], ],
) )
], ],

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/members_management_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/members_management_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/smart_linkage_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/smart_linkage_view.dart';
@ -10,9 +9,8 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart
import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/generated/assets.dart';
class DoorLockGrid extends StatelessWidget { class DoorLockGrid extends StatelessWidget {
String uuid; final String uuid;
DoorLockGrid({ const DoorLockGrid({super.key, required this.uuid});
super.key,required this.uuid});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -14,14 +14,17 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class OnetimePasswordPage extends StatelessWidget { class OnetimePasswordPage extends StatelessWidget {
final String? deviceId; final String? deviceId;
const OnetimePasswordPage({super.key, this.deviceId,}); const OnetimePasswordPage({
super.key,
this.deviceId,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialOneTimePassword( )), create: (BuildContext context) =>
child: BlocConsumer<SmartDoorBloc, SmartDoorState>( SmartDoorBloc(deviceId: deviceId!)..add(InitialOneTimePassword()),
listener: (context, state) { child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
if (state is FailedState) { if (state is FailedState) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
@ -30,25 +33,26 @@ class OnetimePasswordPage extends StatelessWidget {
), ),
); );
} }
}, }, builder: (context, state) {
builder: (context, state) {
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context); final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
return DefaultScaffold( return DefaultScaffold(
title: 'Passwords', title: 'Passwords',
actions: [ actions: [
IconButton( IconButton(
onPressed: () { onPressed: () {
Navigator.of(context).push( Navigator.of(context)
MaterialPageRoute(builder: (context) => OfflineOneTimePasswordPage(deviceId: deviceId, ) .push(MaterialPageRoute(
)).then((result) { builder: (context) => OfflineOneTimePasswordPage(
deviceId: deviceId,
)))
.then((result) {
if (result != null) { if (result != null) {
smartDoorBloc.add(InitialOneTimePassword()); smartDoorBloc.add(InitialOneTimePassword());
smartDoorBloc.add(InitialOneTimePassword()); smartDoorBloc.add(InitialOneTimePassword());
} }
}); });
}, },
icon: const Icon(Icons.add) icon: const Icon(Icons.add))
)
], ],
child: Builder( child: Builder(
builder: (context) { builder: (context) {
@ -62,16 +66,18 @@ class OnetimePasswordPage extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.all(5.0), padding: const EdgeInsets.all(5.0),
child: DefaultContainer( child: DefaultContainer(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 10),
child: ListTile( child: ListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon), leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon),
title: BodyMedium( title: BodyMedium(
text: 'Password Name: ${smartDoorBloc.oneTimePasswords![index].pwdName}', text:
'Password Name: ${smartDoorBloc.oneTimePasswords![index].pwdName}',
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
), ),
onTap: () async { onTap: () async {
final result = await showDialog( await showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return DoorDialog( return DoorDialog(
@ -80,7 +86,6 @@ class OnetimePasswordPage extends StatelessWidget {
); );
}, },
); );
}, },
trailing: const Icon( trailing: const Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
@ -91,7 +96,8 @@ class OnetimePasswordPage extends StatelessWidget {
), ),
); );
}, },
) : Column( )
: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -105,7 +111,6 @@ class OnetimePasswordPage extends StatelessWidget {
); );
}, },
)); ));
}) }));
);
} }
} }

View File

@ -19,31 +19,30 @@ class TimeLimitedPasswordPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (BuildContext context) => SmartDoorBloc(deviceId: deviceId!)..add(InitialTimeLimitPassword()), create: (BuildContext context) =>
child: BlocConsumer<SmartDoorBloc, SmartDoorState>( SmartDoorBloc(deviceId: deviceId!)..add(InitialTimeLimitPassword()),
listener: (context, state) { child: BlocConsumer<SmartDoorBloc, SmartDoorState>(listener: (context, state) {
if (state is FailedState) { if (state is FailedState) {
CustomSnackBar.displaySnackBar( CustomSnackBar.displaySnackBar(state.errorMessage);
state.errorMessage
);
} }
}, }, builder: (context, state) {
builder: (context, state) {
final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context); final smartDoorBloc = BlocProvider.of<SmartDoorBloc>(context);
return DefaultScaffold( return DefaultScaffold(
title: 'Passwords', title: 'Passwords',
actions: [ actions: [
IconButton( IconButton(
onPressed: () { onPressed: () {
Navigator.of(context).push( Navigator.of(context)
MaterialPageRoute(builder: (context) => CreateOfflineTimeLimitPasswordPage(deviceId: deviceId,) .push(MaterialPageRoute(
)).then((result) { builder: (context) => CreateOfflineTimeLimitPasswordPage(
deviceId: deviceId,
)))
.then((result) {
smartDoorBloc.add(InitialTimeLimitPassword()); smartDoorBloc.add(InitialTimeLimitPassword());
smartDoorBloc.add(InitialTimeLimitPassword()); smartDoorBloc.add(InitialTimeLimitPassword());
}); });
}, },
icon: const Icon(Icons.add) icon: const Icon(Icons.add))
)
], ],
child: Builder( child: Builder(
builder: (context) { builder: (context) {
@ -57,16 +56,18 @@ class TimeLimitedPasswordPage extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.all(5.0), padding: const EdgeInsets.all(5.0),
child: DefaultContainer( child: DefaultContainer(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 10),
child: ListTile( child: ListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon), leading: SvgPicture.asset(Assets.timeLimitedPasswordIcon),
title: BodyMedium( title: BodyMedium(
text: 'Password Name: ${smartDoorBloc.timeLimitPasswords![index].pwdName}', text:
'Password Name: ${smartDoorBloc.timeLimitPasswords![index].pwdName}',
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
), ),
onTap: () async { onTap: () async {
final result = await showDialog( await showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return DoorDialog( return DoorDialog(
@ -85,7 +86,8 @@ class TimeLimitedPasswordPage extends StatelessWidget {
), ),
); );
}, },
) : Column( )
: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -99,7 +101,6 @@ class TimeLimitedPasswordPage extends StatelessWidget {
); );
}, },
)); ));
}) }));
);
} }
} }

View File

@ -18,7 +18,7 @@ class GangSwitch extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent), overlayColor: WidgetStateProperty.all(Colors.transparent),
onTap: () { onTap: () {
action(); action();
// var tempControl = DeviceControlModel( // var tempControl = DeviceControlModel(

View File

@ -8,7 +8,6 @@ import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_eve
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart'; import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/shared_widgets/create_schedule.dart'; import 'package:syncrow_app/features/shared_widgets/create_schedule.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/schedule_list.dart'; import 'package:syncrow_app/features/shared_widgets/schedule_list.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
@ -18,17 +17,12 @@ import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
class TimerScheduleScreen extends StatelessWidget { class TimerScheduleScreen extends StatelessWidget {
final DeviceModel device; final DeviceModel device;
final String deviceCode; final String deviceCode;
final String switchCode; final String switchCode;
const TimerScheduleScreen( const TimerScheduleScreen(
{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,8 +32,7 @@ class TimerScheduleScreen extends StatelessWidget {
statusBarIconBrightness: Brightness.light, statusBarIconBrightness: Brightness.light,
), ),
child: BlocProvider( child: BlocProvider(
create: (context) => create: (context) => ThreeGangBloc(switchCode: switchCode, threeGangId: device.uuid ?? '')
ThreeGangBloc(switchCode: switchCode, threeGangId: device.uuid ?? '')
..add(GetCounterEvent(deviceCode: deviceCode)) ..add(GetCounterEvent(deviceCode: deviceCode))
..add(GetScheduleEvent()), ..add(GetScheduleEvent()),
child: BlocBuilder<ThreeGangBloc, ThreeGangState>( child: BlocBuilder<ThreeGangBloc, ThreeGangState>(
@ -76,25 +69,25 @@ class TimerScheduleScreen extends StatelessWidget {
fontWeight: FontsManager.bold, fontWeight: FontsManager.bold,
), ),
actions: [ actions: [
threeGangBloc.createSchedule == true ? threeGangBloc.createSchedule == true
TextButton( ? TextButton(
onPressed: () { onPressed: () {
threeGangBloc.add(ThreeGangSave()); threeGangBloc.add(ThreeGangSave());
}, },
child: const Text('Save') child: const Text('Save'))
) : : threeGangBloc.selectedTabIndex == 1
threeGangBloc.selectedTabIndex==1? IconButton( ? IconButton(
onPressed: () { onPressed: () {
threeGangBloc.toggleCreateSchedule(); threeGangBloc.toggleCreateSchedule();
}, },
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
):SizedBox(), )
: SizedBox(),
], ],
), ),
child: child: state is LoadingInitialState
state is LoadingInitialState? ? const Center(child: CircularProgressIndicator())
const Center(child: CircularProgressIndicator()): : Column(
Column(
children: [ children: [
Container( Container(
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
@ -111,7 +104,6 @@ class TimerScheduleScreen extends StatelessWidget {
threeGangBloc.toggleCreateSchedule(); threeGangBloc.toggleCreateSchedule();
} }
threeGangBloc.toggleSelectedIndex(0); threeGangBloc.toggleSelectedIndex(0);
} else { } else {
threeGangBloc.toggleSelectedIndex(1); threeGangBloc.toggleSelectedIndex(1);
} }
@ -122,15 +114,13 @@ class TimerScheduleScreen extends StatelessWidget {
indicator: const ShapeDecoration( indicator: const ShapeDecoration(
color: ColorsManager.slidingBlueColor, color: ColorsManager.slidingBlueColor,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: borderRadius: BorderRadius.all(Radius.circular(20)),
BorderRadius.all(Radius.circular(20)),
), ),
), ),
tabs: [ tabs: [
Tab( Tab(
child: Container( child: Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(vertical: 10),
vertical: 10),
child: BodySmall( child: BodySmall(
text: 'Countdown', text: 'Countdown',
style: context.bodySmall.copyWith( style: context.bodySmall.copyWith(
@ -156,7 +146,6 @@ class TimerScheduleScreen extends StatelessWidget {
), ),
], ],
), ),
), ),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
@ -169,8 +158,7 @@ class TimerScheduleScreen extends StatelessWidget {
countNum > 0 countNum > 0
? BodyLarge( ? BodyLarge(
text: _formatDuration(countNum), text: _formatDuration(countNum),
fontColor: fontColor: ColorsManager.slidingBlueColor,
ColorsManager.slidingBlueColor,
fontSize: 40, fontSize: 40,
) )
: CupertinoTimerPicker( : CupertinoTimerPicker(
@ -203,12 +191,13 @@ class TimerScheduleScreen extends StatelessWidget {
), ),
), ),
Column( Column(
mainAxisAlignment:threeGangBloc.listSchedule.isNotEmpty? mainAxisAlignment: threeGangBloc.listSchedule.isNotEmpty
MainAxisAlignment.start:MainAxisAlignment.center, ? MainAxisAlignment.start
: MainAxisAlignment.center,
children: [ children: [
SizedBox( SizedBox(
child: threeGangBloc.createSchedule == true ? child: threeGangBloc.createSchedule == true
CreateSchedule( ? CreateSchedule(
onToggleChanged: (bool isOn) { onToggleChanged: (bool isOn) {
threeGangBloc.toggleSchedule = isOn; threeGangBloc.toggleSchedule = isOn;
}, },
@ -220,14 +209,17 @@ class TimerScheduleScreen extends StatelessWidget {
threeGangBloc.selectedDays = selectedDays; threeGangBloc.selectedDays = selectedDays;
}, },
) )
: : Padding(
Padding(
padding: const EdgeInsets.only(top: 10), padding: const EdgeInsets.only(top: 10),
child: ScheduleListView( child: ScheduleListView(
listSchedule: threeGangBloc.listSchedule, // Pass the schedule list here listSchedule: threeGangBloc
.listSchedule, // Pass the schedule list here
onDismissed: (scheduleId) { onDismissed: (scheduleId) {
threeGangBloc.listSchedule.removeWhere((schedule) => schedule.scheduleId == scheduleId); threeGangBloc.listSchedule.removeWhere(
threeGangBloc.add(DeleteScheduleEvent(id: scheduleId)); (schedule) =>
schedule.scheduleId == scheduleId);
threeGangBloc.add(
DeleteScheduleEvent(id: scheduleId));
}, },
onToggleSchedule: (scheduleId, isEnabled) { onToggleSchedule: (scheduleId, isEnabled) {
threeGangBloc.add(ToggleScheduleEvent( threeGangBloc.add(ToggleScheduleEvent(
@ -245,8 +237,7 @@ class TimerScheduleScreen extends StatelessWidget {
), ),
], ],
), ),
)) )));
);
}, },
), ),
), ),

View File

@ -1,10 +1,9 @@
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/devices/bloc/three_gang_bloc/three_gang_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart'; import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart'; import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_state.dart';
import 'package:syncrow_app/features/devices/model/groupTwoGangModel.dart'; import 'package:syncrow_app/features/devices/model/group_two_gang_model.dart';
import 'package:syncrow_app/features/devices/model/group_three_gang_model.dart';
import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart'; 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';
@ -16,7 +15,7 @@ class TwoGangList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<ThreeGangBloc, ThreeGangState>( return BlocBuilder<TwoGangBloc, TwoGangState>(
builder: (context, state) { builder: (context, state) {
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
@ -28,10 +27,10 @@ class TwoGangList extends StatelessWidget {
DevicesDefaultSwitch( DevicesDefaultSwitch(
switchValue: allSwitches, switchValue: allSwitches,
action: () { action: () {
BlocProvider.of<ThreeGangBloc>(context).add(GroupAllOnEvent()); BlocProvider.of<TwoGangBloc>(context).add(GroupAllOnEvent());
}, },
secondAction: () { secondAction: () {
BlocProvider.of<ThreeGangBloc>(context).add(GroupAllOffEvent()); BlocProvider.of<TwoGangBloc>(context).add(GroupAllOffEvent());
}, },
), ),
ListView.builder( ListView.builder(
@ -44,30 +43,27 @@ class TwoGangList extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const SizedBox(height: 10), const SizedBox(height: 10),
BodySmall(text: '${twoGangList[index].deviceName} beside light'), BodySmall(text: twoGangList[index].deviceName),
const SizedBox(height: 5), const SizedBox(height: 5),
DevicesDefaultSwitch( DevicesDefaultSwitch(
switchValue: twoGangList[index].firstSwitch, switchValue: twoGangList[index].firstSwitch,
action: () { action: () {
BlocProvider.of<ThreeGangBloc>(context).add(ChangeFirstSwitchStatusEvent( BlocProvider.of<TwoGangBloc>(context).add(ChangeFirstSwitchStatusEvent(
value: twoGangList[index].firstSwitch, value: twoGangList[index].firstSwitch,
deviceId: twoGangList[index].deviceId)); deviceId: twoGangList[index].deviceId));
}, },
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
BodySmall(text: '${twoGangList[index].deviceName} ceiling light'), BodySmall(text: twoGangList[index].deviceName),
const SizedBox(height: 5), const SizedBox(height: 5),
DevicesDefaultSwitch( DevicesDefaultSwitch(
switchValue: twoGangList[index].secondSwitch, switchValue: twoGangList[index].secondSwitch,
action: () { action: () {
BlocProvider.of<ThreeGangBloc>(context).add(ChangeSecondSwitchStatusEvent( BlocProvider.of<TwoGangBloc>(context).add(ChangeSecondSwitchStatusEvent(
value: twoGangList[index].secondSwitch, value: twoGangList[index].secondSwitch,
deviceId: twoGangList[index].deviceId)); deviceId: twoGangList[index].deviceId));
}, },
), ),
const SizedBox(height: 10),
BodySmall(text: '${twoGangList[index].deviceName} spotlight'),
const SizedBox(height: 5),
], ],
); );
}, },

View File

@ -4,7 +4,7 @@ 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/groupTwoGangModel.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_gang_list.dart';
@ -22,9 +22,7 @@ class TwoGangScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => TwoGangBloc( create: (context) => TwoGangBloc(switchCode: switchCode ?? '', twoGangId: device?.uuid ?? '')
switchCode: switchCode??'',
twoGangId: device?.uuid ?? '')
..add(InitialEvent(groupScreen: device != null ? false : true)), ..add(InitialEvent(groupScreen: device != null ? false : true)),
child: BlocBuilder<TwoGangBloc, TwoGangState>( child: BlocBuilder<TwoGangBloc, TwoGangState>(
builder: (context, state) { builder: (context, state) {
@ -47,7 +45,9 @@ class TwoGangScreen extends StatelessWidget {
} }
return state is LoadingInitialState return state is LoadingInitialState
? const Center( ? const Center(
child: DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),) child:
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
)
: device == null : device == null
? TwoGangList( ? TwoGangList(
twoGangList: groupTwoGangModel, twoGangList: groupTwoGangModel,
@ -116,7 +116,6 @@ class TwoGangScreen extends StatelessWidget {
), ),
], ],
), ),
], ],
), ),
), ),

View File

@ -2,7 +2,9 @@ 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/three_gang/three_gang_interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.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';
@ -39,6 +41,18 @@ class WizardPage extends StatelessWidget {
pageBuilder: (context, animation1, animation2) => pageBuilder: (context, animation1, animation2) =>
const ThreeGangInterface())); const ThreeGangInterface()));
} }
if (groupsList[index].name == '2G') {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => const TwoGangInterface()));
}
if (groupsList[index].name == '1G') {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => const OneGangInterface()));
}
}, },
child: DefaultContainer( child: DefaultContainer(
padding: const EdgeInsets.all(15), padding: const EdgeInsets.all(15),

View File

@ -1,16 +1,13 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
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/shared_widgets/default_button.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/features/shared_widgets/text_widgets/body_medium.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/generated/assets.dart';
import 'empty_schedule.dart'; // for SVG icons import 'empty_schedule.dart'; // for SVG icons
class ScheduleListView extends StatelessWidget { class ScheduleListView extends StatelessWidget {
final List<ScheduleModel> listSchedule; final List<ScheduleModel> listSchedule;
final Function(String) onDismissed; final Function(String) onDismissed;
@ -53,7 +50,6 @@ class ScheduleListView extends StatelessWidget {
), ),
direction: DismissDirection.endToStart, direction: DismissDirection.endToStart,
onDismissed: (direction) { onDismissed: (direction) {
onDismissed(listSchedule[index].scheduleId); onDismissed(listSchedule[index].scheduleId);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
@ -61,9 +57,7 @@ class ScheduleListView extends StatelessWidget {
); );
}, },
child: InkWell( child: InkWell(
onTap: () { onTap: () {},
},
child: DefaultContainer( child: DefaultContainer(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
height: MediaQuery.of(context).size.height / 6.4, height: MediaQuery.of(context).size.height / 6.4,
@ -80,7 +74,8 @@ class ScheduleListView extends StatelessWidget {
fontSize: 22, fontSize: 22,
), ),
Text(listSchedule[index].days.join(' ')), Text(listSchedule[index].days.join(' ')),
Text('Function ${listSchedule[index].function.value ? "ON" : "OFF"}'), Text(
'Function ${listSchedule[index].function.value ? "ON" : "OFF"}'),
], ],
), ),
), ),
@ -114,7 +109,6 @@ class ScheduleListView extends StatelessWidget {
}, },
), ),
) )
: const EmptySchedule() : const EmptySchedule());
);
} }
} }

View File

@ -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) {
@ -375,7 +362,6 @@ class DevicesAPI {
.replaceAll('{endTime}', endTime), .replaceAll('{endTime}', endTime),
expectedResponseModel: (json) { expectedResponseModel: (json) {
return DeviceReport.fromJson(json); return DeviceReport.fromJson(json);
return json;
}, },
); );