You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.4 KiB
177 lines
5.4 KiB
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:dde_gesture_manager/constants/sp_keys.dart';
|
|
import 'package:dde_gesture_manager/extensions.dart';
|
|
import 'package:dde_gesture_manager/models/scheme.dart' as AppScheme;
|
|
import 'package:dde_gesture_manager/utils/helper.dart';
|
|
import 'package:dde_gesture_manager/utils/notificator.dart';
|
|
import 'package:dde_gesture_manager/widgets/me.dart';
|
|
import 'package:dde_gesture_manager_api/apis.dart';
|
|
import 'package:dde_gesture_manager_api/models.dart';
|
|
import 'package:http/http.dart' as http;
|
|
|
|
typedef T BeanBuilder<T>(Map res);
|
|
|
|
typedef T HandleRespBuild<T>(http.Response resp);
|
|
|
|
typedef int GetStatusCodeFunc(Map resp);
|
|
|
|
int getStatusCodeFunc(Map resp) => resp["statusCode"] as int;
|
|
|
|
BeanBuilder<List<T>> listRespBuilderWrap<T>(BeanBuilder<T> builder) =>
|
|
(Map resp) => (resp['list'] as List).map<T>((e) => builder(e)).toList();
|
|
|
|
class HttpErrorCode extends Error {
|
|
int statusCode;
|
|
|
|
HttpErrorCode(this.statusCode, {this.message});
|
|
|
|
String? message;
|
|
|
|
@override
|
|
String toString() => '[$statusCode] $message';
|
|
}
|
|
|
|
class Api {
|
|
static _handleHttpError(e) {
|
|
if (e is SocketException) {
|
|
Notificator.error(
|
|
H().topContext,
|
|
title: LocaleKeys.info_server_error_title.tr(),
|
|
description: LocaleKeys.info_server_error_description.tr(),
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
static HandleRespBuild<T?> _handleRespBuild<T>(BeanBuilder<T> builder) => (http.Response resp) {
|
|
if (builder is GetStatusCodeFunc) return builder({"statusCode": resp.statusCode});
|
|
T? res;
|
|
try {
|
|
var decodeBody = json.decode(utf8.decode(resp.bodyBytes));
|
|
res = decodeBody is Map ? builder(decodeBody) : builder({'list': decodeBody});
|
|
} catch (e) {
|
|
e.sout();
|
|
throw HttpErrorCode(resp.statusCode, message: resp.body);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
static Future<T?> _get<T>(
|
|
String path,
|
|
BeanBuilder<T> builder, {
|
|
Map<String, dynamic>? queryParams,
|
|
bool ignoreToken = false,
|
|
bool ignoreErrorHandle = false,
|
|
}) =>
|
|
http
|
|
.get(
|
|
Uri(
|
|
scheme: Apis.apiScheme,
|
|
host: Apis.apiHost,
|
|
port: Apis.apiPort,
|
|
queryParameters: queryParams,
|
|
path: path,
|
|
),
|
|
headers: <String, String>{
|
|
HttpHeaders.contentTypeHeader: ContentType.json.toString(),
|
|
}..addAll(
|
|
ignoreToken ? {} : {HttpHeaders.authorizationHeader: 'Bearer ${H().sp.getString(SPKeys.accessToken)}'}),
|
|
)
|
|
.then<T?>(
|
|
_handleRespBuild<T>(builder),
|
|
onError: (e) {
|
|
if (ignoreErrorHandle)
|
|
throw e;
|
|
else
|
|
_handleHttpError(e);
|
|
},
|
|
);
|
|
|
|
static Future<T?> _post<T>(
|
|
String path,
|
|
BeanBuilder<T> builder, {
|
|
Map<String, dynamic>? body,
|
|
bool ignoreToken = false,
|
|
bool ignoreErrorHandle = false,
|
|
}) =>
|
|
http
|
|
.post(
|
|
Uri(
|
|
scheme: Apis.apiScheme,
|
|
host: Apis.apiHost,
|
|
port: Apis.apiPort,
|
|
path: path,
|
|
),
|
|
body: jsonEncode(body),
|
|
headers: <String, String>{
|
|
HttpHeaders.contentTypeHeader: ContentType.json.toString(),
|
|
}..addAll(
|
|
ignoreToken ? {} : {HttpHeaders.authorizationHeader: 'Bearer ${H().sp.getString(SPKeys.accessToken)}'}),
|
|
)
|
|
.then<T?>(
|
|
_handleRespBuild<T>(builder),
|
|
onError: (e) {
|
|
if (ignoreErrorHandle)
|
|
throw e;
|
|
else
|
|
_handleHttpError(e);
|
|
},
|
|
);
|
|
|
|
static Future<LoginSuccess?> loginOrSignup({
|
|
required String email,
|
|
required String password,
|
|
}) =>
|
|
_post<LoginSuccess?>(
|
|
Apis.auth.loginOrSignup,
|
|
LoginSuccessSerializer.fromMap,
|
|
body: {
|
|
UserFields.email: email,
|
|
UserFields.password: password,
|
|
},
|
|
ignoreToken: true,
|
|
);
|
|
|
|
static Future<AppVersion?> checkAppVersion({ignoreErrorHandle = false}) => _get<AppVersion?>(
|
|
Apis.system.appVersion,
|
|
AppVersionSerializer.fromMap,
|
|
ignoreToken: true,
|
|
ignoreErrorHandle: ignoreErrorHandle,
|
|
);
|
|
|
|
static Future<bool> checkAuthStatus() => _get<int>(Apis.auth.status, getStatusCodeFunc, ignoreErrorHandle: true)
|
|
.then((value) => value == HttpStatus.noContent);
|
|
|
|
static Future<bool> uploadScheme({required AppScheme.Scheme scheme, required bool share}) => _post(
|
|
Apis.scheme.upload,
|
|
getStatusCodeFunc,
|
|
body: SchemeSerializer.toMap(
|
|
Scheme(
|
|
name: scheme.name,
|
|
uuid: scheme.id,
|
|
description: scheme.description,
|
|
gestures: scheme.gestures,
|
|
shared: share,
|
|
),
|
|
),
|
|
).then((value) => value == HttpStatus.noContent);
|
|
|
|
static Future<List<SimpleSchemeTransMetaData>?> userSchemes({required SchemeListType type}) =>
|
|
_get(Apis.scheme.user(type: type.name.param), listRespBuilderWrap(SimpleSchemeTransMetaDataSerializer.fromMap));
|
|
|
|
static Future<bool> likeScheme({required String schemeId, required bool isLike}) => _get(
|
|
Apis.scheme.like(schemeId: schemeId.param, isLike: StringParam(isLike ? 'like' : 'unlike')),
|
|
getStatusCodeFunc)
|
|
.then((value) {
|
|
return value == HttpStatus.noContent;
|
|
});
|
|
|
|
static Future<SchemeForDownload?> downloadScheme({required String schemeId}) => _get(
|
|
Apis.scheme.download(schemeId: schemeId.param),
|
|
SchemeForDownloadSerializer.fromMap,
|
|
);
|
|
}
|