stream-chat-swift icon indicating copy to clipboard operation
stream-chat-swift copied to clipboard

ChatChannelListVC ignores taps if you tap quickly after navigating back from ChatChannelView

Open linhewinner opened this issue 3 years ago • 1 comments

  1. Go to ChatChannelVC.
  2. Return to ChatChannelListVC.
  3. Tap on a row quickly ... tap is often ignored. A second tap would work. Note that I have localStorage enabled.

I'll explain the root cause and my work-around. I hope Stream can put this fix into ChatChannelListVC so others won't have to wrestle with this.

When you return from a ChatChannelVC, I observed that some channels often get updated (not sure why ... maybe read state or watcher count related). This causes ChatChannelListController:didChangeChannels: callback to be invoked here: https://github.com/GetStream/stream-chat-swift/blob/7fce6491dd95839c45cf8518faff0fb7eacc0ef3/Sources/StreamChatUI/ChatChannelList/ChatChannelListVC.swift#L300

The changes are usually updates only (i.e. no insert/remove/move), but the code calls performBatchUpdates which triggers a server animation. During the animation duration (250ms or so), the ChannelListView appears static but taps will be ignored due to the ongoing "animation". From a user's perspective, it feels like the ChatChannelListView is just ignoring taps for no reason.

Here is my workaround that I hope Stream team can put into the default implementation of ChatChannelListVC

    override func controller(
        _: ChatChannelListController,
        didChangeChannels changes: [ListChange<ChatChannel>]
    ) {
        let updates = changes.filter { change in
            if case .update = change {
                return true
            } else {
                return false
            }
        }

        // Changes can be insert, remove, move or update. The default
        // implementation animates these changes in the thread list.
        // Whenever you foreground the app or navigate back from a
        // thread, there are almost always some updates: e.g. read state
        // Now those updates are "animated" for 250ms or so, during which
        // time taps are ignored. This obviously creates a bug.
        //
        // Now how about we just disable the animation altogether? That
        // is not nice if threads are added, removed or moved around.
        // We still want animations in those case
        //
        // Hence here ... we disable animation if there are ONLY updates;
        // but we continue to allow animation for inserts/removes/moves.
        if updates.count == changes.count {
            UIView.performWithoutAnimation {
                super.controller(controller, didChangeChannels: changes)
            }
        } else {
            super.controller(controller, didChangeChannels: changes)
        }
    }
}

GetStream Environment

GetStream Chat version: 4.10.0 GetStream Chat frameworks: StreamChat, StreamChatUI iOS version: iOS 15.3.1 Swift version: Xcode version: Device: iPhone 13 Pro

Additional context

linhewinner avatar Feb 20 '22 05:02 linhewinner

Hi @linhewinner!

Thank you for taking the time on opening this issue!

This is a known issue that we currently have. Although your solution works by disabling the animations, the root cause actually comes from 2 places, from the Avatar View, which is doing a lot of work currently on the main thread when merging multiple user images and also when getting the last message from a channel which is fetching and parsing data from DB on the main thread.

We will keep this issue open so other people can keep track of it.

Thank you again for your report, we will keep you updated once we have this issue fixed! Until then, your workaround should be okay 👍

Best, Nuno

nuno-vieira avatar Feb 20 '22 17:02 nuno-vieira

Hello!

This is now fixed on the release 4.48.0+ 🚀

Thank you for your patience on this one 🙏

Best, Nuno

nuno-vieira avatar Feb 12 '24 13:02 nuno-vieira

Hi there,

We've made even more improvements in this regard in 4.49.0 👍

Best, Alexey

testableapple avatar Feb 28 '24 10:02 testableapple