Appearance
Overview
- File:
lib/views/contacts_page.dart
The contacts_page.dart file implements the contacts management screen of the HVC XR application. It provides functionality for viewing, selecting, calling, and messaging contacts. The page supports both individual and group interactions, with voice command capabilities for RealWear devices.
Class Structure
dart
class ContactsPage extends StatelessWidget {
static const String routeName = '/ContactsPage';
ContactsPage({Key? key}) : super(key: key);
// Controller declarations
// Methods
// Build method
}Dependencies
dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hvc_xr/hlk_helpers/hlk_utils.dart';
import 'package:hvc_xr/main.dart';
import 'package:hvc_xr/widgets/contact_details_dialog.dart';
import 'package:hvc_xr/widgets/hvc_base_page.dart';
import 'package:permission_handler/permission_handler.dart';
// Additional imports for controllers, models, and widgetsKey Components
Controllers
The page uses several GetX controllers:
dart
final ContactsController contactsController = Get.find();
final MeetingsController meetingsController = Get.find();
final RealTimeController realTimeController = Get.find();
final MessagesController messagesController = Get.find();
final DigilensController digilensController = Get.find();State Management
- Uses GetX for state management
- Implements reactive state with
RxBoolvariables - Manages contact selection state
- Handles pagination for contact lists
Contact Selection Management
Selection Methods
dart
void releaseSelections() {
for (var c in contactsController.contacts) {
c.isSelected = false;
}
contactsController.selected.clear();
messagesController.messages.clear();
}
void onItemSelected(Contact contact, bool isSelected) {
contact.isSelected = isSelected;
if (isSelected) {
contactsController.selected.add(contact);
} else {
contactsController.selected.remove(contact);
}
}Voice Command Integration
Contact Commander
dart
void applyContactCommander(Contact c) async {
var call = 'call ${c.name.toLowerCase()}';
var select = 'select ${c.name.toLowerCase()}';
voiceCommandMap.clear();
voiceCommandMap[call] = () => hvcDebounce(() => callContactByName(c), call);
voiceCommandMap[getMethodFromCommand(call)] = () =>
hvcDebounce(() => callContactByName(c), getMethodFromCommand(call));
voiceCommandMap[select] =
() => hvcDebounce(() => onItemSelected(c, !c.isSelected), select);
voiceCommandMap[getMethodFromCommand(select)] = () => hvcDebounce(
() => onItemSelected(c, !c.isSelected), getMethodFromCommand(select));
await digilensController.loadPageCommands(routeName);
}Call Functionality
Individual Call
dart
void callContactByName(Contact contact) async {
contactsController.selected.add(contact);
final callDto = InitCallDto(
from: user.userId,
fromName: user.name,
targets: [contact.id],
title: 'Meeting with ${user.name}',
source: 'Headset',
platform: 'Android',
);
await validatePermission(
Permission.camera,
() async => await validatePermission(Permission.microphone, () async {
realTimeController.pageFrom = routeName;
await realTimeController.makeCall(
callDto, contact.name, true, contact.isGroup);
}));
releaseSelections();
}Group Call
dart
void handleStartCall() async {
logInfo('calling ...');
if (contactsController.selected.length == 1) {
// Individual call logic
} else {
// Group call logic
final targets = contactsController.selected.map((ct) => ct.id).toList();
final callDto = InitCallDto(
from: user.userId,
fromName: user.name,
targets: targets,
title: 'Group meeting with ${user.name}',
platform: 'Android',
source: 'HeadSet',
);
var isGroupCall = targets.length > 1 ||
contactsController.selected.any((c) => c.isGroup);
await validatePermission(
Permission.camera,
() async => await validatePermission(Permission.microphone, () async {
realTimeController.pageFrom = routeName;
await realTimeController.makeCall(
callDto, null, true, isGroupCall);
}));
releaseSelections();
}
}Messaging Functionality
dart
void handleMessage() {
contactsController.showChat.value = true;
messagesController.messages.clear();
if (contactsController.selected.length == 1) {
messagesController
.loadChatMessagesForUser(contactsController.selected.first.id);
} else {
// todo load existing group chat and by the same occasion set groupId
}
}Contact Details Dialog
dart
void handleDetails(BuildContext context) {
if (contactsController.selected.length == 1) {
showDialog(
context: context,
builder: (ctx) => ContactDetailsDialog(
contact: contactsController.selected.first,
handleMessage: () {
Get.back();
contactsController.showChat.value = true;
if (contactsController.selected.length == 1) {
messagesController.loadChatMessagesForUser(
contactsController.selected.first.id);
}
},
handleCall: () async {
// Call implementation
},
),
);
}
}UI Implementation
Base Page Structure
dart
return HvcBasePage(
position: 1,
pageTitle: 'Contacts',
pageDescription: 'Select the people to participate in a meeting',
showSearchBox: contactsController.showSearchBox,
contactsForChat: contactsController.selectedIds,
// Additional properties and handlers
);Contact List
dart
Obx(
() => ListView.builder(
shrinkWrap: true,
itemCount: contactsController.contacts.length,
itemBuilder: (BuildContext context, int index) {
final contact = contactsController.contacts[index];
if (isDigiLens) applyContactCommander(contact);
return ContactItem(
selectByName: (newVal) => onItemSelected(
contactsController.contacts[index], newVal!),
callByName: () => callContactByName(contact),
contact: contactsController.contacts[index],
onTapHandler: () {
// Dialog implementation
},
onSelected: (newVal) => onItemSelected(
contactsController.contacts[index], newVal!),
);
}),
),Selected Contacts Panel
dart
if (contactsController.selected.isNotEmpty)
Positioned(
right: 0,
child: SelectedContacts(
list: contactsController.selected,
width: getWidth(0.35),
height: getHeight(0.7),
onCloseOrCancel: () {
releaseSelections();
},
handleCall: handleStartCall,
handleMessage: handleMessage,
handleDetails: () => handleDetails(context),
),
),Pagination
dart
handleNext: () async {
contactsController.pageToShow.value = contactsController.page.value;
contactsController.page.value = contactsController.page.value + 1;
await contactsController.getContacts();
},
handlePrevious: () async {
if (contactsController.page.value > 0) {
contactsController.pageToShow.value = contactsController.page.value;
contactsController.page.value = contactsController.page.value - 1;
await contactsController.getContacts();
}
},Search Functionality
dart
handleSearch: (String newText) async {
contactsController.name.value = newText;
contactsController.page.value = 0;
await contactsController.getContacts();
contactsController.shouldReset.value = true;
},Dependencies
get: State managementpermission_handler: Permission managementhvc_xr/widgets: Custom widgetshvc_xr/controllers: Application controllershvc_xr/models: Data models
Styling
- Uses
HvcBasePagefor consistent layout - Implements responsive design with
getWidthandgetHeight - Uses custom widgets for contact items and selection panel
- Maintains consistent styling across the application