RFC: dealing with timestamp-induced judder on TL #374

Open
opened 2024-02-22 19:34:59 +00:00 by Oneric · 0 comments
Member

#353 fixed notifications constantly moving around due to changing timestamps.
However, as it turns out this can sometimes also happen for full notes on the TL or a thread view.

I have ideas how to fix this, but would ideally like to get some feedback on the options first. I’ll explain the source of the problem and possible solutions in detail below.

Unlike notifications, which show the displayname, sometimes the handle and some descriptive text in their title, normal notes only show the displayname and handle. (In the left section which is a flexbox; the right section contains the timestamp, scope indicators and the collapse button).
The displayname is already set to hide overflow with an ellipsis, and the handle + instance icon forms a nowrap block. However, it is possible for an automatic linebreak to be inserted between displayname and the handle if they don’t fit into a single line.

Now if both initially just fit into a single line for a time of say 9min ago, after a little while the timestamp will update to 10min ago causing a linewrap to be inserted, thus changing the height of the note container and everything shifting a bit. The same can happen the other way around when a linebreak is no longer necessary when going from e.g. 59min ago to 1h ago.

Now, at first thought it might seem reasonable to just copy the approach from #353 and always reserve enough space for any reasonable timestamp. However, just like in #353, this would be an issue for the long-form timestamps due to differences in localisations and most of the time wasting way to much space. I don’t think it is desirable to use short timestamps here either.

However, since we only have to deal with two blocks and a single possible linebreak, we have other options not possible for notifications. They come with different tradeoffs though and making the approach a user options would get too messy I think.

  1. Just don’t allow an automatic linebreak between the two blocks; i.e. set

    .Conversation .Status .heading-left {
        flex-wrap: nowrap;
    }
    

    This is foolproof and what I’m using atm (with !important) as a client-side CSS addition.
    However, it is overly punishing on long displaynames imho, and for remote users whose handle contains the whole domain, the display name doesn’t even need to be that long to trigger ellipsis.

  2. Just always enforce a line break between the two, i.e. add something equivalent to the following after the displayname (if we’re not inside the notification view and without using inline style):

    <div style="height: 0px;flex-basis: 100%;"></div>
    

    This also works, but to me feels like a waste of space for local users and/or short displaynames.
    Additionally, this should also allow enabling ellipsis for handles to avoid handles overflowing over the entire screen for ridiculously long domain or nicknames. Though I can’t seem to get this ellipsis working in initial testing.

  3. Freeze the line count after initial creation.
    This avoids wasting space and punishing long displaynames, but comes at the cost of notably increased implementation complexity (and I’m not sure whether that’s desired) — and doesn’t help with overly long handles i guess we can also add a class for two-liners to neable handle ellipsis.
    I don’t have an actual implementation yet, but the basic idea is:

    • somehow set unique refs for the displayname and handle elements in the .vue file
    • on the .js side, on component creation check whether the offsetTop properties of both are identical
      (potentially a race condition if the user is scrolling??)
      • if identical: add a class to the element which will enable nowrap
      • if differing: insert the force-linebreak element like in option 2. (and leave the default wrap mode)

If you’re wondering “but why can’t we do totally different option X”, or “why does the above use such an ugly CSS/JS hack instead of the cleaner and more concise feature Y”, the answer is probably because I don’t know about X/Y. I’m not too well-versed with web frontend stuff; do not hesitate to suggest alternative approaches.

Version

ed0b403

Severity

I can manage

Have you searched for this issue?

  • I have double-checked and have not found this issue mentioned anywhere.
#353 fixed notifications constantly moving around due to changing timestamps. However, as it turns out this can sometimes also happen for full notes on the TL or a thread view. I have ideas how to fix this, but would ideally like to get some feedback on the options first. I’ll explain the source of the problem and possible solutions in detail below. Unlike notifications, which show the displayname, sometimes the handle and some descriptive text in their title, normal notes only show the displayname and handle. (In the left section which is a flexbox; the right section contains the timestamp, scope indicators and the collapse button). The displayname is already set to hide overflow with an ellipsis, and the handle + instance icon forms a `nowrap` block. However, it is possible for an automatic linebreak to be inserted between displayname and the handle if they don’t fit into a single line. Now if both initially just fit into a single line for a time of say `9min ago`, after a little while the timestamp will update to `10min ago` causing a linewrap to be inserted, thus changing the height of the note container and everything shifting a bit. The same can happen the other way around when a linebreak is no longer necessary when going from e.g. `59min ago` to `1h ago`. Now, at first thought it might seem reasonable to just copy the approach from #353 and always reserve enough space for any reasonable timestamp. However, just like in #353, this would be an issue for the long-form timestamps due to differences in localisations and most of the time wasting way to much space. I don’t think it is desirable to use short timestamps here either. However, since we only have to deal with two blocks and a single possible linebreak, we have other options not possible for notifications. They come with different tradeoffs though and making the approach a user options would get too messy I think. 1. Just don’t allow an automatic linebreak between the two blocks; i.e. set ```css .Conversation .Status .heading-left { flex-wrap: nowrap; } ``` This is foolproof and what I’m using atm (with `!important`) as a client-side CSS addition. However, it is overly punishing on long displaynames imho, and for remote users whose handle contains the whole domain, the display name doesn’t even need to be _that_ long to trigger ellipsis. 2. Just always enforce a line break between the two, i.e. add something equivalent to the following after the displayname (if we’re not inside the notification view and without using inline style): ```html <div style="height: 0px;flex-basis: 100%;"></div> ``` This also works, but to me feels like a waste of space for local users and/or short displaynames. Additionally, this should also allow enabling ellipsis for handles to avoid handles overflowing over the entire screen for ridiculously long domain or nicknames. Though I can’t seem to get this ellipsis working in initial testing. 3. Freeze the line count after initial creation. This avoids wasting space and punishing long displaynames, but comes at the cost of notably increased implementation complexity *(and I’m not sure whether that’s desired)* — and ~~doesn’t help with overly long handles~~ *i guess we can also add a class for two-liners to neable handle ellipsis*. I don’t have an actual implementation yet, but the basic idea is: - somehow set unique refs for the displayname and handle elements in the `.vue` file - on the `.js` side, on component creation check whether the `offsetTop` properties of both are identical *(potentially a race condition if the user is scrolling??)* - if identical: add a class to the element which will enable `nowrap` - if differing: insert the force-linebreak element like in option 2. *(and leave the default wrap mode)* If you’re wondering “but why can’t we do totally different option X”, or “why does the above use such an ugly CSS/JS hack instead of the cleaner and more concise feature Y”, the answer is probably because I don’t know about X/Y. I’m not too well-versed with web frontend stuff; do not hesitate to suggest alternative approaches. ### Version ed0b403 ### Severity I can manage ### Have you searched for this issue? - [x] I have double-checked and have not found this issue mentioned anywhere.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: AkkomaGang/akkoma-fe#374
No description provided.