Skip to content

Commit 4068ce0

Browse files
committed
Add firebase queries support for grid view.
1 parent 53205d1 commit 4068ce0

File tree

2 files changed

+121
-16
lines changed

2 files changed

+121
-16
lines changed

lib/src/transformers/node_transformers/passive_grid_view_transformer.dart

Lines changed: 120 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import 'dart:core';
22

3+
import 'package:cloud_firestore/cloud_firestore.dart';
34
import 'package:codelessly_api/codelessly_api.dart';
5+
import 'package:firebase_ui_firestore/firebase_ui_firestore.dart';
46
import 'package:flutter/material.dart';
7+
import 'package:provider/provider.dart';
58

69
import '../../../codelessly_sdk.dart';
710

@@ -31,13 +34,116 @@ class PassiveGridViewWidget extends StatelessWidget {
3134
required this.settings,
3235
});
3336

37+
Query<Map<String, dynamic>> constructQuery(
38+
BuildContext context, Codelessly codelessly) {
39+
final PublishSource source =
40+
codelessly.config?.publishSource ?? PublishSource.preview;
41+
42+
final String collectionPath = node.collectionPath ?? '';
43+
44+
Query<Map<String, dynamic>> query = codelessly.firebaseFirestore.collection(
45+
'${source.rootDataCollection}/${codelessly.authManager.authData!.projectId}/$collectionPath',
46+
);
47+
48+
return constructQueryFromRef(
49+
query,
50+
whereFilters: node.whereFilters,
51+
orderByOperations: node.orderByFilters,
52+
scopedValues: ScopedValues.of(context),
53+
nullSubstitutionMode: settings.nullSubstitutionMode,
54+
);
55+
}
56+
3457
@override
3558
Widget build(BuildContext context) {
3659
if (node.children.isEmpty) {
3760
return AdaptiveNodeBox(node: node, child: const SizedBox());
3861
}
3962
final itemNode = node.children.first;
4063

64+
final bool useCloudDatabase = node.useCloudDatabase;
65+
if (useCloudDatabase && !settings.isPreview) {
66+
final codelessly = context.read<Codelessly>();
67+
final codelesslyController = context.read<CodelesslyWidgetController>();
68+
69+
if (codelessly.authManager.authData == null) {
70+
return codelesslyController.loadingBuilder?.call(context) ??
71+
const Center(child: CircularProgressIndicator());
72+
}
73+
74+
final query = constructQuery(context, codelessly);
75+
76+
return AdaptiveNodeBox(
77+
node: node,
78+
child: FirestoreQueryBuilder<Map<String, dynamic>>(
79+
query: query,
80+
pageSize: node.limit ?? 20,
81+
builder: (context, snapshot, child) {
82+
if (snapshot.isFetching) {
83+
return codelesslyController.loadingBuilder?.call(context) ??
84+
const Center(child: CircularProgressIndicator());
85+
}
86+
87+
if (snapshot.hasError) {
88+
return codelesslyController.errorBuilder?.call(
89+
context,
90+
snapshot.error,
91+
) ??
92+
const Center(child: Text('Error'));
93+
}
94+
95+
final List<QueryDocumentSnapshot<Map>> docs = snapshot.docs;
96+
final itemCount = docs.length;
97+
98+
return GridViewBuilder(
99+
primary: node.primary,
100+
gridDelegate: node.properties.gridDelegate,
101+
shrinkWrap: node.properties.itemCount != null &&
102+
(node.scrollDirection == AxisC.horizontal
103+
? node.isHorizontalWrap
104+
: node.isVerticalWrap),
105+
itemCount: itemCount,
106+
padding: node.padding.flutterEdgeInsets,
107+
keyboardDismissBehavior:
108+
node.keyboardDismissBehavior.flutterKeyboardDismissBehavior,
109+
physics:
110+
node.physics.flutterScrollPhysics(node.shouldAlwaysScroll),
111+
scrollDirection: node.scrollDirection.flutterAxis,
112+
cacheExtent: node.properties.cacheExtent,
113+
reverse: node.reverse,
114+
clipBehavior: node.clipsContent ? Clip.hardEdge : Clip.none,
115+
itemBuilder: (context, index) {
116+
final doc = docs.elementAtOrNull(index);
117+
final id = doc?.id;
118+
final data = doc?.data();
119+
return IndexedItemProvider(
120+
key: ValueKey(index),
121+
item: IndexedItem(
122+
index,
123+
{if (id != null) 'id': id, ...?data},
124+
),
125+
child: Builder(
126+
builder: (context) {
127+
// This builder is important to pass a context that has
128+
// the IndexedItemProvider.
129+
return KeyedSubtree(
130+
key: ValueKey(index),
131+
child: manager.buildWidgetByID(
132+
itemNode,
133+
context,
134+
settings: settings,
135+
),
136+
);
137+
},
138+
),
139+
);
140+
},
141+
);
142+
},
143+
),
144+
);
145+
}
146+
41147
final List? data = PropertyValueDelegate.getVariableValueFromPath<List>(
42148
node.variables['data'] ?? '',
43149
scopedValues: ScopedValues.of(context),
@@ -72,18 +178,20 @@ class PassiveGridViewWidget extends StatelessWidget {
72178
itemBuilder: (context, index) => IndexedItemProvider(
73179
key: ValueKey(index),
74180
item: IndexedItem(index, data?.elementAtOrNull(index)),
75-
child: Builder(builder: (context) {
76-
// This builder is important to pass a context that has
77-
// the IndexedItemProvider.
78-
return KeyedSubtree(
79-
key: ValueKey(index),
80-
child: manager.buildWidgetByID(
81-
itemNode,
82-
context,
83-
settings: settings,
84-
),
85-
);
86-
}),
181+
child: Builder(
182+
builder: (context) {
183+
// This builder is important to pass a context that has
184+
// the IndexedItemProvider.
185+
return KeyedSubtree(
186+
key: ValueKey(index),
187+
child: manager.buildWidgetByID(
188+
itemNode,
189+
context,
190+
settings: settings,
191+
),
192+
);
193+
},
194+
),
87195
),
88196
),
89197
);

lib/src/transformers/node_transformers/passive_list_view_transformer.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,7 @@ class PassiveListViewWidget extends StatelessWidget {
127127
key: ValueKey(index),
128128
item: IndexedItem(
129129
index,
130-
{
131-
if (id != null) 'id': id,
132-
...?data,
133-
},
130+
{if (id != null) 'id': id, ...?data},
134131
),
135132
child: Builder(builder: (context) {
136133
// This builder is important to pass a context that has

0 commit comments

Comments
 (0)