Status-react: Add an unread messages indicator inside chats

Created on 18 Oct 2018  ·  40Comments  ·  Source: status-im/status-react

User Story

As a user, I want to see the number of unread messages in a chat so that I can continue my chats where I left them and track my progress in catching up with new messages.

Description

_Type_: Feature

_Summary_: We need a visible way to indicate and track the number of unread messages left in a chat, and if desired, skip past them and mark all messages as read.

Expected behavior

User has an X number of unread messages in a chat. After opening the chat, we present a small badge to the bottom right with a counter of unread messages left. The chat is opened in the position before any new unread messages, where you last left it.
Scrolling downward should update the counter as the user scrolls past the unread messages, marking them as read. Tapping on the counter should scroll down to the last unread message and mark everything as read. When there are no unread messages left, we dismiss the counter.

Solution

You can follow the intended design in this prototype https://framer.cloud/taJfZ
Mobile designs are here in Figma
Desktop designs Figma

Some things to be aware of, please enclose the badge in a touchable that's slightly larger than the button itself, adding a 12px padding inside the touchable or a margin outside the button. The text inside the badge should be right aligned. The SVG for the icon can be exported directly from Figma, it's called scrollBottomIcon, lmk if you need help or further directions.

![](https://framer.cloud/taJfZ/2/framer/social-1200x630.png)
[Scroll - Unread](https://framer.cloud/taJfZ)
This project was made with Framer, a design tool for turning original concepts into working prototypes.
backlogged bounty-m chat feature

Most helpful comment

@StatusSceptre could we publish this one and also #8047 on gitcoin?

All 40 comments

Thanks @errorists

@dmitryn @yenda @janherich Would love your feedback on this. I recall we had some scroll position issues?

@chadyj yes, there are issues with maintaining scroll position on Android that i didn't overcome without using delay (not good for UX) https://github.com/status-im/status-react/pull/5665

This would be great. Where is it in the backlog @yenda? Also cc @vkjr re desktop.

If it isn't a priority, could we please bounty a quick solution up? Would make my inbox checking so much nicer!

It's the next issue avec the current one, should start this week.

@StatusSceptre could we publish this one and also #8047 on gitcoin?

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


__This issue now has a funding of 300.0 DAI (300.0 USD @ $1.0/DAI) attached to it as part of the status-im fund.__

Thanks for applying @bitsikka! Ping us if you need help getting started.

@bitsikka Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

  • [x] reminder (3 days)
  • [ ] escalation to mods (6 days)

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

@gitcoinbot have been held up wrapping up previous bounties, but they are over now. Moving on with this now.

Just wanted to say still working towards initial PR

Still research/gathering-resources mode

regarding

The chat is opened in the position before any new unread messages, where you last left it

this https://github.com/facebook/react-native/commit/65184ec could be useful(iOS only) but maybe not needed; fetching messages in gaps that was merged not so long ago, seems to be doing it without it :thinking:

@bitsikka Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

  • [x] reminder (3 days)
  • [ ] escalation to mods (6 days)

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

@gitcoinbot yes, still working. Making slow but steady progress. It is turning out to be as challenging for me as I thought it would be.

Hey @bitsikka! Just want to check in on this one. You still working on it?

@rachelhamlin yes, still working on it.
Ran into some external hiccups recently(weird pre monsoon flood, swelling macbook battery and such) - managed now.

I will have a PR soon

No rush in any case @bitsikka. But good to know. Glad all monsoon + battery issues are worked out! 😬

@bitsikka Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

  • [x] reminder (3 days)
  • [ ] escalation to mods (6 days)

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

@gitcoinbot I am still working on this.

Despite having taken so long, I still do not have a clear solution and working towards making it clear and reasonable. So, while I have not given up yet, It might just be that this is out of my league at this point. In which case I will have to give it up.

Either ways, I will have a definite answer in the next few days.

Thanks for baring with me, sorry for the delays.

Thanks very much for giving it a go @bitsikka. Chat-related features are tough.

@bitsikka btw did you notice that I changed the read status it is just a boolean for each message now which simplifies things a bit

@bitsikka btw did you notice that I changed the read status it is just a boolean for each message now which simplifies things a bit

@yenda It helps, thanks! I was somewhat aware of it due to having worked on #4158 New messages counter is shown for already seen messages. I am also aware of whole bunch of apis (including chat) moving soon from clojure to go mainly for performance.

I do diligently try to be up-to-date on all new development by watching all/most new PRs/issues, and rebasing - I have https://github.com/notifications as a pinned tab that I check multiple times a day :p sometimes to a detriment of getting distracted. I like that there are lots of improvements all the time including developer experience.

In the process I have noticed only minor changes in the code base that affects this feature so far.

While I am pursuing leads on various approaches to various parts of this feature, I still do not have a coherent/solid approach I have settled on yet.

But, it feels like I'm getting there and that is exciting. I still love this feature, and would love to do justice to it by doing whatever it takes; while keeping in sync with the overall direction the app is fast evolving; and while giving best performance; and being as timely as possible.

I am making progress on this in the sense that I now have a clearer idea about approaching different aspects of the solution to this issue. Since it is no use writing code without having more-or-less a clear plan, so far I have not written a whole bunch of code, except experiments, disabling old behaviors, and visible ui part of the code.

still rough ideas I have had (this is like the answer to the question in gitcoin about "how will you approach?" for which I said "I don't know" before :p )

1) use viewabilityConfig and onViewableItemsChanged properties of flat-list for updating unread count. Turns out those props are perfect for that.
2) use getItemLayout for the kind of flexibility(see 3) in scrolling we need.

Problem with this is that `getItemLayout` works best with items of fixed height; but, items in our flat-list are made up of various types of messages of varying height.

Even then, I think the height of messages are/can-be-made to be deterministic. So, we can calculate and store the height of each message as it get added to local db. We can use https://github.com/aMarCruz/react-native-text-size or something like that for algorithm to calculate message height for `getItemLayout`.

This seems quite complicated, but seems worth checking it out.

3) use initialScrollIndex to start chat scrolled at particular index "remembered", instead of starting at the top with the first item. Needs getItemLayout to have been implemented.
4) maybe optional/non-critical, use the undocumented prop (iOS only) maintainVisibleContentPosition to keep view from scrolling jankily when new messages arrive and current scroll position is not at the bottom/present.

maybe implement this for Android natively taking cues from iOS implementation.

perhaps it may also be, that this may allow insights to attain scroll flexibility efficiently without having to implement `getItemLayout`.

@errorists @hesterbruikman There is also an issue I am foreseeing now in design/ux. Scroll to bottom button with unread messages counter design assumes that there will only be new present/future messages added to the bottom of the messages list. But, due to "gaps" loading feature, there can also be unread messages towards the top of the list. In this case the arrow-down icon and scrolling only to bottom when pressed can be confusing.

I have thought about maybe having arrow-down and scroll-to-bottom on press primarily; and then once the messages in the present have all been seen, if there are still unseen messages in the past, have the arrow-up icon and scroll to top, to mark all messages as seen.

I don't know what the best approach to ux for this is, but, I do have more pressing issues atop to tackle for now.

cc @yenda @rachelhamlin

@bitsikka would you mind shooting me an email at [email protected]? We also have other more pressing items we'd love your help on, if you have time coming up. And additionally, would like to make sure your time here doesn't go to waste.

@bitsikka would you mind shooting me an email at [email protected]? We also have other more pressing items we'd love your help on, if you have time coming up. And additionally, would like to make sure your time here doesn't go to waste.

Thanks! @rachelhamlin
I just sent you an email

Update:

For 1) it turns out onViewableItemsChanged does not quite register some gaps of items if user scrolls really fast. It skips gaps of items that ought to be marked as seen. But, it looks like we can detect the gaps by using onScrollBeginDrag and onMomentumScrollEnd props to capture min/max index and diff the range with the set of ids registered by onViewableItemsChanged.

There are also performance issues in updating app-db/realm-db frequently in marking items as seen as frequently in the new behavior than how it was in the old behavior. So, will have to optimize somehow using deferring/batching/using-component-or-screen-local-state techniques.

@bitsikka how are you? still working on this?

@tbenr, so good to hear from you! 😄 I am doing great caught up in a different aspect of life that sorely needed attention. Trying to get back to the community hopefully soon.

I stopped working on this in what feels like a long while ago. Unfortunately, lost all work accidentally deleting the branch ☹️ , so I don't have anything to share.

@bitsikka glad to know you're well! Take your time but come back!

Sad to know you lost the work. I'll get info from your comments here.

Let us know when you're up and running again!

I have had a look at this, and come up with some technical issues that are not so straightforward to solve:

We load the oldest unread message from status-go, and also we load the next 20 messages. We can't load all the messages as that would choke the UI if there are many.

That means that we need to have pagination on both sides now.

This is problematic as FlatList will autoscroll on prepending messages (we use an inversed flat list) https://github.com/facebook/react-native/issues/25239

Which means that as you add a new page, it will automatically scroll to the new messages.

In IOS we can use an undocumented feature maintainVisibleContentPosition which solves the issue, but is not available on android.

What I tried is to "scroll back" to the current position after messages are rendered, that works but gives a fairly unpleasant UX (you see messages being scrolled down, and then it jumps back to the original position).

Discord managed to get it working properly (it can be seen in their app), but they are using their own List implementation https://blog.discordapp.com/how-discord-achieves-native-ios-performance-with-react-native-390c84dcd502 , which they say they will open source eventually, but no news on that front for a while.

I will look a bit further into whether is possible to have the same behavior on android, but will time box it and there are many unknowns.

This is awesome @cammellos. Well, not an awesome outcome, but it makes sense to me to get more intel on it.

Could you tell me how many hours you plan to dedicate to this?

Also, am I right to assume that we could build the feature on iOS?

@rachelhamlin I haven't tested on IOS but as I understand it should be possible yes (and should work smoothly).

We have found this https://www.npmjs.com/package/dcd-fast-list which might be discord version of the list which might help with some issues. I have currently tested it a bit and seems like it's a bit different from what we need (no inverse list, we need to be able to compute height of components before having rendered them).

I would probably spend maximum 4 or 5 hours (a morning) on this and see how far we get, and re-evaluate, no more.

@cammellos got it. K. Well then we could make iOS even with Android, considering they won't have push notifications. 😛

I'm going to put this in Fogbugz as a spike.

Some progress on this? Is still possible to move forward and continue the work here?

@alexanmtz hey do I get this right, do you volunteer to work on this one? cause we need it badly. But no, sadly there was no progress made since the last few messages here

@errorists I want an update about this cause I'm interested, and it seems challenging, and I want to know if is possible to continue, so I can apply with a Gitcoin bounty. And I had contributed with Status before, but not this part of the application.

@alexanmtz as @errorists said, would still love to see this issue tackled. Let us get back to you here after the weekend so we can check if any specifics on the issue need updating

@alexanmtz thanks for looking into this.

Currently the blocker is on android side is this https://github.com/facebook/react-native/issues/25239 , ideally we find a solution for both android and ios.
If that's not possible/feasible an ios only solution is probably acceptable, if @hesterbruikman and @errorists are ok with it.

Let me know if you have any question, or I can help you with anything

Issue Status: 1. Open 2. Cancelled


__The funding of 300.0 DAI (300.0 USD @ $1.0/DAI) attached to this issue has been cancelled by the bounty submitter__

There's an update, someone wrote a PR for Android, and there's an implementation that can be used https://github.com/facebook/react-native/pull/29466#issuecomment-664367382 , apparently it still has some issues, but might be worth a try.

Was this page helpful?
0 / 5 - 0 ratings