Appearance
Overview
- File:
lib/views/new_scanner_page.dart
The NewScannerPage is a Flutter widget that provides QR code scanning functionality for the HVC Mobile application. It supports both login and meeting QR codes, with PIN verification capabilities for secure access.
Class Structure
Class Definition
dart
class NewScannerPage extends StatelessWidget {
static const String routeName = '/NewScannerPage';
NewScannerPage({Key? key}) : super(key: key);
MobileScannerController cameraController = MobileScannerController();
final AuthController authController = Get.find();
final ContactsController contactsController = Get.find();
final MeetingsController meetingsController = Get.find();
final RealTimeController realTimeController = Get.find();
final messagesController = Get.put(MessagesController());
String qrcode = '';
String? pin;
late Timer timer;
late PinType pinType;
final TextEditingController textEditingController = TextEditingController();
RxBool shouldTakePin = false.obs, showInfo = true.obs;
final FocusNode focusNode = FocusNode();
}Dependencies
Required Packages
flutter/material.dart- Core Flutter UI componentsget/get.dart- State management and routingget_storage/get_storage.dart- Local storagemobile_scanner/mobile_scanner.dart- QR code scanningpin_code_fields/pin_code_fields.dart- PIN input field
Internal Dependencies
controllers/auth_controller.dart- Authentication managementcontrollers/contacts_controller.dart- Contact managementcontrollers/meetings_controller.dart- Meeting managementcontrollers/messages_controller.dart- Message managementcontrollers/real_time_controller.dart- Real-time communicationhlk_helpers/hlk_extension_methods.dart- Extension methodshlk_helpers/hlk_models.dart- Helper modelshlk_helpers/hlk_utils.dart- Utility functionshlk_helpers/hlk_widget.dart- Custom widgetsmodels/core_models.dart- Core data modelsmodels/dto_models.dart- Data transfer objectsshared/config.dart- Configurationshared/constants.dart- Constants
State Management
State Variables
dart
MobileScannerController cameraController = MobileScannerController();
String qrcode = '';
String? pin;
late Timer timer;
late PinType pinType;
final TextEditingController textEditingController = TextEditingController();
RxBool shouldTakePin = false.obs, showInfo = true.obs;
final FocusNode focusNode = FocusNode();Controller Initialization
dart
final AuthController authController = Get.find();
final ContactsController contactsController = Get.find();
final MeetingsController meetingsController = Get.find();
final RealTimeController realTimeController = Get.find();
final messagesController = Get.put(MessagesController());QR Code Scanning
Scanner Configuration
dart
MobileScanner(
controller: cameraController,
onDetect: (barcodes) {
if (barcodes.barcodes.isEmpty) {
logInfo('Failed to scan Barcode');
} else {
qrcode = barcodes.barcodes.first.rawValue!.trim();
logInfo('scanned data = \n$qrcode');
// Process QR code...
}
},
)QR Code Processing
dart
try {
if (!GetUtils.isNullOrBlank(qrcode)!) {
authController.scannerResult.value = ScannerResult.fromJson(qrcode);
if (authController.scannerResult.value.type.containsIgnoreCase('login')) {
allowPinEntry(true);
pinType = PinType.login;
authController.scannerResult.value.loginData = LoginData.fromMap(
authController.scannerResult.value.data);
} else if (authController.scannerResult.value.type
.containsIgnoreCase('meeting')) {
pinType = PinType.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;
allowPinEntry(true);
} else {
qrcode = 'unknown data';
allowPinEntry(false);
cameraController.start();
}
} else {
qrcode = 'empty data scanned';
allowPinEntry(false);
cameraController.start();
}
} catch (e) {
qrcode = 'invalid data scanned';
cameraController.start();
shouldTakePin.value = false;
handleException(e);
}PIN Verification
PIN Entry UI
dart
PinCodeTextField(
focusNode: focusNode,
enabled: shouldTakePin.value,
appContext: context,
autoDismissKeyboard: true,
keyboardType: TextInputType.number,
length: 4,
obscureText: false,
animationType: AnimationType.fade,
pinTheme: PinTheme(
activeColor: kAppColorBlack,
activeFillColor: kAppColorWhite.withOpacity(0.4),
inactiveFillColor: kAppColorWhite.withOpacity(0.4),
selectedFillColor: kAppColorBlack,
inactiveColor: kAppColorWhite,
selectedColor: kAppColorBlue,
shape: PinCodeFieldShape.box,
fieldWidth: getWidth(0.14),
),
cursorColor: kAppColorWhite,
animationDuration: const Duration(milliseconds: 300),
textStyle: bigTextStyle.copyWith(height: 1.6),
enableActiveFill: true,
controller: textEditingController,
onCompleted: (v) async {
// Handle PIN completion...
},
onChanged: (value) {
if (value.isNumericOnly) {
pin = value.numericOnly(firstWordOnly: true);
logInfo(pin);
} else {
pin = '';
textEditingController.clear();
}
},
)PIN Processing
dart
onCompleted: (v) async {
if (pinType == PinType.login) {
await authController
.login(authController.scannerResult.value.url, pin)
.whenComplete(
() async {
contactsController.clearAll();
await messagesController.clearAll();
await realTimeController.onInit();
await contactsController.getMe();
await messagesController.getAll();
},
);
} else if (pinType == PinType.meeting) {
authController.loading.value = true;
meetingsController.joinMeetingDto.value.pin = pin;
JoinDetails? callDetails = await meetingsController.joinMeeting(
authController.scannerResult.value.url);
if (callDetails != null) {
// Handle meeting join...
} else {
logInfo('WRONG PIN-TYPE IDENTIFIED');
Get.back();
}
}
}UI Components
Main Layout
dart
PageWithBackground(
assetImagePath: 'assets/images/hvc_xr_bg.jpeg',
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: Platform.isIOS ? AppBar() : null,
floatingActionButton: Obx(() => showInfo.value
? FloatingActionButton(
child: Icon(Icons.info_outline),
onPressed: () => HlkDialog.showMessageInAlertDialog(
title: 'Info',
message: 'If you dont have a login QrCode...',
dialogContent: [
AlertDialogContent('OK', (otherContext) => Get.back())
]),
)
: SizedBox.shrink()),
body: GestureDetector(
onTap: () {
showInfo.value = true;
timer = Timer(const Duration(seconds: 5), () => showInfo.value = false);
},
child: SafeArea(
child: Center(
child: Obx(() => shouldTakePin.value
? Column(
// PIN entry UI
)
: MobileScanner(
// Scanner UI
)),
),
),
),
),
)Info Button
dart
FloatingActionButton(
child: Icon(Icons.info_outline),
onPressed: () => HlkDialog.showMessageInAlertDialog(
title: 'Info',
message: 'If you dont have a login QrCode...',
dialogContent: [
AlertDialogContent('OK', (otherContext) => Get.back())
]),
)