mirror of
https://github.com/zoriya/Aeris.git
synced 2026-06-06 03:55:43 +00:00
Merge pull request #100 from AnonymusRaccoon/mobile_client_service_safety
Mobile client: service safety
This commit is contained in:
@@ -43,5 +43,8 @@
|
||||
"tryToConnect": "Try to connect",
|
||||
"routeToApi": "Route to API",
|
||||
"setupAPIRoute": "Setup API Route",
|
||||
"paramInheritTip": "To inherit parameters from previous actions, type '{' in the text field and tap on the choosen parameter"
|
||||
"paramInheritTip": "To inherit parameters from previous actions, type '{' in the text field and tap on the choosen parameter",
|
||||
"authenticatedToNoService": "You are not authenticated to any services.",
|
||||
"connectService": "Connect service",
|
||||
"cantEnablePipeline": "You can't enable this pipeline because it depends on a service that is not connected"
|
||||
}
|
||||
@@ -43,5 +43,8 @@
|
||||
"tryToConnect": "Tester la connection",
|
||||
"routeToApi": "Route de l'API",
|
||||
"setupAPIRoute": "Choisir la route de l'API",
|
||||
"paramInheritTip": "Afin d'hériter de variables venant d'actions précedentes, entrez '{' dans un champ et choisissez la valeur"
|
||||
"paramInheritTip": "Afin d'hériter de variables venant d'actions précedentes, entrez '{' dans un champ et choisissez la valeur",
|
||||
"authenticatedToNoService": "Aucun service n'est connecté",
|
||||
"connectService": "Connexion aux services",
|
||||
"cantEnablePipeline": "Impossible d'activer la pipeline car elle dépend d'un service qui n'est pas connecté"
|
||||
}
|
||||
@@ -50,9 +50,6 @@ class AerisAPI {
|
||||
deepLinkRoute = "$scheme://arthichaud.me";
|
||||
}
|
||||
|
||||
/// Name of the file that contains the JWT used for Aeris' API requestd
|
||||
static const String jwtFile = 'aeris_jwt.txt';
|
||||
|
||||
///ROUTES
|
||||
/// Registers new user in the database and connects it. Returns false if register failed
|
||||
Future<bool> signUpUser(String username, String password) async {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:aeris/src/models/service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:aeris/src/models/reaction.dart';
|
||||
import 'package:aeris/src/models/trigger.dart';
|
||||
@@ -58,4 +59,8 @@ class Pipeline {
|
||||
},
|
||||
'reactions': reactions.map((e) => e.toJSON()).toList()
|
||||
};
|
||||
|
||||
bool dependsOn(Service service) {
|
||||
return service == trigger.service || reactions.any((reaction) => reaction.service == service);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ class ServiceProvider extends ChangeNotifier {
|
||||
List<Service> get connectedServices => _connectedServices;
|
||||
|
||||
/// Get the services the user is not connected to
|
||||
List<Service> get availableServices => Service.all()
|
||||
List<Service> get disconnectedServices => Service.all()
|
||||
.where((element) => !_connectedServices.contains(element))
|
||||
.toList();
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:aeris/src/aeris_api.dart';
|
||||
import 'package:aeris/src/providers/pipelines_provider.dart';
|
||||
import 'package:aeris/src/providers/services_provider.dart';
|
||||
import 'package:aeris/src/views/service_page.dart';
|
||||
import 'package:aeris/src/views/setup_action_page.dart';
|
||||
import 'package:aeris/src/widgets/action_card_popup_menu.dart';
|
||||
import 'package:aeris/src/widgets/aeris_card_page.dart';
|
||||
@@ -28,7 +30,8 @@ class PipelineDetailPage extends StatefulWidget {
|
||||
class _PipelineDetailPageState extends State<PipelineDetailPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
Consumer<PipelineProvider>(builder: (context, provider, _) {
|
||||
Consumer<ServiceProvider>(builder: (context, services, _) {
|
||||
return Consumer<PipelineProvider>(builder: (context, provider, _) {
|
||||
Pipeline pipeline = widget.pipeline;
|
||||
|
||||
final cardHeader = Row(
|
||||
@@ -67,11 +70,24 @@ class _PipelineDetailPageState extends State<PipelineDetailPage> {
|
||||
width: 60,
|
||||
value: pipeline.enabled,
|
||||
onToggle: (value) {
|
||||
setState(() {
|
||||
pipeline.enabled = !pipeline.enabled;
|
||||
GetIt.I<AerisAPI>().editPipeline(pipeline);
|
||||
provider.sortPipelines();
|
||||
});
|
||||
if (!pipeline.enabled && services.disconnectedServices.any(
|
||||
(service) => pipeline.dependsOn(service))
|
||||
) {
|
||||
showDialog<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => WarningDialog(
|
||||
message: AppLocalizations.of(context).cantEnablePipeline,
|
||||
onAccept: () => showAerisCardPage(context, (_) => const ServicePage()),
|
||||
actionButtonColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||
warnedAction: AppLocalizations.of(context).connectService)
|
||||
);
|
||||
} else {
|
||||
setState(() {
|
||||
pipeline.enabled = !pipeline.enabled;
|
||||
GetIt.I<AerisAPI>().editPipeline(pipeline);
|
||||
provider.sortPipelines();
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -184,4 +200,5 @@ class _PipelineDetailPageState extends State<PipelineDetailPage> {
|
||||
]),
|
||||
));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ class ServicePage extends StatelessWidget {
|
||||
warnedAction: AppLocalizations.of(context).disconnect)),
|
||||
context),
|
||||
...getServiceGroup(
|
||||
serviceProvider.availableServices,
|
||||
serviceProvider.disconnectedServices,
|
||||
AppLocalizations.of(context).available,
|
||||
const Icon(Icons.connect_without_contact, color: Colors.green),
|
||||
(Service service) {
|
||||
|
||||
@@ -3,6 +3,9 @@ import 'package:aeris/src/models/action_template.dart';
|
||||
import 'package:aeris/src/aeris_api.dart';
|
||||
import 'package:aeris/src/models/reaction.dart';
|
||||
import 'package:aeris/src/models/trigger.dart';
|
||||
import 'package:aeris/src/providers/services_provider.dart';
|
||||
import 'package:aeris/src/views/service_page.dart';
|
||||
import 'package:aeris/src/widgets/colored_clickable_card.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:aeris/src/models/action.dart' as aeris;
|
||||
import 'package:aeris/src/models/service.dart';
|
||||
@@ -11,6 +14,7 @@ import 'package:aeris/src/widgets/aeris_card_page.dart';
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:skeleton_loader/skeleton_loader.dart';
|
||||
|
||||
///Page to setup an action
|
||||
@@ -43,13 +47,11 @@ class _SetupActionPageState extends State<SetupActionPage> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
serviceState = widget.action.service;
|
||||
availableActions =
|
||||
GetIt.I<AerisAPI>().getActionsFor(serviceState!, widget.action);
|
||||
availableActions = GetIt.I<AerisAPI>().getActionsFor(serviceState!, widget.action);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Widget serviceDropdown = DropdownButton<Service>(
|
||||
Widget serviceDropdown(List<Service> services) {
|
||||
return DropdownButton<Service>(
|
||||
value: serviceState,
|
||||
elevation: 8,
|
||||
underline: Container(),
|
||||
@@ -60,7 +62,7 @@ class _SetupActionPageState extends State<SetupActionPage> {
|
||||
GetIt.I<AerisAPI>().getActionsFor(service!, widget.action);
|
||||
});
|
||||
},
|
||||
items: Service.all().map<DropdownMenuItem<Service>>((Service service) {
|
||||
items: services.map<DropdownMenuItem<Service>>((Service service) {
|
||||
return DropdownMenuItem<Service>(
|
||||
value: service,
|
||||
child: Row(children: [
|
||||
@@ -74,20 +76,42 @@ class _SetupActionPageState extends State<SetupActionPage> {
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
var cardShape = const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)));
|
||||
|
||||
return AerisCardPage(
|
||||
body: Padding(
|
||||
body: Consumer<ServiceProvider>(builder: (context, services, _) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20, left: 10, right: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.action is Trigger
|
||||
? AppLocalizations.of(context).setupTrigger
|
||||
: AppLocalizations.of(context).setupReaction,
|
||||
children: services.connectedServices.isEmpty ?
|
||||
([
|
||||
Text(AppLocalizations.of(context).authenticatedToNoService,
|
||||
style: const TextStyle(
|
||||
fontSize: 25,
|
||||
)
|
||||
),
|
||||
Padding(padding: const EdgeInsets.all(30),
|
||||
child: ColoredClickableCard(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondaryContainer,
|
||||
text:AppLocalizations.of(context).connectService,
|
||||
onTap: () => showAerisCardPage(
|
||||
context, (_) => const ServicePage()).then((value) => setState((){}) //TODO check, might be useless
|
||||
)
|
||||
)
|
||||
)
|
||||
])
|
||||
: [
|
||||
Text(widget.action is Trigger
|
||||
? AppLocalizations.of(context).setupTrigger
|
||||
: AppLocalizations.of(context).setupReaction,
|
||||
style: const TextStyle(
|
||||
fontSize: 25,
|
||||
)),
|
||||
@@ -106,7 +130,7 @@ class _SetupActionPageState extends State<SetupActionPage> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight, child: serviceDropdown),
|
||||
alignment: Alignment.centerRight, child: serviceDropdown(services.connectedServices)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -175,6 +199,6 @@ class _SetupActionPageState extends State<SetupActionPage> {
|
||||
]
|
||||
],
|
||||
),
|
||||
));
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,9 @@ class _AnimatedBackgroundState extends State<AnimatedBackground> with TickerProv
|
||||
});
|
||||
|
||||
Timer(const Duration(milliseconds: 2500), () {
|
||||
topAnimController.forward();
|
||||
try {
|
||||
topAnimController.forward();
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
bottomAnimController.forward();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:aeris/main.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
@@ -11,13 +12,18 @@ class WarningDialog extends StatelessWidget {
|
||||
|
||||
///The action to execute once the warning was accepted
|
||||
final void Function() onAccept;
|
||||
///Color of the button that trigger the action
|
||||
Color? actionButtonColor;
|
||||
|
||||
const WarningDialog(
|
||||
WarningDialog(
|
||||
{Key? key,
|
||||
required this.message,
|
||||
this.actionButtonColor,
|
||||
required this.onAccept,
|
||||
required this.warnedAction})
|
||||
: super(key: key);
|
||||
: super(key: key) {
|
||||
actionButtonColor ??= Theme.of(Aeris.materialKey.currentContext!).colorScheme.error;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -28,27 +34,24 @@ class WarningDialog extends StatelessWidget {
|
||||
)
|
||||
),
|
||||
content: Text(message),
|
||||
actionsAlignment: MainAxisAlignment.spaceEvenly,
|
||||
actionsOverflowDirection: VerticalDirection.up,
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).colorScheme.primaryContainer),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(AppLocalizations.of(context).cancel),
|
||||
),
|
||||
ElevatedButton(
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Theme.of(context).colorScheme.error),
|
||||
primary: actionButtonColor),
|
||||
onPressed: () => {
|
||||
Navigator.pop(context),
|
||||
onAccept(),
|
||||
},
|
||||
child: Text(warnedAction)
|
||||
)
|
||||
],
|
||||
),
|
||||
]);
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user