Skip to content

Commit ac2ed00

Browse files
committed
live ok
1 parent 6f648fc commit ac2ed00

File tree

5 files changed

+264
-19
lines changed

5 files changed

+264
-19
lines changed

example/android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
FlutterApplication and put your custom class here. -->
1515
<application
1616
android:name="io.flutter.app.FlutterApplication"
17-
android:label="flutter_plugin_example"
17+
android:label="parse_sdk"
1818
android:icon="@mipmap/ic_launcher">
1919
<activity
2020
android:name=".MainActivity"

example/lib/domain/constants/application_constants.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ const String keyParseApplicationId = 'myAppId';
33
const String keyParseMasterKey = '123456';
44
const String keyParseServerUrl = 'http://118.24.162.252:2018/parse';
55
const String keyParseLiveServerUrl = 'ws://118.24.162.252:2018/parse';
6+
// const String keyParseServerUrl = 'http://192.168.3.5:4000/parse';
7+
// const String keyParseLiveServerUrl = 'ws://192.168.3.5:4000/parse';

example/lib/main.dart

Lines changed: 252 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:convert';
22
import 'dart:io';
33

4+
import 'package:english_words/english_words.dart';
45
import 'package:flutter/foundation.dart';
56
import 'package:flutter/material.dart';
67
import 'package:flutter_plugin_example/data/base/api_response.dart';
@@ -10,6 +11,7 @@ import 'package:flutter_plugin_example/data/repositories/diet_plan/repository_di
1011
import 'package:flutter_plugin_example/data/repositories/user/repository_user.dart';
1112
import 'package:flutter_plugin_example/domain/constants/application_constants.dart';
1213
import 'package:flutter_plugin_example/domain/utils/db_utils.dart';
14+
import 'package:json_table/json_table.dart';
1315
// import 'package:flutter_stetho/flutter_stetho.dart';
1416
import 'package:parse_server_sdk/parse_server_sdk.dart';
1517

@@ -37,40 +39,168 @@ class MyApp extends StatefulWidget {
3739
_MyAppState createState() => _MyAppState();
3840
}
3941

40-
class _MyAppState extends State<MyApp> {
42+
class _MyAppState extends State<MyApp> with AutomaticKeepAliveClientMixin {
4143
DietPlanRepository dietPlanRepo;
4244
UserRepository userRepo;
45+
// Map<String, dynamic> _result;
46+
List<Map<String, dynamic>> _result = [];
4347

48+
String info = "";
4449
String text = '';
45-
50+
LiveQuery liveQuery;
4651
@override
4752
void initState() {
4853
super.initState();
4954
initData();
5055
}
5156

57+
@override
58+
bool get wantKeepAlive => true;
5259
@override
5360
Widget build(BuildContext context) {
5461
return MaterialApp(
5562
home: Scaffold(
56-
appBar: AppBar(
57-
title: const Text('Plugin example app'),
58-
),
59-
body: Center(
60-
child: Text(text),
61-
),
62-
),
63+
appBar: AppBar(
64+
title: const Text('Parse sdk live test'),
65+
),
66+
body: Container(
67+
margin: EdgeInsets.all(10.0),
68+
child: Column(
69+
children: <Widget>[
70+
// JsonTable(
71+
// jsonDecode(_result.isEmpty ? "[{}]" : _result[0].toString()),
72+
// tableHeaderBuilder: (String header) {
73+
// return Container(
74+
// padding:
75+
// EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
76+
// decoration: BoxDecoration(
77+
// border: Border.all(width: 0.5),
78+
// color: Colors.grey[300]),
79+
// child: Text(
80+
// header,
81+
// textAlign: TextAlign.center,
82+
// style: Theme.of(context).textTheme.display1.copyWith(
83+
// fontWeight: FontWeight.w700,
84+
// fontSize: 14.0,
85+
// color: Colors.black87),
86+
// ),
87+
// );
88+
// },
89+
// tableCellBuilder: (dynamic value) {
90+
// return Container(
91+
// padding:
92+
// EdgeInsets.symmetric(horizontal: 4.0, vertical: 2.0),
93+
// decoration: BoxDecoration(
94+
// border: Border.all(
95+
// width: 0.5, color: Colors.grey.withOpacity(0.5))),
96+
// child: Text(
97+
// value,
98+
// textAlign: TextAlign.center,
99+
// style: Theme.of(context)
100+
// .textTheme
101+
// .display1
102+
// .copyWith(fontSize: 14.0, color: Colors.grey[900]),
103+
// ),
104+
// );
105+
// },
106+
// ),
107+
Flexible(
108+
child: ListView(
109+
children:
110+
_result.map((location) => _ResultItem(location)).toList(),
111+
)),
112+
Row(
113+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
114+
children: <Widget>[
115+
// Button(label: '开始监听', onPressed: _listen()),
116+
RaisedButton(
117+
onPressed: () {
118+
updateSingleItem(context);
119+
},
120+
color: Colors.blue[400],
121+
child: new Text('更新',
122+
style: new TextStyle(color: Colors.white))),
123+
],
124+
),
125+
// RaisedButton(
126+
// onPressed: () {
127+
// _listen();
128+
// },
129+
// color: Colors.blue[400],
130+
// child:
131+
// new Text('开始监听', style: new TextStyle(color: Colors.white))),
132+
// RaisedButton(
133+
// onPressed: () {
134+
// _change(context);
135+
// },
136+
// color: Colors.blue[400],
137+
// child:
138+
// new Text('修改数据', style: new TextStyle(color: Colors.white))),
139+
],
140+
),
141+
)),
63142
);
64143
}
65144

145+
Future<void> _listen() async {
146+
QueryBuilder<ParseObject> query = QueryBuilder<ParseObject>(DietPlan())
147+
..whereEqualTo('objectId', 'Y06whIh1sS');
148+
// LiveQuery liveQuery = LiveQuery();
149+
// print("=====query: $query");
150+
await liveQuery.subscribe(query);
151+
152+
liveQuery.on(LiveQueryEvent.update, (dynamic value) {
153+
print("监听数据连接成功,开始订阅消息!");
154+
155+
print('*** UPDATE ***: ${DateTime.now().toString()}\n $value');
156+
print((value as ParseObject).objectId);
157+
print((value as ParseObject).updatedAt);
158+
print((value as ParseObject).createdAt);
159+
// print((value as ParseObject).get('objectId'));
160+
// print((value as ParseObject).get('updatedAt'));
161+
// print((value as ParseObject).get('createdAt'));
162+
163+
print("监听到数据变化:" + (value as ParseObject).toJson().toString());
164+
// _result.add(value);
165+
});
166+
}
167+
168+
Future<void> updateSingleItem(BuildContext context) async {
169+
final ParseResponse apiResponse = await DietPlan().getObject('Y06whIh1sS');
170+
171+
if (apiResponse.success && apiResponse.count > 0) {
172+
final DietPlan dietPlan = apiResponse.result;
173+
174+
// Shows example of storing values in their proper type and retrieving them
175+
var s = new WordPair.random().asPascalCase;
176+
dietPlan.set<String>('Name', s);
177+
await dietPlan.save();
178+
// await createItem();
179+
// Shows example of pinning an item
180+
// await dietPlan.pin();
181+
182+
// shows example of retrieving a pin
183+
setState(() {});
184+
} else {
185+
print(keyAppName + ': ' + apiResponse.error.message);
186+
}
187+
}
188+
66189
Future<void> initData() async {
67190
// Initialize repository
68191
await initRepository();
69192

70193
// Initialize parse
71194
Parse().initialize(keyParseApplicationId, keyParseServerUrl,
72-
masterKey: keyParseMasterKey, debug: true);
73-
195+
masterKey: keyParseMasterKey,
196+
liveQueryUrl: keyParseServerUrl,
197+
// clientKey: "XXXi3GejX3SIxpDgSbKHHV8uHUUP3QGiPPTlxxxx",
198+
sessionId: "1212121",
199+
autoSendSessionId: true,
200+
debug: true);
201+
// ParseHTTPClient client = ParseHTTPClient();
202+
203+
liveQuery = LiveQuery();
74204
//parse serve with secure store and desktop support
75205

76206
// Parse().initialize(keyParseApplicationId, keyParseServerUrl,
@@ -82,9 +212,31 @@ class _MyAppState extends State<MyApp> {
82212
final ParseResponse response = await Parse().healthCheck();
83213

84214
if (response.success) {
85-
await runTestQueries();
86-
text += 'runTestQueries\n';
87-
print(text);
215+
// await _listen();
216+
QueryBuilder<ParseObject> query = QueryBuilder<ParseObject>(DietPlan())
217+
..whereEqualTo('objectId', 'Y06whIh1sS');
218+
// LiveQuery liveQuery = LiveQuery();
219+
// print("=====query: $query");
220+
await liveQuery.subscribe(query);
221+
222+
await liveQuery.on(LiveQueryEvent.update, (dynamic value) {
223+
print("监听数据连接成功,开始订阅消息!");
224+
225+
print('*** UPDATE ***: ${DateTime.now().toString()}\n $value');
226+
print((value as ParseObject).objectId);
227+
print((value as ParseObject).updatedAt);
228+
print((value as ParseObject).createdAt);
229+
print((value as ParseObject).get<String>('Name'));
230+
// print((value as ParseObject).get('updatedAt'));
231+
// print((value as ParseObject).get('createdAt'));
232+
_result.clear();
233+
print("监听到数据变化:" + (value as ParseObject).toJson().toString());
234+
_result.add(value.toJson());
235+
print(_result.toString());
236+
});
237+
// await runTestQueries();
238+
// text += 'runTestQueries\n';
239+
// print(text);
88240
} else {
89241
text += 'Server health check failed';
90242
print(text);
@@ -119,7 +271,7 @@ class _MyAppState extends State<MyApp> {
119271
}
120272

121273
Future<void> test() async {
122-
User user = User('unreal', 'hhhhhh', '[email protected]');
274+
User user = User('unreal0', 'hhhhhh', '[email protected]');
123275
final ParseResponse signUpResponse = await user.signUp();
124276

125277
if (signUpResponse.success) {
@@ -381,3 +533,88 @@ const String dietPlansToAdd =
381533
'{"className":"Diet_Plans","Name":"Low Carb","Description":"Low Carb diet, main focus on quality fats and protein.","Fat":35,"Carbs":25,"Protein":40,"Status":0},'
382534
'{"className":"Diet_Plans","Name":"Paleo","Description":"Paleo diet.","Fat":60,"Carbs":25,"Protein":10,"Status":0},'
383535
'{"className":"Diet_Plans","Name":"Ketogenic","Description":"High quality fats, low carbs.","Fat":65,"Carbs":5,"Protein":30,"Status":0}]';
536+
537+
class _ResultItem extends StatelessWidget {
538+
final Map<String, dynamic> _data;
539+
540+
const _ResultItem(this._data, {Key key}) : super(key: key);
541+
542+
@override
543+
Widget build(BuildContext context) {
544+
return Padding(
545+
padding: const EdgeInsets.all(16.0),
546+
child: Column(
547+
crossAxisAlignment: CrossAxisAlignment.start,
548+
children: <Widget>[
549+
Text(
550+
DateTime.now().toIso8601String(),
551+
style: TextStyle(color: Colors.grey),
552+
),
553+
SizedBox(width: 4.0, height: 4.0),
554+
// Text(
555+
// "$_data",
556+
// style: TextStyle(color: Colors.black87),
557+
// ),
558+
Text(
559+
jsonFormat(_data),
560+
style: TextStyle(color: Colors.grey[600]),
561+
),
562+
],
563+
),
564+
);
565+
}
566+
567+
String jsonFormat(Map<String, Object> json) {
568+
JsonEncoder encoder = JsonEncoder.withIndent(' ');
569+
return encoder.convert(json);
570+
}
571+
}
572+
573+
// class DietPlan extends ParseObject {
574+
// DietPlan() : super(DIET_PLAN);
575+
576+
// String name;
577+
// String description;
578+
// num protein;
579+
// num carbs;
580+
// num fat;
581+
// num status;
582+
583+
// static const String DIET_PLAN = 'post';
584+
// static const String NAME = 'title';
585+
// // static const String DESCRIPTION = 'text';
586+
// // static const String PROTEIN = 'Protein';
587+
// // static const String CARBS = 'Carbs';
588+
// // static const String FAT = 'Fat';
589+
// // static const String STATUS = 'Status';
590+
591+
// @override
592+
// dynamic fromJson(Map<String, dynamic> objectData) {
593+
// this.name = objectData[NAME];
594+
// // this.description = objectData[DESCRIPTION];
595+
// // this.protein = objectData[PROTEIN];
596+
// // this.carbs = objectData[CARBS];
597+
// // this.fat = objectData[FAT];
598+
// // this.status = objectData[STATUS];
599+
// return this;
600+
// }
601+
602+
// // Map<String, dynamic> toJson() => {
603+
// // NAME: name,
604+
// // // DESCRIPTION: description,
605+
// // // PROTEIN: protein,
606+
// // // CARBS: carbs,
607+
// // // FAT: fat,
608+
// // // STATUS: status,
609+
// // };
610+
611+
// @override
612+
// String toString() {
613+
// return toJson().toString();
614+
// }
615+
616+
// @override
617+
// dynamic copy() {
618+
// return DietPlan();
619+
// }
620+
// }

example/pubspec.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ dependencies:
1111
# flutter_stetho: ^0.2.2
1212
sembast: ^1.13.3+1
1313
shared_preferences: ^0.5.0
14+
json_table: ^0.3.0
15+
intl: ^0.15.8
16+
english_words: ^3.1.4
17+
json_serializable: ^3.0.0
1418

1519
dev_dependencies:
1620
parse_server_sdk:

lib/src/network/parse_live_query.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ class LiveQuery {
1111
securityContext: ParseCoreData().securityContext);
1212

1313
_debug = isDebugEnabled(objectLevelDebug: debug);
14-
_sendSessionId = autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true;
14+
_sendSessionId =
15+
autoSendSessionId ?? ParseCoreData().autoSendSessionId ?? true;
1516
}
1617

1718
WebSocket _webSocket;
@@ -40,7 +41,6 @@ class LiveQuery {
4041

4142
// ignore: always_specify_types
4243
Future subscribe(QueryBuilder query) async {
43-
4444
String _liveQueryURL = _client.data.liveQueryURL;
4545
if (_liveQueryURL.contains('https')) {
4646
_liveQueryURL = _liveQueryURL.replaceAll('https', 'wss');
@@ -75,6 +75,8 @@ class LiveQuery {
7575
}
7676

7777
_channel = IOWebSocketChannel(_webSocket);
78+
// _channel = IOWebSocketChannel.connect(_liveQueryURL);
79+
7880
_channel.stream.listen((dynamic message) {
7981
if (_debug) {
8082
print('$_printConstLiveQuery: Listen: $message');
@@ -101,7 +103,7 @@ class LiveQuery {
101103
if (_debug) {
102104
print('$_printConstLiveQuery: Done');
103105
}
104-
}, onError: (Error error) {
106+
}, onError: (error) {
105107
if (_debug) {
106108
print(
107109
'$_printConstLiveQuery: Error: ${error.runtimeType.toString()}');

0 commit comments

Comments
 (0)