Skip to content

Overview

  • File: lib/views/scanner_page.dart

The scanner_page.dart file implements a QR code scanner functionality for the HVC XR application. It provides capabilities for scanning QR codes for both login and meeting purposes, with support for device orientation handling and automatic timeout. The page is designed to work with RealWear devices and includes features for rapid connect functionality.

Class Structure

dart
class ScannerPage extends StatefulWidget {
  static const String routeName = '/ScannerPage';
  const ScannerPage({Key? key}) : super(key: key);

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

class _ScannerPageState extends State<ScannerPage> {
  // State variables and methods
}

Dependencies

dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:native_device_orientation/native_device_orientation.dart';
import 'package:scan/scan.dart';
// Additional imports for controllers and models

Key Components

State Variables

dart
final ScanController cameraController = ScanController();
String qrcode = '';
Timer? _timer;
RxInt rotationValue = 0.obs;
String title = 'Please scan QR code to login';
String meetingId = '';

Controllers

dart
final AuthController authController = Get.find();
final MeetingsController meetingsController = Get.find();
final RealTimeController realTimeController = Get.find();

Scanner Initialization

Timer Management

dart
void _cancelTimer() {
  if (_timer != null) {
    _timer?.cancel();
    _timer = null;
  }
}
dart
void proceed() {
  if (authController.scannerResult.value.type.containsIgnoreCase('login')) {
    goToPage(const PinPage(pinType: PinType.login), closePage: false);
  } else if (authController.scannerResult.value.type.containsIgnoreCase('meeting')) {
    if (getBoolean(authController.scannerResult.value.meetingData?.pinRequired)) {
      goToPage(const PinPage(pinType: PinType.meeting), closePage: true);
    }
  }
}

void goToPage(Widget page, {bool closePage = true}) async {
  await SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
  ]).then((value) => closePage ? Get.off(page) : Get.to(page));
}

Device Orientation Handling

Orientation Setup

dart
@override
void initState() {
  super.initState();
  NativeDeviceOrientationCommunicator()
      .onOrientationChanged()
      .listen((event) {
    if (event == NativeDeviceOrientation.landscapeRight) {
      rotationValue.value = -2;
    } else {
      rotationValue.value = 0;
    }
  });
  meetingId = (Get.arguments ?? '') as String;
  if (meetingId.isNotEmpty) title = 'Scan Rapid Connect QR Code';
}

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  Future.delayed(Duration.zero, () async {
    var nDor = await NativeDeviceOrientationCommunicator().orientation();
    rotationValue.value =
        nDor == NativeDeviceOrientation.landscapeRight ? -2 : 0;
  });
}

QR Code Processing

Scanner Configuration

dart
var scanner = ScanView(
  controller: cameraController,
  scanAreaScale: 1.0,
  scanLineColor: kAccentColor,
  onCapture: (String barcode) async {
    if (barcode.isEmpty) {
      debugPrint('Failed to scan Barcode');
    } else {
      qrcode = barcode.trim();
      // Process QR code data
    }
  },
);

QR Code Processing Logic

dart
try {
  if (!GetUtils.isNullOrBlank(qrcode)!) {
    if (qrcode.isNumericOnly && meetingId.isNotEmpty) {
      // Handle rapid connect
      var res = await realTimeController.addDeviceToEvent(
        qrcode,
        meetingId,
      );
      Get.back(result: getBoolean(res?.success));
      if (res != null) {
        if (res.success) {
          HlkDialog.showSuccessSnackBar(
              res.message ?? 'request sent successfully');
        } else {
          HlkDialog.showErrorSnackBar(
              res.message ?? 'device request failed');
        }
      }
    } else {
      // Handle login and meeting QR codes
      authController.scannerResult.value =
          ScannerResult.fromJson(qrcode);
      if (authController.scannerResult.value.type
          .containsIgnoreCase('login')) {
        authController.scannerResult.value.loginData =
            LoginData.fromMap(
                authController.scannerResult.value.data);
        proceed();
      } else if (authController.scannerResult.value.type
          .containsIgnoreCase('meeting')) {
        final MeetingData meetingData = MeetingData.fromMap(
            authController.scannerResult.value.data);
        authController.scannerResult.value.meetingData =
            meetingData;
        meetingsController.meetingCode.value =
            meetingData.meetingCode;
        meetingsController.joinMeetingDto.value.meetingToken =
            meetingData.meetingToken;
        proceed();
      }
    }
  }
} catch (e) {
  handleException(e);
}

UI Implementation

Scanner View

dart
return Scaffold(
  appBar: AppBar(
    title: Text(title),
  ),
  body: Obx(
      () => RotatedBox(quarterTurns: rotationValue.value, child: scanner)),
);

Resource Management

Cleanup Methods

dart
@override
void deactivate() {
  super.deactivate();
  _cancelTimer();
  cameraController.pause();
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
  ]);
}

@override
void dispose() {
  super.dispose();
}

Dependencies

  • scan: QR code scanning
  • native_device_orientation: Device orientation handling
  • get: State management
  • flutter/services.dart: System services

Styling

  • Uses consistent app bar styling
  • Implements responsive design
  • Maintains proper orientation
  • Provides clear visual feedback

Released under the MIT License.