fake_weibo 0.1.0
This commit is contained in:
parent
9538c6faa8
commit
59d1407e74
@ -74,7 +74,7 @@ dependencies:
|
|||||||
|
|
||||||
### release
|
### release
|
||||||
````
|
````
|
||||||
latestVersion = 0.0.1+1
|
latestVersion = 0.1.0
|
||||||
````
|
````
|
||||||
|
|
||||||
````
|
````
|
||||||
|
@ -41,7 +41,7 @@ public class FakeWeiboPlugin implements MethodCallHandler, PluginRegistry.Activi
|
|||||||
channel.setMethodCallHandler(plugin);
|
channel.setMethodCallHandler(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FakeWeiboErrorCode {
|
private static class WeiboErrorCode {
|
||||||
public static final int SUCCESS = 0;//成功
|
public static final int SUCCESS = 0;//成功
|
||||||
public static final int USERCANCEL = -1;//用户取消发送
|
public static final int USERCANCEL = -1;//用户取消发送
|
||||||
public static final int SENT_FAIL = -2;//发送失败
|
public static final int SENT_FAIL = -2;//发送失败
|
||||||
@ -79,7 +79,7 @@ public class FakeWeiboPlugin implements MethodCallHandler, PluginRegistry.Activi
|
|||||||
private static final String ARGUMENT_KEY_RESULT_USERID = "userId";
|
private static final String ARGUMENT_KEY_RESULT_USERID = "userId";
|
||||||
private static final String ARGUMENT_KEY_RESULT_ACCESSTOKEN = "accessToken";
|
private static final String ARGUMENT_KEY_RESULT_ACCESSTOKEN = "accessToken";
|
||||||
private static final String ARGUMENT_KEY_RESULT_REFRESHTOKEN = "refreshToken";
|
private static final String ARGUMENT_KEY_RESULT_REFRESHTOKEN = "refreshToken";
|
||||||
private static final String ARGUMENT_KEY_RESULT_EXPIRATIONDATE = "expirationDate";
|
private static final String ARGUMENT_KEY_RESULT_EXPIRESIN = "expiresIn";
|
||||||
|
|
||||||
private final Registrar registrar;
|
private final Registrar registrar;
|
||||||
private final MethodChannel channel;
|
private final MethodChannel channel;
|
||||||
@ -125,13 +125,14 @@ public class FakeWeiboPlugin implements MethodCallHandler, PluginRegistry.Activi
|
|||||||
public void onSuccess(Oauth2AccessToken oauth2AccessToken) {
|
public void onSuccess(Oauth2AccessToken oauth2AccessToken) {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
if (oauth2AccessToken.isSessionValid()) {
|
if (oauth2AccessToken.isSessionValid()) {
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.SUCCESS);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS);
|
||||||
map.put(ARGUMENT_KEY_RESULT_USERID, oauth2AccessToken.getUid());
|
map.put(ARGUMENT_KEY_RESULT_USERID, oauth2AccessToken.getUid());
|
||||||
map.put(ARGUMENT_KEY_RESULT_ACCESSTOKEN, oauth2AccessToken.getToken());
|
map.put(ARGUMENT_KEY_RESULT_ACCESSTOKEN, oauth2AccessToken.getToken());
|
||||||
map.put(ARGUMENT_KEY_RESULT_REFRESHTOKEN, oauth2AccessToken.getRefreshToken());
|
map.put(ARGUMENT_KEY_RESULT_REFRESHTOKEN, oauth2AccessToken.getRefreshToken());
|
||||||
map.put(ARGUMENT_KEY_RESULT_EXPIRATIONDATE, oauth2AccessToken.getExpiresTime());
|
long expiresIn = (long) Math.ceil((oauth2AccessToken.getExpiresTime() - System.currentTimeMillis()) / 1000.0);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_EXPIRESIN, expiresIn);// 向上取整
|
||||||
} else {
|
} else {
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.UNKNOWN);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN);
|
||||||
}
|
}
|
||||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||||
}
|
}
|
||||||
@ -139,7 +140,7 @@ public class FakeWeiboPlugin implements MethodCallHandler, PluginRegistry.Activi
|
|||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.USERCANCEL);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL);
|
||||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,12 +149,12 @@ public class FakeWeiboPlugin implements MethodCallHandler, PluginRegistry.Activi
|
|||||||
// 微博有毒,WbConnectErrorMessage对象两个属性设置错误
|
// 微博有毒,WbConnectErrorMessage对象两个属性设置错误
|
||||||
if (TextUtils.equals(wbConnectErrorMessage.getErrorMessage(), "21338")) {
|
if (TextUtils.equals(wbConnectErrorMessage.getErrorMessage(), "21338")) {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.SSO_PKG_SIGN_ERROR);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SSO_PKG_SIGN_ERROR);
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORMESSAGE, wbConnectErrorMessage.getErrorCode());
|
map.put(ARGUMENT_KEY_RESULT_ERRORMESSAGE, wbConnectErrorMessage.getErrorCode());
|
||||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||||
} else {
|
} else {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.UNKNOWN);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN);
|
||||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,21 +219,21 @@ public class FakeWeiboPlugin implements MethodCallHandler, PluginRegistry.Activi
|
|||||||
@Override
|
@Override
|
||||||
public void onWbShareSuccess() {
|
public void onWbShareSuccess() {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.SUCCESS);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS);
|
||||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWbShareCancel() {
|
public void onWbShareCancel() {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.USERCANCEL);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL);
|
||||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWbShareFail() {
|
public void onWbShareFail() {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, FakeWeiboErrorCode.SHARE_IN_SDK_FAILED);
|
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SHARE_IN_SDK_FAILED);
|
||||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
|
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
|
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
|
||||||
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
@ -41,7 +40,6 @@
|
|||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
|
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
|
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||||
@ -83,7 +81,6 @@
|
|||||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
|
|
||||||
3B80C3931E831B6300D905FE /* App.framework */,
|
3B80C3931E831B6300D905FE /* App.framework */,
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||||
9740EEBA1CF902C7004384FC /* Flutter.framework */,
|
9740EEBA1CF902C7004384FC /* Flutter.framework */,
|
||||||
@ -213,7 +210,6 @@
|
|||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||||
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
|
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||||
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
|
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -6,6 +6,9 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:fake_weibo/fake_weibo.dart';
|
import 'package:fake_weibo/fake_weibo.dart';
|
||||||
|
|
||||||
const String _WEIBO_APP_KEY = '3393861383';
|
const String _WEIBO_APP_KEY = '3393861383';
|
||||||
|
const List<String> _WEIBO_SCOPE = <String>[
|
||||||
|
WeiboScope.ALL,
|
||||||
|
];
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runZoned(() {
|
runZoned(() {
|
||||||
@ -25,14 +28,12 @@ void main() {
|
|||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
FakeWeibo weibo = FakeWeibo(
|
Weibo weibo = Weibo()
|
||||||
|
..registerApp(
|
||||||
appKey: _WEIBO_APP_KEY,
|
appKey: _WEIBO_APP_KEY,
|
||||||
scope: [
|
scope: _WEIBO_SCOPE,
|
||||||
FakeWeiboScope.ALL,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
weibo.registerApp();
|
return WeiboProvider(
|
||||||
return FakeWeiboProvider(
|
|
||||||
weibo: weibo,
|
weibo: weibo,
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
home: Home(
|
home: Home(
|
||||||
@ -46,7 +47,7 @@ class MyApp extends StatelessWidget {
|
|||||||
class Home extends StatefulWidget {
|
class Home extends StatefulWidget {
|
||||||
Home({Key key, @required this.weibo}) : super(key: key);
|
Home({Key key, @required this.weibo}) : super(key: key);
|
||||||
|
|
||||||
final FakeWeibo weibo;
|
final Weibo weibo;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
@ -55,10 +56,10 @@ class Home extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _HomeState extends State<Home> {
|
class _HomeState extends State<Home> {
|
||||||
StreamSubscription<FakeWeiboAuthResp> _auth;
|
StreamSubscription<WeiboAuthResp> _auth;
|
||||||
StreamSubscription<FakeWeiboShareMsgResp> _share;
|
StreamSubscription<WeiboSdkResp> _share;
|
||||||
|
|
||||||
FakeWeiboAuthResp _authResp;
|
WeiboAuthResp _authResp;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -67,13 +68,13 @@ class _HomeState extends State<Home> {
|
|||||||
_share = widget.weibo.shareMsgResp().listen(_listenShareMsg);
|
_share = widget.weibo.shareMsgResp().listen(_listenShareMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenAuth(FakeWeiboAuthResp resp) {
|
void _listenAuth(WeiboAuthResp resp) {
|
||||||
_authResp = resp;
|
_authResp = resp;
|
||||||
String content = 'auth: ${resp.errorCode}';
|
String content = 'auth: ${resp.errorCode}';
|
||||||
_showTips('登录', content);
|
_showTips('登录', content);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenShareMsg(FakeWeiboShareMsgResp resp) {
|
void _listenShareMsg(WeiboSdkResp resp) {
|
||||||
String content = 'share: ${resp.errorCode}';
|
String content = 'share: ${resp.errorCode}';
|
||||||
_showTips('分享', content);
|
_showTips('分享', content);
|
||||||
}
|
}
|
||||||
@ -108,26 +109,29 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: Text('登录'),
|
title: Text('登录'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
widget.weibo.auth();
|
widget.weibo.auth(
|
||||||
|
appKey: _WEIBO_APP_KEY,
|
||||||
|
scope: _WEIBO_SCOPE,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('用户信息'),
|
title: Text('用户信息'),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (_authResp != null &&
|
if (_authResp != null &&
|
||||||
_authResp.errorCode == FakeWeiboErrorCode.SUCCESS) {
|
_authResp.errorCode == WeiboSdkResp.SUCCESS) {
|
||||||
FakeWeiboApiUserResp userResp = await widget.weibo.getUserInfo(
|
WeiboUserInfoResp userInfoResp = await widget.weibo.getUserInfo(
|
||||||
appkey: _WEIBO_APP_KEY,
|
appkey: _WEIBO_APP_KEY,
|
||||||
userId: _authResp.userId,
|
userId: _authResp.userId,
|
||||||
accessToken: _authResp.accessToken);
|
accessToken: _authResp.accessToken,
|
||||||
if (userResp != null &&
|
);
|
||||||
userResp.errorCode ==
|
if (userInfoResp != null &&
|
||||||
FakeWeiboApiBaseResp.ERROR_CODE_SUCCESS) {
|
userInfoResp.errorCode == WeiboApiResp.ERROR_CODE_SUCCESS) {
|
||||||
_showTips('用户信息',
|
_showTips('用户信息',
|
||||||
'${userResp.screenName}\n${userResp.description}\n${userResp.location}\n${userResp.profileImageUrl}');
|
'${userInfoResp.screenName}\n${userInfoResp.description}\n${userInfoResp.location}\n${userInfoResp.profileImageUrl}');
|
||||||
} else {
|
} else {
|
||||||
_showTips('用户信息',
|
_showTips('用户信息',
|
||||||
'获取用户信息失败\n${userResp.errorCode}:${userResp.error}');
|
'获取用户信息失败\n${userInfoResp.errorCode}:${userInfoResp.error}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -43,7 +43,7 @@ static NSString * const ARGUMENT_KEY_RESULT_ERRORMESSAGE = @"errorMessage";
|
|||||||
static NSString * const ARGUMENT_KEY_RESULT_USERID = @"userId";
|
static NSString * const ARGUMENT_KEY_RESULT_USERID = @"userId";
|
||||||
static NSString * const ARGUMENT_KEY_RESULT_ACCESSTOKEN = @"accessToken";
|
static NSString * const ARGUMENT_KEY_RESULT_ACCESSTOKEN = @"accessToken";
|
||||||
static NSString * const ARGUMENT_KEY_RESULT_REFRESHTOKEN = @"refreshToken";
|
static NSString * const ARGUMENT_KEY_RESULT_REFRESHTOKEN = @"refreshToken";
|
||||||
static NSString * const ARGUMENT_KEY_RESULT_EXPIRATIONDATE = @"expirationDate";
|
static NSString * const ARGUMENT_KEY_RESULT_EXPIRESIN = @"expiresIn";
|
||||||
|
|
||||||
-(instancetype)initWithChannel:(FlutterMethodChannel *)channel {
|
-(instancetype)initWithChannel:(FlutterMethodChannel *)channel {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
@ -145,11 +145,11 @@ static NSString * const ARGUMENT_KEY_RESULT_EXPIRATIONDATE = @"expirationDate";
|
|||||||
NSString * userId = authorizeResponse.userID;
|
NSString * userId = authorizeResponse.userID;
|
||||||
NSString * accessToken = authorizeResponse.accessToken;
|
NSString * accessToken = authorizeResponse.accessToken;
|
||||||
NSString * refreshToken = authorizeResponse.refreshToken;
|
NSString * refreshToken = authorizeResponse.refreshToken;
|
||||||
long long expirationDate = authorizeResponse.expirationDate.timeIntervalSince1970 * 1000;
|
long long expiresIn = ceil(authorizeResponse.expirationDate.timeIntervalSinceNow);// 向上取整
|
||||||
[dictionary setValue:userId forKey:ARGUMENT_KEY_RESULT_USERID];
|
[dictionary setValue:userId forKey:ARGUMENT_KEY_RESULT_USERID];
|
||||||
[dictionary setValue:accessToken forKey:ARGUMENT_KEY_RESULT_ACCESSTOKEN];
|
[dictionary setValue:accessToken forKey:ARGUMENT_KEY_RESULT_ACCESSTOKEN];
|
||||||
[dictionary setValue:refreshToken forKey:ARGUMENT_KEY_RESULT_REFRESHTOKEN];
|
[dictionary setValue:refreshToken forKey:ARGUMENT_KEY_RESULT_REFRESHTOKEN];
|
||||||
[dictionary setValue:[NSNumber numberWithLongLong:expirationDate] forKey:ARGUMENT_KEY_RESULT_EXPIRATIONDATE];
|
[dictionary setValue:[NSNumber numberWithLongLong:expiresIn] forKey:ARGUMENT_KEY_RESULT_EXPIRESIN];
|
||||||
}
|
}
|
||||||
[_channel invokeMethod:METHOD_ONAUTHRESP arguments:dictionary];
|
[_channel invokeMethod:METHOD_ONAUTHRESP arguments:dictionary];
|
||||||
} else if ([response isKindOfClass:[WBSendMessageToWeiboResponse class]]) {
|
} else if ([response isKindOfClass:[WBSendMessageToWeiboResponse class]]) {
|
||||||
|
@ -1,529 +1,9 @@
|
|||||||
import 'dart:async';
|
library fake_weibo;
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
export 'src/domain/api/weibo_api_resp.dart';
|
||||||
import 'dart:typed_data';
|
export 'src/domain/api/weibo_user_info_resp.dart'
|
||||||
|
hide WeiboUserInfoRespSerializer;
|
||||||
import 'package:flutter/services.dart';
|
export 'src/domain/sdk/weibo_auth_resp.dart' hide WeiboAuthRespSerializer;
|
||||||
import 'package:flutter/widgets.dart';
|
export 'src/domain/sdk/weibo_sdk_resp.dart' hide WeiboSdkRespSerializer;
|
||||||
import 'package:meta/meta.dart';
|
export 'src/weibo.dart';
|
||||||
|
export 'src/weibo_scope.dart';
|
||||||
class FakeWeiboScope {
|
|
||||||
FakeWeiboScope._();
|
|
||||||
|
|
||||||
static const String EMAIL = 'email';
|
|
||||||
static const String DIRECT_MESSAGES_READ = 'direct_messages_read';
|
|
||||||
static const String DIRECT_MESSAGES_WRITE = 'direct_messages_write';
|
|
||||||
static const String FRIENDSHIPS_GROUPS_READ = 'friendships_groups_read';
|
|
||||||
static const String FRIENDSHIPS_GROUPS_WRITE = 'friendships_groups_write';
|
|
||||||
static const String STATUSES_TO_ME_READ = 'statuses_to_me_read';
|
|
||||||
static const String FOLLOW_APP_OFFICIAL_MICROBLOG =
|
|
||||||
'follow_app_official_microblog';
|
|
||||||
static const String INVITATION_WRITE = 'invitation_write';
|
|
||||||
static const String ALL = 'all';
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeWeiboErrorCode {
|
|
||||||
FakeWeiboErrorCode._();
|
|
||||||
|
|
||||||
/// 成功
|
|
||||||
static const int SUCCESS = 0;
|
|
||||||
|
|
||||||
/// 用户取消发送
|
|
||||||
static const int USERCANCEL = -1;
|
|
||||||
|
|
||||||
/// 发送失败
|
|
||||||
static const int SENT_FAIL = -2;
|
|
||||||
|
|
||||||
/// 授权失败
|
|
||||||
static const int AUTH_DENY = -3;
|
|
||||||
|
|
||||||
/// 用户取消安装微博客户端
|
|
||||||
static const int USERCANCEL_INSTALL = -4;
|
|
||||||
|
|
||||||
/// 支付失败
|
|
||||||
static const int PAY_FAIL = -5;
|
|
||||||
|
|
||||||
/// 分享失败 详情见response UserInfo
|
|
||||||
static const int SHARE_IN_SDK_FAILED = -8;
|
|
||||||
|
|
||||||
/// 不支持的请求
|
|
||||||
static const int UNSUPPORT = -99;
|
|
||||||
|
|
||||||
/// 未知
|
|
||||||
static const int UNKNOWN = -100;
|
|
||||||
|
|
||||||
/// sso package or sign error
|
|
||||||
static const int SSO_PKG_SIGN_ERROR = 21338;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class FakeWeiboBaseResp {
|
|
||||||
FakeWeiboBaseResp({
|
|
||||||
@required this.errorCode,
|
|
||||||
this.errorMessage,
|
|
||||||
});
|
|
||||||
|
|
||||||
final int errorCode;
|
|
||||||
final String errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeWeiboAuthResp extends FakeWeiboBaseResp {
|
|
||||||
FakeWeiboAuthResp._({
|
|
||||||
@required int errorCode,
|
|
||||||
String errorMessage,
|
|
||||||
this.userId,
|
|
||||||
this.accessToken,
|
|
||||||
this.refreshToken,
|
|
||||||
this.expirationDate,
|
|
||||||
}) : super(
|
|
||||||
errorCode: errorCode,
|
|
||||||
errorMessage: errorMessage,
|
|
||||||
);
|
|
||||||
|
|
||||||
final String userId;
|
|
||||||
final String accessToken;
|
|
||||||
final String refreshToken;
|
|
||||||
final int expirationDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeWeiboShareMsgResp extends FakeWeiboBaseResp {
|
|
||||||
FakeWeiboShareMsgResp._({
|
|
||||||
@required int errorCode,
|
|
||||||
String errorMessage,
|
|
||||||
}) : super(
|
|
||||||
errorCode: errorCode,
|
|
||||||
errorMessage: errorMessage,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class FakeWeiboApiBaseResp {
|
|
||||||
FakeWeiboApiBaseResp({
|
|
||||||
@required this.errorCode,
|
|
||||||
this.error,
|
|
||||||
this.request,
|
|
||||||
});
|
|
||||||
|
|
||||||
static const String KEY_ERROR_CODE = 'error_code';
|
|
||||||
static const String KEY_ERROR = 'error';
|
|
||||||
static const String KEY_REQUEST = 'request';
|
|
||||||
|
|
||||||
static const int ERROR_CODE_SUCCESS = 0;
|
|
||||||
|
|
||||||
/// https://open.weibo.com/wiki/Help/error
|
|
||||||
final int errorCode;
|
|
||||||
final String error;
|
|
||||||
final String request;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeWeiboApiUserResp extends FakeWeiboApiBaseResp {
|
|
||||||
FakeWeiboApiUserResp._({
|
|
||||||
int errorCode,
|
|
||||||
String error,
|
|
||||||
String request,
|
|
||||||
this.id,
|
|
||||||
this.idstr,
|
|
||||||
this.screenName,
|
|
||||||
this.name,
|
|
||||||
this.province,
|
|
||||||
this.city,
|
|
||||||
this.location,
|
|
||||||
this.description,
|
|
||||||
this.url,
|
|
||||||
this.profileImageUrl,
|
|
||||||
this.profileUrl,
|
|
||||||
this.domain,
|
|
||||||
this.weihao,
|
|
||||||
this.gender,
|
|
||||||
this.verified,
|
|
||||||
this.avatarLarge,
|
|
||||||
this.avatarHD,
|
|
||||||
}) : super(errorCode: errorCode, error: error, request: request);
|
|
||||||
|
|
||||||
static const String KEY_ID = 'id';
|
|
||||||
static const String KEY_ID_STR = 'idstr';
|
|
||||||
static const String KEY_SCREEN_NAME = 'screen_name';
|
|
||||||
static const String KEY_NAME = 'name';
|
|
||||||
static const String KEY_PROVINCE = 'province';
|
|
||||||
static const String KEY_CITY = 'city';
|
|
||||||
static const String KEY_LOCATION = 'location';
|
|
||||||
static const String KEY_DESCRIPTION = 'description';
|
|
||||||
static const String KEY_URL = 'url';
|
|
||||||
static const String KEY_PROFILE_IMAGE_URL = 'profile_image_url';
|
|
||||||
static const String KEY_PROFILE_URL = 'profile_url';
|
|
||||||
static const String KEY_DOMAIN = 'domain';
|
|
||||||
static const String KEY_WEIHAO = 'weihao';
|
|
||||||
static const String KEY_GENDER = 'gender';
|
|
||||||
static const String KEY_VERIFIED = 'verified';
|
|
||||||
static const String KEY_AVATAR_LARGE = 'avatar_large';
|
|
||||||
static const String KEY_AVATAR_HD = 'avatar_hd';
|
|
||||||
|
|
||||||
/// 用户UID(int64)
|
|
||||||
final int id;
|
|
||||||
|
|
||||||
/// 字符串型的用户 UID
|
|
||||||
final String idstr;
|
|
||||||
|
|
||||||
/// 用户昵称
|
|
||||||
final String screenName;
|
|
||||||
|
|
||||||
/// 友好显示名称
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// 用户所在省级ID
|
|
||||||
final String province;
|
|
||||||
|
|
||||||
/// 用户所在城市ID
|
|
||||||
final String city;
|
|
||||||
|
|
||||||
/// 用户所在地
|
|
||||||
final String location;
|
|
||||||
|
|
||||||
/// 用户个人描述
|
|
||||||
final String description;
|
|
||||||
|
|
||||||
/// 用户博客地址
|
|
||||||
final String url;
|
|
||||||
|
|
||||||
/// 用户头像地址,50×50像素
|
|
||||||
final String profileImageUrl;
|
|
||||||
|
|
||||||
/// 用户的微博统一URL地址
|
|
||||||
final String profileUrl;
|
|
||||||
|
|
||||||
/// 用户的个性化域名
|
|
||||||
final String domain;
|
|
||||||
|
|
||||||
/// 用户的微号
|
|
||||||
final String weihao;
|
|
||||||
|
|
||||||
/// 性别,m:男、f:女、n:未知
|
|
||||||
final String gender;
|
|
||||||
|
|
||||||
// /// 粉丝数
|
|
||||||
// final int followers_count;
|
|
||||||
|
|
||||||
// /// 关注数
|
|
||||||
// final int friends_count;
|
|
||||||
|
|
||||||
// /// 微博数
|
|
||||||
// final int statuses_count;
|
|
||||||
|
|
||||||
// /// 收藏数
|
|
||||||
// final int favourites_count;
|
|
||||||
|
|
||||||
// /// 用户创建(注册)时间
|
|
||||||
// final String created_at;
|
|
||||||
|
|
||||||
// /// 暂未支持
|
|
||||||
// final bool following;
|
|
||||||
|
|
||||||
// /// 是否允许所有人给我发私信,true:是,false:否
|
|
||||||
// final bool allow_all_act_msg;
|
|
||||||
|
|
||||||
// /// 是否允许标识用户的地理位置,true:是,false:否
|
|
||||||
// final bool geo_enabled;
|
|
||||||
|
|
||||||
/// 是否是微博认证用户,即加V用户,true:是,false:否
|
|
||||||
final bool verified;
|
|
||||||
|
|
||||||
// /// 暂未支持
|
|
||||||
// final int verified_type;
|
|
||||||
|
|
||||||
// /// 用户备注信息,只有在查询用户关系时才返回此字段
|
|
||||||
// final String remark;
|
|
||||||
|
|
||||||
// /// 用户的最近一条微博信息字段
|
|
||||||
// final dynamic status;
|
|
||||||
|
|
||||||
// /// 是否允许所有人对我的微博进行评论,true:是,false:否
|
|
||||||
// final bool allow_all_comment;
|
|
||||||
|
|
||||||
/// 用户大头像地址
|
|
||||||
final String avatarLarge;
|
|
||||||
|
|
||||||
/// 用户高清大头像地址
|
|
||||||
final String avatarHD;
|
|
||||||
|
|
||||||
// /// 认证原因
|
|
||||||
// final String verified_reason;
|
|
||||||
|
|
||||||
// /// 该用户是否关注当前登录用户,true:是,false:否
|
|
||||||
// final bool follow_me;
|
|
||||||
|
|
||||||
// /// 用户的在线状态,0:不在线、1:在线
|
|
||||||
// final int online_status;
|
|
||||||
|
|
||||||
// /// 用户的互粉数
|
|
||||||
// final int bi_followers_count;
|
|
||||||
|
|
||||||
// /// 用户当前的语言版本,zh-cn:简体中文,zh-tw:繁体中文,en:英语
|
|
||||||
// final String lang;
|
|
||||||
|
|
||||||
// /// 注意:以下字段暂时不清楚具体含义,OpenAPI 说明文档暂时没有同步更新对应字段
|
|
||||||
// final String star;
|
|
||||||
// final String mbtype;
|
|
||||||
// final String mbrank;
|
|
||||||
// final String block_word;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeWeibo {
|
|
||||||
FakeWeibo({
|
|
||||||
@required String appKey,
|
|
||||||
@required List<String> scope,
|
|
||||||
String redirectUrl = _DEFAULT_REDIRECTURL,
|
|
||||||
}) : assert(appKey != null && appKey.isNotEmpty),
|
|
||||||
assert(scope != null && scope.isNotEmpty),
|
|
||||||
_appKey = appKey,
|
|
||||||
_scope = scope,
|
|
||||||
_redirectUrl = redirectUrl;
|
|
||||||
|
|
||||||
static const String _METHOD_REGISTERAPP = 'registerApp';
|
|
||||||
static const String _METHOD_ISWEIBOINSTALLED = 'isWeiboInstalled';
|
|
||||||
static const String _METHOD_AUTH = 'auth';
|
|
||||||
static const String _METHOD_SHARETEXT = 'shareText';
|
|
||||||
static const String _METHOD_SHAREIMAGE = 'shareImage';
|
|
||||||
static const String _METHOD_SHAREWEBPAGE = 'shareWebpage';
|
|
||||||
|
|
||||||
static const String _METHOD_ONAUTHRESP = 'onAuthResp';
|
|
||||||
static const String _METHOD_ONSHAREMSGRESP = 'onShareMsgResp';
|
|
||||||
|
|
||||||
static const String _ARGUMENT_KEY_APPKEY = 'appKey';
|
|
||||||
static const String _ARGUMENT_KEY_SCOPE = 'scope';
|
|
||||||
static const String _ARGUMENT_KEY_REDIRECTURL = 'redirectUrl';
|
|
||||||
static const String _ARGUMENT_KEY_TEXT = 'text';
|
|
||||||
static const String _ARGUMENT_KEY_TITLE = 'title';
|
|
||||||
static const String _ARGUMENT_KEY_DESCRIPTION = 'description';
|
|
||||||
static const String _ARGUMENT_KEY_THUMBDATA = 'thumbData';
|
|
||||||
static const String _ARGUMENT_KEY_IMAGEDATA = 'imageData';
|
|
||||||
static const String _ARGUMENT_KEY_WEBPAGEURL = 'webpageUrl';
|
|
||||||
|
|
||||||
static const String _ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode";
|
|
||||||
static const String _ARGUMENT_KEY_RESULT_ERRORMESSAGE = "errorMessage";
|
|
||||||
static const String _ARGUMENT_KEY_RESULT_USERID = 'userId';
|
|
||||||
static const String _ARGUMENT_KEY_RESULT_ACCESSTOKEN = 'accessToken';
|
|
||||||
static const String _ARGUMENT_KEY_RESULT_REFRESHTOKEN = 'refreshToken';
|
|
||||||
static const String _ARGUMENT_KEY_RESULT_EXPIRATIONDATE = 'expirationDate';
|
|
||||||
|
|
||||||
static const String _DEFAULT_REDIRECTURL =
|
|
||||||
'https://api.weibo.com/oauth2/default.html';
|
|
||||||
|
|
||||||
static const MethodChannel _channel =
|
|
||||||
MethodChannel('v7lin.github.io/fake_weibo');
|
|
||||||
|
|
||||||
final String _appKey;
|
|
||||||
final List<String> _scope;
|
|
||||||
|
|
||||||
/// 新浪微博开放平台 -> 我的应用 -> 应用信息 -> 高级信息 -> OAuth2.0授权设置
|
|
||||||
final String _redirectUrl;
|
|
||||||
|
|
||||||
final StreamController<FakeWeiboAuthResp> _authRespStreamController =
|
|
||||||
StreamController<FakeWeiboAuthResp>.broadcast();
|
|
||||||
|
|
||||||
final StreamController<FakeWeiboShareMsgResp> _shareMsgRespStreamController =
|
|
||||||
StreamController<FakeWeiboShareMsgResp>.broadcast();
|
|
||||||
|
|
||||||
Future<void> registerApp() {
|
|
||||||
_channel.setMethodCallHandler(_handleMethod);
|
|
||||||
return _channel.invokeMethod(
|
|
||||||
_METHOD_REGISTERAPP,
|
|
||||||
<String, dynamic>{
|
|
||||||
_ARGUMENT_KEY_APPKEY: _appKey,
|
|
||||||
_ARGUMENT_KEY_SCOPE: _scope.join(','),
|
|
||||||
_ARGUMENT_KEY_REDIRECTURL: _redirectUrl,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
|
||||||
switch (call.method) {
|
|
||||||
case _METHOD_ONAUTHRESP:
|
|
||||||
_authRespStreamController.add(FakeWeiboAuthResp._(
|
|
||||||
errorCode: call.arguments[_ARGUMENT_KEY_RESULT_ERRORCODE] as int,
|
|
||||||
errorMessage: call.arguments[_ARGUMENT_KEY_RESULT_ERRORMESSAGE] as String,
|
|
||||||
userId: call.arguments[_ARGUMENT_KEY_RESULT_USERID] as String,
|
|
||||||
accessToken:
|
|
||||||
call.arguments[_ARGUMENT_KEY_RESULT_ACCESSTOKEN] as String,
|
|
||||||
refreshToken:
|
|
||||||
call.arguments[_ARGUMENT_KEY_RESULT_REFRESHTOKEN] as String,
|
|
||||||
expirationDate:
|
|
||||||
call.arguments[_ARGUMENT_KEY_RESULT_EXPIRATIONDATE] as int,
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
case _METHOD_ONSHAREMSGRESP:
|
|
||||||
_shareMsgRespStreamController.add(FakeWeiboShareMsgResp._(
|
|
||||||
errorCode: call.arguments[_ARGUMENT_KEY_RESULT_ERRORCODE] as int,
|
|
||||||
errorMessage: call.arguments[_ARGUMENT_KEY_RESULT_ERRORMESSAGE] as String,
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<FakeWeiboAuthResp> authResp() {
|
|
||||||
return _authRespStreamController.stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<FakeWeiboShareMsgResp> shareMsgResp() {
|
|
||||||
return _shareMsgRespStreamController.stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isWeiboInstalled() async {
|
|
||||||
return (await _channel.invokeMethod(_METHOD_ISWEIBOINSTALLED)) as bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> auth() {
|
|
||||||
return _channel.invokeMethod(
|
|
||||||
_METHOD_AUTH,
|
|
||||||
<String, dynamic>{
|
|
||||||
_ARGUMENT_KEY_APPKEY: _appKey,
|
|
||||||
_ARGUMENT_KEY_SCOPE: _scope.join(','),
|
|
||||||
_ARGUMENT_KEY_REDIRECTURL: _redirectUrl,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<FakeWeiboApiUserResp> getUserInfo({
|
|
||||||
@required String appkey,
|
|
||||||
@required String userId,
|
|
||||||
@required String accessToken,
|
|
||||||
}) {
|
|
||||||
assert(userId != null && userId.isNotEmpty);
|
|
||||||
assert(accessToken != null && accessToken.isNotEmpty);
|
|
||||||
Map<String, String> params = <String, String>{
|
|
||||||
'uid': userId,
|
|
||||||
};
|
|
||||||
return HttpClient()
|
|
||||||
.getUrl(_encodeUrl('https://api.weibo.com/2/users/show.json', appkey,
|
|
||||||
accessToken, params))
|
|
||||||
.then((HttpClientRequest request) {
|
|
||||||
return request.close();
|
|
||||||
}).then((HttpClientResponse response) async {
|
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
|
||||||
String content = await utf8.decodeStream(response);
|
|
||||||
Map<dynamic, dynamic> map = json.decode(content) as Map<dynamic, dynamic>;
|
|
||||||
int errorCode = map.containsKey(FakeWeiboApiBaseResp.KEY_ERROR_CODE)
|
|
||||||
? map[FakeWeiboApiBaseResp.KEY_ERROR_CODE] as int
|
|
||||||
: FakeWeiboApiBaseResp.ERROR_CODE_SUCCESS;
|
|
||||||
if (errorCode == FakeWeiboApiBaseResp.ERROR_CODE_SUCCESS) {
|
|
||||||
return FakeWeiboApiUserResp._(
|
|
||||||
errorCode: errorCode,
|
|
||||||
id: map[FakeWeiboApiUserResp.KEY_ID] as int,
|
|
||||||
idstr: map[FakeWeiboApiUserResp.KEY_ID_STR] as String,
|
|
||||||
screenName: map[FakeWeiboApiUserResp.KEY_SCREEN_NAME] as String,
|
|
||||||
name: map[FakeWeiboApiUserResp.KEY_NAME] as String,
|
|
||||||
province: map[FakeWeiboApiUserResp.KEY_PROVINCE] as String,
|
|
||||||
city: map[FakeWeiboApiUserResp.KEY_CITY] as String,
|
|
||||||
location: map[FakeWeiboApiUserResp.KEY_LOCATION] as String,
|
|
||||||
description: map[FakeWeiboApiUserResp.KEY_DESCRIPTION] as String,
|
|
||||||
url: map[FakeWeiboApiUserResp.KEY_URL] as String,
|
|
||||||
profileImageUrl:
|
|
||||||
map[FakeWeiboApiUserResp.KEY_PROFILE_IMAGE_URL] as String,
|
|
||||||
profileUrl: map[FakeWeiboApiUserResp.KEY_PROFILE_URL] as String,
|
|
||||||
domain: map[FakeWeiboApiUserResp.KEY_DOMAIN] as String,
|
|
||||||
weihao: map[FakeWeiboApiUserResp.KEY_WEIHAO] as String,
|
|
||||||
gender: map[FakeWeiboApiUserResp.KEY_GENDER] as String,
|
|
||||||
verified: map[FakeWeiboApiUserResp.KEY_VERIFIED] as bool,
|
|
||||||
avatarLarge: map[FakeWeiboApiUserResp.KEY_AVATAR_LARGE] as String,
|
|
||||||
avatarHD: map[FakeWeiboApiUserResp.KEY_AVATAR_HD] as String,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return FakeWeiboApiUserResp._(
|
|
||||||
errorCode: errorCode,
|
|
||||||
error: map[FakeWeiboApiBaseResp.KEY_ERROR] as String,
|
|
||||||
request: map[FakeWeiboApiBaseResp.KEY_REQUEST] as String,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw HttpException(
|
|
||||||
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Uri _encodeUrl(
|
|
||||||
String baseUrl,
|
|
||||||
String appkey,
|
|
||||||
String accessToken,
|
|
||||||
Map<String, String> params,
|
|
||||||
) {
|
|
||||||
params.putIfAbsent('source', () => appkey);
|
|
||||||
params.putIfAbsent('access_token', () => accessToken);
|
|
||||||
|
|
||||||
Uri baseUri = Uri.parse(baseUrl);
|
|
||||||
Map<String, List<String>> queryParametersAll =
|
|
||||||
Map<String, List<String>>.of(baseUri.queryParametersAll);
|
|
||||||
params.forEach((String key, String value) {
|
|
||||||
queryParametersAll.remove(key);
|
|
||||||
queryParametersAll.putIfAbsent(key, () => <String>[value]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return baseUri.replace(queryParameters: queryParametersAll);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> shareText({
|
|
||||||
@required String text,
|
|
||||||
}) {
|
|
||||||
assert(text != null && text.isNotEmpty && text.length <= 1024);
|
|
||||||
return _channel.invokeMethod(
|
|
||||||
_METHOD_SHARETEXT,
|
|
||||||
<String, dynamic>{
|
|
||||||
_ARGUMENT_KEY_TEXT: text,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> shareImage({
|
|
||||||
@required Uint8List imageData,
|
|
||||||
}) {
|
|
||||||
assert(imageData != null && imageData.lengthInBytes <= 2 * 1024 * 1024);
|
|
||||||
return _channel.invokeMethod(
|
|
||||||
_METHOD_SHAREIMAGE,
|
|
||||||
<String, dynamic>{
|
|
||||||
_ARGUMENT_KEY_IMAGEDATA: imageData,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> shareWebpage({
|
|
||||||
@required String title,
|
|
||||||
@required String description,
|
|
||||||
@required Uint8List thumbData,
|
|
||||||
@required String webpageUrl,
|
|
||||||
}) {
|
|
||||||
assert(title != null && title.isNotEmpty && title.length <= 512);
|
|
||||||
assert(description != null &&
|
|
||||||
description.isNotEmpty &&
|
|
||||||
description.length <= 1024);
|
|
||||||
assert(thumbData != null && thumbData.lengthInBytes <= 32 * 1024);
|
|
||||||
assert(webpageUrl != null &&
|
|
||||||
webpageUrl.isNotEmpty &&
|
|
||||||
webpageUrl.length <= 255);
|
|
||||||
return _channel.invokeMethod(
|
|
||||||
_METHOD_SHAREWEBPAGE,
|
|
||||||
<String, dynamic>{
|
|
||||||
_ARGUMENT_KEY_TITLE: title,
|
|
||||||
_ARGUMENT_KEY_DESCRIPTION: description,
|
|
||||||
_ARGUMENT_KEY_THUMBDATA: thumbData,
|
|
||||||
_ARGUMENT_KEY_WEBPAGEURL: webpageUrl,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeWeiboProvider extends InheritedWidget {
|
|
||||||
FakeWeiboProvider({
|
|
||||||
Key key,
|
|
||||||
@required this.weibo,
|
|
||||||
@required Widget child,
|
|
||||||
}) : super(key: key, child: child);
|
|
||||||
|
|
||||||
final FakeWeibo weibo;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool updateShouldNotify(InheritedWidget oldWidget) {
|
|
||||||
FakeWeiboProvider oldProvider = oldWidget as FakeWeiboProvider;
|
|
||||||
return weibo != oldProvider.weibo;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FakeWeiboProvider of(BuildContext context) {
|
|
||||||
return context.inheritFromWidgetOfExactType(FakeWeiboProvider)
|
|
||||||
as FakeWeiboProvider;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
14
lib/src/domain/api/weibo_api_resp.dart
Normal file
14
lib/src/domain/api/weibo_api_resp.dart
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
abstract class WeiboApiResp {
|
||||||
|
WeiboApiResp({
|
||||||
|
int errorCode,
|
||||||
|
this.error,
|
||||||
|
this.request,
|
||||||
|
}) : errorCode = errorCode ?? ERROR_CODE_SUCCESS;
|
||||||
|
|
||||||
|
static const int ERROR_CODE_SUCCESS = 0;
|
||||||
|
|
||||||
|
/// https://open.weibo.com/wiki/Help/error
|
||||||
|
final int errorCode;
|
||||||
|
final String error;
|
||||||
|
final String request;
|
||||||
|
}
|
64
lib/src/domain/api/weibo_user_info_resp.dart
Normal file
64
lib/src/domain/api/weibo_user_info_resp.dart
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
||||||
|
import 'package:fake_weibo/src/domain/api/weibo_api_resp.dart';
|
||||||
|
|
||||||
|
part 'weibo_user_info_resp.jser.dart';
|
||||||
|
|
||||||
|
@GenSerializer(nameFormatter: toSnakeCase)
|
||||||
|
class WeiboUserInfoRespSerializer extends Serializer<WeiboUserInfoResp>
|
||||||
|
with _$WeiboUserInfoRespSerializer {}
|
||||||
|
|
||||||
|
class WeiboUserInfoResp extends WeiboApiResp {
|
||||||
|
WeiboUserInfoResp({
|
||||||
|
int errorCode,
|
||||||
|
String error,
|
||||||
|
String request,
|
||||||
|
this.id,
|
||||||
|
this.idstr,
|
||||||
|
this.screenName,
|
||||||
|
this.name,
|
||||||
|
this.location,
|
||||||
|
this.description,
|
||||||
|
this.profileImageUrl,
|
||||||
|
this.gender,
|
||||||
|
this.avatarLarge,
|
||||||
|
this.avatarHd,
|
||||||
|
}) : super(errorCode: errorCode, error: error, request: request);
|
||||||
|
|
||||||
|
/// 用户UID(int64)
|
||||||
|
final int id;
|
||||||
|
|
||||||
|
/// 字符串型的用户 UID
|
||||||
|
final String idstr;
|
||||||
|
|
||||||
|
/// 用户昵称
|
||||||
|
final String screenName;
|
||||||
|
|
||||||
|
/// 友好显示名称
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// 用户所在地
|
||||||
|
final String location;
|
||||||
|
|
||||||
|
/// 用户个人描述
|
||||||
|
final String description;
|
||||||
|
|
||||||
|
/// 用户头像地址,50×50像素
|
||||||
|
final String profileImageUrl;
|
||||||
|
|
||||||
|
/// 性别,m:男、f:女、n:未知
|
||||||
|
final String gender;
|
||||||
|
|
||||||
|
/// 用户大头像地址
|
||||||
|
final String avatarLarge;
|
||||||
|
|
||||||
|
/// 用户高清大头像地址
|
||||||
|
final String avatarHd;
|
||||||
|
|
||||||
|
bool isMale() {
|
||||||
|
return gender == 'm';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFemale() {
|
||||||
|
return gender == 'f';
|
||||||
|
}
|
||||||
|
}
|
54
lib/src/domain/api/weibo_user_info_resp.jser.dart
Normal file
54
lib/src/domain/api/weibo_user_info_resp.jser.dart
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'weibo_user_info_resp.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JaguarSerializerGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
abstract class _$WeiboUserInfoRespSerializer
|
||||||
|
implements Serializer<WeiboUserInfoResp> {
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toMap(WeiboUserInfoResp model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
Map<String, dynamic> ret = <String, dynamic>{};
|
||||||
|
setMapValue(ret, 'id', model.id);
|
||||||
|
setMapValue(ret, 'idstr', model.idstr);
|
||||||
|
setMapValue(ret, 'screen_name', model.screenName);
|
||||||
|
setMapValue(ret, 'name', model.name);
|
||||||
|
setMapValue(ret, 'location', model.location);
|
||||||
|
setMapValue(ret, 'description', model.description);
|
||||||
|
setMapValue(ret, 'profile_image_url', model.profileImageUrl);
|
||||||
|
setMapValue(ret, 'gender', model.gender);
|
||||||
|
setMapValue(ret, 'avatar_large', model.avatarLarge);
|
||||||
|
setMapValue(ret, 'avatar_hd', model.avatarHd);
|
||||||
|
setMapValue(ret, 'error_code', model.errorCode);
|
||||||
|
setMapValue(ret, 'error', model.error);
|
||||||
|
setMapValue(ret, 'request', model.request);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
WeiboUserInfoResp fromMap(Map map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
final obj = new WeiboUserInfoResp(
|
||||||
|
errorCode: map['error_code'] as int ?? getJserDefault('errorCode'),
|
||||||
|
error: map['error'] as String ?? getJserDefault('error'),
|
||||||
|
request: map['request'] as String ?? getJserDefault('request'),
|
||||||
|
id: map['id'] as int ?? getJserDefault('id'),
|
||||||
|
idstr: map['idstr'] as String ?? getJserDefault('idstr'),
|
||||||
|
screenName:
|
||||||
|
map['screen_name'] as String ?? getJserDefault('screenName'),
|
||||||
|
name: map['name'] as String ?? getJserDefault('name'),
|
||||||
|
location: map['location'] as String ?? getJserDefault('location'),
|
||||||
|
description:
|
||||||
|
map['description'] as String ?? getJserDefault('description'),
|
||||||
|
profileImageUrl: map['profile_image_url'] as String ??
|
||||||
|
getJserDefault('profileImageUrl'),
|
||||||
|
gender: map['gender'] as String ?? getJserDefault('gender'),
|
||||||
|
avatarLarge:
|
||||||
|
map['avatar_large'] as String ?? getJserDefault('avatarLarge'),
|
||||||
|
avatarHd: map['avatar_hd'] as String ?? getJserDefault('avatarHd'));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
24
lib/src/domain/sdk/weibo_auth_resp.dart
Normal file
24
lib/src/domain/sdk/weibo_auth_resp.dart
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
||||||
|
import 'package:fake_weibo/src/domain/sdk/weibo_sdk_resp.dart';
|
||||||
|
|
||||||
|
part 'weibo_auth_resp.jser.dart';
|
||||||
|
|
||||||
|
@GenSerializer()
|
||||||
|
class WeiboAuthRespSerializer extends Serializer<WeiboAuthResp>
|
||||||
|
with _$WeiboAuthRespSerializer {}
|
||||||
|
|
||||||
|
class WeiboAuthResp extends WeiboSdkResp {
|
||||||
|
WeiboAuthResp({
|
||||||
|
int errorCode,
|
||||||
|
String errorMessage,
|
||||||
|
this.userId,
|
||||||
|
this.accessToken,
|
||||||
|
this.refreshToken,
|
||||||
|
this.expiresIn,
|
||||||
|
}) : super(errorCode: errorCode, errorMessage: errorMessage);
|
||||||
|
|
||||||
|
final String userId;
|
||||||
|
final String accessToken;
|
||||||
|
final String refreshToken;
|
||||||
|
final int expiresIn;
|
||||||
|
}
|
38
lib/src/domain/sdk/weibo_auth_resp.jser.dart
Normal file
38
lib/src/domain/sdk/weibo_auth_resp.jser.dart
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'weibo_auth_resp.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JaguarSerializerGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
abstract class _$WeiboAuthRespSerializer implements Serializer<WeiboAuthResp> {
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toMap(WeiboAuthResp model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
Map<String, dynamic> ret = <String, dynamic>{};
|
||||||
|
setMapValue(ret, 'userId', model.userId);
|
||||||
|
setMapValue(ret, 'accessToken', model.accessToken);
|
||||||
|
setMapValue(ret, 'refreshToken', model.refreshToken);
|
||||||
|
setMapValue(ret, 'expiresIn', model.expiresIn);
|
||||||
|
setMapValue(ret, 'errorCode', model.errorCode);
|
||||||
|
setMapValue(ret, 'errorMessage', model.errorMessage);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
WeiboAuthResp fromMap(Map map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
final obj = new WeiboAuthResp(
|
||||||
|
errorCode: map['errorCode'] as int ?? getJserDefault('errorCode'),
|
||||||
|
errorMessage:
|
||||||
|
map['errorMessage'] as String ?? getJserDefault('errorMessage'),
|
||||||
|
userId: map['userId'] as String ?? getJserDefault('userId'),
|
||||||
|
accessToken:
|
||||||
|
map['accessToken'] as String ?? getJserDefault('accessToken'),
|
||||||
|
refreshToken:
|
||||||
|
map['refreshToken'] as String ?? getJserDefault('refreshToken'),
|
||||||
|
expiresIn: map['expiresIn'] as int ?? getJserDefault('expiresIn'));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
47
lib/src/domain/sdk/weibo_sdk_resp.dart
Normal file
47
lib/src/domain/sdk/weibo_sdk_resp.dart
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
||||||
|
|
||||||
|
part 'weibo_sdk_resp.jser.dart';
|
||||||
|
|
||||||
|
@GenSerializer()
|
||||||
|
class WeiboSdkRespSerializer extends Serializer<WeiboSdkResp>
|
||||||
|
with _$WeiboSdkRespSerializer {}
|
||||||
|
|
||||||
|
class WeiboSdkResp {
|
||||||
|
WeiboSdkResp({
|
||||||
|
int errorCode,
|
||||||
|
this.errorMessage,
|
||||||
|
}) : errorCode = errorCode ?? SUCCESS;
|
||||||
|
|
||||||
|
/// 成功
|
||||||
|
static const int SUCCESS = 0;
|
||||||
|
|
||||||
|
/// 用户取消发送
|
||||||
|
static const int USERCANCEL = -1;
|
||||||
|
|
||||||
|
/// 发送失败
|
||||||
|
static const int SENT_FAIL = -2;
|
||||||
|
|
||||||
|
/// 授权失败
|
||||||
|
static const int AUTH_DENY = -3;
|
||||||
|
|
||||||
|
/// 用户取消安装微博客户端
|
||||||
|
static const int USERCANCEL_INSTALL = -4;
|
||||||
|
|
||||||
|
/// 支付失败
|
||||||
|
static const int PAY_FAIL = -5;
|
||||||
|
|
||||||
|
/// 分享失败 详情见response UserInfo
|
||||||
|
static const int SHARE_IN_SDK_FAILED = -8;
|
||||||
|
|
||||||
|
/// 不支持的请求
|
||||||
|
static const int UNSUPPORT = -99;
|
||||||
|
|
||||||
|
/// 未知
|
||||||
|
static const int UNKNOWN = -100;
|
||||||
|
|
||||||
|
/// sso package or sign error
|
||||||
|
static const int SSO_PKG_SIGN_ERROR = 21338;
|
||||||
|
|
||||||
|
final int errorCode;
|
||||||
|
final String errorMessage;
|
||||||
|
}
|
28
lib/src/domain/sdk/weibo_sdk_resp.jser.dart
Normal file
28
lib/src/domain/sdk/weibo_sdk_resp.jser.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'weibo_sdk_resp.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JaguarSerializerGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
abstract class _$WeiboSdkRespSerializer implements Serializer<WeiboSdkResp> {
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toMap(WeiboSdkResp model) {
|
||||||
|
if (model == null) return null;
|
||||||
|
Map<String, dynamic> ret = <String, dynamic>{};
|
||||||
|
setMapValue(ret, 'errorCode', model.errorCode);
|
||||||
|
setMapValue(ret, 'errorMessage', model.errorMessage);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
WeiboSdkResp fromMap(Map map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
final obj = new WeiboSdkResp(
|
||||||
|
errorCode: map['errorCode'] as int ?? getJserDefault('errorCode'),
|
||||||
|
errorMessage:
|
||||||
|
map['errorMessage'] as String ?? getJserDefault('errorMessage'));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
221
lib/src/weibo.dart
Normal file
221
lib/src/weibo.dart
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:fake_weibo/src/domain/api/weibo_user_info_resp.dart';
|
||||||
|
import 'package:fake_weibo/src/domain/sdk/weibo_auth_resp.dart';
|
||||||
|
import 'package:fake_weibo/src/domain/sdk/weibo_sdk_resp.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
class Weibo {
|
||||||
|
static const String _METHOD_REGISTERAPP = 'registerApp';
|
||||||
|
static const String _METHOD_ISWEIBOINSTALLED = 'isWeiboInstalled';
|
||||||
|
static const String _METHOD_AUTH = 'auth';
|
||||||
|
static const String _METHOD_SHARETEXT = 'shareText';
|
||||||
|
static const String _METHOD_SHAREIMAGE = 'shareImage';
|
||||||
|
static const String _METHOD_SHAREWEBPAGE = 'shareWebpage';
|
||||||
|
|
||||||
|
static const String _METHOD_ONAUTHRESP = 'onAuthResp';
|
||||||
|
static const String _METHOD_ONSHAREMSGRESP = 'onShareMsgResp';
|
||||||
|
|
||||||
|
static const String _ARGUMENT_KEY_APPKEY = 'appKey';
|
||||||
|
static const String _ARGUMENT_KEY_SCOPE = 'scope';
|
||||||
|
static const String _ARGUMENT_KEY_REDIRECTURL = 'redirectUrl';
|
||||||
|
static const String _ARGUMENT_KEY_TEXT = 'text';
|
||||||
|
static const String _ARGUMENT_KEY_TITLE = 'title';
|
||||||
|
static const String _ARGUMENT_KEY_DESCRIPTION = 'description';
|
||||||
|
static const String _ARGUMENT_KEY_THUMBDATA = 'thumbData';
|
||||||
|
static const String _ARGUMENT_KEY_IMAGEDATA = 'imageData';
|
||||||
|
static const String _ARGUMENT_KEY_WEBPAGEURL = 'webpageUrl';
|
||||||
|
|
||||||
|
static const String _DEFAULT_REDIRECTURL =
|
||||||
|
'https://api.weibo.com/oauth2/default.html';
|
||||||
|
|
||||||
|
static const MethodChannel _channel =
|
||||||
|
MethodChannel('v7lin.github.io/fake_weibo');
|
||||||
|
|
||||||
|
final StreamController<WeiboAuthResp> _authRespStreamController =
|
||||||
|
StreamController<WeiboAuthResp>.broadcast();
|
||||||
|
|
||||||
|
final StreamController<WeiboSdkResp> _shareMsgRespStreamController =
|
||||||
|
StreamController<WeiboSdkResp>.broadcast();
|
||||||
|
|
||||||
|
Future<void> registerApp({
|
||||||
|
@required String appKey,
|
||||||
|
@required List<String> scope,
|
||||||
|
String redirectUrl =
|
||||||
|
_DEFAULT_REDIRECTURL, // 新浪微博开放平台 -> 我的应用 -> 应用信息 -> 高级信息 -> OAuth2.0授权设置
|
||||||
|
}) {
|
||||||
|
assert(appKey != null && appKey.isNotEmpty);
|
||||||
|
assert(scope != null && scope.isNotEmpty);
|
||||||
|
_channel.setMethodCallHandler(_handleMethod);
|
||||||
|
return _channel.invokeMethod(
|
||||||
|
_METHOD_REGISTERAPP,
|
||||||
|
<String, dynamic>{
|
||||||
|
_ARGUMENT_KEY_APPKEY: appKey,
|
||||||
|
_ARGUMENT_KEY_SCOPE: scope.join(','),
|
||||||
|
_ARGUMENT_KEY_REDIRECTURL: redirectUrl,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
|
switch (call.method) {
|
||||||
|
case _METHOD_ONAUTHRESP:
|
||||||
|
_authRespStreamController.add(WeiboAuthRespSerializer()
|
||||||
|
.fromMap(call.arguments as Map<dynamic, dynamic>));
|
||||||
|
break;
|
||||||
|
case _METHOD_ONSHAREMSGRESP:
|
||||||
|
_shareMsgRespStreamController.add(WeiboSdkRespSerializer()
|
||||||
|
.fromMap(call.arguments as Map<dynamic, dynamic>));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<WeiboAuthResp> authResp() {
|
||||||
|
return _authRespStreamController.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<WeiboSdkResp> shareMsgResp() {
|
||||||
|
return _shareMsgRespStreamController.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isWeiboInstalled() async {
|
||||||
|
return (await _channel.invokeMethod(_METHOD_ISWEIBOINSTALLED)) as bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> auth({
|
||||||
|
@required String appKey,
|
||||||
|
@required List<String> scope,
|
||||||
|
String redirectUrl = _DEFAULT_REDIRECTURL,
|
||||||
|
}) {
|
||||||
|
assert(appKey != null && appKey.isNotEmpty);
|
||||||
|
assert(scope != null && scope.isNotEmpty);
|
||||||
|
return _channel.invokeMethod(
|
||||||
|
_METHOD_AUTH,
|
||||||
|
<String, dynamic>{
|
||||||
|
_ARGUMENT_KEY_APPKEY: appKey,
|
||||||
|
_ARGUMENT_KEY_SCOPE: scope.join(','),
|
||||||
|
_ARGUMENT_KEY_REDIRECTURL: redirectUrl,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<WeiboUserInfoResp> getUserInfo({
|
||||||
|
@required String appkey,
|
||||||
|
@required String userId,
|
||||||
|
@required String accessToken,
|
||||||
|
}) {
|
||||||
|
assert(userId != null && userId.isNotEmpty);
|
||||||
|
assert(accessToken != null && accessToken.isNotEmpty);
|
||||||
|
Map<String, String> params = <String, String>{
|
||||||
|
'uid': userId,
|
||||||
|
};
|
||||||
|
return HttpClient()
|
||||||
|
.getUrl(_encodeUrl('https://api.weibo.com/2/users/show.json', appkey,
|
||||||
|
accessToken, params))
|
||||||
|
.then((HttpClientRequest request) {
|
||||||
|
return request.close();
|
||||||
|
}).then((HttpClientResponse response) async {
|
||||||
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
|
String content = await utf8.decodeStream(response);
|
||||||
|
return WeiboUserInfoRespSerializer()
|
||||||
|
.fromMap(json.decode(content) as Map<dynamic, dynamic>);
|
||||||
|
}
|
||||||
|
throw HttpException(
|
||||||
|
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri _encodeUrl(
|
||||||
|
String baseUrl,
|
||||||
|
String appkey,
|
||||||
|
String accessToken,
|
||||||
|
Map<String, String> params,
|
||||||
|
) {
|
||||||
|
params.putIfAbsent('source', () => appkey);
|
||||||
|
params.putIfAbsent('access_token', () => accessToken);
|
||||||
|
|
||||||
|
Uri baseUri = Uri.parse(baseUrl);
|
||||||
|
Map<String, List<String>> queryParametersAll =
|
||||||
|
Map<String, List<String>>.of(baseUri.queryParametersAll);
|
||||||
|
params.forEach((String key, String value) {
|
||||||
|
queryParametersAll.remove(key);
|
||||||
|
queryParametersAll.putIfAbsent(key, () => <String>[value]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return baseUri.replace(queryParameters: queryParametersAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> shareText({
|
||||||
|
@required String text,
|
||||||
|
}) {
|
||||||
|
assert(text != null && text.isNotEmpty && text.length <= 1024);
|
||||||
|
return _channel.invokeMethod(
|
||||||
|
_METHOD_SHARETEXT,
|
||||||
|
<String, dynamic>{
|
||||||
|
_ARGUMENT_KEY_TEXT: text,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> shareImage({
|
||||||
|
@required Uint8List imageData,
|
||||||
|
}) {
|
||||||
|
assert(imageData != null && imageData.lengthInBytes <= 2 * 1024 * 1024);
|
||||||
|
return _channel.invokeMethod(
|
||||||
|
_METHOD_SHAREIMAGE,
|
||||||
|
<String, dynamic>{
|
||||||
|
_ARGUMENT_KEY_IMAGEDATA: imageData,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> shareWebpage({
|
||||||
|
@required String title,
|
||||||
|
@required String description,
|
||||||
|
@required Uint8List thumbData,
|
||||||
|
@required String webpageUrl,
|
||||||
|
}) {
|
||||||
|
assert(title != null && title.isNotEmpty && title.length <= 512);
|
||||||
|
assert(description != null &&
|
||||||
|
description.isNotEmpty &&
|
||||||
|
description.length <= 1024);
|
||||||
|
assert(thumbData != null && thumbData.lengthInBytes <= 32 * 1024);
|
||||||
|
assert(webpageUrl != null &&
|
||||||
|
webpageUrl.isNotEmpty &&
|
||||||
|
webpageUrl.length <= 255);
|
||||||
|
return _channel.invokeMethod(
|
||||||
|
_METHOD_SHAREWEBPAGE,
|
||||||
|
<String, dynamic>{
|
||||||
|
_ARGUMENT_KEY_TITLE: title,
|
||||||
|
_ARGUMENT_KEY_DESCRIPTION: description,
|
||||||
|
_ARGUMENT_KEY_THUMBDATA: thumbData,
|
||||||
|
_ARGUMENT_KEY_WEBPAGEURL: webpageUrl,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeiboProvider extends InheritedWidget {
|
||||||
|
WeiboProvider({
|
||||||
|
Key key,
|
||||||
|
@required this.weibo,
|
||||||
|
@required Widget child,
|
||||||
|
}) : super(key: key, child: child);
|
||||||
|
|
||||||
|
final Weibo weibo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool updateShouldNotify(InheritedWidget oldWidget) {
|
||||||
|
WeiboProvider oldProvider = oldWidget as WeiboProvider;
|
||||||
|
return weibo != oldProvider.weibo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WeiboProvider of(BuildContext context) {
|
||||||
|
return context.inheritFromWidgetOfExactType(WeiboProvider) as WeiboProvider;
|
||||||
|
}
|
||||||
|
}
|
14
lib/src/weibo_scope.dart
Normal file
14
lib/src/weibo_scope.dart
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class WeiboScope {
|
||||||
|
WeiboScope._();
|
||||||
|
|
||||||
|
static const String EMAIL = 'email';
|
||||||
|
static const String DIRECT_MESSAGES_READ = 'direct_messages_read';
|
||||||
|
static const String DIRECT_MESSAGES_WRITE = 'direct_messages_write';
|
||||||
|
static const String FRIENDSHIPS_GROUPS_READ = 'friendships_groups_read';
|
||||||
|
static const String FRIENDSHIPS_GROUPS_WRITE = 'friendships_groups_write';
|
||||||
|
static const String STATUSES_TO_ME_READ = 'statuses_to_me_read';
|
||||||
|
static const String FOLLOW_APP_OFFICIAL_MICROBLOG =
|
||||||
|
'follow_app_official_microblog';
|
||||||
|
static const String INVITATION_WRITE = 'invitation_write';
|
||||||
|
static const String ALL = 'all';
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
name: fake_weibo
|
name: fake_weibo
|
||||||
description: A powerful weibo plugin for Flutter.
|
description: A powerful weibo plugin for Flutter.
|
||||||
version: 0.0.1+1
|
version: 0.1.0
|
||||||
author: v7lin <v7lin@qq.com>
|
author: v7lin <v7lin@qq.com>
|
||||||
homepage: https://github.com/v7lin/fake_weibo
|
homepage: https://github.com/v7lin/fake_weibo
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:fake_weibo/src/domain/api/weibo_user_info_resp.dart';
|
||||||
|
import 'package:fake_weibo/src/domain/sdk/weibo_auth_resp.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
import 'package:jaguar_serializer/jaguar_serializer.dart';
|
||||||
|
|
||||||
@ -21,6 +25,19 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('smoke test - jaguar_serializer', () {
|
test('smoke test - jaguar_serializer', () {
|
||||||
|
WeiboAuthResp authResp = WeiboAuthRespSerializer().fromMap(json.decode(
|
||||||
|
'{"expiresIn":157679999,"errorCode":0,"accessToken":"2.00s67kHGj4SghD8e46233eea9O1IDB","userId":"5611295980","refreshToken":"2.00s67kHGj4SghD6ee52b48200iqHz3"}')
|
||||||
|
as Map<dynamic, dynamic>);
|
||||||
|
expect(authResp.errorCode, equals(0));
|
||||||
|
expect(authResp.expiresIn, equals(157679999));
|
||||||
|
expect(authResp.accessToken, equals('2.00s67kHGj4SghD8e46233eea9O1IDB'));
|
||||||
|
|
||||||
|
WeiboUserInfoResp userInfoResp = WeiboUserInfoRespSerializer().fromMap(json.decode(
|
||||||
|
'{"id":5611295980,"idstr":"5611295980","class":1,"screen_name":"v7lin","name":"v7lin","province":"35","city":"1","location":"福建 福州","description":"","url":"","profile_image_url":"http://tvax4.sinaimg.cn/crop.0.0.640.640.50/0067KqpSly8fujqh4oj39j30hs0hsjs6.jpg","cover_image_phone":"http://ww1.sinaimg.cn/crop.0.0.640.640.640/549d0121tw1egm1kjly3jj20hs0hsq4f.jpg","profile_url":"u/5611295980","domain":"","weihao":"","gender":"m","followers_count":1,"friends_count":1,"pagefriends_count":0,"statuses_count":0,"video_status_count":0,"favourites_count":0,"created_at":"Mon May 18 19:32:52 +0800 2015","following":false,"allow_all_act_msg":false,"geo_enabled":true,"verified":false,"verified_type":-1,"remark":"","insecurity":{"sexual_content":false},"ptype":0,"allow_all_comment":true,"avatar_large":"http://tvax4.sinaimg.cn/crop.0.0.640.640.180/0067KqpSly8fujqh4oj39j30hs0hsjs6.jpg","avatar_hd":"http://tvax4.sinaimg.cn/crop.0.0.640.640.1024/0067KqpSly8fujqh4oj39j30hs0hsjs6.jpg","verified_reason":"","verified_trade":"","verified_reason_url":"","verified_source":"","verified_source_url":"","follow_me":false,"like":false,"like_me":false,"online_status":0,"bi_followers_count":0,"lang":"zh-cn","star":0,"mbtype":0,"mbrank":0,"block_word":0,"block_app":0,"credit_score":80,"user_ability":0,"urank":4,"story_read_state":-1,"vclub_member":0,"is_teenager":0,"is_guardian":0,"is_teenager_list":0}')
|
||||||
|
as Map<dynamic, dynamic>);
|
||||||
|
expect(userInfoResp.errorCode, equals(0));
|
||||||
|
expect(userInfoResp.id, equals(5611295980));
|
||||||
|
expect(userInfoResp.screenName, equals('v7lin'));
|
||||||
|
expect(userInfoResp.avatarHd, equals('http://tvax4.sinaimg.cn/crop.0.0.640.640.1024/0067KqpSly8fujqh4oj39j30hs0hsjs6.jpg'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user