Resolves #523 Change device name for integration

This commit is contained in:
Yegor Vialov 2020-05-03 13:36:40 +00:00
parent a87943da27
commit 536cbf9445
4 changed files with 130 additions and 113 deletions

View File

@ -23,12 +23,12 @@ class MobileAppIntegrationManager {
return '${HomeAssistant().userName}\'s ${DeviceInfoManager().model}';
}
static Future checkAppRegistration({bool forceRegister: false, bool showOkDialog: false}) {
static Future checkAppRegistration({bool showOkDialog: false}) {
Completer completer = Completer();
_appRegistrationData["device_name"] = ConnectionManager().mobileAppDeviceName ?? getDefaultDeviceName();
(_appRegistrationData["app_data"] as Map)["push_token"] = "${HomeAssistant().fcmToken}";
if (ConnectionManager().webhookId == null || forceRegister) {
Logger.d("Mobile app was not registered yet or need to be reseted. Registering...");
if (ConnectionManager().webhookId == null) {
Logger.d("Mobile app was not registered yet. Registering...");
var registrationData = Map.from(_appRegistrationData);
registrationData.addAll({
"device_id": "${DeviceInfoManager().unicDeviceId}",
@ -86,7 +86,7 @@ class MobileAppIntegrationManager {
registrationData = null;
}
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();
} else {
if (INTEGRATION_VERSION > ConnectionManager().appIntegrationVersion) {
@ -112,20 +112,7 @@ class MobileAppIntegrationManager {
_askToRegisterApp();
} else {
Logger.e("Error updating app registration: $e");
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.",
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");
},
)
));
_showError();
}
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() {
eventBus.fire(ShowPopupEvent(
Popup(
@ -149,18 +153,9 @@ class MobileAppIntegrationManager {
static void _askToRegisterApp() {
eventBus.fire(ShowPopupEvent(
Popup(
title: "App integration is broken",
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.",
positiveText: "Register now",
negativeText: "Cancel",
onPositive: () {
SharedPreferences.getInstance().then((prefs) {
prefs.remove("app-webhook-id");
ConnectionManager().webhookId = null;
checkAppRegistration();
});
},
RegisterAppPopup(
title: "Mobile App integration is missing",
body: "Looks like mobile app integration was removed from your Home Assistant or it needs to be updated.",
)
));
}

View File

@ -23,6 +23,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
StreamSubscription _fullReloadSubscription;
StreamSubscription _showPageSubscription;
BottomInfoBarController _bottomInfoBarController;
bool _popupShown = false;
int _previousViewCount;
bool _showLoginButton = false;
bool _preventAppRefresh = false;
@ -183,7 +184,12 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
}
if (_showPopupSubscription == null) {
_showPopupSubscription = eventBus.on<ShowPopupEvent>().listen((event){
event.popup.show(context);
if (!_popupShown) {
_popupShown = true;
event.popup.show(context).then((_){
_popupShown = false;
});
}
});
}
if (_serviceCallSubscription == null) {

View File

@ -14,9 +14,6 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
int _locationInterval = LocationManager().defaultUpdateIntervalMinutes;
bool _locationTrackingEnabled = false;
bool _wait = false;
String _deviceName = '';
bool _applyNameEnabled = false;
String _newDeviceName = '';
@override
void initState() {
@ -30,7 +27,6 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
await prefs.reload();
SharedPreferences.getInstance().then((prefs) {
setState(() {
_deviceName = _newDeviceName = ConnectionManager().mobileAppDeviceName ?? MobileAppIntegrationManager.getDefaultDeviceName();
_locationTrackingEnabled = prefs.getBool("location-enabled") ?? false;
_locationInterval = prefs.getInt("location-interval") ?? LocationManager().defaultUpdateIntervalMinutes;
if (_locationInterval % 5 != 0) {
@ -40,7 +36,7 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
});
}
void incLocationInterval() {
void _incLocationInterval() {
if (_locationInterval < 720) {
setState(() {
_locationInterval = _locationInterval + 5;
@ -48,7 +44,7 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
}
}
void decLocationInterval() {
void _decLocationInterval() {
if (_locationInterval > 5) {
setState(() {
_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 {
if (state) {
await LocationManager().updateDeviceLocation();
@ -156,37 +106,16 @@ class _IntegrationSettingsPageState extends State<IntegrationSettingsPage> {
FlatButton(
padding: EdgeInsets.all(0.0),
child: Text("-", style: Theme.of(context).textTheme.title),
onPressed: () => decLocationInterval(),
onPressed: () => _decLocationInterval(),
),
Text("$_locationInterval", style: Theme.of(context).textTheme.title),
FlatButton(
padding: EdgeInsets.all(0.0),
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)
),
)
]
);
}

View File

@ -10,7 +10,7 @@ class Popup {
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 = [];
buttons.add(FlatButton(
child: new Text("$positiveText"),
@ -33,7 +33,7 @@ class Popup {
));
}
// flutter defined function
showDialog(
return showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
@ -55,8 +55,8 @@ class TokenLoginPopup extends Popup {
final _tokenLoginFormKey = GlobalKey<FormState>();
@override
void show(BuildContext context) {
showDialog(
Future show(BuildContext context) {
return showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
@ -97,6 +97,13 @@ class TokenLoginPopup extends Popup {
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
Container(width: 10),
FlatButton(
child: Text('Login'),
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(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
)
),
Container(width: 10),
FlatButton(
child: Text('Create now'),
onPressed: () {
if (_tokenLoginFormKey.currentState.validate()) {
_tokenLoginFormKey.currentState.save();
}
},
),
],
)
],