Skip to content

Overview

  • File: lib/views/new_scanner_page.dart

The new_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 NewScannerPage extends StatefulWidget {
  static const String routeName = '/NewScannerPage';
  const NewScannerPage({Key? key}) : super(key: key);

  @override
  State<NewScannerPage> createState() => _NewScannerPageState();
}

class _NewScannerPageState extends State<NewScannerPage> {
  // 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:mobile_scanner/mobile_scanner.dart';
import 'package:native_device_orientation/native_device_orientation.dart';
// Additional imports for controllers and models

Key Components

State Variables

dart
MobileScannerController cameraController = MobileScannerController();
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 RealTimeController realTimeController = Get.find();
final MeetingsController meetingsController = 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 = MobileScanner(
    allowDuplicates: false,
    controller: cameraController,
    onDetect: (barcode, args) async {
      if (barcode.rawValue == null) {
        debugPrint('Failed to scan Barcode');
      } else {
        qrcode = barcode.rawValue!.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.stop();
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
  ]);
}

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

Dependencies

  • mobile_scanner: 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.