Merge branch 'mkirk/fts-no-results'
This commit is contained in:
commit
741bc9d1ae
@ -19,9 +19,10 @@ class ConversationSearchViewController: UITableViewController {
|
||||
}
|
||||
|
||||
enum SearchSection: Int {
|
||||
case conversations = 0
|
||||
case contacts = 1
|
||||
case messages = 2
|
||||
case noResults
|
||||
case conversations
|
||||
case contacts
|
||||
case messages
|
||||
}
|
||||
|
||||
// MARK: View Lifecyle
|
||||
@ -32,6 +33,7 @@ class ConversationSearchViewController: UITableViewController {
|
||||
tableView.rowHeight = UITableViewAutomaticDimension
|
||||
tableView.estimatedRowHeight = 60
|
||||
|
||||
tableView.register(EmptySearchResultCell.self, forCellReuseIdentifier: EmptySearchResultCell.reuseIdentifier)
|
||||
tableView.register(ConversationSearchResultCell.self, forCellReuseIdentifier: ConversationSearchResultCell.reuseIdentifier)
|
||||
tableView.register(MessageSearchResultCell.self, forCellReuseIdentifier: MessageSearchResultCell.reuseIdentifier)
|
||||
tableView.register(ContactSearchResultCell.self, forCellReuseIdentifier: ContactSearchResultCell.reuseIdentifier)
|
||||
@ -41,39 +43,41 @@ class ConversationSearchViewController: UITableViewController {
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.deselectRow(at: indexPath, animated: false)
|
||||
|
||||
|
||||
guard let searchSection = SearchSection(rawValue: indexPath.section) else {
|
||||
owsFail("\(logTag) unknown section selected.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
switch searchSection {
|
||||
case .noResults:
|
||||
owsFail("\(logTag) shouldn't be able to tap 'no results' section")
|
||||
case .conversations:
|
||||
let sectionResults = searchResultSet.conversations
|
||||
guard let searchResult = sectionResults[safe: indexPath.row] else {
|
||||
owsFail("\(logTag) unknown row selected.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let thread = searchResult.thread
|
||||
SignalApp.shared().presentConversation(for: thread.threadRecord, action: .compose)
|
||||
|
||||
|
||||
case .contacts:
|
||||
let sectionResults = searchResultSet.contacts
|
||||
guard let searchResult = sectionResults[safe: indexPath.row] else {
|
||||
owsFail("\(logTag) unknown row selected.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
SignalApp.shared().presentConversation(forRecipientId: searchResult.recipientId, action: .compose)
|
||||
|
||||
|
||||
case .messages:
|
||||
let sectionResults = searchResultSet.messages
|
||||
guard let searchResult = sectionResults[safe: indexPath.row] else {
|
||||
owsFail("\(logTag) unknown row selected.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let thread = searchResult.thread
|
||||
SignalApp.shared().presentConversation(for: thread.threadRecord, action: .compose)
|
||||
}
|
||||
@ -88,6 +92,8 @@ class ConversationSearchViewController: UITableViewController {
|
||||
}
|
||||
|
||||
switch searchSection {
|
||||
case .noResults:
|
||||
return searchResultSet.isEmpty ? 1 : 0
|
||||
case .conversations:
|
||||
return searchResultSet.conversations.count
|
||||
case .contacts:
|
||||
@ -104,22 +110,40 @@ class ConversationSearchViewController: UITableViewController {
|
||||
}
|
||||
|
||||
switch searchSection {
|
||||
case .noResults:
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: EmptySearchResultCell.reuseIdentifier) as? EmptySearchResultCell else {
|
||||
owsFail("cell was unexpectedly nil")
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
guard indexPath.row == 0 else {
|
||||
owsFail("searchResult was unexpected index")
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
let searchText = self.searchResultSet.searchText
|
||||
cell.configure(searchText: searchText)
|
||||
return cell
|
||||
case .conversations:
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: ConversationSearchResultCell.reuseIdentifier) as? ConversationSearchResultCell else {
|
||||
owsFail("cell was unexpectedly nil")
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
guard let searchResult = self.searchResultSet.conversations[safe: indexPath.row] else {
|
||||
owsFail("searchResult was unexpectedly nil")
|
||||
return UITableViewCell()
|
||||
}
|
||||
cell.configure(searchResult: searchResult)
|
||||
return cell
|
||||
case .contacts:
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: ContactSearchResultCell.reuseIdentifier) as? ContactSearchResultCell else {
|
||||
owsFail("cell was unexpectedly nil")
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
guard let searchResult = self.searchResultSet.contacts[safe: indexPath.row] else {
|
||||
owsFail("searchResult was unexpectedly nil")
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
@ -127,10 +151,12 @@ class ConversationSearchViewController: UITableViewController {
|
||||
return cell
|
||||
case .messages:
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: MessageSearchResultCell.reuseIdentifier) as? MessageSearchResultCell else {
|
||||
owsFail("cell was unexpectedly nil")
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
guard let searchResult = self.searchResultSet.messages[safe: indexPath.row] else {
|
||||
owsFail("searchResult was unexpectedly nil")
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
@ -140,7 +166,7 @@ class ConversationSearchViewController: UITableViewController {
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 3
|
||||
return 4
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
@ -150,6 +176,8 @@ class ConversationSearchViewController: UITableViewController {
|
||||
}
|
||||
|
||||
switch searchSection {
|
||||
case .noResults:
|
||||
return nil
|
||||
case .conversations:
|
||||
if searchResultSet.conversations.count > 0 {
|
||||
return NSLocalizedString("SEARCH_SECTION_CONVERSATIONS", comment: "section header for search results that match existing conversations (either group or contact conversations)")
|
||||
@ -339,3 +367,42 @@ class ContactSearchResultCell: UITableViewCell {
|
||||
self.snippetLabel.text = searchResult.recipientId
|
||||
}
|
||||
}
|
||||
|
||||
class EmptySearchResultCell: UITableViewCell {
|
||||
static let reuseIdentifier = "EmptySearchResultCell"
|
||||
|
||||
let messageLabel: UILabel
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
self.messageLabel = UILabel()
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
messageLabel.font = UIFont.ows_dynamicTypeBody
|
||||
messageLabel.textAlignment = .center
|
||||
messageLabel.numberOfLines = 3
|
||||
|
||||
contentView.addSubview(messageLabel)
|
||||
|
||||
messageLabel.autoSetDimension(.height, toSize: 150)
|
||||
|
||||
messageLabel.autoPinEdge(toSuperviewMargin: .top, relation: .greaterThanOrEqual)
|
||||
messageLabel.autoPinEdge(toSuperviewMargin: .leading, relation: .greaterThanOrEqual)
|
||||
messageLabel.autoPinEdge(toSuperviewMargin: .bottom, relation: .greaterThanOrEqual)
|
||||
messageLabel.autoPinEdge(toSuperviewMargin: .trailing, relation: .greaterThanOrEqual)
|
||||
|
||||
messageLabel.autoVCenterInSuperview()
|
||||
messageLabel.autoHCenterInSuperview()
|
||||
|
||||
messageLabel.setContentHuggingHigh()
|
||||
messageLabel.setCompressionResistanceHigh()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func configure(searchText: String) {
|
||||
let format = NSLocalizedString("HOME_VIEW_SEARCH_NO_RESULTS_FORMAT", comment: "Format string when search returns no results. Embeds {{search term}}")
|
||||
let messageText: String = NSString(format: format as NSString, searchText) as String
|
||||
self.messageLabel.text = messageText
|
||||
}
|
||||
}
|
||||
|
||||
@ -989,6 +989,9 @@
|
||||
/* Placeholder text for search bar which filters conversations. */
|
||||
"HOME_VIEW_CONVERSATION_SEARCHBAR_PLACEHOLDER" = "Search";
|
||||
|
||||
/* Format string when search returns no results. Embeds {{search term}} */
|
||||
"HOME_VIEW_SEARCH_NO_RESULTS_FORMAT" = "No results found for '%@'";
|
||||
|
||||
/* Title for the home view's 'archive' mode. */
|
||||
"HOME_VIEW_TITLE_ARCHIVE" = "Archive";
|
||||
|
||||
|
||||
@ -27,18 +27,24 @@ public class ContactSearchResult {
|
||||
}
|
||||
|
||||
public class SearchResultSet {
|
||||
public let searchText: String
|
||||
public let conversations: [ConversationSearchResult]
|
||||
public let contacts: [ContactSearchResult]
|
||||
public let messages: [ConversationSearchResult]
|
||||
|
||||
public init(conversations: [ConversationSearchResult], contacts: [ContactSearchResult], messages: [ConversationSearchResult]) {
|
||||
public init(searchText: String, conversations: [ConversationSearchResult], contacts: [ContactSearchResult], messages: [ConversationSearchResult]) {
|
||||
self.searchText = searchText
|
||||
self.conversations = conversations
|
||||
self.contacts = contacts
|
||||
self.messages = messages
|
||||
}
|
||||
|
||||
public class var empty: SearchResultSet {
|
||||
return SearchResultSet(conversations: [], contacts: [], messages: [])
|
||||
return SearchResultSet(searchText: "", conversations: [], contacts: [], messages: [])
|
||||
}
|
||||
|
||||
public var isEmpty: Bool {
|
||||
return conversations.isEmpty && contacts.isEmpty && messages.isEmpty
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +96,7 @@ public class ConversationSearcher: NSObject {
|
||||
// Only show contacts which were not included in an existing 1:1 conversation.
|
||||
let otherContacts: [ContactSearchResult] = contacts.filter { !existingConversationRecipientIds.contains($0.recipientId) }
|
||||
|
||||
return SearchResultSet(conversations: conversations, contacts: otherContacts, messages: messages)
|
||||
return SearchResultSet(searchText: searchText, conversations: conversations, contacts: otherContacts, messages: messages)
|
||||
}
|
||||
|
||||
@objc(filterThreads:withSearchText:)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user