-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathscaffold.dart
163 lines (146 loc) · 5.04 KB
/
scaffold.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../authentication/service/auth_provider.dart';
import '../generated/l10n.dart';
import '../resources/utils.dart';
import 'error_page.dart';
class AppScaffoldAction {
AppScaffoldAction({
this.icon,
this.route,
this.onPressed,
this.tooltip,
this.text,
this.items,
final bool disabled,
}) : disabled = disabled ?? false;
// Icon for the action button
final IconData icon;
// Route to push when the action button is pressed
final String route;
// Action that happens when the button is pressed. This overrides [route].
final void Function() onPressed;
// Action button tooltip text
final String tooltip;
// Action text. This overrides [icon].
final String text;
// Option-action map that should be specified if a popup menu is needed. It
// overrides [route].
final Map<String, void Function()> items;
// Whether the icon color should be disabled.
final bool disabled;
}
class AppScaffold extends StatelessWidget {
AppScaffold({
this.body,
this.title,
final List<AppScaffoldAction> actions,
this.floatingActionButton,
this.appBarBottom,
this.leading,
this.needsToBeAuthenticated = false,
}) : actions = actions ?? [];
final Widget body;
final Widget title;
final Widget floatingActionButton;
final Widget appBarBottom;
final List<AppScaffoldAction> actions;
final AppScaffoldAction leading;
final bool needsToBeAuthenticated;
Widget _widgetFromAction(final AppScaffoldAction action,
{@required final bool enableContent,
@required final BuildContext context}) {
if (action == null) {
return null;
}
final void Function() onPressed =
!enableContent || (action?.onPressed == null && action?.route == null)
? null
: action?.onPressed ??
() => Navigator.pushNamed(context, action?.route);
final icon = action.disabled
? Icon(action.icon ?? Icons.menu_outlined,
color: Theme.of(context).disabledColor)
: Icon(action.icon);
return action?.items != null
? PopupMenuButton<String>(
icon: icon,
tooltip: action.tooltip ?? action.text,
onSelected: (final selected) => action.items[selected](),
itemBuilder: (final BuildContext context) {
return action.items.keys
.map((final option) => PopupMenuItem(
value: option,
child: Text(option),
))
.toList();
},
)
: Tooltip(
message: action?.tooltip ?? action?.text ?? '',
child: action?.text != null
? ButtonTheme(
minWidth: 10,
child: TextButton(
child: Text(
action.text,
style: const TextStyle().apply(
color: Theme.of(context).primaryIconTheme.color),
),
onPressed: onPressed,
),
)
: IconButton(
icon: icon,
onPressed: onPressed,
),
);
}
@override
Widget build(final BuildContext context) {
final authProvider = Provider.of<AuthProvider>(context);
final bool isAuthenticated =
authProvider.isAuthenticated && !authProvider.isAnonymous;
final bool enableContent = !needsToBeAuthenticated || isAuthenticated;
return GestureDetector(
onTap: () {
// Remove current focus on tap
final currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
body: enableContent
? body ??
ErrorPage(
imgPath: 'assets/illustrations/undraw_under_construction.png',
errorMessage: S.current.messageUnderConstruction,
)
: ErrorPage(
imgPath: 'assets/illustrations/undraw_sign_in.png',
info: [TextSpan(text: S.current.warningAuthenticationNeeded)],
actionText: S.current.actionLogIn,
actionOnTap: () => Utils.signOut(context),
),
appBar: PreferredSize(
preferredSize: Size.fromHeight(appBarBottom != null ? 90 : 40),
child: AppBar(
title: title,
centerTitle: true,
bottom: appBarBottom,
backgroundColor: Theme.of(context).primaryColor,
toolbarOpacity: 0.8,
leading: _widgetFromAction(leading,
enableContent: enableContent, context: context),
actions: actions
.map((final action) => _widgetFromAction(action,
enableContent: enableContent, context: context))
.toList(),
),
),
floatingActionButton: floatingActionButton,
),
);
}
}