feat: Menambahkan fitur upload logo toko dan memperbaiki penanganan font dengan fallback

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
master
a2nr 2025-09-01 20:19:37 +07:00
parent b255d0a137
commit cb71664a17
8 changed files with 132 additions and 59 deletions

View File

@ -62,6 +62,22 @@ class EscPosPrintService {
// Mulai dengan inisialisasi printer
List<int> bytes = [];
// Coba tambahkan logo toko jika ada
final logoPath = prefs.getString('store_logo_path');
if (logoPath != null && logoPath.isNotEmpty) {
try {
final img.Image? logo = await getImageFromFilePath(logoPath);
if (logo != null) {
// Mengubah ukuran logo agar pas di struk (lebar maks 300px)
final resizedLogo = img.copyResize(logo, width: 300);
bytes += generator.image(resizedLogo, align: PosAlign.center);
bytes += generator.feed(1); // Beri sedikit spasi setelah logo
}
} catch (e) {
print('Error loading or processing store logo: $e');
}
}
// Tambahkan nama toko sebagai header
bytes += generator.text(storeName,
styles: PosStyles(
@ -348,38 +364,18 @@ class EscPosPrintService {
throw Exception('Gagal mencetak struk: $e');
}
}
}
/// Data class to hold image processing parameters
class ImageProcessParams {
final Uint8List imageBytes;
final int maxWidth;
ImageProcessParams(this.imageBytes, this.maxWidth);
}
/// Helper function to decode and resize image in an isolate
Uint8List? processImageInIsolate(ImageProcessParams params) {
try {
// Decode image
img.Image? image = img.decodeImage(params.imageBytes);
if (image != null) {
// Resize gambar agar sesuai dengan ukuran kertas printer
if (image.width > params.maxWidth) {
final ratio = params.maxWidth / image.width;
final newHeight = (image.height * ratio).round();
image = img.copyResize(image, width: params.maxWidth, height: newHeight);
/// Helper function to get image from file path
static Future<img.Image?> getImageFromFilePath(String path) async {
try {
final file = File(path);
if (await file.exists()) {
final bytes = await file.readAsBytes();
return img.decodeImage(bytes);
}
// Convert image to bytes that can be sent back to main isolate
final imageBytes = Uint8List.fromList(img.encodePng(image));
return imageBytes;
} catch (e) {
print('Error getting image from file path: $e');
}
return null;
} catch (e) {
print('Error processing image in isolate: $e');
return null;
}
}

View File

@ -20,12 +20,23 @@ class AccountSettingsWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
// Mencoba menggunakan Google Fonts Courier Prime, jika gagal gunakan font sistem
TextStyle courierPrime;
try {
courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
fontSize: 14,
height: 1.2,
),
);
} catch (e) {
// Fallback ke font sistem jika Google Fonts tidak tersedia
courierPrime = const TextStyle(
fontFamily: 'CourierPrime, Courier, monospace',
fontSize: 14,
height: 1.2,
),
);
);
}
return Container(
width: double.infinity,

View File

@ -9,12 +9,23 @@ class AddItemButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
// Mencoba menggunakan Google Fonts Courier Prime, jika gagal gunakan font sistem
TextStyle courierPrime;
try {
courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
fontSize: 14,
height: 1.2,
),
);
} catch (e) {
// Fallback ke font sistem jika Google Fonts tidak tersedia
courierPrime = const TextStyle(
fontFamily: 'CourierPrime, Courier, monospace',
fontSize: 14,
height: 1.2,
),
);
);
}
return GestureDetector(
onTap: onTap,

View File

@ -15,12 +15,23 @@ class FireflyTransactionInfo extends StatelessWidget {
@override
Widget build(BuildContext context) {
final courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
// Mencoba menggunakan Google Fonts Courier Prime, jika gagal gunakan font sistem
TextStyle courierPrime;
try {
courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
fontSize: 14,
height: 1.2,
),
);
} catch (e) {
// Fallback ke font sistem jika Google Fonts tidak tersedia
courierPrime = const TextStyle(
fontFamily: 'CourierPrime, Courier, monospace',
fontSize: 14,
height: 1.2,
),
);
);
}
return Container(
width: double.infinity,

View File

@ -25,12 +25,23 @@ class ReceiptItemWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
// Mencoba menggunakan Google Fonts Courier Prime, jika gagal gunakan font sistem
TextStyle courierPrime;
try {
courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
fontSize: 14,
height: 1.2,
),
);
} catch (e) {
// Fallback ke font sistem jika Google Fonts tidak tersedia
courierPrime = const TextStyle(
fontFamily: 'CourierPrime, Courier, monospace',
fontSize: 14,
height: 1.2,
),
);
);
}
return Container(
width: double.infinity,

View File

@ -43,12 +43,23 @@ class _StoreDisclaimerState extends State<StoreDisclaimer> {
@override
Widget build(BuildContext context) {
final courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
// Mencoba menggunakan Google Fonts Courier Prime, jika gagal gunakan font sistem
TextStyle courierPrime;
try {
courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
fontSize: 12,
height: 1.2,
),
);
} catch (e) {
// Fallback ke font sistem jika Google Fonts tidak tersedia
courierPrime = const TextStyle(
fontFamily: 'CourierPrime, Courier, monospace',
fontSize: 12,
height: 1.2,
),
);
);
}
return GestureDetector(
onTap: widget.onTap, // Gunakan callback onTap dari widget

View File

@ -46,12 +46,23 @@ class _StoreInfoWidgetState extends State<StoreInfoWidget> {
// Load data every time the widget is built to ensure it's up-to-date
_loadStoreInfo();
final courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
// Mencoba menggunakan Google Fonts Courier Prime, jika gagal gunakan font sistem
TextStyle courierPrime;
try {
courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
fontSize: 14,
height: 1.2,
),
);
} catch (e) {
// Fallback ke font sistem jika Google Fonts tidak tersedia
courierPrime = const TextStyle(
fontFamily: 'CourierPrime, Courier, monospace',
fontSize: 14,
height: 1.2,
),
);
);
}
return GestureDetector(
onTap: widget.onTap, // Panggil callback ketika di-tap

View File

@ -51,12 +51,23 @@ class _ThankYouPantunState extends State<ThankYouPantun> {
@override
Widget build(BuildContext context) {
final courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
// Mencoba menggunakan Google Fonts Courier Prime, jika gagal gunakan font sistem
TextStyle courierPrime;
try {
courierPrime = GoogleFonts.courierPrime(
textStyle: const TextStyle(
fontSize: 12,
height: 1.2,
),
);
} catch (e) {
// Fallback ke font sistem jika Google Fonts tidak tersedia
courierPrime = const TextStyle(
fontFamily: 'CourierPrime, Courier, monospace',
fontSize: 12,
height: 1.2,
),
);
);
}
return GestureDetector(
onTap: widget.onTap, // Gunakan callback onTap dari widget