Skip to content

Overview ​

  • File: lib/views/contacts_page.dart

The ContactsPage is a Flutter widget that manages the contacts list in the HVC Mobile application. It provides functionality for viewing, searching, and interacting with contacts, including initiating calls, chats, and managing favorites.

Class Structure ​

Class Definition ​

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

  @override
  _ContactsPageState createState() => _ContactsPageState();
}

Controllers ​

dart
final ContactsController contactsController = Get.find();
final MeetingsController meetingsController = Get.find();
final RealTimeController realTimeController = Get.find();
final MessagesController messagesController = Get.find();

State Variables ​

dart
final TextEditingController searchCtrl = TextEditingController();

Dependencies ​

Required Packages ​

  • flutter/material.dart - Core Flutter UI components
  • get/get.dart - State management and routing
  • infinite_scroll_pagination - Infinite scrolling functionality
  • permission_handler - Permission management

Internal Dependencies ​

  • contacts_controller.dart - Contact management logic
  • meetings_controller.dart - Meeting management
  • messages_controller.dart - Message handling
  • real_time_controller.dart - Real-time communication
  • hlk_helpers/ - Custom helper utilities
  • models/ - Data models
  • shared/ - Shared constants and configurations
  • widgets/ - Custom widgets

State Management ​

Initialization ​

dart
@override
void initState() {
  super.initState();
  if (contactsController.contacts.isEmpty) contactsController.fetchPage(1);
}

Reactive State ​

dart
Obx(() => contactsController.loadingContacts.value
    ? const Center(child: CircularProgressIndicator())
    : Column(...))

Contact Management ​

Contact Selection ​

dart
void onItemSelected(Contact contact, bool isSelected) {
  setState(() {
    contact.isSelected = isSelected;
    if (isSelected) {
      contactsController.selected.add(contact);
    } else {
      contactsController.selected.remove(contact);
    }
  });
}

Contact Actions ​

  1. Start Chat
dart
Future<void> goToChat(Contact contact) async {
  UserData user = UserData.fromMap(userData);
  final res = await realTimeController.callSendMessage(
    content: '',
    contentType: 'text',
    user: user,
    contacts: [contact.id],
  );

  if (res != null) {
    messagesController.selectedGroupId.value = res.groupId;
    messagesController.reloadMessages();
    messagesController.getMessagesOnline(groupId: res.groupId);
    Get.to(ContactMessageDetailsPage(
      contact: contact,
      isForMessage: false,
    ));
    if (contact.isGroup) contactsController.getGroupUsers(contact.id);
    messagesController.getChatListOnline();
  }
}
  1. Make Call
dart
callHandler: () async {
  UserData user = UserData.fromMap(userData);
  contactsController.selected.add(contact);

  final callDto = InitCallDto(
    from: user.userId,
    fromName: user.name,
    targets: [contact.id],
    title: 'Meeting with ${user.name}',
    source: 'Mobile',
    platform: Platform.isIOS ? 'iOS' : 'Android',
  );

  await validatePermission(
    Permission.camera,
    () async => await validatePermission(
      Permission.microphone,
      () async {
        await realTimeController.makeCall(
          callDto,
          contact.name,
          true,
          contact.isGroup,
        );
      }
    )
  );
  contactsController.releaseSelections();
}
  1. Toggle Favorite
dart
makeFavoriteHandler: () async {
  await contactsController.makeContactFavorite(
    contact.id,
    !contact.favourite,
  );
}

UI Components ​

dart
if (contactsController.showSearchBox.value)
  Padding(
    padding: const EdgeInsets.only(left: 24, right: 12, top: 10),
    child: Row(
      children: [
        Expanded(
          child: TextFormField(
            controller: searchCtrl,
            validator: requiredValidator,
            decoration: getInputDecoration('Search Contact', false),
          ),
        ),
        IconButton(
          onPressed: () async {
            setState(() {
              contactsController.showSearchBox.value = false;
              contactsController.name.value = searchCtrl.text;
            });
            await contactsController.reload();
            searchCtrl.clear();
          },
          icon: const Icon(Icons.search),
        ),
      ],
    ),
  )

Contact List ​

dart
PagedListView<int, Contact>(
  pagingController: contactsController.pagingController,
  builderDelegate: PagedChildBuilderDelegate<Contact>(
    itemBuilder: (context, contact, index) => ContactItem(...),
    noItemsFoundIndicatorBuilder: (context) => NoItemLoader(...),
  ),
)

Contact Item ​

dart
ContactItem(
  callHandler: () async { ... },
  contact: contactsController.contacts.elementAt(index),
  onSelected: (newVal) => onItemSelected(contact, newVal!),
  onTapHandler: () async => await goToChat(contact),
  messageHandler: () async => await goToChat(contact),
  makeFavoriteHandler: () async { ... },
)

Search Functionality ​

Search Implementation ​

dart
onPressed: () async {
  setState(() {
    contactsController.showSearchBox.value = false;
    contactsController.name.value = searchCtrl.text;
  });
  await contactsController.reload();
  searchCtrl.clear();
}

Search Box Toggle ​

dart
if (contactsController.showSearchBox.value)
  // Show search box
else
  // Hide search box

Communication Features ​

Chat Initialization ​

  1. Create message
  2. Set group ID
  3. Load messages
  4. Navigate to chat page
  5. Load group users (if group chat)
  6. Update chat list

Call Initialization ​

  1. Create call DTO
  2. Validate permissions
  3. Initiate call
  4. Release selections

Released under the MIT License.