mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-09 22:57:21 +00:00
routines and automation Toggle
This commit is contained in:
30
assets/icons/scenesPlayIconCheck.svg
Normal file
30
assets/icons/scenesPlayIconCheck.svg
Normal file
@ -0,0 +1,30 @@
|
||||
<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>
|
After Width: | Height: | Size: 2.0 KiB |
@ -33,7 +33,6 @@ Future<void> main() async {
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
|
||||
MyApp({super.key});
|
||||
|
||||
final GoRouter _router = GoRouter(
|
||||
@ -55,6 +54,7 @@ class MyApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
|
||||
BlocProvider(
|
||||
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||
BlocProvider<VisitorPasswordBloc>(
|
||||
|
@ -55,6 +55,7 @@ class MyApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
|
||||
BlocProvider(
|
||||
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||
BlocProvider<VisitorPasswordBloc>(
|
||||
|
@ -1,124 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/auth/model/project_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_scene_trigger_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_scene_trigger_status.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/routine_model.dart';
|
||||
import 'package:syncrow_web/services/routines_api.dart';
|
||||
|
||||
class AutomationSceneTriggerBloc extends Bloc<AutomationSceneTriggerEvent, AutomationSceneTriggerStatus> {
|
||||
AutomationSceneTriggerBloc() : super(AutomationSceneInitial()) {
|
||||
// on<LoadScenes>(_onLoadScenes);
|
||||
// on<LoadAutomation>(_onLoadAutomation);
|
||||
on<SceneTrigger>(_onSceneTrigger);
|
||||
on<UpdateAutomationStatus>(_onUpdateAutomationStatus);
|
||||
}
|
||||
|
||||
List<ScenesModel> scenes = [];
|
||||
List<ScenesModel> automationList = [];
|
||||
|
||||
// Future<void> _onLoadScenes(LoadScenes event, Emitter<AutomationSceneTriggerStatus> emit) async {
|
||||
// emit(SceneLoading());
|
||||
|
||||
// try {
|
||||
// Project? project = HomeCubit.getInstance().project;
|
||||
|
||||
// if (event.unitId.isNotEmpty) {
|
||||
// scenes = await SceneApi.getScenesByUnitId(event.unitId,
|
||||
// event.unit.community.uuid, project?.uuid ?? TempConst.projectIdDev,
|
||||
// showInDevice: event.showInDevice);
|
||||
// emit(SceneLoaded(scenes, automationList));
|
||||
// } else {
|
||||
// emit(const SceneError(message: 'Unit ID is empty'));
|
||||
// }
|
||||
// } catch (e) {
|
||||
// emit(const SceneError(message: 'Something went wrong'));
|
||||
// }
|
||||
// }
|
||||
|
||||
// Future<void> _onLoadAutomation(
|
||||
// LoadAutomation event, Emitter<AutomationSceneTriggerStatus> emit) async {
|
||||
// emit(SceneLoading());
|
||||
|
||||
// try {
|
||||
// Project? project = HomeCubit.getInstance().project;
|
||||
|
||||
// if (event.unitId.isNotEmpty) {
|
||||
// automationList = await SceneApi.getAutomationByUnitId(
|
||||
// event.unitId, event.communityId, project?.uuid ?? '');
|
||||
// emit(SceneLoaded(scenes, automationList));
|
||||
// } else {
|
||||
// emit(const SceneError(message: 'Unit ID is empty'));
|
||||
// }
|
||||
// } catch (e) {
|
||||
// emit(const SceneError(message: 'Something went wrong'));
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<void> _onSceneTrigger(
|
||||
SceneTrigger event, Emitter<AutomationSceneTriggerStatus> emit) async {
|
||||
final currentState = state;
|
||||
if (currentState is AutomationSceneLoaded) {
|
||||
emit(AutomationSceneLoaded(
|
||||
currentState.scenes,
|
||||
currentState.automationList,
|
||||
loadingSceneId: event.sceneId,
|
||||
));
|
||||
|
||||
try {
|
||||
final success = await SceneApi.triggerScene(event.sceneId);
|
||||
if (success) {
|
||||
emit(SceneTriggerSuccess(event.name));
|
||||
emit(AutomationSceneLoaded(currentState.scenes, currentState.automationList));
|
||||
} else {
|
||||
emit(const AutomationSceneError(message: 'Something went wrong'));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(const AutomationSceneError(message: 'Something went wrong'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onUpdateAutomationStatus(
|
||||
UpdateAutomationStatus event, Emitter<AutomationSceneTriggerStatus> emit) async {
|
||||
final currentState = state;
|
||||
if (currentState is AutomationSceneLoaded) {
|
||||
final newLoadingStates =
|
||||
Map<String, bool>.from(currentState.loadingStates)
|
||||
..[event.automationId] = true;
|
||||
|
||||
emit(AutomationSceneLoaded(
|
||||
currentState.scenes,
|
||||
currentState.automationList,
|
||||
loadingStates: newLoadingStates,
|
||||
));
|
||||
|
||||
try {
|
||||
Project? project = HomeCubit.getInstance().project;
|
||||
|
||||
final success = await SceneApi.updateAutomationStatus(
|
||||
event.automationId,
|
||||
event.automationStatusUpdate,
|
||||
project?.uuid ?? '');
|
||||
if (success) {
|
||||
automationList = await SceneApi.getAutomationByUnitId(
|
||||
event.automationStatusUpdate.spaceUuid,
|
||||
event.communityId,
|
||||
project?.uuid ?? '');
|
||||
newLoadingStates[event.automationId] = false;
|
||||
emit(AutomationSceneLoaded(
|
||||
currentState.scenes,
|
||||
automationList,
|
||||
loadingStates: newLoadingStates,
|
||||
));
|
||||
} else {
|
||||
emit(const AutomationSceneError(message: 'Something went wrong'));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(const AutomationSceneError(message: 'Something went wrong'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||
|
||||
abstract class AutomationSceneTriggerEvent extends Equatable {
|
||||
const AutomationSceneTriggerEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class AutomationSceneScenes extends AutomationSceneTriggerEvent {
|
||||
final String unitId;
|
||||
final bool showInDevice;
|
||||
final SpaceModel unit;
|
||||
|
||||
const AutomationSceneScenes(this.unitId, this.unit, {this.showInDevice = false});
|
||||
|
||||
@override
|
||||
List<Object> get props => [unitId, showInDevice];
|
||||
}
|
||||
|
||||
class AutomationSceneAutomation extends AutomationSceneTriggerEvent {
|
||||
final String unitId;
|
||||
final String communityId;
|
||||
|
||||
|
||||
const AutomationSceneAutomation(this.unitId, this.communityId);
|
||||
|
||||
@override
|
||||
List<Object> get props => [unitId, communityId];
|
||||
}
|
||||
|
||||
class SceneTrigger extends AutomationSceneTriggerEvent {
|
||||
final String sceneId;
|
||||
final String name;
|
||||
|
||||
const SceneTrigger(this.sceneId, this.name);
|
||||
|
||||
@override
|
||||
List<Object> get props => [sceneId];
|
||||
}
|
||||
|
||||
//updateAutomationStatus
|
||||
class UpdateAutomationStatus extends AutomationSceneTriggerEvent {
|
||||
final String automationId;
|
||||
final AutomationStatusUpdate automationStatusUpdate;
|
||||
final String communityId;
|
||||
|
||||
const UpdateAutomationStatus({required this.automationStatusUpdate, required this.automationId, required this.communityId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [automationStatusUpdate];
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/routine_model.dart';
|
||||
|
||||
abstract class AutomationSceneTriggerStatus extends Equatable {
|
||||
const AutomationSceneTriggerStatus();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class AutomationSceneInitial extends AutomationSceneTriggerStatus {}
|
||||
|
||||
class AutomationSceneLoading extends AutomationSceneTriggerStatus {}
|
||||
|
||||
class AutomationSceneLoaded extends AutomationSceneTriggerStatus {
|
||||
final List<ScenesModel> scenes;
|
||||
final List<ScenesModel> automationList;
|
||||
final String? loadingSceneId;
|
||||
final Map<String, bool> loadingStates;
|
||||
|
||||
const AutomationSceneLoaded(this.scenes, this.automationList,
|
||||
{this.loadingSceneId, this.loadingStates = const {}});
|
||||
|
||||
@override
|
||||
List<Object?> get props =>
|
||||
[scenes, loadingSceneId, automationList, loadingStates];
|
||||
}
|
||||
|
||||
class AutomationSceneError extends AutomationSceneTriggerStatus {
|
||||
final String message;
|
||||
|
||||
const AutomationSceneError({required this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
class SceneTriggerSuccess extends AutomationSceneTriggerStatus {
|
||||
final String sceneName;
|
||||
|
||||
const SceneTriggerSuccess(this.sceneName);
|
||||
|
||||
@override
|
||||
List<Object> get props => [sceneName];
|
||||
}
|
||||
|
||||
class UpdateAutomationStatusLoading extends AutomationSceneTriggerStatus {
|
||||
const UpdateAutomationStatusLoading();
|
||||
}
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/delay/delay_fucntions.dart';
|
||||
@ -51,6 +52,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
on<TriggerSwitchTabsEvent>(_triggerSwitchTabsEvent);
|
||||
on<CreateNewRoutineViewEvent>(_createNewRoutineViewEvent);
|
||||
on<ResetErrorMessage>(_resetErrorMessage);
|
||||
on<SceneTrigger>(_onSceneTrigger);
|
||||
on<UpdateAutomationStatus>(_onUpdateAutomationStatus);
|
||||
}
|
||||
|
||||
FutureOr<void> _triggerSwitchTabsEvent(
|
||||
@ -1269,4 +1272,79 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onSceneTrigger(
|
||||
SceneTrigger event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(loadingSceneId: event.sceneId));
|
||||
|
||||
try {
|
||||
final success = await SceneApi.triggerScene(event.sceneId!);
|
||||
|
||||
if (success) {
|
||||
emit(state.copyWith(
|
||||
loadingSceneId: null,
|
||||
// Add success state if needed
|
||||
));
|
||||
// Optional: Add delay to show success feedback
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
loadingSceneId: null,
|
||||
errorMessage: 'Trigger failed',
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
loadingSceneId: null,
|
||||
errorMessage: 'Trigger error: ${e.toString()}',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Future<void> _onUpdateAutomationStatus(
|
||||
UpdateAutomationStatus event, Emitter<RoutineState> emit) async {
|
||||
// Create a new set safely
|
||||
final currentLoadingIds = state.loadingAutomationIds;
|
||||
final newLoadingIds = {...currentLoadingIds!}..add(event.automationId);
|
||||
|
||||
emit(state.copyWith(loadingAutomationIds: newLoadingIds));
|
||||
|
||||
try {
|
||||
final projectId = await ProjectManager.getProjectUUID() ?? '';
|
||||
final success = await SceneApi.updateAutomationStatus(
|
||||
event.automationId, event.automationStatusUpdate, projectId);
|
||||
|
||||
if (success) {
|
||||
final updatedAutomations = await SceneApi.getAutomationByUnitId(
|
||||
event.automationStatusUpdate.spaceUuid,
|
||||
event.communityId,
|
||||
projectId);
|
||||
|
||||
// Remove from loading set safely
|
||||
final updatedLoadingIds = {...state.loadingAutomationIds!}
|
||||
..remove(event.automationId);
|
||||
|
||||
emit(state.copyWith(
|
||||
automations: updatedAutomations,
|
||||
loadingAutomationIds: updatedLoadingIds,
|
||||
));
|
||||
} else {
|
||||
final updatedLoadingIds = {...state.loadingAutomationIds!}
|
||||
..remove(event.automationId);
|
||||
emit(state.copyWith(
|
||||
loadingAutomationIds: updatedLoadingIds,
|
||||
errorMessage: 'Update failed',
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
final updatedLoadingIds = {...state.loadingAutomationIds!}
|
||||
..remove(event.automationId);
|
||||
emit(state.copyWith(
|
||||
loadingAutomationIds: updatedLoadingIds,
|
||||
errorMessage: 'Update error: ${e.toString()}',
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,3 +210,28 @@ class ResetRoutineState extends RoutineEvent {}
|
||||
class ClearFunctions extends RoutineEvent {}
|
||||
|
||||
class ResetErrorMessage extends RoutineEvent {}
|
||||
|
||||
|
||||
|
||||
|
||||
class SceneTrigger extends RoutineEvent {
|
||||
final String? sceneId;
|
||||
final String? name;
|
||||
|
||||
const SceneTrigger({this.sceneId, this.name});
|
||||
|
||||
@override
|
||||
List<Object> get props => [sceneId!,name!];
|
||||
}
|
||||
|
||||
//updateAutomationStatus
|
||||
class UpdateAutomationStatus extends RoutineEvent {
|
||||
final String automationId;
|
||||
final AutomationStatusUpdate automationStatusUpdate;
|
||||
final String communityId;
|
||||
|
||||
const UpdateAutomationStatus({required this.automationStatusUpdate, required this.automationId, required this.communityId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [automationStatusUpdate];
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
part of 'routine_bloc.dart';
|
||||
|
||||
class RoutineState extends Equatable {
|
||||
final String? loadingSceneId;
|
||||
final List<Map<String, dynamic>> ifItems;
|
||||
final List<Map<String, dynamic>> thenItems;
|
||||
final List<Map<String, String>> availableCards;
|
||||
@ -25,6 +26,7 @@ class RoutineState extends Equatable {
|
||||
// final String? automationActionExecutor;
|
||||
final bool routineTab;
|
||||
final bool createRoutineView;
|
||||
final Set<String>? loadingAutomationIds; // Track loading automations
|
||||
|
||||
const RoutineState(
|
||||
{this.ifItems = const [],
|
||||
@ -47,12 +49,16 @@ class RoutineState extends Equatable {
|
||||
this.sceneId,
|
||||
this.automationId,
|
||||
this.isUpdate,
|
||||
this.loadingAutomationIds = const <String>{}, // Initialize with empty set
|
||||
this.loadingSceneId,
|
||||
this.devices = const [],
|
||||
// this.automationActionExecutor,
|
||||
this.routineTab = false,
|
||||
this.createRoutineView = false});
|
||||
|
||||
RoutineState copyWith({
|
||||
String? loadingSceneId,
|
||||
Set<String>? loadingAutomationIds,
|
||||
List<Map<String, dynamic>>? ifItems,
|
||||
List<Map<String, dynamic>>? thenItems,
|
||||
List<ScenesModel>? scenes,
|
||||
@ -79,6 +85,8 @@ class RoutineState extends Equatable {
|
||||
bool? createRoutineView,
|
||||
}) {
|
||||
return RoutineState(
|
||||
loadingSceneId: loadingSceneId,
|
||||
loadingAutomationIds: loadingAutomationIds ?? this.loadingAutomationIds,
|
||||
ifItems: ifItems ?? this.ifItems,
|
||||
thenItems: thenItems ?? this.thenItems,
|
||||
scenes: scenes ?? this.scenes,
|
||||
@ -109,6 +117,7 @@ class RoutineState extends Equatable {
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
loadingAutomationIds,
|
||||
ifItems,
|
||||
thenItems,
|
||||
scenes,
|
||||
@ -134,3 +143,38 @@ class RoutineState extends Equatable {
|
||||
createRoutineView
|
||||
];
|
||||
}
|
||||
|
||||
class SceneInitial extends RoutineState {}
|
||||
|
||||
class SceneLoading extends RoutineState {}
|
||||
|
||||
class SceneLoaded extends RoutineState {
|
||||
final List<ScenesModel>? scenesOrAutomation;
|
||||
const SceneLoaded({this.scenesOrAutomation});
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
scenesOrAutomation,
|
||||
];
|
||||
}
|
||||
|
||||
class SceneError extends RoutineState {
|
||||
final String message;
|
||||
|
||||
const SceneError({required this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
class SceneTriggerSuccess extends RoutineState {
|
||||
final String sceneName;
|
||||
|
||||
const SceneTriggerSuccess(this.sceneName);
|
||||
|
||||
@override
|
||||
List<Object> get props => [sceneName];
|
||||
}
|
||||
|
||||
class UpdateAutomationStatusLoading extends RoutineState {
|
||||
const UpdateAutomationStatusLoading();
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ class ScenesModel {
|
||||
final String status;
|
||||
final String type;
|
||||
final String? icon;
|
||||
final String spaceName;
|
||||
final String spaceId;
|
||||
final String communityId;
|
||||
|
||||
ScenesModel({
|
||||
required this.id,
|
||||
@ -16,6 +19,9 @@ class ScenesModel {
|
||||
required this.name,
|
||||
required this.status,
|
||||
required this.type,
|
||||
required this.spaceName,
|
||||
required this.spaceId,
|
||||
required this.communityId,
|
||||
this.icon,
|
||||
});
|
||||
|
||||
@ -41,6 +47,9 @@ class ScenesModel {
|
||||
name: json["name"] ?? '',
|
||||
status: json["status"] ?? '',
|
||||
type: json["type"] ?? '',
|
||||
spaceName: json["spaceName"] ?? '',
|
||||
spaceId: json["spaceId"] ?? '',
|
||||
communityId: json["communityId"] ?? '',
|
||||
icon:
|
||||
isAutomation == true ? Assets.automation : (json["icon"] as String?),
|
||||
);
|
||||
@ -52,5 +61,8 @@ class ScenesModel {
|
||||
"name": name,
|
||||
"status": status,
|
||||
"type": type,
|
||||
"spaceName": spaceName,
|
||||
"spaceId": spaceId,
|
||||
"communityId": communityId,
|
||||
};
|
||||
}
|
||||
|
@ -60,7 +60,13 @@ class _RoutinesViewState extends State<RoutinesView> {
|
||||
height: 10,
|
||||
),
|
||||
RoutineViewCard(
|
||||
isFromScenes: false,
|
||||
isLoading: false,
|
||||
onChanged: (v) {},
|
||||
status: '',
|
||||
spaceId: '',
|
||||
automationId: '',
|
||||
communityId: '',
|
||||
sceneId: '',
|
||||
cardType: '',
|
||||
spaceName: '',
|
||||
onTap: () {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/main_routine_view/routine_view_card.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
@ -46,48 +46,68 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
if (state.scenes.isEmpty)
|
||||
Text(
|
||||
"No scenes found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
Expanded(
|
||||
child: Text(
|
||||
"No scenes found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (state.scenes.isNotEmpty)
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||
maxWidth: MediaQuery.sizeOf(context).width * 0.7),
|
||||
maxHeight: isSmallScreenSize(context) ? 190 : 200,
|
||||
maxWidth: MediaQuery.sizeOf(context).width * 0.8),
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.scenes.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
cardType: 'scenes',
|
||||
spaceName: 'scenes',
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(
|
||||
createRoutineView: true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetSceneDetails(
|
||||
sceneId: state.scenes[index].id,
|
||||
isTabToRun: true,
|
||||
isUpdate: true,
|
||||
),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.scenes.length,
|
||||
itemBuilder: (context, index) {
|
||||
final scene = state.scenes[index];
|
||||
final isLoading =
|
||||
state.loadingSceneId == scene.id;
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
isLoading: isLoading,
|
||||
sceneOnTap: () {
|
||||
context.read<RoutineBloc>().add(
|
||||
SceneTrigger(
|
||||
sceneId: scene.id,
|
||||
name: scene.name));
|
||||
},
|
||||
status: state.scenes[index].status,
|
||||
communityId:
|
||||
state.scenes[index].communityId ?? '',
|
||||
spaceId: state.scenes[index].spaceId,
|
||||
sceneId: state.scenes[index].sceneTuyaId!,
|
||||
automationId: state.scenes[index].id,
|
||||
cardType: 'scenes',
|
||||
spaceName: state.scenes[index].spaceName,
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(
|
||||
createRoutineView: true),
|
||||
);
|
||||
},
|
||||
textString: state.scenes[index].name,
|
||||
icon: state.scenes[index].icon ??
|
||||
Assets.logoHorizontal,
|
||||
isFromScenes: true,
|
||||
iconInBytes: state.scenes[index].iconInBytes,
|
||||
),
|
||||
),
|
||||
),
|
||||
context.read<RoutineBloc>().add(
|
||||
GetSceneDetails(
|
||||
sceneId: state.scenes[index].id,
|
||||
isTabToRun: true,
|
||||
isUpdate: true,
|
||||
),
|
||||
);
|
||||
},
|
||||
textString: state.scenes[index].name,
|
||||
icon: state.scenes[index].icon ??
|
||||
Assets.logoHorizontal,
|
||||
isFromScenes: true,
|
||||
iconInBytes: state.scenes[index].iconInBytes,
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Text(
|
||||
@ -99,46 +119,74 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
if (state.automations.isEmpty)
|
||||
Text(
|
||||
"No automations found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
Expanded(
|
||||
child: Text(
|
||||
"No automations found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (state.automations.isNotEmpty)
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||
maxHeight: isSmallScreenSize(context) ? 190 : 200,
|
||||
maxWidth: MediaQuery.sizeOf(context).width * 0.7),
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.automations.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
cardType: 'automations',
|
||||
spaceName: 'automations',
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(
|
||||
createRoutineView: true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetAutomationDetails(
|
||||
automationId:
|
||||
state.automations[index].id,
|
||||
isAutomation: true,
|
||||
isUpdate: true),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.automations.length,
|
||||
itemBuilder: (context, index) {
|
||||
final isLoading = state.automations!
|
||||
.contains(state.automations[index].id);
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
isLoading: isLoading,
|
||||
onChanged: (v) {
|
||||
// BlocProvider.of<RoutineBloc>(context)
|
||||
context.read<RoutineBloc>().add(
|
||||
UpdateAutomationStatus(
|
||||
automationId:
|
||||
state.automations[index].id,
|
||||
automationStatusUpdate:
|
||||
AutomationStatusUpdate(
|
||||
spaceUuid: state
|
||||
.automations[index]
|
||||
.spaceId,
|
||||
isEnable: v),
|
||||
communityId:
|
||||
'aff21a57-2f91-4e5c-b99b-0182c3ab65a9'),
|
||||
);
|
||||
},
|
||||
status: state.automations[index].status,
|
||||
communityId: '',
|
||||
spaceId: state.automations[index].spaceId,
|
||||
sceneId: '',
|
||||
automationId: state.automations[index].id,
|
||||
cardType: 'automations',
|
||||
spaceName: state.scenes[index].spaceName,
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(
|
||||
createRoutineView: true),
|
||||
);
|
||||
},
|
||||
textString: state.automations[index].name,
|
||||
icon: state.automations[index].icon ??
|
||||
Assets.automation,
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -7,42 +8,78 @@ import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
class RoutineViewCard extends StatefulWidget with HelperResponsiveLayout {
|
||||
const RoutineViewCard({
|
||||
super.key,
|
||||
required this.onTap,
|
||||
this.sceneOnTap,
|
||||
required this.icon,
|
||||
required this.textString,
|
||||
required this.spaceName,
|
||||
required this.cardType,
|
||||
this.isFromScenes,
|
||||
this.iconInBytes,
|
||||
required this.sceneId,
|
||||
required this.communityId,
|
||||
required this.spaceId,
|
||||
required this.automationId,
|
||||
required this.status,
|
||||
this.onChanged,
|
||||
required this.isLoading,
|
||||
});
|
||||
|
||||
final Function() onTap;
|
||||
final Function()? sceneOnTap;
|
||||
|
||||
final dynamic icon;
|
||||
final String textString;
|
||||
final String spaceName;
|
||||
final String cardType;
|
||||
final String sceneId;
|
||||
final String spaceId;
|
||||
final String status;
|
||||
final bool isLoading;
|
||||
|
||||
final void Function(bool)? onChanged;
|
||||
final String automationId;
|
||||
final String communityId;
|
||||
|
||||
final bool? isFromScenes;
|
||||
final Uint8List? iconInBytes;
|
||||
|
||||
@override
|
||||
State<RoutineViewCard> createState() => _RoutineViewCardState();
|
||||
}
|
||||
|
||||
class _RoutineViewCardState extends State<RoutineViewCard> {
|
||||
bool _showTemporaryCheck = false;
|
||||
|
||||
void _handleSceneTap() {
|
||||
if (!_showTemporaryCheck) {
|
||||
setState(() => _showTemporaryCheck = true);
|
||||
widget.sceneOnTap?.call();
|
||||
Timer(const Duration(seconds: 3), () {
|
||||
if (mounted) setState(() => _showTemporaryCheck = false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double cardWidth = isSmallScreenSize(context)
|
||||
// Use widget.<mixinMethod> instead of just <mixinMethod>
|
||||
final double cardWidth = widget.isSmallScreenSize(context)
|
||||
? 120
|
||||
: isMediumScreenSize(context)
|
||||
: widget.isMediumScreenSize(context)
|
||||
? 135
|
||||
: 150;
|
||||
|
||||
final double cardHeight = isSmallScreenSize(context) ? 160 : 170;
|
||||
final double cardHeight = widget.isSmallScreenSize(context) ? 190 : 200;
|
||||
|
||||
final double iconSize = isSmallScreenSize(context)
|
||||
? 50
|
||||
: isMediumScreenSize(context)
|
||||
? 60
|
||||
: 70;
|
||||
final double iconSize = widget.isSmallScreenSize(context)
|
||||
? 70
|
||||
: widget.isMediumScreenSize(context)
|
||||
? 80
|
||||
: 90;
|
||||
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
@ -62,27 +99,44 @@ class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
(isFromScenes ?? false)
|
||||
? InkWell(
|
||||
onTap: () {},
|
||||
child: SvgPicture.asset(
|
||||
Assets.scenesPlayIcon,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)
|
||||
: CupertinoSwitch(
|
||||
activeColor: ColorsManager.primaryColor,
|
||||
value: false,
|
||||
onChanged: (value) {},
|
||||
)
|
||||
],
|
||||
),
|
||||
widget.cardType != ''
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (widget.isFromScenes ?? false)
|
||||
InkWell(
|
||||
onTap: _handleSceneTap,
|
||||
child: SvgPicture.asset(
|
||||
_showTemporaryCheck
|
||||
? Assets.scenesPlayIconCheck
|
||||
: Assets.scenesPlayIcon,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)
|
||||
else if (widget.isLoading)
|
||||
const SizedBox(
|
||||
width: 49,
|
||||
height: 20,
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child:
|
||||
CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
CupertinoSwitch(
|
||||
activeColor: ColorsManager.primaryColor,
|
||||
value: widget.status == 'enable',
|
||||
onChanged: widget.onChanged,
|
||||
)
|
||||
],
|
||||
)
|
||||
: const SizedBox(),
|
||||
InkWell(
|
||||
onTap: onTap,
|
||||
onTap: widget.onTap,
|
||||
child: Column(
|
||||
children: [
|
||||
Center(
|
||||
@ -97,11 +151,11 @@ class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
),
|
||||
height: iconSize,
|
||||
width: iconSize,
|
||||
child: (isFromScenes ?? false)
|
||||
? (iconInBytes != null &&
|
||||
iconInBytes?.isNotEmpty == true)
|
||||
child: (widget.isFromScenes ?? false)
|
||||
? (widget.iconInBytes != null &&
|
||||
widget.iconInBytes?.isNotEmpty == true)
|
||||
? Image.memory(
|
||||
iconInBytes!,
|
||||
widget.iconInBytes!,
|
||||
height: iconSize,
|
||||
width: iconSize,
|
||||
fit: BoxFit.contain,
|
||||
@ -120,16 +174,18 @@ class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
width: iconSize,
|
||||
fit: BoxFit.contain,
|
||||
)
|
||||
: (icon is String && icon.endsWith('.svg'))
|
||||
: (widget.icon is String &&
|
||||
widget.icon.endsWith('.svg'))
|
||||
? SvgPicture.asset(
|
||||
icon,
|
||||
widget.icon,
|
||||
fit: BoxFit.contain,
|
||||
)
|
||||
: Icon(
|
||||
icon,
|
||||
widget.icon,
|
||||
color: ColorsManager.dialogBlueTitle,
|
||||
size:
|
||||
isSmallScreenSize(context) ? 30 : 40,
|
||||
size: widget.isSmallScreenSize(context)
|
||||
? 30
|
||||
: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -139,16 +195,17 @@ class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
textString,
|
||||
widget.textString,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: context.textTheme.bodySmall?.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: isSmallScreenSize(context) ? 10 : 12,
|
||||
fontSize:
|
||||
widget.isSmallScreenSize(context) ? 10 : 12,
|
||||
),
|
||||
),
|
||||
if (spaceName != '')
|
||||
if (widget.spaceName != '')
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -158,7 +215,7 @@ class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
Text(
|
||||
spaceName,
|
||||
widget.spaceName,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
@ -166,7 +223,9 @@ class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
context.textTheme.bodySmall?.copyWith(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize:
|
||||
isSmallScreenSize(context) ? 10 : 12,
|
||||
widget.isSmallScreenSize(context)
|
||||
? 10
|
||||
: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -12,7 +12,8 @@ class SceneApi {
|
||||
static final HTTPService _httpService = HTTPService();
|
||||
|
||||
// //create scene
|
||||
static Future<Map<String, dynamic>> createScene(CreateSceneModel createSceneModel) async {
|
||||
static Future<Map<String, dynamic>> createScene(
|
||||
CreateSceneModel createSceneModel) async {
|
||||
try {
|
||||
debugPrint('create scene model: ${createSceneModel.toMap()}');
|
||||
final response = await _httpService.post(
|
||||
@ -37,7 +38,8 @@ class SceneApi {
|
||||
CreateAutomationModel createAutomationModel, String projectId) async {
|
||||
try {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.createAutomation.replaceAll('{projectId}', projectId),
|
||||
path:
|
||||
ApiEndpoints.createAutomation.replaceAll('{projectId}', projectId),
|
||||
body: createAutomationModel.toMap(),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
@ -69,7 +71,8 @@ class SceneApi {
|
||||
|
||||
//get scenes by community id and space id
|
||||
|
||||
static Future<List<ScenesModel>> getScenes(String spaceId, String communityId, String projectId,
|
||||
static Future<List<ScenesModel>> getScenes(
|
||||
String spaceId, String communityId, String projectId,
|
||||
{showInDevice = false}) async {
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
@ -155,7 +158,8 @@ class SceneApi {
|
||||
try {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
|
||||
body: createSceneModel.toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
||||
body: createSceneModel
|
||||
.toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
@ -167,14 +171,15 @@ class SceneApi {
|
||||
}
|
||||
|
||||
//update automation
|
||||
static updateAutomation(
|
||||
CreateAutomationModel createAutomationModel, String automationId, String projectId) async {
|
||||
static updateAutomation(CreateAutomationModel createAutomationModel,
|
||||
String automationId, String projectId) async {
|
||||
try {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.updateAutomation
|
||||
.replaceAll('{automationId}', automationId)
|
||||
.replaceAll('{projectId}', projectId),
|
||||
body: createAutomationModel.toJson(automationId.isNotEmpty == true ? automationId : null),
|
||||
body: createAutomationModel
|
||||
.toJson(automationId.isNotEmpty == true ? automationId : null),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
@ -191,7 +196,8 @@ class SceneApi {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json['data']),
|
||||
expectedResponseModel: (json) =>
|
||||
RoutineDetailsModel.fromMap(json['data']),
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
@ -200,7 +206,8 @@ class SceneApi {
|
||||
}
|
||||
|
||||
//delete Scene
|
||||
static Future<bool> deleteScene({required String unitUuid, required String sceneId}) async {
|
||||
static Future<bool> deleteScene(
|
||||
{required String unitUuid, required String sceneId}) async {
|
||||
try {
|
||||
final response = await _httpService.delete(
|
||||
path: ApiEndpoints.deleteScene
|
||||
@ -217,7 +224,9 @@ class SceneApi {
|
||||
|
||||
// delete automation
|
||||
static Future<bool> deleteAutomation(
|
||||
{required String unitUuid, required String automationId, required String projectId}) async {
|
||||
{required String unitUuid,
|
||||
required String automationId,
|
||||
required String projectId}) async {
|
||||
try {
|
||||
final response = await _httpService.delete(
|
||||
path: ApiEndpoints.deleteAutomation
|
||||
@ -232,7 +241,7 @@ class SceneApi {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> updateAutomationStatus(String automationId,
|
||||
static Future<bool> updateAutomationStatus(String automationId,
|
||||
AutomationStatusUpdate createAutomationEnable, String projectId) async {
|
||||
try {
|
||||
final response = await _httpService.patch(
|
||||
@ -260,7 +269,8 @@ class SceneApi {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
static Future<List<ScenesModel>> getAutomationByUnitId(
|
||||
|
||||
static Future<List<ScenesModel>> getAutomationByUnitId(
|
||||
String unitId,
|
||||
String communityId,
|
||||
String projectId,
|
||||
@ -285,5 +295,4 @@ class SceneApi {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -407,6 +407,8 @@ class Assets {
|
||||
'assets/icons/delete_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 spaceLocationIcon = 'assets/icons/spaceLocationIcon.svg';
|
||||
static const String spaceLocationIcon = 'assets/icons/spaseLocationIcon.svg';
|
||||
static const String scenesPlayIcon = 'assets/icons/scenesPlayIcon.svg';
|
||||
static const String scenesPlayIconCheck =
|
||||
'assets/icons/scenesPlayIconCheck.svg';
|
||||
}
|
||||
|
Reference in New Issue
Block a user