Skip to content
This repository has been archived by the owner on Aug 1, 2019. It is now read-only.

[wish] images and text within a single content node out of box #143

Open
dodikk opened this issue Jul 19, 2017 · 10 comments
Open

[wish] images and text within a single content node out of box #143

dodikk opened this issue Jul 19, 2017 · 10 comments

Comments

@dodikk
Copy link

dodikk commented Jul 19, 2017

Often there is a case when a message bubble should contain both

  • multiple images
  • text

So far, each user is forced to implement that as a CustomNode. Having UICollectionView inside an AsyncDisplayKit node might hit the performance. On the other hand, AsyncDisplayKit might be hard to deal with for some users.

It would be nice to have such node out of box in the NMessenger.
Or a snippet in the README, at least.

@dodikk
Copy link
Author

dodikk commented Jul 20, 2017

I've managed to subclass CollectionViewContentNode and add some views by reusing super.layoutSpecThatFits. I don't like this approach but I'm not sure how to apply composition properly in this case.

A pull request will follow but here is the code :

import Foundation
import AsyncDisplayKit


open class CollectionViewWithTextContentNode: CollectionViewContentNode
{
    public var textMessageNode: ASTextNode?
    public var timestampNode  : ASTextNode?
    
    override open func layoutSpecThatFits(
        _ constrainedSize: ASSizeRange)
    -> ASLayoutSpec
    {
        guard let textMessageNodeUnwrap = self.textMessageNode,
              let timestampNodeUnwrap   = self.timestampNode
        else
        {
            return super.layoutSpecThatFits(constrainedSize)
        }
        

        // ====
        //
        let cellsLayout = super.layoutSpecThatFits(constrainedSize)
        
        let imagesPaddingInsets =
            UIEdgeInsets(
                top: 4,
                left: 15,
                bottom: 15,
                right: 4)
        let imagesPadding =
            ASInsetLayoutSpec(
                insets: imagesPaddingInsets,
                child: cellsLayout)
        
        
        // ==== timestampNode
        //
        let timespampPaddingInsets =
            UIEdgeInsets(
                top: 10,
                left: 15,
                bottom: 0,
                right: 0)
        let timestampPadding =
            ASInsetLayoutSpec(
                insets: timespampPaddingInsets,
                child: timestampNodeUnwrap)
        
        // ==== textMessageNode
        //
        let labelPaddingInsets =
            UIEdgeInsets(
                top: 5,
                left: 15,
                bottom: 0,
                right: 0)
        let labelPadding =
            ASInsetLayoutSpec(
                insets: labelPaddingInsets,
                child: textMessageNodeUnwrap)
        
        
        // ====
        //
        let result =
            ASStackLayoutSpec(
                direction: .vertical,
                spacing: 5,
                justifyContent: .start,
                alignItems: .start,
                children: [timestampPadding, labelPadding, imagesPadding])
        
        return result
    }
}

@dodikk
Copy link
Author

dodikk commented Jul 20, 2017

P.S. It works :

simulator screen shot jul 20 2017 12 35 37 pm

dodikk pushed a commit to dodikk/NMessenger that referenced this issue Jul 20, 2017
dodikk pushed a commit to dodikk/NMessenger that referenced this issue Jul 20, 2017
dodikk pushed a commit to dodikk/NMessenger that referenced this issue Jul 20, 2017
also using `defer` keyrowd for safer `imageListGuard.unlock`
dodikk pushed a commit to dodikk/NMessenger that referenced this issue Jul 20, 2017
dodikk pushed a commit to dodikk/NMessenger that referenced this issue Jul 20, 2017
@dodikk
Copy link
Author

dodikk commented Jul 20, 2017

Implemented in #146

@ignotusverum
Copy link

ignotusverum commented Jul 25, 2017

hi @dodikk, I see that you're using tabBarController with NMessenger. I have question regarding that:
Everything works fine on initial load, but chatView disappears when i switch back and forward between controllers from sim/device, and when i use debugView it's actually there, so i'm confused what's happening (i see that contentOffset is changing for some reason, still investigating why). Do you experienced same behavior with your implementation by any chance ?

@dodikk
Copy link
Author

dodikk commented Jul 26, 2017

@ignotusverum , unfortunately, I have not reproduced the described issue.

and when i use debugView it's actually there, so i'm confused what's happening (i see that contentOffset is changing for some reason, still investigating why)

Please check the z-order of your view hierarchy to see if chatView was not overlapped by some other view.

P.S. I believe, you should create a separate github issue and continue the discussion there. Some screenshots or code of your chat view setup would be helpful (but again, not in this github issue).

Skymax1986 pushed a commit to Skymax1986/NMessenger that referenced this issue Aug 28, 2017
Skymax1986 pushed a commit to Skymax1986/NMessenger that referenced this issue Aug 28, 2017
also using `defer` keyrowd for safer `imageListGuard.unlock`
Skymax1986 pushed a commit to Skymax1986/NMessenger that referenced this issue Aug 28, 2017
Skymax1986 pushed a commit to Skymax1986/NMessenger that referenced this issue Aug 28, 2017
@dodikk
Copy link
Author

dodikk commented Sep 20, 2017

A better implementation to avoid ugly inheritance #170

class VHMessageContentNode: ContentNode {
    
    public var textNode: ASTextNode?
    public var timestampNode: ASTextNode?
    public var attachmentsNode: CollectionViewContentNode?
    
    override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
        
        let children: [ASLayoutElement?] = [self.timestampNode,
                                            self.textNode,
                                            self.attachmentsNode]
        
        let stackSpec = ASStackLayoutSpec(direction: .vertical,
                                          spacing: 5,
                                          justifyContent: .start,
                                          alignItems: .start,
                                          children: children.flatMap { $0 })
        
        let insets = UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15)
        
        let insetSpec = ASInsetLayoutSpec(insets: insets,
                                          child: stackSpec)
        return insetSpec
    }
}

@poonamdhomane
Copy link

@dodikk can you share how to use this VHMessageContentNode in example app provided in this lib.

@dodikk
Copy link
Author

dodikk commented Oct 23, 2017

@dodikk can you share how to use this VHMessageContentNode in example app provided in this lib.

@iOSUser110 , you should take the steps below :

  1. Create a node
  2. Pass it to func NMessenger. addMessages() https://github.com/eBay/NMessenger/blob/master/nMessenger/Source/Messenger/Components/NMessenger.swift#L172
// create an instance
//
let contentNode = VHMessageContentNode()

// setup the fields
//
contentNode.textNode = ...;
contentNode.timestampNode = ...;

// create a message node with the content node 
//
let messageNode = VHMessageNode(content: contentNode)

// put the node to NMessenger instance
//
nmessengerView. addMessages([messageNode], scrollsToMessage: false)

@dodikk
Copy link
Author

dodikk commented Oct 23, 2017

@iOSUser110 , actually, the steps are the same as for the built-in ImageContentNode. However, the NMessengerViewController wraps them into the func sendText() and func sendImage() convenience methods.

@dodikk
Copy link
Author

dodikk commented Oct 23, 2017

@iOSUser110 , please keep in mind that VHMessageContentNode is not a part of NMessenger framework yet (as my PullRequest has not been merged yet).

So, unfortunately, you'll have to copy-paste this code to your app codebase.

P.S. Not sure if the class will ever make it to the codebase as not all users might need a timestamp. So I left the example code snippet in this ticket.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants