Files
Quote-Generator-Client/lib/services/quote_api.dart
ImBenji f1ce1c77a4
Some checks failed
Build Android App / build (push) Has been cancelled
add ad services and Docker configuration for web app
2026-01-02 15:21:27 +00:00

176 lines
4.4 KiB
Dart

import "dart:convert";
import "dart:typed_data";
import "package:http/http.dart" as http;
class QuoteEngagement {
final int? likes;
final int? retweets;
final int? replies;
final int? views;
QuoteEngagement({
this.likes,
this.retweets,
this.replies,
this.views,
});
Map<String, dynamic> toJson() {
return {
if (likes != null) "likes": likes,
if (retweets != null) "retweets": retweets,
if (replies != null) "replies": replies,
if (views != null) "views": views,
};
}
}
class QuoteRequest {
final String? displayName;
final String? username;
final dynamic avatarUrl; // can be String or Uint8List
final String? text;
final dynamic imageUrl; // can be String or Uint8List
final int? timestamp;
final bool? verified;
final QuoteEngagement? engagement;
QuoteRequest({
this.displayName,
this.username,
this.avatarUrl,
this.text,
this.imageUrl,
this.timestamp,
this.verified,
this.engagement,
});
// convert image bytes to base64 data uri
String? _encodeImage(dynamic image) {
if (image == null) return null;
if (image is String) return image;
if (image is Uint8List) {
final base64String = base64Encode(image);
return "data:image/png;base64,$base64String";
}
return null;
}
Map<String, dynamic> toJson() {
return {
"displayName": displayName,
"username": username,
"avatarUrl": _encodeImage(avatarUrl),
"text": text,
"imageUrl": _encodeImage(imageUrl),
"timestamp": timestamp,
if (verified != null) "verified": verified,
if (engagement != null) "engagement": engagement!.toJson(),
};
}
String toQueryString() {
final params = <String, String>{};
if (displayName != null) params["displayName"] = displayName!;
if (username != null) params["username"] = username!;
final encodedAvatar = _encodeImage(avatarUrl);
if (encodedAvatar != null) params["avatarUrl"] = encodedAvatar;
if (text != null) params["text"] = text!;
final encodedImage = _encodeImage(imageUrl);
if (encodedImage != null) params["imageUrl"] = encodedImage;
if (timestamp != null) params["timestamp"] = timestamp.toString();
if (verified != null) params["verified"] = verified.toString();
// engagment is complex obj, better suited for POST reqests
if (engagement != null) {
params["engagement"] = jsonEncode(engagement!.toJson());
}
return Uri(queryParameters: params).query;
}
}
class QuoteGeneratorApi {
// static const String _baseUrl = "https://quotes.imbenji.net";
static const String _baseUrl = "http://localhost:3000";
// genrate a quote image using POST
static Future<Uint8List> generateQuotePost(QuoteRequest request) async {
final url = Uri.parse("$_baseUrl/generate");
final requestBody = request.toJson();
final response = await http.post(
url,
headers: {
"Content-Type": "application/json",
"User-Agent": "QuoteGen-Flutter/1.0",
},
body: jsonEncode(requestBody),
);
if (response.statusCode == 200) {
return response.bodyBytes;
} else {
throw Exception("Failed to genrate quote: ${response.statusCode}");
}
}
// generate a quote image usng GET
static Future<Uint8List> generateQuoteGet(QuoteRequest request) async {
final queryString = request.toQueryString();
final url = Uri.parse("$_baseUrl/generate?$queryString");
final response = await http.get(
url,
headers: {"User-Agent": "QuoteGen-Flutter/1.0"},
);
if (response.statusCode == 200) {
return response.bodyBytes;
} else {
throw Exception("Failed to generate quote: ${response.statusCode}");
}
}
// convienence method that uses POST by defualt
static Future<Uint8List> generateQuote(QuoteRequest request) async {
return generateQuotePost(request);
}
// check api helth
static Future<bool> checkHealth() async {
try {
final url = Uri.parse("$_baseUrl/health");
final response = await http.get(
url,
headers: {"User-Agent": "QuoteGen-Flutter/1.0"},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return data["status"] == "ok";
}
return false;
} catch (e) {
return false;
}
}
// helper to get current timestmp in seconds
static int getCurrentTimestamp() {
return DateTime.now().millisecondsSinceEpoch ~/ 1000;
}
}