rluv_client/lib/global/api.dart

228 lines
6.5 KiB
Dart
Raw Permalink Normal View History

2023-07-22 21:29:32 -06:00
import 'dart:convert';
import 'package:colorful_print/colorful_print.dart';
2023-07-19 02:16:13 -06:00
import 'package:dio/dio.dart';
2023-07-22 21:29:32 -06:00
import 'package:flutter/foundation.dart';
2023-07-27 01:40:26 -06:00
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:rluv/global/store.dart';
import '../models/token.dart';
final tokenProvider = StateProvider<Token?>((ref) {
final jwt = ref.watch(jwtProvider);
printColor('Current token: $jwt', textColor: TextColor.green);
2023-07-27 01:40:26 -06:00
if (jwt == null) return null;
try {
return Token.fromJson(JwtDecoder.decode(jwt));
} catch (_) {
return null;
}
});
final jwtProvider = StateNotifierProvider<_JwtNotifier, String?>((ref) {
final prefs = ref.watch(prefsProvider);
final jwt = prefs?.getString('jwt');
return _JwtNotifier(ref, jwt);
});
class _JwtNotifier extends StateNotifier<String?> {
_JwtNotifier(this.ref, String? jwt) : super(null) {
if (jwt != null) {
setToken(jwt);
}
}
2023-07-19 02:16:13 -06:00
2023-07-27 01:40:26 -06:00
final StateNotifierProviderRef ref;
void setToken(String jwt) {
state = jwt;
printColor('Loaded jwt into client: $jwt', textColor: TextColor.cyan);
2023-07-27 01:40:26 -06:00
ref.read(prefsProvider)?.setString('jwt', jwt);
2023-07-19 02:16:13 -06:00
}
2023-07-27 01:40:26 -06:00
void revokeToken() {
printColor('jwt token revoked', textColor: TextColor.cyan);
2023-07-27 01:40:26 -06:00
state = null;
ref.read(prefsProvider)?.remove('jwt');
}
}
final apiProvider = StateNotifierProvider<_ApiNotifier, Dio>((ref) {
return _ApiNotifier(ref, Dio());
});
class _ApiNotifier extends StateNotifier<Dio> {
_ApiNotifier(this.ref, this.dio) : super(dio) {
2023-08-17 13:34:30 -06:00
// dio.options.baseUrl = "https://af70-136-36-2-234.ngrok-free.app/";
2023-07-27 01:40:26 -06:00
// dio.options.baseUrl = "http://localhost:8081/";
dio.options.baseUrl = "https://rluv.fosscat.com/";
dio.interceptors.addAll([
InterceptorsWrapper(onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
2023-07-27 01:40:26 -06:00
final jwt = ref.read(jwtProvider);
if (jwt != null) {
options.headers['token'] = jwt;
}
return handler.next(options);
}, onResponse: (Response response, ResponseInterceptorHandler handler) {
if (response.statusCode != null) {
if (response.statusCode == 200) {
try {
if ((response.data as Map<String, dynamic>).containsKey('success')) {
2023-07-27 01:40:26 -06:00
if (!response.data['success']) return handler.next(response);
}
if ((response.data as Map<String, dynamic>).containsKey('token')) {
2023-07-27 01:40:26 -06:00
final jwt = response.data['token'];
if (jwt != null) {
ref.read(jwtProvider.notifier).setToken(jwt);
// ref.read(tokenProvider.notifier).state =
// Token.fromJson(jwtData);
}
}
} catch (err) {
printColor('Error in interceptor for token: $err', textColor: TextColor.red);
2023-07-27 01:40:26 -06:00
return handler.next(response);
}
}
}
return handler.next(response);
}, onError: (DioException err, ErrorInterceptorHandler handler) {
if (err.response?.statusCode == 403) {
ref.read(jwtProvider.notifier).revokeToken();
}
2023-08-17 13:34:30 -06:00
return handler.next(err);
2023-07-27 01:40:26 -06:00
}),
_LoggingInterceptor(),
]);
}
final Dio dio;
final StateNotifierProviderRef ref;
2023-07-19 02:16:13 -06:00
Future<Map<String, dynamic>?> get(String path) async {
try {
final res = await dio.get(path);
if (res.data != null) {
return res.data as Map<String, dynamic>;
}
return null;
} catch (err) {
return null;
}
}
Future<Map<String, dynamic>?> put({required String path, Object? data}) async {
2023-07-19 02:16:13 -06:00
try {
final res = await dio.put(path, data: data);
if (res.data != null) {
return res.data as Map<String, dynamic>;
}
return null;
} catch (err) {
return null;
}
}
Future<Map<String, dynamic>?> post({required String path, Object? data}) async {
2023-07-22 21:29:32 -06:00
try {
final res = await dio.post(path, data: data);
if (res.data != null) {
return res.data as Map<String, dynamic>;
}
return null;
} catch (err) {
return null;
}
}
Future<Map<String, dynamic>?> delete({required String path, Object? data}) async {
2023-07-19 02:16:13 -06:00
try {
final res = await dio.delete(path, data: data);
if (res.data != null) {
return res.data as Map<String, dynamic>;
}
return null;
} catch (err) {
return null;
}
}
}
2023-07-22 21:29:32 -06:00
2023-07-27 01:40:26 -06:00
class _LoggingInterceptor extends Interceptor {
_LoggingInterceptor();
2023-07-22 21:29:32 -06:00
@override
Future onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
2023-07-22 21:29:32 -06:00
logPrint('///*** REQUEST ***\\\\\\');
printKV('URI', options.uri);
printKV('METHOD', options.method);
logPrint('HEADERS:');
options.headers.forEach((key, v) => printKV(' - $key', v));
logPrint('BODY:');
printJson(options.data);
return handler.next(options);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
printColor('///*** ERROR RESPONSE ***\\\\\\', textColor: TextColor.red);
2023-07-22 21:29:32 -06:00
logPrint('URI: ${err.requestOptions.uri}');
if (err.response != null) {
logPrint('STATUS CODE: ${err.response?.statusCode?.toString()}');
}
logPrint('$err');
if (err.response != null) {
printKV('REDIRECT', err.response?.realUri ?? '');
logPrint('BODY:');
printJson(err.response?.data);
}
return handler.next(err);
}
@override
Future onResponse(Response response, ResponseInterceptorHandler handler) async {
2023-07-22 21:29:32 -06:00
logPrint('///*** RESPONSE ***\\\\\\');
printKV('URI', response.requestOptions.uri);
printKV('STATUS CODE', response.statusCode ?? '');
// printKV('REDIRECT', response.isRedirect);
logPrint('BODY:');
printJson(response.data);
return handler.next(response);
}
void printKV(String key, Object v) {
if (kDebugMode) {
printColor('$key: $v', textColor: TextColor.orange);
2023-07-22 21:29:32 -06:00
}
}
2023-07-27 01:40:26 -06:00
void printJson(dynamic s) {
try {
final data = (s as Map<String, dynamic>?);
if (kDebugMode) {
if (data == null) {
printColor({}, textColor: TextColor.yellow);
2023-07-27 01:40:26 -06:00
return;
}
JsonEncoder encoder = const JsonEncoder.withIndent(' ');
String prettyprint = encoder.convert(s);
printColor(prettyprint, textColor: TextColor.yellow);
2023-07-22 21:29:32 -06:00
}
2023-07-27 01:40:26 -06:00
} catch (_) {
printColor(s, textColor: TextColor.yellow);
2023-07-22 21:29:32 -06:00
}
}
void logPrint(String s) {
if (kDebugMode) {
printColor(s, textColor: TextColor.yellow);
2023-07-22 21:29:32 -06:00
}
}
}