mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-26 15:17:57 +00:00
Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd5fe10a21 | ||
|
|
4055265b0a | ||
|
|
aff7ceeac4 | ||
|
|
246098b83a | ||
|
|
26f50d59dd | ||
|
|
610cdf83a0 | ||
|
|
768996ca45 | ||
|
|
5da42e975a | ||
|
|
bc02664a09 | ||
|
|
057ea8515a | ||
|
|
9cc9fd7f24 | ||
|
|
f5958c1599 | ||
|
|
1d0ef20015 | ||
|
|
2b7a70e0a1 | ||
|
|
321a9b5fa2 | ||
|
|
9058f29787 | ||
|
|
fd497d5797 | ||
|
|
5f4aa93e01 | ||
|
|
96bf262466 | ||
|
|
2969e936d0 | ||
|
|
e6d0e95ddc | ||
|
|
c7b1ed5b8e | ||
|
|
d0e7d12279 |
@@ -0,0 +1,60 @@
|
|||||||
|
name: Azure Static Web Apps CI/CD
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened, closed]
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_deploy_job:
|
||||||
|
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Build and Deploy Job
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout Code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
lfs: false
|
||||||
|
|
||||||
|
- name: Set up Flutter
|
||||||
|
uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
flutter-version: '3.22.2' # Specify the Flutter version you want to use
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
- name: Build Flutter Web App
|
||||||
|
run: flutter build web --release --dart-define=FLAVOR=production
|
||||||
|
|
||||||
|
- name: Build And Deploy
|
||||||
|
id: builddeploy
|
||||||
|
uses: Azure/static-web-apps-deploy@v1
|
||||||
|
with:
|
||||||
|
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_BUSH_01E607F10 }}
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
|
||||||
|
action: "upload"
|
||||||
|
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
|
||||||
|
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
|
||||||
|
app_location: "/build/web" # App source code path
|
||||||
|
api_location: "" # Api source code path - optional
|
||||||
|
output_location: "/build/web" # Built app content directory - optional
|
||||||
|
###### End of Repository/Build Configurations ######
|
||||||
|
|
||||||
|
close_pull_request_job:
|
||||||
|
if: github.event_name == 'pull_request' && github.event.action == 'closed'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Close Pull Request Job
|
||||||
|
steps:
|
||||||
|
- name: Close Pull Request
|
||||||
|
id: closepullrequest
|
||||||
|
uses: Azure/static-web-apps-deploy@v1
|
||||||
|
with:
|
||||||
|
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_MANGO_BUSH_01E607F10 }}
|
||||||
|
action: "close"
|
||||||
@@ -758,6 +758,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
thenItems: [],
|
thenItems: [],
|
||||||
selectedFunctions: {},
|
selectedFunctions: {},
|
||||||
scenes: [],
|
scenes: [],
|
||||||
|
sceneId: '',
|
||||||
|
automationId: '',
|
||||||
automations: [],
|
automations: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
errorMessage: '',
|
errorMessage: '',
|
||||||
@@ -1050,7 +1052,9 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
final automationDetails = await SceneApi.getAutomationDetails(event.automationId);
|
final automationDetails = await SceneApi.getAutomationDetails(event.automationId);
|
||||||
|
|
||||||
final Map<String, Map<String, dynamic>> deviceCards = {};
|
final Map<String, Map<String, dynamic>> deviceIfCards = {};
|
||||||
|
final Map<String, Map<String, dynamic>> deviceThenCards = {};
|
||||||
|
|
||||||
final Map<String, List<DeviceFunctionData>> updatedFunctions =
|
final Map<String, List<DeviceFunctionData>> updatedFunctions =
|
||||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
|
||||||
@@ -1066,8 +1070,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
final deviceId = condition.entityId;
|
final deviceId = condition.entityId;
|
||||||
|
|
||||||
if (!deviceCards.containsKey(deviceId)) {
|
if (!deviceIfCards.containsKey(deviceId)) {
|
||||||
deviceCards[deviceId] = {
|
deviceIfCards[deviceId] = {
|
||||||
'entityId': condition.entityId,
|
'entityId': condition.entityId,
|
||||||
'deviceId': condition.entityId,
|
'deviceId': condition.entityId,
|
||||||
'uniqueCustomId': const Uuid().v4(),
|
'uniqueCustomId': const Uuid().v4(),
|
||||||
@@ -1080,7 +1084,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
final cardData = deviceCards[deviceId]!;
|
final cardData = deviceIfCards[deviceId]!;
|
||||||
final uniqueCustomId = cardData['uniqueCustomId'].toString();
|
final uniqueCustomId = cardData['uniqueCustomId'].toString();
|
||||||
|
|
||||||
if (!updatedFunctions.containsKey(uniqueCustomId)) {
|
if (!updatedFunctions.containsKey(uniqueCustomId)) {
|
||||||
@@ -1117,8 +1121,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
final deviceId =
|
final deviceId =
|
||||||
action.actionExecutor == 'delay' ? '${action.entityId}_delay' : action.entityId;
|
action.actionExecutor == 'delay' ? '${action.entityId}_delay' : action.entityId;
|
||||||
|
|
||||||
if (!deviceCards.containsKey(deviceId)) {
|
if (!deviceThenCards.containsKey(deviceId)) {
|
||||||
deviceCards[deviceId] = {
|
deviceThenCards[deviceId] = {
|
||||||
'entityId': action.entityId,
|
'entityId': action.entityId,
|
||||||
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
|
||||||
'uniqueCustomId': const Uuid().v4(),
|
'uniqueCustomId': const Uuid().v4(),
|
||||||
@@ -1140,10 +1144,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
: action.type == 'automation'
|
: action.type == 'automation'
|
||||||
? 'automation'
|
? 'automation'
|
||||||
: 'action',
|
: 'action',
|
||||||
|
'icon': action.icon ?? ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
final cardData = deviceCards[deviceId]!;
|
final cardData = deviceThenCards[deviceId]!;
|
||||||
final uniqueCustomId = cardData['uniqueCustomId'].toString();
|
final uniqueCustomId = cardData['uniqueCustomId'].toString();
|
||||||
|
|
||||||
if (!updatedFunctions.containsKey(uniqueCustomId)) {
|
if (!updatedFunctions.containsKey(uniqueCustomId)) {
|
||||||
@@ -1192,8 +1197,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ifItems = deviceCards.values.where((card) => card['type'] == 'condition').toList();
|
final ifItems = deviceIfCards.values.where((card) => card['type'] == 'condition').toList();
|
||||||
final thenItems = deviceCards.values
|
final thenItems = deviceThenCards.values
|
||||||
.where((card) =>
|
.where((card) =>
|
||||||
card['type'] == 'action' || card['type'] == 'automation' || card['type'] == 'scene')
|
card['type'] == 'action' || card['type'] == 'automation' || card['type'] == 'scene')
|
||||||
.toList();
|
.toList();
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ class SaveRoutineHelper {
|
|||||||
final functions =
|
final functions =
|
||||||
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: item['type'] == 'tap_to_run'
|
leading: item['type'] == 'tap_to_run' || item['type'] == 'scene'
|
||||||
? Image.memory(
|
? Image.memory(
|
||||||
base64Decode(item['icon']),
|
base64Decode(item['icon']),
|
||||||
width: 22,
|
width: 22,
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ class RoutineDetailsModel {
|
|||||||
spaceUuid: spaceUuid,
|
spaceUuid: spaceUuid,
|
||||||
automationName: name,
|
automationName: name,
|
||||||
decisionExpr: decisionExpr,
|
decisionExpr: decisionExpr,
|
||||||
effectiveTime:
|
effectiveTime: effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
|
||||||
effectiveTime ?? EffectiveTime(start: '', end: '', loops: ''),
|
|
||||||
conditions: conditions?.map((c) => c.toCondition()).toList() ?? [],
|
conditions: conditions?.map((c) => c.toCondition()).toList() ?? [],
|
||||||
actions: actions.map((a) => a.toAutomationAction()).toList(),
|
actions: actions.map((a) => a.toAutomationAction()).toList(),
|
||||||
);
|
);
|
||||||
@@ -64,8 +63,7 @@ class RoutineDetailsModel {
|
|||||||
if (iconId != null) 'iconUuid': iconId,
|
if (iconId != null) 'iconUuid': iconId,
|
||||||
if (showInDevice != null) 'showInDevice': showInDevice,
|
if (showInDevice != null) 'showInDevice': showInDevice,
|
||||||
if (effectiveTime != null) 'effectiveTime': effectiveTime!.toMap(),
|
if (effectiveTime != null) 'effectiveTime': effectiveTime!.toMap(),
|
||||||
if (conditions != null)
|
if (conditions != null) 'conditions': conditions!.map((x) => x.toMap()).toList(),
|
||||||
'conditions': conditions!.map((x) => x.toMap()).toList(),
|
|
||||||
if (type != null) 'type': type,
|
if (type != null) 'type': type,
|
||||||
if (sceneId != null) 'sceneId': sceneId,
|
if (sceneId != null) 'sceneId': sceneId,
|
||||||
if (automationId != null) 'automationId': automationId,
|
if (automationId != null) 'automationId': automationId,
|
||||||
@@ -82,12 +80,10 @@ class RoutineDetailsModel {
|
|||||||
),
|
),
|
||||||
iconId: map['iconUuid'],
|
iconId: map['iconUuid'],
|
||||||
showInDevice: map['showInDevice'],
|
showInDevice: map['showInDevice'],
|
||||||
effectiveTime: map['effectiveTime'] != null
|
effectiveTime:
|
||||||
? EffectiveTime.fromMap(map['effectiveTime'])
|
map['effectiveTime'] != null ? EffectiveTime.fromMap(map['effectiveTime']) : null,
|
||||||
: null,
|
|
||||||
conditions: map['conditions'] != null
|
conditions: map['conditions'] != null
|
||||||
? List<RoutineCondition>.from(
|
? List<RoutineCondition>.from(map['conditions'].map((x) => RoutineCondition.fromMap(x)))
|
||||||
map['conditions'].map((x) => RoutineCondition.fromMap(x)))
|
|
||||||
: null,
|
: null,
|
||||||
type: map['type'],
|
type: map['type'],
|
||||||
sceneId: map['sceneId'],
|
sceneId: map['sceneId'],
|
||||||
@@ -108,15 +104,16 @@ class RoutineAction {
|
|||||||
final RoutineExecutorProperty? executorProperty;
|
final RoutineExecutorProperty? executorProperty;
|
||||||
final String productType;
|
final String productType;
|
||||||
final String? type;
|
final String? type;
|
||||||
|
final String? icon;
|
||||||
|
|
||||||
RoutineAction({
|
RoutineAction(
|
||||||
required this.entityId,
|
{required this.entityId,
|
||||||
required this.actionExecutor,
|
required this.actionExecutor,
|
||||||
required this.productType,
|
required this.productType,
|
||||||
this.executorProperty,
|
this.executorProperty,
|
||||||
this.name,
|
this.name,
|
||||||
this.type,
|
this.type,
|
||||||
});
|
this.icon});
|
||||||
|
|
||||||
CreateSceneAction toCreateSceneAction() {
|
CreateSceneAction toCreateSceneAction() {
|
||||||
return CreateSceneAction(
|
return CreateSceneAction(
|
||||||
@@ -140,22 +137,21 @@ class RoutineAction {
|
|||||||
'actionExecutor': actionExecutor,
|
'actionExecutor': actionExecutor,
|
||||||
if (type != null) 'type': type,
|
if (type != null) 'type': type,
|
||||||
if (name != null) 'name': name,
|
if (name != null) 'name': name,
|
||||||
if (executorProperty != null)
|
if (executorProperty != null) 'executorProperty': executorProperty!.toMap(),
|
||||||
'executorProperty': executorProperty!.toMap(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
factory RoutineAction.fromMap(Map<String, dynamic> map) {
|
factory RoutineAction.fromMap(Map<String, dynamic> map) {
|
||||||
return RoutineAction(
|
return RoutineAction(
|
||||||
entityId: map['entityId'] ?? '',
|
entityId: map['entityId'] ?? '',
|
||||||
actionExecutor: map['actionExecutor'] ?? '',
|
actionExecutor: map['actionExecutor'] ?? '',
|
||||||
productType: map['productType'] ?? '',
|
productType: map['productType'] ?? '',
|
||||||
name: map['name'] ?? '',
|
name: map['name'] ?? '',
|
||||||
type: map['type'] ?? '',
|
type: map['type'] ?? '',
|
||||||
executorProperty: map['executorProperty'] != null
|
executorProperty: map['executorProperty'] != null
|
||||||
? RoutineExecutorProperty.fromMap(map['executorProperty'])
|
? RoutineExecutorProperty.fromMap(map['executorProperty'])
|
||||||
: null,
|
: null,
|
||||||
);
|
icon: map['icon']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,18 +32,17 @@ class DraggableCard extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final deviceFunctions =
|
final deviceFunctions = state.selectedFunctions[deviceData['uniqueCustomId']] ?? [];
|
||||||
state.selectedFunctions[deviceData['uniqueCustomId']] ?? [];
|
|
||||||
|
|
||||||
int index = state.thenItems.indexWhere(
|
int index = state.thenItems
|
||||||
(item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']);
|
.indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']);
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
return _buildCardContent(context, deviceFunctions, padding: padding);
|
return _buildCardContent(context, deviceFunctions, padding: padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ifIndex = state.ifItems.indexWhere(
|
int ifIndex = state.ifItems
|
||||||
(item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']);
|
.indexWhere((item) => item['uniqueCustomId'] == deviceData['uniqueCustomId']);
|
||||||
|
|
||||||
if (ifIndex != -1) {
|
if (ifIndex != -1) {
|
||||||
return _buildCardContent(context, deviceFunctions, padding: padding);
|
return _buildCardContent(context, deviceFunctions, padding: padding);
|
||||||
@@ -53,8 +52,7 @@ class DraggableCard extends StatelessWidget {
|
|||||||
data: deviceData,
|
data: deviceData,
|
||||||
feedback: Transform.rotate(
|
feedback: Transform.rotate(
|
||||||
angle: -0.1,
|
angle: -0.1,
|
||||||
child:
|
child: _buildCardContent(context, deviceFunctions, padding: padding),
|
||||||
_buildCardContent(context, deviceFunctions, padding: padding),
|
|
||||||
),
|
),
|
||||||
childWhenDragging: _buildGreyContainer(),
|
childWhenDragging: _buildGreyContainer(),
|
||||||
child: _buildCardContent(context, deviceFunctions, padding: padding),
|
child: _buildCardContent(context, deviceFunctions, padding: padding),
|
||||||
@@ -63,8 +61,7 @@ class DraggableCard extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCardContent(
|
Widget _buildCardContent(BuildContext context, List<DeviceFunctionData> deviceFunctions,
|
||||||
BuildContext context, List<DeviceFunctionData> deviceFunctions,
|
|
||||||
{EdgeInsetsGeometry? padding}) {
|
{EdgeInsetsGeometry? padding}) {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
@@ -93,7 +90,7 @@ class DraggableCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: deviceData['type'] == 'tap_to_run'
|
child: deviceData['type'] == 'tap_to_run' || deviceData['type'] == 'scene'
|
||||||
? Image.memory(
|
? Image.memory(
|
||||||
base64Decode(deviceData['icon']),
|
base64Decode(deviceData['icon']),
|
||||||
)
|
)
|
||||||
@@ -162,8 +159,7 @@ class DraggableCard extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _formatFunctionValue(DeviceFunctionData function) {
|
String _formatFunctionValue(DeviceFunctionData function) {
|
||||||
if (function.functionCode == 'temp_set' ||
|
if (function.functionCode == 'temp_set' || function.functionCode == 'temp_current') {
|
||||||
function.functionCode == 'temp_current') {
|
|
||||||
return '${(function.value / 10).toStringAsFixed(0)}°C';
|
return '${(function.value / 10).toStringAsFixed(0)}°C';
|
||||||
} else if (function.functionCode.contains('countdown')) {
|
} else if (function.functionCode.contains('countdown')) {
|
||||||
final seconds = function.value.toInt();
|
final seconds = function.value.toInt();
|
||||||
|
|||||||
@@ -26,9 +26,7 @@ class ThenContainer extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text('THEN',
|
const Text('THEN', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18, fontWeight: FontWeight.bold)),
|
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
state.isLoading && state.isUpdate == true
|
state.isLoading && state.isUpdate == true
|
||||||
? const Center(
|
? const Center(
|
||||||
@@ -41,17 +39,12 @@ class ThenContainer extends StatelessWidget {
|
|||||||
state.thenItems.length,
|
state.thenItems.length,
|
||||||
(index) => GestureDetector(
|
(index) => GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (state.thenItems[index]
|
if (state.thenItems[index]['deviceId'] == 'delay') {
|
||||||
['deviceId'] ==
|
final result = await DelayHelper.showDelayPickerDialog(
|
||||||
'delay') {
|
context, state.thenItems[index]);
|
||||||
final result = await DelayHelper
|
|
||||||
.showDelayPickerDialog(context,
|
|
||||||
state.thenItems[index]);
|
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context
|
context.read<RoutineBloc>().add(AddToThenContainer({
|
||||||
.read<RoutineBloc>()
|
|
||||||
.add(AddToThenContainer({
|
|
||||||
...state.thenItems[index],
|
...state.thenItems[index],
|
||||||
'imagePath': Assets.delay,
|
'imagePath': Assets.delay,
|
||||||
'title': 'Delay',
|
'title': 'Delay',
|
||||||
@@ -60,79 +53,58 @@ class ThenContainer extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.thenItems[index]['type'] ==
|
if (state.thenItems[index]['type'] == 'automation') {
|
||||||
'automation') {
|
|
||||||
final result = await showDialog<bool>(
|
final result = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) =>
|
builder: (BuildContext context) => AutomationDialog(
|
||||||
AutomationDialog(
|
|
||||||
automationName:
|
automationName:
|
||||||
state.thenItems[index]
|
state.thenItems[index]['name'] ?? 'Automation',
|
||||||
['name'] ??
|
|
||||||
'Automation',
|
|
||||||
automationId:
|
automationId:
|
||||||
state.thenItems[index]
|
state.thenItems[index]['deviceId'] ?? '',
|
||||||
['deviceId'] ??
|
uniqueCustomId: state.thenItems[index]
|
||||||
'',
|
['uniqueCustomId'],
|
||||||
uniqueCustomId:
|
|
||||||
state.thenItems[index]
|
|
||||||
['uniqueCustomId'],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context
|
context.read<RoutineBloc>().add(AddToThenContainer({
|
||||||
.read<RoutineBloc>()
|
|
||||||
.add(AddToThenContainer({
|
|
||||||
...state.thenItems[index],
|
...state.thenItems[index],
|
||||||
'imagePath':
|
'imagePath': Assets.automation,
|
||||||
Assets.automation,
|
'title': state.thenItems[index]['name'] ??
|
||||||
'title':
|
state.thenItems[index]['title'],
|
||||||
state.thenItems[index]
|
|
||||||
['name'] ??
|
|
||||||
state.thenItems[index]
|
|
||||||
['title'],
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await DeviceDialogHelper
|
final result = await DeviceDialogHelper.showDeviceDialog(
|
||||||
.showDeviceDialog(
|
context, state.thenItems[index],
|
||||||
context, state.thenItems[index],
|
removeComparetors: true);
|
||||||
removeComparetors: true);
|
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(
|
context
|
||||||
AddToThenContainer(
|
.read<RoutineBloc>()
|
||||||
state.thenItems[index]));
|
.add(AddToThenContainer(state.thenItems[index]));
|
||||||
} else if (!['AC', '1G', '2G', '3G']
|
} else if (!['AC', '1G', '2G', '3G']
|
||||||
.contains(state.thenItems[index]
|
.contains(state.thenItems[index]['productType'])) {
|
||||||
['productType'])) {
|
context
|
||||||
context.read<RoutineBloc>().add(
|
.read<RoutineBloc>()
|
||||||
AddToThenContainer(
|
.add(AddToThenContainer(state.thenItems[index]));
|
||||||
state.thenItems[index]));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: DraggableCard(
|
child: DraggableCard(
|
||||||
imagePath: state.thenItems[index]
|
imagePath: state.thenItems[index]['imagePath'] ?? '',
|
||||||
['imagePath'] ??
|
title: state.thenItems[index]['title'] ?? '',
|
||||||
'',
|
|
||||||
title: state.thenItems[index]
|
|
||||||
['title'] ??
|
|
||||||
'',
|
|
||||||
deviceData: state.thenItems[index],
|
deviceData: state.thenItems[index],
|
||||||
padding: const EdgeInsets.symmetric(
|
padding:
|
||||||
horizontal: 4, vertical: 8),
|
const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
|
||||||
isFromThen: true,
|
isFromThen: true,
|
||||||
isFromIf: false,
|
isFromIf: false,
|
||||||
onRemove: () {
|
onRemove: () {
|
||||||
context.read<RoutineBloc>().add(
|
context.read<RoutineBloc>().add(RemoveDragCard(
|
||||||
RemoveDragCard(
|
index: index,
|
||||||
index: index,
|
isFromThen: true,
|
||||||
isFromThen: true,
|
key: state.thenItems[index]['uniqueCustomId']));
|
||||||
key: state.thenItems[index]
|
|
||||||
['uniqueCustomId']));
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
))),
|
))),
|
||||||
@@ -151,9 +123,14 @@ class ThenContainer extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.automationId == mutableData['deviceId'] ||
|
||||||
|
state.sceneId == mutableData['deviceId']) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mutableData['type'] == 'automation') {
|
if (mutableData['type'] == 'automation') {
|
||||||
int index = state.thenItems.indexWhere(
|
int index =
|
||||||
(item) => item['deviceId'] == mutableData['deviceId']);
|
state.thenItems.indexWhere((item) => item['deviceId'] == mutableData['deviceId']);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -178,8 +155,8 @@ class ThenContainer extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mutableData['type'] == 'tap_to_run' && state.isAutomation) {
|
if (mutableData['type'] == 'tap_to_run' && state.isAutomation) {
|
||||||
int index = state.thenItems.indexWhere(
|
int index =
|
||||||
(item) => item['deviceId'] == mutableData['deviceId']);
|
state.thenItems.indexWhere((item) => item['deviceId'] == mutableData['deviceId']);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -197,8 +174,7 @@ class ThenContainer extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mutableData['deviceId'] == 'delay') {
|
if (mutableData['deviceId'] == 'delay') {
|
||||||
final result =
|
final result = await DelayHelper.showDelayPickerDialog(context, mutableData);
|
||||||
await DelayHelper.showDelayPickerDialog(context, mutableData);
|
|
||||||
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer({
|
context.read<RoutineBloc>().add(AddToThenContainer({
|
||||||
@@ -210,13 +186,11 @@ class ThenContainer extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await DeviceDialogHelper.showDeviceDialog(
|
final result = await DeviceDialogHelper.showDeviceDialog(context, mutableData,
|
||||||
context, mutableData,
|
|
||||||
removeComparetors: true);
|
removeComparetors: true);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
} else if (!['AC', '1G', '2G', '3G']
|
} else if (!['AC', '1G', '2G', '3G'].contains(mutableData['productType'])) {
|
||||||
.contains(mutableData['productType'])) {
|
|
||||||
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
context.read<RoutineBloc>().add(AddToThenContainer(mutableData));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -309,8 +309,6 @@ class SpaceManagementBloc
|
|||||||
await _api.deleteSpace(communityUuid, parent.uuid!);
|
await _api.deleteSpace(communityUuid, parent.uuid!);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(
|
|
||||||
'Error deleting space ${parent.name} (UUID: ${parent.uuid}, Community UUID: $communityUuid): $e');
|
|
||||||
rethrow; // Decide whether to stop execution or continue
|
rethrow; // Decide whether to stop execution or continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,7 +340,6 @@ class SpaceManagementBloc
|
|||||||
space.uuid = response?.uuid;
|
space.uuid = response?.uuid;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error creating space ${space.name}: $e');
|
|
||||||
rethrow; // Stop further execution on failure
|
rethrow; // Stop further execution on failure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,13 +133,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
isNameFieldInvalid = value.isEmpty;
|
isNameFieldInvalid = value.isEmpty;
|
||||||
|
|
||||||
if (!isNameFieldInvalid) {
|
if (!isNameFieldInvalid) {
|
||||||
if ((widget.parentSpace?.children.any(
|
if (_isNameConflict(value)) {
|
||||||
(child) => child.name == value) ??
|
|
||||||
false) ||
|
|
||||||
(widget.parentSpace?.name == value) ||
|
|
||||||
(widget.editSpace?.children.any(
|
|
||||||
(child) => child.name == value) ??
|
|
||||||
false)) {
|
|
||||||
isNameFieldExist = true;
|
isNameFieldExist = true;
|
||||||
isOkButtonEnabled = false;
|
isOkButtonEnabled = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -387,7 +381,14 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _isNameConflict(String value) {
|
||||||
|
return (widget.parentSpace?.children.any((child) => child.name == value) ??
|
||||||
|
false) ||
|
||||||
|
(widget.parentSpace?.name == value) ||
|
||||||
|
(widget.editSpace?.parent?.name == value) ||
|
||||||
|
(widget.editSpace?.children.any((child) => child.name == value) ??
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
String _mapIconToProduct(String uuid, List<ProductModel> products) {
|
String _mapIconToProduct(String uuid, List<ProductModel> products) {
|
||||||
// Find the product with the matching UUID
|
// Find the product with the matching UUID
|
||||||
|
|||||||
Reference in New Issue
Block a user