Skip to content

Commit 0203e09

Browse files
graphql_flutter: make first version of demo app
Signed-off-by: Vincenzo Palazzo <[email protected]>
1 parent 984b221 commit 0203e09

File tree

7 files changed

+101
-65
lines changed

7 files changed

+101
-65
lines changed

packages/graphql_flutter/example/graphql_chat/lib/api/query.dart

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,35 @@ class Queries {
55
getChats {
66
__typename
77
id
8-
message
8+
description
99
name
1010
}
1111
}
1212
""";
1313
}
1414

15-
static String createChatMutation({required String name, required String message}) {
15+
static String createChatMutation(
16+
{required String name, required String description}) {
1617
return """
1718
mutation {
18-
createChat(name: $name, message: $message) {
19+
createChat(name: $name, description: $description) {
1920
id
2021
name
21-
message
22+
description
2223
}
2324
}
2425
""";
2526
}
26-
}
27+
28+
static String subscribeToNewChat() {
29+
return """
30+
subscription {
31+
chatCreated {
32+
id
33+
name
34+
description
35+
}
36+
}
37+
""";
38+
}
39+
}

packages/graphql_flutter/example/graphql_chat/lib/main.dart

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,23 @@ Future<void> main() async {
1212
"Accept": "application/json",
1313
"Access-Control_Allow_Origin": "*",
1414
},
15-
'http://127.0.0.1:9000/graphql',
15+
'https://api.chat.graphql-flutter.dev/graphql',
16+
);
17+
var wsLink = WebSocketLink(
18+
'ws://api.chat.graphql-flutter.dev/graphql',
19+
config: const SocketClientConfig(
20+
inactivityTimeout: Duration(seconds: 40),
21+
),
22+
subProtocol: GraphQLProtocol.graphqlTransportWs,
23+
);
24+
final Link link = Link.split(
25+
(request) => request.isSubscription,
26+
wsLink,
27+
httpLink,
1628
);
1729
ValueNotifier<GraphQLClient> client = ValueNotifier(
1830
GraphQLClient(
19-
link: httpLink,
31+
link: link,
2032
// The default store is the InMemoryStore, which does NOT persist to disk
2133
cache: GraphQLCache(store: HiveStore()),
2234
),
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
21
class Chat {
32
final int id;
43
final String name;
5-
final String message;
4+
final String description;
65

7-
const Chat({required this.id, required this.name, required this.message});
6+
const Chat({required this.id, required this.name, required this.description});
87

98
factory Chat.fromJSON(Map<String, dynamic> json) {
10-
return Chat(id: json["id"], name: json["name"], message: json["message"]);
9+
return Chat(
10+
id: json["id"], name: json["name"], description: json["description"]);
1111
}
12-
}
12+
}
Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import 'package:flutter/cupertino.dart';
1+
import 'package:flutter/material.dart';
22
import 'package:graphql_chat/api/query.dart';
33
import 'package:graphql_chat/model/chat.dart';
44
import 'package:graphql_flutter/graphql_flutter.dart';
55
import 'package:logger/logger.dart';
66

77
class HomeViewBody extends StatelessWidget {
88
final Logger _logger = Logger();
9+
List<Chat> _chats = [];
10+
911
HomeViewBody({Key? key}) : super(key: key);
1012

1113
@override
@@ -21,35 +23,71 @@ class HomeViewBody extends StatelessWidget {
2123
Widget _buildScrollView({required BuildContext context}) {
2224
return Query(
2325
options: QueryOptions<List<Chat>>(
26+
fetchPolicy: FetchPolicy.networkOnly,
27+
parserFn: (Map<String, dynamic> json) {
28+
var rawList = List.of(json["getChats"]);
29+
return rawList
30+
.map((jsonChat) => Chat.fromJSON(jsonChat))
31+
.toList();
32+
},
33+
document: gql(Queries.getGetQuery())),
34+
builder: (QueryResult result,
35+
{VoidCallback? refetch, FetchMore? fetchMore}) {
36+
if (result.hasException) {
37+
_logger.e(result.exception);
38+
throw Exception(result.exception);
39+
}
40+
if (result.isLoading) {
41+
_logger.i("Still loading");
42+
return const Text("Loading chats");
43+
}
44+
_logger.d(result.data ?? "Data is undefined");
45+
_chats = result.parsedData as List<Chat>;
46+
return ListView(
47+
children:
48+
_chats.map((chatData) => Text(chatData.description)).toList(),
49+
);
50+
});
51+
}
52+
53+
Widget _buildUpdateScrollView({required BuildContext context}) {
54+
return Subscription(
55+
options: SubscriptionOptions(
2456
parserFn: (Map<String, dynamic> json) {
25-
var rawList = List.of(json["getChats"]);
26-
return rawList.map((jsonChat) => Chat.fromJSON(jsonChat)).toList();
57+
return Chat.fromJSON(json["chatCreated"]);
2758
},
28-
document: gql(Queries.getGetQuery())
29-
), builder: (QueryResult result, { VoidCallback? refetch, FetchMore? fetchMore }) {
30-
if (result.hasException) {
31-
_logger.e(result.exception);
32-
throw Exception(result.exception);
33-
}
34-
if (result.isLoading) {
35-
_logger.i("Still loading");
36-
return const Text("Loading chats");
37-
}
38-
_logger.d(result.data ?? "Data is undefined");
39-
var chats = result.parsedData as List<Chat>;
40-
return ListView(
41-
children: chats.map((chatData) => Text(chatData.message)).toList(),
42-
);
43-
});
59+
document: gql(Queries.subscribeToNewChat()),
60+
),
61+
builder: (result) {
62+
if (result.hasException) {
63+
_logger.e(result.exception);
64+
return Text(result.exception.toString());
65+
}
66+
67+
if (result.isLoading) {
68+
return const Center(
69+
child: CircularProgressIndicator(),
70+
);
71+
}
72+
// ResultAccumulator is a provided helper widget for collating subscription results.
73+
_logger.d(result.data ?? "Data is undefined");
74+
var chat = result.parsedData as Chat;
75+
return ResultAccumulator.appendUniqueEntries(
76+
latest: _chats,
77+
builder: (context, {results}) =>
78+
ListView(children: [Text(chat.name)]),
79+
);
80+
});
4481
}
4582

4683
/// Build the scroll view with all the information
4784
Widget _buildBodyView({required BuildContext context}) {
4885
return Column(
4986
children: [
5087
Expanded(child: _buildScrollView(context: context)),
88+
const Expanded(child: Text("Subscription data")),
89+
Expanded(child: _buildUpdateScrollView(context: context)),
5190
],
5291
);
5392
}
54-
55-
}
93+
}

packages/graphql_flutter/example/graphql_chat/lib/view/home_view.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,4 @@ class _HomeViewState extends State<HomeView> {
8181
},
8282
);
8383
}
84-
}
84+
}

packages/graphql_flutter/example/graphql_chat/pubspec.yaml

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,8 @@ dev_dependencies:
2525
dependency_overrides:
2626
graphql_flutter:
2727
path: ../../
28+
graphql:
29+
path: ../../../graphql
2830

2931
flutter:
30-
uses-material-design: true
31-
# assets:
32-
# - images/a_dot_burr.jpeg
33-
# - images/a_dot_ham.jpeg
34-
35-
# An image asset can refer to one or more resolution-specific "variants", see
36-
# https://flutter.dev/assets-and-images/#resolution-aware
37-
38-
# For details regarding adding assets from package dependencies, see
39-
# https://flutter.dev/assets-and-images/#from-packages
40-
41-
# To add custom fonts to your application, add a fonts section here,
42-
# in this "flutter" section. Each entry in this list should have a
43-
# "family" key with the font family name, and a "fonts" key with a
44-
# list giving the asset and other descriptors for the font. For
45-
# example:
46-
# fonts:
47-
# - family: Schyler
48-
# fonts:
49-
# - asset: fonts/Schyler-Regular.ttf
50-
# - asset: fonts/Schyler-Italic.ttf
51-
# style: italic
52-
# - family: Trajan Pro
53-
# fonts:
54-
# - asset: fonts/TrajanPro.ttf
55-
# - asset: fonts/TrajanPro_Bold.ttf
56-
# weight: 700
57-
#
58-
# For details regarding fonts from package dependencies,
59-
# see https://flutter.dev/custom-fonts/#from-packages
32+
uses-material-design: true

packages/graphql_flutter/example/graphql_chat/test/widget_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
import 'package:flutter_test/flutter_test.dart';
99

1010
void main() {
11-
testWidgets('Counter increments smoke test', (WidgetTester tester) async { });
11+
testWidgets('Counter increments smoke test', (WidgetTester tester) async {});
1212
}

0 commit comments

Comments
 (0)