mirror of https://github.com/oxen-io/session-ios
Merge branch 'mkirk/search-profile-names'
commit
9ea954bec2
@ -1,16 +0,0 @@
|
||||
//
|
||||
// OWSContactsSearcher.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Michael Kirk on 6/27/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Contact.h"
|
||||
|
||||
@interface OWSContactsSearcher : NSObject
|
||||
|
||||
- (instancetype)initWithContacts:(NSArray<Contact *> *)contacts;
|
||||
- (NSArray<Contact *> *)filterWithString:(NSString *)string;
|
||||
|
||||
@end
|
@ -1,40 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSContactsSearcher.h"
|
||||
#import "NSString+OWS.h"
|
||||
#import <SignalServiceKit/PhoneNumber.h>
|
||||
|
||||
@interface OWSContactsSearcher ()
|
||||
|
||||
@property (copy) NSArray<Contact *> *contacts;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSContactsSearcher
|
||||
|
||||
- (instancetype)initWithContacts:(NSArray<Contact *> *)contacts {
|
||||
self = [super init];
|
||||
if (!self) return self;
|
||||
|
||||
_contacts = contacts;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray<Contact *> *)filterWithString:(NSString *)string {
|
||||
NSString *searchTerm = [string ows_stripped];
|
||||
|
||||
if ([searchTerm isEqualToString:@""]) {
|
||||
return self.contacts;
|
||||
}
|
||||
|
||||
NSString *formattedNumber = [PhoneNumber removeFormattingCharacters:searchTerm];
|
||||
|
||||
// TODO: This assumes there's a single search term.
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(fullName contains[c] %@) OR (ANY parsedPhoneNumbers.toE164 contains[c] %@)", searchTerm, formattedNumber];
|
||||
|
||||
return [self.contacts filteredArrayUsingPredicate:predicate];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SignalServiceKit
|
||||
|
||||
@objc
|
||||
class ConversationSearcher: NSObject {
|
||||
|
||||
@objc
|
||||
public static let shared: ConversationSearcher = ConversationSearcher()
|
||||
override private init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
@objc(filterThreads:withSearchText:)
|
||||
public func filterThreads(_ threads: [TSThread], searchText: String) -> [TSThread] {
|
||||
guard searchText.trimmingCharacters(in: .whitespacesAndNewlines).count > 0 else {
|
||||
return threads
|
||||
}
|
||||
|
||||
return threads.filter { thread in
|
||||
switch thread {
|
||||
case let groupThread as TSGroupThread:
|
||||
return self.groupThreadSearcher.matches(item: groupThread, query: searchText)
|
||||
case let contactThread as TSContactThread:
|
||||
return self.contactThreadSearcher.matches(item: contactThread, query: searchText)
|
||||
default:
|
||||
owsFail("Unexpected thread type: \(thread)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(filterGroupThreads:withSearchText:)
|
||||
public func filterGroupThreads(_ groupThreads: [TSGroupThread], searchText: String) -> [TSGroupThread] {
|
||||
guard searchText.trimmingCharacters(in: .whitespacesAndNewlines).count > 0 else {
|
||||
return groupThreads
|
||||
}
|
||||
|
||||
return groupThreads.filter { groupThread in
|
||||
return self.groupThreadSearcher.matches(item: groupThread, query: searchText)
|
||||
}
|
||||
}
|
||||
|
||||
@objc(filterSignalAccounts:withSearchText:)
|
||||
public func filterSignalAccounts(_ signalAccounts: [SignalAccount], searchText: String) -> [SignalAccount] {
|
||||
guard searchText.trimmingCharacters(in: .whitespacesAndNewlines).count > 0 else {
|
||||
return signalAccounts
|
||||
}
|
||||
|
||||
return signalAccounts.filter { signalAccount in
|
||||
self.signalAccountSearcher.matches(item: signalAccount, query: searchText)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
// MARK: Searchers
|
||||
private lazy var groupThreadSearcher: Searcher<TSGroupThread> = Searcher { (groupThread: TSGroupThread) in
|
||||
let groupName = groupThread.groupModel.groupName
|
||||
let memberStrings = groupThread.groupModel.groupMemberIds.map { recipientId in
|
||||
self.indexingString(recipientId: recipientId)
|
||||
}.joined(separator: " ")
|
||||
|
||||
return "\(memberStrings) \(groupName ?? "")"
|
||||
}
|
||||
|
||||
private lazy var contactThreadSearcher: Searcher<TSContactThread> = Searcher { (contactThread: TSContactThread) in
|
||||
let recipientId = contactThread.contactIdentifier()
|
||||
return self.indexingString(recipientId: recipientId)
|
||||
}
|
||||
|
||||
private lazy var signalAccountSearcher: Searcher<SignalAccount> = Searcher { (signalAccount: SignalAccount) in
|
||||
let recipientId = signalAccount.recipientId
|
||||
return self.indexingString(recipientId: recipientId)
|
||||
}
|
||||
|
||||
private var contactsManager: OWSContactsManager {
|
||||
return Environment.getCurrent().contactsManager
|
||||
}
|
||||
|
||||
private func indexingString(recipientId: String) -> String {
|
||||
let contactName = contactsManager.displayName(forPhoneIdentifier: recipientId)
|
||||
let profileName = contactsManager.profileName(forRecipientId: recipientId)
|
||||
|
||||
return "\(recipientId) \(contactName) \(profileName ?? "")"
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
// Copyright © 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import AVKit
|
||||
import WebRTC
|
||||
|
||||
/**
|
||||
* These tests are obtuse - they just assert the exact implementation of the methods. Normally I wouldn't include them,
|
||||
* but these methods make use of a header not included in the standard distribution of the WebRTC.framework. We've
|
||||
* included the header in our local project, and test the methods here to make sure that they are still available when
|
||||
* we upgrade the framework.
|
||||
*
|
||||
* If they are failing, it's possible the RTCAudioSession header, and our usage of it, need to be updated.
|
||||
*/
|
||||
class CallAudioSessionTest: XCTestCase {
|
||||
func testAudioSession() {
|
||||
|
||||
let rtcAudioSession = RTCAudioSession.sharedInstance()
|
||||
// Sanity Check
|
||||
XCTAssertFalse(rtcAudioSession.useManualAudio)
|
||||
|
||||
CallAudioSession().configure()
|
||||
XCTAssertTrue(rtcAudioSession.useManualAudio)
|
||||
XCTAssertFalse(rtcAudioSession.isAudioEnabled)
|
||||
|
||||
CallAudioSession().start()
|
||||
XCTAssertTrue(rtcAudioSession.useManualAudio)
|
||||
XCTAssertTrue(rtcAudioSession.isAudioEnabled)
|
||||
|
||||
CallAudioSession().stop()
|
||||
XCTAssertTrue(rtcAudioSession.useManualAudio)
|
||||
XCTAssertFalse(rtcAudioSession.isAudioEnabled)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue