mirror of
https://bitbucket.org/myhomie/myhomie_app.git
synced 2025-12-06 00:51:19 +00:00
Automation wip + others + notifications wip !
This commit is contained in:
parent
87e8c47003
commit
8a269dc8d4
@ -21,6 +21,8 @@ flutter clean
|
|||||||
|
|
||||||
flutter pub get
|
flutter pub get
|
||||||
|
|
||||||
|
flutter packages pub get
|
||||||
|
|
||||||
flutter pub run build_runner build --delete-conflicting-outputs
|
flutter pub run build_runner build --delete-conflicting-outputs
|
||||||
|
|
||||||
Le fichier est dans le projet.
|
Le fichier est dans le projet.
|
||||||
|
|||||||
@ -24,9 +24,10 @@ if (flutterVersionName == null) {
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 32
|
compileSdkVersion 33
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
@ -110,4 +111,14 @@ flutter {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
// Import the Firebase BoM
|
||||||
|
implementation platform('com.google.firebase:firebase-bom:32.2.0')
|
||||||
|
|
||||||
|
// TODO: Add the dependencies for Firebase products you want to use
|
||||||
|
// When using the BoM, don't specify versions in Firebase dependencies
|
||||||
|
implementation 'com.google.firebase:firebase-analytics'
|
||||||
|
implementation 'com.google.firebase:firebase-messaging'
|
||||||
|
|
||||||
|
// Add the dependencies for any other desired Firebase products
|
||||||
|
// https://firebase.google.com/docs/android/setup#available-libraries
|
||||||
}
|
}
|
||||||
|
|||||||
39
android/app/google-services.json
Normal file
39
android/app/google-services.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "246480640287",
|
||||||
|
"project_id": "unov---myhomie",
|
||||||
|
"storage_bucket": "unov---myhomie.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:246480640287:android:55411924cff9636eb9382a",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "be.unov.myhomie"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "246480640287-iu9np24gr3oaab8gs0c5o8n5at1e3it1.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyD_3Acf-JR2Uw4lCmCR_oKh6U-AKcuYj4o"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "246480640287-iu9np24gr3oaab8gs0c5o8n5at1e3it1.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="be.myhomie.myhomie_app">
|
package="be.unov.myhomie">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="be.myhomie.myhomie_app">
|
package="be.unov.myhomie">
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<application
|
<application
|
||||||
android:label="MyHomie"
|
android:label="MyHomie"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
@ -20,6 +20,9 @@
|
|||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
/>
|
/>
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||||
|
android:value="@string/default_notification_channel_id" />
|
||||||
<!-- Displays an Android View that continues showing the launch screen
|
<!-- Displays an Android View that continues showing the launch screen
|
||||||
Drawable until Flutter paints its first frame, then this splash
|
Drawable until Flutter paints its first frame, then this splash
|
||||||
screen fades out. A splash screen is useful to avoid any visual
|
screen fades out. A splash screen is useful to avoid any visual
|
||||||
@ -33,11 +36,23 @@
|
|||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<!-- Don't delete the meta-data below.
|
<!-- Don't delete the meta-data below.
|
||||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||||
|
android:resource="@drawable/logo" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_color"
|
||||||
|
android:resource="@color/colorPrimary" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package be.myhomie.myhomie_app
|
package be.unov.myhomie
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
|||||||
BIN
android/app/src/main/res/drawable/logo.png
Normal file
BIN
android/app/src/main/res/drawable/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
4
android/app/src/main/res/values/colors.xml
Normal file
4
android/app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#6025b6</color>
|
||||||
|
</resources>
|
||||||
15
android/app/src/main/res/values/strings.xml
Normal file
15
android/app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">MyHomie</string>
|
||||||
|
|
||||||
|
<!-- Replace "000000000000" with your Facebook App ID here. -->
|
||||||
|
<!-- <string name="facebook_app_id">742185533300745</string> -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Replace "000000000000" with your Facebook App ID here.
|
||||||
|
**NOTE**: The scheme needs to start with `fb` and then your ID.
|
||||||
|
-->
|
||||||
|
<!--<string name="fb_login_protocol_scheme">fb742185533300745</string>-->
|
||||||
|
|
||||||
|
<string name="default_notification_channel_id">main</string>
|
||||||
|
</resources>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="be.myhomie.myhomie_app">
|
package="be.unov.myhomie">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#Fri Mar 17 18:48:37 CET 2023
|
#Fri Jul 28 17:03:08 CEST 2023
|
||||||
VERSION_BUILD=19
|
VERSION_BUILD=32
|
||||||
VERSION_MAJOR=1
|
VERSION_MAJOR=1
|
||||||
VERSION_MINOR=0
|
VERSION_MINOR=0
|
||||||
VERSION_PATCH=0
|
VERSION_PATCH=0
|
||||||
|
|||||||
@ -8,6 +8,7 @@ buildscript {
|
|||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
classpath 'com.google.gms:google-services:4.3.15'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
lib/Components/Alarms/getCurrentAlarmModeIcon.dart
Normal file
21
lib/Components/Alarms/getCurrentAlarmModeIcon.dart
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mycore_api/api.dart';
|
||||||
|
|
||||||
|
IconData getAlarmModeIcon(AlarmModeDTO alarmModeDTO) {
|
||||||
|
switch(alarmModeDTO.type) {
|
||||||
|
case AlarmType.desarmed:
|
||||||
|
return Icons.lock_open;
|
||||||
|
case AlarmType.absent:
|
||||||
|
return Icons.person_off;
|
||||||
|
case AlarmType.home:
|
||||||
|
return Icons.home_outlined;
|
||||||
|
case AlarmType.geolocalized:
|
||||||
|
return Icons.location_on;
|
||||||
|
case AlarmType.programmed:
|
||||||
|
return Icons.schedule;
|
||||||
|
case AlarmType.custom:
|
||||||
|
return Icons.tune;
|
||||||
|
default:
|
||||||
|
return Icons.device_unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
77
lib/Components/Custom_Navigation_Bar/CustomAppBar.dart
Normal file
77
lib/Components/Custom_Navigation_Bar/CustomAppBar.dart
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/app_context.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||||
|
CustomAppBar({Key? key, required this.title, this.titleIcon, this.isTextSizeButton});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final IconData? titleIcon;
|
||||||
|
bool? isTextSizeButton = false;
|
||||||
|
final double _preferredHeight = 50;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CustomAppBar> createState() => _CustomAppBarState();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Size get preferredSize => Size.fromHeight(_preferredHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomAppBarState extends State<CustomAppBar> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
HomieAppContext homieAppContext = appContext.getContext();
|
||||||
|
|
||||||
|
final notchInset = MediaQuery.of(context).padding;
|
||||||
|
return AppBar(
|
||||||
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(widget.title),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: widget.titleIcon != null ? Icon(widget.titleIcon) : null,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
/*leading: widget.isHomeButton ? IconButton(
|
||||||
|
icon: const Icon(Icons.home),
|
||||||
|
onPressed: () {
|
||||||
|
// Set new State
|
||||||
|
setState(() {
|
||||||
|
visitAppContext.configuration = null;
|
||||||
|
visitAppContext.isScanningBeacons = false;
|
||||||
|
//Navigator.of(context).pop();
|
||||||
|
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(
|
||||||
|
builder: (context) => const HomePage(),
|
||||||
|
),(route) => false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
) : null,*/
|
||||||
|
actions: [
|
||||||
|
],
|
||||||
|
flexibleSpace: Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.centerRight,
|
||||||
|
end: Alignment.centerLeft,
|
||||||
|
colors: [
|
||||||
|
/*Color(0xFFDD79C2),
|
||||||
|
Color(0xFFB65FBE),
|
||||||
|
Color(0xFF9146BA),
|
||||||
|
Color(0xFF7633B8),
|
||||||
|
Color(0xFF6528B6),
|
||||||
|
Color(0xFF6025B6)*/
|
||||||
|
Color(0xFF306bac),
|
||||||
|
Color(0xFF308aae),
|
||||||
|
Color(0xFF309cb0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -67,8 +67,8 @@ class _CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: [
|
children: [
|
||||||
CustomNavItem(setPage: setPage, icon: NavItemIcon.energy, id: 3),
|
CustomNavItem(setPage: setPage, icon: NavItemIcon.devices, id: 3),
|
||||||
CustomNavItem(setPage: setPage, icon: NavItemIcon.profile, id: 4),
|
CustomNavItem(setPage: setPage, icon: NavItemIcon.energy, id: 4),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -54,22 +54,28 @@ class CustomNavItem extends StatelessWidget {
|
|||||||
size: 25,
|
size: 25,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
);
|
);
|
||||||
case 'energy':
|
case 'devices':
|
||||||
return Icon(
|
return Icon(
|
||||||
Icons.power,
|
Icons.devices_other,
|
||||||
size: 25,
|
size: 25,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
);
|
);
|
||||||
case 'profile': //Todo show user image ?
|
case 'energy':
|
||||||
|
return Icon(
|
||||||
|
Icons.bolt,
|
||||||
|
size: 25,
|
||||||
|
color: Colors.white,
|
||||||
|
);
|
||||||
|
/*case 'profile': //Todo show user image ?
|
||||||
return Icon(
|
return Icon(
|
||||||
Icons.person,
|
Icons.person,
|
||||||
size: 25,
|
size: 25,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
);
|
);*/
|
||||||
}
|
}
|
||||||
//return new FlareActor("assets/animations/bottom_navigation/"+ icon.toString().split(".").last +".flr", alignment:Alignment.center, fit:BoxFit.contain, animation: index == icon.index ? "Selected" : "Unselected"); //icon.index
|
//return new FlareActor("assets/animations/bottom_navigation/"+ icon.toString().split(".").last +".flr", alignment:Alignment.center, fit:BoxFit.contain, animation: index == icon.index ? "Selected" : "Unselected"); //icon.index
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NavItemIcon { home, security, automations, energy, profile }
|
enum NavItemIcon { home, security, automations, devices, energy, profile }
|
||||||
86
lib/Components/check_input_container.dart
Normal file
86
lib/Components/check_input_container.dart
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import 'package:auto_size_text/auto_size_text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../constants.dart';
|
||||||
|
|
||||||
|
class CheckInputContainer extends StatefulWidget {
|
||||||
|
final bool isChecked;
|
||||||
|
final IconData? icon;
|
||||||
|
final String label;
|
||||||
|
final ValueChanged<bool> onChanged;
|
||||||
|
final double fontSize;
|
||||||
|
const CheckInputContainer({
|
||||||
|
Key? key,
|
||||||
|
required this.isChecked,
|
||||||
|
this.icon,
|
||||||
|
required this.label,
|
||||||
|
required this.onChanged,
|
||||||
|
this.fontSize = 20
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_CheckInputContainerState createState() => _CheckInputContainerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CheckInputContainerState extends State<CheckInputContainer> {
|
||||||
|
bool? isChecked;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
setState(() {
|
||||||
|
isChecked = widget.isChecked;
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
if(widget.icon != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
|
child: Icon(
|
||||||
|
widget.icon,
|
||||||
|
color: kMainColor,
|
||||||
|
size: 25.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(widget.label != null)
|
||||||
|
AutoSizeText(
|
||||||
|
widget.label,
|
||||||
|
style: new TextStyle(fontSize: widget.fontSize, fontWeight: FontWeight.w300),
|
||||||
|
maxLines: 2,
|
||||||
|
maxFontSize: widget.fontSize,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(10.0),
|
||||||
|
child: Container(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: Checkbox(
|
||||||
|
shape: CircleBorder(),
|
||||||
|
value: isChecked,
|
||||||
|
checkColor: Colors.white,
|
||||||
|
activeColor: kMainColor,
|
||||||
|
onChanged: (bool? value) {
|
||||||
|
setState(() {
|
||||||
|
isChecked = value;
|
||||||
|
});
|
||||||
|
widget.onChanged(value!);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
138
lib/Components/custom_dialog.dart
Normal file
138
lib/Components/custom_dialog.dart
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:myhomie_app/Components/Buttons/rounded_button.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
|
|
||||||
|
class Consts {
|
||||||
|
Consts._();
|
||||||
|
|
||||||
|
static const double padding = 16.0;
|
||||||
|
static const double avatarRadius = 70.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomDialog extends StatelessWidget {
|
||||||
|
String title, description, buttonText;
|
||||||
|
String? iconSvg;
|
||||||
|
|
||||||
|
Function onPress;
|
||||||
|
|
||||||
|
CustomDialog({
|
||||||
|
required this.title,
|
||||||
|
required this.description,
|
||||||
|
required this.buttonText,
|
||||||
|
this.iconSvg,
|
||||||
|
required this.onPress
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Dialog(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(Consts.padding),
|
||||||
|
),
|
||||||
|
elevation: 0.0,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
child: dialogContent(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogContent(BuildContext context) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
return Stack(
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: Consts.avatarRadius + Consts.padding,
|
||||||
|
bottom: Consts.padding,
|
||||||
|
left: Consts.padding,
|
||||||
|
right: Consts.padding,
|
||||||
|
),
|
||||||
|
margin: EdgeInsets.only(top: Consts.avatarRadius),
|
||||||
|
decoration: new BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(Consts.padding),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black26,
|
||||||
|
blurRadius: 10.0,
|
||||||
|
offset: const Offset(0.0, 10.0),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min, // To make the card compact
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(height: 16.0),
|
||||||
|
Text(
|
||||||
|
description,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 22.0),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.bottomRight,
|
||||||
|
child: RoundedButton(
|
||||||
|
press: () {
|
||||||
|
onPress();
|
||||||
|
Navigator.of(context).pop(); // To close the dialog
|
||||||
|
},
|
||||||
|
text: buttonText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: Consts.padding,
|
||||||
|
right: Consts.padding,
|
||||||
|
child: Container(
|
||||||
|
width: size.width *0.18,
|
||||||
|
height: size.height *0.18,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.centerLeft,
|
||||||
|
end: Alignment.centerRight,
|
||||||
|
colors: [
|
||||||
|
Color(0xFFDD79C2),
|
||||||
|
Color(0xFFB65FBE),
|
||||||
|
Color(0xFF9146BA),
|
||||||
|
Color(0xFF7633B8),
|
||||||
|
Color(0xFF6528B6),
|
||||||
|
Color(0xFF6025B6)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
//borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
if (iconSvg != null)
|
||||||
|
SvgPicture.asset(
|
||||||
|
iconSvg!,
|
||||||
|
height: 65,
|
||||||
|
color: Colors.white,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Container(
|
||||||
|
width: size.width*0.3,
|
||||||
|
height: size.width*0.23,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: kHeadingTextStyle,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.clip
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ class RoundedInputField extends StatelessWidget {
|
|||||||
final String? initialValue;
|
final String? initialValue;
|
||||||
final Color color, textColor, iconColor;
|
final Color color, textColor, iconColor;
|
||||||
final int? maxLength;
|
final int? maxLength;
|
||||||
|
final double? fontSize;
|
||||||
const RoundedInputField({
|
const RoundedInputField({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.hintText,
|
this.hintText,
|
||||||
@ -19,6 +20,7 @@ class RoundedInputField extends StatelessWidget {
|
|||||||
this.iconColor = kTitleTextColor, // TODO
|
this.iconColor = kTitleTextColor, // TODO
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
this.maxLength, // 50
|
this.maxLength, // 50
|
||||||
|
this.fontSize = 20,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -30,7 +32,7 @@ class RoundedInputField extends StatelessWidget {
|
|||||||
initialValue: initialValue,
|
initialValue: initialValue,
|
||||||
cursorColor: textColor,
|
cursorColor: textColor,
|
||||||
maxLength: maxLength,
|
maxLength: maxLength,
|
||||||
style: TextStyle(fontSize: 20, color: textColor),
|
style: TextStyle(fontSize: fontSize, color: textColor),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
icon: icon != null ? Icon(
|
icon: icon != null ? Icon(
|
||||||
icon,
|
icon,
|
||||||
|
|||||||
65
lib/Components/string_input_container.dart
Normal file
65
lib/Components/string_input_container.dart
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import 'package:auto_size_text/auto_size_text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:myhomie_app/Components/rounded_input_field.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
|
|
||||||
|
class StringInputContainer extends StatelessWidget {
|
||||||
|
final Color color;
|
||||||
|
final Color textColor;
|
||||||
|
final String label;
|
||||||
|
final String? initialValue;
|
||||||
|
final ValueChanged<String>? onChanged;
|
||||||
|
final bool isUrl;
|
||||||
|
final bool isSmall;
|
||||||
|
final int maxLength;
|
||||||
|
final double fontSize;
|
||||||
|
final double fontSizeText;
|
||||||
|
const StringInputContainer({
|
||||||
|
Key? key,
|
||||||
|
this.color = kMainColor,
|
||||||
|
this.textColor = Colors.black,
|
||||||
|
required this.label,
|
||||||
|
this.initialValue,
|
||||||
|
this.onChanged,
|
||||||
|
this.isUrl = false,
|
||||||
|
this.isSmall = false,
|
||||||
|
this.maxLength = 50,
|
||||||
|
this.fontSize = 25,
|
||||||
|
this.fontSizeText = 20,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
return Container(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
child: AutoSizeText(
|
||||||
|
label,
|
||||||
|
style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.w300),
|
||||||
|
maxLines: 2,
|
||||||
|
maxFontSize: fontSize,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(10.0),
|
||||||
|
child: Container(
|
||||||
|
width: isUrl ? size.width *0.6 : isSmall ? size.width *0.1 : size.width *0.65,
|
||||||
|
child: RoundedInputField(
|
||||||
|
color: color,
|
||||||
|
textColor: textColor,
|
||||||
|
fontSize: fontSizeText,
|
||||||
|
initialValue: initialValue,
|
||||||
|
onChanged: onChanged,
|
||||||
|
maxLength: maxLength,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
lib/Helpers/NotificationManager.dart
Normal file
46
lib/Helpers/NotificationManager.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:myhomie_app/Components/custom_dialog.dart';
|
||||||
|
import 'package:myhomie_app/Helpers/PushNotificationService.dart';
|
||||||
|
|
||||||
|
class NotificationManager {
|
||||||
|
|
||||||
|
static BuildContext? _context;
|
||||||
|
static String defaultButtonLabel = "Merci !";
|
||||||
|
|
||||||
|
static init({required BuildContext context}) {
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static handleDataMsg(Map<String, dynamic> data){
|
||||||
|
}
|
||||||
|
|
||||||
|
static handleNotificationMsg(PushNotificationMessage message) {
|
||||||
|
//We can add showDialog key in future
|
||||||
|
/*if (data.containsKey('showDialog')) {
|
||||||
|
// Handle data message with dialog
|
||||||
|
_showDialog(data);
|
||||||
|
}*/
|
||||||
|
_showDialog(message: message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static _showDialog({required PushNotificationMessage message}) {
|
||||||
|
var buttonLabel = message.data.labelButton == null ? defaultButtonLabel : message.data.labelButton;
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: _context!,
|
||||||
|
builder: (BuildContext context) => CustomDialog(
|
||||||
|
title: message.title,
|
||||||
|
description: message.body,
|
||||||
|
buttonText: buttonLabel!,
|
||||||
|
onPress: () => {
|
||||||
|
/*if (message.data.type != null) {
|
||||||
|
PageSwitcher(message.data.type)
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
168
lib/Helpers/PushNotificationService.dart
Normal file
168
lib/Helpers/PushNotificationService.dart
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
import 'package:myhomie_app/Helpers/NotificationManager.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
|
||||||
|
import '../constants.dart';
|
||||||
|
|
||||||
|
class PushNotificationService {
|
||||||
|
//final FirebaseMessaging _fcm;
|
||||||
|
|
||||||
|
PushNotificationService(); //this._fcm
|
||||||
|
|
||||||
|
goToPage(Map<String, dynamic> message) {
|
||||||
|
var notification = PushNotificationMessage(
|
||||||
|
title: message['notification']['title'],
|
||||||
|
body: message['notification']['body'],
|
||||||
|
data: DataNotification(
|
||||||
|
collapseKey: message['data']['title'],
|
||||||
|
type: message['data']['type'])
|
||||||
|
);
|
||||||
|
|
||||||
|
//PageSwitcher(notification.data.type);
|
||||||
|
|
||||||
|
Fluttertoast.showToast(
|
||||||
|
msg: 'onResume or onLaunch '+ notification.title + ' : ' + notification.body,
|
||||||
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
|
gravity: ToastGravity.BOTTOM,
|
||||||
|
timeInSecForIosWeb: 1,
|
||||||
|
backgroundColor: kMainColor,
|
||||||
|
textColor: Colors.white,
|
||||||
|
fontSize: 16.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future initialise(HomieAppContext? homieAppContext, {required BuildContext context}) async {
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
//_fcm.requestPermission(); // IosNotificationSettings
|
||||||
|
FirebaseMessaging.instance.requestPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
//_fcm.subscribeToTopic("main");
|
||||||
|
|
||||||
|
FirebaseMessaging.instance.subscribeToTopic("main");
|
||||||
|
|
||||||
|
if(homieAppContext != null) {
|
||||||
|
if (homieAppContext.userId != null) {
|
||||||
|
print('MyHomie USER ID for fcm notification = ' + homieAppContext.userId.toString());
|
||||||
|
FirebaseMessaging.instance.subscribeToTopic(homieAppContext.userId!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you want to test the push notification locally,
|
||||||
|
// you need to get the token and input to the Firebase console
|
||||||
|
// https://console.firebase.google.com/project/YOUR_PROJECT_ID/notification/compose
|
||||||
|
String? token = await FirebaseMessaging.instance.getToken();
|
||||||
|
print("FirebaseMessaging token: $token");
|
||||||
|
|
||||||
|
FirebaseMessaging.instance.getInitialMessage().then(
|
||||||
|
(value) {
|
||||||
|
debugPrint("COUCOUCOUC $value");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
FirebaseMessaging.onMessage.listen((data) {
|
||||||
|
var notification;
|
||||||
|
print("onMessage: $data");
|
||||||
|
print(data);
|
||||||
|
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
notification = PushNotificationMessage(
|
||||||
|
title: data.notification!.title!,
|
||||||
|
body: data.notification!.body!,
|
||||||
|
data: DataNotification(
|
||||||
|
//labelButton: message['data']['labelButton'],
|
||||||
|
type: data.messageType!)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*if (Platform.isIOS) {
|
||||||
|
notification = PushNotificationMessage(
|
||||||
|
title: message['aps']['alert']['title'],
|
||||||
|
body: message['aps']['alert']['body'],
|
||||||
|
data: DataNotification(
|
||||||
|
labelButton: message['labelButton'],
|
||||||
|
type: message['type'])
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
NotificationManager.handleNotificationMsg(notification);
|
||||||
|
// show notification UI here
|
||||||
|
});
|
||||||
|
|
||||||
|
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
|
||||||
|
print('A new onMessageOpenedApp event was published!');
|
||||||
|
|
||||||
|
/*Navigator.pushNamed(
|
||||||
|
context,
|
||||||
|
'/message',
|
||||||
|
arguments: MessageArguments(message, true),
|
||||||
|
);*/
|
||||||
|
});
|
||||||
|
|
||||||
|
/*_fcm.configure(
|
||||||
|
onMessage: (Map<String, dynamic> message) async {
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
onLaunch: (Map<String, dynamic> message) async {
|
||||||
|
print("onLaunch: $message");
|
||||||
|
this.goToPage(message);
|
||||||
|
|
||||||
|
},
|
||||||
|
onResume: (Map<String, dynamic> message) async {
|
||||||
|
print("onResume: $message");
|
||||||
|
this.goToPage(message);
|
||||||
|
},
|
||||||
|
);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PushNotificationMessage {
|
||||||
|
final String title;
|
||||||
|
final String body;
|
||||||
|
final DataNotification data;
|
||||||
|
PushNotificationMessage({
|
||||||
|
required this.title,
|
||||||
|
required this.body,
|
||||||
|
required this.data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataNotification {
|
||||||
|
final String? collapseKey;
|
||||||
|
final String type;
|
||||||
|
final String? labelButton;
|
||||||
|
DataNotification({
|
||||||
|
this.collapseKey,
|
||||||
|
required this.type,
|
||||||
|
this.labelButton
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*PageSwitcher(String type) {
|
||||||
|
switch(type) {
|
||||||
|
case "home":
|
||||||
|
pageController.jumpToPage(NavItemIcon.home.index);
|
||||||
|
break;
|
||||||
|
case "advices":
|
||||||
|
// In case of new advice, need to reload advices list automatically
|
||||||
|
pageController.jumpToPage(NavItemIcon.advices.index);
|
||||||
|
break;
|
||||||
|
case "scan":
|
||||||
|
pageController.jumpToPage(NavItemIcon.scan.index);
|
||||||
|
break;
|
||||||
|
case "shop":
|
||||||
|
pageController.jumpToPage(NavItemIcon.wallet.index);
|
||||||
|
break;
|
||||||
|
case "profile":
|
||||||
|
pageController.jumpToPage(NavItemIcon.profile.index);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pageController.jumpToPage(NavItemIcon.home.index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
213
lib/Screens/Main/Automations/automationDetailPage.dart
Normal file
213
lib/Screens/Main/Automations/automationDetailPage.dart
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mycore_api/api.dart';
|
||||||
|
|
||||||
|
import 'package:mycore_api/api.dart' as API;
|
||||||
|
import 'package:myhomie_app/Components/Alarms/getCurrentAlarmModeIcon.dart';
|
||||||
|
import 'package:myhomie_app/Components/Custom_Navigation_Bar/CustomAppBar.dart';
|
||||||
|
import 'package:myhomie_app/Components/check_input_container.dart';
|
||||||
|
import 'package:myhomie_app/Components/loading_common.dart';
|
||||||
|
import 'package:myhomie_app/Components/string_input_container.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/app_context.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class AutomationDetailPage extends StatefulWidget {
|
||||||
|
const AutomationDetailPage({Key? key, required this.automationDTO}) : super(key: key);
|
||||||
|
|
||||||
|
final API.AutomationDTO automationDTO;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AutomationDetailPage> createState() => _AutomationDetailPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AutomationDetailPageState extends State<AutomationDetailPage> {
|
||||||
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
AutomationDetailDTO? automationDetailDTO;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
//final notchInset = MediaQuery.of(context).padding;
|
||||||
|
|
||||||
|
HomieAppContext homieAppContext = appContext.getContext();
|
||||||
|
|
||||||
|
debugPrint(widget.automationDTO.id!);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
key: _scaffoldKey,
|
||||||
|
appBar: CustomAppBar(
|
||||||
|
title: widget.automationDTO.name!,
|
||||||
|
//titleIcon: getAlarmModeIcon(widget.alarmMode),
|
||||||
|
isTextSizeButton: true,
|
||||||
|
),
|
||||||
|
body: FutureBuilder(
|
||||||
|
future: homieAppContext.clientAPI.automationApi!.automationGetDetail(widget.automationDTO.id!),
|
||||||
|
builder: (context, AsyncSnapshot<AutomationDetailDTO?> snapshot) {
|
||||||
|
if(snapshot.data != null ) {
|
||||||
|
automationDetailDTO = snapshot.data;
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: size.width *1.1,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: StringInputContainer(
|
||||||
|
label: "Nom:",
|
||||||
|
color: kMainColor,
|
||||||
|
textColor: Colors.white,
|
||||||
|
initialValue: automationDetailDTO!.name,
|
||||||
|
onChanged: (String value) {
|
||||||
|
setState(() {
|
||||||
|
automationDetailDTO!.name = value;
|
||||||
|
// TODO SAVE or not
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
/*Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: CheckInputContainer(
|
||||||
|
icon: Icons.notifications_active,
|
||||||
|
label: "Notification :",
|
||||||
|
fontSize: 20,
|
||||||
|
isChecked: alarmModeDetailDTO!.notification!,
|
||||||
|
onChanged: (bool value) {
|
||||||
|
alarmModeDetailDTO!.notification = value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(
|
||||||
|
"Triggers",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
|
),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
for(var trigger in automationDetailDTO!.triggers!)
|
||||||
|
if(automationDetailDTO!.devices!.where((d) => d.id == trigger.deviceId).isNotEmpty)
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(automationDetailDTO!.devices!.firstWhere((d) => d.id == trigger.deviceId).name!),
|
||||||
|
children: <Widget>[
|
||||||
|
ListTile(
|
||||||
|
title: Text("name: "+trigger.stateName! + " - " + "value: "+ trigger.stateValue!),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("Ajouter +", style: TextStyle(), textAlign: TextAlign.center),
|
||||||
|
tileColor: Colors.lightGreen,
|
||||||
|
onTap: () {
|
||||||
|
// Show popup ajout
|
||||||
|
debugPrint("Add device to trigger popup");
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(
|
||||||
|
"Actions",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
|
),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
for(var action in automationDetailDTO!.actions!)
|
||||||
|
actionTile(action),
|
||||||
|
ListTile(
|
||||||
|
title: Text("Ajouter +", style: TextStyle(), textAlign: TextAlign.center),
|
||||||
|
tileColor: Colors.lightGreen,
|
||||||
|
onTap: () {
|
||||||
|
// Show popup ajout
|
||||||
|
debugPrint("Add device to trigger popup");
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
Text("Actions"),
|
||||||
|
for(var device in automationDetailDTO!.devices!.where((d) => automationDetailDTO!.actions!.map((t)=> t.deviceId).contains(d.id)))
|
||||||
|
Text(device.name!),
|
||||||
|
Text(automationDetailDTO!.actions!.toString()),
|
||||||
|
Text("Devices"),
|
||||||
|
Text(automationDetailDTO!.devices!.toString()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const LoadingCommon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
actionTile(API.Action action) {
|
||||||
|
switch(action.type) {
|
||||||
|
case ActionType.DELAY:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
case ActionType.DEVICE:
|
||||||
|
return ExpansionTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
children: [
|
||||||
|
if(automationDetailDTO!.devices!.where((d) => d.id == action.deviceId).isNotEmpty)
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(automationDetailDTO!.devices!.firstWhere((d) => d.id == action.deviceId).name!),
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
title: Text(action.states.toString())
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
case ActionType.GROUP:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
case ActionType.HTTP:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
case ActionType.MQTT:
|
||||||
|
return ExpansionTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
title: Text(action.rawRequest!),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
case ActionType.zIGBEE2MQTT:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mycore_api/api.dart';
|
||||||
|
import 'package:myhomie_app/Components/loading_common.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/Screens/Main/Automations/automationDetailPage.dart';
|
||||||
import 'package:myhomie_app/app_context.dart';
|
import 'package:myhomie_app/app_context.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class AutomationsScreen extends StatefulWidget {
|
class AutomationsScreen extends StatefulWidget {
|
||||||
@ -11,7 +16,7 @@ class AutomationsScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _AutomationsScreenState extends State<AutomationsScreen> {
|
class _AutomationsScreenState extends State<AutomationsScreen> {
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
//List<Message> messages;
|
List<AutomationDTO>? allAutomations;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -22,47 +27,103 @@ class _AutomationsScreenState extends State<AutomationsScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
final appContext = Provider.of<AppContext>(context);
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
HomieAppContext homieAppContext = appContext.getContext();
|
||||||
|
|
||||||
return interfaceElements();
|
return SingleChildScrollView(
|
||||||
|
|
||||||
/*if(appContext.getContext().feed != null) {
|
|
||||||
return interfaceElements();
|
|
||||||
} else {
|
|
||||||
return FutureBuilder(
|
|
||||||
future: Message.getMessages(this.messages, appContext, false, true),
|
|
||||||
builder: (context, AsyncSnapshot<List<Message>> snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
|
||||||
return interfaceElements();
|
|
||||||
} else if (snapshot.connectionState == ConnectionState.none) {
|
|
||||||
print('ConnectionState.none');
|
|
||||||
return Text("No data");
|
|
||||||
} else {
|
|
||||||
return Container(height: size.height * 0.2, child: Loading());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
interfaceElements() {
|
|
||||||
Size size = MediaQuery.of(context).size;
|
|
||||||
final appContext = Provider.of<AppContext>(context);
|
|
||||||
return RefreshIndicator(
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
displacement: 20,
|
|
||||||
onRefresh: () async {
|
|
||||||
print("TODO refresh");
|
|
||||||
//await Message.getMessages(this.messages, appContext, true, true);
|
|
||||||
},
|
|
||||||
child: Container(
|
child: Container(
|
||||||
height: size.height * 0.8,
|
height: size.height * 0.9,
|
||||||
child: SingleChildScrollView(
|
child: FutureBuilder(
|
||||||
child: Column(
|
future: homieAppContext.clientAPI.automationApi!.automationGetAll(homieAppContext.homeId!),
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
builder: (context, AsyncSnapshot<List<AutomationDTO>?> snapshot) {
|
||||||
children: [
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
Text("TODO Automations")
|
allAutomations = snapshot.data;
|
||||||
],
|
return Padding(
|
||||||
),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: RefreshIndicator(
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
displacement: 20,
|
||||||
|
onRefresh: () async {
|
||||||
|
print("TODO refresh");
|
||||||
|
setState(() {});
|
||||||
|
return Future(() => null);
|
||||||
|
//await Message.getMessages(this.messages, appContext, true, true);
|
||||||
|
},
|
||||||
|
child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
debugPrint(allAutomations![index].toString());
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => AutomationDetailPage(
|
||||||
|
automationDTO: allAutomations![index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: size.height * 0.1,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
border: Border.all(
|
||||||
|
color: kBackgroundSecondGrey.withOpacity(0.35),
|
||||||
|
width: 0.2,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: kMainColor.withOpacity(0.35),
|
||||||
|
//spreadRadius: 0.15,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: const Offset(0, 10), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Text(allAutomations![index].name!),
|
||||||
|
Switch(
|
||||||
|
// thumb color (round icon)
|
||||||
|
activeColor: kMainColor,
|
||||||
|
activeTrackColor: Colors.grey.shade400,
|
||||||
|
inactiveThumbColor: Colors.blueGrey.shade600,
|
||||||
|
inactiveTrackColor: Colors.grey.shade400,
|
||||||
|
splashRadius: 50.0,
|
||||||
|
// boolean variable value
|
||||||
|
value: allAutomations![index].active!,
|
||||||
|
// changes the state of the switch
|
||||||
|
onChanged: (bool value) {
|
||||||
|
|
||||||
|
/*setState(() {
|
||||||
|
allAutomations![index].active = value;
|
||||||
|
// TODO save
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: allAutomations!.length
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||||
|
print('ConnectionState.none');
|
||||||
|
return Text("No data");
|
||||||
|
} else {
|
||||||
|
return Container(height: size.height * 0.2, child: LoadingCommon());
|
||||||
|
}
|
||||||
|
}
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
70
lib/Screens/Main/Devices/devices.dart
Normal file
70
lib/Screens/Main/Devices/devices.dart
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:myhomie_app/app_context.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class DevicesScreen extends StatefulWidget {
|
||||||
|
DevicesScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DevicesScreenState createState() => _DevicesScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DevicesScreenState extends State<DevicesScreen> {
|
||||||
|
bool isLoading = true;
|
||||||
|
//List<Message> messages;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
|
||||||
|
return interfaceElements();
|
||||||
|
|
||||||
|
/*if(appContext.getContext().feed != null) {
|
||||||
|
return interfaceElements();
|
||||||
|
} else {
|
||||||
|
return FutureBuilder(
|
||||||
|
future: Message.getMessages(this.messages, appContext, false, true),
|
||||||
|
builder: (context, AsyncSnapshot<List<Message>> snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
return interfaceElements();
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||||
|
print('ConnectionState.none');
|
||||||
|
return Text("No data");
|
||||||
|
} else {
|
||||||
|
return Container(height: size.height * 0.2, child: Loading());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaceElements() {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
return RefreshIndicator(
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
displacement: 20,
|
||||||
|
onRefresh: () async {
|
||||||
|
print("TODO refresh");
|
||||||
|
//await Message.getMessages(this.messages, appContext, true, true);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
height: size.height * 0.8,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("TODO Devices")
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ import 'package:mycore_api/api.dart';
|
|||||||
import 'package:myhomie_app/Components/loading.dart';
|
import 'package:myhomie_app/Components/loading.dart';
|
||||||
import 'package:myhomie_app/Components/loading_common.dart';
|
import 'package:myhomie_app/Components/loading_common.dart';
|
||||||
import 'package:myhomie_app/Models/homieContext.dart';
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/Screens/Main/Home/roomDetailPage.dart';
|
||||||
import 'package:myhomie_app/app_context.dart';
|
import 'package:myhomie_app/app_context.dart';
|
||||||
import 'package:myhomie_app/constants.dart';
|
import 'package:myhomie_app/constants.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -86,10 +87,19 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
debugPrint(roomsMaindetails[index].toString());
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => RoomDetailPage(
|
||||||
|
roomMainDetailDTO: roomsMaindetails[index]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
/*setState(() {
|
||||||
//selectedSection = menuDTO.sections[index];
|
//selectedSection = menuDTO.sections[index];
|
||||||
print("Hero to room detail");
|
print("Hero to room detail");
|
||||||
});
|
});*/
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: boxDecorationRoom(roomsMaindetails[index], false),
|
decoration: boxDecorationRoom(roomsMaindetails[index], false),
|
||||||
|
|||||||
139
lib/Screens/Main/Home/roomDetailPage.dart
Normal file
139
lib/Screens/Main/Home/roomDetailPage.dart
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mycore_api/api.dart';
|
||||||
|
|
||||||
|
import 'package:mycore_api/api.dart' as API;
|
||||||
|
import 'package:myhomie_app/Components/Alarms/getCurrentAlarmModeIcon.dart';
|
||||||
|
import 'package:myhomie_app/Components/Custom_Navigation_Bar/CustomAppBar.dart';
|
||||||
|
import 'package:myhomie_app/Components/check_input_container.dart';
|
||||||
|
import 'package:myhomie_app/Components/loading_common.dart';
|
||||||
|
import 'package:myhomie_app/Components/string_input_container.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/app_context.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class RoomDetailPage extends StatefulWidget {
|
||||||
|
const RoomDetailPage({Key? key, required this.roomMainDetailDTO}) : super(key: key);
|
||||||
|
|
||||||
|
final API.RoomMainDetailDTO roomMainDetailDTO;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RoomDetailPage> createState() => _RoomDetailPagePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RoomDetailPagePageState extends State<RoomDetailPage> {
|
||||||
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
API.RoomDetailDTO? roomDetailDTO;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
//final notchInset = MediaQuery.of(context).padding;
|
||||||
|
|
||||||
|
HomieAppContext homieAppContext = appContext.getContext();
|
||||||
|
|
||||||
|
debugPrint(widget.roomMainDetailDTO.id!);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
key: _scaffoldKey,
|
||||||
|
appBar: CustomAppBar(
|
||||||
|
title: widget.roomMainDetailDTO.name!,
|
||||||
|
//titleIcon: getAlarmModeIcon(widget.alarmMode),
|
||||||
|
isTextSizeButton: true,
|
||||||
|
),
|
||||||
|
body: FutureBuilder(
|
||||||
|
future: homieAppContext.clientAPI.roomApi!.roomGetDetail(widget.roomMainDetailDTO.id!),
|
||||||
|
builder: (context, AsyncSnapshot<API.RoomDetailDTO?> snapshot) {
|
||||||
|
if(snapshot.data != null ) {
|
||||||
|
roomDetailDTO = snapshot.data;
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: size.width *1.1,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: StringInputContainer(
|
||||||
|
label: "Nom:",
|
||||||
|
color: kMainColor,
|
||||||
|
textColor: Colors.white,
|
||||||
|
initialValue: roomDetailDTO!.name,
|
||||||
|
onChanged: (String value) {
|
||||||
|
setState(() {
|
||||||
|
roomDetailDTO!.name = value;
|
||||||
|
// TODO SAVE or not
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
/*Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: CheckInputContainer(
|
||||||
|
icon: Icons.notifications_active,
|
||||||
|
label: "Notification :",
|
||||||
|
fontSize: 20,
|
||||||
|
isChecked: alarmModeDetailDTO!.notification!,
|
||||||
|
onChanged: (bool value) {
|
||||||
|
alarmModeDetailDTO!.notification = value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(
|
||||||
|
"Devices",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
|
),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
for(var device in roomDetailDTO!.devices!)
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(device.name!),
|
||||||
|
children: <Widget>[
|
||||||
|
ListTile(
|
||||||
|
title: Text("type: "+ (device.type != null ? device.type!.value : 'no type') ),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("status: "+ device.status.toString()),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("last update date: "+ device.lastStateDate!.toLocal().toString()),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("lastState: "+ (device.lastState != null ? device.lastState! : 'no data')),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const LoadingCommon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import 'package:myhomie_app/Components/Custom_Navigation_Bar/custom_nav_item.dar
|
|||||||
import 'package:myhomie_app/Helpers/MQTTHelper.dart';
|
import 'package:myhomie_app/Helpers/MQTTHelper.dart';
|
||||||
import 'package:myhomie_app/Screens/Debug/DebugPage.dart';
|
import 'package:myhomie_app/Screens/Debug/DebugPage.dart';
|
||||||
import 'package:myhomie_app/Screens/Main/Automations/automations.dart';
|
import 'package:myhomie_app/Screens/Main/Automations/automations.dart';
|
||||||
|
import 'package:myhomie_app/Screens/Main/Devices/devices.dart';
|
||||||
import 'package:myhomie_app/app_context.dart';
|
import 'package:myhomie_app/app_context.dart';
|
||||||
import 'package:myhomie_app/constants.dart';
|
import 'package:myhomie_app/constants.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -62,8 +63,9 @@ class _MainPageState extends State<MainPage> {
|
|||||||
HomeScreen(),
|
HomeScreen(),
|
||||||
SecurityScreen(),
|
SecurityScreen(),
|
||||||
AutomationsScreen(),
|
AutomationsScreen(),
|
||||||
|
DevicesScreen(),
|
||||||
EnergyScreen(),
|
EnergyScreen(),
|
||||||
ProfileScreen(),
|
//ProfileScreen(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
drawer: Drawer(
|
drawer: Drawer(
|
||||||
|
|||||||
211
lib/Screens/Main/Security/alarmDetailPage.dart
Normal file
211
lib/Screens/Main/Security/alarmDetailPage.dart
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mycore_api/api.dart';
|
||||||
|
|
||||||
|
import 'package:mycore_api/api.dart' as API;
|
||||||
|
import 'package:myhomie_app/Components/Alarms/getCurrentAlarmModeIcon.dart';
|
||||||
|
import 'package:myhomie_app/Components/Custom_Navigation_Bar/CustomAppBar.dart';
|
||||||
|
import 'package:myhomie_app/Components/check_input_container.dart';
|
||||||
|
import 'package:myhomie_app/Components/loading_common.dart';
|
||||||
|
import 'package:myhomie_app/Components/string_input_container.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/app_context.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class AlarmDetailPage extends StatefulWidget {
|
||||||
|
const AlarmDetailPage({Key? key, required this.alarmMode}) : super(key: key);
|
||||||
|
|
||||||
|
final AlarmModeDTO alarmMode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AlarmDetailPage> createState() => _AlarmDetailPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AlarmDetailPageState extends State<AlarmDetailPage> {
|
||||||
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
AlarmModeDetailDTO? alarmModeDetailDTO;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
//final notchInset = MediaQuery.of(context).padding;
|
||||||
|
|
||||||
|
HomieAppContext homieAppContext = appContext.getContext();
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
key: _scaffoldKey,
|
||||||
|
appBar: CustomAppBar(
|
||||||
|
title: widget.alarmMode.name!,
|
||||||
|
titleIcon: getAlarmModeIcon(widget.alarmMode),
|
||||||
|
isTextSizeButton: true,
|
||||||
|
),
|
||||||
|
body: FutureBuilder(
|
||||||
|
future: homieAppContext.clientAPI.alarmApi!.alarmGetDetail(widget.alarmMode.id!),
|
||||||
|
builder: (context, AsyncSnapshot<AlarmModeDetailDTO?> snapshot) {
|
||||||
|
if(snapshot.data != null ) {
|
||||||
|
alarmModeDetailDTO = snapshot.data;
|
||||||
|
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
if(!alarmModeDetailDTO!.isDefault!)
|
||||||
|
SizedBox(
|
||||||
|
width: size.width *1.1,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: StringInputContainer(
|
||||||
|
label: "Nom:",
|
||||||
|
color: kMainColor,
|
||||||
|
textColor: Colors.white,
|
||||||
|
initialValue: alarmModeDetailDTO!.name,
|
||||||
|
onChanged: (String value) {
|
||||||
|
setState(() {
|
||||||
|
alarmModeDetailDTO!.name = value;
|
||||||
|
// TODO SAVE or not
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: CheckInputContainer(
|
||||||
|
icon: Icons.notifications_active,
|
||||||
|
label: "Notification :",
|
||||||
|
fontSize: 20,
|
||||||
|
isChecked: alarmModeDetailDTO!.notification!,
|
||||||
|
onChanged: (bool value) {
|
||||||
|
alarmModeDetailDTO!.notification = value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(
|
||||||
|
"Triggers",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
|
),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
for(var trigger in alarmModeDetailDTO!.triggers!)
|
||||||
|
if(alarmModeDetailDTO!.devices!.where((d) => d.id == trigger.deviceId).isNotEmpty)
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(alarmModeDetailDTO!.devices!.firstWhere((d) => d.id == trigger.deviceId).name!),
|
||||||
|
children: <Widget>[
|
||||||
|
ListTile(
|
||||||
|
title: Text("name: "+trigger.stateName! + " - " + "value: "+ trigger.stateValue!),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("Ajouter +", style: TextStyle(), textAlign: TextAlign.center),
|
||||||
|
tileColor: Colors.lightGreen,
|
||||||
|
onTap: () {
|
||||||
|
// Show popup ajout
|
||||||
|
debugPrint("Add device to trigger popup");
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(
|
||||||
|
"Actions",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
|
),
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
for(var action in alarmModeDetailDTO!.actions!)
|
||||||
|
actionTile(action),
|
||||||
|
ListTile(
|
||||||
|
title: Text("Ajouter +", style: TextStyle(), textAlign: TextAlign.center),
|
||||||
|
tileColor: Colors.lightGreen,
|
||||||
|
onTap: () {
|
||||||
|
// Show popup ajout
|
||||||
|
debugPrint("Add device to trigger popup");
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
Text("Actions"),
|
||||||
|
for(var device in alarmModeDetailDTO!.devices!.where((d) => alarmModeDetailDTO!.actions!.map((t)=> t.deviceId).contains(d.id)))
|
||||||
|
Text(device.name!),
|
||||||
|
Text(alarmModeDetailDTO!.actions!.toString()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const LoadingCommon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
actionTile(API.Action action) {
|
||||||
|
switch(action.type) {
|
||||||
|
case ActionType.DELAY:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
case ActionType.DEVICE:
|
||||||
|
return ExpansionTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
children: [
|
||||||
|
if(alarmModeDetailDTO!.devices!.where((d) => d.id == action.deviceId).isNotEmpty)
|
||||||
|
ExpansionTile(
|
||||||
|
title: Text(alarmModeDetailDTO!.devices!.firstWhere((d) => d.id == action.deviceId).name!),
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
title: Text(action.states.toString())
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
case ActionType.GROUP:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
case ActionType.HTTP:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
case ActionType.MQTT:
|
||||||
|
return ExpansionTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
title: Text(action.rawRequest!),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
case ActionType.zIGBEE2MQTT:
|
||||||
|
return ListTile(
|
||||||
|
title: Text(action.type.toString()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
89
lib/Screens/Main/Security/changeAlarmMode.dart
Normal file
89
lib/Screens/Main/Security/changeAlarmMode.dart
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mycore_api/api.dart';
|
||||||
|
import 'package:myhomie_app/Components/Alarms/getCurrentAlarmModeIcon.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
|
|
||||||
|
Future<String?> showChangeAlarmModePopup(List<AlarmModeDTO> allAlarmModes, HomieAppContext homieAppContext, BuildContext context, Size size) {
|
||||||
|
return showDialog(
|
||||||
|
builder: (BuildContext dialogContext) => AlertDialog(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.0))
|
||||||
|
),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: size.height * 0.5,
|
||||||
|
width: size.width * 0.95,
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left:8.0, right: 8.0, bottom: 8.0, top: 8.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text("Changer le mode d'alarme courante"),
|
||||||
|
),
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: Container(
|
||||||
|
height: size.height*0.4,
|
||||||
|
//color: Colors.orange,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
for(var alarmMode in allAlarmModes)
|
||||||
|
SizedBox(
|
||||||
|
width: size.width * 0.5,
|
||||||
|
height: size.height * 0.05,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(dialogContext, alarmMode.id);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
border: Border.all(
|
||||||
|
color: kBackgroundSecondGrey.withOpacity(0.35),
|
||||||
|
width: 0.2,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: kMainColor.withOpacity(0.35),
|
||||||
|
//spreadRadius: 0.15,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: const Offset(0, 10), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Text(alarmMode.name!),
|
||||||
|
Icon(getAlarmModeIcon(alarmMode)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
), context: context
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,5 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mycore_api/api.dart';
|
||||||
|
import 'package:myhomie_app/Components/Alarms/getCurrentAlarmModeIcon.dart';
|
||||||
|
import 'package:myhomie_app/Components/loading_common.dart';
|
||||||
|
import 'package:myhomie_app/Models/homieContext.dart';
|
||||||
|
import 'package:myhomie_app/Screens/Main/Security/alarmDetailPage.dart';
|
||||||
|
import 'package:myhomie_app/Screens/Main/Security/changeAlarmMode.dart';
|
||||||
import 'package:myhomie_app/app_context.dart';
|
import 'package:myhomie_app/app_context.dart';
|
||||||
|
import 'package:myhomie_app/constants.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class SecurityScreen extends StatefulWidget {
|
class SecurityScreen extends StatefulWidget {
|
||||||
@ -11,7 +18,8 @@ class SecurityScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _SecurityScreenState extends State<SecurityScreen> {
|
class _SecurityScreenState extends State<SecurityScreen> {
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
//List<Message> messages;
|
List<AlarmModeDTO>? allAlarmModes;
|
||||||
|
AlarmModeDTO? currentAlarmMode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -22,31 +30,8 @@ class _SecurityScreenState extends State<SecurityScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
final appContext = Provider.of<AppContext>(context);
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
HomieAppContext homieAppContext = appContext.getContext();
|
||||||
|
|
||||||
return interfaceElements();
|
|
||||||
|
|
||||||
/*if(appContext.getContext().feed != null) {
|
|
||||||
return interfaceElements();
|
|
||||||
} else {
|
|
||||||
return FutureBuilder(
|
|
||||||
future: Message.getMessages(this.messages, appContext, false, true),
|
|
||||||
builder: (context, AsyncSnapshot<List<Message>> snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
|
||||||
return interfaceElements();
|
|
||||||
} else if (snapshot.connectionState == ConnectionState.none) {
|
|
||||||
print('ConnectionState.none');
|
|
||||||
return Text("No data");
|
|
||||||
} else {
|
|
||||||
return Container(height: size.height * 0.2, child: Loading());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
interfaceElements() {
|
|
||||||
Size size = MediaQuery.of(context).size;
|
|
||||||
final appContext = Provider.of<AppContext>(context);
|
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
displacement: 20,
|
displacement: 20,
|
||||||
@ -55,16 +40,98 @@ class _SecurityScreenState extends State<SecurityScreen> {
|
|||||||
//await Message.getMessages(this.messages, appContext, true, true);
|
//await Message.getMessages(this.messages, appContext, true, true);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
height: size.height * 0.8,
|
height: size.height * 0.842,
|
||||||
child: SingleChildScrollView(
|
//child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: [
|
children: [
|
||||||
Text("TODO Security")
|
FutureBuilder(
|
||||||
],
|
future: homieAppContext.clientAPI.alarmApi!.alarmGetAll(homieAppContext.homeId!),
|
||||||
),
|
builder: (context, AsyncSnapshot<List<AlarmModeDTO>?> snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
allAlarmModes = snapshot.data;
|
||||||
|
currentAlarmMode = allAlarmModes!.where((am) => am.activated!).first;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
width: size.width * 0.6,
|
||||||
|
height: size.height * 0.1,
|
||||||
|
decoration: alarmDecoration(currentAlarmMode!),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
var result = await showChangeAlarmModePopup(allAlarmModes!, homieAppContext, context, size);
|
||||||
|
if(result != null && currentAlarmMode!.id != result) {
|
||||||
|
// update current alarmMode
|
||||||
|
try{
|
||||||
|
var resultId = await homieAppContext.clientAPI.alarmApi!.alarmActivate(result);
|
||||||
|
if(resultId != null) {
|
||||||
|
//allAlarmModes!.firstWhere((alarmMode) => alarmMode.id == resultId);
|
||||||
|
setState(() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
debugPrint("An error occured during alarm mode activation - " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
if(currentAlarmMode!.type! != AlarmType.desarmed) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => AlarmDetailPage(
|
||||||
|
alarmMode: currentAlarmMode!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Text(currentAlarmMode!.name!),
|
||||||
|
Icon(getAlarmModeIcon(currentAlarmMode!)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||||
|
print('ConnectionState.none');
|
||||||
|
return Text("No data");
|
||||||
|
} else {
|
||||||
|
return Container(height: size.height * 0.2, child: LoadingCommon());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
Text("TODO Cameras"),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
//),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alarmDecoration(AlarmModeDTO alarmModeDTO) {
|
||||||
|
return BoxDecoration(
|
||||||
|
color: alarmModeDTO.activated! && alarmModeDTO.type == AlarmType.desarmed ? Colors.white : Colors.red.withOpacity(0.6),
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
border: Border.all(
|
||||||
|
color: kBackgroundSecondGrey.withOpacity(0.35),
|
||||||
|
width: 0.2,
|
||||||
|
),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: kMainColor.withOpacity(0.35),
|
||||||
|
//spreadRadius: 0.15,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: const Offset(0, 15), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -22,6 +22,8 @@ class Index with ChangeNotifier {
|
|||||||
return "Security";
|
return "Security";
|
||||||
case NavItemIcon.automations:
|
case NavItemIcon.automations:
|
||||||
return "Automations";
|
return "Automations";
|
||||||
|
case NavItemIcon.devices:
|
||||||
|
return "Devices";
|
||||||
case NavItemIcon.energy:
|
case NavItemIcon.energy:
|
||||||
return "Energy";
|
return "Energy";
|
||||||
case NavItemIcon.profile:
|
case NavItemIcon.profile:
|
||||||
|
|||||||
@ -4186,6 +4186,11 @@ components:
|
|||||||
nullable: true
|
nullable: true
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/Trigger'
|
$ref: '#/components/schemas/Trigger'
|
||||||
|
actions:
|
||||||
|
type: array
|
||||||
|
nullable: true
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Action'
|
||||||
devices:
|
devices:
|
||||||
type: array
|
type: array
|
||||||
nullable: true
|
nullable: true
|
||||||
@ -4442,6 +4447,11 @@ components:
|
|||||||
nullable: true
|
nullable: true
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
devices:
|
||||||
|
type: array
|
||||||
|
nullable: true
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/DeviceDetailDTO'
|
||||||
Condition:
|
Condition:
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:myhomie_app/Helpers/PushNotificationService.dart';
|
||||||
import 'package:myhomie_app/client.dart';
|
import 'package:myhomie_app/client.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ void main() async {
|
|||||||
print(localContext);
|
print(localContext);
|
||||||
} else {
|
} else {
|
||||||
print("NO LOCAL DB !");
|
print("NO LOCAL DB !");
|
||||||
|
localContext = HomieAppContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
initialRoute = isLogged ? '/home' : '/login';
|
initialRoute = isLogged ? '/home' : '/login';
|
||||||
@ -47,10 +50,13 @@ class MyApp extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> {
|
||||||
|
//FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
|
||||||
//HomieAppContext homieAppContext;
|
//HomieAppContext homieAppContext;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final pushNotificationService = PushNotificationService();
|
||||||
|
pushNotificationService.initialise(widget.homieAppContext, context: context);
|
||||||
return ChangeNotifierProvider<AppContext>(
|
return ChangeNotifierProvider<AppContext>(
|
||||||
create: (_) => AppContext(widget.homieAppContext),
|
create: (_) => AppContext(widget.homieAppContext),
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
|
|||||||
@ -5,8 +5,12 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import firebase_core
|
||||||
|
import firebase_messaging
|
||||||
import sqflite
|
import sqflite
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||||
|
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ Name | Type | Description | Notes
|
|||||||
**createdDate** | [**DateTime**](DateTime.md) | | [optional]
|
**createdDate** | [**DateTime**](DateTime.md) | | [optional]
|
||||||
**updatedDate** | [**DateTime**](DateTime.md) | | [optional]
|
**updatedDate** | [**DateTime**](DateTime.md) | | [optional]
|
||||||
**triggers** | [**List<Trigger>**](Trigger.md) | | [optional] [default to const []]
|
**triggers** | [**List<Trigger>**](Trigger.md) | | [optional] [default to const []]
|
||||||
|
**actions** | [**List<Action>**](Action.md) | | [optional] [default to const []]
|
||||||
**devices** | [**List<DeviceDetailDTO>**](DeviceDetailDTO.md) | | [optional] [default to const []]
|
**devices** | [**List<DeviceDetailDTO>**](DeviceDetailDTO.md) | | [optional] [default to const []]
|
||||||
**programmedMode** | [**OneOfProgrammedMode**](OneOfProgrammedMode.md) | | [optional]
|
**programmedMode** | [**OneOfProgrammedMode**](OneOfProgrammedMode.md) | | [optional]
|
||||||
**geolocalizedMode** | [**OneOfGeolocalizedMode**](OneOfGeolocalizedMode.md) | | [optional]
|
**geolocalizedMode** | [**OneOfGeolocalizedMode**](OneOfGeolocalizedMode.md) | | [optional]
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import 'package:mycore_api/api.dart';
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**triggers** | [**List<Trigger>**](Trigger.md) | | [optional] [default to const []]
|
**triggers** | [**List<Trigger>**](Trigger.md) | | [optional] [default to const []]
|
||||||
|
**actions** | [**List<Action>**](Action.md) | | [optional] [default to const []]
|
||||||
**devices** | [**List<DeviceDetailDTO>**](DeviceDetailDTO.md) | | [optional] [default to const []]
|
**devices** | [**List<DeviceDetailDTO>**](DeviceDetailDTO.md) | | [optional] [default to const []]
|
||||||
**programmedMode** | [**OneOfProgrammedMode**](OneOfProgrammedMode.md) | | [optional]
|
**programmedMode** | [**OneOfProgrammedMode**](OneOfProgrammedMode.md) | | [optional]
|
||||||
**geolocalizedMode** | [**OneOfGeolocalizedMode**](OneOfGeolocalizedMode.md) | | [optional]
|
**geolocalizedMode** | [**OneOfGeolocalizedMode**](OneOfGeolocalizedMode.md) | | [optional]
|
||||||
|
|||||||
@ -18,6 +18,7 @@ Name | Type | Description | Notes
|
|||||||
**conditions** | [**List<Condition>**](Condition.md) | | [optional] [default to const []]
|
**conditions** | [**List<Condition>**](Condition.md) | | [optional] [default to const []]
|
||||||
**actions** | [**List<Action>**](Action.md) | | [optional] [default to const []]
|
**actions** | [**List<Action>**](Action.md) | | [optional] [default to const []]
|
||||||
**devicesIds** | **List<String>** | | [optional] [default to const []]
|
**devicesIds** | **List<String>** | | [optional] [default to const []]
|
||||||
|
**devices** | [**List<DeviceDetailDTO>**](DeviceDetailDTO.md) | | [optional] [default to const []]
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ Name | Type | Description | Notes
|
|||||||
**conditions** | [**List<Condition>**](Condition.md) | | [optional] [default to const []]
|
**conditions** | [**List<Condition>**](Condition.md) | | [optional] [default to const []]
|
||||||
**actions** | [**List<Action>**](Action.md) | | [optional] [default to const []]
|
**actions** | [**List<Action>**](Action.md) | | [optional] [default to const []]
|
||||||
**devicesIds** | **List<String>** | | [optional] [default to const []]
|
**devicesIds** | **List<String>** | | [optional] [default to const []]
|
||||||
|
**devices** | [**List<DeviceDetailDTO>**](DeviceDetailDTO.md) | | [optional] [default to const []]
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ class AlarmModeDetailDTO {
|
|||||||
this.createdDate,
|
this.createdDate,
|
||||||
this.updatedDate,
|
this.updatedDate,
|
||||||
this.triggers = const [],
|
this.triggers = const [],
|
||||||
|
this.actions = const [],
|
||||||
this.devices = const [],
|
this.devices = const [],
|
||||||
this.programmedMode,
|
this.programmedMode,
|
||||||
this.geolocalizedMode,
|
this.geolocalizedMode,
|
||||||
@ -84,6 +85,8 @@ class AlarmModeDetailDTO {
|
|||||||
|
|
||||||
List<Trigger>? triggers;
|
List<Trigger>? triggers;
|
||||||
|
|
||||||
|
List<Action>? actions;
|
||||||
|
|
||||||
List<DeviceDetailDTO>? devices;
|
List<DeviceDetailDTO>? devices;
|
||||||
|
|
||||||
ProgrammedMode? programmedMode;
|
ProgrammedMode? programmedMode;
|
||||||
@ -102,6 +105,7 @@ class AlarmModeDetailDTO {
|
|||||||
other.createdDate == createdDate &&
|
other.createdDate == createdDate &&
|
||||||
other.updatedDate == updatedDate &&
|
other.updatedDate == updatedDate &&
|
||||||
other.triggers == triggers &&
|
other.triggers == triggers &&
|
||||||
|
other.actions == actions &&
|
||||||
other.devices == devices &&
|
other.devices == devices &&
|
||||||
other.programmedMode == programmedMode &&
|
other.programmedMode == programmedMode &&
|
||||||
other.geolocalizedMode == geolocalizedMode;
|
other.geolocalizedMode == geolocalizedMode;
|
||||||
@ -119,12 +123,13 @@ class AlarmModeDetailDTO {
|
|||||||
(createdDate == null ? 0 : createdDate!.hashCode) +
|
(createdDate == null ? 0 : createdDate!.hashCode) +
|
||||||
(updatedDate == null ? 0 : updatedDate!.hashCode) +
|
(updatedDate == null ? 0 : updatedDate!.hashCode) +
|
||||||
(triggers == null ? 0 : triggers!.hashCode) +
|
(triggers == null ? 0 : triggers!.hashCode) +
|
||||||
|
(actions == null ? 0 : actions!.hashCode) +
|
||||||
(devices == null ? 0 : devices!.hashCode) +
|
(devices == null ? 0 : devices!.hashCode) +
|
||||||
(programmedMode == null ? 0 : programmedMode!.hashCode) +
|
(programmedMode == null ? 0 : programmedMode!.hashCode) +
|
||||||
(geolocalizedMode == null ? 0 : geolocalizedMode!.hashCode);
|
(geolocalizedMode == null ? 0 : geolocalizedMode!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AlarmModeDetailDTO[id=$id, homeId=$homeId, name=$name, type=$type, activated=$activated, isDefault=$isDefault, notification=$notification, createdDate=$createdDate, updatedDate=$updatedDate, triggers=$triggers, devices=$devices, programmedMode=$programmedMode, geolocalizedMode=$geolocalizedMode]';
|
String toString() => 'AlarmModeDetailDTO[id=$id, homeId=$homeId, name=$name, type=$type, activated=$activated, isDefault=$isDefault, notification=$notification, createdDate=$createdDate, updatedDate=$updatedDate, triggers=$triggers, actions=$actions, devices=$devices, programmedMode=$programmedMode, geolocalizedMode=$geolocalizedMode]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final _json = <String, dynamic>{};
|
final _json = <String, dynamic>{};
|
||||||
@ -158,6 +163,9 @@ class AlarmModeDetailDTO {
|
|||||||
if (triggers != null) {
|
if (triggers != null) {
|
||||||
_json[r'triggers'] = triggers;
|
_json[r'triggers'] = triggers;
|
||||||
}
|
}
|
||||||
|
if (actions != null) {
|
||||||
|
_json[r'actions'] = actions;
|
||||||
|
}
|
||||||
if (devices != null) {
|
if (devices != null) {
|
||||||
_json[r'devices'] = devices;
|
_json[r'devices'] = devices;
|
||||||
}
|
}
|
||||||
@ -199,6 +207,7 @@ class AlarmModeDetailDTO {
|
|||||||
createdDate: mapDateTime(json, r'createdDate', ''),
|
createdDate: mapDateTime(json, r'createdDate', ''),
|
||||||
updatedDate: mapDateTime(json, r'updatedDate', ''),
|
updatedDate: mapDateTime(json, r'updatedDate', ''),
|
||||||
triggers: Trigger.listFromJson(json[r'triggers']) ?? const [],
|
triggers: Trigger.listFromJson(json[r'triggers']) ?? const [],
|
||||||
|
actions: Action.listFromJson(json[r'actions']) ?? const [],
|
||||||
devices: DeviceDetailDTO.listFromJson(json[r'devices']) ?? const [],
|
devices: DeviceDetailDTO.listFromJson(json[r'devices']) ?? const [],
|
||||||
programmedMode: ProgrammedMode.fromJson(json[r'programmedMode']),
|
programmedMode: ProgrammedMode.fromJson(json[r'programmedMode']),
|
||||||
geolocalizedMode: GeolocalizedMode.fromJson(json[r'geolocalizedMode']),
|
geolocalizedMode: GeolocalizedMode.fromJson(json[r'geolocalizedMode']),
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class AlarmModeDetailDTOAllOf {
|
|||||||
/// Returns a new [AlarmModeDetailDTOAllOf] instance.
|
/// Returns a new [AlarmModeDetailDTOAllOf] instance.
|
||||||
AlarmModeDetailDTOAllOf({
|
AlarmModeDetailDTOAllOf({
|
||||||
this.triggers = const [],
|
this.triggers = const [],
|
||||||
|
this.actions = const [],
|
||||||
this.devices = const [],
|
this.devices = const [],
|
||||||
this.programmedMode,
|
this.programmedMode,
|
||||||
this.geolocalizedMode,
|
this.geolocalizedMode,
|
||||||
@ -21,6 +22,8 @@ class AlarmModeDetailDTOAllOf {
|
|||||||
|
|
||||||
List<Trigger>? triggers;
|
List<Trigger>? triggers;
|
||||||
|
|
||||||
|
List<Action>? actions;
|
||||||
|
|
||||||
List<DeviceDetailDTO>? devices;
|
List<DeviceDetailDTO>? devices;
|
||||||
|
|
||||||
ProgrammedMode? programmedMode;
|
ProgrammedMode? programmedMode;
|
||||||
@ -30,6 +33,7 @@ class AlarmModeDetailDTOAllOf {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AlarmModeDetailDTOAllOf &&
|
bool operator ==(Object other) => identical(this, other) || other is AlarmModeDetailDTOAllOf &&
|
||||||
other.triggers == triggers &&
|
other.triggers == triggers &&
|
||||||
|
other.actions == actions &&
|
||||||
other.devices == devices &&
|
other.devices == devices &&
|
||||||
other.programmedMode == programmedMode &&
|
other.programmedMode == programmedMode &&
|
||||||
other.geolocalizedMode == geolocalizedMode;
|
other.geolocalizedMode == geolocalizedMode;
|
||||||
@ -38,18 +42,22 @@ class AlarmModeDetailDTOAllOf {
|
|||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(triggers == null ? 0 : triggers!.hashCode) +
|
(triggers == null ? 0 : triggers!.hashCode) +
|
||||||
|
(actions == null ? 0 : actions!.hashCode) +
|
||||||
(devices == null ? 0 : devices!.hashCode) +
|
(devices == null ? 0 : devices!.hashCode) +
|
||||||
(programmedMode == null ? 0 : programmedMode!.hashCode) +
|
(programmedMode == null ? 0 : programmedMode!.hashCode) +
|
||||||
(geolocalizedMode == null ? 0 : geolocalizedMode!.hashCode);
|
(geolocalizedMode == null ? 0 : geolocalizedMode!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AlarmModeDetailDTOAllOf[triggers=$triggers, devices=$devices, programmedMode=$programmedMode, geolocalizedMode=$geolocalizedMode]';
|
String toString() => 'AlarmModeDetailDTOAllOf[triggers=$triggers, actions=$actions, devices=$devices, programmedMode=$programmedMode, geolocalizedMode=$geolocalizedMode]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final _json = <String, dynamic>{};
|
final _json = <String, dynamic>{};
|
||||||
if (triggers != null) {
|
if (triggers != null) {
|
||||||
_json[r'triggers'] = triggers;
|
_json[r'triggers'] = triggers;
|
||||||
}
|
}
|
||||||
|
if (actions != null) {
|
||||||
|
_json[r'actions'] = actions;
|
||||||
|
}
|
||||||
if (devices != null) {
|
if (devices != null) {
|
||||||
_json[r'devices'] = devices;
|
_json[r'devices'] = devices;
|
||||||
}
|
}
|
||||||
@ -82,6 +90,7 @@ class AlarmModeDetailDTOAllOf {
|
|||||||
|
|
||||||
return AlarmModeDetailDTOAllOf(
|
return AlarmModeDetailDTOAllOf(
|
||||||
triggers: Trigger.listFromJson(json[r'triggers']) ?? const [],
|
triggers: Trigger.listFromJson(json[r'triggers']) ?? const [],
|
||||||
|
actions: Action.listFromJson(json[r'actions']) ?? const [],
|
||||||
devices: DeviceDetailDTO.listFromJson(json[r'devices']) ?? const [],
|
devices: DeviceDetailDTO.listFromJson(json[r'devices']) ?? const [],
|
||||||
programmedMode: ProgrammedMode.fromJson(json[r'programmedMode']),
|
programmedMode: ProgrammedMode.fromJson(json[r'programmedMode']),
|
||||||
geolocalizedMode: GeolocalizedMode.fromJson(json[r'geolocalizedMode']),
|
geolocalizedMode: GeolocalizedMode.fromJson(json[r'geolocalizedMode']),
|
||||||
|
|||||||
@ -23,6 +23,7 @@ class AutomationDetailDTO {
|
|||||||
this.conditions = const [],
|
this.conditions = const [],
|
||||||
this.actions = const [],
|
this.actions = const [],
|
||||||
this.devicesIds = const [],
|
this.devicesIds = const [],
|
||||||
|
this.devices = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
String? id;
|
String? id;
|
||||||
@ -63,6 +64,8 @@ class AutomationDetailDTO {
|
|||||||
|
|
||||||
List<String>? devicesIds;
|
List<String>? devicesIds;
|
||||||
|
|
||||||
|
List<DeviceDetailDTO>? devices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AutomationDetailDTO &&
|
bool operator ==(Object other) => identical(this, other) || other is AutomationDetailDTO &&
|
||||||
other.id == id &&
|
other.id == id &&
|
||||||
@ -74,7 +77,8 @@ class AutomationDetailDTO {
|
|||||||
other.triggers == triggers &&
|
other.triggers == triggers &&
|
||||||
other.conditions == conditions &&
|
other.conditions == conditions &&
|
||||||
other.actions == actions &&
|
other.actions == actions &&
|
||||||
other.devicesIds == devicesIds;
|
other.devicesIds == devicesIds &&
|
||||||
|
other.devices == devices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
@ -88,10 +92,11 @@ class AutomationDetailDTO {
|
|||||||
(triggers == null ? 0 : triggers!.hashCode) +
|
(triggers == null ? 0 : triggers!.hashCode) +
|
||||||
(conditions == null ? 0 : conditions!.hashCode) +
|
(conditions == null ? 0 : conditions!.hashCode) +
|
||||||
(actions == null ? 0 : actions!.hashCode) +
|
(actions == null ? 0 : actions!.hashCode) +
|
||||||
(devicesIds == null ? 0 : devicesIds!.hashCode);
|
(devicesIds == null ? 0 : devicesIds!.hashCode) +
|
||||||
|
(devices == null ? 0 : devices!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AutomationDetailDTO[id=$id, name=$name, active=$active, homeId=$homeId, createdDate=$createdDate, updatedDate=$updatedDate, triggers=$triggers, conditions=$conditions, actions=$actions, devicesIds=$devicesIds]';
|
String toString() => 'AutomationDetailDTO[id=$id, name=$name, active=$active, homeId=$homeId, createdDate=$createdDate, updatedDate=$updatedDate, triggers=$triggers, conditions=$conditions, actions=$actions, devicesIds=$devicesIds, devices=$devices]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final _json = <String, dynamic>{};
|
final _json = <String, dynamic>{};
|
||||||
@ -125,6 +130,9 @@ class AutomationDetailDTO {
|
|||||||
if (devicesIds != null) {
|
if (devicesIds != null) {
|
||||||
_json[r'devicesIds'] = devicesIds;
|
_json[r'devicesIds'] = devicesIds;
|
||||||
}
|
}
|
||||||
|
if (devices != null) {
|
||||||
|
_json[r'devices'] = devices;
|
||||||
|
}
|
||||||
return _json;
|
return _json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +167,7 @@ class AutomationDetailDTO {
|
|||||||
devicesIds: json[r'devicesIds'] is List
|
devicesIds: json[r'devicesIds'] is List
|
||||||
? (json[r'devicesIds'] as List).cast<String>()
|
? (json[r'devicesIds'] as List).cast<String>()
|
||||||
: const [],
|
: const [],
|
||||||
|
devices: DeviceDetailDTO.listFromJson(json[r'devices']) ?? const [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -17,6 +17,7 @@ class AutomationDetailDTOAllOf {
|
|||||||
this.conditions = const [],
|
this.conditions = const [],
|
||||||
this.actions = const [],
|
this.actions = const [],
|
||||||
this.devicesIds = const [],
|
this.devicesIds = const [],
|
||||||
|
this.devices = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
List<Trigger>? triggers;
|
List<Trigger>? triggers;
|
||||||
@ -27,12 +28,15 @@ class AutomationDetailDTOAllOf {
|
|||||||
|
|
||||||
List<String>? devicesIds;
|
List<String>? devicesIds;
|
||||||
|
|
||||||
|
List<DeviceDetailDTO>? devices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is AutomationDetailDTOAllOf &&
|
bool operator ==(Object other) => identical(this, other) || other is AutomationDetailDTOAllOf &&
|
||||||
other.triggers == triggers &&
|
other.triggers == triggers &&
|
||||||
other.conditions == conditions &&
|
other.conditions == conditions &&
|
||||||
other.actions == actions &&
|
other.actions == actions &&
|
||||||
other.devicesIds == devicesIds;
|
other.devicesIds == devicesIds &&
|
||||||
|
other.devices == devices;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
@ -40,10 +44,11 @@ class AutomationDetailDTOAllOf {
|
|||||||
(triggers == null ? 0 : triggers!.hashCode) +
|
(triggers == null ? 0 : triggers!.hashCode) +
|
||||||
(conditions == null ? 0 : conditions!.hashCode) +
|
(conditions == null ? 0 : conditions!.hashCode) +
|
||||||
(actions == null ? 0 : actions!.hashCode) +
|
(actions == null ? 0 : actions!.hashCode) +
|
||||||
(devicesIds == null ? 0 : devicesIds!.hashCode);
|
(devicesIds == null ? 0 : devicesIds!.hashCode) +
|
||||||
|
(devices == null ? 0 : devices!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AutomationDetailDTOAllOf[triggers=$triggers, conditions=$conditions, actions=$actions, devicesIds=$devicesIds]';
|
String toString() => 'AutomationDetailDTOAllOf[triggers=$triggers, conditions=$conditions, actions=$actions, devicesIds=$devicesIds, devices=$devices]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final _json = <String, dynamic>{};
|
final _json = <String, dynamic>{};
|
||||||
@ -59,6 +64,9 @@ class AutomationDetailDTOAllOf {
|
|||||||
if (devicesIds != null) {
|
if (devicesIds != null) {
|
||||||
_json[r'devicesIds'] = devicesIds;
|
_json[r'devicesIds'] = devicesIds;
|
||||||
}
|
}
|
||||||
|
if (devices != null) {
|
||||||
|
_json[r'devices'] = devices;
|
||||||
|
}
|
||||||
return _json;
|
return _json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +95,7 @@ class AutomationDetailDTOAllOf {
|
|||||||
devicesIds: json[r'devicesIds'] is List
|
devicesIds: json[r'devicesIds'] is List
|
||||||
? (json[r'devicesIds'] as List).cast<String>()
|
? (json[r'devicesIds'] as List).cast<String>()
|
||||||
: const [],
|
: const [],
|
||||||
|
devices: DeviceDetailDTO.listFromJson(json[r'devices']) ?? const [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
72
pubspec.lock
72
pubspec.lock
@ -9,6 +9,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "48.0.0"
|
version: "48.0.0"
|
||||||
|
_flutterfire_internals:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: _flutterfire_internals
|
||||||
|
sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.4"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -33,6 +41,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.10.0"
|
version: "2.10.0"
|
||||||
|
auto_size_text:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: auto_size_text
|
||||||
|
sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -209,6 +225,54 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.4"
|
version: "6.1.4"
|
||||||
|
firebase_core:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_core
|
||||||
|
sha256: "2e9324f719e90200dc7d3c4f5d2abc26052f9f2b995d3b6626c47a0dfe1c8192"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.15.0"
|
||||||
|
firebase_core_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_core_platform_interface
|
||||||
|
sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.8.0"
|
||||||
|
firebase_core_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_core_web
|
||||||
|
sha256: "0fd5c4b228de29b55fac38aed0d9e42514b3d3bd47675de52bf7f8fccaf922fa"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.6.0"
|
||||||
|
firebase_messaging:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: firebase_messaging
|
||||||
|
sha256: "8ac91d83a028eef050de770f1dc98421e215714d245f34de7b154d436676fbd0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "14.6.5"
|
||||||
|
firebase_messaging_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_messaging_platform_interface
|
||||||
|
sha256: b2995e3640efb646e9ebf0e2fa50dea84895f0746a31d7e3af0e5e009a533a1a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.5.4"
|
||||||
|
firebase_messaging_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: firebase_messaging_web
|
||||||
|
sha256: "5d8446a28339124a2cb4f57a6ca454a3aca7d0c5c0cdfa5707afb192f7c830a7"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.5.4"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -455,6 +519,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.0"
|
version: "5.1.0"
|
||||||
|
plugin_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: plugin_platform_interface
|
||||||
|
sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.5"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -41,6 +41,8 @@ dependencies:
|
|||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.0
|
cupertino_icons: ^1.0.0
|
||||||
|
auto_size_text: ^3.0.0
|
||||||
|
firebase_messaging: ^14.6.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
firebase_core
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user