feat: Menambahkan fitur upload logo toko dan memperbaiki penanganan font dengan fallback
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>master
							parent
							
								
									b255d0a137
								
							
						
					
					
						commit
						cb71664a17
					
				| 
						 | 
				
			
			@ -61,6 +61,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,
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +201,7 @@ class EscPosPrintService {
 | 
			
		|||
      String customDisclaimer;
 | 
			
		||||
      try {
 | 
			
		||||
        customDisclaimer = prefs.getString('store_disclaimer_text') ?? 
 | 
			
		||||
            'Barang yang sudah dibeli tidak dapat dikembalikan/ditukar. '
 | 
			
		||||
            'Barang yang sudah dibeli tidak dapat dikembalikan/ditukar. ' 
 | 
			
		||||
            'Harap periksa kembali struk belanja Anda sebelum meninggalkan toko.';
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        print('Error saat memuat disclaimer: $e');
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue