Approach to ConversationListBox
Goal of this document is to describe the steps involved in moving from a Textview based widget to a ListBox based widget and to describe to the project what the plan behind the coming PRs and commits will be, also requested by @lovetox.
The document is stored in wiki form to allow discussion and mutual manipulation of the document.
For reference, here's the relevevant discussion from the Gajim MUC (where
erik == @ehuelsmann):
[11:22:39 PM] lovetox: erik, yes refactoring some things before working on the listbox is a good idea [11:23:14 PM] lovetox: its best you write down where you see potential for refactoring and let me look over it [11:23:58 PM] lovetox: so i can tell you into how much of a rabbit hole you are getting your self :) [11:24:48 PM] erik: lovetox: thanks. I've started some initial explorations in that area. Are you asking that I wrote something like a refactoring plan before going into the actual effort? [11:24:49 PM] lovetox: and of course the smaller the PR the faster it gets merged [11:24:56 PM] erik: I think that's fair [11:25:38 PM] erik: Ok. I'll write a bit of a plan and work on small commits along the plan. [11:26:04 PM] lovetox: yeah i think its usefull if you tell me what and where you want to refactor before you start it [11:33:25 PM] erik: I'll need a few days to get more of a grip on the code base.
High level assessment of the existing code base
ConversationTextview is tightly coupled with
HtmlTextview as it highly depends on the fact that the HtmlTextview is an editor: it directly accesses the editor buffer and uses it all over the place.
On the other side,
ChatControlBase depend on
ConversationTextview to display the list of messages, where
HistoryWindow uses some of the api provided by
ConversationTextview to populate the window and does some formatting of its own.
ChatControlBase leaves formatting of messages entirely to
The view performs the following functions:
- Maintaining a mapping of message IDs to text buffer positions
- Maintaining a mapping of 'time' to text buffer positions
- Maintaining a list of corrected messages (by message ID)
- Formatting message lines:
- Adding encryption status
- Adding a timestamp
- Adding the nick of the sender
- Scanning and formatting URLs in message text
- Formatting non-message lines (such as status messages, muc title, etc.)
- Deal with all user-interactions through the registration of various event handlers (popup menu, clicking of URLs, etc.)
HtmlTextview adds a single function to the above: parsing the provided content for
xhtml-im content (and cleaning non-compliant content).
ConversationTextview maintains the following API to achieve the formatting functions:
- (creation and updates of
HtmlTextview.get_buffer()-tags in various places)
For the mappings it maintains the following functions and attributes:
- correct_message [function]
- message_list [attribute]
- last_received_message_id [attribute]
HtmlTextview manages presentation with the following functions:
- display_html (which is also responsible for handling
From the summary above, it seems like
ConversationTextview is all of the model, the view and the controller: it maintains the data to be presented in all its aspects (model), it generates/manages presentation by virtue of the various
print_* methods (view) and it deals with various signals (e.g. user input) which affect presentation as well as other actions such as starting external browsers and all.
This mixture of roles of the
ConversationTextview complicates replacing the presentation of messages with a ListBox from a Textview.
Approach to moving to a listbox
- Separate the concerns currently concentrated in ConversationTextview a. Add new setup to this document a. Agree on changed separation of concerns with @lovetox (and others?)
- Gradually implement the new separation
- Based on separated concerns, design a ConversationListBoxview and ListBoxrow
- Implement minimal Listboxrow and ConversationListBoxview
- Synchronize APIs between ConversationListBoxview and ConversationTexview
- Based on some developer setting make listboxview and textview selectable
- Work on primary ListBoxrow until it's on-par with the current textview approach
- (merge the on-par replacement to master?)
- Develop specialized ListBoxrows for status messages, subject lines, etc., etc.
Requirements for a new design
High level functional requirements
- Allow for progressive introduction of improved presentation of various types of "messages" (rows)
- Allow swapping in/out of the current Textview based on developer need (and allow experimentation with other presentations in the future)
- Be on-par presentation-wise with the existing view (before being merged to master)
- Separate the concerns (at least) to be able to swap various presentation experiments quickly and easily
- managing the presented content & reacting to (user) input
- Building presentation logic which maps various types of messages to their respective ListBoxrow classes to allow differences per message(type)
(to be done)
In a chat with @lovetox, the following requirements were mentioned as well:
[04:46:27 PM] lovetox: first goals should be, the listbox should provide a way to add a message row, the message row itself should be a object that displays an avatar, the message, encryption symbol [04:47:25 PM] lovetox: the message row object should be based on some generic object, we will probably need many row objects that slightly differ [04:47:43 PM] lovetox: like some kind of status messages, error messages, info messages, etc [04:49:23 PM] wurstsalat: File transfers, image previews :)