Untitled

 avatar
unknown
plain_text
9 months ago
6.1 kB
13
Indexable
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';

class ScannerPage extends StatefulWidget {
  const ScannerPage({super.key});

  @override
  State<ScannerPage> createState() => _ScannerPageState();
}

class _ScannerPageState extends State<ScannerPage>
    with SingleTickerProviderStateMixin {
  bool isCameraPaused = false;
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
  Barcode? result;
  QRViewController? controller;

  late AnimationController _animationController;
  late Animation<double> _animation;

  bool _isFlashOn = false;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    )..repeat(reverse: true);

    _animation = Tween<double>(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
    );
  }

  @override
  void reassemble() {
    super.reassemble();
    if (Platform.isAndroid) {
      controller?.pauseCamera();
    }
    controller?.resumeCamera();
  }

  @override
  void dispose() {
    controller?.dispose();
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final scanBoxSize = MediaQuery.of(context).size.width * 0.7;

    return Scaffold(
      appBar: AppBar(
        title: Text('Scanner'),
        centerTitle: true,
        actions: [
          IconButton(
            icon: Icon(_isFlashOn ? Icons.flash_on : Icons.flash_off),
            onPressed: () async {
              if (controller != null) {
                await controller!.toggleFlash();
                bool? flashStatus = await controller!.getFlashStatus();
                setState(() {
                  _isFlashOn = flashStatus ?? false;
                });
              }
            },
          ),
        ],
      ),
      body: Stack(
        children: [
          QRView(
            key: qrKey,
            onQRViewCreated: _onQRViewCreated,
            overlay: QrScannerOverlayShape(
              borderColor: Colors.blueAccent,
              borderRadius: 12,
              borderLength: 30,
              borderWidth: 10,
              cutOutSize: scanBoxSize,
            ),
          ),
          Center(
            child: SizedBox(
              width: scanBoxSize,
              height: scanBoxSize,
              child: AnimatedBuilder(
                animation: _animation,
                builder: (context, child) {
                  return CustomPaint(
                    painter: ScannerLaserPainter(
                      animationValue: _animation.value,
                    ),
                  );
                },
              ),
            ),
          ),

          // Positioned
        ],
      ),
    );
  }

  void _onQRViewCreated(QRViewController controller) async {
    setState(() {
      this.controller = controller;
    });

    bool? flashStatus = await controller.getFlashStatus();
    setState(() {
      _isFlashOn = flashStatus ?? false;
    });

    controller.scannedDataStream.listen((scanData) {
      if (mounted && result == null) {
        controller.pauseCamera();
        _animationController.stop();

        setState(() {
          result = scanData;
        });

        Future.delayed(const Duration(seconds: 1), () {
          if (mounted) {
            context.pushReplacementNamed(
              'detail_inventory_barcode',
              extra: scanData.code!,
            );
            // _showSuccessDialog(context, scanData.code!);
          }
        });
      }
    });
  }
}

class ScannerLaserPainter extends CustomPainter {
  final double animationValue;

  ScannerLaserPainter({required this.animationValue});

  @override
  void paint(Canvas canvas, Size size) {
    final laserY = size.height * animationValue;
    const laserHeight = 60.0;

    final Rect rect = Rect.fromLTWH(
      0,
      laserY - laserHeight / 2,
      size.width,
      laserHeight,
    );

    final gradient = LinearGradient(
      colors: [Colors.transparent, Colors.blueAccent, Colors.transparent],
      stops: const [0.0, 0.5, 1.0],
      begin: Alignment.topCenter,
      end: Alignment.bottomCenter,
    );

    final paint = Paint()..shader = gradient.createShader(rect);
    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(covariant ScannerLaserPainter oldDelegate) {
    return oldDelegate.animationValue != animationValue;
  }
}

void _showSuccessDialog(BuildContext context, String code) {
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return AlertDialog(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Padding(
              padding: const EdgeInsets.only(top: 32, bottom: 20),
              // child: Assets.icons.success.svg(height: 100),
              child: Icon(Icons.check_circle, color: Colors.green, size: 100),
            ),
            Text(
              'Selamat!',
              textAlign: TextAlign.center,
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
            ),
            const SizedBox(height: 8),
            Text(
              'Anda telah berhasil melakukan presensi matakuliah Algoritma $code.',
              textAlign: TextAlign.center,
              style: TextStyle(color: Colors.black54),
            ),
          ],
        ),
        actions: <Widget>[
          TextButton(
            child: const Text('OK'),
            onPressed: () {
              // Navigator.pushAndRemoveUntil(
              //   context,
              //   MaterialPageRoute(
              //     builder: (context) => const TemplateMhsPage(),
              //   ),
              //   (Route<dynamic> route) => false,
              // );
            },
          ),
        ],
      );
    },
  );
}
Editor is loading...
Leave a Comment