mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-14 17:25:50 +00:00
Compare commits
1 Commits
SP-1189-Re
...
SP-1277-FE
Author | SHA1 | Date | |
---|---|---|---|
6c691d4b3c |
@ -1,21 +0,0 @@
|
|||||||
<svg width="23" height="23" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_7572_5102)">
|
|
||||||
<path d="M11.255 22.5148H11.2389C9.82071 22.5148 8.66699 21.361 8.66699 19.9429V19.3419C8.66699 18.9913 8.95123 18.707 9.30183 18.707H13.1921C13.5427 18.707 13.8269 18.9913 13.8269 19.3419V19.9429C13.8269 21.3611 12.6731 22.5148 11.255 22.5148Z" fill="#FFA81C"/>
|
|
||||||
<path d="M13.1912 18.707H11.2461V22.5148H11.2542C12.6723 22.5148 13.826 21.361 13.826 19.9429V19.3419C13.826 18.9912 13.5418 18.707 13.1912 18.707Z" fill="#FF9300"/>
|
|
||||||
<path d="M12.5157 4.81334H9.97762C9.62701 4.81334 9.34277 4.5291 9.34277 4.1785V2.74955C9.34277 1.69974 10.1968 0.845703 11.2466 0.845703C12.2964 0.845703 13.1505 1.69978 13.1505 2.74955V4.1785C13.1505 4.5291 12.8663 4.81334 12.5157 4.81334Z" fill="#FFA81C"/>
|
|
||||||
<path d="M12.5151 4.81334C12.8657 4.81334 13.1499 4.5291 13.1499 4.1785V2.74955C13.1499 1.69974 12.2959 0.845703 11.2461 0.845703V4.81334H12.5151Z" fill="#FF9300"/>
|
|
||||||
<path d="M17.9733 19.9777H4.51899C3.96952 19.9777 3.52246 19.5306 3.52246 18.9811V18.0735C3.52246 17.0793 3.88851 16.1245 4.55319 15.3852C5.00799 14.8792 5.25846 14.226 5.25846 13.5457V9.43293C5.25846 6.13133 7.94448 3.44531 11.2461 3.44531C14.5477 3.44531 17.2337 6.13133 17.2337 9.43293V13.5457C17.2337 14.226 17.4842 14.8792 17.939 15.3851C18.6037 16.1245 18.9697 17.0792 18.9697 18.0734V18.9811C18.9698 19.5306 18.5228 19.9777 17.9733 19.9777Z" fill="#FFCF2C"/>
|
|
||||||
<path d="M17.9732 19.9776C18.5227 19.9776 18.9698 19.5306 18.9698 18.9811V18.0734C18.9698 17.0792 18.6037 16.1245 17.939 15.3851C17.4842 14.8792 17.2337 14.226 17.2337 13.5457V9.43293C17.2337 6.13133 14.5477 3.44531 11.2461 3.44531V19.9776H17.9732Z" fill="#FFC12E"/>
|
|
||||||
<path d="M3.52246 18.0734V18.9811C3.52246 19.5306 3.96952 19.9776 4.51899 19.9776H17.9732C18.5227 19.9776 18.9698 19.5306 18.9698 18.9811V18.0734C18.9698 17.638 18.8995 17.2102 18.7648 16.8047H3.72747C3.59272 17.2102 3.52246 17.638 3.52246 18.0734Z" fill="#FFF566"/>
|
|
||||||
<path d="M11.2461 16.8047V19.9776H17.9732C18.5227 19.9776 18.9698 19.5306 18.9698 18.9811V18.0734C18.9698 17.638 18.8995 17.2102 18.7647 16.8047H11.2461V16.8047Z" fill="#FFE645"/>
|
|
||||||
<path d="M1.04282 7.85721C0.998428 7.85721 0.953397 7.85255 0.908238 7.84278C0.565508 7.7688 0.347673 7.43097 0.421653 7.08824C0.930035 4.73345 2.22744 2.57028 4.07483 0.997187C4.3418 0.769872 4.74247 0.802079 4.96975 1.06897C5.19706 1.33594 5.16494 1.73657 4.89797 1.96388C3.2616 3.35728 2.11262 5.2723 1.66273 7.35619C1.59852 7.65376 1.33536 7.85721 1.04282 7.85721Z" fill="#FF8B6E"/>
|
|
||||||
<path d="M21.4417 7.85717C21.1491 7.85717 20.886 7.65377 20.8218 7.35619C20.3719 5.2723 19.2229 3.35728 17.5866 1.96393C17.3196 1.73661 17.2875 1.33594 17.5148 1.06901C17.7421 0.80204 18.1427 0.769875 18.4097 0.997233C20.2571 2.57024 21.5545 4.73345 22.0628 7.08825C22.1368 7.43098 21.919 7.7688 21.5763 7.84278C21.5311 7.85247 21.4861 7.85717 21.4417 7.85717Z" fill="#FF674F"/>
|
|
||||||
<path d="M3.48329 8.6005C3.4444 8.6005 3.40495 8.5969 3.36534 8.58945C3.02075 8.5247 2.79394 8.19284 2.85869 7.84829C3.20714 5.99413 4.18429 4.28141 5.61006 3.02565C5.87314 2.79385 6.27431 2.81937 6.50603 3.08245C6.73779 3.34557 6.71231 3.74671 6.44923 3.97842C5.23495 5.04796 4.40293 6.50556 4.1065 8.08276C4.04919 8.38778 3.78268 8.6005 3.48329 8.6005Z" fill="#FF8B6E"/>
|
|
||||||
<path d="M19.0004 8.60042C18.701 8.60042 18.4345 8.38771 18.3772 8.08273C18.0808 6.50557 17.2489 5.04793 16.0346 3.97843C15.7715 3.74667 15.7461 3.34554 15.9778 3.08241C16.2095 2.81934 16.6107 2.7939 16.8738 3.02562C18.2995 4.28138 19.2766 5.99405 19.625 7.84817C19.6898 8.19277 19.4629 8.52458 19.1183 8.58933C19.0788 8.59682 19.0393 8.60042 19.0004 8.60042Z" fill="#FF674F"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_7572_5102">
|
|
||||||
<rect width="21.67" height="21.67" fill="white" transform="translate(0.407227 0.845703)"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.8 KiB |
@ -1,4 +0,0 @@
|
|||||||
<svg width="8" height="9" viewBox="0 0 8 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M7.13918 0.5H4.10294C4.0408 0.5 3.98117 0.524721 3.93722 0.568668L0.251783 4.25398C-0.0839278 4.58982 -0.0839278 5.13617 0.251783 5.47188L3.02848 8.24852C3.1906 8.41064 3.40686 8.49994 3.63734 8.5H3.6374C3.86794 8.5 4.0842 8.41064 4.24638 8.24846L7.9317 4.56308C7.97565 4.51914 8.00037 4.4595 8.00037 4.39736L8.00043 1.36113C8.00037 0.886312 7.61399 0.5 7.13918 0.5ZM7.53159 4.30031L3.91488 7.91702C3.84127 7.9907 3.74269 8.03122 3.6374 8.03122C3.53205 8.03122 3.43353 7.9907 3.35992 7.91708L0.583222 5.14045C0.43026 4.98748 0.43026 4.73845 0.583222 4.58542L4.19999 0.968775H7.13918C7.35556 0.968775 7.53165 1.14481 7.53165 1.36119L7.53159 4.30031Z" fill="#999999"/>
|
|
||||||
<path d="M5.93455 1.8291C5.73782 1.8291 5.55288 1.90577 5.41377 2.04487C5.27466 2.18392 5.19806 2.36886 5.19806 2.56559C5.19806 2.76232 5.27466 2.94726 5.41377 3.08637C5.55288 3.22548 5.73782 3.30208 5.93455 3.30208C6.13121 3.30208 6.31616 3.22548 6.45527 3.08637C6.59437 2.94726 6.67098 2.76232 6.67098 2.56559C6.67098 2.36886 6.59437 2.18392 6.45533 2.04487C6.31622 1.90577 6.13128 1.8291 5.93455 1.8291ZM6.12383 2.75487C6.07329 2.80547 6.00602 2.83331 5.93455 2.83331C5.86301 2.83331 5.79581 2.80547 5.74527 2.75487C5.69467 2.70433 5.66683 2.63707 5.66683 2.56559C5.66683 2.49412 5.69467 2.42685 5.74527 2.37631C5.79581 2.32571 5.86307 2.29788 5.93455 2.29788C6.00602 2.29788 6.07323 2.32571 6.12383 2.37631C6.17443 2.42685 6.20226 2.49412 6.20226 2.56559C6.20226 2.63707 6.17437 2.70433 6.12383 2.75487Z" fill="#999999"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.6 KiB |
@ -1,3 +0,0 @@
|
|||||||
<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M21.412 9.9034L18.9398 9.28324C18.788 8.81496 18.5981 8.35938 18.3703 7.92902C18.7373 7.30886 19.522 6.00531 19.522 6.00531C19.6613 5.75219 19.6233 5.43578 19.4208 5.23324L17.6362 3.43609C17.4338 3.23364 17.1047 3.19563 16.8642 3.3475L14.9404 4.49922C14.4975 4.27141 14.0419 4.08152 13.5862 3.92969L12.9661 1.45754C12.9028 1.17902 12.6496 0.976562 12.3586 0.976562H9.82734C9.53629 0.976562 9.28312 1.17902 9.21989 1.4575C9.21989 1.4575 8.78953 3.18293 8.59973 3.92965C8.10614 4.09418 7.62516 4.29663 7.16957 4.5498L5.16984 3.34746C4.91672 3.19558 4.60031 3.23359 4.39781 3.43605L2.61328 5.23324C2.39817 5.43578 2.36016 5.75219 2.51199 6.00531L3.75234 8.06828C3.5498 8.46063 3.38527 8.86563 3.24609 9.28324L0.773948 9.9034C0.495427 9.96672 0.292969 10.2198 0.292969 10.5109V13.0422C0.292969 13.3332 0.495427 13.5864 0.773906 13.6496L3.24609 14.2698C3.39797 14.7381 3.60051 15.2064 3.82832 15.6494L2.72723 17.4845C2.57535 17.7376 2.61328 18.054 2.82844 18.2692L4.61301 20.0537C4.81547 20.2563 5.13188 20.2942 5.38504 20.1423C5.38504 20.1423 6.62531 19.4082 7.2329 19.0412C7.67578 19.2817 8.13136 19.4715 8.59973 19.6234L9.21989 22.0956C9.28317 22.374 9.53629 22.5765 9.82734 22.5765H12.3586C12.6496 22.5765 12.9028 22.374 12.9661 22.0956L13.5862 19.6234C14.0671 19.4715 14.5354 19.269 14.9911 19.0286C15.6112 19.3955 16.8642 20.1423 16.8642 20.1423C17.1046 20.2942 17.4337 20.2563 17.6362 20.0537L19.4208 18.2692C19.6232 18.054 19.6613 17.7376 19.522 17.4845L18.383 15.5987C18.6108 15.1684 18.788 14.7254 18.9398 14.2698L21.412 13.6496C21.6905 13.5864 21.8929 13.3332 21.8929 13.0422V10.5109C21.893 10.2198 21.6905 9.96672 21.412 9.9034ZM11.093 16.2063C8.65031 16.2063 6.66328 14.2192 6.66328 11.7766C6.66328 9.33391 8.65031 7.34688 11.093 7.34688C13.5356 7.34688 15.5227 9.33391 15.5227 11.7766C15.5227 14.2192 13.5356 16.2063 11.093 16.2063Z" fill="#A1A7B3"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.9 KiB |
@ -201,17 +201,20 @@ class ForgetPasswordWebPage extends StatelessWidget {
|
|||||||
!state.isButtonEnabled &&
|
!state.isButtonEnabled &&
|
||||||
state.remainingTime != 1
|
state.remainingTime != 1
|
||||||
? null
|
? null
|
||||||
:
|
: () {
|
||||||
() {
|
|
||||||
if (forgetBloc
|
if (forgetBloc
|
||||||
.forgetEmailKey
|
.forgetEmailKey.currentState!
|
||||||
.currentState!
|
.validate() ||
|
||||||
.validate()) {
|
forgetBloc
|
||||||
forgetBloc.add(
|
.forgetRegionKey.currentState!
|
||||||
StartTimerEvent());
|
.validate()) {
|
||||||
|
if (forgetBloc
|
||||||
|
.forgetRegionKey.currentState!
|
||||||
|
.validate()) {
|
||||||
|
forgetBloc.add(StartTimerEvent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'Get Code ${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "(${forgetBloc.formattedTime(state.remainingTime)}) " : ""}',
|
'Get Code ${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "(${forgetBloc.formattedTime(state.remainingTime)}) " : ""}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -13,7 +13,6 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
late AcStatusModel deviceStatus;
|
late AcStatusModel deviceStatus;
|
||||||
final String deviceId;
|
final String deviceId;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
Timer? _countdownTimer;
|
|
||||||
|
|
||||||
AcBloc({required this.deviceId}) : super(AcsInitialState()) {
|
AcBloc({required this.deviceId}) : super(AcsInitialState()) {
|
||||||
on<AcFetchDeviceStatusEvent>(_onFetchAcStatus);
|
on<AcFetchDeviceStatusEvent>(_onFetchAcStatus);
|
||||||
@ -22,16 +21,7 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
on<AcBatchControlEvent>(_onAcBatchControl);
|
on<AcBatchControlEvent>(_onAcBatchControl);
|
||||||
on<AcFactoryResetEvent>(_onFactoryReset);
|
on<AcFactoryResetEvent>(_onFactoryReset);
|
||||||
on<AcStatusUpdated>(_onAcStatusUpdated);
|
on<AcStatusUpdated>(_onAcStatusUpdated);
|
||||||
on<OnClose>(_onClose);
|
|
||||||
on<IncreaseTimeEvent>(_handleIncreaseTime);
|
|
||||||
on<DecreaseTimeEvent>(_handleDecreaseTime);
|
|
||||||
on<UpdateTimerEvent>(_handleUpdateTimer);
|
|
||||||
on<ToggleScheduleEvent>(_handleToggleTimer);
|
|
||||||
on<ApiCountdownValueEvent>(_handleApiCountdownValue);
|
|
||||||
}
|
}
|
||||||
bool timerActive = false;
|
|
||||||
int scheduledHours = 0;
|
|
||||||
int scheduledMinutes = 0;
|
|
||||||
|
|
||||||
FutureOr<void> _onFetchAcStatus(
|
FutureOr<void> _onFetchAcStatus(
|
||||||
AcFetchDeviceStatusEvent event, Emitter<AcsState> emit) async {
|
AcFetchDeviceStatusEvent event, Emitter<AcsState> emit) async {
|
||||||
@ -40,23 +30,8 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
final status =
|
final status =
|
||||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||||
deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status);
|
deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status);
|
||||||
if (deviceStatus.countdown1 != 0) {
|
|
||||||
// Convert API value to minutes
|
|
||||||
final totalMinutes = deviceStatus.countdown1 * 6;
|
|
||||||
scheduledHours = totalMinutes ~/ 60;
|
|
||||||
scheduledMinutes = totalMinutes % 60;
|
|
||||||
timerActive = true;
|
|
||||||
_startCountdownTimer(emit);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(ACStatusLoaded(
|
|
||||||
status: deviceStatus,
|
|
||||||
scheduledHours: scheduledHours,
|
|
||||||
scheduledMinutes: scheduledMinutes,
|
|
||||||
isTimerActive: timerActive,
|
|
||||||
));
|
|
||||||
|
|
||||||
_listenToChanges(event.deviceId);
|
_listenToChanges(event.deviceId);
|
||||||
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(AcsFailedState(error: e.toString()));
|
emit(AcsFailedState(error: e.toString()));
|
||||||
}
|
}
|
||||||
@ -95,16 +70,31 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
|
|
||||||
void _onAcStatusUpdated(AcStatusUpdated event, Emitter<AcsState> emit) {
|
void _onAcStatusUpdated(AcStatusUpdated event, Emitter<AcsState> emit) {
|
||||||
deviceStatus = event.deviceStatus;
|
deviceStatus = event.deviceStatus;
|
||||||
emit(ACStatusLoaded(status: deviceStatus));
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Future<void> testFirebaseConnection() async {
|
||||||
|
// // Reference to a test node in your database
|
||||||
|
// final testRef = FirebaseDatabase.instance.ref("test");
|
||||||
|
|
||||||
|
// // Write a test value
|
||||||
|
// await testRef.set("Hello, Firebase!");
|
||||||
|
|
||||||
|
// // Listen for changes on the test node
|
||||||
|
// testRef.onValue.listen((DatabaseEvent event) {
|
||||||
|
// final data = event.snapshot.value;
|
||||||
|
// print("Data from Firebase: $data");
|
||||||
|
// // If you see "Hello, Firebase!" printed in your console, it means the connection works.
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
FutureOr<void> _onAcControl(
|
FutureOr<void> _onAcControl(
|
||||||
AcControlEvent event, Emitter<AcsState> emit) async {
|
AcControlEvent event, Emitter<AcsState> emit) async {
|
||||||
final oldValue = _getValueByCode(event.code);
|
final oldValue = _getValueByCode(event.code);
|
||||||
|
|
||||||
_updateLocalValue(event.code, event.value, emit);
|
_updateLocalValue(event.code, event.value, emit);
|
||||||
|
|
||||||
emit(ACStatusLoaded(status: deviceStatus));
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
await _runDebounce(
|
await _runDebounce(
|
||||||
isBatch: false,
|
isBatch: false,
|
||||||
@ -161,7 +151,7 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
void _revertValueAndEmit(
|
void _revertValueAndEmit(
|
||||||
String deviceId, String code, dynamic oldValue, Emitter<AcsState> emit) {
|
String deviceId, String code, dynamic oldValue, Emitter<AcsState> emit) {
|
||||||
_updateLocalValue(code, oldValue, emit);
|
_updateLocalValue(code, oldValue, emit);
|
||||||
emit(ACStatusLoaded(status: deviceStatus));
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateLocalValue(String code, dynamic value, Emitter<AcsState> emit) {
|
void _updateLocalValue(String code, dynamic value, Emitter<AcsState> emit) {
|
||||||
@ -194,16 +184,11 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
if (value is bool) {
|
if (value is bool) {
|
||||||
deviceStatus = deviceStatus.copyWith(childLock: value);
|
deviceStatus = deviceStatus.copyWith(childLock: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'countdown_time':
|
|
||||||
if (value is int) {
|
|
||||||
deviceStatus = deviceStatus.copyWith(countdown1: value);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
emit(ACStatusLoaded(status: deviceStatus));
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic _getValueByCode(String code) {
|
dynamic _getValueByCode(String code) {
|
||||||
@ -218,8 +203,6 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
return deviceStatus.fanSpeedsString;
|
return deviceStatus.fanSpeedsString;
|
||||||
case 'child_lock':
|
case 'child_lock':
|
||||||
return deviceStatus.childLock;
|
return deviceStatus.childLock;
|
||||||
case 'countdown_time':
|
|
||||||
return deviceStatus.countdown1;
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -233,7 +216,7 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
await DevicesManagementApi().getBatchStatus(event.devicesIds);
|
||||||
deviceStatus =
|
deviceStatus =
|
||||||
AcStatusModel.fromJson(event.devicesIds.first, status.status);
|
AcStatusModel.fromJson(event.devicesIds.first, status.status);
|
||||||
emit(ACStatusLoaded(status: deviceStatus));
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(AcsFailedState(error: e.toString()));
|
emit(AcsFailedState(error: e.toString()));
|
||||||
}
|
}
|
||||||
@ -245,7 +228,7 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
|
|
||||||
_updateLocalValue(event.code, event.value, emit);
|
_updateLocalValue(event.code, event.value, emit);
|
||||||
|
|
||||||
emit(ACStatusLoaded(status: deviceStatus));
|
emit(ACStatusLoaded(deviceStatus));
|
||||||
|
|
||||||
await _runDebounce(
|
await _runDebounce(
|
||||||
isBatch: true,
|
isBatch: true,
|
||||||
@ -274,144 +257,4 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
|||||||
emit(AcsFailedState(error: e.toString()));
|
emit(AcsFailedState(error: e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onClose(OnClose event, Emitter<AcsState> emit) {
|
|
||||||
_countdownTimer?.cancel();
|
|
||||||
_timer?.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleIncreaseTime(IncreaseTimeEvent event, Emitter<AcsState> emit) {
|
|
||||||
if (state is! ACStatusLoaded) return;
|
|
||||||
final currentState = state as ACStatusLoaded;
|
|
||||||
int newHours = scheduledHours;
|
|
||||||
int newMinutes = scheduledMinutes + 30;
|
|
||||||
newHours += newMinutes ~/ 60;
|
|
||||||
newMinutes = newMinutes % 60;
|
|
||||||
if (newHours > 23) {
|
|
||||||
newHours = 23;
|
|
||||||
newMinutes = 59;
|
|
||||||
}
|
|
||||||
scheduledHours = newHours;
|
|
||||||
scheduledMinutes = newMinutes;
|
|
||||||
|
|
||||||
emit(currentState.copyWith(
|
|
||||||
scheduledHours: scheduledHours,
|
|
||||||
scheduledMinutes: scheduledMinutes,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleDecreaseTime(DecreaseTimeEvent event, Emitter<AcsState> emit) {
|
|
||||||
if (state is! ACStatusLoaded) return;
|
|
||||||
final currentState = state as ACStatusLoaded;
|
|
||||||
int totalMinutes = (scheduledHours * 60) + scheduledMinutes;
|
|
||||||
totalMinutes = (totalMinutes - 30).clamp(0, 1440);
|
|
||||||
scheduledHours = totalMinutes ~/ 60;
|
|
||||||
scheduledMinutes = totalMinutes % 60;
|
|
||||||
|
|
||||||
emit(currentState.copyWith(
|
|
||||||
scheduledHours: scheduledHours,
|
|
||||||
scheduledMinutes: scheduledMinutes,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _handleToggleTimer(
|
|
||||||
ToggleScheduleEvent event, Emitter<AcsState> emit) async {
|
|
||||||
if (state is! ACStatusLoaded) return;
|
|
||||||
final currentState = state as ACStatusLoaded;
|
|
||||||
|
|
||||||
timerActive = !timerActive;
|
|
||||||
|
|
||||||
if (timerActive) {
|
|
||||||
final totalMinutes = scheduledHours * 60 + scheduledMinutes;
|
|
||||||
if (totalMinutes <= 0) {
|
|
||||||
timerActive = false;
|
|
||||||
emit(currentState.copyWith(isTimerActive: timerActive));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final scaledValue = totalMinutes ~/ 6;
|
|
||||||
await _runDebounce(
|
|
||||||
isBatch: false,
|
|
||||||
deviceId: deviceId,
|
|
||||||
code: 'countdown_time',
|
|
||||||
value: scaledValue,
|
|
||||||
oldValue: scaledValue,
|
|
||||||
emit: emit,
|
|
||||||
);
|
|
||||||
_startCountdownTimer(emit);
|
|
||||||
emit(currentState.copyWith(isTimerActive: timerActive));
|
|
||||||
} catch (e) {
|
|
||||||
timerActive = false;
|
|
||||||
emit(AcsFailedState(error: e.toString()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await _runDebounce(
|
|
||||||
isBatch: false,
|
|
||||||
deviceId: deviceId,
|
|
||||||
code: 'countdown_time',
|
|
||||||
value: 0,
|
|
||||||
oldValue: 0,
|
|
||||||
emit: emit,
|
|
||||||
);
|
|
||||||
_countdownTimer?.cancel();
|
|
||||||
scheduledHours = 0;
|
|
||||||
scheduledMinutes = 0;
|
|
||||||
emit(currentState.copyWith(
|
|
||||||
isTimerActive: timerActive,
|
|
||||||
scheduledHours: 0,
|
|
||||||
scheduledMinutes: 0,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _startCountdownTimer(Emitter<AcsState> emit) {
|
|
||||||
_countdownTimer?.cancel();
|
|
||||||
int totalSeconds = (scheduledHours * 3600) + (scheduledMinutes * 60);
|
|
||||||
|
|
||||||
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
||||||
if (totalSeconds > 0) {
|
|
||||||
totalSeconds--;
|
|
||||||
scheduledHours = totalSeconds ~/ 3600;
|
|
||||||
scheduledMinutes = (totalSeconds % 3600) ~/ 60;
|
|
||||||
add(UpdateTimerEvent());
|
|
||||||
} else {
|
|
||||||
_countdownTimer?.cancel();
|
|
||||||
timerActive = false;
|
|
||||||
scheduledHours = 0;
|
|
||||||
scheduledMinutes = 0;
|
|
||||||
add(TimerCompletedEvent());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleUpdateTimer(UpdateTimerEvent event, Emitter<AcsState> emit) {
|
|
||||||
if (state is ACStatusLoaded) {
|
|
||||||
final currentState = state as ACStatusLoaded;
|
|
||||||
emit(currentState.copyWith(
|
|
||||||
scheduledHours: scheduledHours,
|
|
||||||
scheduledMinutes: scheduledMinutes,
|
|
||||||
isTimerActive: timerActive,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleApiCountdownValue(
|
|
||||||
ApiCountdownValueEvent event, Emitter<AcsState> emit) {
|
|
||||||
if (state is ACStatusLoaded) {
|
|
||||||
final totalMinutes = event.apiValue * 6;
|
|
||||||
final scheduledHours = totalMinutes ~/ 60;
|
|
||||||
scheduledMinutes = totalMinutes % 60;
|
|
||||||
_startCountdownTimer(
|
|
||||||
emit,
|
|
||||||
);
|
|
||||||
add(UpdateTimerEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() {
|
|
||||||
add(OnClose());
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ sealed class AcsEvent extends Equatable {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
class AcUpdated extends AcsEvent {}
|
class AcUpdated extends AcsEvent {}
|
||||||
|
|
||||||
class AcFetchDeviceStatusEvent extends AcsEvent {
|
class AcFetchDeviceStatusEvent extends AcsEvent {
|
||||||
@ -19,12 +18,10 @@ class AcFetchDeviceStatusEvent extends AcsEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId];
|
List<Object> get props => [deviceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class AcStatusUpdated extends AcsEvent {
|
class AcStatusUpdated extends AcsEvent {
|
||||||
final AcStatusModel deviceStatus;
|
final AcStatusModel deviceStatus;
|
||||||
AcStatusUpdated(this.deviceStatus);
|
AcStatusUpdated(this.deviceStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AcFetchBatchStatusEvent extends AcsEvent {
|
class AcFetchBatchStatusEvent extends AcsEvent {
|
||||||
final List<String> devicesIds;
|
final List<String> devicesIds;
|
||||||
|
|
||||||
@ -76,30 +73,3 @@ class AcFactoryResetEvent extends AcsEvent {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [deviceId, factoryResetModel];
|
List<Object> get props => [deviceId, factoryResetModel];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class OnClose extends AcsEvent {}
|
|
||||||
|
|
||||||
class IncreaseTimeEvent extends AcsEvent {
|
|
||||||
@override
|
|
||||||
List<Object> get props => [];
|
|
||||||
}
|
|
||||||
|
|
||||||
class DecreaseTimeEvent extends AcsEvent {
|
|
||||||
@override
|
|
||||||
List<Object> get props => [];
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToggleScheduleEvent extends AcsEvent {}
|
|
||||||
|
|
||||||
class TimerCompletedEvent extends AcsEvent {}
|
|
||||||
|
|
||||||
class UpdateTimerEvent extends AcsEvent {
|
|
||||||
}
|
|
||||||
|
|
||||||
class ApiCountdownValueEvent extends AcsEvent {
|
|
||||||
final int apiValue;
|
|
||||||
|
|
||||||
const ApiCountdownValueEvent(this.apiValue);
|
|
||||||
}
|
|
||||||
|
@ -2,9 +2,8 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
|
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
|
||||||
|
|
||||||
abstract class AcsState extends Equatable {
|
abstract class AcsState extends Equatable {
|
||||||
final bool isTimerActive;
|
const AcsState();
|
||||||
|
|
||||||
const AcsState({this.isTimerActive = false});
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
@ -16,30 +15,8 @@ class AcsLoadingState extends AcsState {}
|
|||||||
class ACStatusLoaded extends AcsState {
|
class ACStatusLoaded extends AcsState {
|
||||||
final AcStatusModel status;
|
final AcStatusModel status;
|
||||||
final DateTime timestamp;
|
final DateTime timestamp;
|
||||||
final int scheduledHours;
|
|
||||||
final int scheduledMinutes;
|
|
||||||
final bool isTimerActive;
|
|
||||||
|
|
||||||
ACStatusLoaded({
|
ACStatusLoaded(this.status) : timestamp = DateTime.now();
|
||||||
required this.status,
|
|
||||||
this.scheduledHours = 0,
|
|
||||||
this.scheduledMinutes = 0,
|
|
||||||
this.isTimerActive = false,
|
|
||||||
}) : timestamp = DateTime.now();
|
|
||||||
ACStatusLoaded copyWith({
|
|
||||||
AcStatusModel? status,
|
|
||||||
int? scheduledHours,
|
|
||||||
int? scheduledMinutes,
|
|
||||||
bool? isTimerActive,
|
|
||||||
int? remainingTime,
|
|
||||||
}) {
|
|
||||||
return ACStatusLoaded(
|
|
||||||
status: status ?? this.status,
|
|
||||||
scheduledHours: scheduledHours ?? this.scheduledHours,
|
|
||||||
scheduledMinutes: scheduledMinutes ?? this.scheduledMinutes,
|
|
||||||
isTimerActive: isTimerActive ?? this.isTimerActive,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [status, timestamp];
|
List<Object> get props => [status, timestamp];
|
||||||
@ -63,14 +40,3 @@ class AcsFailedState extends AcsState {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [error];
|
List<Object> get props => [error];
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimerRunInProgress extends AcsState {
|
|
||||||
final int remainingTime;
|
|
||||||
|
|
||||||
const TimerRunInProgress(this.remainingTime);
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object> get props => [remainingTime];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ class AcStatusModel {
|
|||||||
final bool childLock;
|
final bool childLock;
|
||||||
final TempModes acMode;
|
final TempModes acMode;
|
||||||
final FanSpeeds acFanSpeed;
|
final FanSpeeds acFanSpeed;
|
||||||
final int countdown1;
|
|
||||||
|
|
||||||
AcStatusModel({
|
AcStatusModel({
|
||||||
required this.uuid,
|
required this.uuid,
|
||||||
@ -19,7 +18,6 @@ class AcStatusModel {
|
|||||||
required this.modeString,
|
required this.modeString,
|
||||||
required this.tempSet,
|
required this.tempSet,
|
||||||
required this.currentTemp,
|
required this.currentTemp,
|
||||||
required this.countdown1,
|
|
||||||
required this.fanSpeedsString,
|
required this.fanSpeedsString,
|
||||||
required this.childLock,
|
required this.childLock,
|
||||||
}) : acMode = getACMode(modeString),
|
}) : acMode = getACMode(modeString),
|
||||||
@ -32,7 +30,6 @@ class AcStatusModel {
|
|||||||
late int currentTemp;
|
late int currentTemp;
|
||||||
late String fanSpeeds;
|
late String fanSpeeds;
|
||||||
late bool childLock;
|
late bool childLock;
|
||||||
late int _countdown1 = 0;
|
|
||||||
|
|
||||||
for (var status in jsonList) {
|
for (var status in jsonList) {
|
||||||
switch (status.code) {
|
switch (status.code) {
|
||||||
@ -54,9 +51,6 @@ class AcStatusModel {
|
|||||||
case 'child_lock':
|
case 'child_lock':
|
||||||
childLock = status.value ?? false;
|
childLock = status.value ?? false;
|
||||||
break;
|
break;
|
||||||
case 'countdown_time':
|
|
||||||
_countdown1 = status.value ?? 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +62,6 @@ class AcStatusModel {
|
|||||||
currentTemp: currentTemp,
|
currentTemp: currentTemp,
|
||||||
fanSpeedsString: fanSpeeds,
|
fanSpeedsString: fanSpeeds,
|
||||||
childLock: childLock,
|
childLock: childLock,
|
||||||
countdown1: _countdown1,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +73,6 @@ class AcStatusModel {
|
|||||||
int? currentTemp,
|
int? currentTemp,
|
||||||
String? fanSpeedsString,
|
String? fanSpeedsString,
|
||||||
bool? childLock,
|
bool? childLock,
|
||||||
int? countdown1,
|
|
||||||
}) {
|
}) {
|
||||||
return AcStatusModel(
|
return AcStatusModel(
|
||||||
uuid: uuid ?? this.uuid,
|
uuid: uuid ?? this.uuid,
|
||||||
@ -90,7 +82,6 @@ class AcStatusModel {
|
|||||||
currentTemp: currentTemp ?? this.currentTemp,
|
currentTemp: currentTemp ?? this.currentTemp,
|
||||||
fanSpeedsString: fanSpeedsString ?? this.fanSpeedsString,
|
fanSpeedsString: fanSpeedsString ?? this.fanSpeedsString,
|
||||||
childLock: childLock ?? this.childLock,
|
childLock: childLock ?? this.childLock,
|
||||||
countdown1: countdown1 ?? this.countdown1,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,10 +10,11 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo
|
|||||||
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
const AcDeviceControlsView({super.key, required this.device});
|
const AcDeviceControlsView({super.key, required this.device});
|
||||||
|
|
||||||
final AllDevicesModel device;
|
final AllDevicesModel device;
|
||||||
|
|
||||||
@ -22,13 +23,11 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
final isLarge = isLargeScreenSize(context);
|
final isLarge = isLargeScreenSize(context);
|
||||||
final isMedium = isMediumScreenSize(context);
|
final isMedium = isMediumScreenSize(context);
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => AcBloc(deviceId: device.uuid!)
|
create: (context) => AcBloc(deviceId: device.uuid!)
|
||||||
..add(AcFetchDeviceStatusEvent(device.uuid!)),
|
..add(AcFetchDeviceStatusEvent(device.uuid!)),
|
||||||
child: BlocBuilder<AcBloc, AcsState>(
|
child: BlocBuilder<AcBloc, AcsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final acBloc = BlocProvider.of<AcBloc>(context);
|
|
||||||
if (state is ACStatusLoaded) {
|
if (state is ACStatusLoaded) {
|
||||||
return GridView(
|
return GridView(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
@ -79,101 +78,56 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
),
|
),
|
||||||
ToggleWidget(
|
ToggleWidget(
|
||||||
label: '',
|
label: '',
|
||||||
labelWidget: Column(
|
labelWidget: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Container(
|
IconButton(
|
||||||
width: MediaQuery.of(context).size.width,
|
padding: const EdgeInsets.all(0),
|
||||||
decoration: const ShapeDecoration(
|
onPressed: () {},
|
||||||
color: ColorsManager.primaryColor,
|
icon: const Icon(
|
||||||
shape: RoundedRectangleBorder(
|
Icons.remove,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
size: 28,
|
||||||
),
|
color: ColorsManager.greyColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Center(
|
Text(
|
||||||
child: SizedBox(
|
'06',
|
||||||
child: Row(
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
color: ColorsManager.dialogBlueTitle,
|
||||||
children: [
|
fontWeight: FontWeight.bold,
|
||||||
IconButton(
|
),
|
||||||
onPressed: () {
|
),
|
||||||
if (acBloc.timerActive == false) {
|
Text(
|
||||||
context
|
'h',
|
||||||
.read<AcBloc>()
|
style: context.textTheme.bodySmall!
|
||||||
.add(DecreaseTimeEvent());
|
.copyWith(color: ColorsManager.blackColor),
|
||||||
}
|
),
|
||||||
},
|
Text(
|
||||||
icon: const Icon(Icons.remove,
|
'30',
|
||||||
color: ColorsManager.greyColor),
|
style: context.textTheme.titleLarge!.copyWith(
|
||||||
),
|
color: ColorsManager.dialogBlueTitle,
|
||||||
Text(
|
fontWeight: FontWeight.bold,
|
||||||
acBloc.scheduledHours
|
),
|
||||||
.toString()
|
),
|
||||||
.padLeft(2, '0'),
|
Text('m',
|
||||||
style: Theme.of(context)
|
style: context.textTheme.bodySmall!
|
||||||
.textTheme
|
.copyWith(color: ColorsManager.blackColor)),
|
||||||
.titleLarge!
|
IconButton(
|
||||||
.copyWith(
|
padding: const EdgeInsets.all(0),
|
||||||
color: ColorsManager.dialogBlueTitle,
|
onPressed: () {},
|
||||||
fontWeight: FontWeight.bold,
|
icon: const Icon(
|
||||||
),
|
Icons.add,
|
||||||
),
|
size: 28,
|
||||||
Text(
|
color: ColorsManager.greyColor,
|
||||||
'h',
|
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodySmall!
|
|
||||||
.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
acBloc.scheduledMinutes
|
|
||||||
.toString()
|
|
||||||
.padLeft(2, '0'),
|
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.titleLarge!
|
|
||||||
.copyWith(
|
|
||||||
color: ColorsManager.dialogBlueTitle,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'm',
|
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodySmall!
|
|
||||||
.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
if (acBloc.timerActive == false) {
|
|
||||||
context
|
|
||||||
.read<AcBloc>()
|
|
||||||
.add(IncreaseTimeEvent());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.add,
|
|
||||||
color: ColorsManager.greyColor),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
value: acBloc.timerActive,
|
value: false,
|
||||||
code: 'ac_schedule',
|
code: 'ac_schedule',
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
icon: Assets.acSchedule,
|
icon: Assets.acSchedule,
|
||||||
onChange: (value) {
|
onChange: (value) {},
|
||||||
context.read<AcBloc>().add(ToggleScheduleEvent());
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ToggleWidget(
|
ToggleWidget(
|
||||||
deviceId: device.uuid!,
|
deviceId: device.uuid!,
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
class DeviceSubSpace {
|
|
||||||
String? id;
|
|
||||||
String? createdAt;
|
|
||||||
String? updatedAt;
|
|
||||||
String? subspaceName;
|
|
||||||
bool? disabled;
|
|
||||||
|
|
||||||
DeviceSubSpace({this.id, this.createdAt, this.updatedAt, this.subspaceName, this.disabled});
|
|
||||||
|
|
||||||
DeviceSubSpace.fromJson(Map<String, dynamic> json) {
|
|
||||||
id = json['uuid']?.toString() ?? '';
|
|
||||||
createdAt = json['createdAt']?.toString() ?? '';
|
|
||||||
updatedAt = json['updatedAt']?.toString() ?? '';
|
|
||||||
subspaceName = json['subspaceName']?.toString() ?? '';
|
|
||||||
subspaceName = json['subspaceName']?.toString() ?? '';
|
|
||||||
disabled = json['disabled'] ?? false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
class DeviceTagModel {
|
|
||||||
String? id;
|
|
||||||
String? createdAt;
|
|
||||||
String? updatedAt;
|
|
||||||
String? name;
|
|
||||||
|
|
||||||
DeviceTagModel({
|
|
||||||
this.id,
|
|
||||||
this.createdAt,
|
|
||||||
this.updatedAt,
|
|
||||||
this.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
DeviceTagModel.fromJson(Map<String, dynamic> json) {
|
|
||||||
id = json['uuid']?.toString() ?? '';
|
|
||||||
createdAt = json['createdAt']?.toString() ?? '';
|
|
||||||
updatedAt = json['updatedAt']?.toString() ?? '';
|
|
||||||
name = json['name']?.toString() ?? '';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,6 @@
|
|||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_community.model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_community.model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_space_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_space_model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_sub_space.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_subspace.model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_subspace.model.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_tag_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart';
|
import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart';
|
||||||
@ -10,7 +8,6 @@ import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
|||||||
import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart';
|
import 'package:syncrow_web/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart';
|
import 'package:syncrow_web/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/gateway.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/models/wps/wps_functions.dart';
|
import 'package:syncrow_web/pages/routines/models/wps/wps_functions.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/enum/device_types.dart';
|
import 'package:syncrow_web/utils/enum/device_types.dart';
|
||||||
@ -80,41 +77,38 @@ class AllDevicesModel {
|
|||||||
int? batteryLevel;
|
int? batteryLevel;
|
||||||
String? productName;
|
String? productName;
|
||||||
List<DeviceSpaceModel>? spaces;
|
List<DeviceSpaceModel>? spaces;
|
||||||
List<DeviceTagModel>? deviceTags;
|
|
||||||
DeviceSubSpace? deviceSubSpace;
|
|
||||||
|
|
||||||
AllDevicesModel(
|
AllDevicesModel({
|
||||||
{this.room,
|
this.room,
|
||||||
this.subspace,
|
this.subspace,
|
||||||
this.unit,
|
this.unit,
|
||||||
this.community,
|
this.community,
|
||||||
this.productUuid,
|
this.productUuid,
|
||||||
this.productType,
|
this.productType,
|
||||||
this.permissionType,
|
this.permissionType,
|
||||||
this.activeTime,
|
this.activeTime,
|
||||||
this.category,
|
this.category,
|
||||||
this.categoryName,
|
this.categoryName,
|
||||||
this.createTime,
|
this.createTime,
|
||||||
this.gatewayId,
|
this.gatewayId,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.ip,
|
this.ip,
|
||||||
this.lat,
|
this.lat,
|
||||||
this.localKey,
|
this.localKey,
|
||||||
this.lon,
|
this.lon,
|
||||||
this.model,
|
this.model,
|
||||||
this.name,
|
this.name,
|
||||||
this.nodeId,
|
this.nodeId,
|
||||||
this.online,
|
this.online,
|
||||||
this.ownerId,
|
this.ownerId,
|
||||||
this.sub,
|
this.sub,
|
||||||
this.timeZone,
|
this.timeZone,
|
||||||
this.updateTime,
|
this.updateTime,
|
||||||
this.uuid,
|
this.uuid,
|
||||||
this.batteryLevel,
|
this.batteryLevel,
|
||||||
this.productName,
|
this.productName,
|
||||||
this.spaces,
|
this.spaces,
|
||||||
this.deviceTags,
|
});
|
||||||
this.deviceSubSpace});
|
|
||||||
|
|
||||||
AllDevicesModel.fromJson(Map<String, dynamic> json) {
|
AllDevicesModel.fromJson(Map<String, dynamic> json) {
|
||||||
room = (json['room'] != null && (json['room'] is Map))
|
room = (json['room'] != null && (json['room'] is Map))
|
||||||
@ -152,15 +146,12 @@ class AllDevicesModel {
|
|||||||
updateTime = int.tryParse(json['updateTime']?.toString() ?? '');
|
updateTime = int.tryParse(json['updateTime']?.toString() ?? '');
|
||||||
uuid = json['uuid']?.toString();
|
uuid = json['uuid']?.toString();
|
||||||
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
|
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
|
||||||
|
|
||||||
productName = json['productName']?.toString();
|
productName = json['productName']?.toString();
|
||||||
deviceTags = json['deviceTag'] != null && json['deviceTag'] is List
|
|
||||||
? (json['deviceTag'] as List).map((tag) => DeviceTagModel.fromJson(tag)).toList()
|
|
||||||
: [];
|
|
||||||
deviceSubSpace = json['subspace'] != null
|
|
||||||
? DeviceSubSpace.fromJson(json['subspace'])
|
|
||||||
: DeviceSubSpace(subspaceName: '');
|
|
||||||
if (json['spaces'] != null && json['spaces'] is List) {
|
if (json['spaces'] != null && json['spaces'] is List) {
|
||||||
spaces = (json['spaces'] as List).map((space) => DeviceSpaceModel.fromJson(space)).toList();
|
spaces = (json['spaces'] as List)
|
||||||
|
.map((space) => DeviceSpaceModel.fromJson(space))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +199,8 @@ SOS
|
|||||||
String tempIcon = '';
|
String tempIcon = '';
|
||||||
if (type == DeviceType.LightBulb) {
|
if (type == DeviceType.LightBulb) {
|
||||||
tempIcon = Assets.lightBulb;
|
tempIcon = Assets.lightBulb;
|
||||||
} else if (type == DeviceType.CeilingSensor || type == DeviceType.WallSensor) {
|
} else if (type == DeviceType.CeilingSensor ||
|
||||||
|
type == DeviceType.WallSensor) {
|
||||||
tempIcon = Assets.sensors;
|
tempIcon = Assets.sensors;
|
||||||
} else if (type == DeviceType.AC) {
|
} else if (type == DeviceType.AC) {
|
||||||
tempIcon = Assets.ac;
|
tempIcon = Assets.ac;
|
||||||
@ -255,69 +247,76 @@ SOS
|
|||||||
switch (productType) {
|
switch (productType) {
|
||||||
case 'AC':
|
case 'AC':
|
||||||
return [
|
return [
|
||||||
SwitchFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
SwitchFunction(
|
||||||
ModeFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
TempSetFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
ModeFunction(
|
||||||
CurrentTempFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
LevelFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
TempSetFunction(
|
||||||
ChildLockFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
|
CurrentTempFunction(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
||||||
|
LevelFunction(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
|
ChildLockFunction(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
];
|
];
|
||||||
|
|
||||||
case '1G':
|
case '1G':
|
||||||
return [
|
return [
|
||||||
OneGangSwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
|
OneGangSwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||||
OneGangCountdownFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
|
OneGangCountdownFunction(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||||
];
|
];
|
||||||
|
|
||||||
case '2G':
|
case '2G':
|
||||||
return [
|
return [
|
||||||
TwoGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
TwoGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||||
TwoGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
TwoGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||||
TwoGangCountdown1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
TwoGangCountdown1Function(
|
||||||
TwoGangCountdown2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||||
|
TwoGangCountdown2Function(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||||
];
|
];
|
||||||
|
|
||||||
case '3G':
|
case '3G':
|
||||||
return [
|
return [
|
||||||
ThreeGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
ThreeGangSwitch1Function(
|
||||||
ThreeGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
ThreeGangSwitch3Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
ThreeGangSwitch2Function(
|
||||||
ThreeGangCountdown1Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
ThreeGangCountdown2Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
ThreeGangSwitch3Function(
|
||||||
ThreeGangCountdown3Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
|
ThreeGangCountdown1Function(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
|
ThreeGangCountdown2Function(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
|
ThreeGangCountdown3Function(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
];
|
];
|
||||||
case 'WPS':
|
case 'WPS':
|
||||||
return [
|
return [
|
||||||
//IF Functions
|
//IF Functions
|
||||||
PresenceStateFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
PresenceStateFunction(
|
||||||
CurrentDistanceFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
||||||
IlluminanceValueFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
CurrentDistanceFunction(
|
||||||
PresenceTimeFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
||||||
|
IlluminanceValueFunction(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
||||||
|
PresenceTimeFunction(
|
||||||
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
|
||||||
|
|
||||||
//THEN Functions
|
//THEN Functions
|
||||||
FarDetectionFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
FarDetectionFunction(
|
||||||
MotionSensitivityFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
||||||
MotionLessSensitivityFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
MotionSensitivityFunction(
|
||||||
IndicatorFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
||||||
NoOneTimeFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
MotionLessSensitivityFunction(
|
||||||
];
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
||||||
case 'GW':
|
IndicatorFunction(
|
||||||
return [
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
|
||||||
GatewaySwitchAlarmSound(
|
NoOneTimeFunction(
|
||||||
deviceId: uuid ?? '',
|
deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
|
||||||
deviceName: name ?? '',
|
|
||||||
type: 'BOTH',
|
|
||||||
),
|
|
||||||
GatewayMasterState(
|
|
||||||
deviceId: uuid ?? '',
|
|
||||||
deviceName: name ?? '',
|
|
||||||
type: 'BOTH',
|
|
||||||
),
|
|
||||||
GatewayFactoryReset(
|
|
||||||
deviceId: uuid ?? '',
|
|
||||||
deviceName: name ?? '',
|
|
||||||
type: 'BOTH',
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
default:
|
default:
|
||||||
return [];
|
return [];
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
class GatewayModel {
|
|
||||||
final String uuid;
|
|
||||||
final bool switchAlarmSound;
|
|
||||||
final String masterState;
|
|
||||||
final bool factoryReset;
|
|
||||||
final String alarmActive;
|
|
||||||
|
|
||||||
GatewayModel({
|
|
||||||
required this.uuid,
|
|
||||||
required this.switchAlarmSound,
|
|
||||||
required this.masterState,
|
|
||||||
required this.factoryReset,
|
|
||||||
required this.alarmActive,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory GatewayModel.fromJson(Map<String, dynamic> json) {
|
|
||||||
final status = json['status'] as List<dynamic>? ?? <dynamic>[];
|
|
||||||
|
|
||||||
bool? switchAlarmSound;
|
|
||||||
String? masterState;
|
|
||||||
bool? factoryReset;
|
|
||||||
String? alarmActive;
|
|
||||||
|
|
||||||
for (final item in status) {
|
|
||||||
switch (item['code']) {
|
|
||||||
case 'switch_alarm_sound':
|
|
||||||
switchAlarmSound = item['value'] as bool;
|
|
||||||
break;
|
|
||||||
case 'master_state':
|
|
||||||
masterState = item['value'] as String;
|
|
||||||
break;
|
|
||||||
case 'factory_reset':
|
|
||||||
factoryReset = item['value'] as bool;
|
|
||||||
break;
|
|
||||||
case 'alarm_active':
|
|
||||||
alarmActive = item['value'] as String;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GatewayModel(
|
|
||||||
uuid: json['uuid'] as String? ?? '',
|
|
||||||
switchAlarmSound: switchAlarmSound ?? false,
|
|
||||||
masterState: masterState ?? '',
|
|
||||||
factoryReset: factoryReset ?? false,
|
|
||||||
alarmActive: alarmActive ?? '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -62,6 +62,9 @@ class ToggleWidget extends StatelessWidget {
|
|||||||
)),
|
)),
|
||||||
if (showToggle)
|
if (showToggle)
|
||||||
Container(
|
Container(
|
||||||
|
height: 20,
|
||||||
|
width: 35,
|
||||||
|
padding: const EdgeInsets.only(right: 16, top: 10),
|
||||||
child: CupertinoSwitch(
|
child: CupertinoSwitch(
|
||||||
value: value,
|
value: value,
|
||||||
activeColor: ColorsManager.dialogBlueTitle,
|
activeColor: ColorsManager.dialogBlueTitle,
|
||||||
|
@ -13,8 +13,7 @@ import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_la
|
|||||||
|
|
||||||
import '../models/sos_status_model.dart';
|
import '../models/sos_status_model.dart';
|
||||||
|
|
||||||
class SosDeviceControlsView extends StatelessWidget
|
class SosDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
|
||||||
with HelperResponsiveLayout {
|
|
||||||
const SosDeviceControlsView({
|
const SosDeviceControlsView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.device,
|
required this.device,
|
||||||
@ -25,8 +24,7 @@ class SosDeviceControlsView extends StatelessWidget
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) =>
|
create: (context) => SosDeviceBloc()..add(GetDeviceStatus(device.uuid!)),
|
||||||
SosDeviceBloc()..add(GetDeviceStatus(device.uuid!)),
|
|
||||||
child: BlocBuilder<SosDeviceBloc, SosDeviceState>(
|
child: BlocBuilder<SosDeviceBloc, SosDeviceState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is SosDeviceLoadingState) {
|
if (state is SosDeviceLoadingState) {
|
||||||
@ -65,8 +63,7 @@ class SosDeviceControlsView extends StatelessWidget
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildStatusControls(
|
Widget _buildStatusControls(BuildContext context, SosStatusModel deviceStatus) {
|
||||||
BuildContext context, SosStatusModel deviceStatus) {
|
|
||||||
final isExtraLarge = isExtraLargeScreenSize(context);
|
final isExtraLarge = isExtraLargeScreenSize(context);
|
||||||
final isLarge = isLargeScreenSize(context);
|
final isLarge = isLargeScreenSize(context);
|
||||||
final isMedium = isMediumScreenSize(context);
|
final isMedium = isMediumScreenSize(context);
|
||||||
@ -88,7 +85,7 @@ class SosDeviceControlsView extends StatelessWidget
|
|||||||
IconNameStatusContainer(
|
IconNameStatusContainer(
|
||||||
isFullIcon: false,
|
isFullIcon: false,
|
||||||
name: deviceStatus.sosStatus == 'sos' ? 'SOS' : 'Normal',
|
name: deviceStatus.sosStatus == 'sos' ? 'SOS' : 'Normal',
|
||||||
icon: deviceStatus.sosStatus == 'sos' ? Assets.sosNormal : Assets.sos,
|
icon: deviceStatus.sosStatus == 'sos' ? Assets.sos : Assets.sosNormal,
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
status: false,
|
status: false,
|
||||||
textColor: ColorsManager.blackColor,
|
textColor: ColorsManager.blackColor,
|
||||||
|
@ -30,7 +30,6 @@ class FunctionBloc extends Bloc<FunctionBlocEvent, FunctionBlocState> {
|
|||||||
condition: event.functionData.condition ?? existingData.condition,
|
condition: event.functionData.condition ?? existingData.condition,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
functions.clear();
|
|
||||||
functions.add(event.functionData);
|
functions.add(event.functionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
TriggerSwitchTabsEvent event,
|
TriggerSwitchTabsEvent event,
|
||||||
Emitter<RoutineState> emit,
|
Emitter<RoutineState> emit,
|
||||||
) {
|
) {
|
||||||
emit(state.copyWith(routineTab: event.isRoutineTab, createRoutineView: false));
|
emit(state.copyWith(
|
||||||
|
routineTab: event.isRoutineTab, createRoutineView: false));
|
||||||
add(ResetRoutineState());
|
add(ResetRoutineState());
|
||||||
if (event.isRoutineTab) {
|
if (event.isRoutineTab) {
|
||||||
add(const LoadScenes());
|
add(const LoadScenes());
|
||||||
@ -90,8 +91,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems);
|
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems);
|
||||||
|
|
||||||
// Find the index of the item in teh current itemsList
|
// Find the index of the item in teh current itemsList
|
||||||
int index =
|
int index = updatedIfItems.indexWhere(
|
||||||
updatedIfItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
(map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
||||||
// Replace the map if the index is valid
|
// Replace the map if the index is valid
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
updatedIfItems[index] = event.item;
|
updatedIfItems[index] = event.item;
|
||||||
@ -100,18 +101,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event.isTabToRun) {
|
if (event.isTabToRun) {
|
||||||
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
|
emit(state.copyWith(
|
||||||
|
ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
|
emit(state.copyWith(
|
||||||
|
ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddToThenContainer(AddToThenContainer event, Emitter<RoutineState> emit) {
|
void _onAddToThenContainer(
|
||||||
|
AddToThenContainer event, Emitter<RoutineState> emit) {
|
||||||
final currentItems = List<Map<String, dynamic>>.from(state.thenItems);
|
final currentItems = List<Map<String, dynamic>>.from(state.thenItems);
|
||||||
|
|
||||||
// Find the index of the item in teh current itemsList
|
// Find the index of the item in teh current itemsList
|
||||||
int index =
|
int index = currentItems.indexWhere(
|
||||||
currentItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
(map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
|
||||||
// Replace the map if the index is valid
|
// Replace the map if the index is valid
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
currentItems[index] = event.item;
|
currentItems[index] = event.item;
|
||||||
@ -122,42 +126,45 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
emit(state.copyWith(thenItems: currentItems));
|
emit(state.copyWith(thenItems: currentItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddFunctionsToRoutine(AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
void _onAddFunctionsToRoutine(
|
||||||
|
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
||||||
try {
|
try {
|
||||||
if (event.functions.isEmpty) return;
|
if (event.functions.isEmpty) return;
|
||||||
|
|
||||||
// List<DeviceFunctionData> selectedFunction = List<DeviceFunctionData>.from(event.functions);
|
List<DeviceFunctionData> selectedFunction =
|
||||||
|
List<DeviceFunctionData>.from(event.functions);
|
||||||
|
|
||||||
Map<String, List<DeviceFunctionData>> currentSelectedFunctions =
|
Map<String, List<DeviceFunctionData>> currentSelectedFunctions =
|
||||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
||||||
|
List<DeviceFunctionData> currentFunctions =
|
||||||
|
List<DeviceFunctionData>.from(
|
||||||
|
currentSelectedFunctions[event.uniqueCustomId] ?? []);
|
||||||
|
|
||||||
// if (currentSelectedFunctions.containsKey(event.uniqueCustomId)) {
|
List<String> functionCode = [];
|
||||||
// List<DeviceFunctionData> currentFunctions =
|
for (int i = 0; i < selectedFunction.length; i++) {
|
||||||
// List<DeviceFunctionData>.from(currentSelectedFunctions[event.uniqueCustomId] ?? []);
|
for (int j = 0; j < currentFunctions.length; j++) {
|
||||||
|
if (selectedFunction[i].functionCode ==
|
||||||
|
currentFunctions[j].functionCode) {
|
||||||
|
currentFunctions[j] = selectedFunction[i];
|
||||||
|
if (!functionCode.contains(currentFunctions[j].functionCode)) {
|
||||||
|
functionCode.add(currentFunctions[j].functionCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// List<String> functionCode = [];
|
for (int i = 0; i < functionCode.length; i++) {
|
||||||
// for (int i = 0; i < selectedFunction.length; i++) {
|
selectedFunction
|
||||||
// for (int j = 0; j < currentFunctions.length; j++) {
|
.removeWhere((code) => code.functionCode == functionCode[i]);
|
||||||
// if (selectedFunction[i].functionCode == currentFunctions[j].functionCode) {
|
}
|
||||||
// currentFunctions[j] = selectedFunction[i];
|
|
||||||
// if (!functionCode.contains(currentFunctions[j].functionCode)) {
|
|
||||||
// functionCode.add(currentFunctions[j].functionCode);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (int i = 0; i < functionCode.length; i++) {
|
currentSelectedFunctions[event.uniqueCustomId] =
|
||||||
// selectedFunction.removeWhere((code) => code.functionCode == functionCode[i]);
|
List.from(currentFunctions)..addAll(selectedFunction);
|
||||||
// }
|
} else {
|
||||||
|
currentSelectedFunctions[event.uniqueCustomId] =
|
||||||
// currentSelectedFunctions[event.uniqueCustomId] = List.from(currentFunctions)
|
List.from(event.functions);
|
||||||
// ..addAll(selectedFunction);
|
}
|
||||||
// } else {
|
|
||||||
// currentSelectedFunctions[event.uniqueCustomId] = List.from(event.functions);
|
|
||||||
// }
|
|
||||||
|
|
||||||
currentSelectedFunctions[event.uniqueCustomId] = List.from(event.functions);
|
|
||||||
|
|
||||||
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -165,24 +172,30 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onLoadScenes(LoadScenes event, Emitter<RoutineState> emit) async {
|
Future<void> _onLoadScenes(
|
||||||
|
LoadScenes event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||||
List<ScenesModel> scenes = [];
|
List<ScenesModel> scenes = [];
|
||||||
try {
|
try {
|
||||||
BuildContext context = NavigationService.navigatorKey.currentContext!;
|
BuildContext context = NavigationService.navigatorKey.currentContext!;
|
||||||
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') {
|
if (createRoutineBloc.selectedSpaceId == '' &&
|
||||||
|
createRoutineBloc.selectedCommunityId == '') {
|
||||||
var spaceBloc = context.read<SpaceTreeBloc>();
|
var spaceBloc = context.read<SpaceTreeBloc>();
|
||||||
for (var communityId in spaceBloc.state.selectedCommunities) {
|
for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||||
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
List<String> spacesList =
|
||||||
|
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||||
for (var spaceId in spacesList) {
|
for (var spaceId in spacesList) {
|
||||||
scenes.addAll(await SceneApi.getScenes(spaceId, communityId, projectUuid));
|
scenes.addAll(
|
||||||
|
await SceneApi.getScenes(spaceId, communityId, projectUuid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scenes.addAll(await SceneApi.getScenes(
|
scenes.addAll(await SceneApi.getScenes(
|
||||||
createRoutineBloc.selectedSpaceId, createRoutineBloc.selectedCommunityId, projectUuid));
|
createRoutineBloc.selectedSpaceId,
|
||||||
|
createRoutineBloc.selectedCommunityId,
|
||||||
|
projectUuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
@ -199,7 +212,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<RoutineState> emit) async {
|
Future<void> _onLoadAutomation(
|
||||||
|
LoadAutomation event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||||
List<ScenesModel> automations = [];
|
List<ScenesModel> automations = [];
|
||||||
final projectId = await ProjectManager.getProjectUUID() ?? '';
|
final projectId = await ProjectManager.getProjectUUID() ?? '';
|
||||||
@ -207,17 +221,23 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
BuildContext context = NavigationService.navigatorKey.currentContext!;
|
BuildContext context = NavigationService.navigatorKey.currentContext!;
|
||||||
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
||||||
try {
|
try {
|
||||||
if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') {
|
|
||||||
|
if (createRoutineBloc.selectedSpaceId == '' &&
|
||||||
|
createRoutineBloc.selectedCommunityId == '') {
|
||||||
var spaceBloc = context.read<SpaceTreeBloc>();
|
var spaceBloc = context.read<SpaceTreeBloc>();
|
||||||
for (var communityId in spaceBloc.state.selectedCommunities) {
|
for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||||
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
List<String> spacesList =
|
||||||
|
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||||
for (var spaceId in spacesList) {
|
for (var spaceId in spacesList) {
|
||||||
automations.addAll(await SceneApi.getAutomation(spaceId, communityId, projectId));
|
automations.addAll(
|
||||||
|
await SceneApi.getAutomation(spaceId, communityId, projectId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
automations.addAll(await SceneApi.getAutomation(
|
automations.addAll(await SceneApi.getAutomation(
|
||||||
createRoutineBloc.selectedSpaceId, createRoutineBloc.selectedCommunityId, projectId));
|
createRoutineBloc.selectedSpaceId,
|
||||||
|
createRoutineBloc.selectedCommunityId,
|
||||||
|
projectId));
|
||||||
}
|
}
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
automations: automations,
|
automations: automations,
|
||||||
@ -233,14 +253,16 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onSearchRoutines(SearchRoutines event, Emitter<RoutineState> emit) async {
|
FutureOr<void> _onSearchRoutines(
|
||||||
|
SearchRoutines event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
emit(state.copyWith(isLoading: false, errorMessage: null));
|
emit(state.copyWith(isLoading: false, errorMessage: null));
|
||||||
emit(state.copyWith(searchText: event.query));
|
emit(state.copyWith(searchText: event.query));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onAddSelectedIcon(AddSelectedIcon event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onAddSelectedIcon(
|
||||||
|
AddSelectedIcon event, Emitter<RoutineState> emit) {
|
||||||
emit(state.copyWith(selectedIcon: event.icon));
|
emit(state.copyWith(selectedIcon: event.icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +276,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
return actions.last['deviceId'] == 'delay';
|
return actions.last['deviceId'] == 'delay';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onCreateScene(CreateSceneEvent event, Emitter<RoutineState> emit) async {
|
Future<void> _onCreateScene(
|
||||||
|
CreateSceneEvent event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
// Check if first action is delay
|
// Check if first action is delay
|
||||||
// if (_isFirstActionDelay(state.thenItems)) {
|
// if (_isFirstActionDelay(state.thenItems)) {
|
||||||
@ -267,7 +290,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
if (_isLastActionDelay(state.thenItems)) {
|
if (_isLastActionDelay(state.thenItems)) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
errorMessage: 'A delay condition cannot be the only or the last action',
|
errorMessage:
|
||||||
|
'A delay condition cannot be the only or the last action',
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
@ -343,7 +367,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onCreateAutomation(CreateAutomationEvent event, Emitter<RoutineState> emit) async {
|
Future<void> _onCreateAutomation(
|
||||||
|
CreateAutomationEvent event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
if (state.routineName == null || state.routineName!.isEmpty) {
|
if (state.routineName == null || state.routineName!.isEmpty) {
|
||||||
@ -365,7 +390,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
if (_isLastActionDelay(state.thenItems)) {
|
if (_isLastActionDelay(state.thenItems)) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
errorMessage: 'A delay condition cannot be the only or the last action',
|
errorMessage:
|
||||||
|
'A delay condition cannot be the only or the last action',
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
));
|
));
|
||||||
CustomSnackBar.redSnackBar('Cannot have delay as the last action');
|
CustomSnackBar.redSnackBar('Cannot have delay as the last action');
|
||||||
@ -456,7 +482,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
actions: actions,
|
actions: actions,
|
||||||
);
|
);
|
||||||
|
|
||||||
final result = await SceneApi.createAutomation(createAutomationModel, projectUuid);
|
final result =
|
||||||
|
await SceneApi.createAutomation(createAutomationModel, projectUuid);
|
||||||
if (result['success']) {
|
if (result['success']) {
|
||||||
add(ResetRoutineState());
|
add(ResetRoutineState());
|
||||||
add(const LoadAutomation());
|
add(const LoadAutomation());
|
||||||
@ -477,17 +504,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onRemoveDragCard(RemoveDragCard event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onRemoveDragCard(
|
||||||
|
RemoveDragCard event, Emitter<RoutineState> emit) {
|
||||||
if (event.isFromThen) {
|
if (event.isFromThen) {
|
||||||
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
|
final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
|
||||||
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
final selectedFunctions =
|
||||||
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
|
||||||
thenItems.removeAt(event.index);
|
thenItems.removeAt(event.index);
|
||||||
selectedFunctions.remove(event.key);
|
selectedFunctions.remove(event.key);
|
||||||
emit(state.copyWith(thenItems: thenItems, selectedFunctions: selectedFunctions));
|
emit(state.copyWith(
|
||||||
|
thenItems: thenItems, selectedFunctions: selectedFunctions));
|
||||||
} else {
|
} else {
|
||||||
final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
|
final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
|
||||||
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
final selectedFunctions =
|
||||||
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
|
||||||
ifItems.removeAt(event.index);
|
ifItems.removeAt(event.index);
|
||||||
selectedFunctions.remove(event.key);
|
selectedFunctions.remove(event.key);
|
||||||
@ -498,7 +529,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
isAutomation: false,
|
isAutomation: false,
|
||||||
isTabToRun: false));
|
isTabToRun: false));
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(ifItems: ifItems, selectedFunctions: selectedFunctions));
|
emit(state.copyWith(
|
||||||
|
ifItems: ifItems, selectedFunctions: selectedFunctions));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,138 +542,141 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onEffectiveTimeEvent(EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onEffectiveTimeEvent(
|
||||||
|
EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
|
||||||
emit(state.copyWith(effectiveTime: event.effectiveTime));
|
emit(state.copyWith(effectiveTime: event.effectiveTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onSetRoutineName(SetRoutineName event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onSetRoutineName(
|
||||||
|
SetRoutineName event, Emitter<RoutineState> emit) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
routineName: event.name,
|
routineName: event.name,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// (
|
(
|
||||||
// List<Map<String, dynamic>>,
|
List<Map<String, dynamic>>,
|
||||||
// List<Map<String, dynamic>>,
|
List<Map<String, dynamic>>,
|
||||||
// Map<String, List<DeviceFunctionData>>
|
Map<String, List<DeviceFunctionData>>
|
||||||
// ) _createCardData(
|
) _createCardData(
|
||||||
// List<RoutineAction> actions,
|
List<RoutineAction> actions,
|
||||||
// List<RoutineCondition>? conditions,
|
List<RoutineCondition>? conditions,
|
||||||
// Map<String, List<DeviceFunctionData>> currentFunctions,
|
Map<String, List<DeviceFunctionData>> currentFunctions,
|
||||||
// bool isTabToRun,
|
bool isTabToRun,
|
||||||
// ) {
|
) {
|
||||||
// final ifItems = isTabToRun
|
final ifItems = isTabToRun
|
||||||
// ? [
|
? [
|
||||||
// {
|
{
|
||||||
// 'entityId': 'tab_to_run',
|
'entityId': 'tab_to_run',
|
||||||
// 'uniqueCustomId': const Uuid().v4(),
|
'uniqueCustomId': const Uuid().v4(),
|
||||||
// 'deviceId': 'tab_to_run',
|
'deviceId': 'tab_to_run',
|
||||||
// 'title': 'Tab to run',
|
'title': 'Tab to run',
|
||||||
// 'productType': 'tab_to_run',
|
'productType': 'tab_to_run',
|
||||||
// 'imagePath': Assets.tabToRun,
|
'imagePath': Assets.tabToRun,
|
||||||
// }
|
}
|
||||||
// ]
|
]
|
||||||
// : conditions?.map((condition) {
|
: conditions?.map((condition) {
|
||||||
// final matchingDevice = state.devices.firstWhere(
|
final matchingDevice = state.devices.firstWhere(
|
||||||
// (device) => device.uuid == condition.entityId,
|
(device) => device.uuid == condition.entityId,
|
||||||
// orElse: () => AllDevicesModel(
|
orElse: () => AllDevicesModel(
|
||||||
// uuid: condition.entityId,
|
uuid: condition.entityId,
|
||||||
// name: condition.entityId,
|
name: condition.entityId,
|
||||||
// productType: condition.entityType,
|
productType: condition.entityType,
|
||||||
// ),
|
),
|
||||||
// );
|
);
|
||||||
|
|
||||||
// final cardData = {
|
final cardData = {
|
||||||
// 'entityId': condition.entityId,
|
'entityId': condition.entityId,
|
||||||
// 'uniqueCustomId': const Uuid().v4(),
|
'uniqueCustomId': const Uuid().v4(),
|
||||||
// 'deviceId': condition.entityId,
|
'deviceId': condition.entityId,
|
||||||
// 'title': matchingDevice.name ?? condition.entityId,
|
'title': matchingDevice.name ?? condition.entityId,
|
||||||
// 'productType': condition.entityType,
|
'productType': condition.entityType,
|
||||||
// 'imagePath':
|
'imagePath':
|
||||||
// matchingDevice.getDefaultIcon(condition.entityType),
|
matchingDevice.getDefaultIcon(condition.entityType),
|
||||||
// };
|
};
|
||||||
|
|
||||||
// final functions = matchingDevice.functions;
|
final functions = matchingDevice.functions;
|
||||||
|
|
||||||
// for (var function in functions) {
|
for (var function in functions) {
|
||||||
// if (function.code == condition.expr.statusCode) {
|
if (function.code == condition.expr.statusCode) {
|
||||||
// currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
||||||
// DeviceFunctionData(
|
DeviceFunctionData(
|
||||||
// entityId: condition.entityId,
|
entityId: condition.entityId,
|
||||||
// functionCode: condition.expr.statusCode,
|
functionCode: condition.expr.statusCode,
|
||||||
// value: condition.expr.statusValue,
|
value: condition.expr.statusValue,
|
||||||
// operationName: function.operationName,
|
operationName: function.operationName,
|
||||||
// ),
|
),
|
||||||
// ];
|
];
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return cardData;
|
return cardData;
|
||||||
// }).toList() ??
|
}).toList() ??
|
||||||
// [];
|
[];
|
||||||
|
|
||||||
// final thenItems = actions.map((action) {
|
final thenItems = actions.map((action) {
|
||||||
// final matchingDevice = state.devices.firstWhere(
|
final matchingDevice = state.devices.firstWhere(
|
||||||
// (device) => device.uuid == action.entityId,
|
(device) => device.uuid == action.entityId,
|
||||||
// orElse: () => AllDevicesModel(
|
orElse: () => AllDevicesModel(
|
||||||
// uuid: action.entityId,
|
uuid: action.entityId,
|
||||||
// name: action.entityId,
|
name: action.entityId,
|
||||||
// productType: action.productType,
|
productType: action.productType,
|
||||||
// ),
|
),
|
||||||
// );
|
);
|
||||||
|
|
||||||
// final cardData = {
|
final cardData = {
|
||||||
// 'entityId': action.entityId,
|
'entityId': action.entityId,
|
||||||
// 'uniqueCustomId': const Uuid().v4(),
|
'uniqueCustomId': const Uuid().v4(),
|
||||||
// 'deviceId':
|
'deviceId':
|
||||||
// action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||||
// 'title': action.actionExecutor == 'delay'
|
'title': action.actionExecutor == 'delay'
|
||||||
// ? 'Delay'
|
? 'Delay'
|
||||||
// : (matchingDevice.name ?? 'Device'),
|
: (matchingDevice.name ?? 'Device'),
|
||||||
// 'productType': action.productType,
|
'productType': action.productType,
|
||||||
// 'imagePath': matchingDevice.getDefaultIcon(action.productType),
|
'imagePath': matchingDevice.getDefaultIcon(action.productType),
|
||||||
// };
|
};
|
||||||
|
|
||||||
// final functions = matchingDevice.functions;
|
final functions = matchingDevice.functions;
|
||||||
|
|
||||||
// if (action.executorProperty != null && action.actionExecutor != 'delay') {
|
if (action.executorProperty != null && action.actionExecutor != 'delay') {
|
||||||
// final functionCode = action.executorProperty!.functionCode;
|
final functionCode = action.executorProperty!.functionCode;
|
||||||
// for (var function in functions) {
|
for (var function in functions) {
|
||||||
// if (function.code == functionCode) {
|
if (function.code == functionCode) {
|
||||||
// currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
||||||
// DeviceFunctionData(
|
DeviceFunctionData(
|
||||||
// entityId: action.entityId,
|
entityId: action.entityId,
|
||||||
// functionCode: functionCode ?? '',
|
functionCode: functionCode ?? '',
|
||||||
// value: action.executorProperty!.functionValue,
|
value: action.executorProperty!.functionValue,
|
||||||
// operationName: function.operationName,
|
operationName: function.operationName,
|
||||||
// ),
|
),
|
||||||
// ];
|
];
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// } else if (action.actionExecutor == 'delay') {
|
} else if (action.actionExecutor == 'delay') {
|
||||||
// final delayFunction = DelayFunction(
|
final delayFunction = DelayFunction(
|
||||||
// deviceId: action.entityId,
|
deviceId: action.entityId,
|
||||||
// deviceName: 'Delay',
|
deviceName: 'Delay',
|
||||||
// );
|
);
|
||||||
// currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
currentFunctions[cardData['uniqueCustomId'] ?? ''] = [
|
||||||
// DeviceFunctionData(
|
DeviceFunctionData(
|
||||||
// entityId: action.entityId,
|
entityId: action.entityId,
|
||||||
// functionCode: 'delay',
|
functionCode: 'delay',
|
||||||
// value: action.executorProperty?.delaySeconds ?? 0,
|
value: action.executorProperty?.delaySeconds ?? 0,
|
||||||
// operationName: delayFunction.operationName,
|
operationName: delayFunction.operationName,
|
||||||
// ),
|
),
|
||||||
// ];
|
];
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return cardData;
|
return cardData;
|
||||||
// }).toList();
|
}).toList();
|
||||||
|
|
||||||
// return (thenItems, ifItems, currentFunctions);
|
return (thenItems, ifItems, currentFunctions);
|
||||||
// }
|
}
|
||||||
|
|
||||||
Future<void> _onGetSceneDetails(GetSceneDetails event, Emitter<RoutineState> emit) async {
|
Future<void> _onGetSceneDetails(
|
||||||
|
GetSceneDetails event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
@ -689,10 +724,12 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
if (!deviceCards.containsKey(deviceId)) {
|
if (!deviceCards.containsKey(deviceId)) {
|
||||||
deviceCards[deviceId] = {
|
deviceCards[deviceId] = {
|
||||||
'entityId': action.entityId,
|
'entityId': action.entityId,
|
||||||
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
'deviceId':
|
||||||
'uniqueCustomId': action.type == 'automation' || action.actionExecutor == 'delay'
|
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||||
? const Uuid().v4()
|
'uniqueCustomId':
|
||||||
: action.entityId,
|
action.type == 'automation' || action.actionExecutor == 'delay'
|
||||||
|
? const Uuid().v4()
|
||||||
|
: action.entityId,
|
||||||
'title': action.actionExecutor == 'delay'
|
'title': action.actionExecutor == 'delay'
|
||||||
? 'Delay'
|
? 'Delay'
|
||||||
: action.type == 'automation'
|
: action.type == 'automation'
|
||||||
@ -727,15 +764,16 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
// emit(state.copyWith(automationActionExecutor: action.actionExecutor));
|
// emit(state.copyWith(automationActionExecutor: action.actionExecutor));
|
||||||
} else if (action.executorProperty != null && action.actionExecutor != 'delay') {
|
} else if (action.executorProperty != null &&
|
||||||
// if (!updatedFunctions.containsKey(uniqueCustomId)) {
|
action.actionExecutor != 'delay') {
|
||||||
// updatedFunctions[uniqueCustomId] = [];
|
if (!updatedFunctions.containsKey(uniqueCustomId)) {
|
||||||
// }
|
updatedFunctions[uniqueCustomId] = [];
|
||||||
|
}
|
||||||
final functions = matchingDevice?.functions;
|
final functions = matchingDevice?.functions;
|
||||||
final functionCode = action.executorProperty?.functionCode;
|
final functionCode = action.executorProperty?.functionCode;
|
||||||
for (DeviceFunction function in functions ?? []) {
|
for (DeviceFunction function in functions ?? []) {
|
||||||
if (function.code == functionCode) {
|
if (function.code == functionCode) {
|
||||||
updatedFunctions[const Uuid().v4()]!.add(
|
updatedFunctions[uniqueCustomId]!.add(
|
||||||
DeviceFunctionData(
|
DeviceFunctionData(
|
||||||
entityId: action.entityId,
|
entityId: action.entityId,
|
||||||
functionCode: functionCode ?? '',
|
functionCode: functionCode ?? '',
|
||||||
@ -799,7 +837,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onResetRoutineState(ResetRoutineState event, Emitter<RoutineState> emit) {
|
FutureOr<void> _onResetRoutineState(
|
||||||
|
ResetRoutineState event, Emitter<RoutineState> emit) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
ifItems: [],
|
ifItems: [],
|
||||||
thenItems: [],
|
thenItems: [],
|
||||||
@ -822,7 +861,6 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
isUpdate: false,
|
isUpdate: false,
|
||||||
createRoutineView: false));
|
createRoutineView: false));
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _deleteScene(DeleteScene event, Emitter<RoutineState> emit) async {
|
FutureOr<void> _deleteScene(DeleteScene event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
final projectId = await ProjectManager.getProjectUUID() ?? '';
|
final projectId = await ProjectManager.getProjectUUID() ?? '';
|
||||||
@ -862,7 +900,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FutureOr<void> _deleteAutomation(DeleteAutomation event, Emitter<RoutineState> emit) {
|
// FutureOr<void> _deleteAutomation(DeleteAutomation event, Emitter<RoutineState> emit) {
|
||||||
// try {
|
// try {
|
||||||
// emit(state.copyWith(isLoading: true));
|
// emit(state.copyWith(isLoading: true));
|
||||||
@ -877,7 +915,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
FutureOr<void> _fetchDevices(FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
|
FutureOr<void> _fetchDevices(
|
||||||
|
FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true));
|
emit(state.copyWith(isLoading: true));
|
||||||
try {
|
try {
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
@ -886,17 +925,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
||||||
var spaceBloc = context.read<SpaceTreeBloc>();
|
var spaceBloc = context.read<SpaceTreeBloc>();
|
||||||
|
|
||||||
if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') {
|
if (createRoutineBloc.selectedSpaceId == '' &&
|
||||||
|
createRoutineBloc.selectedCommunityId == '') {
|
||||||
for (var communityId in spaceBloc.state.selectedCommunities) {
|
for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||||
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
List<String> spacesList =
|
||||||
|
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||||
for (var spaceId in spacesList) {
|
for (var spaceId in spacesList) {
|
||||||
devices.addAll(
|
devices.addAll(await DevicesManagementApi()
|
||||||
await DevicesManagementApi().fetchDevices(communityId, spaceId, projectUuid));
|
.fetchDevices(communityId, spaceId, projectUuid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
devices.addAll(await DevicesManagementApi().fetchDevices(
|
devices.addAll(await DevicesManagementApi().fetchDevices(
|
||||||
createRoutineBloc.selectedCommunityId, createRoutineBloc.selectedSpaceId, projectUuid));
|
createRoutineBloc.selectedCommunityId,
|
||||||
|
createRoutineBloc.selectedSpaceId,
|
||||||
|
projectUuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(state.copyWith(isLoading: false, devices: devices));
|
emit(state.copyWith(isLoading: false, devices: devices));
|
||||||
@ -905,7 +948,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onUpdateScene(UpdateScene event, Emitter<RoutineState> emit) async {
|
FutureOr<void> _onUpdateScene(
|
||||||
|
UpdateScene event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
// Check if first action is delay
|
// Check if first action is delay
|
||||||
// if (_isFirstActionDelay(state.thenItems)) {
|
// if (_isFirstActionDelay(state.thenItems)) {
|
||||||
@ -919,7 +963,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
if (_isLastActionDelay(state.thenItems)) {
|
if (_isLastActionDelay(state.thenItems)) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
errorMessage: 'A delay condition cannot be the only or the last action',
|
errorMessage:
|
||||||
|
'A delay condition cannot be the only or the last action',
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
@ -972,7 +1017,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
actions: actions,
|
actions: actions,
|
||||||
);
|
);
|
||||||
|
|
||||||
final result = await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
|
final result =
|
||||||
|
await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
|
||||||
if (result['success']) {
|
if (result['success']) {
|
||||||
add(ResetRoutineState());
|
add(ResetRoutineState());
|
||||||
add(const LoadScenes());
|
add(const LoadScenes());
|
||||||
@ -991,7 +1037,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<void> _onUpdateAutomation(UpdateAutomation event, Emitter<RoutineState> emit) async {
|
FutureOr<void> _onUpdateAutomation(
|
||||||
|
UpdateAutomation event, Emitter<RoutineState> emit) async {
|
||||||
try {
|
try {
|
||||||
if (state.routineName == null || state.routineName!.isEmpty) {
|
if (state.routineName == null || state.routineName!.isEmpty) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
@ -1206,13 +1253,15 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final deviceId =
|
final deviceId = action.actionExecutor == 'delay'
|
||||||
action.actionExecutor == 'delay' ? '${action.entityId}_delay' : action.entityId;
|
? '${action.entityId}_delay'
|
||||||
|
: action.entityId;
|
||||||
|
|
||||||
if (!deviceThenCards.containsKey(deviceId)) {
|
if (!deviceThenCards.containsKey(deviceId)) {
|
||||||
deviceThenCards[deviceId] = {
|
deviceThenCards[deviceId] = {
|
||||||
'entityId': action.entityId,
|
'entityId': action.entityId,
|
||||||
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
'deviceId':
|
||||||
|
action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||||
'uniqueCustomId': const Uuid().v4(),
|
'uniqueCustomId': const Uuid().v4(),
|
||||||
'title': action.actionExecutor == 'delay'
|
'title': action.actionExecutor == 'delay'
|
||||||
? 'Delay'
|
? 'Delay'
|
||||||
@ -1232,7 +1281,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
: action.type == 'automation'
|
: action.type == 'automation'
|
||||||
? 'automation'
|
? 'automation'
|
||||||
: 'action',
|
: 'action',
|
||||||
'icon': action.icon ?? '',
|
'icon': action.icon ?? ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1243,7 +1292,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
updatedFunctions[uniqueCustomId] = [];
|
updatedFunctions[uniqueCustomId] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.executorProperty != null && action.actionExecutor != 'delay') {
|
if (action.executorProperty != null &&
|
||||||
|
action.actionExecutor != 'delay') {
|
||||||
final functions = matchingDevice.functions;
|
final functions = matchingDevice.functions;
|
||||||
final functionCode = action.executorProperty!.functionCode;
|
final functionCode = action.executorProperty!.functionCode;
|
||||||
for (var function in functions) {
|
for (var function in functions) {
|
||||||
@ -1285,10 +1335,14 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ifItems = deviceIfCards.values.where((card) => card['type'] == 'condition').toList();
|
final ifItems = deviceIfCards.values
|
||||||
|
.where((card) => card['type'] == 'condition')
|
||||||
|
.toList();
|
||||||
final thenItems = deviceThenCards.values
|
final thenItems = deviceThenCards.values
|
||||||
.where((card) =>
|
.where((card) =>
|
||||||
card['type'] == 'action' || card['type'] == 'automation' || card['type'] == 'scene')
|
card['type'] == 'action' ||
|
||||||
|
card['type'] == 'automation' ||
|
||||||
|
card['type'] == 'scene')
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
@ -1310,7 +1364,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSceneTrigger(SceneTrigger event, Emitter<RoutineState> emit) async {
|
Future<void> _onSceneTrigger(
|
||||||
|
SceneTrigger event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(loadingSceneId: event.sceneId));
|
emit(state.copyWith(loadingSceneId: event.sceneId));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -1352,24 +1407,29 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
final updatedAutomations = await SceneApi.getAutomationByUnitId(
|
final updatedAutomations = await SceneApi.getAutomationByUnitId(
|
||||||
event.automationStatusUpdate.spaceUuid, event.communityId, projectId);
|
event.automationStatusUpdate.spaceUuid,
|
||||||
|
event.communityId,
|
||||||
|
projectId);
|
||||||
|
|
||||||
// Remove from loading set safely
|
// Remove from loading set safely
|
||||||
final updatedLoadingIds = {...state.loadingAutomationIds!}..remove(event.automationId);
|
final updatedLoadingIds = {...state.loadingAutomationIds!}
|
||||||
|
..remove(event.automationId);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
automations: updatedAutomations,
|
automations: updatedAutomations,
|
||||||
loadingAutomationIds: updatedLoadingIds,
|
loadingAutomationIds: updatedLoadingIds,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
final updatedLoadingIds = {...state.loadingAutomationIds!}..remove(event.automationId);
|
final updatedLoadingIds = {...state.loadingAutomationIds!}
|
||||||
|
..remove(event.automationId);
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
loadingAutomationIds: updatedLoadingIds,
|
loadingAutomationIds: updatedLoadingIds,
|
||||||
errorMessage: 'Update failed',
|
errorMessage: 'Update failed',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
final updatedLoadingIds = {...state.loadingAutomationIds!}..remove(event.automationId);
|
final updatedLoadingIds = {...state.loadingAutomationIds!}
|
||||||
|
..remove(event.automationId);
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
loadingAutomationIds: updatedLoadingIds,
|
loadingAutomationIds: updatedLoadingIds,
|
||||||
errorMessage: 'Update error: ${e.toString()}',
|
errorMessage: 'Update error: ${e.toString()}',
|
||||||
|
@ -63,11 +63,7 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 15, right: 15),
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
child: CommunityDropdown(
|
child: CommunityDropdown(
|
||||||
communities: _bloc.communities..sort(
|
communities: _bloc.communities,
|
||||||
(a, b) => a.name.toLowerCase().compareTo(
|
|
||||||
b.name.toLowerCase(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
selectedValue: _selectedCommunity,
|
selectedValue: _selectedCommunity,
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -3,7 +3,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ac_dialog.dart';
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ac_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_helper.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart';
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart';
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart';
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart';
|
||||||
@ -50,6 +49,7 @@ class DeviceDialogHelper {
|
|||||||
final deviceSelectedFunctions =
|
final deviceSelectedFunctions =
|
||||||
routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? [];
|
routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? [];
|
||||||
|
|
||||||
|
|
||||||
switch (productType) {
|
switch (productType) {
|
||||||
case 'AC':
|
case 'AC':
|
||||||
return ACHelper.showACFunctionsDialog(
|
return ACHelper.showACFunctionsDialog(
|
||||||
@ -98,15 +98,6 @@ class DeviceDialogHelper {
|
|||||||
deviceSelectedFunctions: deviceSelectedFunctions,
|
deviceSelectedFunctions: deviceSelectedFunctions,
|
||||||
uniqueCustomId: data['uniqueCustomId'],
|
uniqueCustomId: data['uniqueCustomId'],
|
||||||
removeComparetors: removeComparetors);
|
removeComparetors: removeComparetors);
|
||||||
case 'GW':
|
|
||||||
return GatewayHelper.showGatewayFunctionsDialog(
|
|
||||||
context: context,
|
|
||||||
functions: functions,
|
|
||||||
uniqueCustomId: data['uniqueCustomId'],
|
|
||||||
deviceSelectedFunctions: deviceSelectedFunctions,
|
|
||||||
device: data['device'],
|
|
||||||
);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
|
||||||
|
|
||||||
class GatewayOperationalValue {
|
|
||||||
final String icon;
|
|
||||||
final String description;
|
|
||||||
final dynamic value;
|
|
||||||
|
|
||||||
GatewayOperationalValue({
|
|
||||||
required this.icon,
|
|
||||||
required this.description,
|
|
||||||
required this.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class GatewayFunctions extends DeviceFunction<GatewayOperationalValue> {
|
|
||||||
final String type;
|
|
||||||
|
|
||||||
GatewayFunctions({
|
|
||||||
required super.deviceId,
|
|
||||||
required super.deviceName,
|
|
||||||
required super.code,
|
|
||||||
required super.operationName,
|
|
||||||
required super.icon,
|
|
||||||
required this.type,
|
|
||||||
});
|
|
||||||
|
|
||||||
List<GatewayOperationalValue> getOperationalValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
final class GatewaySwitchAlarmSound extends GatewayFunctions {
|
|
||||||
GatewaySwitchAlarmSound({
|
|
||||||
required super.deviceId,
|
|
||||||
required super.deviceName,
|
|
||||||
required super.type,
|
|
||||||
}) : super(
|
|
||||||
code: 'switch_alarm_sound',
|
|
||||||
operationName: 'Switch Alarm Sound',
|
|
||||||
icon: Assets.activeBell,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<GatewayOperationalValue> getOperationalValues() => [
|
|
||||||
GatewayOperationalValue(
|
|
||||||
icon: Assets.assetsAcPower,
|
|
||||||
description: "ON",
|
|
||||||
value: true,
|
|
||||||
),
|
|
||||||
GatewayOperationalValue(
|
|
||||||
icon: Assets.assetsAcPowerOFF,
|
|
||||||
description: "OFF",
|
|
||||||
value: false,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
final class GatewayMasterState extends GatewayFunctions {
|
|
||||||
GatewayMasterState({
|
|
||||||
required super.deviceId,
|
|
||||||
required super.deviceName,
|
|
||||||
required super.type,
|
|
||||||
}) : super(
|
|
||||||
code: 'master_state',
|
|
||||||
operationName: 'Master State',
|
|
||||||
icon: Assets.gear,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<GatewayOperationalValue> getOperationalValues() {
|
|
||||||
return [
|
|
||||||
GatewayOperationalValue(
|
|
||||||
icon: Assets.assetsAcPower,
|
|
||||||
description: "Normal",
|
|
||||||
value: 'normal',
|
|
||||||
),
|
|
||||||
GatewayOperationalValue(
|
|
||||||
icon: Assets.assetsAcPowerOFF,
|
|
||||||
description: "Alarm",
|
|
||||||
value: 'alarm',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class GatewayFactoryReset extends GatewayFunctions {
|
|
||||||
GatewayFactoryReset({
|
|
||||||
required super.deviceId,
|
|
||||||
required super.deviceName,
|
|
||||||
required super.type,
|
|
||||||
}) : super(
|
|
||||||
code: 'factory_reset',
|
|
||||||
operationName: 'Factory Reset',
|
|
||||||
icon: Assets.factoryReset,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<GatewayOperationalValue> getOperationalValues() {
|
|
||||||
return [
|
|
||||||
GatewayOperationalValue(
|
|
||||||
icon: Assets.assetsAcPower,
|
|
||||||
description: "ON",
|
|
||||||
value: true,
|
|
||||||
),
|
|
||||||
GatewayOperationalValue(
|
|
||||||
icon: Assets.assetsAcPowerOFF,
|
|
||||||
description: "OFF",
|
|
||||||
value: false,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,12 +8,12 @@ class DialogFooter extends StatelessWidget {
|
|||||||
final int? dialogWidth;
|
final int? dialogWidth;
|
||||||
|
|
||||||
const DialogFooter({
|
const DialogFooter({
|
||||||
super.key,
|
Key? key,
|
||||||
required this.onCancel,
|
required this.onCancel,
|
||||||
required this.onConfirm,
|
required this.onConfirm,
|
||||||
required this.isConfirmEnabled,
|
required this.isConfirmEnabled,
|
||||||
this.dialogWidth,
|
this.dialogWidth,
|
||||||
});
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -28,19 +28,21 @@ class DialogFooter extends StatelessWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
_buildFooterButton(
|
Expanded(
|
||||||
context: context,
|
child: _buildFooterButton(
|
||||||
text: 'Cancel',
|
context,
|
||||||
onTap: onCancel,
|
'Cancel',
|
||||||
|
onCancel,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
if (isConfirmEnabled) ...[
|
if (isConfirmEnabled) ...[
|
||||||
Container(width: 1, height: 50, color: ColorsManager.greyColor),
|
Container(width: 1, height: 50, color: ColorsManager.greyColor),
|
||||||
_buildFooterButton(
|
Expanded(
|
||||||
context: context,
|
child: _buildFooterButton(
|
||||||
text: 'Confirm',
|
context,
|
||||||
onTap: onConfirm,
|
'Confirm',
|
||||||
textColor:
|
onConfirm,
|
||||||
isConfirmEnabled ? ColorsManager.primaryColorWithOpacity : Colors.red,
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -48,24 +50,24 @@ class DialogFooter extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFooterButton({
|
Widget _buildFooterButton(
|
||||||
required BuildContext context,
|
BuildContext context,
|
||||||
required String text,
|
String text,
|
||||||
required VoidCallback? onTap,
|
VoidCallback? onTap,
|
||||||
Color? textColor,
|
) {
|
||||||
}) {
|
return GestureDetector(
|
||||||
return Expanded(
|
onTap: onTap,
|
||||||
child: TextButton(
|
child: SizedBox(
|
||||||
style: TextButton.styleFrom(
|
height: 50,
|
||||||
foregroundColor: ColorsManager.primaryColorWithOpacity,
|
child: Center(
|
||||||
disabledForegroundColor: ColorsManager.primaryColor,
|
child: Text(
|
||||||
),
|
text,
|
||||||
onPressed: onTap,
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
child: Text(
|
color: text == 'Confirm'
|
||||||
text,
|
? ColorsManager.primaryColorWithOpacity
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
: ColorsManager.textGray,
|
||||||
color: textColor ?? ColorsManager.textGray,
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,6 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
class DraggableCard extends StatelessWidget {
|
class DraggableCard extends StatelessWidget {
|
||||||
@ -71,7 +70,7 @@ class DraggableCard extends StatelessWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
padding: padding ?? const EdgeInsets.all(16),
|
padding: padding ?? const EdgeInsets.all(16),
|
||||||
width: 110,
|
width: 110,
|
||||||
height: deviceFunctions.isEmpty ? 160 : 170,
|
height: deviceFunctions.isEmpty ? 123 : null,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@ -79,7 +78,6 @@ class DraggableCard extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
height: 50,
|
height: 50,
|
||||||
@ -103,82 +101,19 @@ class DraggableCard extends StatelessWidget {
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
padding: const EdgeInsets.symmetric(horizontal: 3),
|
||||||
child: Flexible(
|
child: Text(
|
||||||
child: Text(
|
deviceData['title'] ?? deviceData['name'] ?? title,
|
||||||
deviceData['title'] ?? deviceData['name'] ?? title,
|
textAlign: TextAlign.center,
|
||||||
textAlign: TextAlign.center,
|
overflow: TextOverflow.ellipsis,
|
||||||
overflow: TextOverflow.ellipsis,
|
maxLines: 2,
|
||||||
maxLines: 2,
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
color: ColorsManager.blackColor,
|
||||||
color: ColorsManager.blackColor,
|
fontSize: 12,
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
|
||||||
height: 4,
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: deviceData['tag'] != null && deviceData['tag'] != '',
|
|
||||||
child: Row(
|
|
||||||
spacing: 2,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 8, height: 8, child: SvgPicture.asset(Assets.deviceTagIcon)),
|
|
||||||
Flexible(
|
|
||||||
child: Text(
|
|
||||||
deviceData['tag'] ?? '',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
maxLines: 2,
|
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
|
||||||
color: ColorsManager.lightGreyColor,
|
|
||||||
fontSize: 9,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: deviceData['subSpace'] != null && deviceData['subSpace'] != '',
|
|
||||||
child: const SizedBox(
|
|
||||||
height: 4,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: deviceData['subSpace'] != null && deviceData['subSpace'] != '',
|
|
||||||
child: Row(
|
|
||||||
spacing: 2,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 8,
|
|
||||||
height: 8,
|
|
||||||
child: SvgPicture.asset(Assets.spaceLocationIcon)),
|
|
||||||
Flexible(
|
|
||||||
child: Text(
|
|
||||||
deviceData['subSpace'] ?? '',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
maxLines: 2,
|
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
|
||||||
color: ColorsManager.lightGreyColor,
|
|
||||||
fontSize: 9,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (deviceFunctions.isNotEmpty)
|
|
||||||
const SizedBox(
|
|
||||||
height: 4,
|
|
||||||
),
|
|
||||||
if (deviceFunctions.isNotEmpty)
|
if (deviceFunctions.isNotEmpty)
|
||||||
...deviceFunctions.map((function) => Row(
|
...deviceFunctions.map((function) => Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@ -188,7 +123,7 @@ class DraggableCard extends StatelessWidget {
|
|||||||
'${function.operationName}: ${_formatFunctionValue(function)}',
|
'${function.operationName}: ${_formatFunctionValue(function)}',
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
style: context.textTheme.bodySmall?.copyWith(
|
||||||
fontSize: 9,
|
fontSize: 9,
|
||||||
color: ColorsManager.lightGreyColor,
|
color: ColorsManager.textGray,
|
||||||
height: 1.2,
|
height: 1.2,
|
||||||
),
|
),
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
|
@ -71,8 +71,8 @@ class IfContainer extends StatelessWidget {
|
|||||||
'1G',
|
'1G',
|
||||||
'2G',
|
'2G',
|
||||||
'3G',
|
'3G',
|
||||||
'WPS'
|
'WPS',
|
||||||
'GW',
|
'CPS',
|
||||||
].contains(
|
].contains(
|
||||||
state.ifItems[index]['productType'])) {
|
state.ifItems[index]['productType'])) {
|
||||||
context.read<RoutineBloc>().add(
|
context.read<RoutineBloc>().add(
|
||||||
@ -130,7 +130,7 @@ class IfContainer extends StatelessWidget {
|
|||||||
context
|
context
|
||||||
.read<RoutineBloc>()
|
.read<RoutineBloc>()
|
||||||
.add(AddToIfContainer(mutableData, false));
|
.add(AddToIfContainer(mutableData, false));
|
||||||
} else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW']
|
} else if (!['AC', '1G', '2G', '3G', 'WPS', 'CPS']
|
||||||
.contains(mutableData['productType'])) {
|
.contains(mutableData['productType'])) {
|
||||||
context
|
context
|
||||||
.read<RoutineBloc>()
|
.read<RoutineBloc>()
|
||||||
|
@ -183,7 +183,7 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
|||||||
state.automations[index].id,
|
state.automations[index].id,
|
||||||
cardType: 'automations',
|
cardType: 'automations',
|
||||||
spaceName:
|
spaceName:
|
||||||
state.automations[index].spaceName,
|
state.scenes[index].spaceName,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<RoutineBloc>(context)
|
BlocProvider.of<RoutineBloc>(context)
|
||||||
.add(
|
.add(
|
||||||
|
@ -1,5 +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_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
||||||
|
|
||||||
@ -17,8 +18,6 @@ class _RoutineDevicesState extends State<RoutineDevices> {
|
|||||||
context.read<RoutineBloc>().add(FetchDevicesInRoutine());
|
context.read<RoutineBloc>().add(FetchDevicesInRoutine());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const _allowedProductTypes = {'AC', '1G', '2G', '3G', 'WPS', 'GW'};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||||
@ -33,8 +32,14 @@ class _RoutineDevicesState extends State<RoutineDevices> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final deviceList = state.devices
|
List<AllDevicesModel> deviceList = state.devices
|
||||||
.where((device) => _allowedProductTypes.contains(device.productType))
|
.where((device) =>
|
||||||
|
device.productType == 'AC' ||
|
||||||
|
device.productType == '1G' ||
|
||||||
|
device.productType == '2G' ||
|
||||||
|
device.productType == '3G' ||
|
||||||
|
device.productType == 'WPS' ||
|
||||||
|
device.productType == 'CPS')
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return Wrap(
|
return Wrap(
|
||||||
@ -42,32 +47,37 @@ class _RoutineDevicesState extends State<RoutineDevices> {
|
|||||||
runSpacing: 10,
|
runSpacing: 10,
|
||||||
children: deviceList.asMap().entries.map((entry) {
|
children: deviceList.asMap().entries.map((entry) {
|
||||||
final device = entry.value;
|
final device = entry.value;
|
||||||
|
|
||||||
final deviceData = {
|
|
||||||
'device': device,
|
|
||||||
'imagePath': device.getDefaultIcon(device.productType),
|
|
||||||
'title': device.name ?? '',
|
|
||||||
'deviceId': device.uuid,
|
|
||||||
'productType': device.productType,
|
|
||||||
'functions': device.functions,
|
|
||||||
'uniqueCustomId': '',
|
|
||||||
'tag': device.deviceTags!.isNotEmpty ? device.deviceTags![0].name : '',
|
|
||||||
'subSpace': device.deviceSubSpace?.subspaceName ?? '',
|
|
||||||
};
|
|
||||||
|
|
||||||
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
||||||
return device.name!.toLowerCase().contains(state.searchText!.toLowerCase())
|
return device.name!
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(state.searchText!.toLowerCase())
|
||||||
? DraggableCard(
|
? DraggableCard(
|
||||||
imagePath: deviceData['imagePath'] as String,
|
imagePath: device.getDefaultIcon(device.productType),
|
||||||
title: deviceData['title'] as String,
|
title: device.name ?? '',
|
||||||
deviceData: deviceData,
|
deviceData: {
|
||||||
|
'device': device,
|
||||||
|
'imagePath': device.getDefaultIcon(device.productType),
|
||||||
|
'title': device.name ?? '',
|
||||||
|
'deviceId': device.uuid,
|
||||||
|
'productType': device.productType,
|
||||||
|
'functions': device.functions,
|
||||||
|
'uniqueCustomId': '',
|
||||||
|
},
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink();
|
: Container();
|
||||||
} else {
|
} else {
|
||||||
return DraggableCard(
|
return DraggableCard(
|
||||||
imagePath: deviceData['imagePath'] as String,
|
imagePath: device.getDefaultIcon(device.productType),
|
||||||
title: deviceData['title'] as String,
|
title: device.name ?? '',
|
||||||
deviceData: deviceData,
|
deviceData: {
|
||||||
|
'device': device,
|
||||||
|
'imagePath': device.getDefaultIcon(device.productType),
|
||||||
|
'title': device.name ?? '',
|
||||||
|
'deviceId': device.uuid,
|
||||||
|
'productType': device.productType,
|
||||||
|
'functions': device.functions,
|
||||||
|
'uniqueCustomId': '',
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}).toList(),
|
}).toList(),
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
|
|
||||||
class RoutineDialogFunctionListTile extends StatelessWidget {
|
|
||||||
const RoutineDialogFunctionListTile({
|
|
||||||
super.key,
|
|
||||||
required this.iconPath,
|
|
||||||
required this.operationName,
|
|
||||||
required this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String iconPath;
|
|
||||||
final String operationName;
|
|
||||||
final void Function() onTap;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ListTile(
|
|
||||||
leading: SvgPicture.asset(
|
|
||||||
iconPath,
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
placeholderBuilder: (context) => const SizedBox(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
operationName,
|
|
||||||
style: context.textTheme.bodyMedium,
|
|
||||||
),
|
|
||||||
trailing: const Icon(
|
|
||||||
Icons.arrow_forward_ios,
|
|
||||||
size: 16,
|
|
||||||
color: ColorsManager.textGray,
|
|
||||||
),
|
|
||||||
onTap: onTap,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
|
|
||||||
class RoutineDialogSelectionListTile extends StatelessWidget {
|
|
||||||
const RoutineDialogSelectionListTile({
|
|
||||||
required this.iconPath,
|
|
||||||
required this.description,
|
|
||||||
required this.isSelected,
|
|
||||||
required this.onTap,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final bool isSelected;
|
|
||||||
final String iconPath;
|
|
||||||
final String description;
|
|
||||||
final void Function() onTap;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ListTile(
|
|
||||||
leading: SvgPicture.asset(
|
|
||||||
iconPath,
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
placeholderBuilder: (context) => Container(
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
description,
|
|
||||||
style: context.textTheme.bodyMedium,
|
|
||||||
),
|
|
||||||
trailing: Icon(
|
|
||||||
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
|
|
||||||
size: 24,
|
|
||||||
color: isSelected
|
|
||||||
? ColorsManager.primaryColorWithOpacity
|
|
||||||
: ColorsManager.textGray,
|
|
||||||
),
|
|
||||||
onTap: onTap,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,130 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/models/gateway.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog_value_selector.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_functions_list.dart';
|
|
||||||
|
|
||||||
class GatewayDialog extends StatefulWidget {
|
|
||||||
const GatewayDialog({
|
|
||||||
required this.uniqueCustomId,
|
|
||||||
required this.functions,
|
|
||||||
required this.deviceSelectedFunctions,
|
|
||||||
required this.device,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String? uniqueCustomId;
|
|
||||||
final List<DeviceFunction> functions;
|
|
||||||
final List<DeviceFunctionData> deviceSelectedFunctions;
|
|
||||||
final AllDevicesModel? device;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<GatewayDialog> createState() => _GatewayDialogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _GatewayDialogState extends State<GatewayDialog> {
|
|
||||||
late final List<GatewayFunctions> _gatewayFunctions;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_gatewayFunctions = widget.functions.whereType<GatewayFunctions>().toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
final selectedFunction = state.selectedFunction;
|
|
||||||
return Container(
|
|
||||||
width: selectedFunction != null ? 600 : 360,
|
|
||||||
height: 450,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.only(top: 20),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
const DialogHeader('Gateway Conditions'),
|
|
||||||
Expanded(child: _buildMainContent(context, state)),
|
|
||||||
_buildDialogFooter(context, state),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMainContent(BuildContext context, FunctionBlocState state) {
|
|
||||||
final selectedFunction = state.selectedFunction;
|
|
||||||
final selectedOperationName = state.selectedOperationName;
|
|
||||||
final selectedFunctionData = state.addedFunctions.firstWhere(
|
|
||||||
(f) => f.functionCode == selectedFunction,
|
|
||||||
orElse: () => DeviceFunctionData(
|
|
||||||
entityId: '',
|
|
||||||
functionCode: selectedFunction ?? '',
|
|
||||||
operationName: '',
|
|
||||||
value: null,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final selectedGatewayFunctions = _gatewayFunctions.firstWhere(
|
|
||||||
(f) => f.code == selectedFunction,
|
|
||||||
orElse: () => GatewaySwitchAlarmSound(
|
|
||||||
deviceId: '',
|
|
||||||
deviceName: '',
|
|
||||||
type: '',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final operations = selectedGatewayFunctions.getOperationalValues();
|
|
||||||
|
|
||||||
return Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
GatewayFunctionsList(gatewayFunctions: _gatewayFunctions),
|
|
||||||
if (state.selectedFunction != null)
|
|
||||||
Expanded(
|
|
||||||
child: GatewayDialogValueSelector(
|
|
||||||
operations: operations,
|
|
||||||
selectedFunction: selectedFunction ?? '',
|
|
||||||
selectedFunctionData: selectedFunctionData,
|
|
||||||
gatewayFunctions: _gatewayFunctions,
|
|
||||||
operationName: selectedOperationName ?? '',
|
|
||||||
device: widget.device,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildDialogFooter(BuildContext context, FunctionBlocState state) {
|
|
||||||
return DialogFooter(
|
|
||||||
onCancel: () => Navigator.pop(context),
|
|
||||||
onConfirm: state.addedFunctions.isNotEmpty
|
|
||||||
? () {
|
|
||||||
context.read<RoutineBloc>().add(
|
|
||||||
AddFunctionToRoutine(
|
|
||||||
state.addedFunctions,
|
|
||||||
widget.uniqueCustomId ?? '-1',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
Navigator.pop(
|
|
||||||
context,
|
|
||||||
{'deviceId': widget.functions.firstOrNull?.deviceId},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
isConfirmEnabled: state.selectedFunction != null,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/models/gateway.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialog_selection_list_tile.dart';
|
|
||||||
|
|
||||||
class GatewayDialogValueSelector extends StatelessWidget {
|
|
||||||
const GatewayDialogValueSelector({
|
|
||||||
required this.operations,
|
|
||||||
required this.selectedFunction,
|
|
||||||
required this.selectedFunctionData,
|
|
||||||
required this.gatewayFunctions,
|
|
||||||
required this.device,
|
|
||||||
required this.operationName,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<GatewayOperationalValue> operations;
|
|
||||||
final String selectedFunction;
|
|
||||||
final DeviceFunctionData? selectedFunctionData;
|
|
||||||
final List<GatewayFunctions> gatewayFunctions;
|
|
||||||
final AllDevicesModel? device;
|
|
||||||
final String operationName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return ListView.builder(
|
|
||||||
itemCount: operations.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final operation = operations[index];
|
|
||||||
final isSelected = selectedFunctionData?.value == operation.value;
|
|
||||||
return RoutineDialogSelectionListTile(
|
|
||||||
iconPath: operation.icon,
|
|
||||||
description: operation.description,
|
|
||||||
isSelected: isSelected,
|
|
||||||
onTap: () {
|
|
||||||
if (!isSelected) {
|
|
||||||
context.read<FunctionBloc>().add(
|
|
||||||
AddFunction(
|
|
||||||
functionData: DeviceFunctionData(
|
|
||||||
entityId: device?.uuid ?? '',
|
|
||||||
functionCode: selectedFunction,
|
|
||||||
operationName: operationName,
|
|
||||||
value: operation.value,
|
|
||||||
condition: selectedFunctionData?.condition,
|
|
||||||
valueDescription: selectedFunctionData?.valueDescription,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/models/gateway.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialog_function_list_tile.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
|
|
||||||
class GatewayFunctionsList extends StatelessWidget {
|
|
||||||
const GatewayFunctionsList({
|
|
||||||
required this.gatewayFunctions,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<GatewayFunctions> gatewayFunctions;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox(
|
|
||||||
width: 360,
|
|
||||||
child: ListView.separated(
|
|
||||||
shrinkWrap: false,
|
|
||||||
itemCount: gatewayFunctions.length,
|
|
||||||
separatorBuilder: (context, index) => const Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 40.0),
|
|
||||||
child: Divider(color: ColorsManager.dividerColor),
|
|
||||||
),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final function = gatewayFunctions[index];
|
|
||||||
return RoutineDialogFunctionListTile(
|
|
||||||
iconPath: function.icon,
|
|
||||||
operationName: function.operationName,
|
|
||||||
onTap: () => context.read<FunctionBloc>().add(
|
|
||||||
SelectFunction(
|
|
||||||
functionCode: function.code,
|
|
||||||
operationName: function.operationName,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_dialog.dart';
|
|
||||||
|
|
||||||
abstract final class GatewayHelper {
|
|
||||||
const GatewayHelper._();
|
|
||||||
|
|
||||||
static Future<Map<String, dynamic>?> showGatewayFunctionsDialog({
|
|
||||||
required BuildContext context,
|
|
||||||
required List<DeviceFunction> functions,
|
|
||||||
required String? uniqueCustomId,
|
|
||||||
required List<DeviceFunctionData> deviceSelectedFunctions,
|
|
||||||
required AllDevicesModel? device,
|
|
||||||
}) async {
|
|
||||||
return showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => BlocProvider<FunctionBloc>(
|
|
||||||
create: (context) => FunctionBloc()
|
|
||||||
..add(
|
|
||||||
InitializeFunctions(deviceSelectedFunctions),
|
|
||||||
),
|
|
||||||
child: GatewayDialog(
|
|
||||||
uniqueCustomId: uniqueCustomId,
|
|
||||||
functions: functions,
|
|
||||||
deviceSelectedFunctions: deviceSelectedFunctions,
|
|
||||||
device: device,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo
|
|||||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routines/helper/duration_format_helper.dart';
|
import 'package:syncrow_web/pages/routines/helper/duration_format_helper.dart';
|
||||||
|
import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||||
import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
||||||
@ -24,21 +25,23 @@ class OneGangSwitchHelper {
|
|||||||
required String uniqueCustomId,
|
required String uniqueCustomId,
|
||||||
required bool removeComparetors,
|
required bool removeComparetors,
|
||||||
}) async {
|
}) async {
|
||||||
List<BaseSwitchFunction> oneGangFunctions = functions.whereType<BaseSwitchFunction>().toList();
|
List<BaseSwitchFunction> oneGangFunctions =
|
||||||
|
functions.whereType<BaseSwitchFunction>().toList();
|
||||||
|
|
||||||
return showDialog<Map<String, dynamic>?>(
|
return showDialog<Map<String, dynamic>?>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
create: (_) => FunctionBloc()
|
||||||
|
..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
|
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final selectedFunction = state.selectedFunction;
|
final selectedFunction = state.selectedFunction;
|
||||||
final selectedOperationName = state.selectedOperationName;
|
final selectedOperationName = state.selectedOperationName;
|
||||||
final selectedFunctionData =
|
final selectedFunctionData = state.addedFunctions
|
||||||
state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
|
.firstWhere((f) => f.functionCode == selectedFunction,
|
||||||
orElse: () => DeviceFunctionData(
|
orElse: () => DeviceFunctionData(
|
||||||
entityId: '',
|
entityId: '',
|
||||||
functionCode: selectedFunction ?? '',
|
functionCode: selectedFunction ?? '',
|
||||||
@ -85,9 +88,12 @@ class OneGangSwitchHelper {
|
|||||||
color: ColorsManager.textGray,
|
color: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.read<FunctionBloc>().add(SelectFunction(
|
context
|
||||||
|
.read<FunctionBloc>()
|
||||||
|
.add(SelectFunction(
|
||||||
functionCode: function.code,
|
functionCode: function.code,
|
||||||
operationName: function.operationName,
|
operationName:
|
||||||
|
function.operationName,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -220,11 +226,11 @@ class OneGangSwitchHelper {
|
|||||||
selectedFunctionData,
|
selectedFunctionData,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildCountDownDisplay(
|
_buildCountDownDisplay(context, initialValue, device, operationName,
|
||||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
selectedFunctionData, selectCode),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildCountDownSlider(
|
_buildCountDownSlider(context, initialValue, device, operationName,
|
||||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
selectedFunctionData, selectCode),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -265,7 +271,8 @@ class OneGangSwitchHelper {
|
|||||||
minHeight: 40.0,
|
minHeight: 40.0,
|
||||||
minWidth: 40.0,
|
minWidth: 40.0,
|
||||||
),
|
),
|
||||||
isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
isSelected:
|
||||||
|
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||||
children: conditions.map((c) => Text(c)).toList(),
|
children: conditions.map((c) => Text(c)).toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -313,7 +320,8 @@ class OneGangSwitchHelper {
|
|||||||
value: (initialValue ?? 0).toDouble(),
|
value: (initialValue ?? 0).toDouble(),
|
||||||
min: operationalValues.minValue?.toDouble() ?? 0.0,
|
min: operationalValues.minValue?.toDouble() ?? 0.0,
|
||||||
max: operationalValues.maxValue?.toDouble() ?? 0.0,
|
max: operationalValues.maxValue?.toDouble() ?? 0.0,
|
||||||
divisions: (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) /
|
divisions: (((operationalValues.maxValue ?? 0) -
|
||||||
|
(operationalValues.minValue ?? 0)) /
|
||||||
(operationalValues.stepValue ?? 1))
|
(operationalValues.stepValue ?? 1))
|
||||||
.round(),
|
.round(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -365,9 +373,13 @@ class OneGangSwitchHelper {
|
|||||||
style: context.textTheme.bodyMedium,
|
style: context.textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
trailing: Icon(
|
trailing: Icon(
|
||||||
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
|
isSelected
|
||||||
|
? Icons.radio_button_checked
|
||||||
|
: Icons.radio_button_unchecked,
|
||||||
size: 24,
|
size: 24,
|
||||||
color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
|
color: isSelected
|
||||||
|
? ColorsManager.primaryColorWithOpacity
|
||||||
|
: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (!isSelected) {
|
if (!isSelected) {
|
||||||
@ -379,7 +391,8 @@ class OneGangSwitchHelper {
|
|||||||
operationName: operationName,
|
operationName: operationName,
|
||||||
value: value.value,
|
value: value.value,
|
||||||
condition: selectedFunctionData?.condition,
|
condition: selectedFunctionData?.condition,
|
||||||
valueDescription: selectedFunctionData?.valueDescription,
|
valueDescription:
|
||||||
|
selectedFunctionData?.valueDescription,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
@ -27,12 +28,9 @@ class _TimeWheelPickerState extends State<TimeWheelPicker> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_hoursController =
|
_hoursController = FixedExtentScrollController(initialItem: widget.initialHours);
|
||||||
FixedExtentScrollController(initialItem: widget.initialHours);
|
_minutesController = FixedExtentScrollController(initialItem: widget.initialMinutes);
|
||||||
_minutesController =
|
_secondsController = FixedExtentScrollController(initialItem: widget.initialSeconds);
|
||||||
FixedExtentScrollController(initialItem: widget.initialMinutes);
|
|
||||||
_secondsController =
|
|
||||||
FixedExtentScrollController(initialItem: widget.initialSeconds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -49,8 +47,6 @@ class _TimeWheelPickerState extends State<TimeWheelPicker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_hoursController.dispose();
|
_hoursController.dispose();
|
||||||
@ -65,28 +61,26 @@ class _TimeWheelPickerState extends State<TimeWheelPicker> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_buildPickerColumn(
|
_buildPickerColumn(
|
||||||
label: 'h',
|
label: 'h',
|
||||||
controller: _hoursController,
|
controller: _hoursController,
|
||||||
itemCount: 3,
|
itemCount: 24,
|
||||||
onChanged: (value) {
|
onChanged: (value) => _handleTimeChange(
|
||||||
_handleTimeChange(
|
value,
|
||||||
value,
|
_minutesController.selectedItem,
|
||||||
_minutesController.selectedItem,
|
_secondsController.selectedItem,
|
||||||
_secondsController.selectedItem,
|
),
|
||||||
);
|
),
|
||||||
}),
|
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
_buildPickerColumn(
|
_buildPickerColumn(
|
||||||
label: 'm',
|
label: 'm',
|
||||||
controller: _minutesController,
|
controller: _minutesController,
|
||||||
itemCount: 60,
|
itemCount: 60,
|
||||||
onChanged: (value) {
|
onChanged: (value) => _handleTimeChange(
|
||||||
_handleTimeChange(
|
_hoursController.selectedItem,
|
||||||
_hoursController.selectedItem,
|
value,
|
||||||
value,
|
_secondsController.selectedItem,
|
||||||
_secondsController.selectedItem,
|
),
|
||||||
);
|
),
|
||||||
}),
|
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
_buildPickerColumn(
|
_buildPickerColumn(
|
||||||
label: 's',
|
label: 's',
|
||||||
@ -103,19 +97,6 @@ class _TimeWheelPickerState extends State<TimeWheelPicker> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handleTimeChange(int hours, int minutes, int seconds) {
|
void _handleTimeChange(int hours, int minutes, int seconds) {
|
||||||
int total = hours * 3600 + minutes * 60 + seconds;
|
|
||||||
if (total > 10000) {
|
|
||||||
hours = 2;
|
|
||||||
minutes = 46;
|
|
||||||
seconds = 40;
|
|
||||||
total = 10000;
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
_hoursController.jumpToItem(hours);
|
|
||||||
_minutesController.jumpToItem(minutes);
|
|
||||||
_secondsController.jumpToItem(seconds);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.onTimeChanged(hours, minutes, seconds);
|
widget.onTimeChanged(hours, minutes, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,4 +147,4 @@ class _TimeWheelPickerState extends State<TimeWheelPicker> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,10 +3,10 @@
|
|||||||
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_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/automation_dialog.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/delay_dialog.dart';
|
|
||||||
import 'package:syncrow_web/pages/routines/helper/dialog_helper/device_dialog_helper.dart';
|
import 'package:syncrow_web/pages/routines/helper/dialog_helper/device_dialog_helper.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
||||||
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/automation_dialog.dart';
|
||||||
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/delay_dialog.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ class ThenContainer extends StatelessWidget {
|
|||||||
'2G',
|
'2G',
|
||||||
'3G',
|
'3G',
|
||||||
'WPS',
|
'WPS',
|
||||||
"GW",
|
'CPS',
|
||||||
].contains(state.thenItems[index]
|
].contains(state.thenItems[index]
|
||||||
['productType'])) {
|
['productType'])) {
|
||||||
context.read<RoutineBloc>().add(
|
context.read<RoutineBloc>().add(
|
||||||
@ -230,7 +230,7 @@ class ThenContainer extends StatelessWidget {
|
|||||||
dialogType: "THEN");
|
dialogType: "THEN");
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
} else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW']
|
} else if (!['AC', '1G', '2G', '3G', 'WPS', 'CPS']
|
||||||
.contains(mutableData['productType'])) {
|
.contains(mutableData['productType'])) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
@ -109,11 +107,6 @@ class _LoadedSpaceViewState extends State<LoadedSpaceView> {
|
|||||||
selectedSpaceUuid: widget.selectedSpace?.uuid ??
|
selectedSpaceUuid: widget.selectedSpace?.uuid ??
|
||||||
widget.selectedCommunity?.uuid ??
|
widget.selectedCommunity?.uuid ??
|
||||||
'',
|
'',
|
||||||
onCreateCommunity: (name, description) {
|
|
||||||
context.read<SpaceManagementBloc>().add(
|
|
||||||
CreateCommunityEvent(name, description, context),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
CommunityStructureArea(
|
CommunityStructureArea(
|
||||||
selectedCommunity: widget.selectedCommunity,
|
selectedCommunity: widget.selectedCommunity,
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
|
||||||
|
|
||||||
class SidebarAddCommunityButton extends StatelessWidget {
|
|
||||||
const SidebarAddCommunityButton({
|
|
||||||
required this.onTap,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final void Function() onTap;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox.square(
|
|
||||||
dimension: 30,
|
|
||||||
child: IconButton(
|
|
||||||
style: IconButton.styleFrom(
|
|
||||||
iconSize: 20,
|
|
||||||
backgroundColor: ColorsManager.circleImageBackground,
|
|
||||||
shape: const CircleBorder(
|
|
||||||
side: BorderSide(
|
|
||||||
color: ColorsManager.lightGrayBorderColor,
|
|
||||||
width: 3,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: onTap,
|
|
||||||
icon: SvgPicture.asset(Assets.addIcon),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/sidebar_add_community_button.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
|
||||||
|
|
||||||
class SidebarHeader extends StatelessWidget {
|
|
||||||
const SidebarHeader({
|
|
||||||
required this.onAddCommunity,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final void Function() onAddCommunity;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: subSectionContainerDecoration,
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Communities',
|
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SidebarAddCommunityButton(
|
|
||||||
onTap: onAddCommunity,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +1,80 @@
|
|||||||
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:flutter_svg/svg.dart';
|
||||||
import 'package:syncrow_web/common/widgets/search_bar.dart';
|
import 'package:syncrow_web/common/widgets/search_bar.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_tile.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_tile.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/sidebar_header.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_tile_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_tile_widget.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_community/view/create_community_dialog.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_event.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
class SidebarWidget extends StatefulWidget {
|
class SidebarWidget extends StatefulWidget {
|
||||||
final List<CommunityModel> communities;
|
final List<CommunityModel> communities;
|
||||||
final String? selectedSpaceUuid;
|
final String? selectedSpaceUuid;
|
||||||
final void Function(String name, String description) onCreateCommunity;
|
|
||||||
|
|
||||||
const SidebarWidget({
|
const SidebarWidget({
|
||||||
required this.communities,
|
|
||||||
required this.onCreateCommunity,
|
|
||||||
this.selectedSpaceUuid,
|
|
||||||
super.key,
|
super.key,
|
||||||
|
required this.communities,
|
||||||
|
this.selectedSpaceUuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SidebarWidget> createState() => _SidebarWidgetState();
|
_SidebarWidgetState createState() => _SidebarWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SidebarWidgetState extends State<SidebarWidget> {
|
class _SidebarWidgetState extends State<SidebarWidget> {
|
||||||
String _searchQuery = '';
|
String _searchQuery = ''; // Track search query
|
||||||
String? _selectedSpaceUuid;
|
String? _selectedSpaceUuid;
|
||||||
String? _selectedId;
|
String? _selectedId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_selectedId = widget.selectedSpaceUuid;
|
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_selectedId = widget.selectedSpaceUuid; // Initialize with the passed selected space UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(covariant SidebarWidget oldWidget) {
|
void didUpdateWidget(covariant SidebarWidget oldWidget) {
|
||||||
if (widget.selectedSpaceUuid != oldWidget.selectedSpaceUuid) {
|
|
||||||
setState(() => _selectedId = widget.selectedSpaceUuid);
|
|
||||||
}
|
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (widget.selectedSpaceUuid != oldWidget.selectedSpaceUuid) {
|
||||||
|
setState(() {
|
||||||
|
_selectedId = widget.selectedSpaceUuid;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CommunityModel> _filteredCommunities() {
|
// Function to filter communities based on the search query
|
||||||
|
List<CommunityModel> _filterCommunities() {
|
||||||
if (_searchQuery.isEmpty) {
|
if (_searchQuery.isEmpty) {
|
||||||
|
// Reset the selected community and space UUIDs if there's no query
|
||||||
_selectedSpaceUuid = null;
|
_selectedSpaceUuid = null;
|
||||||
return widget.communities;
|
return widget.communities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter communities and expand only those that match the query
|
||||||
return widget.communities.where((community) {
|
return widget.communities.where((community) {
|
||||||
final containsQueryInCommunity =
|
final containsQueryInCommunity =
|
||||||
community.name.toLowerCase().contains(_searchQuery.toLowerCase());
|
community.name.toLowerCase().contains(_searchQuery.toLowerCase());
|
||||||
final containsQueryInSpaces = community.spaces.any((space) =>
|
final containsQueryInSpaces =
|
||||||
_containsQuery(space: space, query: _searchQuery.toLowerCase()));
|
community.spaces.any((space) => _containsQuery(space, _searchQuery.toLowerCase()));
|
||||||
|
|
||||||
return containsQueryInCommunity || containsQueryInSpaces;
|
return containsQueryInCommunity || containsQueryInSpaces;
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _containsQuery({
|
// Helper function to determine if any space or its children match the search query
|
||||||
required SpaceModel space,
|
bool _containsQuery(SpaceModel space, String query) {
|
||||||
required String query,
|
|
||||||
}) {
|
|
||||||
final matchesSpace = space.name.toLowerCase().contains(query);
|
final matchesSpace = space.name.toLowerCase().contains(query);
|
||||||
final matchesChildren = space.children.any(
|
final matchesChildren =
|
||||||
(child) => _containsQuery(space: child, query: query),
|
space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
||||||
);
|
|
||||||
|
|
||||||
|
// If the space or any of its children match the query, expand this space
|
||||||
if (matchesSpace || matchesChildren) {
|
if (matchesSpace || matchesChildren) {
|
||||||
_selectedSpaceUuid = space.uuid;
|
_selectedSpaceUuid = space.uuid;
|
||||||
}
|
}
|
||||||
@ -81,32 +83,79 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool _isSpaceOrChildSelected(SpaceModel space) {
|
bool _isSpaceOrChildSelected(SpaceModel space) {
|
||||||
final isSpaceSelected = _selectedSpaceUuid == space.uuid;
|
// Return true if the current space or any of its child spaces is selected
|
||||||
final anySubSpaceIsSelected = space.children.any(_isSpaceOrChildSelected);
|
if (_selectedSpaceUuid == space.uuid) {
|
||||||
return isSpaceSelected || anySubSpaceIsSelected;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively check if any child spaces match the query
|
||||||
|
for (var child in space.children) {
|
||||||
|
if (_isSpaceOrChildSelected(child)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final filteredCommunities = _filteredCommunities();
|
final filteredCommunities = _filterCommunities();
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: 300,
|
width: 300,
|
||||||
decoration: subSectionContainerDecoration,
|
decoration: subSectionContainerDecoration,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min, // Ensures the Column only takes necessary height
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SidebarHeader(onAddCommunity: _onAddCommunity),
|
// Communities title with the add button
|
||||||
|
Container(
|
||||||
|
decoration: subSectionContainerDecoration,
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text('Communities',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
)),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => _navigateToBlank(context),
|
||||||
|
child: Container(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: ColorsManager.whiteColors,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.roundedAddIcon,
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Search bar
|
||||||
CustomSearchBar(
|
CustomSearchBar(
|
||||||
onSearchChanged: (query) => setState(() => _searchQuery = query),
|
onSearchChanged: (query) {
|
||||||
|
setState(() {
|
||||||
|
_searchQuery = query;
|
||||||
|
});
|
||||||
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
// Community list
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: filteredCommunities
|
children: filteredCommunities.map((community) {
|
||||||
.map((community) => _buildCommunityTile(context, community))
|
return _buildCommunityTile(context, community);
|
||||||
.toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -114,7 +163,18 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _navigateToBlank(BuildContext context) {
|
||||||
|
setState(() {
|
||||||
|
_selectedId = '';
|
||||||
|
});
|
||||||
|
context.read<SpaceManagementBloc>().add(
|
||||||
|
NewCommunityEvent(communities: widget.communities),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildCommunityTile(BuildContext context, CommunityModel community) {
|
Widget _buildCommunityTile(BuildContext context, CommunityModel community) {
|
||||||
|
bool hasChildren = community.spaces.isNotEmpty;
|
||||||
|
|
||||||
return CommunityTile(
|
return CommunityTile(
|
||||||
title: community.name,
|
title: community.name,
|
||||||
key: ValueKey(community.uuid),
|
key: ValueKey(community.uuid),
|
||||||
@ -123,7 +183,7 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
|||||||
onItemSelected: () {
|
onItemSelected: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedId = community.uuid;
|
_selectedId = community.uuid;
|
||||||
_selectedSpaceUuid = null;
|
_selectedSpaceUuid = null; // Update the selected community
|
||||||
});
|
});
|
||||||
|
|
||||||
context.read<CenterBodyBloc>().add(CommunitySelectedEvent());
|
context.read<CenterBodyBloc>().add(CommunitySelectedEvent());
|
||||||
@ -132,73 +192,46 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
|||||||
SelectCommunityEvent(selectedCommunity: community),
|
SelectCommunityEvent(selectedCommunity: community),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onExpansionChanged: (title, expanded) {},
|
onExpansionChanged: (String title, bool expanded) {
|
||||||
children: community.spaces
|
_handleExpansionChange(community.uuid, expanded);
|
||||||
.where((space) {
|
},
|
||||||
final isDeleted = space.status != SpaceStatus.deleted;
|
children: hasChildren
|
||||||
final isParentDeleted = space.status != SpaceStatus.parentDeleted;
|
? community.spaces
|
||||||
return (isDeleted || isParentDeleted);
|
.where((space) => (space.status != SpaceStatus.deleted ||
|
||||||
})
|
space.status != SpaceStatus.parentDeleted))
|
||||||
.map((space) => _buildSpaceTile(space: space, community: community))
|
.map((space) => _buildSpaceTile(space, community))
|
||||||
.toList(),
|
.toList()
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSpaceTile({
|
Widget _buildSpaceTile(SpaceModel space, CommunityModel community, {int depth = 1}) {
|
||||||
required SpaceModel space,
|
bool isExpandedSpace = _isSpaceOrChildSelected(space);
|
||||||
required CommunityModel community,
|
|
||||||
}) {
|
|
||||||
final spaceIsExpanded = _isSpaceOrChildSelected(space);
|
|
||||||
final isSelected = _selectedId == space.uuid;
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsetsDirectional.only(start: 16.0),
|
padding: EdgeInsets.only(left: depth * 16.0),
|
||||||
child: SpaceTile(
|
child: SpaceTile(
|
||||||
title: space.name,
|
title: space.name,
|
||||||
key: ValueKey(space.uuid),
|
key: ValueKey(space.uuid),
|
||||||
isSelected: isSelected,
|
isSelected: _selectedId == space.uuid,
|
||||||
initiallyExpanded: spaceIsExpanded,
|
initiallyExpanded: isExpandedSpace,
|
||||||
onExpansionChanged: (expanded) {},
|
onExpansionChanged: (bool expanded) {
|
||||||
onItemSelected: () {
|
_handleExpansionChange(space.uuid ?? '', expanded);
|
||||||
setState(() {
|
},
|
||||||
_selectedId = space.uuid;
|
onItemSelected: () {
|
||||||
_selectedSpaceUuid = space.uuid;
|
setState(() {
|
||||||
});
|
_selectedId = space.uuid;
|
||||||
|
_selectedSpaceUuid = space.uuid;
|
||||||
|
});
|
||||||
|
|
||||||
context.read<SpaceManagementBloc>().add(
|
context.read<SpaceManagementBloc>().add(
|
||||||
SelectSpaceEvent(selectedCommunity: community, selectedSpace: space),
|
SelectSpaceEvent(selectedCommunity: community, selectedSpace: space),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
children: space.children
|
children: space.children.isNotEmpty
|
||||||
.map(
|
? space.children.map((childSpace) => _buildSpaceTile(childSpace, community)).toList()
|
||||||
(childSpace) => _buildSpaceTile(
|
: [], // Recursively render child spaces if available
|
||||||
space: childSpace,
|
));
|
||||||
community: community,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onAddCommunity() => _selectedId?.isNotEmpty ?? true
|
void _handleExpansionChange(String uuid, bool expanded) {}
|
||||||
? _clearSelection()
|
|
||||||
: _showCreateCommunityDialog();
|
|
||||||
|
|
||||||
void _clearSelection() {
|
|
||||||
setState(() => _selectedId = '');
|
|
||||||
context.read<SpaceManagementBloc>().add(
|
|
||||||
NewCommunityEvent(communities: widget.communities),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showCreateCommunityDialog() {
|
|
||||||
showDialog<void>(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => CreateCommunityDialog(
|
|
||||||
isEditMode: false,
|
|
||||||
existingCommunityNames: widget.communities.map((e) => e.name).toList(),
|
|
||||||
onCreateCommunity: widget.onCreateCommunity,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
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_web/pages/common/buttons/cancel_button.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_state.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/widgets/create_subspace_model_chips_box.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/widgets/create_subspace_model_footer_buttons.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
|
|
||||||
class CreateSubSpaceModelDialog extends StatelessWidget {
|
class CreateSubSpaceModelDialog extends StatelessWidget {
|
||||||
final bool isEdit;
|
final bool isEdit;
|
||||||
@ -15,67 +14,211 @@ class CreateSubSpaceModelDialog extends StatelessWidget {
|
|||||||
final List<SubspaceTemplateModel>? existingSubSpaces;
|
final List<SubspaceTemplateModel>? existingSubSpaces;
|
||||||
final void Function(List<SubspaceTemplateModel> newSubspaces)? onUpdate;
|
final void Function(List<SubspaceTemplateModel> newSubspaces)? onUpdate;
|
||||||
|
|
||||||
const CreateSubSpaceModelDialog({
|
const CreateSubSpaceModelDialog(
|
||||||
required this.isEdit,
|
{Key? key,
|
||||||
required this.dialogTitle,
|
required this.isEdit,
|
||||||
this.existingSubSpaces,
|
required this.dialogTitle,
|
||||||
this.onUpdate,
|
this.existingSubSpaces,
|
||||||
super.key,
|
this.onUpdate})
|
||||||
});
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
final textController = TextEditingController();
|
||||||
|
|
||||||
return Dialog(
|
return Dialog(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) {
|
create: (_) {
|
||||||
final bloc = SubSpaceModelBloc();
|
final bloc = SubSpaceModelBloc();
|
||||||
if (existingSubSpaces != null) {
|
if (existingSubSpaces != null) {
|
||||||
for (final subSpace in existingSubSpaces ?? []) {
|
for (var subSpace in existingSubSpaces!) {
|
||||||
bloc.add(AddSubSpaceModel(subSpace));
|
bloc.add(AddSubSpaceModel(subSpace));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bloc;
|
return bloc;
|
||||||
},
|
},
|
||||||
child: BlocBuilder<SubSpaceModelBloc, SubSpaceModelState>(
|
child: BlocBuilder<SubSpaceModelBloc, SubSpaceModelState>(
|
||||||
builder: (context, state) => Container(
|
builder: (context, state) {
|
||||||
color: ColorsManager.whiteColors,
|
return Container(
|
||||||
width: screenWidth * 0.3,
|
color: ColorsManager.whiteColors,
|
||||||
padding: const EdgeInsets.all(16),
|
child: SizedBox(
|
||||||
child: Column(
|
width: screenWidth * 0.3,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Padding(
|
||||||
mainAxisSize: MainAxisSize.min,
|
padding: const EdgeInsets.all(16.0),
|
||||||
children: [
|
child: Column(
|
||||||
Text(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
dialogTitle,
|
mainAxisSize: MainAxisSize.min,
|
||||||
style: context.textTheme.headlineLarge?.copyWith(
|
children: [
|
||||||
color: ColorsManager.blackColor,
|
Text(
|
||||||
),
|
dialogTitle,
|
||||||
),
|
style: Theme.of(context)
|
||||||
const SizedBox(height: 16),
|
.textTheme
|
||||||
CreateSubspaceModelChipsBox(subSpaces: state.subSpaces),
|
.headlineLarge
|
||||||
if (state.errorMessage.isNotEmpty)
|
?.copyWith(color: ColorsManager.blackColor),
|
||||||
Padding(
|
),
|
||||||
padding: const EdgeInsets.only(bottom: 16),
|
const SizedBox(height: 16),
|
||||||
child: Text(
|
Container(
|
||||||
state.errorMessage,
|
width: screenWidth * 0.35,
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
padding: const EdgeInsets.symmetric(
|
||||||
color: ColorsManager.red,
|
vertical: 10.0, horizontal: 16.0),
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.boxColor,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 8.0,
|
||||||
|
runSpacing: 8.0,
|
||||||
|
children: [
|
||||||
|
...state.subSpaces.asMap().entries.map(
|
||||||
|
(entry) {
|
||||||
|
final index = entry.key;
|
||||||
|
final subSpace = entry.value;
|
||||||
|
|
||||||
|
final lowerName =
|
||||||
|
subSpace.subspaceName.toLowerCase();
|
||||||
|
|
||||||
|
final duplicateIndices = state.subSpaces
|
||||||
|
.asMap()
|
||||||
|
.entries
|
||||||
|
.where((e) =>
|
||||||
|
e.value.subspaceName.toLowerCase() ==
|
||||||
|
lowerName)
|
||||||
|
.map((e) => e.key)
|
||||||
|
.toList();
|
||||||
|
final isDuplicate =
|
||||||
|
duplicateIndices.length > 1 &&
|
||||||
|
duplicateIndices.indexOf(index) != 0;
|
||||||
|
|
||||||
|
return Chip(
|
||||||
|
label: Text(subSpace.subspaceName,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(
|
||||||
|
color: ColorsManager.spaceColor,
|
||||||
|
)),
|
||||||
|
backgroundColor: ColorsManager.whiteColors,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
side: BorderSide(
|
||||||
|
color: isDuplicate
|
||||||
|
? ColorsManager.red
|
||||||
|
: ColorsManager.transparentColor,
|
||||||
|
width: 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
deleteIcon: Container(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color: ColorsManager.lightGrayColor,
|
||||||
|
width: 1.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.close,
|
||||||
|
size: 16,
|
||||||
|
color: ColorsManager.lightGrayColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onDeleted: () => context
|
||||||
|
.read<SubSpaceModelBloc>()
|
||||||
|
.add(RemoveSubSpaceModel(subSpace)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 200,
|
||||||
|
child: TextField(
|
||||||
|
controller: textController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: state.subSpaces.isEmpty
|
||||||
|
? 'Please enter the name'
|
||||||
|
: null,
|
||||||
|
hintStyle: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall!
|
||||||
|
.copyWith(
|
||||||
|
color: ColorsManager
|
||||||
|
.lightGrayColor)),
|
||||||
|
onSubmitted: (value) {
|
||||||
|
if (value.trim().isNotEmpty) {
|
||||||
|
context.read<SubSpaceModelBloc>().add(
|
||||||
|
AddSubSpaceModel(
|
||||||
|
SubspaceTemplateModel(
|
||||||
|
subspaceName: value.trim(),
|
||||||
|
disabled: false)));
|
||||||
|
textController.clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium
|
||||||
|
?.copyWith(
|
||||||
|
color: ColorsManager.blackColor)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (state.errorMessage.isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16.0),
|
||||||
|
child: Text(state.errorMessage,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(
|
||||||
|
color: ColorsManager.red,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: CancelButton(
|
||||||
|
label: 'Cancel',
|
||||||
|
onPressed: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: DefaultButton(
|
||||||
|
onPressed: (state.errorMessage.isNotEmpty)
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
final subSpaces = context
|
||||||
|
.read<SubSpaceModelBloc>()
|
||||||
|
.state
|
||||||
|
.subSpaces;
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
if (onUpdate != null) {
|
||||||
|
onUpdate!(subSpaces);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
|
borderRadius: 10,
|
||||||
|
foregroundColor: state.errorMessage.isNotEmpty
|
||||||
|
? ColorsManager.whiteColorsWithOpacity
|
||||||
|
: ColorsManager.whiteColors,
|
||||||
|
child: const Text('OK'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
));
|
||||||
CreateSubspaceModelFooterButtons(
|
},
|
||||||
onUpdate: onUpdate,
|
|
||||||
errorMessage: state.errorMessage,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/widgets/subspace_chip.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/widgets/subspaces_textfield.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
|
|
||||||
class CreateSubspaceModelChipsBox extends StatelessWidget {
|
|
||||||
const CreateSubspaceModelChipsBox({
|
|
||||||
required this.subSpaces,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<SubspaceTemplateModel> subSpaces;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
width: screenWidth * 0.35,
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 10,
|
|
||||||
horizontal: 16,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: ColorsManager.boxColor,
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: Wrap(
|
|
||||||
spacing: 8,
|
|
||||||
runSpacing: 8,
|
|
||||||
alignment: WrapAlignment.start,
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
|
||||||
children: [
|
|
||||||
...subSpaces.asMap().entries.map(
|
|
||||||
(entry) {
|
|
||||||
final index = entry.key;
|
|
||||||
final subSpace = entry.value;
|
|
||||||
|
|
||||||
final lowerName = subSpace.subspaceName.toLowerCase();
|
|
||||||
|
|
||||||
final duplicateIndices = subSpaces
|
|
||||||
.asMap()
|
|
||||||
.entries
|
|
||||||
.where((e) => e.value.subspaceName.toLowerCase() == lowerName)
|
|
||||||
.map((e) => e.key)
|
|
||||||
.toList();
|
|
||||||
final isDuplicate = duplicateIndices.length > 1 &&
|
|
||||||
duplicateIndices.indexOf(index) != 0;
|
|
||||||
|
|
||||||
return SubspaceChip(
|
|
||||||
subSpace: subSpace,
|
|
||||||
isDuplicate: isDuplicate,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SubspacesTextfield(
|
|
||||||
hintText: subSpaces.isEmpty ? 'Please enter the name' : null,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
|
||||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
|
|
||||||
class CreateSubspaceModelFooterButtons extends StatelessWidget {
|
|
||||||
const CreateSubspaceModelFooterButtons({
|
|
||||||
required this.onUpdate,
|
|
||||||
required this.errorMessage,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final void Function(List<SubspaceTemplateModel> newSubspaces)? onUpdate;
|
|
||||||
final String errorMessage;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: CancelButton(
|
|
||||||
label: 'Cancel',
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: DefaultButton(
|
|
||||||
onPressed: errorMessage.isEmpty
|
|
||||||
? () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
if (onUpdate != null) {
|
|
||||||
final subSpaces =
|
|
||||||
context.read<SubSpaceModelBloc>().state.subSpaces;
|
|
||||||
onUpdate!(subSpaces);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
backgroundColor: ColorsManager.secondaryColor,
|
|
||||||
borderRadius: 10,
|
|
||||||
foregroundColor: errorMessage.isNotEmpty
|
|
||||||
? ColorsManager.whiteColorsWithOpacity
|
|
||||||
: ColorsManager.whiteColors,
|
|
||||||
child: const Text('OK'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_event.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
|
|
||||||
class SubspaceChip extends StatelessWidget {
|
|
||||||
const SubspaceChip({
|
|
||||||
required this.subSpace,
|
|
||||||
required this.isDuplicate,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final SubspaceTemplateModel subSpace;
|
|
||||||
final bool isDuplicate;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Chip(
|
|
||||||
label: Text(
|
|
||||||
subSpace.subspaceName,
|
|
||||||
style: context.textTheme.bodySmall?.copyWith(
|
|
||||||
color: isDuplicate ? ColorsManager.red : ColorsManager.spaceColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
backgroundColor: ColorsManager.whiteColors,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
side: BorderSide(
|
|
||||||
color: isDuplicate ? ColorsManager.red : ColorsManager.transparentColor,
|
|
||||||
width: 0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
deleteIcon: Container(
|
|
||||||
padding: const EdgeInsetsDirectional.all(1),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(
|
|
||||||
color: ColorsManager.lightGrayColor,
|
|
||||||
width: 1.5,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: const FittedBox(
|
|
||||||
fit: BoxFit.scaleDown,
|
|
||||||
child: Icon(
|
|
||||||
Icons.close,
|
|
||||||
color: ColorsManager.lightGrayColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onDeleted: () => context.read<SubSpaceModelBloc>().add(
|
|
||||||
RemoveSubSpaceModel(subSpace),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_event.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
|
||||||
|
|
||||||
class SubspacesTextfield extends StatefulWidget {
|
|
||||||
const SubspacesTextfield({
|
|
||||||
required this.hintText,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String? hintText;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SubspacesTextfield> createState() => _SubspacesTextfieldState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SubspacesTextfieldState extends State<SubspacesTextfield> {
|
|
||||||
late final TextEditingController _controller;
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_controller = TextEditingController();
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_controller.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox(
|
|
||||||
width: 100,
|
|
||||||
child: TextField(
|
|
||||||
controller: _controller,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: InputBorder.none,
|
|
||||||
hintText: widget.hintText,
|
|
||||||
hintStyle: context.textTheme.bodySmall?.copyWith(
|
|
||||||
color: ColorsManager.lightGrayColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onSubmitted: (value) {
|
|
||||||
final trimmedValue = value.trim();
|
|
||||||
if (trimmedValue.isNotEmpty) {
|
|
||||||
context.read<SubSpaceModelBloc>().add(
|
|
||||||
AddSubSpaceModel(
|
|
||||||
SubspaceTemplateModel(
|
|
||||||
subspaceName: trimmedValue,
|
|
||||||
disabled: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_controller.clear();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,10 +13,12 @@ class Assets {
|
|||||||
static const String rightLine = "assets/images/right_line.png";
|
static const String rightLine = "assets/images/right_line.png";
|
||||||
static const String google = "assets/images/google.svg";
|
static const String google = "assets/images/google.svg";
|
||||||
static const String facebook = "assets/images/facebook.svg";
|
static const String facebook = "assets/images/facebook.svg";
|
||||||
static const String invisiblePassword = "assets/images/Password_invisible.svg";
|
static const String invisiblePassword =
|
||||||
|
"assets/images/Password_invisible.svg";
|
||||||
static const String visiblePassword = "assets/images/password_visible.svg";
|
static const String visiblePassword = "assets/images/password_visible.svg";
|
||||||
static const String accessIcon = "assets/images/access_icon.svg";
|
static const String accessIcon = "assets/images/access_icon.svg";
|
||||||
static const String spaseManagementIcon = "assets/images/spase_management_icon.svg";
|
static const String spaseManagementIcon =
|
||||||
|
"assets/images/spase_management_icon.svg";
|
||||||
static const String devicesIcon = "assets/images/devices_icon.svg";
|
static const String devicesIcon = "assets/images/devices_icon.svg";
|
||||||
static const String moveinIcon = "assets/images/movein_icon.svg";
|
static const String moveinIcon = "assets/images/movein_icon.svg";
|
||||||
static const String constructionIcon = "assets/images/construction_icon.svg";
|
static const String constructionIcon = "assets/images/construction_icon.svg";
|
||||||
@ -29,13 +31,15 @@ class Assets {
|
|||||||
static const String emptyTable = "assets/images/empty_table.svg";
|
static const String emptyTable = "assets/images/empty_table.svg";
|
||||||
|
|
||||||
// General assets
|
// General assets
|
||||||
static const String motionlessDetection = "assets/icons/motionless_detection.svg";
|
static const String motionlessDetection =
|
||||||
|
"assets/icons/motionless_detection.svg";
|
||||||
static const String acHeating = "assets/icons/ac_heating.svg";
|
static const String acHeating = "assets/icons/ac_heating.svg";
|
||||||
static const String acPowerOff = "assets/icons/ac_power_off.svg";
|
static const String acPowerOff = "assets/icons/ac_power_off.svg";
|
||||||
static const String acFanMiddle = "assets/icons/ac_fan_middle.svg";
|
static const String acFanMiddle = "assets/icons/ac_fan_middle.svg";
|
||||||
static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg";
|
static const String switchAlarmSound = "assets/icons/switch_alarm_sound.svg";
|
||||||
static const String resetOff = "assets/icons/reset_off.svg";
|
static const String resetOff = "assets/icons/reset_off.svg";
|
||||||
static const String sensitivityOperationIcon = "assets/icons/sesitivity_operation_icon.svg";
|
static const String sensitivityOperationIcon =
|
||||||
|
"assets/icons/sesitivity_operation_icon.svg";
|
||||||
static const String motionDetection = "assets/icons/motion_detection.svg";
|
static const String motionDetection = "assets/icons/motion_detection.svg";
|
||||||
static const String freezing = "assets/icons/freezing.svg";
|
static const String freezing = "assets/icons/freezing.svg";
|
||||||
static const String indicator = "assets/icons/indicator.svg";
|
static const String indicator = "assets/icons/indicator.svg";
|
||||||
@ -56,7 +60,8 @@ class Assets {
|
|||||||
static const String celsiusDegrees = "assets/icons/celsius_degrees.svg";
|
static const String celsiusDegrees = "assets/icons/celsius_degrees.svg";
|
||||||
static const String masterState = "assets/icons/master_state.svg";
|
static const String masterState = "assets/icons/master_state.svg";
|
||||||
static const String acPower = "assets/icons/ac_power.svg";
|
static const String acPower = "assets/icons/ac_power.svg";
|
||||||
static const String farDetectionFunction = "assets/icons/far_detection_function.svg";
|
static const String farDetectionFunction =
|
||||||
|
"assets/icons/far_detection_function.svg";
|
||||||
static const String nobodyTime = "assets/icons/nobody_time.svg";
|
static const String nobodyTime = "assets/icons/nobody_time.svg";
|
||||||
|
|
||||||
// Automation functions
|
// Automation functions
|
||||||
@ -64,33 +69,47 @@ class Assets {
|
|||||||
"assets/icons/automation_functions/temp_password_unlock.svg";
|
"assets/icons/automation_functions/temp_password_unlock.svg";
|
||||||
static const String doorlockNormalOpen =
|
static const String doorlockNormalOpen =
|
||||||
"assets/icons/automation_functions/doorlock_normal_open.svg";
|
"assets/icons/automation_functions/doorlock_normal_open.svg";
|
||||||
static const String doorbell = "assets/icons/automation_functions/doorbell.svg";
|
static const String doorbell =
|
||||||
|
"assets/icons/automation_functions/doorbell.svg";
|
||||||
static const String remoteUnlockViaApp =
|
static const String remoteUnlockViaApp =
|
||||||
"assets/icons/automation_functions/remote_unlock_via_app.svg";
|
"assets/icons/automation_functions/remote_unlock_via_app.svg";
|
||||||
static const String doubleLock = "assets/icons/automation_functions/double_lock.svg";
|
static const String doubleLock =
|
||||||
static const String selfTestResult = "assets/icons/automation_functions/self_test_result.svg";
|
"assets/icons/automation_functions/double_lock.svg";
|
||||||
static const String lockAlarm = "assets/icons/automation_functions/lock_alarm.svg";
|
static const String selfTestResult =
|
||||||
static const String presenceState = "assets/icons/automation_functions/presence_state.svg";
|
"assets/icons/automation_functions/self_test_result.svg";
|
||||||
static const String currentTemp = "assets/icons/automation_functions/current_temp.svg";
|
static const String lockAlarm =
|
||||||
static const String presence = "assets/icons/automation_functions/presence.svg";
|
"assets/icons/automation_functions/lock_alarm.svg";
|
||||||
|
static const String presenceState =
|
||||||
|
"assets/icons/automation_functions/presence_state.svg";
|
||||||
|
static const String currentTemp =
|
||||||
|
"assets/icons/automation_functions/current_temp.svg";
|
||||||
|
static const String presence =
|
||||||
|
"assets/icons/automation_functions/presence.svg";
|
||||||
static const String residualElectricity =
|
static const String residualElectricity =
|
||||||
"assets/icons/automation_functions/residual_electricity.svg";
|
"assets/icons/automation_functions/residual_electricity.svg";
|
||||||
static const String hijackAlarm = "assets/icons/automation_functions/hijack_alarm.svg";
|
static const String hijackAlarm =
|
||||||
static const String passwordUnlock = "assets/icons/automation_functions/password_unlock.svg";
|
"assets/icons/automation_functions/hijack_alarm.svg";
|
||||||
|
static const String passwordUnlock =
|
||||||
|
"assets/icons/automation_functions/password_unlock.svg";
|
||||||
static const String remoteUnlockRequest =
|
static const String remoteUnlockRequest =
|
||||||
"assets/icons/automation_functions/remote_unlock_req.svg";
|
"assets/icons/automation_functions/remote_unlock_req.svg";
|
||||||
static const String cardUnlock = "assets/icons/automation_functions/card_unlock.svg";
|
static const String cardUnlock =
|
||||||
|
"assets/icons/automation_functions/card_unlock.svg";
|
||||||
static const String motion = "assets/icons/automation_functions/motion.svg";
|
static const String motion = "assets/icons/automation_functions/motion.svg";
|
||||||
static const String fingerprintUnlock =
|
static const String fingerprintUnlock =
|
||||||
"assets/icons/automation_functions/fingerprint_unlock.svg";
|
"assets/icons/automation_functions/fingerprint_unlock.svg";
|
||||||
|
|
||||||
// Presence Sensor Assets
|
// Presence Sensor Assets
|
||||||
static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg";
|
static const String sensorMotionIcon = "assets/icons/sensor_motion_ic.svg";
|
||||||
static const String sensorPresenceIcon = "assets/icons/sensor_presence_ic.svg";
|
static const String sensorPresenceIcon =
|
||||||
|
"assets/icons/sensor_presence_ic.svg";
|
||||||
static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg";
|
static const String sensorVacantIcon = "assets/icons/sensor_vacant_ic.svg";
|
||||||
static const String illuminanceRecordIcon = "assets/icons/illuminance_record_ic.svg";
|
static const String illuminanceRecordIcon =
|
||||||
static const String presenceRecordIcon = "assets/icons/presence_record_ic.svg";
|
"assets/icons/illuminance_record_ic.svg";
|
||||||
static const String helpDescriptionIcon = "assets/icons/help_description_ic.svg";
|
static const String presenceRecordIcon =
|
||||||
|
"assets/icons/presence_record_ic.svg";
|
||||||
|
static const String helpDescriptionIcon =
|
||||||
|
"assets/icons/help_description_ic.svg";
|
||||||
|
|
||||||
static const String lightPulp = "assets/icons/light_pulb.svg";
|
static const String lightPulp = "assets/icons/light_pulb.svg";
|
||||||
static const String acDevice = "assets/icons/ac_device.svg";
|
static const String acDevice = "assets/icons/ac_device.svg";
|
||||||
@ -140,10 +159,12 @@ class Assets {
|
|||||||
static const String unit = 'assets/icons/unit_icon.svg';
|
static const String unit = 'assets/icons/unit_icon.svg';
|
||||||
static const String villa = 'assets/icons/villa_icon.svg';
|
static const String villa = 'assets/icons/villa_icon.svg';
|
||||||
static const String iconEdit = 'assets/icons/icon_edit_icon.svg';
|
static const String iconEdit = 'assets/icons/icon_edit_icon.svg';
|
||||||
static const String textFieldSearch = 'assets/icons/textfield_search_icon.svg';
|
static const String textFieldSearch =
|
||||||
|
'assets/icons/textfield_search_icon.svg';
|
||||||
static const String roundedAddIcon = 'assets/icons/rounded_add_icon.svg';
|
static const String roundedAddIcon = 'assets/icons/rounded_add_icon.svg';
|
||||||
static const String addIcon = 'assets/icons/add_icon.svg';
|
static const String addIcon = 'assets/icons/add_icon.svg';
|
||||||
static const String smartThermostatIcon = 'assets/icons/smart_thermostat_icon.svg';
|
static const String smartThermostatIcon =
|
||||||
|
'assets/icons/smart_thermostat_icon.svg';
|
||||||
static const String smartLightIcon = 'assets/icons/smart_light_icon.svg';
|
static const String smartLightIcon = 'assets/icons/smart_light_icon.svg';
|
||||||
static const String presenceSensor = 'assets/icons/presence_sensor.svg';
|
static const String presenceSensor = 'assets/icons/presence_sensor.svg';
|
||||||
static const String Gang3SwitchIcon = 'assets/icons/3_Gang_switch_icon.svg';
|
static const String Gang3SwitchIcon = 'assets/icons/3_Gang_switch_icon.svg';
|
||||||
@ -191,7 +212,8 @@ class Assets {
|
|||||||
//assets/icons/water_leak_normal.svg
|
//assets/icons/water_leak_normal.svg
|
||||||
static const String waterLeakNormal = 'assets/icons/water_leak_normal.svg';
|
static const String waterLeakNormal = 'assets/icons/water_leak_normal.svg';
|
||||||
//assets/icons/water_leak_detected.svg
|
//assets/icons/water_leak_detected.svg
|
||||||
static const String waterLeakDetected = 'assets/icons/water_leak_detected.svg';
|
static const String waterLeakDetected =
|
||||||
|
'assets/icons/water_leak_detected.svg';
|
||||||
|
|
||||||
//assets/icons/automation_records.svg
|
//assets/icons/automation_records.svg
|
||||||
static const String automationRecords = 'assets/icons/automation_records.svg';
|
static const String automationRecords = 'assets/icons/automation_records.svg';
|
||||||
@ -258,40 +280,64 @@ class Assets {
|
|||||||
static const String delay = 'assets/icons/routine/delay.svg';
|
static const String delay = 'assets/icons/routine/delay.svg';
|
||||||
|
|
||||||
// Assets for functions_icons
|
// Assets for functions_icons
|
||||||
static const String assetsSensitivityFunction = "assets/icons/functions_icons/sensitivity.svg";
|
static const String assetsSensitivityFunction =
|
||||||
|
"assets/icons/functions_icons/sensitivity.svg";
|
||||||
static const String assetsSensitivityOperationIcon =
|
static const String assetsSensitivityOperationIcon =
|
||||||
"assets/icons/functions_icons/sesitivity_operation_icon.svg";
|
"assets/icons/functions_icons/sesitivity_operation_icon.svg";
|
||||||
static const String assetsAcPower = "assets/icons/functions_icons/ac_power.svg";
|
static const String assetsAcPower =
|
||||||
static const String assetsAcPowerOFF = "assets/icons/functions_icons/ac_power_off.svg";
|
"assets/icons/functions_icons/ac_power.svg";
|
||||||
static const String assetsChildLock = "assets/icons/functions_icons/child_lock.svg";
|
static const String assetsAcPowerOFF =
|
||||||
static const String assetsFreezing = "assets/icons/functions_icons/freezing.svg";
|
"assets/icons/functions_icons/ac_power_off.svg";
|
||||||
static const String assetsFanSpeed = "assets/icons/functions_icons/fan_speed.svg";
|
static const String assetsChildLock =
|
||||||
static const String assetsAcCooling = "assets/icons/functions_icons/ac_cooling.svg";
|
"assets/icons/functions_icons/child_lock.svg";
|
||||||
static const String assetsAcHeating = "assets/icons/functions_icons/ac_heating.svg";
|
static const String assetsFreezing =
|
||||||
static const String assetsCelsiusDegrees = "assets/icons/functions_icons/celsius_degrees.svg";
|
"assets/icons/functions_icons/freezing.svg";
|
||||||
static const String assetsTempreture = "assets/icons/functions_icons/tempreture.svg";
|
static const String assetsFanSpeed =
|
||||||
static const String assetsAcFanLow = "assets/icons/functions_icons/ac_fan_low.svg";
|
"assets/icons/functions_icons/fan_speed.svg";
|
||||||
static const String assetsAcFanMiddle = "assets/icons/functions_icons/ac_fan_middle.svg";
|
static const String assetsAcCooling =
|
||||||
static const String assetsAcFanHigh = "assets/icons/functions_icons/ac_fan_high.svg";
|
"assets/icons/functions_icons/ac_cooling.svg";
|
||||||
static const String assetsAcFanAuto = "assets/icons/functions_icons/ac_fan_auto.svg";
|
static const String assetsAcHeating =
|
||||||
static const String assetsSceneChildLock = "assets/icons/functions_icons/scene_child_lock.svg";
|
"assets/icons/functions_icons/ac_heating.svg";
|
||||||
|
static const String assetsCelsiusDegrees =
|
||||||
|
"assets/icons/functions_icons/celsius_degrees.svg";
|
||||||
|
static const String assetsTempreture =
|
||||||
|
"assets/icons/functions_icons/tempreture.svg";
|
||||||
|
static const String assetsAcFanLow =
|
||||||
|
"assets/icons/functions_icons/ac_fan_low.svg";
|
||||||
|
static const String assetsAcFanMiddle =
|
||||||
|
"assets/icons/functions_icons/ac_fan_middle.svg";
|
||||||
|
static const String assetsAcFanHigh =
|
||||||
|
"assets/icons/functions_icons/ac_fan_high.svg";
|
||||||
|
static const String assetsAcFanAuto =
|
||||||
|
"assets/icons/functions_icons/ac_fan_auto.svg";
|
||||||
|
static const String assetsSceneChildLock =
|
||||||
|
"assets/icons/functions_icons/scene_child_lock.svg";
|
||||||
static const String assetsSceneChildUnlock =
|
static const String assetsSceneChildUnlock =
|
||||||
"assets/icons/functions_icons/scene_child_unlock.svg";
|
"assets/icons/functions_icons/scene_child_unlock.svg";
|
||||||
static const String assetsSceneRefresh = "assets/icons/functions_icons/scene_refresh.svg";
|
static const String assetsSceneRefresh =
|
||||||
static const String assetsLightCountdown = "assets/icons/functions_icons/light_countdown.svg";
|
"assets/icons/functions_icons/scene_refresh.svg";
|
||||||
static const String assetsFarDetection = "assets/icons/functions_icons/far_detection.svg";
|
static const String assetsLightCountdown =
|
||||||
|
"assets/icons/functions_icons/light_countdown.svg";
|
||||||
|
static const String assetsFarDetection =
|
||||||
|
"assets/icons/functions_icons/far_detection.svg";
|
||||||
static const String assetsFarDetectionFunction =
|
static const String assetsFarDetectionFunction =
|
||||||
"assets/icons/functions_icons/far_detection_function.svg";
|
"assets/icons/functions_icons/far_detection_function.svg";
|
||||||
static const String assetsIndicator = "assets/icons/functions_icons/indicator.svg";
|
static const String assetsIndicator =
|
||||||
static const String assetsMotionDetection = "assets/icons/functions_icons/motion_detection.svg";
|
"assets/icons/functions_icons/indicator.svg";
|
||||||
|
static const String assetsMotionDetection =
|
||||||
|
"assets/icons/functions_icons/motion_detection.svg";
|
||||||
static const String assetsMotionlessDetection =
|
static const String assetsMotionlessDetection =
|
||||||
"assets/icons/functions_icons/motionless_detection.svg";
|
"assets/icons/functions_icons/motionless_detection.svg";
|
||||||
static const String assetsNobodyTime = "assets/icons/functions_icons/nobody_time.svg";
|
static const String assetsNobodyTime =
|
||||||
static const String assetsFactoryReset = "assets/icons/functions_icons/factory_reset.svg";
|
"assets/icons/functions_icons/nobody_time.svg";
|
||||||
static const String assetsMasterState = "assets/icons/functions_icons/master_state.svg";
|
static const String assetsFactoryReset =
|
||||||
|
"assets/icons/functions_icons/factory_reset.svg";
|
||||||
|
static const String assetsMasterState =
|
||||||
|
"assets/icons/functions_icons/master_state.svg";
|
||||||
static const String assetsSwitchAlarmSound =
|
static const String assetsSwitchAlarmSound =
|
||||||
"assets/icons/functions_icons/switch_alarm_sound.svg";
|
"assets/icons/functions_icons/switch_alarm_sound.svg";
|
||||||
static const String assetsResetOff = "assets/icons/functions_icons/reset_off.svg";
|
static const String assetsResetOff =
|
||||||
|
"assets/icons/functions_icons/reset_off.svg";
|
||||||
|
|
||||||
// Assets for automation_functions
|
// Assets for automation_functions
|
||||||
static const String assetsCardUnlock =
|
static const String assetsCardUnlock =
|
||||||
@ -322,7 +368,8 @@ class Assets {
|
|||||||
"assets/icons/functions_icons/automation_functions/self_test_result.svg";
|
"assets/icons/functions_icons/automation_functions/self_test_result.svg";
|
||||||
static const String assetsPresence =
|
static const String assetsPresence =
|
||||||
"assets/icons/functions_icons/automation_functions/presence.svg";
|
"assets/icons/functions_icons/automation_functions/presence.svg";
|
||||||
static const String assetsMotion = "assets/icons/functions_icons/automation_functions/motion.svg";
|
static const String assetsMotion =
|
||||||
|
"assets/icons/functions_icons/automation_functions/motion.svg";
|
||||||
static const String assetsCurrentTemp =
|
static const String assetsCurrentTemp =
|
||||||
"assets/icons/functions_icons/automation_functions/current_temp.svg";
|
"assets/icons/functions_icons/automation_functions/current_temp.svg";
|
||||||
static const String assetsPresenceState =
|
static const String assetsPresenceState =
|
||||||
@ -334,12 +381,16 @@ class Assets {
|
|||||||
static const String activeUser = 'assets/icons/active_user.svg';
|
static const String activeUser = 'assets/icons/active_user.svg';
|
||||||
static const String deActiveUser = 'assets/icons/deactive_user.svg';
|
static const String deActiveUser = 'assets/icons/deactive_user.svg';
|
||||||
static const String invitedIcon = 'assets/icons/invited_icon.svg';
|
static const String invitedIcon = 'assets/icons/invited_icon.svg';
|
||||||
static const String rectangleCheckBox = 'assets/icons/rectangle_check_box.png';
|
static const String rectangleCheckBox =
|
||||||
|
'assets/icons/rectangle_check_box.png';
|
||||||
static const String CheckBoxChecked = 'assets/icons/box_checked.png';
|
static const String CheckBoxChecked = 'assets/icons/box_checked.png';
|
||||||
static const String emptyBox = 'assets/icons/empty_box.png';
|
static const String emptyBox = 'assets/icons/empty_box.png';
|
||||||
static const String completeProcessIcon = 'assets/icons/compleate_process_icon.svg';
|
static const String completeProcessIcon =
|
||||||
static const String currentProcessIcon = 'assets/icons/current_process_icon.svg';
|
'assets/icons/compleate_process_icon.svg';
|
||||||
static const String uncomplete_ProcessIcon = 'assets/icons/uncompleate_process_icon.svg';
|
static const String currentProcessIcon =
|
||||||
|
'assets/icons/current_process_icon.svg';
|
||||||
|
static const String uncomplete_ProcessIcon =
|
||||||
|
'assets/icons/uncompleate_process_icon.svg';
|
||||||
static const String wrongProcessIcon = 'assets/icons/wrong_process_icon.svg';
|
static const String wrongProcessIcon = 'assets/icons/wrong_process_icon.svg';
|
||||||
static const String arrowForward = 'assets/icons/arrow_forward.svg';
|
static const String arrowForward = 'assets/icons/arrow_forward.svg';
|
||||||
static const String arrowDown = 'assets/icons/arrow_down.svg';
|
static const String arrowDown = 'assets/icons/arrow_down.svg';
|
||||||
@ -352,14 +403,17 @@ class Assets {
|
|||||||
static const String duplicate = 'assets/icons/duplicate.svg';
|
static const String duplicate = 'assets/icons/duplicate.svg';
|
||||||
static const String spaceDelete = 'assets/icons/space_delete.svg';
|
static const String spaceDelete = 'assets/icons/space_delete.svg';
|
||||||
|
|
||||||
static const String deleteSpaceLinkIcon = 'assets/icons/delete_space_link_icon.svg';
|
static const String deleteSpaceLinkIcon =
|
||||||
|
'assets/icons/delete_space_link_icon.svg';
|
||||||
static const String spaceLinkIcon = 'assets/icons/space_link_icon.svg';
|
static const String spaceLinkIcon = 'assets/icons/space_link_icon.svg';
|
||||||
static const String successIcon = 'assets/icons/success_icon.svg';
|
static const String successIcon = 'assets/icons/success_icon.svg';
|
||||||
static const String spaceLocationIcon = 'assets/icons/spaseLocationIcon.svg';
|
static const String spaceLocationIcon = 'assets/icons/spaseLocationIcon.svg';
|
||||||
static const String scenesPlayIcon = 'assets/icons/scenesPlayIcon.png';
|
static const String scenesPlayIcon = 'assets/icons/scenesPlayIcon.png';
|
||||||
static const String scenesPlayIconCheck = 'assets/icons/scenesPlayIconCheck.png';
|
static const String scenesPlayIconCheck =
|
||||||
|
'assets/icons/scenesPlayIconCheck.png';
|
||||||
static const String presenceStateIcon = 'assets/icons/presence_state.svg';
|
static const String presenceStateIcon = 'assets/icons/presence_state.svg';
|
||||||
static const String currentDistanceIcon = 'assets/icons/current_distance_icon.svg';
|
static const String currentDistanceIcon =
|
||||||
|
'assets/icons/current_distance_icon.svg';
|
||||||
|
|
||||||
static const String farDetectionIcon = 'assets/icons/far_detection_icon.svg';
|
static const String farDetectionIcon = 'assets/icons/far_detection_icon.svg';
|
||||||
static const String motionDetectionSensitivityIcon =
|
static const String motionDetectionSensitivityIcon =
|
||||||
@ -369,11 +423,8 @@ class Assets {
|
|||||||
'assets/icons/motionless_detection_sensitivity_icon.svg';
|
'assets/icons/motionless_detection_sensitivity_icon.svg';
|
||||||
|
|
||||||
static const String IndicatorIcon = 'assets/icons/Indicator_icon.svg';
|
static const String IndicatorIcon = 'assets/icons/Indicator_icon.svg';
|
||||||
static const String motionDetectionSensitivityValueIcon =
|
static const String motionDetectionSensitivityValueIcon = 'assets/icons/motion_detection_sensitivity_value_icon.svg';
|
||||||
'assets/icons/motion_detection_sensitivity_value_icon.svg';
|
static const String presenceTimeIcon = 'assets/icons/presence_time_icon.svg';
|
||||||
static const String presenceTimeIcon = 'assets/icons/presence_time_icon.svg';
|
static const String IlluminanceIcon = 'assets/icons/Illuminance_icon.svg';
|
||||||
static const String IlluminanceIcon = 'assets/icons/Illuminance_icon.svg';
|
|
||||||
static const String gear = 'assets/icons/gear.svg';
|
|
||||||
static const String activeBell = 'assets/icons/active_bell.svg';
|
|
||||||
static const String deviceTagIcon = 'assets/icons/device_tag_ic.svg';
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user