import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:f0ckapp/models/mediaitem_model.dart'; import 'package:f0ckapp/models/suggestion_model.dart'; final FlutterSecureStorage storage = const FlutterSecureStorage( aOptions: AndroidOptions(encryptedSharedPreferences: true), ); Future> fetchMedia({ int? older, String type = 'image', int mode = 0, bool random = false, String? tag, }) async { final Uri url = Uri.parse('https://api.f0ck.me/items/get').replace( queryParameters: { 'type': type, 'mode': mode.toString(), 'random': (random ? 1 : 0).toString(), if (tag != null) 'tag': tag, if (older != null) 'older': older.toString(), }, ); final http.Response response = await http.get(url); if (response.statusCode == 200) { final List jsonList = jsonDecode(response.body); return jsonList.map((item) => MediaItem.fromJson(item)).toList(); } else { throw Exception('Fehler beim Abrufen der Medien: ${response.statusCode}'); } } Future fetchMediaDetail(int itemId) async { final Uri url = Uri.parse('https://api.f0ck.me/item/${itemId.toString()}'); final http.Response response = await http.get(url); if (response.statusCode == 200) { final Map jsonResponse = jsonDecode(response.body); return MediaItem.fromJson(jsonResponse); } else { throw Exception( 'Fehler beim Abrufen der Media-Details: ${response.statusCode}', ); } } Future> fetchSuggestions(String query) async { final Uri uri = Uri.parse('https://api.f0ck.me/search/?q=$query'); try { final http.Response response = await http .get(uri) .timeout(const Duration(seconds: 5)); if (response.statusCode == 200) { final dynamic decoded = jsonDecode(response.body); if (decoded is List) { final suggestions = decoded .map((item) => Suggestion.fromJson(item as Map)) .toList(); suggestions.sort((a, b) => b.score.compareTo(a.score)); return suggestions; } else { throw Exception('Unerwartetes Format: Es wurde eine Liste erwartet.'); } } else if (response.statusCode == 400) { final dynamic error = jsonDecode(response.body); final String message = error is Map ? error['detail']?.toString() ?? 'Unbekannter Fehler.' : 'Unbekannter Fehler.'; throw Exception('Client-Fehler 400: $message'); } else { throw Exception( 'Fehler beim Abrufen der Vorschläge: ${response.statusCode}', ); } } on TimeoutException { throw Exception('Anfrage an die API hat zu lange gedauert.'); } catch (e) { throw Exception('Fehler bei der Verarbeitung der Anfrage: $e'); } } Future login(String username, String password) async { final Uri url = Uri.parse('https://api.f0ck.me/login'); final http.Response response = await http.post( url, body: {'username': username, 'password': password}, ); if (response.statusCode == 200) { final dynamic data = jsonDecode(response.body); final token = data['token']; if (token != null) { await storage.write(key: "token", value: token); return true; } else { throw Exception('Token nicht im Response enthalten.'); } } else { throw Exception('Login fehlgeschlagen: ${response.statusCode}'); } }