Initial commit: Captain Claude Mobile App
- Flutter app with chat and terminal screens - WebSocket integration for real-time chat - xterm integration for screen sessions - Markdown rendering with code blocks - JWT authentication Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
82
lib/services/api_service.dart
Normal file
82
lib/services/api_service.dart
Normal file
@@ -0,0 +1,82 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import '../config/api_config.dart';
|
||||
import '../models/session.dart';
|
||||
import '../models/message.dart';
|
||||
|
||||
class ApiService {
|
||||
late final Dio _dio;
|
||||
String? _token;
|
||||
|
||||
ApiService() {
|
||||
_dio = Dio(BaseOptions(
|
||||
baseUrl: ApiConfig.baseUrl,
|
||||
connectTimeout: ApiConfig.connectionTimeout,
|
||||
receiveTimeout: ApiConfig.receiveTimeout,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
));
|
||||
|
||||
_dio.interceptors.add(InterceptorsWrapper(
|
||||
onRequest: (options, handler) {
|
||||
if (_token != null) {
|
||||
options.headers['Authorization'] = 'Bearer $_token';
|
||||
}
|
||||
return handler.next(options);
|
||||
},
|
||||
onError: (error, handler) {
|
||||
if (error.response?.statusCode == 401) {
|
||||
// Token expired, trigger re-login
|
||||
}
|
||||
return handler.next(error);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
void setToken(String? token) {
|
||||
_token = token;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> login(String username, String password) async {
|
||||
final response = await _dio.post(
|
||||
ApiConfig.login,
|
||||
data: {
|
||||
'username': username,
|
||||
'password': password,
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
Future<List<ScreenSession>> getSessions() async {
|
||||
final response = await _dio.get(ApiConfig.sessions);
|
||||
return (response.data as List)
|
||||
.map((json) => ScreenSession.fromJson(json))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<List<Conversation>> getHistory({int limit = 20}) async {
|
||||
final response = await _dio.get(
|
||||
ApiConfig.history,
|
||||
queryParameters: {'limit': limit},
|
||||
);
|
||||
return (response.data as List)
|
||||
.map((json) => Conversation.fromJson(json))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<List<Message>> getConversationMessages(String conversationId) async {
|
||||
final response = await _dio.get('${ApiConfig.history}/$conversationId');
|
||||
return (response.data as List)
|
||||
.map((json) => Message.fromJson(json))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> uploadFile(String filePath) async {
|
||||
final formData = FormData.fromMap({
|
||||
'file': await MultipartFile.fromFile(filePath),
|
||||
});
|
||||
final response = await _dio.post(ApiConfig.upload, data: formData);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user