格式化

This commit is contained in:
v7lin
2022-05-16 18:54:52 +08:00
parent 27f5f8cc7d
commit 39a9a43d8d
7 changed files with 76 additions and 58 deletions

View File

@ -15,16 +15,22 @@ class TencentApi {
required String openid, required String openid,
required String accessToken, required String accessToken,
}) { }) {
return HttpClient().getUrl(Uri.parse('https://graph.qq.com/user/get_user_info?access_token=$accessToken&oauth_consumer_key=$appId&openid=$openid')).then((HttpClientRequest request) { return HttpClient()
.getUrl(Uri.parse(
'https://graph.qq.com/user/get_user_info?access_token=$accessToken&oauth_consumer_key=$appId&openid=$openid'))
.then((HttpClientRequest request) {
return request.close(); return request.close();
}).then((HttpClientResponse response) async { }).then((HttpClientResponse response) async {
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
final ContentType? contentType = response.headers.contentType; final ContentType? contentType = response.headers.contentType;
final Encoding encoding = Encoding.getByName(contentType?.charset) ?? utf8; final Encoding encoding =
Encoding.getByName(contentType?.charset) ?? utf8;
final String content = await encoding.decodeStream(response); final String content = await encoding.decodeStream(response);
return TencentUserInfoResp.fromJson(json.decode(content) as Map<String, dynamic>); return TencentUserInfoResp.fromJson(
json.decode(content) as Map<String, dynamic>);
} }
throw HttpException('HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.'); throw HttpException(
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
}); });
} }
@ -34,12 +40,16 @@ class TencentApi {
required String accessToken, required String accessToken,
String unionid = '1', String unionid = '1',
}) { }) {
return HttpClient().getUrl(Uri.parse('https://graph.qq.com/oauth2.0/me?access_token=$accessToken&unionid=$unionid')).then((HttpClientRequest request) { return HttpClient()
.getUrl(Uri.parse(
'https://graph.qq.com/oauth2.0/me?access_token=$accessToken&unionid=$unionid'))
.then((HttpClientRequest request) {
return request.close(); return request.close();
}).then((HttpClientResponse response) async { }).then((HttpClientResponse response) async {
if (response.statusCode == HttpStatus.ok) { if (response.statusCode == HttpStatus.ok) {
final ContentType? contentType = response.headers.contentType; final ContentType? contentType = response.headers.contentType;
final Encoding encoding = Encoding.getByName(contentType?.charset) ?? utf8; final Encoding encoding =
Encoding.getByName(contentType?.charset) ?? utf8;
final String callback = await encoding.decodeStream(response); final String callback = await encoding.decodeStream(response);
// 腾讯有毒 callback( $json ); // 腾讯有毒 callback( $json );
final RegExp exp = RegExp(r'callback\( (.*) \)\;'); final RegExp exp = RegExp(r'callback\( (.*) \)\;');
@ -47,11 +57,13 @@ class TencentApi {
if (match?.groupCount == 1) { if (match?.groupCount == 1) {
final String? content = match!.group(1); final String? content = match!.group(1);
if (content != null) { if (content != null) {
return TencentUnionidResp.fromJson(json.decode(content) as Map<String, dynamic>); return TencentUnionidResp.fromJson(
json.decode(content) as Map<String, dynamic>);
} }
} }
} }
throw HttpException('HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.'); throw HttpException(
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
}); });
} }
} }

View File

@ -70,6 +70,13 @@ class _HomeState extends State<Home> {
), ),
body: ListView( body: ListView(
children: <Widget>[ children: <Widget>[
ListTile(
title: Text('3.1.0 之后的版本请先获取权限'),
onTap: () async {
await Tencent.setIsPermissionGranted(granted: true);
_showTips('授权', '已授权获取设备信息/同意隐私协议');
},
),
ListTile( ListTile(
title: Text('注册APP'), title: Text('注册APP'),
onTap: () async { onTap: () async {
@ -80,17 +87,11 @@ class _HomeState extends State<Home> {
ListTile( ListTile(
title: Text('环境检查'), title: Text('环境检查'),
onTap: () async { onTap: () async {
final String content = 'QQ install: ${await Tencent.isQQInstalled()}\nTIM install: ${await Tencent.isTIMInstalled()}'; final String content =
'QQ install: ${await Tencent.isQQInstalled()}\nTIM install: ${await Tencent.isTIMInstalled()}';
_showTips('环境检查', content); _showTips('环境检查', content);
}, },
), ),
ListTile(
title: Text('3.1.0 之后的版本请先获取权限'),
onTap: () async {
await Tencent.setIsPermissionGranted(granted: true);
_showTips('授权', '已授权获取设备信息/同意隐私协议');
},
),
ListTile( ListTile(
title: Text('登录'), title: Text('登录'),
onTap: () { onTap: () {
@ -102,14 +103,17 @@ class _HomeState extends State<Home> {
ListTile( ListTile(
title: Text('获取用户信息'), title: Text('获取用户信息'),
onTap: () async { onTap: () async {
if ((_loginResp?.isSuccessful ?? false) && !(_loginResp!.isExpired ?? true)) { if ((_loginResp?.isSuccessful ?? false) &&
final TencentUserInfoResp userInfo = await TencentApi.getUserInfo( !(_loginResp!.isExpired ?? true)) {
final TencentUserInfoResp userInfo =
await TencentApi.getUserInfo(
appId: _TENCENT_APPID, appId: _TENCENT_APPID,
openid: _loginResp!.openid!, openid: _loginResp!.openid!,
accessToken: _loginResp!.accessToken!, accessToken: _loginResp!.accessToken!,
); );
if (userInfo.isSuccessful) { if (userInfo.isSuccessful) {
_showTips('用户信息', '${userInfo.nickname} - ${userInfo.gender} - ${userInfo.genderType}'); _showTips('用户信息',
'${userInfo.nickname} - ${userInfo.gender} - ${userInfo.genderType}');
} else { } else {
_showTips('用户信息', '${userInfo.ret} - ${userInfo.msg}'); _showTips('用户信息', '${userInfo.ret} - ${userInfo.msg}');
} }
@ -119,14 +123,17 @@ class _HomeState extends State<Home> {
ListTile( ListTile(
title: Text('获取UnionID'), title: Text('获取UnionID'),
onTap: () async { onTap: () async {
if ((_loginResp?.isSuccessful ?? false) && !(_loginResp!.isExpired ?? true)) { if ((_loginResp?.isSuccessful ?? false) &&
!(_loginResp!.isExpired ?? true)) {
final TencentUnionidResp unionid = await TencentApi.getUnionId( final TencentUnionidResp unionid = await TencentApi.getUnionId(
accessToken: _loginResp!.accessToken!, accessToken: _loginResp!.accessToken!,
); );
if (unionid.isSuccessful) { if (unionid.isSuccessful) {
_showTips('UnionID', '${unionid.clientId} - ${unionid.openid} - ${unionid.unionid}'); _showTips('UnionID',
'${unionid.clientId} - ${unionid.openid} - ${unionid.unionid}');
} else { } else {
_showTips('UnionID', '${unionid.error} - ${unionid.errorDescription}'); _showTips('UnionID',
'${unionid.error} - ${unionid.errorDescription}');
} }
} }
}, },
@ -152,7 +159,8 @@ class _HomeState extends State<Home> {
ListTile( ListTile(
title: Text('图片分享'), title: Text('图片分享'),
onTap: () async { onTap: () async {
final File file = await DefaultCacheManager().getSingleFile('https://www.baidu.com/img/bd_logo1.png?where=super'); final File file = await DefaultCacheManager().getSingleFile(
'https://www.baidu.com/img/bd_logo1.png?where=super');
await Tencent.shareImage( await Tencent.shareImage(
scene: TencentScene.SCENE_QQ, scene: TencentScene.SCENE_QQ,
imageUri: Uri.file(file.path), imageUri: Uri.file(file.path),

View File

@ -5,23 +5,8 @@
// gestures. You can also use WidgetTester to find child widgets in the widget // gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct. // tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:tencent_kit_example/main.dart';
void main() { void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async { testWidgets('smoke test', (WidgetTester tester) async {});
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) => widget is Text &&
widget.data!.startsWith('Running on:'),
),
findsOneWidget,
);
});
} }

View File

@ -11,17 +11,22 @@ import 'tencent_kit_platform_interface.dart';
class MethodChannelTencentKit extends TencentKitPlatform { class MethodChannelTencentKit extends TencentKitPlatform {
/// The method channel used to interact with the native platform. /// The method channel used to interact with the native platform.
@visibleForTesting @visibleForTesting
late final MethodChannel methodChannel = const MethodChannel('v7lin.github.io/tencent_kit')..setMethodCallHandler(_handleMethod); late final MethodChannel methodChannel =
const MethodChannel('v7lin.github.io/tencent_kit')
..setMethodCallHandler(_handleMethod);
final StreamController<BaseResp> _respStreamController = StreamController<BaseResp>.broadcast(); final StreamController<BaseResp> _respStreamController =
StreamController<BaseResp>.broadcast();
Future<dynamic> _handleMethod(MethodCall call) async { Future<dynamic> _handleMethod(MethodCall call) async {
switch (call.method) { switch (call.method) {
case 'onLoginResp': case 'onLoginResp':
_respStreamController.add(LoginResp.fromJson((call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>())); _respStreamController.add(LoginResp.fromJson(
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
break; break;
case 'onShareResp': case 'onShareResp':
_respStreamController.add(ShareMsgResp.fromJson((call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>())); _respStreamController.add(ShareMsgResp.fromJson(
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
break; break;
} }
} }
@ -49,8 +54,7 @@ class MethodChannelTencentKit extends TencentKitPlatform {
'registerApp', 'registerApp',
<String, dynamic>{ <String, dynamic>{
'appId': appId, 'appId': appId,
if (universalLink?.isNotEmpty ?? false) if (universalLink?.isNotEmpty ?? false) 'universalLink': universalLink,
'universalLink': universalLink,
}, },
); );
} }
@ -97,8 +101,7 @@ class MethodChannelTencentKit extends TencentKitPlatform {
assert(scene == TencentScene.SCENE_QZONE); assert(scene == TencentScene.SCENE_QZONE);
assert((summary?.isNotEmpty ?? false) || assert((summary?.isNotEmpty ?? false) ||
((imageUris?.isNotEmpty ?? false) && ((imageUris?.isNotEmpty ?? false) &&
imageUris! imageUris!.every((Uri element) => element.isScheme('file'))) ||
.every((Uri element) => element.isScheme('file'))) ||
(videoUri != null && videoUri.isScheme('file'))); (videoUri != null && videoUri.isScheme('file')));
return methodChannel.invokeMethod<void>( return methodChannel.invokeMethod<void>(
'shareMood', 'shareMood',
@ -107,7 +110,7 @@ class MethodChannelTencentKit extends TencentKitPlatform {
if (summary?.isNotEmpty ?? false) 'summary': summary, if (summary?.isNotEmpty ?? false) 'summary': summary,
if (imageUris?.isNotEmpty ?? false) if (imageUris?.isNotEmpty ?? false)
'imageUris': 'imageUris':
imageUris!.map((Uri imageUri) => imageUri.toString()).toList(), imageUris!.map((Uri imageUri) => imageUri.toString()).toList(),
if (videoUri != null) 'videoUri': videoUri.toString(), if (videoUri != null) 'videoUri': videoUri.toString(),
}, },
); );

View File

@ -29,14 +29,16 @@ abstract class TencentKitPlatform extends PlatformInterface {
required bool granted, required bool granted,
String? buildModel /* android.os.Build.MODEL */, String? buildModel /* android.os.Build.MODEL */,
}) { }) {
throw UnimplementedError('setIsPermissionGranted({required granted, buildModel}) has not been implemented.'); throw UnimplementedError(
'setIsPermissionGranted({required granted, buildModel}) has not been implemented.');
} }
Future<void> registerApp({ Future<void> registerApp({
required String appId, required String appId,
String? universalLink, String? universalLink,
}) { }) {
throw UnimplementedError('registerApp({required appId, universalLink}) has not been implemented.'); throw UnimplementedError(
'registerApp({required appId, universalLink}) has not been implemented.');
} }
Future<bool> isQQInstalled() { Future<bool> isQQInstalled() {
@ -54,7 +56,8 @@ abstract class TencentKitPlatform extends PlatformInterface {
Future<void> login({ Future<void> login({
required List<String> scope, required List<String> scope,
}) { }) {
throw UnimplementedError('login({required scope}) has not been implemented.'); throw UnimplementedError(
'login({required scope}) has not been implemented.');
} }
Future<void> logout() { Future<void> logout() {
@ -67,14 +70,16 @@ abstract class TencentKitPlatform extends PlatformInterface {
List<Uri>? imageUris, List<Uri>? imageUris,
Uri? videoUri, Uri? videoUri,
}) { }) {
throw UnimplementedError('shareMood({required scene, summary, imageUris, videoUri}) has not been implemented.'); throw UnimplementedError(
'shareMood({required scene, summary, imageUris, videoUri}) has not been implemented.');
} }
Future<void> shareText({ Future<void> shareText({
required int scene, required int scene,
required String summary, required String summary,
}) { }) {
throw UnimplementedError('shareText({required scene, required summary}) has not been implemented.'); throw UnimplementedError(
'shareText({required scene, required summary}) has not been implemented.');
} }
Future<void> shareImage({ Future<void> shareImage({
@ -83,7 +88,8 @@ abstract class TencentKitPlatform extends PlatformInterface {
String? appName, String? appName,
int extInt = TencentQZoneFlag.DEFAULT, int extInt = TencentQZoneFlag.DEFAULT,
}) { }) {
throw UnimplementedError('shareImage({required scene, required imageUri, appName, extInt}) has not been implemented.'); throw UnimplementedError(
'shareImage({required scene, required imageUri, appName, extInt}) has not been implemented.');
} }
Future<void> shareMusic({ Future<void> shareMusic({
@ -96,7 +102,8 @@ abstract class TencentKitPlatform extends PlatformInterface {
String? appName, String? appName,
int extInt = TencentQZoneFlag.DEFAULT, int extInt = TencentQZoneFlag.DEFAULT,
}) { }) {
throw UnimplementedError('shareMusic({required scene, required title, summary, imageUri, required musicUrl, required targetUrl, appName, extInt}) has not been implemented.'); throw UnimplementedError(
'shareMusic({required scene, required title, summary, imageUri, required musicUrl, required targetUrl, appName, extInt}) has not been implemented.');
} }
Future<void> shareWebpage({ Future<void> shareWebpage({
@ -108,6 +115,7 @@ abstract class TencentKitPlatform extends PlatformInterface {
String? appName, String? appName,
int extInt = TencentQZoneFlag.DEFAULT, int extInt = TencentQZoneFlag.DEFAULT,
}) { }) {
throw UnimplementedError('shareWebpage({required scene, required title, summary, imageUri, required targetUrl, appName, extInt}) has not been implemented.'); throw UnimplementedError(
'shareWebpage({required scene, required title, summary, imageUri, required targetUrl, appName, extInt}) has not been implemented.');
} }
} }

View File

@ -10,7 +10,7 @@ void main() {
setUp(() { setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async { channel.setMockMethodCallHandler((MethodCall methodCall) async {
switch(methodCall.method) { switch (methodCall.method) {
case 'isQQInstalled': case 'isQQInstalled':
return true; return true;
} }

View File

@ -7,7 +7,9 @@ import 'package:tencent_kit/src/tencent_kit_method_channel.dart';
import 'package:tencent_kit/src/tencent_kit_platform_interface.dart'; import 'package:tencent_kit/src/tencent_kit_platform_interface.dart';
import 'package:tencent_kit/tencent_kit.dart'; import 'package:tencent_kit/tencent_kit.dart';
class MockTencentKitPlatform with MockPlatformInterfaceMixin implements TencentKitPlatform { class MockTencentKitPlatform
with MockPlatformInterfaceMixin
implements TencentKitPlatform {
@override @override
Future<void> setIsPermissionGranted({ Future<void> setIsPermissionGranted({
required bool granted, required bool granted,