Tuba icon indicating copy to clipboard operation
Tuba copied to clipboard

[Request]: Migrate timelines to ListView

Open bleakgrey opened this issue 1 year ago • 2 comments

Describe the request

This is going to be a long one.

As discussed previously, the status widget in its current state is causing us quite a bit of trouble. It's being pestered by 3 major issues:

Property binding issues There are some obscure errors caused by property binding lifecycle management, which renders some things broken (#103).

I believe this can be addressed by using Expressions introduced in GTK4. I'll quote the GTK team's post directly: GObject’s GBinding mechanism goes in the right direction, but is not flexible enough to handle situations where you may need to bind properties of sub-objects or widgets deep inside the hierarchy of your widget, and where the objects in questions may not even exist at the time you are setting up the binding.

I believe this is something we should try using instead.

View architecture Back when Tootle was a thing, I used .ui files to describe views. I found it a good way to separate layout from logic, and I still think we should stick to it. However, Tuba widened its scope quite a bit by adding support for new instance backends and instance features. I proposed a potential solution in #57 to accommodate these changes, but now I'm rather skeptical about my proposal as: a) the performance gains in #128 turned out to be rather negligent b) it seems to make the developer's quality of life worse by reverting back to defining views via code

Scalability Due to the fact that timelines use a ListBox (which constructs a widget for each status) and continuous scrolling, it may be a bottleneck for some low-end devices. Timelines can be modernized by porting them to use a ListView instead, which GTK devs recommend doing anyway: While it is not a problem for short lists to instantiate widgets for every item in the model, once lists grow to thousands or millions of elements, this gets less feasible. Because of this, the views only create a limited amount of listitems and recycle them by binding them to new items. In general, views try to keep listitems available only for the items that can actually be seen on screen.

All things considered, I think we've been optimizing the wrong thing. I've been searching for a way to reduce the complexity of the widget's hierarchy, when it makes much more sense to reduce the amount of the status widgets visible.

I propose doing the following:

  • Make the status widget use containers bound to ListModels when possible, especially so for emoji reactions and attachments. If a container's data model is empty, it's just an empty container that just sits in there and doesn't need much. However, it allows for seamless live updates via, say, stream events if such functionality should be needed.
  • Migrate timelines to the new infrastructure offered by ListView. It seems to scale much better, and uses just a handful of widgets that are rebound to different data objects as the user scrolls the view back and forth.
  • Do not construct status widgets dynamically, and rely on .ui view definitions that heavily abuse Expressions instead.
  • Deprecate the Widgetizible interface and let each timeline decide how to render its data model via its ListItemFactory. Each API entity now may want different views anyway (for example, a view for a API.Tag being displayed in search results, and another for being suggested by Composer's autocomplete).

All ideas are open for discussion, of course!

Implementation Details

  • [ ] This should be an option in settings.
  • [ ] This should be only available to some fediverse backends. (Include which ones on the above field).
  • [X] This is client-only (and shouldn't sync with the instance).
  • [X] This follows the GNOME HIG.

bleakgrey avatar Apr 10 '23 20:04 bleakgrey