reason

update mvvm

......@@ -4,13 +4,16 @@ import 'package:Parlando/generated/json/user_entity.g.dart';
@JsonSerializable()
class UserEntity {
late int id;
late String name;
late String avatar;
String? status;
int? code;
String? message;
UserData? data;
UserError? error;
UserEntity();
factory UserEntity.fromJson(Map<String, dynamic> json) => $UserEntityFromJson(json);
factory UserEntity.fromJson(Map<String, dynamic> json) =>
$UserEntityFromJson(json);
Map<String, dynamic> toJson() => $UserEntityToJson(this);
......@@ -18,4 +21,49 @@ class UserEntity {
String toString() {
return jsonEncode(this);
}
}
@JsonSerializable()
class UserData {
int? id;
dynamic nickname;
dynamic mobile;
String? email;
String? avatar;
String? gender;
dynamic provider;
@JSONField(name: "provider_id")
dynamic providerId;
String? state;
@JSONField(name: "created_at")
String? createdAt;
@JSONField(name: "updated_at")
String? updatedAt;
UserData();
factory UserData.fromJson(Map<String, dynamic> json) =>
$UserDataFromJson(json);
Map<String, dynamic> toJson() => $UserDataToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
@JsonSerializable()
class UserError {
UserError();
factory UserError.fromJson(Map<String, dynamic> json) =>
$UserErrorFromJson(json);
Map<String, dynamic> toJson() => $UserErrorToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
\ No newline at end of file
......
This diff is collapsed. Click to expand it.
import 'package:Parlando/account/models/user_entity.dart';
import 'package:Parlando/apis/api_response.dart';
import 'package:Parlando/net/dio_utils.dart';
import 'package:Parlando/net/http_api.dart';
import 'package:flutter/material.dart';
class AccountViewProvider with ChangeNotifier {
ApiResponse _apiResponse = ApiResponse.initial('Empty data');
UserData? _user;
ApiResponse get response {
return _apiResponse;
}
UserData? get media {
return _user;
}
Future<void> fetchAccountData(String value) async {
_apiResponse = ApiResponse.loading('Fetching artist data');
// TODO 不知道为啥会提前触发,先注释掉吧
DioUtils.instance.asyncRequestNetwork<UserEntity>(
Method.get,
HttpApi.user,
onSuccess: (data) {
_apiResponse = ApiResponse.completed(data!.data);
notifyListeners();
},
onError: (code, msg) {
_apiResponse = ApiResponse.error(msg);
notifyListeners();
},
);
}
void setSelectedAccount(UserData? user) {
_user = user;
// notifyListeners();
}
}
class ApiResponse<T> {
Status status;
T? data;
String? message;
ApiResponse.initial(this.message) : status = Status.INITIAL;
ApiResponse.loading(this.message) : status = Status.LOADING;
ApiResponse.completed(this.data) : status = Status.COMPLETED;
ApiResponse.error(this.message) : status = Status.ERROR;
@override
String toString() {
return "Status : $status \n Message : $message \n Data : $data";
}
}
enum Status { INITIAL, LOADING, COMPLETED, ERROR }
class AppException implements Exception {
late final String? _message;
late final String? _prefix;
AppException([this._message, this._prefix]);
@override
String toString() {
return "$_prefix$_message";
}
}
class FetchDataException extends AppException {
FetchDataException([String? message])
: super(message, "Error During Communication: ");
}
class BadRequestException extends AppException {
BadRequestException([message]) : super(message, "Invalid Request: ");
}
class UnauthorisedException extends AppException {
UnauthorisedException([message]) : super(message, "Unauthorised Request: ");
}
class InvalidInputException extends AppException {
InvalidInputException([String? message]) : super(message, "Invalid Input: ");
}
import 'package:Parlando/generated/json/base/json_convert_content.dart';
import 'package:Parlando/login/models/auth_entity.dart';
AuthEntity $LoginEntityFromJson(Map<String, dynamic> json) {
final AuthEntity loginEntity = AuthEntity();
AuthEntity $AuthEntityFromJson(Map<String, dynamic> json) {
final AuthEntity authEntity = AuthEntity();
final String? status = jsonConvert.convert<String>(json['status']);
if (status != null) {
loginEntity.status = status;
authEntity.status = status;
}
final int? code = jsonConvert.convert<int>(json['code']);
if (code != null) {
loginEntity.code = code;
authEntity.code = code;
}
final String? message = jsonConvert.convert<String>(json['message']);
if (message != null) {
loginEntity.message = message;
authEntity.message = message;
}
final AuthData? data = jsonConvert.convert<AuthData>(json['data']);
if (data != null) {
loginEntity.data = data;
authEntity.data = data;
}
final AuthError? error = jsonConvert.convert<AuthError>(json['error']);
if (error != null) {
loginEntity.error = error;
authEntity.error = error;
}
return loginEntity;
return authEntity;
}
Map<String, dynamic> $LoginEntityToJson(AuthEntity entity) {
Map<String, dynamic> $AuthEntityToJson(AuthEntity entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['status'] = entity.status;
data['code'] = entity.code;
......@@ -36,27 +36,27 @@ Map<String, dynamic> $LoginEntityToJson(AuthEntity entity) {
return data;
}
AuthData $LoginDataFromJson(Map<String, dynamic> json) {
final AuthData loginData = AuthData();
AuthData $AuthDataFromJson(Map<String, dynamic> json) {
final AuthData authData = AuthData();
final String? token = jsonConvert.convert<String>(json['token']);
if (token != null) {
loginData.token = token;
authData.token = token;
}
return loginData;
return authData;
}
Map<String, dynamic> $LoginDataToJson(AuthData entity) {
Map<String, dynamic> $AuthDataToJson(AuthData entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['token'] = entity.token;
return data;
}
AuthError $LoginErrorFromJson(Map<String, dynamic> json) {
final AuthError loginError = AuthError();
return loginError;
AuthError $AuthErrorFromJson(Map<String, dynamic> json) {
final AuthError authError = AuthError();
return authError;
}
Map<String, dynamic> $LoginErrorToJson(AuthError entity) {
Map<String, dynamic> $AuthErrorToJson(AuthError entity) {
final Map<String, dynamic> data = <String, dynamic>{};
return data;
}
......
......@@ -3,24 +3,41 @@
// ignore_for_file: prefer_single_quotes
// This file is automatically generated. DO NOT EDIT, all your changes would be lost.
import 'package:flutter/material.dart';
import 'package:Parlando/account/models/user_entity.dart';
import 'package:Parlando/generated/json/user_entity.g.dart';
import 'package:Parlando/category/models/category_item_entity.dart';
import 'package:Parlando/generated/json/category_item_entity.g.dart';
import 'package:Parlando/home/models/setting_entity.dart';
import 'package:Parlando/generated/json/setting_entity.g.dart';
import 'package:Parlando/login/models/auth_entity.dart';
import 'package:Parlando/generated/json/login_entity.g.dart';
import 'package:Parlando/poem/models/lang_sort_entity.dart';
import 'package:Parlando/generated/json/lang_sort_entity.g.dart';
import 'package:Parlando/poem/models/search_entity.dart';
import 'package:Parlando/generated/json/search_entity.g.dart';
import 'package:Parlando/timeline/models/friend_entity.dart';
import 'package:Parlando/generated/json/friend_entity.g.dart';
JsonConvert jsonConvert = JsonConvert();
typedef JsonConvertFunction<T> = T Function(Map<String, dynamic> json);
class JsonConvert {
static final Map<String, JsonConvertFunction> _convertFuncMap = {
(UserEntity).toString(): UserEntity.fromJson,
(UserData).toString(): UserData.fromJson,
(UserError).toString(): UserError.fromJson,
(CategoryItemEntity).toString(): CategoryItemEntity.fromJson,
(SettingEntity).toString(): SettingEntity.fromJson,
(SettingData).toString(): SettingData.fromJson,
(SettingDataLoginSetting).toString(): SettingDataLoginSetting.fromJson,
(SettingError).toString(): SettingError.fromJson,
(AuthEntity).toString(): AuthEntity.fromJson,
(AuthData).toString(): AuthData.fromJson,
(AuthError).toString(): AuthError.fromJson,
(LangSortEntity).toString(): LangSortEntity.fromJson,
(SearchEntity).toString(): SearchEntity.fromJson,
(SearchItems).toString(): SearchItems.fromJson,
(SearchItemsOwner).toString(): SearchItemsOwner.fromJson,
(SearchItemsLicense).toString(): SearchItemsLicense.fromJson,
(FriendEntity).toString(): FriendEntity.fromJson,
(FriendData).toString(): FriendData.fromJson,
};
T? convert<T>(dynamic value) {
if (value == null) {
return null;
......@@ -35,7 +52,7 @@ class JsonConvert {
try {
return value.map((dynamic e) => asT<T>(e)).toList();
} catch (e, stackTrace) {
print('asT<$T> $e $stackTrace');
debugPrint('asT<$T> $e $stackTrace');
return <T>[];
}
}
......@@ -47,15 +64,16 @@ class JsonConvert {
try {
return (value as List<dynamic>).map((dynamic e) => asT<T>(e)!).toList();
} catch (e, stackTrace) {
print('asT<$T> $e $stackTrace');
debugPrint('asT<$T> $e $stackTrace');
return <T>[];
}
}
T? asT<T extends Object?>(dynamic value) {
if (value is T) {
return value;
}
final String type = T.toString();
final String type = T.toString();
try {
final String valueS = value.toString();
if (type == "String") {
......@@ -66,87 +84,48 @@ class JsonConvert {
return double.tryParse(valueS)?.toInt() as T?;
} else {
return intValue as T;
} } else if (type == "double") {
}
} else if (type == "double") {
return double.parse(valueS) as T;
} else if (type == "DateTime") {
} else if (type == "DateTime") {
return DateTime.parse(valueS) as T;
} else if (type == "bool") {
} else if (type == "bool") {
if (valueS == '0' || valueS == '1') {
return (valueS == '1') as T;
}
return (valueS == 'true') as T;
} else if (type == "Map" || type.startsWith("Map<")) {
return value as T;
} else {
return JsonConvert.fromJsonAsT<T>(value);
if (_convertFuncMap.containsKey(type)) {
return _convertFuncMap[type]!(value) as T;
} else {
throw UnimplementedError('$type unimplemented');
}
}
} catch (e, stackTrace) {
print('asT<$T> $e $stackTrace');
debugPrint('asT<$T> $e $stackTrace');
return null;
}
}
//Go back to a single instance by type
static M? _fromJsonSingle<M>(Map<String, dynamic> json) {
final String type = M.toString();
if (type == (UserEntity).toString()) {
return UserEntity.fromJson(json) as M;
}
if (type == (CategoryItemEntity).toString()) {
return CategoryItemEntity.fromJson(json) as M;
}
if (type == (SettingEntity).toString()) {
return SettingEntity.fromJson(json) as M;
}
if (type == (SettingData).toString()) {
return SettingData.fromJson(json) as M;
}
if (type == (SettingDataLoginSetting).toString()) {
return SettingDataLoginSetting.fromJson(json) as M;
}
if (type == (SettingError).toString()) {
return SettingError.fromJson(json) as M;
}
if (type == (AuthEntity).toString()) {
return AuthEntity.fromJson(json) as M;
}
if (type == (AuthData).toString()) {
return AuthData.fromJson(json) as M;
}
if (type == (AuthError).toString()) {
return AuthError.fromJson(json) as M;
}
if (type == (LangSortEntity).toString()) {
return LangSortEntity.fromJson(json) as M;
}
if (type == (SearchEntity).toString()) {
return SearchEntity.fromJson(json) as M;
}
if (type == (SearchItems).toString()) {
return SearchItems.fromJson(json) as M;
}
if (type == (SearchItemsOwner).toString()) {
return SearchItemsOwner.fromJson(json) as M;
}
if (type == (SearchItemsLicense).toString()) {
return SearchItemsLicense.fromJson(json) as M;
}
if (type == (FriendEntity).toString()) {
return FriendEntity.fromJson(json) as M;
}
if (type == (FriendData).toString()) {
return FriendData.fromJson(json) as M;
}
print("$type not found");
return null;
}
}
//list is returned by type
static M? _getListChildType<M>(List<Map<String, dynamic>> data) {
static M? _getListChildType<M>(List<Map<String, dynamic>> data) {
if (<UserEntity>[] is M) {
return data
.map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e))
.toList() as M;
}
if (<UserData>[] is M) {
return data
.map<UserData>((Map<String, dynamic> e) => UserData.fromJson(e))
.toList() as M;
}
if (<UserError>[] is M) {
return data
.map<UserError>((Map<String, dynamic> e) => UserError.fromJson(e))
.toList() as M;
}
if (<CategoryItemEntity>[] is M) {
return data
.map<CategoryItemEntity>(
......@@ -232,18 +211,17 @@ class JsonConvert {
.toList() as M;
}
print("${M.toString()} not found");
return null;
}
debugPrint("${M.toString()} not found");
return null;
}
static M? fromJsonAsT<M>(dynamic json) {
if(json == null){
return null;
} if (json is List) {
return _getListChildType<M>(json.map((e) => e as Map<String, dynamic>).toList());
} else {
return _fromJsonSingle<M>(json as Map<String, dynamic>);
}
}
if (json is List) {
return _getListChildType<M>(
json.map((e) => e as Map<String, dynamic>).toList());
} else {
return jsonConvert.asT<M>(json);
}
}
}
\ No newline at end of file
......
......@@ -3,25 +3,110 @@ import 'package:Parlando/account/models/user_entity.dart';
UserEntity $UserEntityFromJson(Map<String, dynamic> json) {
final UserEntity userEntity = UserEntity();
final String? status = jsonConvert.convert<String>(json['status']);
if (status != null) {
userEntity.status = status;
}
final int? code = jsonConvert.convert<int>(json['code']);
if (code != null) {
userEntity.code = code;
}
final String? message = jsonConvert.convert<String>(json['message']);
if (message != null) {
userEntity.message = message;
}
final UserData? data = jsonConvert.convert<UserData>(json['data']);
if (data != null) {
userEntity.data = data;
}
final UserError? error = jsonConvert.convert<UserError>(json['error']);
if (error != null) {
userEntity.error = error;
}
return userEntity;
}
Map<String, dynamic> $UserEntityToJson(UserEntity entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['status'] = entity.status;
data['code'] = entity.code;
data['message'] = entity.message;
data['data'] = entity.data?.toJson();
data['error'] = entity.error?.toJson();
return data;
}
UserData $UserDataFromJson(Map<String, dynamic> json) {
final UserData userData = UserData();
final int? id = jsonConvert.convert<int>(json['id']);
if (id != null) {
userEntity.id = id;
userData.id = id;
}
final dynamic? nickname = jsonConvert.convert<dynamic>(json['nickname']);
if (nickname != null) {
userData.nickname = nickname;
}
final dynamic? mobile = jsonConvert.convert<dynamic>(json['mobile']);
if (mobile != null) {
userData.mobile = mobile;
}
final String? name = jsonConvert.convert<String>(json['name']);
if (name != null) {
userEntity.name = name;
final String? email = jsonConvert.convert<String>(json['email']);
if (email != null) {
userData.email = email;
}
final String? avatar = jsonConvert.convert<String>(json['avatar']);
if (avatar != null) {
userEntity.avatar = avatar;
userData.avatar = avatar;
}
return userEntity;
final String? gender = jsonConvert.convert<String>(json['gender']);
if (gender != null) {
userData.gender = gender;
}
final dynamic? provider = jsonConvert.convert<dynamic>(json['provider']);
if (provider != null) {
userData.provider = provider;
}
final dynamic? providerId = jsonConvert.convert<dynamic>(json['provider_id']);
if (providerId != null) {
userData.providerId = providerId;
}
final String? state = jsonConvert.convert<String>(json['state']);
if (state != null) {
userData.state = state;
}
final String? createdAt = jsonConvert.convert<String>(json['created_at']);
if (createdAt != null) {
userData.createdAt = createdAt;
}
final String? updatedAt = jsonConvert.convert<String>(json['updated_at']);
if (updatedAt != null) {
userData.updatedAt = updatedAt;
}
return userData;
}
Map<String, dynamic> $UserEntityToJson(UserEntity entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = entity.id;
data['name'] = entity.name;
data['avatar'] = entity.avatar;
return data;
}
\ No newline at end of file
Map<String, dynamic> $UserDataToJson(UserData entity) {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = entity.id;
data['nickname'] = entity.nickname;
data['mobile'] = entity.mobile;
data['email'] = entity.email;
data['avatar'] = entity.avatar;
data['gender'] = entity.gender;
data['provider'] = entity.provider;
data['provider_id'] = entity.providerId;
data['state'] = entity.state;
data['created_at'] = entity.createdAt;
data['updated_at'] = entity.updatedAt;
return data;
}
UserError $UserErrorFromJson(Map<String, dynamic> json) {
final UserError userError = UserError();
return userError;
}
Map<String, dynamic> $UserErrorToJson(UserError entity) {
final Map<String, dynamic> data = <String, dynamic>{};
return data;
}
......
import 'dart:convert';
import 'package:Parlando/generated/json/base/json_field.dart';
import 'package:Parlando/generated/json/login_entity.g.dart';
import 'package:Parlando/generated/json/auth_entity.g.dart';
@JsonSerializable()
class AuthEntity {
......@@ -13,9 +13,9 @@ class AuthEntity {
AuthEntity();
factory AuthEntity.fromJson(Map<String, dynamic> json) =>
$LoginEntityFromJson(json);
$AuthEntityFromJson(json);
Map<String, dynamic> toJson() => $LoginEntityToJson(this);
Map<String, dynamic> toJson() => $AuthEntityToJson(this);
@override
String toString() {
......@@ -30,9 +30,9 @@ class AuthData {
AuthData();
factory AuthData.fromJson(Map<String, dynamic> json) =>
$LoginDataFromJson(json);
$AuthDataFromJson(json);
Map<String, dynamic> toJson() => $LoginDataToJson(this);
Map<String, dynamic> toJson() => $AuthDataToJson(this);
@override
String toString() {
......@@ -45,12 +45,12 @@ class AuthError {
AuthError();
factory AuthError.fromJson(Map<String, dynamic> json) =>
$LoginErrorFromJson(json);
$AuthErrorFromJson(json);
Map<String, dynamic> toJson() => $LoginErrorToJson(this);
Map<String, dynamic> toJson() => $AuthErrorToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
}
\ No newline at end of file
......
import 'package:Parlando/account/view_models/account_view_model.dart';
import 'package:dio/dio.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
......@@ -88,15 +89,10 @@ class MyApp extends StatelessWidget {
/// 统一添加身份验证请求头
interceptors.add(AuthInterceptor());
/// 刷新Token
interceptors.add(TokenInterceptor());
/// 打印Log(生产模式去除)
if (!Constant.inProduction) {
interceptors.add(LoggingInterceptor());
}
/// 适配数据(根据自己的数据结构,可自行选择添加)
interceptors.add(AdapterInterceptor());
configDio(
baseUrl: 'http://www.yiyan.pub/api/v1/',
......@@ -131,7 +127,8 @@ class MyApp extends StatelessWidget {
final Widget app = MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ThemeProvider()),
ChangeNotifierProvider(create: (_) => LocaleProvider())
ChangeNotifierProvider(create: (_) => LocaleProvider()),
ChangeNotifierProvider(create: (_) => AccountViewProvider())
],
child: Consumer2<ThemeProvider, LocaleProvider>(
builder:
......@@ -145,14 +142,13 @@ class MyApp extends StatelessWidget {
return OKToast(
backgroundColor: Colors.black54,
textPadding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0),
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0),
radius: 20.0,
position: ToastPosition.bottom,
child: app);
}
Widget _buildMaterialApp(
ThemeProvider provider, LocaleProvider localeProvider) {
Widget _buildMaterialApp(ThemeProvider provider, LocaleProvider localeProvider) {
return MaterialApp(
title: '一言',
// showPerformanceOverlay: true, //显示性能标签
......
......@@ -120,6 +120,33 @@ class DioUtils {
return options;
}
Future request<T>(
String method,
String url, {
Object? data,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
Options? options,
}) async {
final Response<String> response = await _dio.request<String>(
url,
data: data,
queryParameters: queryParameters,
options: _checkOptions(method, options),
cancelToken: cancelToken,
);
try {
final String data = response.data.toString();
final bool isCompute = !Constant.isDriverTest && data.length > 10 * 1024;
final Map<String, dynamic> _map =
isCompute ? await compute(parseData, data) : parseData(data);
return BaseEntity<T>.fromJson(_map);
} catch (e) {
debugPrint(e.toString());
return BaseEntity<T>(ExceptionHandle.parse_error, '数据解析错误!', null);
}
}
Future requestNetwork<T>(
Method method,
String url, {
......
......@@ -3,6 +3,7 @@ class HttpApi {
static const String register = 'register';
static const String verify = 'verify';
static const String login = 'login';
static const String user = 'user';
static const String search = 'search/repositories';
static const String subscriptions = 'users/simplezhli/subscriptions';
static const String upload = 'uuc/upload-inco';
......
......@@ -14,12 +14,11 @@ import 'error_handle.dart';
class AuthInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final String accessToken = SpUtil.getString(Constant.accessToken).nullSafe;
final String accessToken = SpUtil.getString(Constant.userToken).nullSafe;
if (accessToken.isNotEmpty) {
options.headers['Authorization'] = 'token $accessToken';
options.headers['Authorization'] = 'Bearer $accessToken';
}
if (!Device.isWeb) {
// https://developer.github.com/v3/#user-agent-required
options.headers['User-Agent'] = 'Mozilla/5.0';
}
super.onRequest(options, handler);
......
......@@ -1423,5 +1423,5 @@ packages:
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.16.0 <3.0.0"
dart: ">=2.16.2 <3.0.0"
flutter: ">=2.10.0"
......
......@@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.14.0 <3.0.0"
sdk: ">=2.16.2 <3.0.0"
flutter: ">=2.5.0"
# Dependencies specify other packages that your package needs in poem to work.
......