Compare commits
	
		
			13 Commits
		
	
	
		
			1.1.0-beta
			...
			1.1.0-beta
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | fec3c525e1 | ||
|  | b1bbed6d80 | ||
|  | 13878cfc51 | ||
|  | be49180205 | ||
|  | c4a0b16553 | ||
|  | caacd5e9f4 | ||
|  | 5fa28abb6c | ||
|  | e0a28c0b59 | ||
|  | 096e714a04 | ||
|  | 78893ea01f | ||
|  | 90efb29be5 | ||
|  | fca323c56b | ||
|  | e5fe6af5f3 | 
| @@ -1,5 +1,6 @@ | |||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     package="com.keyboardcrumbs.hassclient"> |     package="com.keyboardcrumbs.hassclient" | ||||||
|  |     android:installLocation="auto"> | ||||||
|  |  | ||||||
|     <uses-feature android:name="android.hardware.touchscreen" |     <uses-feature android:name="android.hardware.touchscreen" | ||||||
|         android:required="false" /> |         android:required="false" /> | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ public class MainActivity extends FlutterActivity { | |||||||
|                                         updateTokenTask.execute(token); |                                         updateTokenTask.execute(token); | ||||||
|                                         result.success(token); |                                         result.success(token); | ||||||
|                                     } else { |                                     } else { | ||||||
|                                         result.error("fcm_error", task.getException().getMessage(), task.getException()); |                                         result.error("fcm_error", task.getException().getMessage(), null); | ||||||
|                                     } |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             }); |                             }); | ||||||
|   | |||||||
| @@ -185,8 +185,13 @@ void main() async { | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   WidgetsFlutterBinding.ensureInitialized(); |   WidgetsFlutterBinding.ensureInitialized(); | ||||||
|   await AppSettings().loadAppTheme(); |   await AppSettings().loadStartupSettings(); | ||||||
|   await Hive.initFlutter(); |   await Hive.initFlutter(); | ||||||
|  |   if (AppSettings().displayMode == DisplayMode.fullscreen) { | ||||||
|  |     SystemChrome.setEnabledSystemUIOverlays([]); | ||||||
|  |   } else { | ||||||
|  |     SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   runZoned(() { |   runZoned(() { | ||||||
|       runApp(new HAClientApp( |       runApp(new HAClientApp( | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
| part of '../main.dart'; | part of '../main.dart'; | ||||||
|  |  | ||||||
|  | enum DisplayMode {normal, fullscreen} | ||||||
|  |  | ||||||
| class AppSettings { | class AppSettings { | ||||||
|  |  | ||||||
|   static const DEFAULT_HIVE_BOX = 'defaultSettingsBox'; |   static const DEFAULT_HIVE_BOX = 'defaultSettingsBox'; | ||||||
| @@ -26,6 +28,7 @@ class AppSettings { | |||||||
|   String webhookId; |   String webhookId; | ||||||
|   double haVersion; |   double haVersion; | ||||||
|   bool scrollBadges; |   bool scrollBadges; | ||||||
|  |   DisplayMode displayMode; | ||||||
|   AppTheme appTheme; |   AppTheme appTheme; | ||||||
|   final int defaultLocationUpdateIntervalMinutes = 20; |   final int defaultLocationUpdateIntervalMinutes = 20; | ||||||
|   Duration locationUpdateInterval; |   Duration locationUpdateInterval; | ||||||
| @@ -34,9 +37,10 @@ class AppSettings { | |||||||
|   bool get isAuthenticated => longLivedToken != null; |   bool get isAuthenticated => longLivedToken != null; | ||||||
|   bool get isTempAuthenticated => tempToken != null; |   bool get isTempAuthenticated => tempToken != null; | ||||||
|  |  | ||||||
|   loadAppTheme() async { |   loadStartupSettings() async { | ||||||
|     SharedPreferences prefs = await SharedPreferences.getInstance(); |     SharedPreferences prefs = await SharedPreferences.getInstance(); | ||||||
|     appTheme = AppTheme.values[prefs.getInt('app-theme') ?? AppTheme.defaultTheme.index]; |     appTheme = AppTheme.values[prefs.getInt('app-theme') ?? AppTheme.defaultTheme.index]; | ||||||
|  |     displayMode = DisplayMode.values[prefs.getInt('display-mode') ?? DisplayMode.normal.index]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future load(bool full) async { |   Future load(bool full) async { | ||||||
| @@ -104,7 +108,7 @@ class AppSettings { | |||||||
|     Hive.box(DEFAULT_HIVE_BOX).delete(AUTH_TOKEN_KEY); |     Hive.box(DEFAULT_HIVE_BOX).delete(AUTH_TOKEN_KEY); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future saveLongLivedToken(token) async { |   void saveLongLivedToken(token) { | ||||||
|     longLivedToken = token; |     longLivedToken = token; | ||||||
|     tempToken = null; |     tempToken = null; | ||||||
|     Hive.box(DEFAULT_HIVE_BOX).put(AUTH_TOKEN_KEY, longLivedToken); |     Hive.box(DEFAULT_HIVE_BOX).put(AUTH_TOKEN_KEY, longLivedToken); | ||||||
|   | |||||||
| @@ -254,6 +254,7 @@ class ConnectionManager { | |||||||
|     sendSocketMessage(type: "auth/long_lived_access_token", additionalData: {"client_name": "HA Client app ${DateTime.now().millisecondsSinceEpoch}", "lifespan": 365}).then((data) { |     sendSocketMessage(type: "auth/long_lived_access_token", additionalData: {"client_name": "HA Client app ${DateTime.now().millisecondsSinceEpoch}", "lifespan": 365}).then((data) { | ||||||
|       Logger.d("Got long-lived token."); |       Logger.d("Got long-lived token."); | ||||||
|       AppSettings().saveLongLivedToken(data); |       AppSettings().saveLongLivedToken(data); | ||||||
|  |       completer.complete(); | ||||||
|     }).catchError((e) { |     }).catchError((e) { | ||||||
|       completer.completeError(HACException("Authentication error: $e", actions: [HAErrorAction.reload(title: "Retry"), HAErrorAction.loginAgain(title: "Relogin")])); |       completer.completeError(HACException("Authentication error: $e", actions: [HAErrorAction.reload(title: "Retry"), HAErrorAction.loginAgain(title: "Relogin")])); | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -139,7 +139,7 @@ class MobileAppIntegrationManager { | |||||||
|         positiveText: "Report issue", |         positiveText: "Report issue", | ||||||
|         negativeText: "Close", |         negativeText: "Close", | ||||||
|         onPositive: () { |         onPositive: () { | ||||||
|           Launcher.launchURLInBrowser("https://github.com/estevez-dev/ha_client/issues/new"); |           Launcher.launchURLInBrowser("https://github.com/estevez-dev/ha_client/issues/new/choose"); | ||||||
|         } |         } | ||||||
|       ) |       ) | ||||||
|     )); |     )); | ||||||
|   | |||||||
| @@ -1,18 +1,37 @@ | |||||||
| part of '../main.dart'; | part of '../main.dart'; | ||||||
|  |  | ||||||
| class FullScreenPage extends StatelessWidget { | class FullScreenPage extends StatefulWidget { | ||||||
|  |  | ||||||
|   final Widget child; |   final Widget child; | ||||||
|  |  | ||||||
|   const FullScreenPage({Key key, this.child}) : super(key: key); |   const FullScreenPage({Key key, this.child}) : super(key: key); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   _FullScreenPageState createState() => _FullScreenPageState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _FullScreenPageState extends State<FullScreenPage> { | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     SystemChrome.setEnabledSystemUIOverlays([]); | ||||||
|  |     super.initState(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return Container( |     return Container( | ||||||
|       color: Colors.black, |       color: Colors.black, | ||||||
|       child: Center( |       child: Center( | ||||||
|         child: this.child, |         child: this.widget.child, | ||||||
|       ), |       ), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void dispose() { | ||||||
|  |     SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); | ||||||
|  |     super.dispose(); | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -301,7 +301,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker | |||||||
|         title: Text("Report an issue"), |         title: Text("Report an issue"), | ||||||
|         onTap: () { |         onTap: () { | ||||||
|           Navigator.of(context).pop(); |           Navigator.of(context).pop(); | ||||||
|           Launcher.launchURLInBrowser("https://github.com/estevez-dev/ha_client/issues/new"); |           Launcher.launchURLInBrowser("https://github.com/estevez-dev/ha_client/issues/new/choose"); | ||||||
|         }, |         }, | ||||||
|       ), |       ), | ||||||
|       Divider(), |       Divider(), | ||||||
| @@ -484,7 +484,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker | |||||||
|               floating: true, |               floating: true, | ||||||
|               pinned: true, |               pinned: true, | ||||||
|               snap: false, |               snap: false, | ||||||
|               primary: true, |               primary: AppSettings().displayMode == DisplayMode.normal, | ||||||
|               title: Text(HomeAssistant().locationName ?? ""), |               title: Text(HomeAssistant().locationName ?? ""), | ||||||
|               actions: <Widget>[ |               actions: <Widget>[ | ||||||
|                 PopupMenuButton( |                 PopupMenuButton( | ||||||
| @@ -493,6 +493,15 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker | |||||||
|                     child: Icon(MaterialDesignIcons.getIconDataFromIconName( |                     child: Icon(MaterialDesignIcons.getIconDataFromIconName( | ||||||
|                         "mdi:dots-vertical"), color: Theme.of(context).primaryIconTheme.color) |                         "mdi:dots-vertical"), color: Theme.of(context).primaryIconTheme.color) | ||||||
|                   ), |                   ), | ||||||
|  |                   onSelected: (String val) { | ||||||
|  |                     if (val == "reload") { | ||||||
|  |                       _quickLoad(); | ||||||
|  |                     } else if (val == "logout")  { | ||||||
|  |                       HomeAssistant().logout().then((_) { | ||||||
|  |                         _quickLoad(); | ||||||
|  |                       }); | ||||||
|  |                     } | ||||||
|  |                   }, | ||||||
|                   itemBuilder: (BuildContext context) { |                   itemBuilder: (BuildContext context) { | ||||||
|                     List<PopupMenuEntry<String>> result = [ |                     List<PopupMenuEntry<String>> result = [ | ||||||
|                       PopupMenuItem<String>( |                       PopupMenuItem<String>( | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ class _PurchasePageState extends State<PurchasePage> { | |||||||
|     } else { |     } else { | ||||||
|       const Set<String> _kIds = {'one_time_support','just_few_bucks_per_year', 'app_fan_support_per_year', 'grateful_user_support_per_year'}; |       const Set<String> _kIds = {'one_time_support','just_few_bucks_per_year', 'app_fan_support_per_year', 'grateful_user_support_per_year'}; | ||||||
|       final ProductDetailsResponse response = await InAppPurchaseConnection.instance.queryProductDetails(_kIds); |       final ProductDetailsResponse response = await InAppPurchaseConnection.instance.queryProductDetails(_kIds); | ||||||
|       if (!response.notFoundIDs.isEmpty) { |       if (response.notFoundIDs.isNotEmpty) { | ||||||
|         Logger.d("Products not found: ${response.notFoundIDs}"); |         Logger.d("Products not found: ${response.notFoundIDs}"); | ||||||
|       } |       } | ||||||
|       _products = response.productDetails; |       _products = response.productDetails; | ||||||
| @@ -90,22 +90,6 @@ class _PurchasePageState extends State<PurchasePage> { | |||||||
|     } else { |     } else { | ||||||
|       body = _buildProducts(); |       body = _buildProducts(); | ||||||
|     } |     } | ||||||
|     body.add( |  | ||||||
|       Card( |  | ||||||
|         child: Container( |  | ||||||
|           height: 80, |  | ||||||
|           child: InkWell( |  | ||||||
|             child: Image.network('https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif'), |  | ||||||
|             onTap: () { |  | ||||||
|               Launcher.launchURLInCustomTab( |  | ||||||
|                 context: context, |  | ||||||
|                 url: 'https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ARWGETZD2D83Q&source=url' |  | ||||||
|               ); |  | ||||||
|             }, |  | ||||||
|           ) |  | ||||||
|         ), |  | ||||||
|       ) |  | ||||||
|     ); |  | ||||||
|     return new Scaffold( |     return new Scaffold( | ||||||
|       appBar: new AppBar( |       appBar: new AppBar( | ||||||
|         leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: (){ |         leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: (){ | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ class _AppSettingsPageState extends State<AppSettingsPage> { | |||||||
|  |  | ||||||
|   Widget _buildMenuItem(BuildContext context, IconData icon,String title, AppSettingsSection section) { |   Widget _buildMenuItem(BuildContext context, IconData icon,String title, AppSettingsSection section) { | ||||||
|     return ListTile( |     return ListTile( | ||||||
|       title: Text(title, style: Theme.of(context).textTheme.subhead), |       title: Text(title), | ||||||
|       leading: Icon(icon), |       leading: Icon(icon), | ||||||
|       trailing: Icon(Icons.keyboard_arrow_right), |       trailing: Icon(Icons.keyboard_arrow_right), | ||||||
|       onTap: () { |       onTap: () { | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> { | |||||||
|  |  | ||||||
|   AppTheme _currentTheme; |   AppTheme _currentTheme; | ||||||
|   bool _scrollBadges = false; |   bool _scrollBadges = false; | ||||||
|  |   DisplayMode _displayMode; | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   void initState() { |   void initState() { | ||||||
| @@ -25,7 +26,8 @@ class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> { | |||||||
|     await prefs.reload(); |     await prefs.reload(); | ||||||
|     SharedPreferences.getInstance().then((prefs) { |     SharedPreferences.getInstance().then((prefs) { | ||||||
|       setState(() { |       setState(() { | ||||||
|         _currentTheme = AppTheme.values[prefs.getInt("app-theme") ?? AppTheme.defaultTheme.index]; |         _currentTheme = AppTheme.values[prefs.getInt('app-theme') ?? AppTheme.defaultTheme.index]; | ||||||
|  |         _displayMode = DisplayMode.values[prefs.getInt('display-mode') ?? DisplayMode.normal.index]; | ||||||
|         _scrollBadges = prefs.getBool('scroll-badges') ?? true; |         _scrollBadges = prefs.getBool('scroll-badges') ?? true; | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| @@ -42,18 +44,34 @@ class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Future _saveOther() async { |   Future _saveBadgesSettings() async { | ||||||
|     SharedPreferences prefs = await SharedPreferences.getInstance(); |     SharedPreferences prefs = await SharedPreferences.getInstance(); | ||||||
|     AppSettings().scrollBadges = _scrollBadges; |     AppSettings().scrollBadges = _scrollBadges; | ||||||
|     await prefs.setBool('scroll-badges', _scrollBadges); |     await prefs.setBool('scroll-badges', _scrollBadges); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   Future _saveDisplayMode(DisplayMode mode) async { | ||||||
|  |     SharedPreferences prefs = await SharedPreferences.getInstance(); | ||||||
|  |     AppSettings().displayMode = mode; | ||||||
|  |     await prefs.setInt('display-mode', mode.index); | ||||||
|  |     if (mode == DisplayMode.fullscreen) { | ||||||
|  |       SystemChrome.setEnabledSystemUIOverlays([]); | ||||||
|  |     } else { | ||||||
|  |       SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   Map appThemeName = { |   Map appThemeName = { | ||||||
|     AppTheme.defaultTheme: 'Default', |     AppTheme.defaultTheme: 'Default', | ||||||
|     AppTheme.haTheme: 'Home Assistant theme', |     AppTheme.haTheme: 'Home Assistant theme', | ||||||
|     AppTheme.darkTheme: 'Dark theme' |     AppTheme.darkTheme: 'Dark theme' | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  |   Map DisplayModeName = { | ||||||
|  |     DisplayMode.normal: 'Normal', | ||||||
|  |     DisplayMode.fullscreen: 'Fullscreen' | ||||||
|  |   }; | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return ListView( |     return ListView( | ||||||
| @@ -93,7 +111,28 @@ class _LookAndFeelSettingsPageState extends State<LookAndFeelSettingsPage> { | |||||||
|               setState(() { |               setState(() { | ||||||
|                 _scrollBadges = val; |                 _scrollBadges = val; | ||||||
|               }); |               }); | ||||||
|               _saveOther(); |               _saveBadgesSettings(); | ||||||
|  |             }, | ||||||
|  |           ), | ||||||
|  |           Container(height: Sizes.doubleRowPadding), | ||||||
|  |           Text("Display mode:", style: Theme.of(context).textTheme.body2), | ||||||
|  |           Container(height: Sizes.rowPadding), | ||||||
|  |           DropdownButton<DisplayMode>( | ||||||
|  |             value: _displayMode, | ||||||
|  |             iconSize: 30.0, | ||||||
|  |             isExpanded: true, | ||||||
|  |             style: Theme.of(context).textTheme.title, | ||||||
|  |             items: DisplayMode.values.map((value) { | ||||||
|  |               return new DropdownMenuItem<DisplayMode>( | ||||||
|  |                 value: value, | ||||||
|  |                 child: Text('${DisplayModeName[value]}'), | ||||||
|  |               ); | ||||||
|  |             }).toList(), | ||||||
|  |             onChanged: (DisplayMode val) { | ||||||
|  |               setState(() { | ||||||
|  |                 _displayMode = val; | ||||||
|  |               }); | ||||||
|  |               _saveDisplayMode(val); | ||||||
|             }, |             }, | ||||||
|           ), |           ), | ||||||
|         ] |         ] | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| name: hass_client | name: hass_client | ||||||
| description: Home Assistant Android Client | description: Home Assistant Android Client | ||||||
|  |  | ||||||
| version: 1.1.0+1153 | version: 1.1.0+1156 | ||||||
|  |  | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user