Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Query for label on tap in RepoIssuesVC #2414

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

BrianLitwin
Copy link
Member

@BrianLitwin BrianLitwin commented Nov 10, 2018

Connected to #2263

Summary:

In RepositoryIssuesViewController, when a user taps a label, the label is appended to the searchBar text and the query is fetched.

Test Notes:

Manually:

  • tapping on a label adds the appropriate query to the search bar and fetches the appropriate result.
  • tapping on a label that is already contained in the query doesn't append duplicate labels
  • tapping a point beside the last label in the LabelListView is passed through and an IssuesVC is pushed. Ie, the LabelListView doesn't eat touches inside it's frame where there are no label cells.

How:

There's a lot of chaining delegates involved. Reviewers: it will help to look at this view hierarchy:

  • RepositoryIssuesViewController ( BaseListViewController )
    • SearchBarSectionController ( ListSwiftSectionController )
      • SearchBarCell ( UICollectionViewCell )
    • RepositorySummarySectionController ( ListSwiftSectionController )
      • RepositorySummaryCell ( SelectableCell )
        • LabelListView ( UICollectionView )

The label is inside the LabelListView. It tells RepositorySummaryCell, which tells RepositorySummarySectionController, which tells RepositoryIssuesViewController that it has been tapped.
Then:
The RepoIssueViewController then tells SearchBarSectionController to tell SearchBarCell to set the searchBar text appropriately. Then the fetch proceeds as it currently would, as though the user entered the text in the searchBar. My hope is that this preserves a "one-way data flow".

@BrianLitwin
Copy link
Member Author

BrianLitwin commented Nov 10, 2018

Manual Test Screen Vid

It's kinda hard to see but this tests the items in Test Notes above:


ezgif com-video-to-gif 4

@BrianLitwin
Copy link
Member Author

BrianLitwin commented Nov 10, 2018

@jdisho Thanks for your review! I'm not 100% sure why this is, but I don't see the pattern of conforming to protocols in extensions used elsewhere in the app. I'm just trying to stay consistent with the rest of the codebase; I don't have any strong opinion on the issue. See IssuesViewController for an example of conforming to a lot of delegates inside the class.

@rnystrom
Copy link
Member

rnystrom commented Nov 10, 2018

+1 on not using extension unless necessary. I hit compiler errors early on in GitHawk's development from over-using them and lost a ton of time debugging + refactoring.

placeholder: Constants.Strings.search,
delegate: self,
query: previousSearchString
)
self?.setSearchBarTextSectionControllerDelegate = sectionController
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit of a backwards pattern. Delegates should be communicating "back up" instead of sending info down.

Instead, can we just get the search VC from the adapter and set its text?

func didTap(label: String) {
  // probably move "header" to an actual property in the VC
  guard let controller = feed.swiftAdapter.sectionController(for: "header") as SearchBarSectionController
    else { return }
  controller.append(query: " label:\(label)")
}

Much more straightforward

func append(query: String) {
searchBar.text?.append(query)
guard let text = searchBar.text else { return }
delegate?.didChangeSearchText(cell: self, query: text)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not triggered when setting the text in the bar?

Copy link
Member Author

@BrianLitwin BrianLitwin Nov 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the delegate method is not triggered here on it's own. The text in the search bar changes but no fetch/update happens.

@@ -35,6 +40,7 @@ final class SearchBarSectionController: ListSwiftSectionController<String>, Sear
guard let `self` = self else { return }
cell.delegate = self
cell.configure(query: self.query, placeholder: self.placeholder)
self.setSearchBarTextDelegate = cell
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should follow the same pattern of fetching the SC explicitly and instead of backwards-wiring the delegate to the cell, just find the cell and set the text in the SC:

func append(query: String) {
  guard let cell = collectionContext?.cellForItemAt(index: 0) as? SearchBarCell { else return }
  cell.searchBar.text = query
}

guard let lastCell = collectionView.cellForItem(at: [0, labels.count - 1])
else { return self }
return point.x > lastCell.frame.maxX ? self : super.hitTest(point, with: event)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eep, mucking w/ hitTest makes me so nervous. Why is this necessary?

Also simply checking for x > maxX looks too limited, should there be some point-in-rect math?

Copy link
Member Author

@BrianLitwin BrianLitwin Nov 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

screenshot 2018-11-11 11 57 13

I highlighted the LabelListView frame in orange. The UicollectionView's frame is set to its bounds.

Without the HitTest override, if you click inside the orange border on an area that's not a LabelCell, nothing happens. In the HitTest override, I'm trying to process taps that land on a label cell, and pass through taps that touchdown right of the right-most label cell.

Perhaps setting the CollectionView's frame is more appropriate, so that it's only as wide as it needs to be given the number of labels that it presents?

Copy link
Member Author

@BrianLitwin BrianLitwin Nov 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to send the taps to the right places:

// this is copied/pasted from existing methods to find width 
    static func labelTextTotalWidth(labels: [RepositoryLabel]) -> CGFloat {
        let interitemSpacing = labels.count > 1 ? CGFloat(labels.count - 1) * Styles.Sizes.labelSpacing : 0.0
        return labels.reduce(0, { $0 + LabelListCell.size($1.name).width }) + interitemSpacing
    }


override func layoutSubviews() {
        super.layoutSubviews()
        collectionView.frame = CGRect(
            x: bounds.minX,
            y: bounds.minY,
            width: min(LabelListView.labelTextTotalWidth(labels: labels), bounds.width)
            height: bounds.height
        )
}

@@ -14,11 +14,12 @@ protocol SearchBarSectionControllerDelegate: class {
}

final class SearchBarSectionController: ListSwiftSectionController<String>, SearchBarCellDelegate {


static let listSwiftId = "header"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay with this name?

searchBarCell?.configure(query: query, placeholder: placeholder)
self.query = query
delegate?.didChangeSelection(sectionController: self, query: query)
}
Copy link
Member Author

@BrianLitwin BrianLitwin Nov 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reason for keeping a reference to SearchBarCell and using it here:

let cell = collectionContext?.cellForItemAt(index: 0) as? SearchBarCell 

Above code was returning nil if the searchBar was scrolled out of view. Eg scroll down a little, tap a label, and the collectionContext.cellForItem method would return nil.

@BrianLitwin
Copy link
Member Author

BrianLitwin commented Nov 11, 2018

Wanted to add this screenshot with the updated method used to calculate the CollectionView's frame. See this comment above. Here, the CollectionView's border is Orange. Seems like it's working correctly:

screenshot 2018-11-11 15 27 58

@Huddie Huddie added the 😴 awaiting changes Changes requested, waiting on author to update label Dec 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
😴 awaiting changes Changes requested, waiting on author to update
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants