Skip to content

Commit da7b63f

Browse files
authored
ParseLiveListElementSnapshot added (#329)
* Created ParseLiveList * LiveList & LivListBuilder works * Cleanup * changed to animated list * Fix in dataloading * updated AnimatedList * Finished Animations & cleanup * handle reconnect * Added dispose methodes & renamed classes & cleanup * cleanup * Fix animation duration * added README ParseLiveList section * Initialized example_livelist * Update application_constants.dart * Update .gitignore * Revert "Update .gitignore" This reverts commit 4d8982d. * Update .gitignore * HotFix: object Update from client If the client changes the object. (ParseObject does not get copied) * Implemented simple example * Update README.md * Update main.dart * Update README.md * Update README.md * LiveList - Performance Improvement This is the change mentioned in #324 (comment) Requires #326 * LiveList - Performance Improvement This is the change mentioned in #324 (comment) Requires #326 * example_livelist: use clientKey * Changed example_livelist query In the README I wrote, you can use a field called "show" to hide elements. * Remove: RemovedItemBuilder duplicade to ChildBuilder * removed firstBuild * ParseLiveListElementSnapshot added
1 parent 3fdbe97 commit da7b63f

File tree

2 files changed

+57
-33
lines changed

2 files changed

+57
-33
lines changed

example_livelist/lib/main.dart

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,31 +80,32 @@ class _MyAppState extends State<MyApp> {
8080
child: ParseLiveListWidget<ParseObject>(
8181
query: _queryBuilder,
8282
duration: const Duration(seconds: 1),
83-
childBuilder:
84-
(BuildContext context, bool failed, ParseObject loadedData) {
85-
if (failed) {
83+
childBuilder: (BuildContext context,
84+
ParseLiveListElementSnapshot<ParseObject> snapshot) {
85+
if (snapshot.failed) {
8686
return const Text('something went wrong!');
87-
} else if (loadedData != null) {
87+
} else if (snapshot.hasData) {
8888
return ListTile(
8989
title: Row(
9090
children: <Widget>[
9191
Flexible(
92-
child: Text(loadedData.get<int>('order').toString()),
92+
child: Text(
93+
snapshot.loadedData.get<int>('order').toString()),
9394
flex: 1,
9495
),
9596
Flexible(
9697
child: Container(
9798
alignment: Alignment.center,
9899
child: Text(
99-
loadedData.get<String>('text'),
100+
snapshot.loadedData.get<String>('text'),
100101
),
101102
),
102103
flex: 10,
103104
),
104105
],
105106
),
106107
onLongPress: () {
107-
objectFormKey.currentState.setObject(loadedData);
108+
objectFormKey.currentState.setObject(snapshot.loadedData);
108109
},
109110
);
110111
} else {

lib/src/utils/parse_live_list.dart

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,10 @@ class ParseLiveList<T extends ParseObject> {
207207
keyVarObjectId, _list[index].object.get<String>(keyVarObjectId))
208208
..setLimit(1);
209209
final ParseResponse response = await queryBuilder.query();
210-
if (response.success) {
210+
if (response.success && response.results != null) {
211211
_list[index].object = response.results.first;
212212
} else {
213+
_list[index].object = null;
213214
throw response.error;
214215
}
215216
}
@@ -293,12 +294,20 @@ class ParseLiveListDeleteEvent<T extends ParseObject>
293294
ParseLiveListDeleteEvent(int index, T object) : super(index, object);
294295
}
295296

296-
typedef Stream<T> StreamGetter<T extends ParseObject>();
297-
typedef T DataGetter<T extends ParseObject>();
298-
typedef Widget ChildBuilder<T extends ParseObject>(
299-
BuildContext context, bool failed, T loadedData);
300-
typedef Widget RemovedItemBuilder<T extends ParseObject>(
301-
BuildContext context, int index, T oldObject);
297+
typedef StreamGetter<T extends ParseObject> = Stream<T> Function();
298+
typedef DataGetter<T extends ParseObject> = T Function();
299+
typedef ChildBuilder<T extends ParseObject> = Widget Function(
300+
BuildContext context, ParseLiveListElementSnapshot<T> snapshot);
301+
302+
class ParseLiveListElementSnapshot<T extends ParseObject> {
303+
ParseLiveListElementSnapshot({this.loadedData, this.error});
304+
305+
final T loadedData;
306+
final ParseError error;
307+
308+
bool get hasData => loadedData != null;
309+
bool get failed => error != null;
310+
}
302311

303312
class ParseLiveListWidget<T extends ParseObject> extends StatefulWidget {
304313
const ParseLiveListWidget(
@@ -329,8 +338,8 @@ class ParseLiveListWidget<T extends ParseObject> extends StatefulWidget {
329338
final bool reverse;
330339
final bool shrinkWrap;
331340

332-
final ChildBuilder childBuilder;
333-
final RemovedItemBuilder<T> removedItemBuilder;
341+
final ChildBuilder<T> childBuilder;
342+
final ChildBuilder<T> removedItemBuilder;
334343

335344
@override
336345
_ParseLiveListWidgetState<T> createState() =>
@@ -392,7 +401,7 @@ class _ParseLiveListWidgetState<T extends ParseObject>
392401
ParseLiveList<T> _liveList;
393402
final GlobalKey<AnimatedListState> _animatedListKey =
394403
GlobalKey<AnimatedListState>();
395-
final RemovedItemBuilder<T> removedItemBuilder;
404+
final ChildBuilder<T> removedItemBuilder;
396405

397406
@override
398407
Widget build(BuildContext context) {
@@ -448,7 +457,7 @@ class ParseLiveListElementWidget<T extends ParseObject> extends StatefulWidget {
448457
final DataGetter<T> loadedData;
449458
final Animation<double> sizeFactor;
450459
final Duration duration;
451-
final ChildBuilder childBuilder;
460+
final ChildBuilder<T> childBuilder;
452461

453462
@override
454463
_ParseLiveListElementWidgetState<T> createState() {
@@ -461,23 +470,38 @@ class _ParseLiveListElementWidgetState<T extends ParseObject>
461470
with SingleTickerProviderStateMixin {
462471
_ParseLiveListElementWidgetState(
463472
DataGetter<T> loadedDataGetter, StreamGetter<T> stream) {
464-
loadedData = loadedDataGetter();
473+
// loadedData = loadedDataGetter();
474+
_snapshot = ParseLiveListElementSnapshot<T>(loadedData: loadedDataGetter());
465475
if (stream != null) {
466-
_streamSubscription = stream().listen((T data) {
467-
if (widget != null) {
468-
setState(() {
469-
loadedData = data;
470-
});
471-
} else {
472-
loadedData = data;
473-
}
474-
});
476+
_streamSubscription = stream().listen(
477+
(T data) {
478+
if (widget != null) {
479+
setState(() {
480+
_snapshot = ParseLiveListElementSnapshot<T>(loadedData: data);
481+
});
482+
} else {
483+
_snapshot = ParseLiveListElementSnapshot<T>(loadedData: data);
484+
}
485+
},
486+
onError: (Object error) {
487+
if (error is ParseError) {
488+
if (widget != null) {
489+
setState(() {
490+
_snapshot = ParseLiveListElementSnapshot<T>(error: error);
491+
});
492+
} else {
493+
_snapshot = ParseLiveListElementSnapshot<T>(error: error);
494+
}
495+
}
496+
},
497+
cancelOnError: false,
498+
);
475499
}
476500
}
477-
T loadedData;
478-
bool failed = false;
501+
502+
ParseLiveListElementSnapshot<T> _snapshot;
503+
479504
StreamSubscription<T> _streamSubscription;
480-
bool firstBuild = true;
481505

482506
@override
483507
void dispose() {
@@ -493,10 +517,9 @@ class _ParseLiveListElementWidgetState<T extends ParseObject>
493517
child: AnimatedSize(
494518
duration: widget.duration,
495519
vsync: this,
496-
child: widget.childBuilder(context, failed, loadedData),
520+
child: widget.childBuilder(context, _snapshot),
497521
),
498522
);
499-
firstBuild = false;
500523
return result;
501524
}
502525
}

0 commit comments

Comments
 (0)