eBay/NMessenger

[wish] move messages to a specified index path

dodikk opened this issue · 3 comments

To solve the following app use-case :

GIVEN message sending has failed
WHEN resending succeeds
THEN message timestamp is changed to latest time and it should be moved to the bottom of the screen

    open func moveMessage(
        _ message: GeneralMessengerCell,
        to index: Int)
    {
        precondition(Thread.isMainThread)
        precondition(0 != self.state.itemCount)
        
        let table = self.messengerNode
        
        let bottomIndexPath =
            IndexPath(
                row: index,
                section: NMessengerSection.messenger.rawValue)
        
        self.waitForMessageLock
        {
            [weak self] in
            
            guard let strongSelf = self,
                  let messageIndexPath = table.indexPath(for: message)
            else
            {
                self?.state.messageLock.signal()
                return
            }
            
            if let messageIndexInBuffer = strongSelf.state.cellBuffer.index(of: message)
            {
                strongSelf.state.cellBuffer.remove(at: messageIndexInBuffer)
                strongSelf.state.cellBuffer.insert(message, at: index)
            }
            
            DispatchQueue.main.async
            {
                precondition(Thread.isMainThread)
                table.moveRow(at: messageIndexPath, to: bottomIndexPath)
            }
            
            strongSelf.state.messageLock.signal()
        }
    }
    
    open func moveMessageToBottom(_ message: GeneralMessengerCell)
    {
        precondition(Thread.isMainThread)
        precondition(0 != self.state.itemCount)
        
        let isInverted = true
        let bottomIndex: Int = (isInverted) ? 0 : (self.state.itemCount - 1)
        
        self.moveMessage(message, to: bottomIndex)
    }

No luck so far. The messages disappear but some blank space appears at the bottom.
Will workaround with "delete + add" so far.

Add + remove works only with `. scrollsToMessage =true"

    private func implMoveMessage(
        _ message: GeneralMessengerCell,
        to index: Int,
        completion: (()->Void)? = nil)
    {
        precondition(Thread.isMainThread)
        precondition(0 != self.state.itemCount)
        
        self.removeMessagesWithBlock(
            [message],
            animation: .none)
        {
            DispatchQueue.main.async
            {
                self.addMessagesWithBlock(
                    [message],
                    scrollsToMessage: true,
                    withAnimation: .bottom,
                    completion: completion)
            }
        }
    }

Otherwise it crashes since .state.cellBuffer is out of sync with the moved cell index.

screen shot 2017-11-03 at 7 01 35 pm