1
- import 'package:flutter/gestures.dart' ;
2
1
import 'package:flutter/material.dart' ;
3
2
import 'package:flutter/rendering.dart' ;
4
3
import 'package:flutter_hooks/flutter_hooks.dart' ;
@@ -59,6 +58,7 @@ class _MainPage extends HookWidget {
59
58
@override
60
59
Widget build (BuildContext context) {
61
60
useNavigator ([loginNavigator, detailsNavigator]);
61
+
62
62
final state = useObservableState (
63
63
MainModelStateData (),
64
64
() => model.getState (),
@@ -72,6 +72,9 @@ class _MainPage extends HookWidget {
72
72
(current, newState) => (current as MainModelEventData ).equals (newState),
73
73
).value;
74
74
75
+ final expandedState = useState (true );
76
+ final controller = useScrollController ();
77
+
75
78
useEffect (() {
76
79
model.initState ();
77
80
}, []);
@@ -96,12 +99,19 @@ class _MainPage extends HookWidget {
96
99
model: model,
97
100
snippets: snippets ?? List .empty (),
98
101
filter: state.filter ?? SnippetFilter (),
102
+ controller: controller,
103
+ expanded: expandedState.value,
104
+ onExpandChange: (expanded) => expandedState.value = expanded,
99
105
);
100
106
},
101
107
),
102
108
floatingActionButton: FloatingActionButton .small (
103
109
onPressed: () {
104
- // TODO Scroll to top
110
+ controller.animateTo (
111
+ 0.0 ,
112
+ duration: const Duration (seconds: 1 ),
113
+ curve: const ElasticInCurve (),
114
+ );
105
115
},
106
116
tooltip: 'Scroll to top' ,
107
117
backgroundColor: ColorStyles .surfacePrimary (),
@@ -114,31 +124,40 @@ class _MainPage extends HookWidget {
114
124
}
115
125
}
116
126
117
- class _MainPageData extends StatelessWidget {
118
- const _MainPageData ({
119
- Key ? key,
120
- required this .navigator,
121
- required this .model,
122
- required this .snippets,
123
- required this .filter,
124
- }) : super (key: key);
127
+ typedef ExpandChangeListener = Function (bool );
128
+
129
+ class _MainPageData extends HookWidget {
130
+ const _MainPageData (
131
+ {Key ? key,
132
+ required this .navigator,
133
+ required this .model,
134
+ required this .snippets,
135
+ required this .filter,
136
+ required this .controller,
137
+ required this .expanded,
138
+ required this .onExpandChange})
139
+ : super (key: key);
125
140
126
141
final DetailsNavigator navigator;
127
142
final MainModelBridge model;
128
143
final List <Snippet > snippets;
129
144
final SnippetFilter filter;
145
+ final ScrollController controller;
146
+ final bool expanded;
147
+ final ExpandChangeListener onExpandChange;
130
148
131
149
@override
132
150
Widget build (BuildContext context) {
133
151
return NestedScrollView (
152
+ controller: controller,
134
153
floatHeaderSlivers: true ,
135
154
headerSliverBuilder: (_, __) {
136
155
return [
137
156
SliverAppBar (
138
157
elevation: 0.0 ,
139
158
centerTitle: true ,
140
159
title: Row (mainAxisSize: MainAxisSize .min, children: [
141
- Image .asset (Assets .appLogo, width: 18.0 ),
160
+ Image .asset (Assets .appLogo, width: Dimens .logoSignetSize ),
142
161
const SizedBox (width: Dimens .m),
143
162
TextStyles .appBarLogo ('SnipMe' ),
144
163
]),
@@ -150,11 +169,13 @@ class _MainPageData extends StatelessWidget {
150
169
),
151
170
actions: [
152
171
IconButton (
153
- icon: const Icon (Icons .close_fullscreen_outlined),
172
+ icon: Icon (
173
+ expanded
174
+ ? Icons .close_fullscreen_outlined
175
+ : Icons .open_in_full_outlined,
176
+ ),
154
177
color: Colors .black,
155
- onPressed: () {
156
- // TODO Handle collapse items
157
- },
178
+ onPressed: () => onExpandChange (! expanded),
158
179
),
159
180
],
160
181
),
@@ -211,7 +232,9 @@ class _MainPageData extends StatelessWidget {
211
232
},
212
233
),
213
234
),
214
- const SizedBox (height: Dimens .m,)
235
+ const SizedBox (
236
+ height: Dimens .m,
237
+ )
215
238
],
216
239
),
217
240
),
@@ -233,6 +256,7 @@ class _MainPageData extends StatelessWidget {
233
256
horizontal: Dimens .m,
234
257
),
235
258
child: SnippetListTile (
259
+ isExpanded: expanded,
236
260
snippet: snippet,
237
261
onTap: () {
238
262
navigator.goToDetails (context, snippet.uuid! );
0 commit comments