With the new use of RoomFlags for signifying whether or not a room's
chat should be populated with local logs (ROOM_POPULATE_LOGS),
SaveLogs() is redundant.
A Commands() method was added to the CayaProtocol class returning a
CommandMap, which will be used by Caya when searching for commands.
KeyList::AddList() and List::AddList() were also added to libsupport,
for convenience.
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).
This makes it so RunView's built-in timestamps are used― but requires
that a time_t be sent with each newly-appended line. This allows for lines to
be backdated or forward-dated.
Add a program-wide avatar cache― whenever a contact or user's avatar has
changed, it gets cached in ~/config/settings/Caya/Cache/$account/People
(for contacts) or $account/Users (for everyone else).
ImageCache is now used, only for caching the kPersonIcon resource image―
it might be useful later for other commonly used images (status
indicators, etc).
Fixes#4
In the API, a firm distinction between initially fetching a room's
metadata and receiving further changes has been made:
IM_ROOM_METADATA will be sent to Caya on request (IM_GET_ROOM_METADATA)
with the room's name, subject, etc. The other metadata-related messages
should only be sent to Caya after the room is initialized, not as a
means of initially setting its metadata.
Basic room flags were added, though they aren't yet used― they should
allow the protocol/add-on/user to configure some room features. Logging,
auto-joining, etc.
Rooms are now cached in ~/config/settings/Caya/Cache/$account/Rooms/,
with each file representing a seperate room. The filename is used as the
identifier, and these files now also serve as log files. The log
attribute name has also changed from "logs" to "Caya:logs".
When a protocol has succesfuly connected, all cached rooms are
automatically joined.
When no accounts are active, all items in the Menubar->Chat menu are
disabled, and some other menu items related to starting/managing chats
are disabled in other views.
One new message was added to the API― IM_PROTOCOL_READY, which tells
Caya that a given protocol has logged in and is ready to receive
messages (rather than just sending).
This is currently done in XMPP after the roster is loaded, which be a
process that stalls the protocol for a few seconds. IM_PROTOCOL_READY
should only be sent after those initial, potentially time-heavy
operations.
Accounts can now be temporarily disabled (in a Pidgin-like style)
through Preferences->Accounts. Work is still required to allow
enabling/re-enabling of accounts on-the-fly, and for keeping an
account's disabled state persistent.
The ConversationListView is now an BOutlineListView, and rooms are
added as subitems to the item of their associated account. Right now,
account items aren't selectable or useful.
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.
A BAlert is used to inform the user of room invitations― InviteDialogue―
and to send their response directly to the protocol's looper.
Some new protocol messages were added (and older ones were moved around
to compenstate)― IM_ROOM_SEND_INVITE, IM_ROOM_INVITE_REFUSED,
IM_ROOM_INVITE_RECEIVED, IM_ROOM_INVITE_ACCEPT, and
IM_ROOM_INVITE_REFUSE.
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.
Allow kicking/banning/muting/unmuting/deafening and undeafening through
the UserListView right-click menu (if permissions are sufficient).
Support for banning, kicking, and muting were added to the XMPP add-on―
deafening isn't supported, so is left out.
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. :-)
Add scaffodling support for arbitrary roles and permission-based (and
varying!) UI.
A new class, Role, represents a user's role in a given room, with three
values:
* The role's title
* The role's permission-set
* The role's priority
The permission set is a bitmask value for various permissions (e.g.,
PERM_WRITE, PERM_BAN, etc), and priority is position in the hierarchy.
A user with higher priority (and PERM_BAN) can ban a user with lower
priority, but not vice-versa. Two users with the same priority can't
ban/kick/mute each other, etc.
These permissions should be used to determine what UI elements are
displayed― if the user doesn't have permission to ban users, then a
"Ban" button shouldn't exist. If the user is muted, they shouldn't be
able to type. So on and so forth.
For now, permissions are sent with a IM_ROLECHANGE message and stored
by the Conversation, but aren't really in use yet.
This system should be flexible groundwork to account for the varying
administrative hierarchies and norms of different protocols.
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.
Two new messages were added to the protocol API to do this:
M_ROOM_PARTICIPANTS, which can be used when someone joins a room, or
on joining a room to send a full list of users, and IM_ROOM_PARTICIPANT_LEFT,
for when a user has left the room/disconnected.
IM_SET_STATUS no longer assumes received data comes from contacts, but
any general user.
UserItem was made to reflect changes in the User's name.
Chat messages can now be reliably received in a given room. :)
Protocol messages was added to the API to allow joining abstract rooms
by their chat_id― IM_JOIN_ROOM and IM_ROOM_JOINED. To make room in
anticipation of future room-related calls, some messages' values have
been shifted.
A JoinWindow was created (found through [Chat→Join Room] or [Alt-J] in
the main window), to allow joining a room with this protocol message.
The user can select which account the room should be joined from through
a drop-down menu in the lower left-hand corner― a design I think could
be replicated in other parts of Caya well.
Path() and SetPath() in CayaProtocol were renamed to AddOnPath() and
SetAddOnPath() respectively. GetName() and SetName() were also added,
where "name" is the account name (aka the leaf of the protocols settings
path).
To Server, a new KeyMap was added for convenience (AccountInstances), to
associate these account names with their instance IDs.
UserListView and UserItem were added as the backbone of the user-list,
and the (currently unused) Caya message CAYA_SEND_INVITE was established
for inviting users to rooms.
Some menus were reworked (e.g., pop-ups of the RosterListView) or
generally tweaked to be more sensical or consistent.
ALT-↑ and ALT-↓ change the active conversation, based on its position
in the main window's ConversationListView. If a conversation is
registered by the main window, and no other conversation is selected, it
is automatically selected.
Now all instances of sending messages (bar status changes) to a
conversation's CayaRenderView only happen when attached to the window.
Messages sent by user appear after the protocol confirms it's been sent
(IM_MESSAGE_SENT), rather than appearing right after the user sends it
to the protocol (IM_SEND_MESSAGE).
Logs are now re-enabled (since they can safely be appended under any
circumstance).
Removes explicit setting of sizes in ConversationView and StatusView,
allowing them to be resized appropriately. Also rearranges StatusView
somewhat, so that it's more friendly to smaller sizes. (The avatar is
moved from being beside the status menu field to being beside the
nickname textbox.)
All chats now stay in a single window, which removes and switches its
current ConversationView with the appropriate one using
Conversation::GetView().
This is a stepping-stone to merging the ChatWindow into the MainWindow.
Now all active conversations will be listed in the main window, in a
ConversationListView. Clicking one of the items will open its
conversation window as you'd expect, etc.
The roster list is now split from MainWindow into RosterWindow, which
can be used arbitrarily for selecting something from contacts. The
im_what, title, and target can be specified.
Right now it's in use under the Chat menu, "New chat…". Chats can only
have two members (DM/PM), so "New chat…" directly leads to the roster
list.
In the future, roster list might be extended to allow specification of
non-contact users based on their identifiers, or filtering based on
protocol/account― this could help it with "invites" to future rooms,
etc.
IM_CREATE_CHAT and IM_CHAT_CREATED were also added to the protocol API,
allowing a new chat to be explicitly created from Caya or the protocol.
Also adds a function to protocols to toggle this― if CayaProtocol::SaveLogs()
returns true, then local logs will be used to popualte conversation
windows. Otherwise, it's up to the protocol itself.
A new protocol IM_MESSAGE was also created, IM_LOGS_RECEIVED, which can
be used to populate conversations with old logs.
This is a commit with it's foot in a lot of places, but:
The Conversation class was created as the abstraction of chats: All
ImMessages that are relevant to a conversation get routed through it,
meta-data on chats is stored in it (even if right now that's basically
limited to the user list and ID).
Server was given more methods to help accessing contacts―
ContactById(BString) and AddContact(Contact*). This better allows
Conversations to add and fetch Contacts as necessary. Right now, all
users in chats are treated as Contacts, so in the future creating an
independent userlist for Server (fUserMap?) would be useful.
Server also now stores all Conversations (fChatMap) and has some
convenience methods like for Contacts: Conversations(),
ConversationById(BString), and AddConversation(Conversation*).
CayaRenderView has been changed to not store user nicks, and will use
the appropriate nick of any arbitrarily-numbered user.
Users also have a map of all Conversations they are a part of
(fChatMap).
The Remove* methods of KeyMap now return the removed item.
This dichotomy is useful and necessary in multi-user chats, so I split
Contact into a parent class, User. User should be used for generic
members of rooms, Contact used mainly with the roster.
CayaProtocolAddOn now has the convenience functions ProtoIcon(),
ProtoSignature(), and ProtoFriendlySignature(), for getting info from
its default protocol.
Now an add-on can contain multiple protocols, and the protocol API has
changed. An add-on must now export protocol_count() and protocol_at(),
with the latter replacing protocol(). protocol_count() returning the
amount of protocols in a given add-on, and protocol_at(i) giving a
new CayaProtocol* "at" the given index.
CayaProtocol has also been changed, adding Signature(),
FriendlySignature(), Icon(), Path(), and SetPath(). The reasoning is
that different protocols (even within a single add-on) will have
different signatures and icons, so this data should be accessible from
the protocol itself.
CayaProtocolAddOn now has CountProtocols() and ProtocolAt(i), allowing
the accessing of multiple protocols. A CayaProtocolAddOn can be given a
default protocol index in the constructor, whose protocol will be
returned with Protocol(). Version() was also moved from CayaProtocol to
CayaProtocolAddOn.
* Add General section in Preference/Behavior
* Don't prompt at quit option under General section
* Show confirmation dialog on quit (if enabled)
Misc
* Replace +/- in preferences Accounts with Add/Del
Added unread message count to window title and also in notification.
Made one notification for each conversation, with new messages, the
count is simply being updated.
* Shows notifications when contacts go online or offline. Unfortunately XMPP plugins will send presence notifications when the roster is populate so presence notification is shown for every online contact when the roster list view is populated the first time.
There's only one little problem that will probably be solved after Alpha1: if you have multiple accounts, all of them will set the avatar icon and the user will see just the last icon set.