One of the design nuggets by Dr. Drew was to think about how to manage contacts. If you’ve been reading our (BedLamp, marcb, raxter) blogs, you’ll know by now that we’ve taken a highly modular/granular approach to this project. Each concept is mapped to it’s own class, right down to each packet type.
So, how did we go about solving the questions posed by Dr. Drew? Up until today, we had all contact management floating around in the GUI code. This was making me unhappy, so today’s goal was to extract that logic into it’s own module. Nugget for nugget, here is a quick look at how this new module fares.
Can your users quickly find the contact they’re looking for? What if their contact list exceeds 1000 contacts?
MXit::AddressBook provides an abstraction for dealing with contacts. Contacts are stored in a QHash, where the hash key is the contactAddress (unique) and the value of that key is the actual MXit::Contact, a base class for constructing and managing a contact. Additionally, AddressBook uses a QMap which is a special type of hash – keys are ordered using a heap. The key in the map is actually a mixture of a numeric presence-rating and the contact’s addres. For example, if John is online, the QHash will store him as <”John”, Contact*>, while the QMap will store him as <”1john”, Contact*>.
This is a very lightweight solution to ordering contacts. The QHash allows for very fast lookups by contact address (mostly to check uniqueness to decided whether to insert a new contact or update an existing one), while the QMap allows for very fast ordering. Contact’s are stored as pointers, meaning that both structures will leave a small footprint in memory.
Can we find the contact they want? Absolutely, with O(1) time. Can we manage 1000+ contacts? Absolutely, and with O(logn) insertion time (at login) and O(1) update time (status changes).
What kind of filtering mechanism are you planning to use? Are you planning to use a flat, 1-dimensional list or perhaps something a bit more structured? Searching and grouping are two obvious approaches…..try think of something fresh.
Contacts are ordered first by presence, then by name. We currently have no support for groups, or searching. Watch this space!
How do you plan to keep your users informed about the various chat events that are taking place e.g. new messages, status changes etc.
We have seperated the concepts of contacts and conversations into just that: contacts and conversations. Double-clicking on a contact will not just open up a chat window to that contact. Rather, it will create a conversation with that contact. Conversations can contain an arbitrary number of contacts (e.g. group chat) and are managed from a seperate widget. As for notifications, we now have a system tray icon which pops up event notifications.
Finally, my plans for the new Message class are quite nifty, if I say so myself. I plan on mimicking a paging algorithm (used by Operating Systems to manage memory) so that extended conversations, or run time, doesn’t have a negative impact on your system. That is, old messages will fade out of memory and land up in a log file. If a user scolls up in the conversation these messages will be paged back into memory. This is also a nice step towards keeping message history, so that users can lookup old conversations.
As you can see, we are well on our way to having good contact management. One of the main areas we’ve been focusing on is to make the chat-side of the application as smooth as possible. This sounds kind of obvious, but it is important to not get let all the other features of MXit detract from it’s core: a chat application.