mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge branch 'mkirk/search-profile-names'
This commit is contained in:
commit
9ea954bec2
|
@ -230,8 +230,6 @@
|
||||||
4574A5D61DD6704700C6B692 /* CallService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4574A5D51DD6704700C6B692 /* CallService.swift */; };
|
4574A5D61DD6704700C6B692 /* CallService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4574A5D51DD6704700C6B692 /* CallService.swift */; };
|
||||||
4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */; };
|
4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */ = {isa = PBXBuildFile; fileRef = 4579431D1E7C8CE9008ED0C0 /* Pastelog.m */; };
|
||||||
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45794E851E00620000066731 /* CallUIAdapter.swift */; };
|
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45794E851E00620000066731 /* CallUIAdapter.swift */; };
|
||||||
45843D1F1D2236B30013E85A /* OWSContactsSearcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */; };
|
|
||||||
45843D201D2236B30013E85A /* OWSContactsSearcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */; };
|
|
||||||
45847E871E4283C30080EAB3 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45847E861E4283C30080EAB3 /* Intents.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
45847E871E4283C30080EAB3 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45847E861E4283C30080EAB3 /* Intents.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */; };
|
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */; };
|
||||||
45855F381D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */; };
|
45855F381D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */; };
|
||||||
|
@ -257,6 +255,8 @@
|
||||||
45A6DAD71EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; };
|
45A6DAD71EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; };
|
||||||
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
|
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
|
||||||
45AE48521E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
|
45AE48521E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
|
||||||
|
45B72DDA1FD5E70600151AF6 /* ConversationSearcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B72DD91FD5E70600151AF6 /* ConversationSearcher.swift */; };
|
||||||
|
45B72DDB1FD5E70600151AF6 /* ConversationSearcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B72DD91FD5E70600151AF6 /* ConversationSearcher.swift */; };
|
||||||
45BB93381E688E14001E3939 /* UIDevice+featureSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */; };
|
45BB93381E688E14001E3939 /* UIDevice+featureSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */; };
|
||||||
45BB93391E688E14001E3939 /* UIDevice+featureSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */; };
|
45BB93391E688E14001E3939 /* UIDevice+featureSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */; };
|
||||||
45BD60821DE9547E00A8F436 /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BD60811DE9547E00A8F436 /* Contacts.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
45BD60821DE9547E00A8F436 /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BD60811DE9547E00A8F436 /* Contacts.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
|
@ -279,7 +279,6 @@
|
||||||
45E7A6A81E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */; };
|
45E7A6A81E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */; };
|
||||||
45F170AC1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */; };
|
45F170AC1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */; };
|
||||||
45F170AD1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */; };
|
45F170AD1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */; };
|
||||||
45F170AF1E2F0393003FC1F2 /* CallAudioSessionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170AE1E2F0393003FC1F2 /* CallAudioSessionTest.swift */; };
|
|
||||||
45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170BA1E2FC5D3003FC1F2 /* CallAudioService.swift */; };
|
45F170BB1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170BA1E2FC5D3003FC1F2 /* CallAudioService.swift */; };
|
||||||
45F170BC1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170BA1E2FC5D3003FC1F2 /* CallAudioService.swift */; };
|
45F170BC1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170BA1E2FC5D3003FC1F2 /* CallAudioService.swift */; };
|
||||||
45F170CC1E310E22003FC1F2 /* WeakTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170CB1E310E22003FC1F2 /* WeakTimer.swift */; };
|
45F170CC1E310E22003FC1F2 /* WeakTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45F170CB1E310E22003FC1F2 /* WeakTimer.swift */; };
|
||||||
|
@ -816,8 +815,6 @@
|
||||||
4579431C1E7C8CE9008ED0C0 /* Pastelog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pastelog.h; sourceTree = "<group>"; };
|
4579431C1E7C8CE9008ED0C0 /* Pastelog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pastelog.h; sourceTree = "<group>"; };
|
||||||
4579431D1E7C8CE9008ED0C0 /* Pastelog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pastelog.m; sourceTree = "<group>"; };
|
4579431D1E7C8CE9008ED0C0 /* Pastelog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pastelog.m; sourceTree = "<group>"; };
|
||||||
45794E851E00620000066731 /* CallUIAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CallUIAdapter.swift; path = UserInterface/CallUIAdapter.swift; sourceTree = "<group>"; };
|
45794E851E00620000066731 /* CallUIAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CallUIAdapter.swift; path = UserInterface/CallUIAdapter.swift; sourceTree = "<group>"; };
|
||||||
45843D1D1D2236B30013E85A /* OWSContactsSearcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactsSearcher.h; sourceTree = "<group>"; };
|
|
||||||
45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsSearcher.m; sourceTree = "<group>"; };
|
|
||||||
45847E861E4283C30080EAB3 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
|
45847E861E4283C30080EAB3 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
|
||||||
45855F351D9498A40084F340 /* OWSContactAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactAvatarBuilder.h; sourceTree = "<group>"; };
|
45855F351D9498A40084F340 /* OWSContactAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactAvatarBuilder.h; sourceTree = "<group>"; };
|
||||||
45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactAvatarBuilder.m; sourceTree = "<group>"; };
|
45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactAvatarBuilder.m; sourceTree = "<group>"; };
|
||||||
|
@ -849,6 +846,7 @@
|
||||||
45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = "<group>"; };
|
45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = "<group>"; };
|
||||||
45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = "<group>"; };
|
45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = "<group>"; };
|
||||||
45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; };
|
45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
|
45B72DD91FD5E70600151AF6 /* ConversationSearcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearcher.swift; sourceTree = "<group>"; };
|
||||||
45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIDevice+featureSupport.swift"; sourceTree = "<group>"; };
|
45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIDevice+featureSupport.swift"; sourceTree = "<group>"; };
|
||||||
45BD60811DE9547E00A8F436 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; };
|
45BD60811DE9547E00A8F436 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; };
|
||||||
45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+OWS.swift"; sourceTree = "<group>"; };
|
45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+OWS.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -866,7 +864,6 @@
|
||||||
45E615151E8C590B0018AD52 /* DisplayableText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableText.swift; sourceTree = "<group>"; };
|
45E615151E8C590B0018AD52 /* DisplayableText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableText.swift; sourceTree = "<group>"; };
|
||||||
45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableTextFilterTest.swift; sourceTree = "<group>"; };
|
45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableTextFilterTest.swift; sourceTree = "<group>"; };
|
||||||
45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallAudioSession.swift; sourceTree = "<group>"; };
|
45F170AB1E2F0351003FC1F2 /* CallAudioSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallAudioSession.swift; sourceTree = "<group>"; };
|
||||||
45F170AE1E2F0393003FC1F2 /* CallAudioSessionTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallAudioSessionTest.swift; sourceTree = "<group>"; };
|
|
||||||
45F170B31E2F0A6A003FC1F2 /* RTCAudioSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCAudioSession.h; sourceTree = "<group>"; };
|
45F170B31E2F0A6A003FC1F2 /* RTCAudioSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCAudioSession.h; sourceTree = "<group>"; };
|
||||||
45F170BA1E2FC5D3003FC1F2 /* CallAudioService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallAudioService.swift; sourceTree = "<group>"; };
|
45F170BA1E2FC5D3003FC1F2 /* CallAudioService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallAudioService.swift; sourceTree = "<group>"; };
|
||||||
45F170CB1E310E22003FC1F2 /* WeakTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakTimer.swift; sourceTree = "<group>"; };
|
45F170CB1E310E22003FC1F2 /* WeakTimer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakTimer.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1644,8 +1641,6 @@
|
||||||
children = (
|
children = (
|
||||||
76EB040818170B33006006FC /* OWSContactsManager.h */,
|
76EB040818170B33006006FC /* OWSContactsManager.h */,
|
||||||
76EB040918170B33006006FC /* OWSContactsManager.m */,
|
76EB040918170B33006006FC /* OWSContactsManager.m */,
|
||||||
45843D1D1D2236B30013E85A /* OWSContactsSearcher.h */,
|
|
||||||
45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */,
|
|
||||||
4542F0931EB9372700C7EE92 /* SystemContactsFetcher.swift */,
|
4542F0931EB9372700C7EE92 /* SystemContactsFetcher.swift */,
|
||||||
);
|
);
|
||||||
path = contact;
|
path = contact;
|
||||||
|
@ -1725,6 +1720,7 @@
|
||||||
76EB04FB18170B33006006FC /* Util.h */,
|
76EB04FB18170B33006006FC /* Util.h */,
|
||||||
45F170D51E315310003FC1F2 /* Weak.swift */,
|
45F170D51E315310003FC1F2 /* Weak.swift */,
|
||||||
45F170CB1E310E22003FC1F2 /* WeakTimer.swift */,
|
45F170CB1E310E22003FC1F2 /* WeakTimer.swift */,
|
||||||
|
45B72DD91FD5E70600151AF6 /* ConversationSearcher.swift */,
|
||||||
);
|
);
|
||||||
path = util;
|
path = util;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1837,7 +1833,6 @@
|
||||||
B660F6731C29867F00687D6E /* call */ = {
|
B660F6731C29867F00687D6E /* call */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
45F170AE1E2F0393003FC1F2 /* CallAudioSessionTest.swift */,
|
|
||||||
456F6E2E1E261D1000FD2210 /* PeerConnectionClientTest.swift */,
|
456F6E2E1E261D1000FD2210 /* PeerConnectionClientTest.swift */,
|
||||||
);
|
);
|
||||||
path = call;
|
path = call;
|
||||||
|
@ -2719,6 +2714,7 @@
|
||||||
450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */,
|
450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */,
|
||||||
34D1F0821F8678AA0066283D /* ConversationHeaderView.m in Sources */,
|
34D1F0821F8678AA0066283D /* ConversationHeaderView.m in Sources */,
|
||||||
340CB2241EAC155C0001CAA1 /* ContactsViewHelper.m in Sources */,
|
340CB2241EAC155C0001CAA1 /* ContactsViewHelper.m in Sources */,
|
||||||
|
45B72DDA1FD5E70600151AF6 /* ConversationSearcher.swift in Sources */,
|
||||||
34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */,
|
34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */,
|
||||||
34CE88EC1F3237260098030F /* OWSProfileManager.m in Sources */,
|
34CE88EC1F3237260098030F /* OWSProfileManager.m in Sources */,
|
||||||
4542F0941EB9372700C7EE92 /* SystemContactsFetcher.swift in Sources */,
|
4542F0941EB9372700C7EE92 /* SystemContactsFetcher.swift in Sources */,
|
||||||
|
@ -2773,7 +2769,6 @@
|
||||||
D221A09A169C9E5E00537ABF /* main.m in Sources */,
|
D221A09A169C9E5E00537ABF /* main.m in Sources */,
|
||||||
345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */,
|
345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */,
|
||||||
4585C4601ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m in Sources */,
|
4585C4601ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m in Sources */,
|
||||||
45843D1F1D2236B30013E85A /* OWSContactsSearcher.m in Sources */,
|
|
||||||
B6258B331C29E2E60014138E /* NotificationsManager.m in Sources */,
|
B6258B331C29E2E60014138E /* NotificationsManager.m in Sources */,
|
||||||
34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */,
|
34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */,
|
||||||
34533F181EA8D2070006114F /* OWSAudioAttachmentPlayer.m in Sources */,
|
34533F181EA8D2070006114F /* OWSAudioAttachmentPlayer.m in Sources */,
|
||||||
|
@ -2928,11 +2923,9 @@
|
||||||
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */,
|
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */,
|
||||||
452D1EE81DCA90D100A57EC4 /* MesssagesBubblesSizeCalculatorTest.swift in Sources */,
|
452D1EE81DCA90D100A57EC4 /* MesssagesBubblesSizeCalculatorTest.swift in Sources */,
|
||||||
451DE9FE1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */,
|
451DE9FE1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */,
|
||||||
45F170AF1E2F0393003FC1F2 /* CallAudioSessionTest.swift in Sources */,
|
|
||||||
456F6E231E24133500FD2210 /* Platform.swift in Sources */,
|
456F6E231E24133500FD2210 /* Platform.swift in Sources */,
|
||||||
4539B5871F79348F007141FF /* PushRegistrationManager.swift in Sources */,
|
4539B5871F79348F007141FF /* PushRegistrationManager.swift in Sources */,
|
||||||
4504493A1F45EE7D002D1ADA /* NSString+OWS.m in Sources */,
|
4504493A1F45EE7D002D1ADA /* NSString+OWS.m in Sources */,
|
||||||
45843D201D2236B30013E85A /* OWSContactsSearcher.m in Sources */,
|
|
||||||
45AE48521E0732D6004D96C2 /* TurnServerInfo.swift in Sources */,
|
45AE48521E0732D6004D96C2 /* TurnServerInfo.swift in Sources */,
|
||||||
45360B901F9527DA00FA666C /* SearcherTest.swift in Sources */,
|
45360B901F9527DA00FA666C /* SearcherTest.swift in Sources */,
|
||||||
B660F7561C29988E00687D6E /* PushManager.m in Sources */,
|
B660F7561C29988E00687D6E /* PushManager.m in Sources */,
|
||||||
|
@ -2978,6 +2971,7 @@
|
||||||
45A6DAD71EBBF85500893231 /* ReminderView.swift in Sources */,
|
45A6DAD71EBBF85500893231 /* ReminderView.swift in Sources */,
|
||||||
B660F6D21C29868000687D6E /* PushManagerTest.m in Sources */,
|
B660F6D21C29868000687D6E /* PushManagerTest.m in Sources */,
|
||||||
45C0DC1F1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */,
|
45C0DC1F1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */,
|
||||||
|
45B72DDB1FD5E70600151AF6 /* ConversationSearcher.swift in Sources */,
|
||||||
4505C2C01E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
|
4505C2C01E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
|
||||||
455AC69E1F4F8B0300134004 /* ImageCacheTest.swift in Sources */,
|
455AC69E1F4F8B0300134004 /* ImageCacheTest.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "ContactsViewHelper.h"
|
#import "ContactsViewHelper.h"
|
||||||
#import "ContactTableViewCell.h"
|
|
||||||
#import "Environment.h"
|
#import "Environment.h"
|
||||||
#import "NSString+OWS.h"
|
#import "NSString+OWS.h"
|
||||||
#import "OWSProfileManager.h"
|
#import "OWSProfileManager.h"
|
||||||
|
@ -31,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
@property (nonatomic) BOOL shouldNotifyDelegateOfUpdatedContacts;
|
@property (nonatomic) BOOL shouldNotifyDelegateOfUpdatedContacts;
|
||||||
@property (nonatomic) BOOL hasUpdatedContactsAtLeastOnce;
|
@property (nonatomic) BOOL hasUpdatedContactsAtLeastOnce;
|
||||||
@property (nonatomic) OWSProfileManager *profileManager;
|
@property (nonatomic) OWSProfileManager *profileManager;
|
||||||
|
@property (nonatomic, readonly) ConversationSearcher *conversationSearcher;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
_blockingManager = [OWSBlockingManager sharedManager];
|
_blockingManager = [OWSBlockingManager sharedManager];
|
||||||
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
|
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
|
||||||
|
_conversationSearcher = ConversationSearcher.shared;
|
||||||
|
|
||||||
_contactsManager = [Environment getCurrent].contactsManager;
|
_contactsManager = [Environment getCurrent].contactsManager;
|
||||||
_profileManager = [OWSProfileManager sharedManager];
|
_profileManager = [OWSProfileManager sharedManager];
|
||||||
|
@ -173,37 +174,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)doesSignalAccount:(SignalAccount *)signalAccount matchSearchTerm:(NSString *)searchTerm
|
|
||||||
{
|
|
||||||
OWSAssert(signalAccount);
|
|
||||||
OWSAssert(searchTerm.length > 0);
|
|
||||||
|
|
||||||
if ([signalAccount.contact.fullName.lowercaseString containsString:searchTerm.lowercaseString]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString *asPhoneNumber = [PhoneNumber removeFormattingCharacters:searchTerm];
|
|
||||||
if (asPhoneNumber.length > 0 && [signalAccount.recipientId containsString:asPhoneNumber]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)doesSignalAccount:(SignalAccount *)signalAccount matchSearchTerms:(NSArray<NSString *> *)searchTerms
|
|
||||||
{
|
|
||||||
OWSAssert(signalAccount);
|
|
||||||
OWSAssert(searchTerms.count > 0);
|
|
||||||
|
|
||||||
for (NSString *searchTerm in searchTerms) {
|
|
||||||
if (![self doesSignalAccount:signalAccount matchSearchTerm:searchTerm]) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray<NSString *> *)searchTermsForSearchString:(NSString *)searchText
|
- (NSArray<NSString *> *)searchTermsForSearchString:(NSString *)searchText
|
||||||
{
|
{
|
||||||
return [[[searchText ows_stripped]
|
return [[[searchText ows_stripped]
|
||||||
|
@ -216,17 +186,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (NSArray<SignalAccount *> *)signalAccountsMatchingSearchString:(NSString *)searchText
|
- (NSArray<SignalAccount *> *)signalAccountsMatchingSearchString:(NSString *)searchText
|
||||||
{
|
{
|
||||||
NSArray<NSString *> *searchTerms = [self searchTermsForSearchString:searchText];
|
return [self.conversationSearcher filterSignalAccounts:self.signalAccounts withSearchText:searchText];
|
||||||
|
|
||||||
if (searchTerms.count < 1) {
|
|
||||||
return self.signalAccounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [self.signalAccounts
|
|
||||||
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SignalAccount *signalAccount,
|
|
||||||
NSDictionary<NSString *, id> *_Nullable bindings) {
|
|
||||||
return [self doesSignalAccount:signalAccount matchSearchTerms:searchTerms];
|
|
||||||
}]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)doesContact:(Contact *)contact matchSearchTerm:(NSString *)searchTerm
|
- (BOOL)doesContact:(Contact *)contact matchSearchTerm:(NSString *)searchTerm
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#import "Environment.h"
|
#import "Environment.h"
|
||||||
#import "NewGroupViewController.h"
|
#import "NewGroupViewController.h"
|
||||||
#import "NewNonContactConversationViewController.h"
|
#import "NewNonContactConversationViewController.h"
|
||||||
#import "OWSContactsSearcher.h"
|
|
||||||
#import "OWSTableViewController.h"
|
#import "OWSTableViewController.h"
|
||||||
#import "Signal-Swift.h"
|
#import "Signal-Swift.h"
|
||||||
#import "UIColor+OWS.h"
|
#import "UIColor+OWS.h"
|
||||||
|
@ -45,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
MFMessageComposeViewControllerDelegate>
|
MFMessageComposeViewControllerDelegate>
|
||||||
|
|
||||||
@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
|
@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
|
||||||
|
@property (nonatomic, readonly) ConversationSearcher *conversationSearcher;
|
||||||
|
|
||||||
@property (nonatomic, readonly) UIView *noSignalContactsView;
|
@property (nonatomic, readonly) UIView *noSignalContactsView;
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
self.view.backgroundColor = UIColor.whiteColor;
|
self.view.backgroundColor = UIColor.whiteColor;
|
||||||
_contactsViewHelper = [[ContactsViewHelper alloc] initWithDelegate:self];
|
_contactsViewHelper = [[ContactsViewHelper alloc] initWithDelegate:self];
|
||||||
|
_conversationSearcher = [ConversationSearcher shared];
|
||||||
_nonContactAccountSet = [NSMutableSet set];
|
_nonContactAccountSet = [NSMutableSet set];
|
||||||
_collation = [UILocalizedIndexedCollation currentCollation];
|
_collation = [UILocalizedIndexedCollation currentCollation];
|
||||||
|
|
||||||
|
@ -630,35 +631,17 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (NSArray<TSGroupThread *> *)filteredGroupThreads
|
- (NSArray<TSGroupThread *> *)filteredGroupThreads
|
||||||
{
|
{
|
||||||
AnySearcher *searcher = [[AnySearcher alloc] initWithIndexer:^NSString * _Nonnull(id _Nonnull obj) {
|
NSMutableArray<TSGroupThread *> *groupThreads = [NSMutableArray new];
|
||||||
if (![obj isKindOfClass:[TSGroupThread class]]) {
|
|
||||||
OWSFail(@"unexpected item in searcher");
|
|
||||||
return @"";
|
|
||||||
}
|
|
||||||
TSGroupThread *groupThread = (TSGroupThread *)obj;
|
|
||||||
NSString *groupName = groupThread.groupModel.groupName;
|
|
||||||
NSMutableString *groupMemberNames = [NSMutableString new];
|
|
||||||
for (NSString *recipientId in groupThread.groupModel.groupMemberIds) {
|
|
||||||
NSString *contactName = [self.contactsViewHelper.contactsManager displayNameForPhoneIdentifier:recipientId];
|
|
||||||
[groupMemberNames appendFormat:@" %@", contactName];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [NSString stringWithFormat:@"%@ %@", groupName, groupMemberNames];
|
|
||||||
}];
|
|
||||||
|
|
||||||
NSMutableArray<TSGroupThread *> *matchingThreads = [NSMutableArray new];
|
|
||||||
[TSGroupThread enumerateCollectionObjectsUsingBlock:^(id obj, BOOL *stop) {
|
[TSGroupThread enumerateCollectionObjectsUsingBlock:^(id obj, BOOL *stop) {
|
||||||
if (![obj isKindOfClass:[TSGroupThread class]]) {
|
if (![obj isKindOfClass:[TSGroupThread class]]) {
|
||||||
// group and contact threads are in the same collection.
|
// group and contact threads are in the same collection.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TSGroupThread *groupThread = (TSGroupThread *)obj;
|
TSGroupThread *groupThread = (TSGroupThread *)obj;
|
||||||
if ([searcher item:groupThread doesMatchQuery:self.searchBar.text]) {
|
[groupThreads addObject:groupThread];
|
||||||
[matchingThreads addObject:groupThread];
|
|
||||||
}
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return [matchingThreads copy];
|
return [self.conversationSearcher filterGroupThreads:groupThreads withSearchText:self.searchBar.text];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - No Contacts Mode
|
#pragma mark - No Contacts Mode
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#import "Environment.h"
|
#import "Environment.h"
|
||||||
#import "NSString+OWS.h"
|
#import "NSString+OWS.h"
|
||||||
#import "OWSContactsManager.h"
|
#import "OWSContactsManager.h"
|
||||||
#import "OWSContactsSearcher.h"
|
|
||||||
#import "OWSTableViewController.h"
|
#import "OWSTableViewController.h"
|
||||||
|
#import "Signal-Swift.h"
|
||||||
#import "ThreadViewHelper.h"
|
#import "ThreadViewHelper.h"
|
||||||
#import "UIColor+OWS.h"
|
#import "UIColor+OWS.h"
|
||||||
#import "UIFont+OWS.h"
|
#import "UIFont+OWS.h"
|
||||||
|
@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
UISearchBarDelegate>
|
UISearchBarDelegate>
|
||||||
|
|
||||||
@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
|
@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
|
||||||
|
@property (nonatomic, readonly) ConversationSearcher *conversationSearcher;
|
||||||
@property (nonatomic, readonly) ThreadViewHelper *threadViewHelper;
|
@property (nonatomic, readonly) ThreadViewHelper *threadViewHelper;
|
||||||
|
|
||||||
@property (nonatomic, readonly) OWSTableViewController *tableViewController;
|
@property (nonatomic, readonly) OWSTableViewController *tableViewController;
|
||||||
|
@ -54,6 +54,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
self.view.backgroundColor = [UIColor whiteColor];
|
self.view.backgroundColor = [UIColor whiteColor];
|
||||||
|
|
||||||
_contactsViewHelper = [[ContactsViewHelper alloc] initWithDelegate:self];
|
_contactsViewHelper = [[ContactsViewHelper alloc] initWithDelegate:self];
|
||||||
|
_conversationSearcher = ConversationSearcher.shared;
|
||||||
_threadViewHelper = [ThreadViewHelper new];
|
_threadViewHelper = [ThreadViewHelper new];
|
||||||
_threadViewHelper.delegate = self;
|
_threadViewHelper.delegate = self;
|
||||||
|
|
||||||
|
@ -131,11 +132,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
__weak SelectThreadViewController *weakSelf = self;
|
__weak SelectThreadViewController *weakSelf = self;
|
||||||
ContactsViewHelper *helper = self.contactsViewHelper;
|
ContactsViewHelper *helper = self.contactsViewHelper;
|
||||||
OWSTableContents *contents = [OWSTableContents new];
|
OWSTableContents *contents = [OWSTableContents new];
|
||||||
OWSTableSection *section = [OWSTableSection new];
|
|
||||||
|
|
||||||
// Threads
|
// Existing threads are listed first, ordered by most recently active
|
||||||
|
OWSTableSection *recentChatsSection = [OWSTableSection new];
|
||||||
|
recentChatsSection.headerTitle = NSLocalizedString(
|
||||||
|
@"SELECT_THREAD_TABLE_RECENT_CHATS_TITLE", @"Table section header for recently active conversations");
|
||||||
for (TSThread *thread in [self filteredThreadsWithSearchText]) {
|
for (TSThread *thread in [self filteredThreadsWithSearchText]) {
|
||||||
[section addItem:[OWSTableItem itemWithCustomCellBlock:^{
|
[recentChatsSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
|
||||||
SelectThreadViewController *strongSelf = weakSelf;
|
SelectThreadViewController *strongSelf = weakSelf;
|
||||||
OWSCAssert(strongSelf);
|
OWSCAssert(strongSelf);
|
||||||
|
|
||||||
|
@ -145,16 +148,23 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[cell configureWithThread:thread contactsManager:helper.contactsManager];
|
[cell configureWithThread:thread contactsManager:helper.contactsManager];
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
customRowHeight:[ContactTableViewCell rowHeight]
|
customRowHeight:[ContactTableViewCell rowHeight]
|
||||||
actionBlock:^{
|
actionBlock:^{
|
||||||
[weakSelf.delegate threadWasSelected:thread];
|
[weakSelf.delegate threadWasSelected:thread];
|
||||||
}]];
|
}]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contacts
|
if (recentChatsSection.itemCount > 0) {
|
||||||
|
[contents addSection:recentChatsSection];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contacts who don't yet have a thread are listed last
|
||||||
|
OWSTableSection *otherContactsSection = [OWSTableSection new];
|
||||||
|
otherContactsSection.headerTitle = NSLocalizedString(
|
||||||
|
@"SELECT_THREAD_TABLE_OTHER_CHATS_TITLE", @"Table section header for conversations you haven't recently used.");
|
||||||
NSArray<SignalAccount *> *filteredSignalAccounts = [self filteredSignalAccountsWithSearchText];
|
NSArray<SignalAccount *> *filteredSignalAccounts = [self filteredSignalAccountsWithSearchText];
|
||||||
for (SignalAccount *signalAccount in filteredSignalAccounts) {
|
for (SignalAccount *signalAccount in filteredSignalAccounts) {
|
||||||
[section addItem:[OWSTableItem itemWithCustomCellBlock:^{
|
[otherContactsSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
|
||||||
SelectThreadViewController *strongSelf = weakSelf;
|
SelectThreadViewController *strongSelf = weakSelf;
|
||||||
OWSCAssert(strongSelf);
|
OWSCAssert(strongSelf);
|
||||||
|
|
||||||
|
@ -169,19 +179,24 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
|
[cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
customRowHeight:[ContactTableViewCell rowHeight]
|
customRowHeight:[ContactTableViewCell rowHeight]
|
||||||
actionBlock:^{
|
actionBlock:^{
|
||||||
[weakSelf signalAccountWasSelected:signalAccount];
|
[weakSelf signalAccountWasSelected:signalAccount];
|
||||||
}]];
|
}]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section.itemCount < 1) {
|
if (otherContactsSection.itemCount > 0) {
|
||||||
[section
|
[contents addSection:otherContactsSection];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recentChatsSection.itemCount + otherContactsSection.itemCount < 1) {
|
||||||
|
OWSTableSection *emptySection = [OWSTableSection new];
|
||||||
|
[emptySection
|
||||||
addItem:[OWSTableItem
|
addItem:[OWSTableItem
|
||||||
softCenterLabelItemWithText:NSLocalizedString(@"SETTINGS_BLOCK_LIST_NO_CONTACTS",
|
softCenterLabelItemWithText:NSLocalizedString(@"SETTINGS_BLOCK_LIST_NO_CONTACTS",
|
||||||
@"A label that indicates the user has no Signal contacts.")]];
|
@"A label that indicates the user has no Signal contacts.")]];
|
||||||
|
[contents addSection:emptySection];
|
||||||
}
|
}
|
||||||
[contents addSection:section];
|
|
||||||
|
|
||||||
self.tableViewController.contents = contents;
|
self.tableViewController.contents = contents;
|
||||||
}
|
}
|
||||||
|
@ -222,28 +237,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (NSArray<TSThread *> *)filteredThreadsWithSearchText
|
- (NSArray<TSThread *> *)filteredThreadsWithSearchText
|
||||||
{
|
{
|
||||||
NSArray<TSThread *> *threads = self.threadViewHelper.threads;
|
|
||||||
|
|
||||||
NSString *searchTerm = [[self.searchBar text] ows_stripped];
|
NSString *searchTerm = [[self.searchBar text] ows_stripped];
|
||||||
|
|
||||||
if ([searchTerm isEqualToString:@""]) {
|
return [self.conversationSearcher filterThreads:self.threadViewHelper.threads withSearchText:searchTerm];
|
||||||
return threads;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString *formattedNumber = [PhoneNumber removeFormattingCharacters:searchTerm];
|
|
||||||
|
|
||||||
NSMutableArray *result = [NSMutableArray new];
|
|
||||||
for (TSThread *thread in threads) {
|
|
||||||
if ([thread.name containsString:searchTerm]) {
|
|
||||||
[result addObject:thread];
|
|
||||||
} else if ([thread isKindOfClass:[TSContactThread class]]) {
|
|
||||||
TSContactThread *contactThread = (TSContactThread *)thread;
|
|
||||||
if (formattedNumber.length > 0 && [contactThread.contactIdentifier containsString:formattedNumber]) {
|
|
||||||
[result addObject:thread];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray<SignalAccount *> *)filteredSignalAccountsWithSearchText
|
- (NSArray<SignalAccount *> *)filteredSignalAccountsWithSearchText
|
||||||
|
@ -259,10 +255,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *searchString = [self.searchBar text];
|
NSString *searchString = self.searchBar.text;
|
||||||
|
NSArray<SignalAccount *> *matchingAccounts =
|
||||||
|
[self.contactsViewHelper signalAccountsMatchingSearchString:searchString];
|
||||||
|
|
||||||
ContactsViewHelper *helper = self.contactsViewHelper;
|
return [matchingAccounts
|
||||||
return [[helper signalAccountsMatchingSearchString:searchString]
|
|
||||||
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SignalAccount *signalAccount,
|
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SignalAccount *signalAccount,
|
||||||
NSDictionary<NSString *, id> *_Nullable bindings) {
|
NSDictionary<NSString *, id> *_Nullable bindings) {
|
||||||
return ![contactIdsToIgnore containsObject:signalAccount.recipientId];
|
return ![contactIdsToIgnore containsObject:signalAccount.recipientId];
|
||||||
|
|
|
@ -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
|
|
90
Signal/src/util/ConversationSearcher.swift
Normal file
90
Signal/src/util/ConversationSearcher.swift
Normal file
|
@ -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 ?? "")"
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import Foundation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A generic searching class, configurable with an indexing block
|
||||||
class Searcher<T> {
|
class Searcher<T> {
|
||||||
|
|
||||||
private let indexer: (T) -> String
|
private let indexer: (T) -> String
|
||||||
|
@ -36,7 +37,16 @@ class Searcher<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func stem(string: String) -> [String] {
|
private func stem(string: String) -> [String] {
|
||||||
return normalize(string: string).components(separatedBy: .whitespaces)
|
var normalized = normalize(string: string)
|
||||||
|
|
||||||
|
// Remove any phone number formatting from the search terms
|
||||||
|
let nonformattingScalars = normalized.unicodeScalars.lazy.filter {
|
||||||
|
!CharacterSet.punctuationCharacters.contains($0)
|
||||||
|
}
|
||||||
|
|
||||||
|
normalized = String(String.UnicodeScalarView(nonformattingScalars))
|
||||||
|
|
||||||
|
return normalized.components(separatedBy: .whitespacesAndNewlines)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func normalize(string: String) -> String {
|
private func normalize(string: String) -> String {
|
||||||
|
|
|
@ -170,6 +170,8 @@ const CGFloat kContactTableViewCellAvatarTextMargin = 12;
|
||||||
self.nameLabel.attributedText = attributedText;
|
self.nameLabel.attributedText = attributedText;
|
||||||
|
|
||||||
if ([thread isKindOfClass:[TSContactThread class]]) {
|
if ([thread isKindOfClass:[TSContactThread class]]) {
|
||||||
|
self.recipientId = thread.contactIdentifier;
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
selector:@selector(otherUsersProfileDidChange:)
|
selector:@selector(otherUsersProfileDidChange:)
|
||||||
name:kNSNotificationName_OtherUsersProfileDidChange
|
name:kNSNotificationName_OtherUsersProfileDidChange
|
||||||
|
@ -220,6 +222,7 @@ const CGFloat kContactTableViewCellAvatarTextMargin = 12;
|
||||||
diameter:kContactTableViewCellAvatarSize
|
diameter:kContactTableViewCellAvatarSize
|
||||||
contactsManager:contactsManager] build];
|
contactsManager:contactsManager] build];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateProfileName
|
- (void)updateProfileName
|
||||||
{
|
{
|
||||||
OWSContactsManager *contactsManager = self.contactsManager;
|
OWSContactsManager *contactsManager = self.contactsManager;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
import SignalServiceKit
|
||||||
|
|
||||||
struct VerificationFailedError: Error { }
|
struct VerificationFailedError: Error { }
|
||||||
struct FailedToGetRPRegistrationTokenError: Error { }
|
struct FailedToGetRPRegistrationTokenError: Error { }
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
|
import SignalServiceKit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a brittle test, which will break if our layout changes.
|
* This is a brittle test, which will break if our layout changes.
|
||||||
|
@ -23,7 +24,12 @@ class MesssagesBubblesSizeCalculatorTest: XCTestCase {
|
||||||
func viewItemForText(_ text: String?) -> ConversationViewItem {
|
func viewItemForText(_ text: String?) -> ConversationViewItem {
|
||||||
let interaction = TSOutgoingMessage(timestamp: 0, in: thread, messageBody: text)
|
let interaction = TSOutgoingMessage(timestamp: 0, in: thread, messageBody: text)
|
||||||
interaction.save()
|
interaction.save()
|
||||||
let viewItem = ConversationViewItem(tsInteraction:interaction, isGroupThread:false)
|
|
||||||
|
var viewItem: ConversationViewItem!
|
||||||
|
interaction.dbReadWriteConnection().readWrite { transaction in
|
||||||
|
viewItem = ConversationViewItem(interaction: interaction, isGroupThread: false, transaction: transaction)
|
||||||
|
}
|
||||||
|
|
||||||
viewItem.shouldShowDate = false
|
viewItem.shouldShowDate = false
|
||||||
viewItem.shouldHideRecipientStatus = true
|
viewItem.shouldHideRecipientStatus = true
|
||||||
return viewItem
|
return viewItem
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#import <SignalServiceKit/TSAttachmentStream.h>
|
#import <SignalServiceKit/TSAttachmentStream.h>
|
||||||
#import <SignalServiceKit/TSOutgoingMessage.h>
|
#import <SignalServiceKit/TSOutgoingMessage.h>
|
||||||
#import <XCTest/XCTest.h>
|
#import <XCTest/XCTest.h>
|
||||||
|
#import <YapDatabase/YapDatabaseConnection.h>
|
||||||
|
|
||||||
@interface ConversationViewItem (Testing)
|
@interface ConversationViewItem (Testing)
|
||||||
|
|
||||||
|
@ -64,8 +65,10 @@
|
||||||
|
|
||||||
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
|
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
|
||||||
|
|
||||||
TSAttachmentStream *attachment = [[TSAttachmentStream alloc] initWithContentType:mimeType sourceFilename:nil];
|
|
||||||
DataSource *dataSource = [DataSourcePath dataSourceWithFilePath:filePath];
|
DataSource *dataSource = [DataSourcePath dataSourceWithFilePath:filePath];
|
||||||
|
TSAttachmentStream *attachment = [[TSAttachmentStream alloc] initWithContentType:mimeType
|
||||||
|
byteCount:(UInt32)dataSource.dataLength
|
||||||
|
sourceFilename:nil];
|
||||||
BOOL success = [attachment writeDataSource:dataSource];
|
BOOL success = [attachment writeDataSource:dataSource];
|
||||||
OWSAssert(success);
|
OWSAssert(success);
|
||||||
[attachment save];
|
[attachment save];
|
||||||
|
@ -75,7 +78,12 @@
|
||||||
TSOutgoingMessage *message =
|
TSOutgoingMessage *message =
|
||||||
[[TSOutgoingMessage alloc] initWithTimestamp:1 inThread:nil messageBody:nil attachmentIds:attachmentIds];
|
[[TSOutgoingMessage alloc] initWithTimestamp:1 inThread:nil messageBody:nil attachmentIds:attachmentIds];
|
||||||
[message save];
|
[message save];
|
||||||
ConversationViewItem *viewItem = [[ConversationViewItem alloc] initWithInteraction:message isGroupThread:NO];
|
|
||||||
|
__block ConversationViewItem *viewItem = nil;
|
||||||
|
[TSYapDatabaseObject.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||||
|
viewItem = [[ConversationViewItem alloc] initWithInteraction:message isGroupThread:NO transaction:transaction];
|
||||||
|
}];
|
||||||
|
|
||||||
return viewItem;
|
return viewItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,14 +9,15 @@ class SearcherTest: XCTestCase {
|
||||||
struct TestCharacter {
|
struct TestCharacter {
|
||||||
let name: String
|
let name: String
|
||||||
let description: String
|
let description: String
|
||||||
|
let phoneNumber: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
let smerdyakov = TestCharacter(name: "Pavel Fyodorovich Smerdyakov", description: "A rusty hue in the sky")
|
let smerdyakov = TestCharacter(name: "Pavel Fyodorovich Smerdyakov", description: "A rusty hue in the sky", phoneNumber: nil)
|
||||||
let stinkingLizaveta = TestCharacter(name: "Stinking Lizaveta", description: "object of pity")
|
let stinkingLizaveta = TestCharacter(name: "Stinking Lizaveta", description: "object of pity", phoneNumber: "+13235555555")
|
||||||
let regularLizaveta = TestCharacter(name: "Lizaveta", description: "")
|
let regularLizaveta = TestCharacter(name: "Lizaveta", description: "", phoneNumber: "1 (415) 555-5555")
|
||||||
|
|
||||||
let indexer = { (character: TestCharacter) in
|
let indexer = { (character: TestCharacter) in
|
||||||
return "\(character.name) \(character.description)"
|
return "\(character.name) \(character.description) \(character.phoneNumber ?? "")"
|
||||||
}
|
}
|
||||||
|
|
||||||
var searcher: Searcher<TestCharacter> {
|
var searcher: Searcher<TestCharacter> {
|
||||||
|
@ -57,4 +58,20 @@ class SearcherTest: XCTestCase {
|
||||||
XCTAssert(searcher.matches(item: stinkingLizaveta, query: "Lizaveta St"))
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query: "Lizaveta St"))
|
||||||
XCTAssert(searcher.matches(item: stinkingLizaveta, query: " Lizaveta St "))
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query: " Lizaveta St "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testFormattingChars() {
|
||||||
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query:"323"))
|
||||||
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query:"1-323-555-5555"))
|
||||||
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query:"13235555555"))
|
||||||
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query:"+1-323"))
|
||||||
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query:"Liza +1-323"))
|
||||||
|
|
||||||
|
// Sanity check, match both by names
|
||||||
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query:"Liza"))
|
||||||
|
XCTAssert(searcher.matches(item: regularLizaveta, query:"Liza"))
|
||||||
|
|
||||||
|
// Disambiguate the two Liza's by area code
|
||||||
|
XCTAssert(searcher.matches(item: stinkingLizaveta, query:"Liza 323"))
|
||||||
|
XCTAssertFalse(searcher.matches(item: regularLizaveta, query:"Liza 323"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1342,6 +1342,12 @@
|
||||||
/* Label for 'select gif to attach' action sheet button */
|
/* Label for 'select gif to attach' action sheet button */
|
||||||
"SELECT_GIF_BUTTON" = "GIF";
|
"SELECT_GIF_BUTTON" = "GIF";
|
||||||
|
|
||||||
|
/* Table section header for conversations you haven't recently used. */
|
||||||
|
"SELECT_THREAD_TABLE_OTHER_CHATS_TITLE" = "Other Contacts";
|
||||||
|
|
||||||
|
/* Table section header for recently active conversations */
|
||||||
|
"SELECT_THREAD_TABLE_RECENT_CHATS_TITLE" = "Recent Chats";
|
||||||
|
|
||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"SEND_AGAIN_BUTTON" = "Send Again";
|
"SEND_AGAIN_BUTTON" = "Send Again";
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
// This should be redundant with the logic above.
|
// This should be redundant with the logic above.
|
||||||
[logPathSet addObjectsFromArray:self.fileLogger.logFileManager.unsortedLogFilePaths];
|
[logPathSet addObjectsFromArray:self.fileLogger.logFileManager.unsortedLogFilePaths];
|
||||||
NSArray<NSString *> *logPaths = logPathSet.allObjects;
|
NSArray<NSString *> *logPaths = logPathSet.allObjects;
|
||||||
return [logPaths sortedArrayUsingSelector:@selector(compare:)];
|
return [logPaths sortedArrayUsingSelector:@selector((compare:))];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)wipeLogs
|
- (void)wipeLogs
|
||||||
|
|
|
@ -320,8 +320,6 @@ NSString *const kSyncMessageFileExtension = @"bin";
|
||||||
// Store the file in a subdirectory whose name is the uniqueId of this attachment,
|
// Store the file in a subdirectory whose name is the uniqueId of this attachment,
|
||||||
// to avoid collisions between multiple attachments with the same name.
|
// to avoid collisions between multiple attachments with the same name.
|
||||||
NSString *attachmentFolderPath = [folder stringByAppendingPathComponent:uniqueId];
|
NSString *attachmentFolderPath = [folder stringByAppendingPathComponent:uniqueId];
|
||||||
NSError *error = nil;
|
|
||||||
BOOL attachmentFolderPathExists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentFolderPath];
|
|
||||||
if (![OWSFileSystem ensureDirectoryExists:attachmentFolderPath]) {
|
if (![OWSFileSystem ensureDirectoryExists:attachmentFolderPath]) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue