Appearance
Contacts Page
- File: src/pages/private/contacts/index.svelte
Overview
The Contacts page provides a comprehensive interface for managing contacts, groups, and initiating communications. It features contact searching, filtering, sorting, group management, and event creation capabilities. These diverse views provide users with different perspectives and functionalities, offering a comprehensive and versatile user experience. Users can switch between these views to access specific features, manage contacts, and interact with groups effortlessly.
Core Features
1. Contact Management
- View and search contacts
- Sort contacts alphabetically or by recent activity
- Filter contacts by alphabet
- Add/remove favorites
- View contact details
- Group management
2. Communication Features
- Start chat sessions
- Initiate calls
- Create events
- Manage group communications
UI Structure
1. Main Layout
svelte
<div class="flex-grow grid grid-cols-1 overflow-y-hidden">
<!-- Contact Selection Bar -->
<ContactSelection/>
<!-- Contact List -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
<!-- Individual Contacts -->
<ContactBox/>
<!-- Group Contacts -->
<GroupContactBox/>
</div>
<!-- Alphabet Scroll -->
<AlphabetScroll/>
</div>Contact Selection Bar
The ContactSelection bar or component serves as the initial section on the contact page, remaining hidden until a contact is checked. When triggered, it displays an avatar of the selected contacts on the far left, accompanied by three action buttons on the right side. These action buttons offer the following functionalities:
Start Event button: Initiates the EventForm component, pre-populating it with the selected contacts as initial participants.
Chat button: Creates a group chat with the selected contacts, triggering the chat view for easy communication.
Search icon button: Activates an input field, enabling users to conduct quick and efficient searches within the contact selection area.
svelte
<ContactSelection
contacts={selectedContacts}
on:close={clearSelection}
on:call={onCall}
on:message={onMessage}
bind:searchValue
/>Control Section
After the contact selection bar, the second segment of the contact page is the control action area. This section remains constantly visible, except when the contact selection bar is active. The control action view comprises the page header positioned on the far left and various control elements on the right, which include:
Dropdown Menu: This menu enables users to sort the contacts either alphabetically or based on recent interactions.
Search Icon Button: Users can activate this button to reveal an input field, facilitating quick and efficient searches within the contact selection area.
New Group Button: This button triggers the NewGroup component or form, empowering users to create new contact groups conveniently.
Person Icon Button: The person icon button facilitates navigation within the AlphabetScroll component. When clicked, it allows users to scroll to specific contacts whose initials match the selected alphabetical character.
The control action area offers essential tools and functionalities for managing contacts efficiently, while the constant visibility ensures quick access to these features throughout the contact page.
Contacts and Groups Grid
The section is divided into two parts: the contacts section, which occupies three-fourths of the space, and the groups section, which occupies one-fourth.
- Contact Section: This shows grid layout of all contacts, seamlessly presented through the use of the contact box component. This component offers various functionalities, allowing users to access and interact with their contacts efficiently. The component presents essential contact details and provides quick access to actions like initiating calls, sending messages, and marking favorites.
svelte
<ContactBox
{contact}
on:checked={onContactChecked}
on:addFavourite={addFavourite}
on:removeFavourate={removeFavourate}
on:viewDetails={onViewDetails}
on:call={onCall}
on:message={onMessage}
/>- Group Section: Similar to the contact section, the group section make use of the group contact box tailored specifically for groups. This component elegantly displays essential details about each group, showcases recent interactions, and provides quick access to key action for group management.
svelte
<GroupContactBox
{contact}
on:checked={onContactChecked}
on:viewDetails={openGroupManager}
on:call={onCall}
on:message={onMessage}
on:openManager={openGroupManager}
/>Modal Systems
1. Contact Details Modal
A modal show casing the details of a selected contact
svelte
<Modal on:close={() => (activeContact = null)}>
<ContactDetails
contact={activeContact}
on:call={onCall}
on:message={onMessage}
/>
</Modal>2. New Event Modal
A modal to create a new event
svelte
<Modal title="New Event" buttons={newEventButtons}>
<EventForm
{contacts}
initialContacts={activeContacts}
{startNow}
on:change={onEventFormChange}
/>
</Modal>3. Group Management Modal
A modal show casing managing tools and actions for groups
svelte
<Modal title={`${edit ? "Edit Group" : "New Group"}`}>
<NewGroup
on:change={onGroupFormChange}
groupId={activeGroupId}
/>
</Modal>State Management
1. Contact State
svelte
let contacts: IContact[] = [];
let selectedContacts: IContact[] = [];
let activeContact: IContact | null;
let busy = false;2. Search State
svelte
let showSearch = false;
let searchValue: string;
let sort = "name";
let activeLetter: string;
let activeCharacters: string[] = [];3. Group State
svelte
let groupId: number | null;
let groupData: any;
let showNewGroupForm = false;
let edit = false;Key Functions
1. Contact Operations
svelte
// Load Contacts
async function search(term, alphabet, sort) {
busy = true;
try {
const ret = await readContacts(term, alphabet, sort);
contacts = ret.success ? ret.data : [];
activeCharacters = ret.contactAlphabets;
} finally {
busy = false;
}
}
// Favorite Management
async function addFavourite({ detail: contact }) {
const ret = await setFavourite(contact.id, true);
if (ret.success) {
await dSearch(searchValue, activeLetter, sort);
}
}2. Communication Functions
svelte
// Start Chat
async function onMessage({ detail: contact }) {
const selected = contact ? [contact] : selectedContacts;
$activeChat = { targets: selected };
const ret = await sendMessage({
content: "",
contacts: selected.map(x => x.id)
});
if (ret.success && ret.data?.groupId) {
activateChatGroup(+ret.data.groupId);
}
}
// Initiate Call/Event
function onCall({ detail: contact }) {
activeContacts = contact ? [contact] : selectedContacts;
startNow = true;
showNewEventForm = true;
}3. Group Management
svelte
// Create Group
async function createGroup(command) {
const ret = await createGroup({
name: groupData.groupName,
description: groupData.description,
participants: known,
unknownParticipants: unknown
});
if (ret.success) {
showInfo("Group created successfully");
await dSearch(searchValue, activeLetter, sort);
}
}Event Handlers
1. Contact Selection
svelte
function onContactChecked({ detail }) {
const { contact, checked } = detail;
if (!checked) {
selectedContacts = selectedContacts.filter(x => x.id !== contact.id);
} else {
selectedContacts = [...selectedContacts, contact];
}
}2. Real-time Status Updates
svelte
function onUserStatusChanged(status) {
contacts = contacts.map(x => {
if (x.username == status.username) {
x.online = status.online;
}
return x;
});
}Permissions
svelte
// View Access
if (!hasPermission(Permissions.viewContacts)) {
$goto("/private/dashboard");
return;
}
// Group Management
{#if hasPermission(Permissions.manageGroups)}
<button on:click={() => showNewGroupForm = true}>
New group
</button>
{/if}Lifecycle Management
svelte
onMount(async () => {
// Check permissions
if (!hasPermission(Permissions.viewContacts)) {
$goto("/private/dashboard");
return;
}
// Initial data load
await dSearch(searchValue, activeLetter, sort);
});
onDestroy(() => {
unsubscribe("userStatus", onUserStatusChanged);
});