Compare commits

..

11 Commits

Author SHA1 Message Date
fd6b737556 Refactor one_gang_switch_dialog.dart to use one_gang_switch instead of ac in function names and variables 2025-04-09 12:17:26 +03:00
d08ab8caac add dialogType to devices and add parameter in showSwitchFunctionsDialog 2025-04-09 10:09:56 +03:00
c2476b9719 Merge pull request #132 from SyncrowIOT/fix_routine_popup_and_wall_sensor_bugs
Fix routine popup and wall sensor bugs
2025-04-07 16:43:48 +03:00
a56f4e488e Refactor routine_view_card.dart to adjust the size of the CircularProgressIndicator
Fix routine popup
Update wall_presence_sensor.dart to handle null selectedOperationName
2025-04-07 16:42:44 +03:00
6bd9fb7e4e Refactor routine_view_card.dart to adjust the size o 2025-04-07 16:22:21 +03:00
d264409d29 - Refactor the WpsFunctions class in wps_functions.dart to use 'cm' instead of 'temp' for the description of operational values.
- Update the WallPresenceSensor class in wall_presence_sensor.dart to use the selected operation name
2025-04-07 14:27:36 +03:00
ca44f3bf55 fix routine popup 2025-04-07 12:53:12 +03:00
9949a0a0bf Merge pull request #131 from SyncrowIOT/SP-1281-FE-Save-Display-Configured-Sensor-as-a-Card
save presence state and edit selected value
2025-04-07 09:30:38 +03:00
52498f4e6b Merge pull request #130 from SyncrowIOT/routine_ui_issue
Refactor SVG icons and update asset paths and fix RoutinesView issues
2025-04-06 16:33:49 +03:00
37440f288c Merge branch 'dev' into routine_ui_issue 2025-04-06 16:27:34 +03:00
ad922577da Refactor SVG icons and update asset paths and fix RoutinesView issues 2025-04-06 11:28:59 +03:00
24 changed files with 677 additions and 578 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,17 +0,0 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_6675_32326)">
<path d="M18 3C9.71584 3 3 9.71572 3 18C3 26.2843 9.71584 33 18 33C26.2842 33 33 26.2843 33 18C33 9.71572 26.2842 3 18 3ZM23.1844 18.7951L15.6844 23.4826C15.5326 23.5774 15.3601 23.625 15.1875 23.625C15.0312 23.625 14.8746 23.5861 14.7329 23.5073C14.4349 23.3421 14.25 23.0285 14.25 22.6875V13.3125C14.25 12.9715 14.4349 12.6579 14.7329 12.4927C15.0309 12.3265 15.3953 12.3366 15.6844 12.5174L23.1844 17.2049C23.4584 17.3766 23.625 17.6769 23.625 18C23.625 18.3231 23.4584 18.6235 23.1844 18.7951Z" fill="#F4F4F4"/>
</g>
<defs>
<filter id="filter0_d_6675_32326" x="0" y="0" width="36" height="36" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="1.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_6675_32326"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_6675_32326" result="shape"/>
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,30 +0,0 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_7280_5211)">
<circle cx="18" cy="18" r="15" fill="#F4F4F4"/>
</g>
<g filter="url(#filter1_i_7280_5211)">
<path d="M25.1663 13.187C24.8231 12.8439 24.2666 12.8439 23.9234 13.1871L16.1621 20.9484L12.0766 16.8628C11.7334 16.5196 11.1768 16.5196 10.8336 16.8628C10.4904 17.206 10.4904 17.7625 10.8336 18.1057L15.5406 22.8127C15.7122 22.9844 15.9372 23.0701 16.1621 23.0701C16.3869 23.0701 16.6119 22.9843 16.7835 22.8127L25.1663 14.43C25.5095 14.0868 25.5095 13.5303 25.1663 13.187Z" fill="white"/>
</g>
<defs>
<filter id="filter0_d_7280_5211" x="0" y="0" width="36" height="36" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="1.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_7280_5211"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_7280_5211" result="shape"/>
</filter>
<filter id="filter1_i_7280_5211" x="10.5762" y="12.9297" width="14.8475" height="10.1406" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="1.5"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_7280_5211"/>
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

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

View File

@ -2,6 +2,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_manager.dart'; import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_event.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_event.dart';
import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_state.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_state.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/services/space_mana_api.dart'; import 'package:syncrow_web/services/space_mana_api.dart';
@ -10,11 +11,12 @@ class CreateRoutineBloc extends Bloc<CreateRoutineEvent, CreateRoutineState> {
on<SpaceOnlyWithDevicesEvent>(_fetchSpaceOnlyWithDevices); on<SpaceOnlyWithDevicesEvent>(_fetchSpaceOnlyWithDevices);
on<SaveCommunityIdAndSpaceIdEvent>(saveSpaceIdCommunityId); on<SaveCommunityIdAndSpaceIdEvent>(saveSpaceIdCommunityId);
on<ResetSelectedEvent>(resetSelected); on<ResetSelectedEvent>(resetSelected);
on<FetchCommunityEvent>(_fetchCommunity);
} }
String selectedSpaceId = ''; String selectedSpaceId = '';
String selectedCommunityId = ''; String selectedCommunityId = '';
List<CommunityModel> communities = [];
List<SpaceModel> spacesOnlyWithDevices = []; List<SpaceModel> spacesOnlyWithDevices = [];
Future<void> _fetchSpaceOnlyWithDevices( Future<void> _fetchSpaceOnlyWithDevices(
@ -30,7 +32,7 @@ class CreateRoutineBloc extends Bloc<CreateRoutineEvent, CreateRoutineState> {
emit(SpaceWithDeviceLoadedState(spacesOnlyWithDevices)); emit(SpaceWithDeviceLoadedState(spacesOnlyWithDevices));
} catch (e) { } catch (e) {
emit(SpaceTreeErrorState('Error loading communities and spaces: $e')); emit(SpaceTreeErrorState('Error loading spaces: $e'));
} }
} }
@ -48,4 +50,18 @@ class CreateRoutineBloc extends Bloc<CreateRoutineEvent, CreateRoutineState> {
selectedCommunityId = ''; selectedCommunityId = '';
emit(const ResetSelectedState()); emit(const ResetSelectedState());
} }
Future<void> _fetchCommunity(
FetchCommunityEvent event, Emitter<CreateRoutineState> emit) async {
emit(const CommunitiesLoadingState());
try {
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
communities =
await CommunitySpaceManagementApi().fetchCommunities(projectUuid);
emit(const CommunityLoadedState());
} catch (e) {
emit(SpaceTreeErrorState('Error loading communities $e'));
}
}
} }

View File

@ -41,3 +41,11 @@ class ResetSelectedEvent extends CreateRoutineEvent {
@override @override
List<Object> get props => []; List<Object> get props => [];
} }
class FetchCommunityEvent extends CreateRoutineEvent {
const FetchCommunityEvent();
@override
List<Object> get props => [];
}

View File

@ -44,3 +44,10 @@ class ResetSelectedState extends CreateRoutineState {
const ResetSelectedState(); const ResetSelectedState();
} }
class CommunityLoadedState extends CreateRoutineState {
const CommunityLoadedState();
}
class CommunitiesLoadingState extends CreateRoutineState {
const CommunitiesLoadingState();
}

View File

@ -1,12 +1,11 @@
import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class CommunityDropdown extends StatelessWidget { class CommunityDropdown extends StatelessWidget {
final String? selectedValue; final String? selectedValue;
final List<CommunityModel> communities;
final Function(String?) onChanged; final Function(String?) onChanged;
final TextEditingController _searchController = TextEditingController(); final TextEditingController _searchController = TextEditingController();
@ -14,6 +13,7 @@ class CommunityDropdown extends StatelessWidget {
Key? key, Key? key,
required this.selectedValue, required this.selectedValue,
required this.onChanged, required this.onChanged,
required this.communities,
}) : super(key: key); }) : super(key: key);
@override @override
@ -32,123 +32,123 @@ class CommunityDropdown extends StatelessWidget {
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
BlocBuilder<SpaceTreeBloc, SpaceTreeState>( SizedBox(
builder: (context, state) { child: Container(
return SizedBox( decoration: BoxDecoration(
child: Container( borderRadius: BorderRadius.circular(10),
),
child: DropdownButton2<String>(
underline: const SizedBox(),
value: selectedValue,
items: communities.map((community) {
return DropdownMenuItem<String>(
value: community.uuid,
child: Text(
' ${community.name}',
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
);
}).toList(),
onChanged: onChanged,
style: const TextStyle(color: Colors.black),
hint: Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
" Please Select",
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.textGray,
),
),
),
customButton: Container(
height: 45,
decoration: BoxDecoration(
border: Border.all(color: ColorsManager.textGray, width: 1.0),
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 5,
child: Text(
selectedValue != null
? " ${communities.firstWhere((element) => element.uuid == selectedValue).name}"
: ' Please Select',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: selectedValue != null
? Colors.black
: ColorsManager.textGray,
),
overflow: TextOverflow.ellipsis,
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
height: 45,
child: const Icon(
Icons.keyboard_arrow_down,
color: ColorsManager.textGray,
),
),
),
],
),
),
dropdownStyleData: DropdownStyleData(
maxHeight: MediaQuery.of(context).size.height * 0.4,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
child: DropdownButton2<String>( ),
underline: SizedBox(), dropdownSearchData: DropdownSearchData(
value: selectedValue, searchController: _searchController,
items: state.communityList.map((community) { searchInnerWidgetHeight: 50,
return DropdownMenuItem<String>( searchInnerWidget: Container(
value: community.uuid, height: 50,
child: Text( padding:
' ${community.name}', const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
overflow: TextOverflow.ellipsis, child: TextFormField(
maxLines: 1, style: const TextStyle(color: Colors.black),
controller: _searchController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 12,
), ),
); hintText: 'Search for community...',
}).toList(), border: OutlineInputBorder(
onChanged: onChanged, borderRadius: BorderRadius.circular(8),
style: TextStyle(color: Colors.black),
hint: Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
" Please Select",
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.textGray,
),
),
),
customButton: Container(
height: 45,
decoration: BoxDecoration(
border: Border.all(color: ColorsManager.textGray, width: 1.0),
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 5,
child: Text(
selectedValue != null
? " ${state.communityList.firstWhere((element) => element.uuid == selectedValue).name}"
: ' Please Select',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color:
selectedValue != null ? Colors.black : ColorsManager.textGray,
),
overflow: TextOverflow.ellipsis,
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: const BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
height: 45,
child: const Icon(
Icons.keyboard_arrow_down,
color: ColorsManager.textGray,
),
),
),
],
),
),
dropdownStyleData: DropdownStyleData(
maxHeight: MediaQuery.of(context).size.height * 0.4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
),
dropdownSearchData: DropdownSearchData(
searchController: _searchController,
searchInnerWidgetHeight: 50,
searchInnerWidget: Container(
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: TextFormField(
style: const TextStyle(color: Colors.black),
controller: _searchController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 12,
),
hintText: 'Search for community...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
), ),
), ),
searchMatchFn: (item, searchValue) {
final communityName = (item.child as Text).data?.toLowerCase() ?? '';
return communityName.contains(searchValue.toLowerCase().trim());
},
),
onMenuStateChange: (isOpen) {
if (!isOpen) {
_searchController.clear();
}
},
menuItemStyleData: const MenuItemStyleData(
height: 40,
), ),
), ),
)); searchMatchFn: (item, searchValue) {
}, final communityName =
), (item.child as Text).data?.toLowerCase() ?? '';
return communityName
.contains(searchValue.toLowerCase().trim());
},
),
onMenuStateChange: (isOpen) {
if (!isOpen) {
_searchController.clear();
}
},
menuItemStyleData: const MenuItemStyleData(
height: 40,
),
),
))
], ],
), ),
); );

View File

@ -5,11 +5,10 @@ import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routi
import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart';
import 'package:syncrow_web/pages/routines/create_new_routines/commu_dropdown.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/commu_dropdown.dart';
import 'package:syncrow_web/pages/routines/create_new_routines/space_dropdown.dart'; import 'package:syncrow_web/pages/routines/create_new_routines/space_dropdown.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class CreateNewRoutinesDialog extends StatefulWidget { class CreateNewRoutinesDialog extends StatefulWidget {
const CreateNewRoutinesDialog({Key? key}) : super(key: key); const CreateNewRoutinesDialog({super.key});
@override @override
State<CreateNewRoutinesDialog> createState() => State<CreateNewRoutinesDialog> createState() =>
@ -19,136 +18,160 @@ class CreateNewRoutinesDialog extends StatefulWidget {
class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> { class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
String? _selectedCommunity; String? _selectedCommunity;
String? _selectedSpace; String? _selectedSpace;
void _fetchSpaces(String communityId) {
context
.read<CreateRoutineBloc>()
.add(SpaceOnlyWithDevicesEvent(communityId));
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<CreateRoutineBloc, CreateRoutineState>( return BlocProvider(
builder: (context, state) { create: (BuildContext context) =>
final _bloc = BlocProvider.of<CreateRoutineBloc>(context); CreateRoutineBloc()..add(const FetchCommunityEvent()),
final spaces = _bloc.spacesOnlyWithDevices; child: BlocBuilder<CreateRoutineBloc, CreateRoutineState>(
final isLoading = state is SpaceWithDeviceLoadingState; builder: (context, state) {
final _bloc = BlocProvider.of<CreateRoutineBloc>(context);
final spaces = _bloc.spacesOnlyWithDevices;
final isLoadingCommunities = state is CommunitiesLoadingState;
final isLoadingSpaces = state is SpaceWithDeviceLoadingState;
String spaceHint = 'Select a community first';
if (_selectedCommunity != null) {
if (isLoadingSpaces) {
spaceHint = 'Loading spaces...';
} else if (spaces.isEmpty) {
spaceHint = 'No spaces available';
} else {
spaceHint = 'Select Space';
}
}
String spaceHint = 'Select a community first'; return AlertDialog(
backgroundColor: Colors.white,
if (_selectedCommunity != null) { insetPadding: EdgeInsets.zero,
if (isLoading) { contentPadding: EdgeInsets.zero,
spaceHint = 'Loading spaces...'; shape: RoundedRectangleBorder(
} else if (spaces.isEmpty) { borderRadius: BorderRadius.circular(12)),
spaceHint = 'No spaces available'; title: Text(
} else { 'Create New Routines',
spaceHint = 'Select Space'; textAlign: TextAlign.center,
} style: Theme.of(context).textTheme.bodyMedium!.copyWith(
} color: ColorsManager.primaryColor,
),
return AlertDialog(
backgroundColor: Colors.white,
insetPadding: EdgeInsets.zero,
contentPadding: EdgeInsets.zero,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
title: Text(
'Create New Routines',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: ColorsManager.primaryColor,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Divider(),
Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: CommunityDropdown(
selectedValue: _selectedCommunity,
onChanged: (String? newValue) {
setState(() {
_selectedCommunity = newValue;
_selectedSpace = null;
});
if (newValue != null) {
_fetchSpaces(newValue);
}
},
),
), ),
const SizedBox(height: 5), content: Stack(
Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: SpaceDropdown(
hintMessage: spaceHint,
spaces: spaces,
selectedValue: _selectedSpace,
onChanged: (String? newValue) {
setState(() {
_selectedSpace = newValue;
});
},
),
),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
Padding( Column(
padding: const EdgeInsets.only( mainAxisSize: MainAxisSize.min,
left: 20, children: [
right: 20, const Divider(),
), Padding(
child: TextButton( padding: const EdgeInsets.only(left: 15, right: 15),
onPressed: () { child: CommunityDropdown(
Navigator.of(context).pop(); communities: _bloc.communities,
}, selectedValue: _selectedCommunity,
child: Text( onChanged: (String? newValue) {
'Cancel', setState(() {
style: Theme.of(context).textTheme.bodyMedium!.copyWith( _selectedCommunity = newValue;
fontWeight: FontWeight.w400, _selectedSpace = null;
fontSize: 14, });
color: ColorsManager.blackColor, if (newValue != null) {
), _bloc.add(SpaceOnlyWithDevicesEvent(newValue));
}
},
),
), ),
), const SizedBox(height: 5),
), Padding(
Padding( padding: const EdgeInsets.only(left: 15, right: 15),
padding: const EdgeInsets.only( child: SpaceDropdown(
left: 20, hintMessage: spaceHint,
right: 20, spaces: spaces,
), selectedValue: _selectedSpace,
child: TextButton( onChanged: (String? newValue) {
onPressed: setState(() {
_selectedCommunity != null && _selectedSpace != null _selectedSpace = newValue;
? () { });
Navigator.of(context).pop({ },
'community': _selectedCommunity, ),
'space': _selectedSpace, ),
}); const Divider(),
} Row(
: null, mainAxisAlignment: MainAxisAlignment.spaceAround,
child: Text( children: [
'Next', Padding(
style: Theme.of(context).textTheme.bodyMedium!.copyWith( padding: const EdgeInsets.only(
fontWeight: FontWeight.w400, left: 20,
fontSize: 14, right: 20,
color: _selectedCommunity != null && ),
child: TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
'Cancel',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(
fontWeight: FontWeight.w400,
fontSize: 14,
color: ColorsManager.blackColor,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 20,
right: 20,
),
child: TextButton(
onPressed: _selectedCommunity != null &&
_selectedSpace != null _selectedSpace != null
? ColorsManager.blueColor ? () {
: Colors.blue.shade100, Navigator.of(context).pop({
'community': _selectedCommunity,
'space': _selectedSpace,
});
}
: null,
child: Text(
'Next',
style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(
fontWeight: FontWeight.w400,
fontSize: 14,
color: _selectedCommunity != null &&
_selectedSpace != null
? ColorsManager.blueColor
: Colors.blue.shade100,
),
),
), ),
),
],
),
const SizedBox(height: 10),
],
),
if (isLoadingCommunities)
const SizedBox(
height: 200,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: CircularProgressIndicator(
color: ColorsManager.primaryColor,
),
),
],
), ),
), ),
),
], ],
), ),
SizedBox(height: 10), );
], },
), ));
);
},
);
} }
} }

View File

@ -49,45 +49,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,
data['device'], device: data['device'],
deviceSelectedFunctions, deviceSelectedFunctions: deviceSelectedFunctions,
data['uniqueCustomId'], uniqueCustomId: data['uniqueCustomId'],
removeComparetors); removeComparetors: removeComparetors,
dialogType: dialogType,
);
case '1G': case '1G':
return OneGangSwitchHelper.showSwitchFunctionsDialog( return OneGangSwitchHelper.showSwitchFunctionsDialog(
context, dialogType: dialogType,
functions, context: context,
data['device'], functions: functions,
deviceSelectedFunctions, device: data['device'],
data['uniqueCustomId'], deviceSelectedFunctions: deviceSelectedFunctions,
removeComparetors); uniqueCustomId: data['uniqueCustomId'],
removeComparetors: removeComparetors);
case '2G': case '2G':
return TwoGangSwitchHelper.showSwitchFunctionsDialog( return TwoGangSwitchHelper.showSwitchFunctionsDialog(
context, dialogType: dialogType,
functions, context: context,
data['device'], functions: functions,
deviceSelectedFunctions, device: data['device'],
data['uniqueCustomId'], deviceSelectedFunctions: deviceSelectedFunctions,
removeComparetors); uniqueCustomId: data['uniqueCustomId'],
removeComparetors: removeComparetors);
case '3G': case '3G':
return ThreeGangSwitchHelper.showSwitchFunctionsDialog( return ThreeGangSwitchHelper.showSwitchFunctionsDialog(
context, dialogType: dialogType,
functions, context: context,
data['device'], functions: functions,
deviceSelectedFunctions, device: data['device'],
data['uniqueCustomId'], deviceSelectedFunctions: deviceSelectedFunctions,
removeComparetors); uniqueCustomId: data['uniqueCustomId'],
removeComparetors: removeComparetors);
case 'WPS': case 'WPS':
return WallPresenceSensor.showWPSFunctionsDialog( return WallPresenceSensor.showWPSFunctionsDialog(
dialogType: dialogType, dialogType: dialogType,

View File

@ -5,23 +5,28 @@ 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({required super.deviceId, required super.deviceName}) SwitchFunction(
{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
@ -40,11 +45,13 @@ class SwitchFunction extends ACFunction {
} }
class ModeFunction extends ACFunction { class ModeFunction extends ACFunction {
ModeFunction({required super.deviceId, required super.deviceName}) ModeFunction(
{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
@ -72,7 +79,8 @@ class TempSetFunction extends ACFunction {
final int max; final int max;
final int step; final int step;
TempSetFunction({required super.deviceId, required super.deviceName}) TempSetFunction(
{required super.deviceId, required super.deviceName, required type})
: min = 160, : min = 160,
max = 300, max = 300,
step = 1, step = 1,
@ -80,6 +88,7 @@ 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
@ -97,8 +106,10 @@ class TempSetFunction extends ACFunction {
} }
class LevelFunction extends ACFunction { class LevelFunction extends ACFunction {
LevelFunction({required super.deviceId, required super.deviceName}) LevelFunction(
{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,
@ -130,8 +141,10 @@ class LevelFunction extends ACFunction {
} }
class ChildLockFunction extends ACFunction { class ChildLockFunction extends ACFunction {
ChildLockFunction({required super.deviceId, required super.deviceName}) ChildLockFunction(
{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,
@ -157,11 +170,13 @@ class CurrentTempFunction extends ACFunction {
final int max; final int max;
final int step; final int step;
CurrentTempFunction({required super.deviceId, required super.deviceName}) CurrentTempFunction(
{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}) ThreeGangSwitch1Function({required super.deviceId, required super.deviceName ,required type})
: 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}) ThreeGangCountdown1Function({required super.deviceId, required super.deviceName ,required type})
: 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}) ThreeGangSwitch2Function({required super.deviceId, required super.deviceName, required type})
: 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}) ThreeGangCountdown2Function({required super.deviceId, required super.deviceName ,required type})
: 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}) ThreeGangSwitch3Function({required super.deviceId, required super.deviceName ,required type})
: 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}) ThreeGangCountdown3Function({required super.deviceId, required super.deviceName ,required type})
: super( : super(
code: 'countdown_3', code: 'countdown_3',
operationName: 'Light 3 Countdown', operationName: 'Light 3 Countdown',

View File

@ -244,11 +244,12 @@ class CurrentDistanceFunction extends WpsFunctions {
@override @override
List<WpsOperationalValue> getOperationalValues() { List<WpsOperationalValue> getOperationalValues() {
List<WpsOperationalValue> values = []; List<WpsOperationalValue> values = [];
for (int temp = min; temp <= max; temp += step) { for (int cm = min; cm <= max; cm += step) {
values.add(WpsOperationalValue( values.add(WpsOperationalValue(
icon: Assets.assetsTempreture, icon: Assets.assetsTempreture,
description: "${temp}CM", description: "${cm}CM",
value: temp,
value: cm,
)); ));
} }
return values; return values;

View File

@ -90,6 +90,7 @@ class _RoutinesViewState extends State<RoutinesView> {
], ],
), ),
), ),
const SizedBox(height: 50),
], ],
), ),
) )

View File

@ -105,9 +105,7 @@ class IfContainer extends StatelessWidget {
); );
}, },
onAcceptWithDetails: (data) async { onAcceptWithDetails: (data) async {
print('data.data=${data.data}');
final uniqueCustomId = const Uuid().v4(); final uniqueCustomId = const Uuid().v4();
final mutableData = Map<String, dynamic>.from(data.data); final mutableData = Map<String, dynamic>.from(data.data);
mutableData['uniqueCustomId'] = uniqueCustomId; mutableData['uniqueCustomId'] = uniqueCustomId;

View File

@ -31,165 +31,185 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
? const Center( ? const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
) )
: Padding( : SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 16.0), child: Padding(
child: Column( padding: const EdgeInsets.symmetric(vertical: 16.0),
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start,
children: [ mainAxisSize: MainAxisSize.min,
Text( children: [
"Scenes (Tab to Run)", Text(
style: Theme.of(context).textTheme.titleLarge?.copyWith( "Scenes (Tab to Run)",
color: ColorsManager.grayColor, style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold, color: ColorsManager.grayColor,
), fontWeight: FontWeight.bold,
), ),
const SizedBox(height: 10), ),
if (state.scenes.isEmpty) const SizedBox(height: 10),
Expanded( if (state.scenes.isEmpty)
child: Text( Text(
"No scenes found", "No scenes found",
style: context.textTheme.bodyMedium?.copyWith( style: context.textTheme.bodyMedium?.copyWith(
color: ColorsManager.grayColor, color: ColorsManager.grayColor,
), ),
), ),
), if (state.scenes.isNotEmpty)
if (state.scenes.isNotEmpty) SizedBox(
ConstrainedBox( height: 200,
constraints: BoxConstraints( child: ListView.builder(
maxHeight: isSmallScreenSize(context) ? 190 : 200, shrinkWrap: true,
maxWidth: MediaQuery.sizeOf(context).width * 0.8), scrollDirection: Axis.horizontal,
child: ListView.builder( itemCount: state.scenes.length,
scrollDirection: Axis.horizontal, itemBuilder: (context, index) {
itemCount: state.scenes.length, final scene = state.scenes[index];
itemBuilder: (context, index) { final isLoading =
final scene = state.scenes[index]; state.loadingSceneId == scene.id;
final isLoading =
state.loadingSceneId == scene.id;
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
right: isSmallScreenSize(context) ? 4.0 : 8.0, right:
), isSmallScreenSize(context) ? 4.0 : 8.0,
child: RoutineViewCard( ),
isLoading: isLoading, child: Column(
sceneOnTap: () { children: [
context.read<RoutineBloc>().add( RoutineViewCard(
SceneTrigger( isLoading: isLoading,
sceneId: scene.id, sceneOnTap: () {
name: scene.name)); context.read<RoutineBloc>().add(
}, SceneTrigger(
status: state.scenes[index].status, sceneId: scene.id,
communityId: name: scene.name));
state.scenes[index].communityId ?? '', },
spaceId: state.scenes[index].spaceId, status: state.scenes[index].status,
sceneId: state.scenes[index].sceneTuyaId!, communityId:
automationId: state.scenes[index].id, state.scenes[index].communityId ??
cardType: 'scenes', '',
spaceName: state.scenes[index].spaceName, spaceId: state.scenes[index].spaceId,
onTap: () { sceneId:
BlocProvider.of<RoutineBloc>(context).add( state.scenes[index].sceneTuyaId!,
const CreateNewRoutineViewEvent( automationId: state.scenes[index].id,
createRoutineView: true), cardType: 'scenes',
); spaceName:
context.read<RoutineBloc>().add( state.scenes[index].spaceName,
GetSceneDetails( onTap: () {
sceneId: state.scenes[index].id, BlocProvider.of<RoutineBloc>(context)
isTabToRun: true, .add(
isUpdate: true, const CreateNewRoutineViewEvent(
), createRoutineView: true),
); );
}, context.read<RoutineBloc>().add(
textString: state.scenes[index].name, GetSceneDetails(
icon: state.scenes[index].icon ?? sceneId:
Assets.logoHorizontal, state.scenes[index].id,
isFromScenes: true, isTabToRun: true,
iconInBytes: state.scenes[index].iconInBytes, isUpdate: true,
), ),
); );
}), },
textString: state.scenes[index].name,
icon: state.scenes[index].icon ??
Assets.logoHorizontal,
isFromScenes: true,
iconInBytes:
state.scenes[index].iconInBytes,
),
],
),
);
}),
),
const SizedBox(height: 10),
Text(
"Automations",
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.bold,
),
), ),
const SizedBox(height: 10), const SizedBox(height: 3),
Text( if (state.automations.isEmpty)
"Automations", Text(
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 5),
if (state.automations.isEmpty)
Expanded(
child: Text(
"No automations found", "No automations found",
style: context.textTheme.bodyMedium?.copyWith( style: context.textTheme.bodyMedium?.copyWith(
color: ColorsManager.grayColor, color: ColorsManager.grayColor,
), ),
), ),
), if (state.automations.isNotEmpty)
if (state.automations.isNotEmpty) SizedBox(
ConstrainedBox( height: 200,
constraints: BoxConstraints(
maxHeight: isSmallScreenSize(context) ? 185 : 192,
maxWidth: MediaQuery.sizeOf(context).width * 0.7),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: state.automations.length,
itemBuilder: (context, index) {
final isLoading = state.automations!
.contains(state.automations[index].id);
return Padding( child: ListView.builder(
padding: EdgeInsets.only( shrinkWrap: true,
right: isSmallScreenSize(context) ? 4.0 : 8.0, scrollDirection: Axis.horizontal,
), itemCount: state.automations.length,
child: RoutineViewCard( itemBuilder: (context, index) {
isLoading: isLoading, final isLoading = state.automations!
onChanged: (v) { .contains(state.automations[index].id);
// BlocProvider.of<RoutineBloc>(context)
context.read<RoutineBloc>().add( return Column(
UpdateAutomationStatus( children: [
automationId: Padding(
state.automations[index].id, padding: EdgeInsets.only(
automationStatusUpdate: right: isSmallScreenSize(context)
AutomationStatusUpdate( ? 4.0
spaceUuid: state : 8.0,
.automations[index] ),
.spaceId, child: RoutineViewCard(
isEnable: v), isLoading: isLoading,
communityId: state onChanged: (v) {
.automations[index].communityId, context.read<RoutineBloc>().add(
), UpdateAutomationStatus(
); automationId: state
}, .automations[index].id,
status: state.automations[index].status, automationStatusUpdate:
communityId: '', AutomationStatusUpdate(
spaceId: state.automations[index].spaceId, spaceUuid: state
sceneId: '', .automations[
automationId: state.automations[index].id, index]
cardType: 'automations', .spaceId,
spaceName: state.scenes[index].spaceName, isEnable: v),
onTap: () { communityId: state
BlocProvider.of<RoutineBloc>(context).add( .automations[index]
const CreateNewRoutineViewEvent( .communityId,
createRoutineView: true), ),
); );
context.read<RoutineBloc>().add( },
GetAutomationDetails( status: state.automations[index].status,
automationId: communityId: '',
state.automations[index].id, spaceId:
isAutomation: true, state.automations[index].spaceId,
isUpdate: true), sceneId: '',
); automationId:
}, state.automations[index].id,
textString: state.automations[index].name, cardType: 'automations',
icon: state.automations[index].icon ?? spaceName:
Assets.automation, state.scenes[index].spaceName,
), onTap: () {
); BlocProvider.of<RoutineBloc>(context)
}), .add(
), const CreateNewRoutineViewEvent(
], createRoutineView: true),
);
context.read<RoutineBloc>().add(
GetAutomationDetails(
automationId: state
.automations[index].id,
isAutomation: true,
isUpdate: true),
);
},
textString:
state.automations[index].name,
icon: state.automations[index].icon ??
Assets.automation,
),
),
],
);
}),
),
],
),
), ),
); );
}, },

View File

@ -106,10 +106,10 @@ class _RoutineViewCardState extends State<RoutineViewCard> {
if (widget.isFromScenes ?? false) if (widget.isFromScenes ?? false)
InkWell( InkWell(
onTap: _handleSceneTap, onTap: _handleSceneTap,
child: SvgPicture.asset( child: Image.asset(
_showTemporaryCheck _showTemporaryCheck
? Assets.scenesPlayIconCheck ? Assets.scenesPlayIcon
: Assets.scenesPlayIcon, : Assets.scenesPlayIconCheck,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
) )
@ -177,6 +177,8 @@ class _RoutineViewCardState extends State<RoutineViewCard> {
: (widget.icon is String && : (widget.icon is String &&
widget.icon.endsWith('.svg')) widget.icon.endsWith('.svg'))
? SvgPicture.asset( ? SvgPicture.asset(
height: iconSize,
width: iconSize,
widget.icon, widget.icon,
fit: BoxFit.contain, fit: BoxFit.contain,
) )

View File

@ -13,29 +13,38 @@ 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({
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 { required String dialogType,
List<ACFunction> acFunctions = functions.whereType<ACFunction>().toList(); }) async {
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()..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 ?? '',
@ -65,8 +74,10 @@ class ACHelper {
child: _buildFunctionsList( child: _buildFunctionsList(
context: context, context: context,
acFunctions: acFunctions, acFunctions: acFunctions,
onFunctionSelected: (functionCode, operationName) => onFunctionSelected:
context.read<FunctionBloc>().add(SelectFunction( (functionCode, operationName) => context
.read<FunctionBloc>()
.add(SelectFunction(
functionCode: functionCode, functionCode: functionCode,
operationName: operationName, operationName: operationName,
)), )),
@ -194,7 +205,8 @@ class ACHelper {
); );
} }
final selectedFn = acFunctions.firstWhere((f) => f.code == selectedFunction); final selectedFn =
acFunctions.firstWhere((f) => f.code == selectedFunction);
final values = selectedFn.getOperationalValues(); final values = selectedFn.getOperationalValues();
return _buildOperationalValuesList( return _buildOperationalValuesList(
@ -290,7 +302,8 @@ class ACHelper {
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(),
); );
} }
@ -384,9 +397,13 @@ class ACHelper {
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) {
@ -398,7 +415,8 @@ class ACHelper {
operationName: operationName, operationName: operationName,
value: value.value, value: value.value,
condition: selectedFunctionData?.condition, condition: selectedFunctionData?.condition,
valueDescription: selectedFunctionData?.valueDescription, valueDescription:
selectedFunctionData?.valueDescription,
), ),
), ),
); );

View File

@ -5,8 +5,10 @@ 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';
@ -14,29 +16,32 @@ 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({
BuildContext context, required String dialogType,
List<DeviceFunction> functions, required BuildContext context,
AllDevicesModel? device, required List<DeviceFunction> functions,
List<DeviceFunctionData>? deviceSelectedFunctions, required AllDevicesModel? device,
String uniqueCustomId, required List<DeviceFunctionData>? deviceSelectedFunctions,
bool removeComparetors, required String uniqueCustomId,
) async { required bool removeComparetors,
List<BaseSwitchFunction> acFunctions = functions.whereType<BaseSwitchFunction>().toList(); }) async {
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 ?? '',
@ -61,12 +66,12 @@ class OneGangSwitchHelper {
// Left side: Function list // Left side: Function list
Expanded( Expanded(
child: ListView.separated( child: ListView.separated(
itemCount: acFunctions.length, itemCount: oneGangFunctions.length,
separatorBuilder: (_, __) => const Divider( separatorBuilder: (_, __) => const Divider(
color: ColorsManager.dividerColor, color: ColorsManager.dividerColor,
), ),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final function = acFunctions[index]; final function = oneGangFunctions[index];
return ListTile( return ListTile(
leading: SvgPicture.asset( leading: SvgPicture.asset(
function.icon, function.icon,
@ -83,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,
)); ));
}, },
); );
@ -99,7 +107,7 @@ class OneGangSwitchHelper {
context: context, context: context,
selectedFunction: selectedFunction, selectedFunction: selectedFunction,
selectedFunctionData: selectedFunctionData, selectedFunctionData: selectedFunctionData,
acFunctions: acFunctions, acFunctions: oneGangFunctions,
device: device, device: device,
operationName: selectedOperationName ?? '', operationName: selectedOperationName ?? '',
removeComparetors: removeComparetors, removeComparetors: removeComparetors,
@ -174,8 +182,14 @@ 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(
@ -212,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),
], ],
); );
} }
@ -257,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(),
); );
} }
@ -305,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) {
@ -357,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) {
@ -371,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,
), ),
), ),
); );

View File

@ -14,14 +14,15 @@ 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({
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 String dialogType,
) async { required bool removeComparetors,
}) async {
List<BaseSwitchFunction> switchFunctions = List<BaseSwitchFunction> switchFunctions =
functions.whereType<BaseSwitchFunction>().toList(); functions.whereType<BaseSwitchFunction>().toList();

View File

@ -14,29 +14,32 @@ 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({
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 { required String dialogType,
List<BaseSwitchFunction> switchFunctions = functions.whereType<BaseSwitchFunction>().toList(); }) async {
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()..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 ?? '',
@ -83,9 +86,12 @@ class TwoGangSwitchHelper {
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,
)); ));
}, },
); );
@ -161,7 +167,8 @@ class TwoGangSwitchHelper {
required String operationName, required String operationName,
required bool removeComparetors, required bool removeComparetors,
}) { }) {
if (selectedFunction == 'countdown_1' || selectedFunction == 'countdown_2') { if (selectedFunction == 'countdown_1' ||
selectedFunction == 'countdown_2') {
final initialValue = selectedFunctionData?.value ?? 200; final initialValue = selectedFunctionData?.value ?? 200;
return _buildTemperatureSelector( return _buildTemperatureSelector(
context: context, context: context,
@ -175,7 +182,8 @@ class TwoGangSwitchHelper {
); );
} }
final selectedFn = switchFunctions.firstWhere((f) => f.code == selectedFunction); final selectedFn =
switchFunctions.firstWhere((f) => f.code == selectedFunction);
final values = selectedFn.getOperationalValues(); final values = selectedFn.getOperationalValues();
return _buildOperationalValuesList( return _buildOperationalValuesList(
@ -212,11 +220,11 @@ class TwoGangSwitchHelper {
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),
], ],
); );
} }
@ -257,7 +265,8 @@ class TwoGangSwitchHelper {
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(),
); );
} }
@ -305,7 +314,8 @@ 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) - (operationalValues.minValue ?? 0)) / divisions: (((operationalValues.maxValue ?? 0) -
(operationalValues.minValue ?? 0)) /
(operationalValues.stepValue ?? 1)) (operationalValues.stepValue ?? 1))
.round(), .round(),
onChanged: (value) { onChanged: (value) {
@ -357,9 +367,13 @@ class TwoGangSwitchHelper {
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) {
@ -371,7 +385,8 @@ class TwoGangSwitchHelper {
operationName: operationName, operationName: operationName,
value: value.value, value: value.value,
condition: selectedFunctionData?.condition, condition: selectedFunctionData?.condition,
valueDescription: selectedFunctionData?.valueDescription, valueDescription:
selectedFunctionData?.valueDescription,
), ),
), ),
); );

View File

@ -13,7 +13,6 @@ import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:flutter_bloc/flutter_bloc.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/bloc/functions_bloc/functions_bloc_bloc.dart';
class WallPresenceSensor extends StatefulWidget { class WallPresenceSensor extends StatefulWidget {
final List<DeviceFunction> functions; final List<DeviceFunction> functions;
final AllDevicesModel? device; final AllDevicesModel? device;
@ -171,7 +170,7 @@ class _WallPresenceSensorState extends State<WallPresenceSensor> {
orElse: () => DeviceFunctionData( orElse: () => DeviceFunctionData(
entityId: '', entityId: '',
functionCode: selectedFunction, functionCode: selectedFunction,
operationName: '', operationName: state.selectedOperationName ?? '',
value: null, value: null,
), ),
); );
@ -251,11 +250,8 @@ class _ValueSelector extends StatelessWidget {
); );
} }
bool _isSliderFunction(String function) => [ bool _isSliderFunction(String function) =>
'dis_current', ['dis_current', 'presence_time', 'illuminance_value'].contains(function);
'presence_time',
'illuminance_value'
].contains(function);
} }
class _SliderValueSelector extends StatelessWidget { class _SliderValueSelector extends StatelessWidget {

View File

@ -408,9 +408,9 @@ class Assets {
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.svg'; static const String scenesPlayIcon = 'assets/icons/scenesPlayIcon.png';
static const String scenesPlayIconCheck = static const String scenesPlayIconCheck =
'assets/icons/scenesPlayIconCheck.svg'; '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 = static const String currentDistanceIcon =
'assets/icons/current_distance_icon.svg'; 'assets/icons/current_distance_icon.svg';
@ -427,5 +427,4 @@ class Assets {
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';
//Illuminance_icon
} }