In Chat-O-Matic, text messages are enqueued by the ConversationView
and appended when the ConversationView becomes attached to the window
(editing a non-attached BTextView doesn't go well).
Previously, only the receive-time was added to the enqueued message― so
that if the view doesn't come into focus for a long while after message
receipt, the timestamp is still accurate. The user's nickname and color
weren't added as well, meaning that if the user left the room before the
message was appended, the ugly user-id and default user color would be
used instead.
This appends user_color and user_name.
Binary logs are no longer stored as a single message with a list of
strings and int64s ("body", "user_name", "user_id", "when"), but a
message with sub-messages (IM_MESSAGE_RECEIVED) verbatim saved.
This has the main benefit of preserving message formatting (coloring,
bold, italics, etc).
Chat messages can now be formatted with colors in addition to varying
faces with "color_start," "color_length," and "color" slots in
IM_MESSAGE_RECEIVED.
Now addons can format messages with new slots accepted by
IM_MESSAGE_RECEIVED: "face_start," "face_length," and "face".
The first two deal with the position of the face-change by character
offset in the string, and the last being the face flag affected.
Now, per each account, there is a read-only chat view associated with
it, accessible through its item in the conversations list. This can be
used to place system messages, MOTDs, insignificant errors, etc.
Protocols can send text to this buffer by specifying no "chat_id" in
an IM_MESSAGE_RECEIVED message.
Seperate UserItems are now created for each list, too, rather than a
single one being created per-user. This functionally works a lot nicer.
But onto more important things… now setting the user's own nick should
work quite well. Finally. =w=
This has given me a good bit of trouble over the past couple of days―
setting the user's nick *worked*, but it wouldn't propagate to its
corresponding UserItem nor its UserInfoDialog. It would, however, work
with the StatusView.
These are all registered Observers of the User itself, so if one works,
they *all* should, them all being registered to the same User.
Now, if a given User isn't found in the ProtocolLooper's user-list,
the Conversation class will take it upon itself to create a new
one and add it to both of their respective lists.
So the user's own contact would be set in the ProtocolLooper― but it
*wouldn't* be added to the user-list.
Hilarity ensues as two seperate objects for the user's own contact would
be created.
Since the StatusView is registered to the ProtocolLooper's "real" own contact
slot, it would receive all updates… but since Conversations' user-lists and
items would be registered to the Conversation-created "fake" user, they
would be borked.
Simple oversight, but wow it hecked with me. :P
/me waves arms in the air like a maniac
/me knocks over a nearby cup of coffee
/me gasps when the coffee spills onto the adjacent laptop
/me cries out “Fore! Wait, four! Wait, fire!” when the laptop bursts
into flames
/me burns to a crisp
If the user has permission to change a room's subject or name, they can
now edit the text views displaying them (toward the top of the window).
When enter is pressed, the changes will be sent to the protocol.
To do this, a BTextView subclass was added to libinterface
(splitting somewhat from SendTextView)― EnterTextView sends a message
containing the text to the given target when the user hits enter sans
modifiers.
When a new message is posted (or the user is messaged), the room's item
in the roomlist is now highlighted, like Vision.
Chat also auto-scrolls when new messages are posted.
If the user's in a one-on-one chat, notify on every message― otherwise,
only notify when the user's name/ID is mentioned by another user.
Notifications should be managed by roomflags, but that's for another
time.
The BTextBox used for sending messages has been moved from the main
window to individual ConversationViews, allowing seperate histories,
texts, etc., to exist in different conversations.
EditingFilter (a filter that hooked into MainWindow) was previously used
to field special key combos with this textbox, including "ENTER" for
sending, but this has been replaced with a new textview subclass
(SendTextView).
A new class was added (ChatCommand) to represent commands, which are
all stored in the Server iself.
A command can be assigned any arbitrary BMessage, and can be given
arguments with some semantic meaning (so far just "string" or "room
participant," etc).
"invite" and moderation commands were added (ban/kick/mute etc).
Previously, all Conversations/Contacts/Users were stored in the Server,
each in their respective KeyMaps, identified solely by their
identifiers. This leads to the glaring problem of overlap― if the user
has multiple accounts, some users/rooms might be used or present in multiple
accounts at the same time.
Now, each accounts' Contacts, Conversations, and Users are stored in
its ProtocolLooper, making this overlap impossible. An oversight of only
allowing one user identifier to be stored (fMySelf) in Server was also fixed
this way.
This is the bulk of the work required for multi-account support― now,
the user can join the same XMPP room on two seperate accounts, and it
works perfectly.
Allows custom colors to be dictated to RunView directly from
CayaRenderView. Some colors that were reliant on hard-coded theme
have been replaced with system colors.
New API messages were added to distinguish between a user leaving of
their own volition and being kicked/banned.
Messages are now shown in the chat view when a user leaves or or
kicked/banned, etc.
If chat logs are stored in an endless plain-text file, they're going to be a
pain to parse. If they're stored in a binary file, they're a pain for
the user to `grep` or go through manually, but they're easier to parse.
Why not both?
Logs are now stored with a BMessage (with BStringLists) in the 'logs'
attribute, and the plain-text logs in the file itself.
The attribute will only store 20 messages, but the file itself will be
appended to forever.
The logs directory also changed, from ~/config/settings/Caya/Cache/Logs
to ~/config/settings/Caya/Logs.
Useful functions for reading/writing messages to and from an attribute were
borrowed from BePodder's libfunky. :-)
Now the user can leave or be forced to leave a chat.
For this, two protocol API messages were added: IM_LEAVE_ROOM, and IM_ROOM_LEFT.
Aside from that, IM_ROOM_BAN_PARTICIPANT and IM_ROOM_KICK_PARTICIPANT
were added, though they aren't used yet.
The conversation view now displays the protocol icon and room subject.
Messages for receiving room names (IM_ROOM_NAME) and subjects
(IM_ROOM_SUBJECT) were added, and support for the latter was given to
the XMPP add-on.
New message APIs were added, and several (room-related) im_what values were
moved into the 150s/160s.
UserItem::_TintColor() was moved to CayaUtils, because it can be used in
several different contexts.
The new Notifier→Observer relation chain:
* Conversation → ConversationItem, ConversationView
* User → UserListItem, UserInfoWindow, UserPopUp
* Contact → RosterItem
These line up pretty intuitively― if something changes in the conversation, you
want the list item and view to change too.
But there's one more here that's less intuitive:
* User → Conversation
If Conversation observes something from a user (i.e., status change), it
immediately knows to do one thing only: invalidate the user list, because
something's changed.