Resolves #523 Change device name for integration
This commit is contained in:
parent
a87943da27
commit
536cbf9445
@ -23,12 +23,12 @@ class MobileAppIntegrationManager {
|
|||||||
return '${HomeAssistant().userName}\'s ${DeviceInfoManager().model}';
|
return '${HomeAssistant().userName}\'s ${DeviceInfoManager().model}';
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future checkAppRegistration({bool forceRegister: false, bool showOkDialog: false}) {
|
static Future checkAppRegistration({bool showOkDialog: false}) {
|
||||||
Completer completer = Completer();
|
Completer completer = Completer();
|
||||||
_appRegistrationData["device_name"] = ConnectionManager().mobileAppDeviceName ?? getDefaultDeviceName();
|
_appRegistrationData["device_name"] = ConnectionManager().mobileAppDeviceName ?? getDefaultDeviceName();
|
||||||
(_appRegistrationData["app_data"] as Map)["push_token"] = "${HomeAssistant().fcmToken}";
|
(_appRegistrationData["app_data"] as Map)["push_token"] = "${HomeAssistant().fcmToken}";
|
||||||
if (ConnectionManager().webhookId == null || forceRegister) {
|
if (ConnectionManager().webhookId == null) {
|
||||||
Logger.d("Mobile app was not registered yet or need to be reseted. Registering...");
|
Logger.d("Mobile app was not registered yet. Registering...");
|
||||||
var registrationData = Map.from(_appRegistrationData);
|
var registrationData = Map.from(_appRegistrationData);
|
||||||
registrationData.addAll({
|
registrationData.addAll({
|
||||||
"device_id": "${DeviceInfoManager().unicDeviceId}",
|
"device_id": "${DeviceInfoManager().unicDeviceId}",
|
||||||
@ -86,7 +86,7 @@ class MobileAppIntegrationManager {
|
|||||||
registrationData = null;
|
registrationData = null;
|
||||||
}
|
}
|
||||||
if (registrationData == null || registrationData.isEmpty) {
|
if (registrationData == null || registrationData.isEmpty) {
|
||||||
Logger.d("No registration data in response. MobileApp integration was removed or broken");
|
Logger.e("No registration data in response. MobileApp integration was removed or broken");
|
||||||
_askToRegisterApp();
|
_askToRegisterApp();
|
||||||
} else {
|
} else {
|
||||||
if (INTEGRATION_VERSION > ConnectionManager().appIntegrationVersion) {
|
if (INTEGRATION_VERSION > ConnectionManager().appIntegrationVersion) {
|
||||||
@ -112,20 +112,7 @@ class MobileAppIntegrationManager {
|
|||||||
_askToRegisterApp();
|
_askToRegisterApp();
|
||||||
} else {
|
} else {
|
||||||
Logger.e("Error updating app registration: $e");
|
Logger.e("Error updating app registration: $e");
|
||||||
eventBus.fire(ShowPopupEvent(
|
_showError();
|
||||||
Popup(
|
|
||||||
title: "App integration is not working properly",
|
|
||||||
body: "Something wrong with HA Client integration on your Home Assistant server. Please report this issue.",
|
|
||||||
positiveText: "Report to GitHub",
|
|
||||||
negativeText: "Report to Discord",
|
|
||||||
onPositive: () {
|
|
||||||
Launcher.launchURLInBrowser("https://github.com/estevez-dev/ha_client/issues/new");
|
|
||||||
},
|
|
||||||
onNegative: () {
|
|
||||||
Launcher.launchURLInBrowser("https://discord.gg/AUzEvwn");
|
|
||||||
},
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
completer.complete();
|
completer.complete();
|
||||||
});
|
});
|
||||||
@ -133,6 +120,23 @@ class MobileAppIntegrationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _showError() {
|
||||||
|
eventBus.fire(ShowPopupEvent(
|
||||||
|
Popup(
|
||||||
|
title: "App integration is not working properly",
|
||||||
|
body: "Something wrong with HA Client integration on your Home Assistant server. Please report this issue. You can try to remove Mobile App integration from Home Assistant and restart server to fix this issue.",
|
||||||
|
positiveText: "Report to GitHub",
|
||||||
|
negativeText: "Report to Discord",
|
||||||
|
onPositive: () {
|
||||||
|
Launcher.launchURLInBrowser("https://github.com/estevez-dev/ha_client/issues/new");
|
||||||
|
},
|
||||||
|
onNegative: () {
|
||||||
|
Launcher.launchURLInBrowser("https://discord.gg/AUzEvwn");
|
||||||
|
},
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
static void _askToRemoveAndRegisterApp() {
|
static void _askToRemoveAndRegisterApp() {
|
||||||
eventBus.fire(ShowPopupEvent(
|
eventBus.fire(ShowPopupEvent(
|
||||||
Popup(
|
Popup(
|
||||||
@ -149,18 +153,9 @@ class MobileAppIntegrationManager {
|
|||||||
|
|
||||||
static void _askToRegisterApp() {
|
static void _askToRegisterApp() {
|
||||||
eventBus.fire(ShowPopupEvent(
|
eventBus.fire(ShowPopupEvent(
|
||||||
Popup(
|
RegisterAppPopup(
|
||||||
title: "App integration is broken",
|
title: "Mobile App integration is missing",
|
||||||
body: "Looks like app integration was removed from your Home Assistant or it needs to be updated. HA Client needs to be registered on your Home Assistant server to make it possible to use notifications and location tracking. Please remove 'Mobile App' integration for this device from your Home Assistant before registering and restart Home Assistant. Then go back here.",
|
body: "Looks like mobile app integration was removed from your Home Assistant or it needs to be updated.",
|
||||||
positiveText: "Register now",
|
|
||||||
negativeText: "Cancel",
|
|
||||||
onPositive: () {
|
|
||||||
SharedPreferences.getInstance().then((prefs) {
|
|
||||||
prefs.remove("app-webhook-id");
|
|
||||||
ConnectionManager().webhookId = null;
|
|
||||||
checkAppRegistration();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
|||||||
StreamSubscription _fullReloadSubscription;
|
StreamSubscription _fullReloadSubscription;
|
||||||
StreamSubscription _showPageSubscription;
|
StreamSubscription _showPageSubscription;
|
||||||
BottomInfoBarController _bottomInfoBarController;
|
BottomInfoBarController _bottomInfoBarController;
|
||||||
|
bool _popupShown = false;
|
||||||
int _previousViewCount;
|
int _previousViewCount;
|
||||||
bool _showLoginButton = false;
|
bool _showLoginButton = false;
|
||||||
bool _preventAppRefresh = false;
|
bool _preventAppRefresh = false;
|
||||||
@ -183,7 +184,12 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
|||||||
}
|
}
|
||||||
if (_showPopupSubscription == null) {
|
if (_showPopupSubscription == null) {
|
||||||
_showPopupSubscription = eventBus.on<ShowPopupEvent>().listen((event){
|
_showPopupSubscription = eventBus.on<ShowPopupEvent>().listen((event){
|
||||||
event.popup.show(context);
|
if (!_popupShown) {
|
||||||
|
_popupShown = true;
|
||||||
|
event.popup.show(context).then((_){
|
||||||
|
_popupShown = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (_serviceCallSubscription == null) {
|
if (_serviceCallSubscription == null) {
|
||||||
|
@ -14,9 +14,6 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
|
|||||||
int _locationInterval = LocationManager().defaultUpdateIntervalMinutes;
|
int _locationInterval = LocationManager().defaultUpdateIntervalMinutes;
|
||||||
bool _locationTrackingEnabled = false;
|
bool _locationTrackingEnabled = false;
|
||||||
bool _wait = false;
|
bool _wait = false;
|
||||||
String _deviceName = '';
|
|
||||||
bool _applyNameEnabled = false;
|
|
||||||
String _newDeviceName = '';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -30,7 +27,6 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
|
|||||||
await prefs.reload();
|
await prefs.reload();
|
||||||
SharedPreferences.getInstance().then((prefs) {
|
SharedPreferences.getInstance().then((prefs) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_deviceName = _newDeviceName = ConnectionManager().mobileAppDeviceName ?? MobileAppIntegrationManager.getDefaultDeviceName();
|
|
||||||
_locationTrackingEnabled = prefs.getBool("location-enabled") ?? false;
|
_locationTrackingEnabled = prefs.getBool("location-enabled") ?? false;
|
||||||
_locationInterval = prefs.getInt("location-interval") ?? LocationManager().defaultUpdateIntervalMinutes;
|
_locationInterval = prefs.getInt("location-interval") ?? LocationManager().defaultUpdateIntervalMinutes;
|
||||||
if (_locationInterval % 5 != 0) {
|
if (_locationInterval % 5 != 0) {
|
||||||
@ -40,7 +36,7 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void incLocationInterval() {
|
void _incLocationInterval() {
|
||||||
if (_locationInterval < 720) {
|
if (_locationInterval < 720) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_locationInterval = _locationInterval + 5;
|
_locationInterval = _locationInterval + 5;
|
||||||
@ -48,7 +44,7 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void decLocationInterval() {
|
void _decLocationInterval() {
|
||||||
if (_locationInterval > 5) {
|
if (_locationInterval > 5) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_locationInterval = _locationInterval - 5;
|
_locationInterval = _locationInterval - 5;
|
||||||
@ -56,52 +52,6 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
restart() {
|
|
||||||
eventBus.fire(ShowPopupEvent(
|
|
||||||
Popup(
|
|
||||||
title: "Are you sure you want to restart Home Assistant?",
|
|
||||||
body: "This will restart your Home Assistant server.",
|
|
||||||
positiveText: "Sure. Make it so",
|
|
||||||
negativeText: "What?? No!",
|
|
||||||
onPositive: () {
|
|
||||||
ConnectionManager().callService(domain: "homeassistant", service: "restart");
|
|
||||||
}
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
eventBus.fire(ShowPopupEvent(
|
|
||||||
Popup(
|
|
||||||
title: "Are you sure you want to STOP Home Assistant?",
|
|
||||||
body: "This will STOP your Home Assistant server. It means that your web interface as well as HA Client will not work untill you'll find a way to start your server using ssh or something.",
|
|
||||||
positiveText: "Sure. Make it so",
|
|
||||||
negativeText: "What?? No!",
|
|
||||||
onPositive: () {
|
|
||||||
ConnectionManager().callService(domain: "homeassistant", service: "stop");
|
|
||||||
},
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
updateRegistration() {
|
|
||||||
MobileAppIntegrationManager.checkAppRegistration(showOkDialog: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
resetRegistration() {
|
|
||||||
eventBus.fire(ShowPopupEvent(
|
|
||||||
Popup(
|
|
||||||
title: "Waaaait",
|
|
||||||
body: "If you don't whant to have duplicate integrations and entities in your HA for your current device, first you need to remove MobileApp integration from Integration settings in HA and restart server.",
|
|
||||||
positiveText: "Done it already",
|
|
||||||
negativeText: "Ok, I will",
|
|
||||||
onPositive: () {
|
|
||||||
MobileAppIntegrationManager.checkAppRegistration(showOkDialog: true, forceRegister: true);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
_switchLocationTrackingState(bool state) async {
|
_switchLocationTrackingState(bool state) async {
|
||||||
if (state) {
|
if (state) {
|
||||||
await LocationManager().updateDeviceLocation();
|
await LocationManager().updateDeviceLocation();
|
||||||
@ -156,37 +106,16 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
|
|||||||
FlatButton(
|
FlatButton(
|
||||||
padding: EdgeInsets.all(0.0),
|
padding: EdgeInsets.all(0.0),
|
||||||
child: Text("-", style: Theme.of(context).textTheme.title),
|
child: Text("-", style: Theme.of(context).textTheme.title),
|
||||||
onPressed: () => decLocationInterval(),
|
onPressed: () => _decLocationInterval(),
|
||||||
),
|
),
|
||||||
Text("$_locationInterval", style: Theme.of(context).textTheme.title),
|
Text("$_locationInterval", style: Theme.of(context).textTheme.title),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
padding: EdgeInsets.all(0.0),
|
padding: EdgeInsets.all(0.0),
|
||||||
child: Text("+", style: Theme.of(context).textTheme.title),
|
child: Text("+", style: Theme.of(context).textTheme.title),
|
||||||
onPressed: () => incLocationInterval(),
|
onPressed: () => _incLocationInterval(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
Divider(),
|
|
||||||
Text("Device name", style: Theme.of(context).textTheme.title),
|
|
||||||
Container(height: Sizes.rowPadding,),
|
|
||||||
TextField(
|
|
||||||
/*decoration: InputDecoration(
|
|
||||||
labelText: "Long-lived token"
|
|
||||||
),*/
|
|
||||||
controller: TextEditingController.fromValue(TextEditingValue(text: _newDeviceName)),
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
_newDeviceName = value;
|
|
||||||
_applyNameEnabled = _newDeviceName != _deviceName;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
),
|
|
||||||
Container(height: 6.0,),
|
|
||||||
RaisedButton(
|
|
||||||
color: Colors.blue,
|
|
||||||
onPressed: () => _applyNameEnabled ? updateRegistration() : null,
|
|
||||||
child: Text("Update device name", style: Theme.of(context).textTheme.button)
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ class Popup {
|
|||||||
|
|
||||||
Popup({@required this.title, @required this.body, this.positiveText, this.negativeText, this.onPositive, this.onNegative});
|
Popup({@required this.title, @required this.body, this.positiveText, this.negativeText, this.onPositive, this.onNegative});
|
||||||
|
|
||||||
void show(BuildContext context) {
|
Future show(BuildContext context) {
|
||||||
List<Widget> buttons = [];
|
List<Widget> buttons = [];
|
||||||
buttons.add(FlatButton(
|
buttons.add(FlatButton(
|
||||||
child: new Text("$positiveText"),
|
child: new Text("$positiveText"),
|
||||||
@ -33,7 +33,7 @@ class Popup {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
// flutter defined function
|
// flutter defined function
|
||||||
showDialog(
|
return showDialog(
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -55,8 +55,8 @@ class TokenLoginPopup extends Popup {
|
|||||||
final _tokenLoginFormKey = GlobalKey<FormState>();
|
final _tokenLoginFormKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void show(BuildContext context) {
|
Future show(BuildContext context) {
|
||||||
showDialog(
|
return showDialog(
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -97,6 +97,13 @@ class TokenLoginPopup extends Popup {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
FlatButton(
|
||||||
|
child: Text('Cancel'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Container(width: 10),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text('Login'),
|
child: Text('Login'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -105,13 +112,93 @@ class TokenLoginPopup extends Popup {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Container(width: 10),
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegisterAppPopup extends Popup {
|
||||||
|
|
||||||
|
RegisterAppPopup({String title, String body}): super(title: title, body: body);
|
||||||
|
|
||||||
|
final _tokenLoginFormKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future show(BuildContext context) {
|
||||||
|
return showDialog(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
// return object of type Dialog
|
||||||
|
return SimpleDialog(
|
||||||
|
title: new Text('${this.title}'),
|
||||||
|
children: <Widget>[
|
||||||
|
Form(
|
||||||
|
key: _tokenLoginFormKey,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 20, right: 20),
|
||||||
|
child: Text('${this.body}')
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
child: TextFormField(
|
||||||
|
initialValue: ConnectionManager().mobileAppDeviceName ?? MobileAppIntegrationManager.getDefaultDeviceName(),
|
||||||
|
onSaved: (newValue) {
|
||||||
|
String deviceName = newValue?.trim();
|
||||||
|
SharedPreferences.getInstance().then((prefs) {
|
||||||
|
prefs.remove("app-webhook-id");
|
||||||
|
prefs.setString('app-integration-device-name', deviceName);
|
||||||
|
ConnectionManager().webhookId = null;
|
||||||
|
ConnectionManager().mobileAppDeviceName = deviceName;
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
MobileAppIntegrationManager.checkAppRegistration();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'Device name*',
|
||||||
|
hintText: 'Please enter device name',
|
||||||
|
contentPadding: EdgeInsets.all(0),
|
||||||
|
hintStyle: Theme.of(context).textTheme.subhead.copyWith(
|
||||||
|
color: Theme.of(context).textTheme.overline.color
|
||||||
|
)
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (value.trim().isEmpty) {
|
||||||
|
return 'Device name can\'t be emty';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text('Cancel'),
|
child: Text('Cancel'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
|
Container(width: 10),
|
||||||
|
FlatButton(
|
||||||
|
child: Text('Create now'),
|
||||||
|
onPressed: () {
|
||||||
|
if (_tokenLoginFormKey.currentState.validate()) {
|
||||||
|
_tokenLoginFormKey.currentState.save();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user