initial
Some checks failed
Build Android App / build (push) Failing after 32m54s

This commit is contained in:
ImBenji
2026-01-02 12:05:49 +00:00
parent 4808116608
commit 7a88585b6e
12 changed files with 1356 additions and 367 deletions

View File

@@ -0,0 +1,251 @@
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,
};
}
factory QuoteEngagement.fromJson(Map<String, dynamic> json) {
return QuoteEngagement(
likes: json["likes"],
retweets: json["retweets"],
replies: json["replies"],
views: json["views"],
);
}
}
class QuoteSessionRequest {
final String? displayName;
final String? username;
final dynamic avatarUrl;
final String? text;
final dynamic imageUrl;
final int? timestamp;
final bool? verified;
final QuoteEngagement? engagement;
final bool clearAvatarUrl;
final bool clearImageUrl;
final bool clearEngagement;
QuoteSessionRequest({
this.displayName,
this.username,
this.avatarUrl,
this.text,
this.imageUrl,
this.timestamp,
this.verified,
this.engagement,
this.clearAvatarUrl = false,
this.clearImageUrl = false,
this.clearEngagement = false,
});
// convert img 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() {
final map = <String, dynamic>{};
if (displayName != null) map["displayName"] = displayName;
if (username != null) map["username"] = username;
if (clearAvatarUrl) {
map["avatarUrl"] = null;
} else {
final encodedAvatar = _encodeImage(avatarUrl);
if (encodedAvatar != null) map["avatarUrl"] = encodedAvatar;
}
if (text != null) map["text"] = text;
if (clearImageUrl) {
map["imageUrl"] = null;
} else {
final encodedImage = _encodeImage(imageUrl);
if (encodedImage != null) map["imageUrl"] = encodedImage;
}
if (timestamp != null) map["timestamp"] = timestamp;
if (verified != null) map["verified"] = verified;
if (clearEngagement) {
map["engagement"] = null;
} else if (engagement != null) {
map["engagement"] = engagement!.toJson();
}
return map;
}
}
class QuoteSession {
final String id;
final String? displayName;
final String? username;
final String? avatarUrl;
final String? text;
final String? imageUrl;
final int? timestamp;
final bool? verified;
final QuoteEngagement? engagement;
final int createdAt;
final int updatedAt;
QuoteSession({
required this.id,
this.displayName,
this.username,
this.avatarUrl,
this.text,
this.imageUrl,
this.timestamp,
this.verified,
this.engagement,
required this.createdAt,
required this.updatedAt,
});
factory QuoteSession.fromJson(Map<String, dynamic> json) {
return QuoteSession(
id: json["id"],
displayName: json["displayName"],
username: json["username"],
avatarUrl: json["avatarUrl"],
text: json["text"],
imageUrl: json["imageUrl"],
timestamp: json["timestamp"],
verified: json["verified"],
engagement: json["engagement"] != null
? QuoteEngagement.fromJson(json["engagement"])
: null,
createdAt: json["createdAt"],
updatedAt: json["updatedAt"],
);
}
}
class QuoteGeneratorApiV2 {
static const String _baseUrl = "https://quotes.imbenji.net";
// static const String _baseUrl = "http://localhost:3000";
// create new session
static Future<QuoteSession> createSession(QuoteSessionRequest request) async {
final url = Uri.parse("$_baseUrl/v2/quote");
final response = await http.post(
url,
headers: {"Content-Type": "application/json"},
body: jsonEncode(request.toJson()),
);
if (response.statusCode == 201) {
final data = jsonDecode(response.body);
return QuoteSession.fromJson(data);
} else {
throw Exception("Failed to create sesion: ${response.statusCode}");
}
}
// get session state
static Future<QuoteSession> getSession(String sessionId) async {
final url = Uri.parse("$_baseUrl/v2/quote/$sessionId");
final response = await http.get(url);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return QuoteSession.fromJson(data);
} else {
throw Exception("Failed to get session: ${response.statusCode}");
}
}
// update session fields (only send whats changed)
static Future<QuoteSession> updateSession(
String sessionId,
QuoteSessionRequest updates,
) async {
final url = Uri.parse("$_baseUrl/v2/quote/$sessionId");
final response = await http.patch(
url,
headers: {"Content-Type": "application/json"},
body: jsonEncode(updates.toJson()),
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return QuoteSession.fromJson(data);
} else {
throw Exception("Failed to updte session: ${response.statusCode}");
}
}
// render the session as image
static Future<Uint8List> generateImage(String sessionId) async {
final url = Uri.parse("$_baseUrl/v2/quote/$sessionId/image");
final response = await http.get(url);
if (response.statusCode == 200) {
return response.bodyBytes;
} else {
throw Exception("Failed to genrate image: ${response.statusCode}");
}
}
// delete session
static Future<void> deleteSession(String sessionId) async {
final url = Uri.parse("$_baseUrl/v2/quote/$sessionId");
final response = await http.delete(url);
if (response.statusCode != 204) {
throw Exception("Failed to delte session: ${response.statusCode}");
}
}
// helper to get curren timestamp in seconds
static int getCurrentTimestamp() {
return DateTime.now().millisecondsSinceEpoch ~/ 1000;
}
}