Line data Source code
1 : import 'dart:io';
2 : import 'package:mvvm_builder/mvvm_builder.dart';
3 :
4 : import 'package:flutter/cupertino.dart';
5 : import 'package:flutter/material.dart';
6 : import 'package:flutter/services.dart';
7 : import 'package:pal/src/database/entity/helper/helper_entity.dart';
8 : import 'package:pal/src/database/entity/helper/helper_trigger_type.dart';
9 : import 'package:pal/src/injectors/editor_app/editor_app_injector.dart';
10 : import 'package:pal/src/pal_navigator_observer.dart';
11 : import 'package:pal/src/services/editor/helper/helper_editor_service.dart';
12 : import 'package:pal/src/theme.dart';
13 : import 'package:pal/src/ui/editor/pages/helper_editor/editor_router.dart';
14 : import 'package:pal/src/ui/editor/widgets/snackbar_mixin.dart';
15 : import 'package:pal/src/ui/editor/pages/helper_editor/helper_editor.dart';
16 : import 'package:pal/src/ui/shared/utilities/element_finder.dart';
17 : import 'package:pal/src/router.dart';
18 : import 'package:pal/src/ui/editor/pages/helper_editor/helper_editor_factory.dart';
19 :
20 : import 'helper_details_model.dart';
21 : import 'helper_details_presenter.dart';
22 :
23 : abstract class HelperDetailsInterface {
24 :
25 : Future showDeleteDialog(
26 : HelperDetailsPresenter presenter,
27 : );
28 :
29 : Future onDialogCancel(
30 : BuildContext context,
31 : );
32 :
33 : Future onDialogApprove(
34 : BuildContext context,
35 : HelperDetailsPresenter presenter,
36 : );
37 :
38 : void showMessage(String message, bool success);
39 :
40 : void popBackToList();
41 :
42 : void launchHelperEditor(String routename);
43 : }
44 :
45 : class HelperDetailsComponentArguments {
46 :
47 : final GlobalKey<NavigatorState> hostedAppNavigatorKey;
48 : final HelperEntity helper;
49 : final String pageId, pageRouteName;
50 :
51 2 : HelperDetailsComponentArguments(
52 : this.hostedAppNavigatorKey,
53 : this.helper,
54 : this.pageId,
55 : this.pageRouteName
56 : );
57 : }
58 :
59 : class HelperDetailsComponent extends StatelessWidget with SnackbarMixin implements HelperDetailsInterface {
60 :
61 : final EditorHelperService testHelperService;
62 :
63 : final HelperDetailsComponentArguments arguments;
64 :
65 : final _mvvmPageBuilder = MVVMPageBuilder<HelperDetailsPresenter, HelperDetailsModel>();
66 :
67 : final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
68 :
69 1 : HelperDetailsComponent({
70 : Key key,
71 : @required this.arguments,
72 : this.testHelperService,
73 1 : }) : super(key: key);
74 :
75 1 : @override
76 : Widget build(BuildContext context) {
77 2 : return _mvvmPageBuilder.build(
78 1 : key: ValueKey('pal_HelperDetailsComponent_Builder'),
79 : context: context,
80 2 : presenterBuilder: (context) => HelperDetailsPresenter(
81 1 : HelperDetailsModel(),
82 : this,
83 1 : this.testHelperService ?? EditorInjector.of(context).helperService,
84 1 : this.arguments,
85 : ),
86 1 : builder: (context, presenter, model) {
87 1 : return Scaffold(
88 1 : key: _scaffoldKey,
89 2 : appBar: _buildAppBar(context.buildContext, presenter, model),
90 2 : body: _buildBody(context.buildContext, model),
91 : );
92 : },
93 : );
94 : }
95 :
96 1 : AppBar _buildAppBar(BuildContext context, HelperDetailsPresenter presenter,
97 : HelperDetailsModel model) {
98 1 : return AppBar(
99 : elevation: 0,
100 : backgroundColor: Colors.transparent,
101 1 : iconTheme: IconThemeData(
102 3 : color: PalTheme.of(context).colors.dark,
103 : ),
104 1 : title: Text(
105 1 : model?.helperName ?? 'Detail',
106 1 : style: TextStyle(
107 3 : color: PalTheme.of(context).colors.dark,
108 : ),
109 : ),
110 1 : actions: [
111 1 : CupertinoButton(
112 1 : key: ValueKey('editHelper'),
113 4 : disabledColor: PalTheme.of(context).colors.dark.withOpacity(0.7),
114 1 : onPressed: presenter.callEditHelper,
115 1 : child: Icon(
116 : Icons.edit,
117 3 : color: PalTheme.of(context).colors.dark,
118 : ),
119 : ),
120 1 : CupertinoButton(
121 1 : key: ValueKey('deleteHelper'),
122 4 : disabledColor: PalTheme.of(context).colors.black.withOpacity(0.7),
123 1 : onPressed: (!model.isDeleting)
124 2 : ? () => this.showDeleteDialog(presenter)
125 : : null,
126 1 : child: (!model.isDeleting)
127 1 : ? Icon(
128 : Icons.delete,
129 3 : color: PalTheme.of(context).colors.dark,
130 : )
131 1 : : SizedBox(
132 : height: 20.0,
133 : width: 20.0,
134 1 : child: Opacity(
135 : opacity: 0.7,
136 1 : child: CircularProgressIndicator(
137 : strokeWidth: 2.0,
138 : ),
139 : ),
140 : ),
141 : )
142 : ],
143 : );
144 : }
145 :
146 1 : _buildBody(BuildContext context, HelperDetailsModel model) {
147 1 : return SafeArea(
148 1 : child: Container(
149 : width: double.infinity,
150 1 : child: SingleChildScrollView(
151 1 : child: Column(
152 1 : children: [
153 1 : _buildLine(
154 : 'Available on version',
155 3 : '${model.helperMinVer ?? 'first'} - ${model.helperMaxVer ?? 'latest'}',
156 : context,
157 1 : ValueKey('versions'),
158 : ),
159 1 : _buildLine(
160 : 'Trigger mode',
161 2 : getHelperTriggerTypeDescription(model.helperTriggerType),
162 : context,
163 1 : ValueKey('triggerMode'),
164 : )
165 : ],
166 : ),
167 : ),
168 : ),
169 : );
170 : }
171 :
172 1 : _buildLine(
173 : String label,
174 : String text,
175 : BuildContext context,
176 : Key key,
177 : ) {
178 1 : TextStyle textStyle = TextStyle(
179 3 : color: PalTheme.of(context).colors.dark,
180 : );
181 1 : return DecoratedBox(
182 1 : decoration: BoxDecoration(
183 1 : border: Border(
184 1 : bottom: BorderSide(
185 4 : color: PalTheme.of(context).colors.dark.withAlpha(40),
186 : ),
187 : ),
188 : ),
189 1 : child: Padding(
190 : padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 20.0),
191 1 : child: Row(
192 : mainAxisAlignment: MainAxisAlignment.spaceBetween,
193 1 : children: [
194 1 : Text(
195 : label,
196 1 : style: textStyle.copyWith(fontWeight: FontWeight.bold),
197 : ),
198 1 : Text(
199 : text,
200 : style: textStyle,
201 : key: key,
202 : ),
203 : ],
204 : ),
205 : ),
206 : );
207 : }
208 :
209 1 : @override
210 : Future showDeleteDialog(HelperDetailsPresenter presenter) {
211 : String title = 'Warning';
212 : String content = 'Are you sure to delete this helper ?';
213 : String cancelAction = 'Cancel';
214 : String yesAction = 'Yes 👍';
215 :
216 1 : if (Platform.isIOS) {
217 0 : return showCupertinoDialog(
218 0 : context: _scaffoldKey.currentContext,
219 0 : builder: (context) {
220 0 : return CupertinoAlertDialog(
221 0 : key: ValueKey('pal_HelperDetailsComponent_DeleteDialog_iOS'),
222 0 : title: Text(title),
223 0 : content: Text(content),
224 0 : actions: <Widget>[
225 0 : CupertinoDialogAction(
226 0 : key: ValueKey(
227 : 'pal_HelperDetailsComponent_DeleteDialog_iOS_Cancel'),
228 0 : child: Text(cancelAction),
229 0 : onPressed: () => this.onDialogCancel(context),
230 : ),
231 0 : CupertinoDialogAction(
232 0 : key: ValueKey(
233 : 'pal_HelperDetailsComponent_DeleteDialog_iOS_Approve'),
234 0 : child: Text(
235 : yesAction,
236 0 : style: TextStyle(color: Colors.redAccent),
237 : ),
238 0 : onPressed: () => this.onDialogApprove(context, presenter),
239 : ),
240 : ],
241 : );
242 : },
243 : );
244 : } else {
245 1 : return showDialog(
246 2 : context: _scaffoldKey.currentContext,
247 1 : builder: (context) {
248 1 : return AlertDialog(
249 1 : key: ValueKey('pal_HelperDetailsComponent_DeleteDialog_Android'),
250 1 : title: Text(title),
251 1 : content: Text(content),
252 1 : actions: <Widget>[
253 1 : FlatButton(
254 1 : key: ValueKey(
255 : 'pal_HelperDetailsComponent_DeleteDialog_Android_Cancel'),
256 1 : child: Text(cancelAction),
257 2 : onPressed: () => this.onDialogCancel(context),
258 : ),
259 1 : FlatButton(
260 1 : key: ValueKey(
261 : 'pal_HelperDetailsComponent_DeleteDialog_Android_Approve'),
262 1 : child: Text(
263 : yesAction,
264 1 : style: TextStyle(color: Colors.redAccent),
265 : ),
266 2 : onPressed: () => this.onDialogApprove(context, presenter),
267 : ),
268 : ],
269 : );
270 : },
271 : );
272 : }
273 : }
274 :
275 : @override
276 1 : Future onDialogApprove(
277 : BuildContext context,
278 : HelperDetailsPresenter presenter,
279 : ) async {
280 1 : HapticFeedback.selectionClick();
281 2 : Navigator.of(context).pop(true);
282 2 : await presenter.deleteHelper();
283 : }
284 :
285 : @override
286 1 : Future onDialogCancel(
287 : BuildContext context,
288 : ) async {
289 1 : HapticFeedback.selectionClick();
290 2 : Navigator.of(context).pop(false);
291 : }
292 :
293 1 : @override
294 : showMessage(String message, bool success) {
295 2 : return showSnackbarMessage(_scaffoldKey, message, success);
296 : }
297 :
298 1 : @override
299 : void popBackToList() {
300 3 : Navigator.pop(_scaffoldKey.currentContext, HelperDetailsPopState.deleted);
301 : }
302 :
303 0 : @override
304 : void launchHelperEditor(String routename) {
305 0 : new EditorRouter(arguments.hostedAppNavigatorKey).editHelper(routename, arguments.helper);
306 : // Go back
307 0 : Navigator.of(_scaffoldKey.currentContext)
308 0 : .pop(HelperDetailsPopState.editorOpened);
309 : }
310 : }
|