Compare commits

..

7 Commits

17 changed files with 617 additions and 219 deletions

View File

@ -0,0 +1,21 @@
<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>

After

Width:  |  Height:  |  Size: 3.8 KiB

3
assets/icons/gear.svg Normal file
View File

@ -0,0 +1,3 @@
<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>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -8,6 +8,7 @@ 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';
@ -247,18 +248,12 @@ SOS
switch (productType) { switch (productType) {
case 'AC': case 'AC':
return [ return [
SwitchFunction( SwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), ModeFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
ModeFunction( TempSetFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), CurrentTempFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
TempSetFunction( LevelFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), ChildLockFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
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':
@ -281,17 +276,17 @@ SOS
case '3G': case '3G':
return [ return [
ThreeGangSwitch1Function( ThreeGangSwitch1Function(
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), deviceId: uuid ?? '', deviceName: name ?? ''),
ThreeGangSwitch2Function( ThreeGangSwitch2Function(
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), deviceId: uuid ?? '', deviceName: name ?? ''),
ThreeGangSwitch3Function( ThreeGangSwitch3Function(
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), deviceId: uuid ?? '', deviceName: name ?? ''),
ThreeGangCountdown1Function( ThreeGangCountdown1Function(
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), deviceId: uuid ?? '', deviceName: name ?? ''),
ThreeGangCountdown2Function( ThreeGangCountdown2Function(
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), deviceId: uuid ?? '', deviceName: name ?? ''),
ThreeGangCountdown3Function( ThreeGangCountdown3Function(
deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'), deviceId: uuid ?? '', deviceName: name ?? ''),
]; ];
case 'WPS': case 'WPS':
return [ return [
@ -317,6 +312,26 @@ SOS
NoOneTimeFunction( NoOneTimeFunction(
deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'), deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
// FarDetectionSliderFunction(
// deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN')
];
case 'GW':
return [
GatewaySwitchAlarmSound(
deviceId: uuid ?? '',
deviceName: name ?? '',
type: 'BOTH',
),
GatewayMasterState(
deviceId: uuid ?? '',
deviceName: name ?? '',
type: 'BOTH',
),
GatewayFactoryReset(
deviceId: uuid ?? '',
deviceName: name ?? '',
type: 'BOTH',
),
]; ];
default: default:
return []; return [];

View File

@ -0,0 +1,40 @@
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>;
final switchAlarmSound = status.firstWhere(
(item) => item['code'] == 'switch_alarm_sound',
)['value'] as bool;
final masterState = status.firstWhere(
(item) => item['code'] == 'master_state',
)['value'] as String;
final factoryReset = status.firstWhere(
(item) => item['code'] == 'factory_reset',
)['value'] as bool;
final alarmActive = status.firstWhere(
(item) => item['code'] == 'alarm_active',
)['value'] as String;
return GatewayModel(
uuid: json['uuid'] as String,
switchAlarmSound: switchAlarmSound,
masterState: masterState,
factoryReset: factoryReset,
alarmActive: alarmActive,
);
}
}

View File

@ -1,11 +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/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/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_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/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';
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart'; import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/wall_sensor/wall_presence_sensor.dart';
class DeviceDialogHelper { class DeviceDialogHelper {
@ -49,46 +50,46 @@ class DeviceDialogHelper {
final deviceSelectedFunctions = final deviceSelectedFunctions =
routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? []; routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? [];
if (removeComparetors && data['productType'] != 'WPS') {
//remove the current temp function in the 'if container'
functions.removeAt(3);
}
switch (productType) { switch (productType) {
case 'AC': case 'AC':
return ACHelper.showACFunctionsDialog( return ACHelper.showACFunctionsDialog(
context: context, context,
functions: functions, functions,
device: data['device'], data['device'],
deviceSelectedFunctions: deviceSelectedFunctions, deviceSelectedFunctions,
uniqueCustomId: data['uniqueCustomId'], data['uniqueCustomId'],
removeComparetors: removeComparetors, removeComparetors,
dialogType: dialogType,
); );
case '1G': case '1G':
return OneGangSwitchHelper.showSwitchFunctionsDialog( return OneGangSwitchHelper.showSwitchFunctionsDialog(
dialogType: dialogType, context,
context: context, functions,
functions: functions, data['device'],
device: data['device'], deviceSelectedFunctions,
deviceSelectedFunctions: deviceSelectedFunctions, data['uniqueCustomId'],
uniqueCustomId: data['uniqueCustomId'], removeComparetors);
removeComparetors: removeComparetors);
case '2G': case '2G':
return TwoGangSwitchHelper.showSwitchFunctionsDialog( return TwoGangSwitchHelper.showSwitchFunctionsDialog(
dialogType: dialogType, context,
context: context, functions,
functions: functions, data['device'],
device: data['device'], deviceSelectedFunctions,
deviceSelectedFunctions: deviceSelectedFunctions, data['uniqueCustomId'],
uniqueCustomId: data['uniqueCustomId'], removeComparetors);
removeComparetors: removeComparetors);
case '3G': case '3G':
return ThreeGangSwitchHelper.showSwitchFunctionsDialog( return ThreeGangSwitchHelper.showSwitchFunctionsDialog(
dialogType: dialogType, context,
context: context, functions,
functions: functions, data['device'],
device: data['device'], deviceSelectedFunctions,
deviceSelectedFunctions: deviceSelectedFunctions, data['uniqueCustomId'],
uniqueCustomId: data['uniqueCustomId'], removeComparetors);
removeComparetors: removeComparetors);
case 'WPS': case 'WPS':
return WallPresenceSensor.showWPSFunctionsDialog( return WallPresenceSensor.showWPSFunctionsDialog(
dialogType: dialogType, dialogType: dialogType,
@ -98,6 +99,15 @@ class DeviceDialogHelper {
deviceSelectedFunctions: deviceSelectedFunctions, deviceSelectedFunctions: deviceSelectedFunctions,
uniqueCustomId: data['uniqueCustomId'], uniqueCustomId: data['uniqueCustomId'],
removeComparetors: removeComparetors); removeComparetors: removeComparetors);
case 'GW':
return GatewayHelper.showGatewayFunctionsDialog(
dialogType: dialogType,
context: context,
functions: functions,
uniqueCustomId: data['uniqueCustomId'],
deviceSelectedFunctions: deviceSelectedFunctions,
);
default: default:
return null; return null;
} }

View File

@ -5,28 +5,23 @@ import 'package:syncrow_web/utils/constants/app_enum.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
abstract class ACFunction extends DeviceFunction<AcStatusModel> { abstract class ACFunction extends DeviceFunction<AcStatusModel> {
final String type;
ACFunction({ ACFunction({
required super.deviceId, required super.deviceId,
required super.deviceName, required super.deviceName,
required super.code, required super.code,
required super.operationName, required super.operationName,
required super.icon, required super.icon,
required this.type,
}); });
List<ACOperationalValue> getOperationalValues(); List<ACOperationalValue> getOperationalValues();
} }
class SwitchFunction extends ACFunction { class SwitchFunction extends ACFunction {
SwitchFunction( SwitchFunction({required super.deviceId, required super.deviceName})
{required super.deviceId, required super.deviceName, required type})
: super( : super(
code: 'switch', code: 'switch',
operationName: 'Power', operationName: 'Power',
icon: Assets.assetsAcPower, icon: Assets.assetsAcPower,
type: type,
); );
@override @override
@ -45,13 +40,11 @@ class SwitchFunction extends ACFunction {
} }
class ModeFunction extends ACFunction { class ModeFunction extends ACFunction {
ModeFunction( ModeFunction({required super.deviceId, required super.deviceName})
{required super.deviceId, required super.deviceName, required type})
: super( : super(
code: 'mode', code: 'mode',
operationName: 'Mode', operationName: 'Mode',
icon: Assets.assetsFreezing, icon: Assets.assetsFreezing,
type: type,
); );
@override @override
@ -79,8 +72,7 @@ class TempSetFunction extends ACFunction {
final int max; final int max;
final int step; final int step;
TempSetFunction( TempSetFunction({required super.deviceId, required super.deviceName})
{required super.deviceId, required super.deviceName, required type})
: min = 160, : min = 160,
max = 300, max = 300,
step = 1, step = 1,
@ -88,7 +80,6 @@ class TempSetFunction extends ACFunction {
code: 'temp_set', code: 'temp_set',
operationName: 'Set Temperature', operationName: 'Set Temperature',
icon: Assets.assetsTempreture, icon: Assets.assetsTempreture,
type: type,
); );
@override @override
@ -106,10 +97,8 @@ class TempSetFunction extends ACFunction {
} }
class LevelFunction extends ACFunction { class LevelFunction extends ACFunction {
LevelFunction( LevelFunction({required super.deviceId, required super.deviceName})
{required super.deviceId, required super.deviceName, required type})
: super( : super(
type: type,
code: 'level', code: 'level',
operationName: 'Fan Speed', operationName: 'Fan Speed',
icon: Assets.assetsFanSpeed, icon: Assets.assetsFanSpeed,
@ -141,10 +130,8 @@ class LevelFunction extends ACFunction {
} }
class ChildLockFunction extends ACFunction { class ChildLockFunction extends ACFunction {
ChildLockFunction( ChildLockFunction({required super.deviceId, required super.deviceName})
{required super.deviceId, required super.deviceName, required type})
: super( : super(
type: type,
code: 'child_lock', code: 'child_lock',
operationName: 'Child Lock', operationName: 'Child Lock',
icon: Assets.assetsChildLock, icon: Assets.assetsChildLock,
@ -170,13 +157,11 @@ class CurrentTempFunction extends ACFunction {
final int max; final int max;
final int step; final int step;
CurrentTempFunction( CurrentTempFunction({required super.deviceId, required super.deviceName})
{required super.deviceId, required super.deviceName, required type})
: min = -100, : min = -100,
max = 990, max = 990,
step = 1, step = 1,
super( super(
type: type,
code: 'temp_current', code: 'temp_current',
operationName: 'Current Temperature', operationName: 'Current Temperature',
icon: Assets.currentTemp, icon: Assets.currentTemp,

View File

@ -3,7 +3,7 @@ import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operation
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
class ThreeGangSwitch1Function extends BaseSwitchFunction { class ThreeGangSwitch1Function extends BaseSwitchFunction {
ThreeGangSwitch1Function({required super.deviceId, required super.deviceName ,required type}) ThreeGangSwitch1Function({required super.deviceId, required super.deviceName})
: super( : super(
code: 'switch_1', code: 'switch_1',
operationName: 'Light 1 Switch', operationName: 'Light 1 Switch',
@ -26,7 +26,7 @@ class ThreeGangSwitch1Function extends BaseSwitchFunction {
} }
class ThreeGangCountdown1Function extends BaseSwitchFunction { class ThreeGangCountdown1Function extends BaseSwitchFunction {
ThreeGangCountdown1Function({required super.deviceId, required super.deviceName ,required type}) ThreeGangCountdown1Function({required super.deviceId, required super.deviceName})
: super( : super(
code: 'countdown_1', code: 'countdown_1',
operationName: 'Light 1 Countdown', operationName: 'Light 1 Countdown',
@ -47,7 +47,7 @@ class ThreeGangCountdown1Function extends BaseSwitchFunction {
} }
class ThreeGangSwitch2Function extends BaseSwitchFunction { class ThreeGangSwitch2Function extends BaseSwitchFunction {
ThreeGangSwitch2Function({required super.deviceId, required super.deviceName, required type}) ThreeGangSwitch2Function({required super.deviceId, required super.deviceName})
: super( : super(
code: 'switch_2', code: 'switch_2',
operationName: 'Light 2 Switch', operationName: 'Light 2 Switch',
@ -70,7 +70,7 @@ class ThreeGangSwitch2Function extends BaseSwitchFunction {
} }
class ThreeGangCountdown2Function extends BaseSwitchFunction { class ThreeGangCountdown2Function extends BaseSwitchFunction {
ThreeGangCountdown2Function({required super.deviceId, required super.deviceName ,required type}) ThreeGangCountdown2Function({required super.deviceId, required super.deviceName})
: super( : super(
code: 'countdown_2', code: 'countdown_2',
operationName: 'Light 2 Countdown', operationName: 'Light 2 Countdown',
@ -91,7 +91,7 @@ class ThreeGangCountdown2Function extends BaseSwitchFunction {
} }
class ThreeGangSwitch3Function extends BaseSwitchFunction { class ThreeGangSwitch3Function extends BaseSwitchFunction {
ThreeGangSwitch3Function({required super.deviceId, required super.deviceName ,required type}) ThreeGangSwitch3Function({required super.deviceId, required super.deviceName})
: super( : super(
code: 'switch_3', code: 'switch_3',
operationName: 'Light 3 Switch', operationName: 'Light 3 Switch',
@ -114,7 +114,7 @@ class ThreeGangSwitch3Function extends BaseSwitchFunction {
} }
class ThreeGangCountdown3Function extends BaseSwitchFunction { class ThreeGangCountdown3Function extends BaseSwitchFunction {
ThreeGangCountdown3Function({required super.deviceId, required super.deviceName ,required type}) ThreeGangCountdown3Function({required super.deviceId, required super.deviceName})
: super( : super(
code: 'countdown_3', code: 'countdown_3',
operationName: 'Light 3 Countdown', operationName: 'Light 3 Countdown',

View File

@ -0,0 +1,108 @@
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',
super.operationName = 'Switch Alarm Sound',
super.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',
super.operationName = 'Master State',
super.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',
super.operationName = 'Factory Reset',
super.icon = Assets.factoryReset,
});
@override
List<GatewayOperationalValue> getOperationalValues() {
return [
GatewayOperationalValue(
icon: Assets.assetsAcPower,
description: "ON",
value: true,
),
GatewayOperationalValue(
icon: Assets.assetsAcPowerOFF,
description: "OFF",
value: false,
),
];
}
}

View File

@ -72,6 +72,7 @@ class IfContainer extends StatelessWidget {
'2G', '2G',
'3G', '3G',
'WPS' 'WPS'
'GW',
].contains( ].contains(
state.ifItems[index]['productType'])) { state.ifItems[index]['productType'])) {
context.read<RoutineBloc>().add( context.read<RoutineBloc>().add(
@ -129,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'] } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW']
.contains(mutableData['productType'])) { .contains(mutableData['productType'])) {
context context
.read<RoutineBloc>() .read<RoutineBloc>()

View File

@ -1,6 +1,5 @@
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';
@ -32,14 +31,10 @@ class _RoutineDevicesState extends State<RoutineDevices> {
} }
}); });
List<AllDevicesModel> deviceList = state.devices final deviceList = state.devices.where((device) {
.where((device) => const allowedProductTypes = {'AC', '1G', '2G', '3G', 'WPS', 'GW'};
device.productType == 'AC' || return allowedProductTypes.contains(device.productType);
device.productType == '1G' || }).toList();
device.productType == '2G' ||
device.productType == '3G' ||
device.productType == 'WPS')
.toList();
return Wrap( return Wrap(
spacing: 10, spacing: 10,
@ -63,7 +58,7 @@ class _RoutineDevicesState extends State<RoutineDevices> {
'uniqueCustomId': '', 'uniqueCustomId': '',
}, },
) )
: Container(); : const SizedBox.shrink();
} else { } else {
return DraggableCard( return DraggableCard(
imagePath: device.getDefaultIcon(device.productType), imagePath: device.getDefaultIcon(device.productType),

View File

@ -13,38 +13,29 @@ 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/bloc/functions_bloc/functions_bloc_bloc.dart';
class ACHelper { class ACHelper {
static Future<Map<String, dynamic>?> showACFunctionsDialog({ static Future<Map<String, dynamic>?> showACFunctionsDialog(
required BuildContext context, BuildContext context,
required List<DeviceFunction> functions, List<DeviceFunction> functions,
required AllDevicesModel? device, AllDevicesModel? device,
required List<DeviceFunctionData>? deviceSelectedFunctions, List<DeviceFunctionData>? deviceSelectedFunctions,
required String uniqueCustomId, String uniqueCustomId,
required bool? removeComparetors, bool? removeComparetors,
required String dialogType, ) async {
}) async { List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList();
List<ACFunction> acFunctions =
functions.whereType<ACFunction>().where((function) {
if (dialogType == 'THEN') {
return function.type == 'THEN' || function.type == 'BOTH';
}
return function.type == 'IF' || function.type == 'BOTH';
}).toList();
// List<ACFunction> acFunctions = functions.whereType<ACFunction>().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() create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
..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 = state.addedFunctions final selectedFunctionData =
.firstWhere((f) => f.functionCode == selectedFunction, state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
orElse: () => DeviceFunctionData( orElse: () => DeviceFunctionData(
entityId: '', entityId: '',
functionCode: selectedFunction ?? '', functionCode: selectedFunction ?? '',
@ -74,10 +65,8 @@ class ACHelper {
child: _buildFunctionsList( child: _buildFunctionsList(
context: context, context: context,
acFunctions: acFunctions, acFunctions: acFunctions,
onFunctionSelected: onFunctionSelected: (functionCode, operationName) =>
(functionCode, operationName) => context context.read<FunctionBloc>().add(SelectFunction(
.read<FunctionBloc>()
.add(SelectFunction(
functionCode: functionCode, functionCode: functionCode,
operationName: operationName, operationName: operationName,
)), )),
@ -205,8 +194,7 @@ class ACHelper {
); );
} }
final selectedFn = final selectedFn = acFunctions.firstWhere((f) => f.code == selectedFunction);
acFunctions.firstWhere((f) => f.code == selectedFunction);
final values = selectedFn.getOperationalValues(); final values = selectedFn.getOperationalValues();
return _buildOperationalValuesList( return _buildOperationalValuesList(
@ -302,8 +290,7 @@ class ACHelper {
minHeight: 40.0, minHeight: 40.0,
minWidth: 40.0, minWidth: 40.0,
), ),
isSelected: isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
children: conditions.map((c) => Text(c)).toList(), children: conditions.map((c) => Text(c)).toList(),
); );
} }
@ -397,13 +384,9 @@ class ACHelper {
style: context.textTheme.bodyMedium, style: context.textTheme.bodyMedium,
), ),
trailing: Icon( trailing: Icon(
isSelected isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
size: 24, size: 24,
color: isSelected color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
? ColorsManager.primaryColorWithOpacity
: ColorsManager.textGray,
), ),
onTap: () { onTap: () {
if (!isSelected) { if (!isSelected) {
@ -415,8 +398,7 @@ class ACHelper {
operationName: operationName, operationName: operationName,
value: value.value, value: value.value,
condition: selectedFunctionData?.condition, condition: selectedFunctionData?.condition,
valueDescription: valueDescription: selectedFunctionData?.valueDescription,
selectedFunctionData?.valueDescription,
), ),
), ),
); );

View File

@ -0,0 +1,29 @@
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/device_functions.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_if_dialog.dart';
final class GatewayHelper {
static Future<Map<String, dynamic>?> showGatewayFunctionsDialog({
required String dialogType,
required BuildContext context,
required List<DeviceFunction> functions,
required String? uniqueCustomId,
required List<DeviceFunctionData> deviceSelectedFunctions,
}) async {
return showDialog(
context: context,
builder: (context) => BlocProvider<FunctionBloc>(
create: (context) => FunctionBloc()
..add(
InitializeFunctions(deviceSelectedFunctions),
),
child: GatewayIfDialog(
uniqueCustomId: uniqueCustomId,
functions: functions,
deviceSelectedFunctions: deviceSelectedFunctions),
),
);
}
}

View File

@ -0,0 +1,243 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.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/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
class GatewayIfDialog extends StatefulWidget {
const GatewayIfDialog({
required this.uniqueCustomId,
required this.functions,
required this.deviceSelectedFunctions,
super.key,
});
final String? uniqueCustomId;
final List<DeviceFunction> functions;
final List<DeviceFunctionData> deviceSelectedFunctions;
@override
State<GatewayIfDialog> createState() => _GatewayIfDialogState();
}
class _GatewayIfDialogState extends State<GatewayIfDialog> {
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 _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,
);
}
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,
),
);
return Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_buildFunctionList(context),
if (state.selectedFunction != null)
Expanded(
child: _buildValueSelector(
context: context,
selectedFunction: selectedFunction ?? '',
selectedFunctionData: selectedFunctionData,
acFunctions: _gatewayFunctions,
operationName: selectedOperationName ?? '',
),
),
],
);
}
Widget _buildFunctionList(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 ListTile(
leading: SvgPicture.asset(
function.icon,
width: 24,
height: 24,
placeholderBuilder: (context) => const SizedBox(
width: 24,
height: 24,
),
),
title: Text(
function.operationName,
style: context.textTheme.bodyMedium,
),
trailing: const Icon(
Icons.arrow_forward_ios,
size: 16,
color: ColorsManager.textGray,
),
onTap: () => context.read<FunctionBloc>().add(
SelectFunction(
functionCode: function.code,
operationName: function.operationName,
),
),
);
},
),
);
}
static Widget _buildValueSelector({
required BuildContext context,
required String selectedFunction,
required DeviceFunctionData? selectedFunctionData,
required List<GatewayFunctions> acFunctions,
AllDevicesModel? device,
required String operationName,
}) {
final selectedGatewayFunctions = acFunctions.firstWhere(
(f) => f.code == selectedFunction,
);
final values = selectedGatewayFunctions.getOperationalValues();
return _buildOperationalValuesList(
context: context,
values: values,
selectedValue: selectedFunctionData?.value,
device: device,
operationName: operationName,
selectCode: selectedFunction,
selectedFunctionData: selectedFunctionData,
);
}
static Widget _buildOperationalValuesList({
required BuildContext context,
required List<GatewayOperationalValue> values,
required dynamic selectedValue,
AllDevicesModel? device,
required String operationName,
required String selectCode,
DeviceFunctionData? selectedFunctionData,
}) {
return ListView.builder(
itemCount: values.length,
itemBuilder: (context, index) {
final value = values[index];
final isSelected = selectedValue == value.value;
return ListTile(
leading: SvgPicture.asset(
value.icon,
width: 24,
height: 24,
placeholderBuilder: (context) => Container(
width: 24,
height: 24,
color: Colors.transparent,
),
),
title: Text(
value.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: () {
if (!isSelected) {
context.read<FunctionBloc>().add(
AddFunction(
functionData: DeviceFunctionData(
entityId: device?.uuid ?? '',
functionCode: selectCode,
operationName: operationName,
value: value.value,
condition: selectedFunctionData?.condition,
valueDescription: selectedFunctionData?.valueDescription,
),
),
);
}
},
);
},
);
}
}

View File

@ -5,10 +5,8 @@ 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/switch_operational_value.dart'; import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.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/dialog_header.dart';
@ -16,32 +14,29 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
class OneGangSwitchHelper { class OneGangSwitchHelper {
static Future<Map<String, dynamic>?> showSwitchFunctionsDialog({ static Future<Map<String, dynamic>?> showSwitchFunctionsDialog(
required String dialogType, BuildContext context,
required BuildContext context, List<DeviceFunction> functions,
required List<DeviceFunction> functions, AllDevicesModel? device,
required AllDevicesModel? device, List<DeviceFunctionData>? deviceSelectedFunctions,
required List<DeviceFunctionData>? deviceSelectedFunctions, String uniqueCustomId,
required String uniqueCustomId, bool removeComparetors,
required bool removeComparetors, ) async {
}) async { List<BaseSwitchFunction> acFunctions = 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() create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
..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 = state.addedFunctions final selectedFunctionData =
.firstWhere((f) => f.functionCode == selectedFunction, state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
orElse: () => DeviceFunctionData( orElse: () => DeviceFunctionData(
entityId: '', entityId: '',
functionCode: selectedFunction ?? '', functionCode: selectedFunction ?? '',
@ -66,12 +61,12 @@ class OneGangSwitchHelper {
// Left side: Function list // Left side: Function list
Expanded( Expanded(
child: ListView.separated( child: ListView.separated(
itemCount: oneGangFunctions.length, itemCount: acFunctions.length,
separatorBuilder: (_, __) => const Divider( separatorBuilder: (_, __) => const Divider(
color: ColorsManager.dividerColor, color: ColorsManager.dividerColor,
), ),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final function = oneGangFunctions[index]; final function = acFunctions[index];
return ListTile( return ListTile(
leading: SvgPicture.asset( leading: SvgPicture.asset(
function.icon, function.icon,
@ -88,12 +83,9 @@ class OneGangSwitchHelper {
color: ColorsManager.textGray, color: ColorsManager.textGray,
), ),
onTap: () { onTap: () {
context context.read<FunctionBloc>().add(SelectFunction(
.read<FunctionBloc>()
.add(SelectFunction(
functionCode: function.code, functionCode: function.code,
operationName: operationName: function.operationName,
function.operationName,
)); ));
}, },
); );
@ -107,7 +99,7 @@ class OneGangSwitchHelper {
context: context, context: context,
selectedFunction: selectedFunction, selectedFunction: selectedFunction,
selectedFunctionData: selectedFunctionData, selectedFunctionData: selectedFunctionData,
acFunctions: oneGangFunctions, acFunctions: acFunctions,
device: device, device: device,
operationName: selectedOperationName ?? '', operationName: selectedOperationName ?? '',
removeComparetors: removeComparetors, removeComparetors: removeComparetors,
@ -182,14 +174,8 @@ class OneGangSwitchHelper {
removeComparetors: removeComparetors, removeComparetors: removeComparetors,
); );
} }
final selectedFn = acFunctions.firstWhere(
(f) => f.code == selectedFunction,
orElse: () => OneGangSwitchFunction(
deviceId: '',
deviceName: '',
),
);
final selectedFn = acFunctions.firstWhere((f) => f.code == selectedFunction);
final values = selectedFn.getOperationalValues(); final values = selectedFn.getOperationalValues();
return _buildOperationalValuesList( return _buildOperationalValuesList(
@ -226,11 +212,11 @@ class OneGangSwitchHelper {
selectedFunctionData, selectedFunctionData,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
_buildCountDownDisplay(context, initialValue, device, operationName, _buildCountDownDisplay(
selectedFunctionData, selectCode), context, initialValue, device, operationName, selectedFunctionData, selectCode),
const SizedBox(height: 20), const SizedBox(height: 20),
_buildCountDownSlider(context, initialValue, device, operationName, _buildCountDownSlider(
selectedFunctionData, selectCode), context, initialValue, device, operationName, selectedFunctionData, selectCode),
], ],
); );
} }
@ -271,8 +257,7 @@ class OneGangSwitchHelper {
minHeight: 40.0, minHeight: 40.0,
minWidth: 40.0, minWidth: 40.0,
), ),
isSelected: isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
children: conditions.map((c) => Text(c)).toList(), children: conditions.map((c) => Text(c)).toList(),
); );
} }
@ -320,8 +305,7 @@ 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) - divisions: (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) /
(operationalValues.minValue ?? 0)) /
(operationalValues.stepValue ?? 1)) (operationalValues.stepValue ?? 1))
.round(), .round(),
onChanged: (value) { onChanged: (value) {
@ -373,13 +357,9 @@ class OneGangSwitchHelper {
style: context.textTheme.bodyMedium, style: context.textTheme.bodyMedium,
), ),
trailing: Icon( trailing: Icon(
isSelected isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
size: 24, size: 24,
color: isSelected color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
? ColorsManager.primaryColorWithOpacity
: ColorsManager.textGray,
), ),
onTap: () { onTap: () {
if (!isSelected) { if (!isSelected) {
@ -391,8 +371,7 @@ class OneGangSwitchHelper {
operationName: operationName, operationName: operationName,
value: value.value, value: value.value,
condition: selectedFunctionData?.condition, condition: selectedFunctionData?.condition,
valueDescription: valueDescription: selectedFunctionData?.valueDescription,
selectedFunctionData?.valueDescription,
), ),
), ),
); );

View File

@ -14,15 +14,14 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
class ThreeGangSwitchHelper { class ThreeGangSwitchHelper {
static Future<Map<String, dynamic>?> showSwitchFunctionsDialog({ static Future<Map<String, dynamic>?> showSwitchFunctionsDialog(
required BuildContext context, BuildContext context,
required List<DeviceFunction> functions, List<DeviceFunction> functions,
required AllDevicesModel? device, AllDevicesModel? device,
required List<DeviceFunctionData>? deviceSelectedFunctions, List<DeviceFunctionData>? deviceSelectedFunctions,
required String uniqueCustomId, String uniqueCustomId,
required String dialogType, bool removeComparetors,
required bool removeComparetors, ) async {
}) async {
List<BaseSwitchFunction> switchFunctions = List<BaseSwitchFunction> switchFunctions =
functions.whereType<BaseSwitchFunction>().toList(); functions.whereType<BaseSwitchFunction>().toList();

View File

@ -14,32 +14,29 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
class TwoGangSwitchHelper { class TwoGangSwitchHelper {
static Future<Map<String, dynamic>?> showSwitchFunctionsDialog({ static Future<Map<String, dynamic>?> showSwitchFunctionsDialog(
required BuildContext context, BuildContext context,
required List<DeviceFunction> functions, List<DeviceFunction> functions,
required AllDevicesModel? device, AllDevicesModel? device,
required List<DeviceFunctionData>? deviceSelectedFunctions, List<DeviceFunctionData>? deviceSelectedFunctions,
required String uniqueCustomId, String uniqueCustomId,
required bool removeComparetors, bool removeComparetors,
required String dialogType, ) async {
}) async { List<BaseSwitchFunction> switchFunctions = functions.whereType<BaseSwitchFunction>().toList();
List<BaseSwitchFunction> switchFunctions =
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() create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
..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 = state.addedFunctions final selectedFunctionData =
.firstWhere((f) => f.functionCode == selectedFunction, state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
orElse: () => DeviceFunctionData( orElse: () => DeviceFunctionData(
entityId: '', entityId: '',
functionCode: selectedFunction ?? '', functionCode: selectedFunction ?? '',
@ -86,12 +83,9 @@ class TwoGangSwitchHelper {
color: ColorsManager.textGray, color: ColorsManager.textGray,
), ),
onTap: () { onTap: () {
context context.read<FunctionBloc>().add(SelectFunction(
.read<FunctionBloc>()
.add(SelectFunction(
functionCode: function.code, functionCode: function.code,
operationName: operationName: function.operationName,
function.operationName,
)); ));
}, },
); );
@ -167,8 +161,7 @@ class TwoGangSwitchHelper {
required String operationName, required String operationName,
required bool removeComparetors, required bool removeComparetors,
}) { }) {
if (selectedFunction == 'countdown_1' || if (selectedFunction == 'countdown_1' || selectedFunction == 'countdown_2') {
selectedFunction == 'countdown_2') {
final initialValue = selectedFunctionData?.value ?? 200; final initialValue = selectedFunctionData?.value ?? 200;
return _buildTemperatureSelector( return _buildTemperatureSelector(
context: context, context: context,
@ -182,8 +175,7 @@ class TwoGangSwitchHelper {
); );
} }
final selectedFn = final selectedFn = switchFunctions.firstWhere((f) => f.code == selectedFunction);
switchFunctions.firstWhere((f) => f.code == selectedFunction);
final values = selectedFn.getOperationalValues(); final values = selectedFn.getOperationalValues();
return _buildOperationalValuesList( return _buildOperationalValuesList(
@ -220,11 +212,11 @@ class TwoGangSwitchHelper {
selectedFunctionData, selectedFunctionData,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
_buildCountDownDisplay(context, initialValue, device, operationName, _buildCountDownDisplay(
selectedFunctionData, selectCode), context, initialValue, device, operationName, selectedFunctionData, selectCode),
const SizedBox(height: 20), const SizedBox(height: 20),
_buildCountDownSlider(context, initialValue, device, operationName, _buildCountDownSlider(
selectedFunctionData, selectCode), context, initialValue, device, operationName, selectedFunctionData, selectCode),
], ],
); );
} }
@ -265,8 +257,7 @@ class TwoGangSwitchHelper {
minHeight: 40.0, minHeight: 40.0,
minWidth: 40.0, minWidth: 40.0,
), ),
isSelected: isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
children: conditions.map((c) => Text(c)).toList(), children: conditions.map((c) => Text(c)).toList(),
); );
} }
@ -314,8 +305,7 @@ class TwoGangSwitchHelper {
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) - divisions: (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) /
(operationalValues.minValue ?? 0)) /
(operationalValues.stepValue ?? 1)) (operationalValues.stepValue ?? 1))
.round(), .round(),
onChanged: (value) { onChanged: (value) {
@ -367,13 +357,9 @@ class TwoGangSwitchHelper {
style: context.textTheme.bodyMedium, style: context.textTheme.bodyMedium,
), ),
trailing: Icon( trailing: Icon(
isSelected isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
size: 24, size: 24,
color: isSelected color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
? ColorsManager.primaryColorWithOpacity
: ColorsManager.textGray,
), ),
onTap: () { onTap: () {
if (!isSelected) { if (!isSelected) {
@ -385,8 +371,7 @@ class TwoGangSwitchHelper {
operationName: operationName, operationName: operationName,
value: value.value, value: value.value,
condition: selectedFunctionData?.condition, condition: selectedFunctionData?.condition,
valueDescription: valueDescription: selectedFunctionData?.valueDescription,
selectedFunctionData?.valueDescription,
), ),
), ),
); );

View File

@ -426,5 +426,8 @@ class Assets {
static const String motionDetectionSensitivityValueIcon = 'assets/icons/motion_detection_sensitivity_value_icon.svg'; static const String motionDetectionSensitivityValueIcon = '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';
} }