mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-03-11 02:51:44 +00:00
Compare commits
6 Commits
Implement_
...
user_agree
| Author | SHA1 | Date | |
|---|---|---|---|
| de024994c9 | |||
| bcc4ba98ff | |||
| df0f1c6c94 | |||
| 1f62cadcec | |||
| 90812f78e8 | |||
| b1368bf4d7 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,9 +5,11 @@
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.build/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
.swiftpm/
|
||||
migrate_working_dir/
|
||||
|
||||
# IntelliJ related
|
||||
|
||||
@ -329,4 +329,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 4243bd7f9184f79552dd731a7c9d5cad03bd2706
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
COCOAPODS: 1.16.2
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import UIKit
|
||||
import Flutter
|
||||
|
||||
@UIApplicationMain
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
@ -19,10 +22,21 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
backgroundColor: Colors.transparent,
|
||||
leadingWidth: 200,
|
||||
toolbarHeight: Constants.appBarHeight,
|
||||
leading: HomeCubit.getInstance().spaces!.isNotEmpty
|
||||
? HomeCubit.appBarLeading[HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]!
|
||||
: null,
|
||||
actions: HomeCubit.appBarActions[HomeCubit.bottomNavItems[HomeCubit.pageIndex].label],
|
||||
leading: InkWell(
|
||||
onTap: () {
|
||||
final spaces = HomeCubit.getInstance().spaces!;
|
||||
showSpaceBottomSheet(context, spaces);
|
||||
},
|
||||
child: HomeCubit.getInstance().spaces!.isNotEmpty
|
||||
? AbsorbPointer(
|
||||
absorbing: true,
|
||||
child: HomeCubit.appBarLeading[HomeCubit
|
||||
.bottomNavItems[HomeCubit.pageIndex].label]!,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
actions: HomeCubit.appBarActions[
|
||||
HomeCubit.bottomNavItems[HomeCubit.pageIndex].label],
|
||||
));
|
||||
},
|
||||
);
|
||||
@ -31,3 +45,83 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
Size get preferredSize => Size.fromHeight(Constants.appBarHeight);
|
||||
}
|
||||
|
||||
void showSpaceBottomSheet(BuildContext context, List<SpaceModel> spaces) {
|
||||
showModalBottomSheet(
|
||||
isScrollControlled: true,
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setModalState) {
|
||||
String? selectedSpaceId = HomeCubit.getInstance().selectedSpace?.id;
|
||||
final bool shouldLimitHeight = spaces.length > 5;
|
||||
return Container(
|
||||
constraints: shouldLimitHeight
|
||||
? BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.5,
|
||||
)
|
||||
: const BoxConstraints(),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
Container(
|
||||
decoration: const BoxDecoration(color: Colors.black12),
|
||||
height: 5,
|
||||
width: 50,
|
||||
),
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: spaces.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final space = spaces[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 30, right: 30),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(space.name),
|
||||
],
|
||||
),
|
||||
Radio<String>(
|
||||
value: space.id,
|
||||
groupValue: selectedSpaceId,
|
||||
onChanged: (String? newValue) {
|
||||
if (newValue != null) {
|
||||
setModalState(() {
|
||||
selectedSpaceId = newValue;
|
||||
});
|
||||
HomeCubit.getInstance().changeSelectedSpace(
|
||||
spaces.firstWhere((s) => s.id == newValue),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
child: const Divider(
|
||||
color: Colors.grey,
|
||||
thickness: 0.5,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,12 +3,15 @@ import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/privacy_policy.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/user_agreement.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/styles_manager.dart';
|
||||
@ -202,6 +205,93 @@ class SignUpView extends StatelessWidget {
|
||||
hint: "At least 8 characters"),
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text:
|
||||
'By signing up you agree to our ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
fontSize: 16,
|
||||
color: ColorsManager
|
||||
.onPrimaryColor,
|
||||
),
|
||||
children: [
|
||||
WidgetSpan(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context)
|
||||
.push(MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
const UserAgreement(),
|
||||
));
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'Terms & Conditions',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.copyWith(
|
||||
decoration:
|
||||
TextDecoration
|
||||
.underline,
|
||||
decorationColor:
|
||||
ColorsManager
|
||||
.onPrimaryColor,
|
||||
color: ColorsManager
|
||||
.onPrimaryColor,
|
||||
fontSize: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' and ',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
fontSize: 16,
|
||||
color: ColorsManager
|
||||
.onPrimaryColor,
|
||||
)),
|
||||
WidgetSpan(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context)
|
||||
.push(MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
const PrivacyPolicy(),
|
||||
));
|
||||
},
|
||||
child: BodyMedium(
|
||||
text: 'Privacy Policy',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(
|
||||
decoration:
|
||||
TextDecoration
|
||||
.underline,
|
||||
decorationColor:
|
||||
Colors.white,
|
||||
color: ColorsManager
|
||||
.onPrimaryColor,
|
||||
fontSize: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
||||
@ -18,6 +18,7 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
||||
on<ChangeIndicatorEvent>(_changeIndicator);
|
||||
on<ChangeValueEvent>(_changeValue);
|
||||
on<WallSensorUpdatedEvent>(_wallSensorUpdated);
|
||||
on<GetDeviceReportsEvent>(_getDeviceReports);
|
||||
}
|
||||
|
||||
void _fetchCeilingSensorStatus(InitialEvent event, Emitter<WallSensorState> emit) async {
|
||||
@ -91,4 +92,17 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
||||
} catch (_) {}
|
||||
emit(UpdateState(wallSensorModel: deviceStatus));
|
||||
}
|
||||
|
||||
void _getDeviceReports(GetDeviceReportsEvent event, Emitter<WallSensorState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
|
||||
try {
|
||||
await DevicesAPI.getDeviceReports(deviceId, event.code).then((value) {
|
||||
emit(DeviceReportsState(deviceReport: value, code: event.code));
|
||||
});
|
||||
} catch (e) {
|
||||
emit(FailedState(error: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,3 +29,15 @@ class ChangeValueEvent extends WallSensorEvent {
|
||||
@override
|
||||
List<Object> get props => [value, code];
|
||||
}
|
||||
|
||||
class GetDeviceReportsEvent extends WallSensorEvent {
|
||||
final String deviceUuid;
|
||||
final String code;
|
||||
const GetDeviceReportsEvent({
|
||||
required this.deviceUuid,
|
||||
required this.code,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceUuid, code];
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart';
|
||||
|
||||
class WallSensorState extends Equatable {
|
||||
@ -36,3 +37,9 @@ class FailedState extends WallSensorState {
|
||||
@override
|
||||
List<Object> get props => [error];
|
||||
}
|
||||
|
||||
class DeviceReportsState extends WallSensorState {
|
||||
final DeviceReport deviceReport;
|
||||
final String code;
|
||||
const DeviceReportsState({required this.deviceReport, required this.code});
|
||||
}
|
||||
|
||||
@ -9,17 +9,18 @@ class WallSensorModel {
|
||||
int currentDistance;
|
||||
int illuminance;
|
||||
bool indicator;
|
||||
int noOneTime;
|
||||
|
||||
WallSensorModel({
|
||||
required this.presenceState,
|
||||
required this.farDetection,
|
||||
required this.presenceTime,
|
||||
required this.motionSensitivity,
|
||||
required this.motionlessSensitivity,
|
||||
required this.currentDistance,
|
||||
required this.illuminance,
|
||||
required this.indicator,
|
||||
});
|
||||
WallSensorModel(
|
||||
{required this.presenceState,
|
||||
required this.farDetection,
|
||||
required this.presenceTime,
|
||||
required this.motionSensitivity,
|
||||
required this.motionlessSensitivity,
|
||||
required this.currentDistance,
|
||||
required this.illuminance,
|
||||
required this.indicator,
|
||||
required this.noOneTime});
|
||||
|
||||
factory WallSensorModel.fromJson(List<StatusModel> jsonList) {
|
||||
late String _presenceState;
|
||||
@ -30,6 +31,7 @@ class WallSensorModel {
|
||||
late int _currentDistance;
|
||||
late int _illuminance;
|
||||
late bool _indicator;
|
||||
late int _noOneTime;
|
||||
|
||||
for (int i = 0; i < jsonList.length; i++) {
|
||||
if (jsonList[i].code == 'presence_state') {
|
||||
@ -48,6 +50,8 @@ class WallSensorModel {
|
||||
_illuminance = jsonList[i].value ?? 0;
|
||||
} else if (jsonList[i].code == 'indicator') {
|
||||
_indicator = jsonList[i].value ?? false;
|
||||
} else if (jsonList[i].code == 'no_one_time') {
|
||||
_noOneTime = jsonList[i].value ?? 0;
|
||||
}
|
||||
}
|
||||
return WallSensorModel(
|
||||
@ -58,6 +62,7 @@ class WallSensorModel {
|
||||
motionlessSensitivity: _motionlessSensitivity,
|
||||
currentDistance: _currentDistance,
|
||||
illuminance: _illuminance,
|
||||
indicator: _indicator);
|
||||
indicator: _indicator,
|
||||
noOneTime: _noOneTime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scenes_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
|
||||
class SceneListview extends StatelessWidget {
|
||||
final List<ScenesModel> scenes;
|
||||
@ -31,23 +28,28 @@ class SceneListview extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
child: DefaultContainer(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
Routes.sceneTasksRoute,
|
||||
arguments: SceneSettingsRouteArguments(
|
||||
sceneType: CreateSceneEnum.tabToRun.name,
|
||||
sceneId: scene.id,
|
||||
sceneName: scene.name,
|
||||
),
|
||||
);
|
||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
||||
context
|
||||
.read<SceneBloc>()
|
||||
.add(SceneTrigger(scene.id, scene.name));
|
||||
// Navigator.pushNamed(
|
||||
// context,
|
||||
// Routes.sceneTasksRoute,
|
||||
// arguments: SceneSettingsRouteArguments(
|
||||
// sceneType: CreateSceneEnum.tabToRun.name,
|
||||
// sceneId: scene.id,
|
||||
// sceneName: scene.name,
|
||||
// ),
|
||||
// );
|
||||
// context.read<SmartSceneSelectBloc>()
|
||||
// .add(const SmartSceneClearEvent());
|
||||
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
.add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false));
|
||||
// BlocProvider.of<CreateSceneBloc>(context).add(
|
||||
// FetchSceneTasksEvent(
|
||||
// sceneId: scene.id, isAutomation: false));
|
||||
|
||||
/// the state to set the scene type must be after the fetch
|
||||
BlocProvider.of<CreateSceneBloc>(context)
|
||||
.add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
||||
// /// the state to set the scene type must be after the fetch
|
||||
// BlocProvider.of<CreateSceneBloc>(context)
|
||||
// .add(const SceneTypeEvent(CreateSceneEnum.tabToRun));
|
||||
},
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.4,
|
||||
@ -62,7 +64,8 @@ class SceneListview extends StatelessWidget {
|
||||
height: 32,
|
||||
width: 32,
|
||||
fit: BoxFit.fill,
|
||||
errorBuilder: (context, error, stackTrace) => Image.asset(
|
||||
errorBuilder: (context, error, stackTrace) =>
|
||||
Image.asset(
|
||||
Assets.assetsIconsLogo,
|
||||
height: 32,
|
||||
width: 32,
|
||||
|
||||
@ -215,8 +215,7 @@ class ParametersList extends StatelessWidget {
|
||||
{
|
||||
'icon': Assets.assetsIconsPresenceSensorAssetsEmpty,
|
||||
'title': 'Nobody Time',
|
||||
'code': null,
|
||||
//TODO: Implement the nobody time
|
||||
'code': 'no_one_time',
|
||||
},
|
||||
{
|
||||
'icon': Assets.assetsIconsPresenceSensorAssetsIndicator,
|
||||
@ -231,7 +230,7 @@ class ParametersList extends StatelessWidget {
|
||||
{
|
||||
'icon': Assets.assetsIconsPresenceSensorAssetsIlluminanceRecord,
|
||||
'title': 'Illuminance Record',
|
||||
'code': null
|
||||
'code': 'illuminance_value'
|
||||
},
|
||||
];
|
||||
}
|
||||
@ -240,6 +239,7 @@ Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, Dev
|
||||
WallSensorModel wallSensorStatus) {
|
||||
String? unit;
|
||||
dynamic value;
|
||||
int noBodyTimeValue;
|
||||
if (wallSensorButton['code'] != null) {
|
||||
// if (wallSensor.status.any((element) => element.code == wallSensorButton['code'] as String)) {
|
||||
// unit = unitsMap[wallSensorButton['code'] as String];
|
||||
@ -256,12 +256,15 @@ Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, Dev
|
||||
} else if (wallSensorButton['code'] == 'illuminance_value') {
|
||||
unit = unitsMap[wallSensorButton['code'] as String];
|
||||
value = wallSensorStatus.illuminance;
|
||||
} else if (wallSensorButton['code'] == 'no_one_time') {
|
||||
unit = unitsMap[wallSensorButton['code'] as String];
|
||||
value = wallSensorStatus.noOneTime;
|
||||
}
|
||||
}
|
||||
return DefaultContainer(
|
||||
margin: const EdgeInsets.only(bottom: 5),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
|
||||
onTap: () {
|
||||
onTap: () async {
|
||||
if (wallSensorButton['page'] != null) {
|
||||
Navigator.push(
|
||||
context,
|
||||
@ -270,6 +273,42 @@ Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, Dev
|
||||
),
|
||||
);
|
||||
}
|
||||
if (wallSensorButton['title'] == 'Presence Record') {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => PresenceRecords(
|
||||
deviceId: wallSensor.uuid!,
|
||||
code: 'presence_state',
|
||||
title: 'Presence Record',
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
if (wallSensorButton['title'] == 'Illuminance Record') {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => PresenceRecords(
|
||||
deviceId: wallSensor.uuid!,
|
||||
code: 'illuminance_value',
|
||||
title: 'Illuminance Record',
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
if (wallSensorButton['title'] == 'Nobody Time') {
|
||||
int noBodyTimeValue = value as int;
|
||||
String controlCode = 'no_one_time';
|
||||
final result = await showDialog(
|
||||
context: context,
|
||||
builder: (context) => ParameterControlDialog(
|
||||
title: 'Nobody Time', sensor: wallSensor, value: noBodyTimeValue, min: 0, max: 10000),
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
BlocProvider.of<WallSensorBloc>(context)
|
||||
.add(ChangeValueEvent(value: result, code: controlCode));
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
|
||||
@ -0,0 +1,120 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class PresenceRecords extends StatelessWidget {
|
||||
final String deviceId;
|
||||
final String code;
|
||||
final String title;
|
||||
const PresenceRecords(
|
||||
{super.key, required this.deviceId, required this.code, required this.title});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: title,
|
||||
child: BlocProvider(
|
||||
create: (context) => WallSensorBloc(deviceId: deviceId)
|
||||
..add(GetDeviceReportsEvent(deviceUuid: deviceId, code: code)),
|
||||
child: BlocBuilder<WallSensorBloc, WallSensorState>(builder: (context, state) {
|
||||
final Map<String, List<DeviceEvent>> groupedRecords = {};
|
||||
|
||||
if (state is LoadingInitialState) {
|
||||
return const Center(
|
||||
child: DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
|
||||
);
|
||||
} else if (state is DeviceReportsState) {
|
||||
for (var record in state.deviceReport.data ?? []) {
|
||||
final DateTime eventDateTime = DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
|
||||
final String formattedDate = DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
|
||||
|
||||
// Group by formatted date
|
||||
if (groupedRecords.containsKey(formattedDate)) {
|
||||
groupedRecords[formattedDate]!.add(record);
|
||||
} else {
|
||||
groupedRecords[formattedDate] = [record];
|
||||
}
|
||||
}
|
||||
}
|
||||
return groupedRecords.isEmpty
|
||||
? const Center(
|
||||
child: Text('No records found'),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: groupedRecords.length,
|
||||
itemBuilder: (context, index) {
|
||||
final String date = groupedRecords.keys.elementAt(index);
|
||||
final List<DeviceEvent> recordsForDate = groupedRecords[date]!;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 5, top: 10),
|
||||
child: Text(
|
||||
date,
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.grayColor,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
DefaultContainer(
|
||||
child: Column(
|
||||
children: [
|
||||
...recordsForDate.asMap().entries.map((entry) {
|
||||
final int idx = entry.key;
|
||||
final DeviceEvent record = entry.value;
|
||||
final DateTime eventDateTime =
|
||||
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
|
||||
final String formattedTime =
|
||||
DateFormat('HH:mm:ss').format(eventDateTime);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
record.value == 'true'
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
color: record.value == 'true' ? Colors.blue : Colors.grey,
|
||||
),
|
||||
title: Text(
|
||||
record.value == 'true' ? "Opened" : "Closed",
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
subtitle: Text('$formattedTime'),
|
||||
),
|
||||
),
|
||||
if (idx != recordsForDate.length - 1)
|
||||
const Divider(
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -9,6 +11,8 @@ import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_e
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_records_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/persence_records.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
@ -41,7 +45,8 @@ class WallMountedInterface extends StatelessWidget {
|
||||
motionlessSensitivity: 0,
|
||||
currentDistance: 0,
|
||||
illuminance: 0,
|
||||
indicator: false);
|
||||
indicator: false,
|
||||
noOneTime: 0);
|
||||
|
||||
if (state is UpdateState) {
|
||||
wallSensorModel = state.wallSensorModel;
|
||||
|
||||
@ -1,12 +1,35 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/services/api/profile_api.dart';
|
||||
|
||||
part 'menu_state.dart';
|
||||
|
||||
class MenuCubit extends Cubit<MenuState> {
|
||||
MenuCubit() : super(MenuInitial());
|
||||
|
||||
static MenuCubit of(context) => BlocProvider.of<MenuCubit>(context);
|
||||
|
||||
String name = '';
|
||||
String userAgreementHtml = "";
|
||||
String privacyPolicyHtml = "";
|
||||
|
||||
Future<void> fetchAgreement() async {
|
||||
try {
|
||||
emit(MenuLoading());
|
||||
final response = await ProfileApi().fetchUserAgreement();
|
||||
userAgreementHtml = response;
|
||||
emit(MenuLoaded(userAgreementHtml));
|
||||
} catch (error) {
|
||||
emit(MenuError(error.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchPrivacyPolicy() async {
|
||||
try {
|
||||
emit(MenuLoading());
|
||||
final response = await ProfileApi().fetchPrivacyPolicy();
|
||||
privacyPolicyHtml = response;
|
||||
emit(MenuLoaded(privacyPolicyHtml));
|
||||
} catch (error) {
|
||||
emit(MenuError(error.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,3 +3,22 @@ part of 'menu_cubit.dart';
|
||||
abstract class MenuState {}
|
||||
|
||||
class MenuInitial extends MenuState {}
|
||||
|
||||
class MenuLoading extends MenuState {}
|
||||
|
||||
class MenuLoaded extends MenuState {
|
||||
final String userAgreementHtml;
|
||||
MenuLoaded(this.userAgreementHtml);
|
||||
}
|
||||
|
||||
class MenuError extends MenuState {
|
||||
final String message;
|
||||
|
||||
MenuError(this.message);
|
||||
}
|
||||
|
||||
class MenuNameUpdated extends MenuState {
|
||||
final String name;
|
||||
|
||||
MenuNameUpdated(this.name);
|
||||
}
|
||||
|
||||
57
lib/features/menu/bloc/privacy_policy.dart
Normal file
57
lib/features/menu/bloc/privacy_policy.dart
Normal file
@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class PrivacyPolicy extends StatefulWidget {
|
||||
const PrivacyPolicy({super.key});
|
||||
|
||||
@override
|
||||
_PrivacyPolicyState createState() => _PrivacyPolicyState();
|
||||
}
|
||||
|
||||
class _PrivacyPolicyState extends State<PrivacyPolicy> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
MenuCubit.of(context).fetchPrivacyPolicy();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'Privacy Policy',
|
||||
child: BlocBuilder<MenuCubit, MenuState>(
|
||||
builder: (context, state) {
|
||||
if (state is MenuLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is MenuLoaded) {
|
||||
return ListView(
|
||||
children: [
|
||||
Html(
|
||||
data: state.userAgreementHtml.isNotEmpty
|
||||
? state.userAgreementHtml
|
||||
: '',
|
||||
onLinkTap: (url, attributes, element) async {
|
||||
final uri = Uri.parse(url!);
|
||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (state is MenuError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Error: ${state.message}',
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const Center(child: Text('Loading User Agreement...'));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
57
lib/features/menu/bloc/user_agreement.dart
Normal file
57
lib/features/menu/bloc/user_agreement.dart
Normal file
@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class UserAgreement extends StatefulWidget {
|
||||
const UserAgreement({super.key});
|
||||
|
||||
@override
|
||||
_UserAgreementState createState() => _UserAgreementState();
|
||||
}
|
||||
|
||||
class _UserAgreementState extends State<UserAgreement> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
MenuCubit.of(context).fetchAgreement();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'User Agreement',
|
||||
child: BlocBuilder<MenuCubit, MenuState>(
|
||||
builder: (context, state) {
|
||||
if (state is MenuLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is MenuLoaded) {
|
||||
return ListView(
|
||||
children: [
|
||||
Html(
|
||||
data: state.userAgreementHtml.isNotEmpty
|
||||
? state.userAgreementHtml
|
||||
: '',
|
||||
onLinkTap: (url, attributes, element) async {
|
||||
final uri = Uri.parse(url!);
|
||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
} else if (state is MenuError) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Error: ${state.message}',
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const Center(child: Text('Loading User Agreement...'));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/effective_period/effect_period_bloc.dart';
|
||||
@ -34,6 +35,7 @@ class MyApp extends StatelessWidget {
|
||||
BlocProvider(create: (context) => CreateSceneBloc()),
|
||||
BlocProvider(create: (context) => SceneBloc()),
|
||||
BlocProvider(create: (context) => ProfileBloc()),
|
||||
BlocProvider(create: (context) => MenuCubit()),
|
||||
],
|
||||
child: MaterialApp(
|
||||
navigatorKey: NavigationService.navigatorKey,
|
||||
|
||||
@ -53,7 +53,8 @@ abstract class ApiEndpoints {
|
||||
//POST
|
||||
static const String addUnit = '/unit';
|
||||
static const String addUnitToUser = '/unit/user';
|
||||
static const String verifyInvitationCode = '/user/{userUuid}/spaces/verify-code';
|
||||
static const String verifyInvitationCode =
|
||||
'/user/{userUuid}/spaces/verify-code';
|
||||
|
||||
//GET
|
||||
static const String unitByUuid = '/unit/';
|
||||
@ -63,8 +64,7 @@ abstract class ApiEndpoints {
|
||||
static const String unitUser = '/unit/user/';
|
||||
static const String invitationCode =
|
||||
'/projects/{projectUuid}/communities/{communityUuid}/spaces/{unitUuid}/invitation-code';
|
||||
static const String activationCode =
|
||||
'/invite-user/activation';
|
||||
static const String activationCode = '/invite-user/activation';
|
||||
|
||||
//PUT
|
||||
static const String renameUnit = '/unit/{unitUuid}';
|
||||
@ -97,7 +97,8 @@ abstract class ApiEndpoints {
|
||||
static const String controlGroup = '/group/control';
|
||||
//GET
|
||||
static const String groupBySpace = '/group/{unitUuid}';
|
||||
static const String devicesByGroupName = '/group/{unitUuid}/devices/{groupName}';
|
||||
static const String devicesByGroupName =
|
||||
'/group/{unitUuid}/devices/{groupName}';
|
||||
|
||||
static const String groupByUuid = '/group/{groupUuid}';
|
||||
//DELETE
|
||||
@ -109,7 +110,8 @@ abstract class ApiEndpoints {
|
||||
static const String addDeviceToRoom = '/device/room';
|
||||
static const String addDeviceToGroup = '/device/group';
|
||||
static const String controlDevice = '/device/{deviceUuid}/control';
|
||||
static const String firmwareDevice = '/device/{deviceUuid}/firmware/{firmwareVersion}';
|
||||
static const String firmwareDevice =
|
||||
'/device/{deviceUuid}/firmware/{firmwareVersion}';
|
||||
static const String getDevicesByUserId = '/device/user/{userId}';
|
||||
static const String getDevicesByUnitId = '/device/unit/{unitUuid}';
|
||||
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
||||
@ -120,8 +122,10 @@ abstract class ApiEndpoints {
|
||||
static const String deviceByUuid = '/device/{deviceUuid}';
|
||||
static const String deviceFunctions = '/device/{deviceUuid}/functions';
|
||||
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
||||
static const String deviceFunctionsStatus = '/device/{deviceUuid}/functions/status';
|
||||
static const String powerClamp = '/device/{powerClampUuid}/power-clamp/status';
|
||||
static const String deviceFunctionsStatus =
|
||||
'/device/{deviceUuid}/functions/status';
|
||||
static const String powerClamp =
|
||||
'/device/{powerClampUuid}/power-clamp/status';
|
||||
|
||||
///Device Permission Module
|
||||
//POST
|
||||
@ -149,14 +153,16 @@ abstract class ApiEndpoints {
|
||||
|
||||
static const String getUnitAutomation = '/automation/{unitUuid}';
|
||||
|
||||
static const String getAutomationDetails = '/automation/details/{automationId}';
|
||||
static const String getAutomationDetails =
|
||||
'/automation/details/{automationId}';
|
||||
|
||||
/// PUT
|
||||
static const String updateScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
static const String updateAutomation = '/automation/{automationId}';
|
||||
|
||||
static const String updateAutomationStatus = '/automation/status/{automationId}';
|
||||
static const String updateAutomationStatus =
|
||||
'/automation/status/{automationId}';
|
||||
|
||||
/// DELETE
|
||||
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||
@ -165,8 +171,10 @@ abstract class ApiEndpoints {
|
||||
|
||||
//////////////////////Door Lock //////////////////////
|
||||
//online
|
||||
static const String addTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
static const String getTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
static const String addTemporaryPassword =
|
||||
'/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
static const String getTemporaryPassword =
|
||||
'/door-lock/temporary-password/online/{doorLockUuid}';
|
||||
|
||||
//one-time offline
|
||||
static const String addOneTimeTemporaryPassword =
|
||||
@ -198,7 +206,8 @@ abstract class ApiEndpoints {
|
||||
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
|
||||
|
||||
static const String saveSchedule = '/schedule/{deviceUuid}';
|
||||
static const String getSchedule = '/schedule/{deviceUuid}?category={category}';
|
||||
static const String getSchedule =
|
||||
'/schedule/{deviceUuid}?category={category}';
|
||||
static const String changeSchedule = '/schedule/enable/{deviceUuid}';
|
||||
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
|
||||
static const String reportLogs =
|
||||
@ -207,8 +216,13 @@ abstract class ApiEndpoints {
|
||||
static const String statusBatch = '/device/status/batch';
|
||||
static const String deviceScene = '/device/{deviceUuid}/scenes';
|
||||
|
||||
static const String fourSceneByName = '/device/{deviceUuid}/scenes?switchName={switchName}';
|
||||
static const String fourSceneByName =
|
||||
'/device/{deviceUuid}/scenes?switchName={switchName}';
|
||||
|
||||
static const String resetDevice = '/factory/reset/{deviceUuid}';
|
||||
static const String unAssignScenesDevice = '/device/{deviceUuid}/scenes?switchName={switchName}';
|
||||
static const String unAssignScenesDevice =
|
||||
'/device/{deviceUuid}/scenes?switchName={switchName}';
|
||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
||||
static const String terms = '/terms';
|
||||
static const String policy = '/policy';
|
||||
}
|
||||
|
||||
@ -88,8 +88,7 @@ class DevicesAPI {
|
||||
|
||||
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.deviceFunctionsStatus
|
||||
.replaceAll('{deviceUuid}', deviceId),
|
||||
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -98,8 +97,7 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> getPowerClampStatus(
|
||||
String deviceId) async {
|
||||
static Future<Map<String, dynamic>> getPowerClampStatus(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
@ -111,9 +109,7 @@ class DevicesAPI {
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> renamePass(
|
||||
{required String name,
|
||||
required String doorLockUuid,
|
||||
required String passwordId}) async {
|
||||
{required String name, required String doorLockUuid, required String passwordId}) async {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.renamePassword
|
||||
.replaceAll('{doorLockUuid}', doorLockUuid)
|
||||
@ -148,8 +144,7 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future getSceneBySwitchName(
|
||||
{String? deviceId, String? switchName}) async {
|
||||
static Future getSceneBySwitchName({String? deviceId, String? switchName}) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.fourSceneByName
|
||||
.replaceAll('{deviceUuid}', deviceId!)
|
||||
@ -170,11 +165,7 @@ class DevicesAPI {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!),
|
||||
body: jsonEncode(
|
||||
{
|
||||
"switchName": switchName,
|
||||
"sceneUuid": sceneUuid,
|
||||
"spaceUuid": spaceUuid
|
||||
},
|
||||
{"switchName": switchName, "sceneUuid": sceneUuid, "spaceUuid": spaceUuid},
|
||||
),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
@ -194,8 +185,7 @@ class DevicesAPI {
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<List<DeviceModel>> getDeviceByGroupName(
|
||||
String unitId, String groupName) async {
|
||||
static Future<List<DeviceModel>> getDeviceByGroupName(String unitId, String groupName) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.devicesByGroupName
|
||||
.replaceAll('{unitUuid}', unitId)
|
||||
@ -240,9 +230,7 @@ class DevicesAPI {
|
||||
if (json == null || json.isEmpty || json == []) {
|
||||
return <DeviceModel>[];
|
||||
}
|
||||
return data
|
||||
.map<DeviceModel>((device) => DeviceModel.fromJson(device))
|
||||
.toList();
|
||||
return data.map<DeviceModel>((device) => DeviceModel.fromJson(device)).toList();
|
||||
},
|
||||
);
|
||||
|
||||
@ -254,8 +242,7 @@ class DevicesAPI {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
||||
String gatewayId) async {
|
||||
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||
showServerMessage: false,
|
||||
@ -277,8 +264,7 @@ class DevicesAPI {
|
||||
String deviceId,
|
||||
) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -289,8 +275,7 @@ class DevicesAPI {
|
||||
|
||||
static Future getOneTimePasswords(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getOneTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -301,8 +286,7 @@ class DevicesAPI {
|
||||
|
||||
static Future getTimeLimitPasswords(String deviceId) async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -327,12 +311,10 @@ class DevicesAPI {
|
||||
"invalidTime": invalidTime,
|
||||
};
|
||||
if (scheduleList != null) {
|
||||
body["scheduleList"] =
|
||||
scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||
}
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
body: body,
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => json,
|
||||
@ -343,8 +325,7 @@ class DevicesAPI {
|
||||
static Future generateOneTimePassword({deviceId}) async {
|
||||
try {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addOneTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
@ -356,12 +337,10 @@ class DevicesAPI {
|
||||
}
|
||||
}
|
||||
|
||||
static Future generateMultiTimePassword(
|
||||
{deviceId, effectiveTime, invalidTime}) async {
|
||||
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
|
||||
try {
|
||||
final response = await _httpService.post(
|
||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword
|
||||
.replaceAll('{doorLockUuid}', deviceId),
|
||||
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
|
||||
showServerMessage: true,
|
||||
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
|
||||
expectedResponseModel: (json) {
|
||||
@ -545,4 +524,18 @@ class DevicesAPI {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<DeviceReport> getDeviceReports(
|
||||
String uuid,
|
||||
String code,
|
||||
) async {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return DeviceReport.fromJson(json);
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,4 +116,24 @@ class ProfileApi {
|
||||
});
|
||||
return response as List<TimeZone>;
|
||||
}
|
||||
|
||||
Future fetchUserAgreement() async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.terms,
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
return json['data'];
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
Future fetchPrivacyPolicy() async {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.policy,
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
return json['data'];
|
||||
});
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
//ignore_for_file: constant_identifier_names
|
||||
import 'dart:ui';
|
||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/privacy_policy.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/user_agreement.dart';
|
||||
// import 'package:syncrow_app/features/menu/view/widgets/create_home/create_home_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/join_home/join_home_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/manage_home/manage_home_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/privacy/privacy_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/view/securty_view.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
@ -99,7 +100,9 @@ Map<String, DeviceType> devicesTypesMap = {
|
||||
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
DeviceType.AC: [
|
||||
FunctionModel(
|
||||
code: 'switch', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'mode',
|
||||
type: functionTypesMap['Enum'],
|
||||
@ -122,7 +125,9 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
// "range": ["low", "middle", "high", "auto"]
|
||||
})),
|
||||
FunctionModel(
|
||||
code: 'child_lock', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'child_lock',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
],
|
||||
DeviceType.Gateway: [
|
||||
FunctionModel(
|
||||
@ -136,7 +141,9 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
"range": ["normal", "alarm"]
|
||||
})),
|
||||
FunctionModel(
|
||||
code: 'factory_reset', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'factory_reset',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'alarm_active',
|
||||
type: functionTypesMap['String'],
|
||||
@ -146,7 +153,8 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
FunctionModel(
|
||||
code: 'sensitivity',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "", "min": 1, "max": 10, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "", "min": 1, "max": 10, "scale": 0, "step": 1})),
|
||||
],
|
||||
DeviceType.DoorLock: [
|
||||
FunctionModel(
|
||||
@ -154,7 +162,9 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
type: functionTypesMap['Raw'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'remote_no_dp_key', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})),
|
||||
code: 'remote_no_dp_key',
|
||||
type: functionTypesMap['Raw'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'normal_open_switch',
|
||||
type: functionTypesMap['Boolean'],
|
||||
@ -164,64 +174,87 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
FunctionModel(
|
||||
code: 'far_detection',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "cm", "min": 75, "max": 600, "scale": 0, "step": 75})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "cm", "min": 75, "max": 600, "scale": 0, "step": 75})),
|
||||
FunctionModel(
|
||||
code: 'presence_time',
|
||||
type: functionTypesMap['Integer'],
|
||||
values:
|
||||
ValueModel.fromJson({"unit": "Min", "min": 0, "max": 65535, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "Min", "min": 0, "max": 65535, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'motion_sensitivity_value',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'motionless_sensitivity',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'indicator', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'indicator',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
],
|
||||
DeviceType.OneGang: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
],
|
||||
DeviceType.TwoGang: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_2',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_2',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
],
|
||||
DeviceType.ThreeGang: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_2',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_3', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_3',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_2',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_3',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
],
|
||||
DeviceType.Curtain: [
|
||||
FunctionModel(
|
||||
@ -233,15 +266,19 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
FunctionModel(
|
||||
code: 'percent_control',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "%", "min": 0, "max": 100, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "%", "min": 0, "max": 100, "scale": 0, "step": 1})),
|
||||
],
|
||||
DeviceType.WH: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'relay_status',
|
||||
type: functionTypesMap['Enum'],
|
||||
@ -265,7 +302,9 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
],
|
||||
DeviceType.DS: [
|
||||
FunctionModel(
|
||||
code: 'doorcontact_state', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})),
|
||||
code: 'doorcontact_state',
|
||||
type: functionTypesMap['Raw'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'battery_percentage',
|
||||
type: functionTypesMap['Integer'],
|
||||
@ -273,11 +312,14 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
],
|
||||
DeviceType.OneTouch: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'relay_status',
|
||||
type: functionTypesMap['Enum'],
|
||||
@ -299,17 +341,23 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
],
|
||||
DeviceType.TowTouch: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_2',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_2',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'relay_status',
|
||||
type: functionTypesMap['Enum'],
|
||||
@ -337,23 +385,32 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
],
|
||||
DeviceType.ThreeTouch: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_2',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_3', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_3',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_2',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_3',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'relay_status',
|
||||
type: functionTypesMap['Enum'],
|
||||
@ -387,19 +444,24 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
],
|
||||
DeviceType.GarageDoor: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'tr_timecon',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 120, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 120, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_alarm',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'door_control_1',
|
||||
type: functionTypesMap['Enum'],
|
||||
@ -420,19 +482,24 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
DeviceType.WaterLeak: [],
|
||||
DeviceType.PC: [
|
||||
FunctionModel(
|
||||
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_1',
|
||||
type: functionTypesMap['Boolean'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'countdown_1',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'tr_timecon',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 120, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 120, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'countdown_alarm',
|
||||
type: functionTypesMap['Integer'],
|
||||
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
values: ValueModel.fromJson(
|
||||
{"unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1})),
|
||||
FunctionModel(
|
||||
code: 'door_control_1',
|
||||
type: functionTypesMap['Enum'],
|
||||
@ -476,9 +543,13 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
"range": ["scene"]
|
||||
})),
|
||||
FunctionModel(
|
||||
code: 'scene_id_group_id', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})),
|
||||
code: 'scene_id_group_id',
|
||||
type: functionTypesMap['Raw'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_backlight', type: functionTypesMap['Enum'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_backlight',
|
||||
type: functionTypesMap['Enum'],
|
||||
values: ValueModel.fromJson({})),
|
||||
],
|
||||
DeviceType.SixScene: [
|
||||
FunctionModel(
|
||||
@ -518,13 +589,19 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
|
||||
"range": ["scene"]
|
||||
})),
|
||||
FunctionModel(
|
||||
code: 'scene_id_group_id', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})),
|
||||
code: 'scene_id_group_id',
|
||||
type: functionTypesMap['Raw'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'switch_backlight', type: functionTypesMap['Enum'], values: ValueModel.fromJson({})),
|
||||
code: 'switch_backlight',
|
||||
type: functionTypesMap['Enum'],
|
||||
values: ValueModel.fromJson({})),
|
||||
],
|
||||
DeviceType.SOS: [
|
||||
FunctionModel(
|
||||
code: 'contact_state', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})),
|
||||
code: 'contact_state',
|
||||
type: functionTypesMap['Raw'],
|
||||
values: ValueModel.fromJson({})),
|
||||
FunctionModel(
|
||||
code: 'battery_percentage',
|
||||
type: functionTypesMap['Integer'],
|
||||
@ -709,16 +786,20 @@ List<Map<String, Object>> menuSections = [
|
||||
'title': 'Legal Information',
|
||||
'color': const Color(0xFF001B72),
|
||||
'buttons': [
|
||||
{'title': 'About', 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout, 'page': null},
|
||||
// {
|
||||
// 'title': 'Privacy Policy',
|
||||
// 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy,
|
||||
// 'page': null
|
||||
// },
|
||||
{
|
||||
'title': 'About',
|
||||
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout,
|
||||
'page': null
|
||||
},
|
||||
{
|
||||
'title': 'Privacy Policy',
|
||||
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy,
|
||||
'page': const PrivacyPolicy()
|
||||
},
|
||||
{
|
||||
'title': 'User Agreement',
|
||||
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsUserAgreement,
|
||||
'page': null
|
||||
'page': const UserAgreement()
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
224
pubspec.lock
224
pubspec.lock
@ -25,6 +25,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.0"
|
||||
audio_session:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audio_session
|
||||
sha256: b2a26ba8b7efa1790d6460e82971fde3e398cfbe2295df9dea22f3499d2c12a7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.23"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -73,6 +81,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
chewie:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: chewie
|
||||
sha256: "8bc4ac4cf3f316e50a25958c0f5eb9bb12cf7e8308bb1d74a43b230da2cfc144"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.5"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -129,6 +145,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
device_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -440,6 +464,70 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_widget_from_html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_widget_from_html
|
||||
sha256: f3967a5b42896662efdd420b5adaf8a7d3692b0f44462a07c80e3b4c173b1a02
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.3"
|
||||
flutter_widget_from_html_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_widget_from_html_core
|
||||
sha256: b1048fd119a14762e2361bd057da608148a895477846d6149109b2151d2f7abf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.2"
|
||||
fwfh_cached_network_image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fwfh_cached_network_image
|
||||
sha256: "8e44226801bfba27930673953afce8af44da7e92573be93f60385d9865a089dd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.14.3"
|
||||
fwfh_chewie:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fwfh_chewie
|
||||
sha256: "37bde9cedfb6dc5546176f7f0c56af1e814966cb33ec58f16c9565ed93ccb704"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.14.8"
|
||||
fwfh_just_audio:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fwfh_just_audio
|
||||
sha256: "38dc2c55803bd3cef33042c473e0c40b891ad4548078424641a32032f6a1245f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.2"
|
||||
fwfh_svg:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fwfh_svg
|
||||
sha256: "550b1014d12b5528d8bdb6e3b44b58721f3fb1f65d7a852d1623a817008bdfc4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.3"
|
||||
fwfh_url_launcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fwfh_url_launcher
|
||||
sha256: b9f5d55a5ae2c2c07243ba33f7ba49ac9544bdb2f4c16d8139df9ccbebe3449c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.1"
|
||||
fwfh_webview:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fwfh_webview
|
||||
sha256: c0a8b664b642f40f4c252a0ab4e72c22dcd97c7fb3a7e50a6b4bdb6f63afca19
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.3"
|
||||
get_it:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -552,6 +640,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.7"
|
||||
just_audio:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: just_audio
|
||||
sha256: "1a1eb86e7d81e69a1d36943f2b3efd62dece3dad2cafd9ec2e62e6db7c04d9b7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.43"
|
||||
just_audio_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: just_audio_platform_interface
|
||||
sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.0"
|
||||
just_audio_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: just_audio_web
|
||||
sha256: "9a98035b8b24b40749507687520ec5ab404e291d2b0937823ff45d92cb18d448"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.13"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -584,6 +696,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -640,6 +760,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
package_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: cb44f49b6e690fa766f023d5b22cac6b9affe741dd792b6ac7ad4fabe0d7b097
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1101,6 +1237,46 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
video_player:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player
|
||||
sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.9.2"
|
||||
video_player_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_android
|
||||
sha256: e343701aa890b74a863fa460f5c0e628127ed06a975d7d9af6b697133fb25bdf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.1"
|
||||
video_player_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_avfoundation
|
||||
sha256: "8a4e73a3faf2b13512978a43cf1cdda66feeeb900a0527f1fbfd7b19cf3458d3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.7"
|
||||
video_player_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_platform_interface
|
||||
sha256: "229d7642ccd9f3dc4aba169609dd6b5f3f443bb4cc15b82f7785fcada5af9bbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.3"
|
||||
video_player_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_web
|
||||
sha256: "881b375a934d8ebf868c7fb1423b2bfaa393a0a265fa3f733079a86536064a10"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1109,6 +1285,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.1"
|
||||
wakelock_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_plus
|
||||
sha256: "104d94837bb28c735894dcd592877e990149c380e6358b00c04398ca1426eed4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
wakelock_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_plus_platform_interface
|
||||
sha256: "70e780bc99796e1db82fe764b1e7dcb89a86f1e5b3afb1db354de50f2e41eb7a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1117,6 +1309,38 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1"
|
||||
webview_flutter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter
|
||||
sha256: "6869c8786d179f929144b4a1f86e09ac0eddfe475984951ea6c634774c16b522"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.0"
|
||||
webview_flutter_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_android
|
||||
sha256: ed021f27ae621bc97a6019fb601ab16331a3db4bf8afa305e9f6689bdb3edced
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.16.8"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_platform_interface
|
||||
sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
webview_flutter_wkwebview:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_wkwebview
|
||||
sha256: "9c62cc46fa4f2d41e10ab81014c1de470a6c6f26051a2de32111b2ee55287feb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.14.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -5,7 +5,7 @@ description: This is the mobile application project, developed with Flutter for
|
||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
version: 1.0.9+45
|
||||
version: 1.0.10+46
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.6 <4.0.0"
|
||||
@ -47,6 +47,7 @@ dependencies:
|
||||
fl_chart: ^0.69.0
|
||||
firebase_database: ^10.5.7
|
||||
percent_indicator: ^4.2.3
|
||||
flutter_html: ^3.0.0-beta.2
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user