diff --git a/Podfile b/Podfile index 09108e238..1f1778fec 100644 --- a/Podfile +++ b/Podfile @@ -22,9 +22,6 @@ def shared_pods # third party pods pod 'AFNetworking', inhibit_warnings: true - pod 'JSQMessagesViewController', git: 'https://github.com/signalapp/JSQMessagesViewController.git', branch: 'mkirk/share-compatible', :inhibit_warnings => true - #pod 'JSQMessagesViewController', git: 'https://github.com/signalapp/JSQMessagesViewController.git', branch: 'signal-master', :inhibit_warnings => true - #pod 'JSQMessagesViewController', path: '../JSQMessagesViewController' pod 'Mantle', :inhibit_warnings => true # pod 'YapDatabase/SQLCipher', :inhibit_warnings => true pod 'PureLayout', :inhibit_warnings => true diff --git a/Podfile.lock b/Podfile.lock index 2cce25b58..e4840b241 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -29,9 +29,6 @@ PODS: - Curve25519Kit (2.1.0) - GRKOpenSSLFramework (1.0.2.12) - HKDFKit (0.0.4) - - JSQMessagesViewController (7.3.4): - - JSQSystemSoundPlayer (~> 2.0.1) - - JSQSystemSoundPlayer (2.0.1) - libPhoneNumber-iOS (0.9.13) - Mantle (2.1.0): - Mantle/extobjc (= 2.1.0) @@ -141,7 +138,6 @@ DEPENDENCIES: - Curve25519Kit (from `https://github.com/signalapp/Curve25519Kit`, branch `mkirk/framework-friendly`) - GRKOpenSSLFramework (from `https://github.com/signalapp/GRKOpenSSLFramework`) - HKDFKit (from `https://github.com/signalapp/HKDFKit.git`, branch `mkirk/framework-friendly`) - - JSQMessagesViewController (from `https://github.com/signalapp/JSQMessagesViewController.git`, branch `mkirk/share-compatible`) - Mantle - PureLayout - Reachability @@ -157,7 +153,6 @@ SPEC REPOS: - AFNetworking - ATAppUpdater - CocoaLumberjack - - JSQSystemSoundPlayer - libPhoneNumber-iOS - Mantle - PromiseKit @@ -179,9 +174,6 @@ EXTERNAL SOURCES: HKDFKit: :branch: mkirk/framework-friendly :git: https://github.com/signalapp/HKDFKit.git - JSQMessagesViewController: - :branch: mkirk/share-compatible - :git: https://github.com/signalapp/JSQMessagesViewController.git SignalServiceKit: :path: "." SocketRocket: @@ -206,9 +198,6 @@ CHECKOUT OPTIONS: HKDFKit: :commit: d2e2e50990e88537d6c4e38cc32a6f6debd83446 :git: https://github.com/signalapp/HKDFKit.git - JSQMessagesViewController: - :commit: 33dd72b7bac85fc54a87fb8016c9a927af222153 - :git: https://github.com/signalapp/JSQMessagesViewController.git SocketRocket: :commit: 28035e1a98a427853e4038ff1b70479fa8374cfa :git: https://github.com/facebook/SocketRocket.git @@ -227,8 +216,6 @@ SPEC CHECKSUMS: Curve25519Kit: 76d0859ecb34704f7732847812363f83b23a6a59 GRKOpenSSLFramework: 8a3735ad41e7dc1daff460467bccd32ca5d6ae3e HKDFKit: 3fb424060aaf69795bc8ab34c4c233b98dc6303b - JSQMessagesViewController: 39fed975e3c9f8eba7292071e29eeb541d105e66 - JSQSystemSoundPlayer: c5850e77a4363ffd374cd851154b9af93264ed8d libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b PromiseKit: 743e497a5f505a470d3bbbf4ce0663c1268af0a4 @@ -243,6 +230,6 @@ SPEC CHECKSUMS: YapDatabase: 299a32de9d350d37a9ac5b0532609d87d5d2a5de YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 -PODFILE CHECKSUM: 66640e0d5c06e9fb855faf7f6a8a3e9915eb5b78 +PODFILE CHECKSUM: db797890d3df475827063ba956cb42afa148ff19 COCOAPODS: 1.5.3 diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 54e2f694e..d27f2bc02 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -42,6 +42,17 @@ 340FC8CD20518C77007AEB0F /* OWSBackupJob.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8CC20518C76007AEB0F /* OWSBackupJob.m */; }; 340FC8D0205BF2FA007AEB0F /* OWSBackupIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC8CE205BF2FA007AEB0F /* OWSBackupIO.m */; }; 341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; }; + 34219801210612F600C57195 /* iRate.m in Sources */ = {isa = PBXBuildFile; fileRef = 342197FF210612F600C57195 /* iRate.m */; }; + 3421980F21061A0700C57195 /* UIColor+JSQMessages.m in Sources */ = {isa = PBXBuildFile; fileRef = 3421980521061A0600C57195 /* UIColor+JSQMessages.m */; }; + 3421981021061A0700C57195 /* JSQMessagesAvatarImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 3421980621061A0600C57195 /* JSQMessagesAvatarImage.m */; }; + 3421981121061A0700C57195 /* JSQMessagesAvatarImageFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 3421980721061A0600C57195 /* JSQMessagesAvatarImageFactory.h */; }; + 3421981221061A0700C57195 /* JSQMVC-LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 3421980821061A0600C57195 /* JSQMVC-LICENSE */; }; + 3421981321061A0700C57195 /* JSQMessagesAvatarImageFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 3421980921061A0700C57195 /* JSQMessagesAvatarImageFactory.m */; }; + 3421981421061A0700C57195 /* JSQMessagesAvatarImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 3421980A21061A0700C57195 /* JSQMessagesAvatarImage.h */; }; + 3421981521061A0700C57195 /* UIColor+JSQMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 3421980B21061A0700C57195 /* UIColor+JSQMessages.h */; }; + 3421981621061A0700C57195 /* JSQMVC-README.md in Resources */ = {isa = PBXBuildFile; fileRef = 3421980C21061A0700C57195 /* JSQMVC-README.md */; }; + 3421981721061A0700C57195 /* JSQMVC-SIGNAL.md in Resources */ = {isa = PBXBuildFile; fileRef = 3421980D21061A0700C57195 /* JSQMVC-SIGNAL.md */; }; + 3421981821061A0700C57195 /* JSQMessageAvatarImageDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3421980E21061A0700C57195 /* JSQMessageAvatarImageDataSource.h */; }; 34277A5E20751BDC006049F2 /* OWSQuotedMessageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34277A5C20751BDC006049F2 /* OWSQuotedMessageView.m */; }; 3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3427C64220F500DF00EEC730 /* OWSMessageTimerView.m */; }; 3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3430FE171F7751D4000EC51B /* GiphyAPI.swift */; }; @@ -454,7 +465,6 @@ B10C9B601A7049EC00ECA2BF /* pause_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10C9B5C1A7049EC00ECA2BF /* pause_icon@2x.png */; }; B10C9B611A7049EC00ECA2BF /* play_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B10C9B5D1A7049EC00ECA2BF /* play_icon.png */; }; B10C9B621A7049EC00ECA2BF /* play_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B10C9B5E1A7049EC00ECA2BF /* play_icon@2x.png */; }; - B609597C1C2C0FC6004E8797 /* iRate.m in Sources */ = {isa = PBXBuildFile; fileRef = B609597B1C2C0FC6004E8797 /* iRate.m */; }; B60EDE041A05A01700D73516 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B60EDE031A05A01700D73516 /* AudioToolbox.framework */; }; B633C5861A1D190B0059AC12 /* call@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5041A1D190B0059AC12 /* call@2x.png */; }; B633C58D1A1D190B0059AC12 /* contact_default_feed.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C50B1A1D190B0059AC12 /* contact_default_feed.png */; }; @@ -647,6 +657,18 @@ 341458471FBE11C4005ABCF9 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = ""; }; 341F2C0D1F2B8AE700D07D6B /* DebugUIMisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMisc.h; sourceTree = ""; }; 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMisc.m; sourceTree = ""; }; + 342197FF210612F600C57195 /* iRate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iRate.m; sourceTree = ""; }; + 34219800210612F600C57195 /* iRate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iRate.h; sourceTree = ""; }; + 3421980521061A0600C57195 /* UIColor+JSQMessages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+JSQMessages.m"; sourceTree = ""; }; + 3421980621061A0600C57195 /* JSQMessagesAvatarImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSQMessagesAvatarImage.m; sourceTree = ""; }; + 3421980721061A0600C57195 /* JSQMessagesAvatarImageFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQMessagesAvatarImageFactory.h; sourceTree = ""; }; + 3421980821061A0600C57195 /* JSQMVC-LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "JSQMVC-LICENSE"; sourceTree = ""; }; + 3421980921061A0700C57195 /* JSQMessagesAvatarImageFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSQMessagesAvatarImageFactory.m; sourceTree = ""; }; + 3421980A21061A0700C57195 /* JSQMessagesAvatarImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQMessagesAvatarImage.h; sourceTree = ""; }; + 3421980B21061A0700C57195 /* UIColor+JSQMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+JSQMessages.h"; sourceTree = ""; }; + 3421980C21061A0700C57195 /* JSQMVC-README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "JSQMVC-README.md"; sourceTree = ""; }; + 3421980D21061A0700C57195 /* JSQMVC-SIGNAL.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "JSQMVC-SIGNAL.md"; sourceTree = ""; }; + 3421980E21061A0700C57195 /* JSQMessageAvatarImageDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQMessageAvatarImageDataSource.h; sourceTree = ""; }; 34277A5C20751BDC006049F2 /* OWSQuotedMessageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSQuotedMessageView.m; sourceTree = ""; }; 34277A5D20751BDC006049F2 /* OWSQuotedMessageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSQuotedMessageView.h; sourceTree = ""; }; 3427C64120F500DE00EEC730 /* OWSMessageTimerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageTimerView.h; sourceTree = ""; }; @@ -1074,7 +1096,6 @@ 45E5A6981F61E6DD001E4A8A /* MarqueeLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarqueeLabel.swift; sourceTree = ""; }; 45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableTextFilterTest.swift; sourceTree = ""; }; 45F170AB1E2F0351003FC1F2 /* OWSAudioSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAudioSession.swift; sourceTree = ""; }; - 45F170B31E2F0A6A003FC1F2 /* RTCAudioSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCAudioSession.h; sourceTree = ""; }; 45F170BA1E2FC5D3003FC1F2 /* CallAudioService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallAudioService.swift; sourceTree = ""; }; 45F170D51E315310003FC1F2 /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = ""; }; 45F32C1D205718B000A300D5 /* MediaPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MediaPageViewController.swift; path = Signal/src/ViewControllers/MediaPageViewController.swift; sourceTree = SOURCE_ROOT; }; @@ -1129,8 +1150,6 @@ B10C9B5D1A7049EC00ECA2BF /* play_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = play_icon.png; sourceTree = ""; }; B10C9B5E1A7049EC00ECA2BF /* play_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "play_icon@2x.png"; sourceTree = ""; }; B60341CD1AA5469800A01E42 /* ja_JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja_JP; path = translations/ja_JP.lproj/Localizable.strings; sourceTree = ""; }; - B609597A1C2C0FC6004E8797 /* iRate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iRate.h; path = Libraries/iRate/iRate.h; sourceTree = SOURCE_ROOT; }; - B609597B1C2C0FC6004E8797 /* iRate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iRate.m; path = Libraries/iRate/iRate.m; sourceTree = SOURCE_ROOT; }; B60EDE031A05A01700D73516 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; B633C5041A1D190B0059AC12 /* call@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call@2x.png"; sourceTree = ""; }; B633C50B1A1D190B0059AC12 /* contact_default_feed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contact_default_feed.png; sourceTree = ""; }; @@ -1419,6 +1438,49 @@ path = ThreadSettings; sourceTree = ""; }; + 342197FE210612F600C57195 /* iRate */ = { + isa = PBXGroup; + children = ( + 342197FF210612F600C57195 /* iRate.m */, + 34219800210612F600C57195 /* iRate.h */, + ); + name = iRate; + path = Signal/Libraries/iRate; + sourceTree = SOURCE_ROOT; + }; + 34219802210619C800C57195 /* Libraries */ = { + isa = PBXGroup; + children = ( + 342197FE210612F600C57195 /* iRate */, + ); + path = Libraries; + sourceTree = ""; + }; + 34219803210619D300C57195 /* Libraries */ = { + isa = PBXGroup; + children = ( + 3421980421061A0600C57195 /* JSQMessagesViewController */, + ); + path = Libraries; + sourceTree = ""; + }; + 3421980421061A0600C57195 /* JSQMessagesViewController */ = { + isa = PBXGroup; + children = ( + 3421980521061A0600C57195 /* UIColor+JSQMessages.m */, + 3421980621061A0600C57195 /* JSQMessagesAvatarImage.m */, + 3421980721061A0600C57195 /* JSQMessagesAvatarImageFactory.h */, + 3421980821061A0600C57195 /* JSQMVC-LICENSE */, + 3421980921061A0700C57195 /* JSQMessagesAvatarImageFactory.m */, + 3421980A21061A0700C57195 /* JSQMessagesAvatarImage.h */, + 3421980B21061A0700C57195 /* UIColor+JSQMessages.h */, + 3421980C21061A0700C57195 /* JSQMVC-README.md */, + 3421980D21061A0700C57195 /* JSQMVC-SIGNAL.md */, + 3421980E21061A0700C57195 /* JSQMessageAvatarImageDataSource.h */, + ); + path = JSQMessagesViewController; + sourceTree = ""; + }; 34330A581E7875FB00DF2FB9 /* Fonts */ = { isa = PBXGroup; children = ( @@ -1925,19 +1987,20 @@ 453518931FC63DBF00210559 /* SignalMessaging */ = { isa = PBXGroup; children = ( - 4541B71C209D3B4F0008608F /* ViewModels */, - 45194F911FD7214600333B2C /* Models */, - 451F8A361FD7115D005CB9DA /* ViewControllers */, 454A96571FD600B4008D2A0E /* attachments */, 34480B5C1FD0A98800BC14EF /* categories */, 346129A11FD1F09100532771 /* contacts */, 3461293F1FD1D74B00532771 /* environment */, 453518951FC63DBF00210559 /* Info.plist */, + 34219803210619D300C57195 /* Libraries */, + 45194F911FD7214600333B2C /* Models */, 346129B01FD1F7E800532771 /* profiles */, 34480B5A1FD0A7E300BC14EF /* SignalMessaging-Prefix.pch */, 453518941FC63DBF00210559 /* SignalMessaging.h */, 34480B471FD0A60200BC14EF /* utils */, 346129DB1FD5C02900532771 /* viewControllers */, + 451F8A361FD7115D005CB9DA /* ViewControllers */, + 4541B71C209D3B4F0008608F /* ViewModels */, 346129CE1FD207F200532771 /* views */, ); path = SignalMessaging; @@ -2034,24 +2097,6 @@ path = Jobs; sourceTree = ""; }; - 45F170B01E2F0A35003FC1F2 /* Libraries */ = { - isa = PBXGroup; - children = ( - 45F170B11E2F0A6A003FC1F2 /* WebRTC */, - ); - name = Libraries; - path = Signal; - sourceTree = ""; - }; - 45F170B11E2F0A6A003FC1F2 /* WebRTC */ = { - isa = PBXGroup; - children = ( - 45F170B31E2F0A6A003FC1F2 /* RTCAudioSession.h */, - ); - name = WebRTC; - path = Libraries/WebRTC; - sourceTree = SOURCE_ROOT; - }; 45FBC57A1DF8575700E9B410 /* CallKit */ = { isa = PBXGroup; children = ( @@ -2072,7 +2117,6 @@ 45D231751DC7E8C50034FA89 /* Jobs */, 457F3AC01D14A0F700C51351 /* Models */, 76EB041D18170B33006006FC /* network */, - B60959791C2C0FA9004E8797 /* rating */, 45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */, 45CD81A41DBFF8CF004C9430 /* Storyboards */, 450DF2061E0DD28D003D14BE /* UserInterface */, @@ -2206,15 +2250,6 @@ name = Pods; sourceTree = ""; }; - B60959791C2C0FA9004E8797 /* rating */ = { - isa = PBXGroup; - children = ( - B609597A1C2C0FC6004E8797 /* iRate.h */, - B609597B1C2C0FC6004E8797 /* iRate.m */, - ); - name = rating; - sourceTree = ""; - }; B633C4FD1A1D190B0059AC12 /* Images */ = { isa = PBXGroup; children = ( @@ -2329,7 +2364,6 @@ isa = PBXGroup; children = ( D221A093169C9E5E00537ABF /* Signal */, - 45F170B01E2F0A35003FC1F2 /* Libraries */, 453518691FC635DD00210559 /* SignalShareExtension */, 453518931FC63DBF00210559 /* SignalMessaging */, D221A08C169C9E5E00537ABF /* Frameworks */, @@ -2397,6 +2431,7 @@ 34330A581E7875FB00DF2FB9 /* Fonts */, B633C4FD1A1D190B0059AC12 /* Images */, B66DBF4919D5BBC8006EA940 /* Images.xcassets */, + 34219802210619C800C57195 /* Libraries */, B67EBF5C19194AC60084CCFD /* Settings.bundle */, B657DDC91911A40500F45B0C /* Signal.entitlements */, 34074F54203D0722004596AE /* Sounds */, @@ -2456,6 +2491,7 @@ 344F248420069E9C00CFB4F4 /* CountryCodeViewController.h in Headers */, 4503F1C4204711D300CEE724 /* OWS107LegacySounds.h in Headers */, 346129711FD1D74C00532771 /* SignalKeyingStorage.h in Headers */, + 3421981121061A0700C57195 /* JSQMessagesAvatarImageFactory.h in Headers */, 34C82E5120F8E1F300E9688D /* Theme.h in Headers */, 34612A011FD5F31400532771 /* OWS104CreateRecipientIdentities.h in Headers */, 450998691FD8C10200D89EB3 /* AttachmentSharing.h in Headers */, @@ -2463,6 +2499,7 @@ 451F8A3C1FD71392005CB9DA /* UIUtil.h in Headers */, 346129D61FD20ADC00532771 /* UIViewController+OWS.h in Headers */, 451F8A401FD7145D005CB9DA /* OWSTableViewController.h in Headers */, + 3421981421061A0700C57195 /* JSQMessagesAvatarImage.h in Headers */, 3461296F1FD1D74C00532771 /* Release.h in Headers */, 34612A061FD7238600532771 /* OWSContactsSyncing.h in Headers */, 34480B571FD0A7A400BC14EF /* OWSScrubbingLogFormatter.h in Headers */, @@ -2471,7 +2508,9 @@ 346129951FD1E30000532771 /* OWSDatabaseMigration.h in Headers */, 45194F961FD7226300333B2C /* SelectThreadViewController.h in Headers */, 34B6D27420F664C900765BE2 /* OWSUnreadIndicator.h in Headers */, + 3421981821061A0700C57195 /* JSQMessageAvatarImageDataSource.h in Headers */, 346129B41FD1F7E800532771 /* OWSProfileManager.h in Headers */, + 3421981521061A0700C57195 /* UIColor+JSQMessages.h in Headers */, 34D2015120DC160E00A6FD3A /* ContactCellView.h in Headers */, 346129FA1FD5F31400532771 /* OWS100RemoveTSRecipientsMigration.h in Headers */, 346129E21FD5C0BE00532771 /* VersionMigrations.h in Headers */, @@ -2757,6 +2796,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3421981621061A0700C57195 /* JSQMVC-README.md in Resources */, + 3421981721061A0700C57195 /* JSQMVC-SIGNAL.md in Resources */, + 3421981221061A0700C57195 /* JSQMVC-LICENSE in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2943,8 +2985,6 @@ "${BUILT_PRODUCTS_DIR}/Curve25519Kit/Curve25519Kit.framework", "${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework", "${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework", - "${BUILT_PRODUCTS_DIR}/JSQMessagesViewController/JSQMessagesViewController.framework", - "${BUILT_PRODUCTS_DIR}/JSQSystemSoundPlayer/JSQSystemSoundPlayer.framework", "${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework", "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework", "${BUILT_PRODUCTS_DIR}/ProtocolBuffers/ProtocolBuffers.framework", @@ -2968,8 +3008,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519Kit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQMessagesViewController.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQSystemSoundPlayer.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ProtocolBuffers.framework", @@ -3020,8 +3058,6 @@ "${BUILT_PRODUCTS_DIR}/Curve25519Kit/Curve25519Kit.framework", "${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework", "${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework", - "${BUILT_PRODUCTS_DIR}/JSQMessagesViewController/JSQMessagesViewController.framework", - "${BUILT_PRODUCTS_DIR}/JSQSystemSoundPlayer/JSQSystemSoundPlayer.framework", "${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework", "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework", "${BUILT_PRODUCTS_DIR}/ProtocolBuffers/ProtocolBuffers.framework", @@ -3043,8 +3079,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519Kit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQMessagesViewController.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQSystemSoundPlayer.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ProtocolBuffers.framework", @@ -3106,6 +3140,7 @@ 45BE4EA22012AD2000935E59 /* DisappearingTimerConfigurationView.swift in Sources */, 346129F71FD5F31400532771 /* OWS105AttachmentFilePaths.m in Sources */, 45194F931FD7215C00333B2C /* OWSContactOffersInteraction.m in Sources */, + 3421980F21061A0700C57195 /* UIColor+JSQMessages.m in Sources */, 4523D016206EDC2B00A2AB51 /* LRUCache.swift in Sources */, 344F249A200FD03300CFB4F4 /* MessageApprovalViewController.swift in Sources */, 450998681FD8C0FF00D89EB3 /* AttachmentSharing.m in Sources */, @@ -3114,6 +3149,7 @@ 34074F61203D0CBE004596AE /* OWSSounds.m in Sources */, 346129B51FD1F7E800532771 /* OWSProfileManager.m in Sources */, 346129701FD1D74C00532771 /* Release.m in Sources */, + 3421981321061A0700C57195 /* JSQMessagesAvatarImageFactory.m in Sources */, 452EC6E1205FF5DC000E787C /* Bench.swift in Sources */, 3478506C1FD9B78A007B8332 /* NoopNotificationsManager.swift in Sources */, 34480B621FD0A98800BC14EF /* UIColor+OWS.m in Sources */, @@ -3177,6 +3213,7 @@ 3438226A209B63500094FEB7 /* EditContactShareNameViewController.swift in Sources */, 34B6D27520F664C900765BE2 /* OWSUnreadIndicator.m in Sources */, 346129A61FD1F09100532771 /* OWSContactsManager.m in Sources */, + 3421981021061A0700C57195 /* JSQMessagesAvatarImage.m in Sources */, 4541B71D209D3B7A0008608F /* ContactShareViewModel.swift in Sources */, 4598198F204E2F28009414F2 /* OWS108CallLoggingPreference.m in Sources */, 346129D21FD2085A00532771 /* CommonStrings.swift in Sources */, @@ -3315,6 +3352,7 @@ 3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */, 34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */, 34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */, + 34219801210612F600C57195 /* iRate.m in Sources */, 45F32C222057297A00A300D5 /* MediaDetailViewController.m in Sources */, 34B3F8851E8DF1700035BE1A /* NewGroupViewController.m in Sources */, 34D8C0271ED3673300188D7C /* DebugUIMessages.m in Sources */, @@ -3362,7 +3400,6 @@ 340FC8B5204DAC8D007AEB0F /* AboutTableViewController.m in Sources */, 34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */, 340FC8B9204DAC8D007AEB0F /* UpdateGroupViewController.m in Sources */, - B609597C1C2C0FC6004E8797 /* iRate.m in Sources */, 4574A5D61DD6704700C6B692 /* CallService.swift in Sources */, 340FC8A8204DAC8D007AEB0F /* CodeVerificationViewController.m in Sources */, 3461299C1FD1EA9E00532771 /* NotificationsManager.m in Sources */, diff --git a/Libraries/iRate/iRate.h b/Signal/Libraries/iRate/iRate.h similarity index 100% rename from Libraries/iRate/iRate.h rename to Signal/Libraries/iRate/iRate.h diff --git a/Libraries/iRate/iRate.m b/Signal/Libraries/iRate/iRate.m similarity index 100% rename from Libraries/iRate/iRate.m rename to Signal/Libraries/iRate/iRate.m diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index 1193d56cf..c477bc168 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -136,7 +136,8 @@ const CGFloat kIconViewLength = 24; - (NSString *)threadName { NSString *threadName = self.thread.name; - if ([threadName isEqualToString:self.thread.contactIdentifier]) { + if (self.thread.contactIdentifier && + [threadName isEqualToString:self.thread.contactIdentifier]) { threadName = [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:self.thread.contactIdentifier]; } else if (threadName.length == 0 && [self isGroupThread]) { diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-LICENSE b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-LICENSE new file mode 100644 index 000000000..e7a4b01d5 --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-LICENSE @@ -0,0 +1,20 @@ + +MIT License +Copyright (c) 2013-present Jesse Squires + +http://www.jessesquires.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-README.md b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-README.md new file mode 100644 index 000000000..4d699c3ab --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-README.md @@ -0,0 +1,104 @@ +![JSQMessagesViewController banner](https://raw.githubusercontent.com/jessesquires/JSQMessagesViewController/develop/Assets/jsq_messages_banner.png) + +[![Build Status](https://secure.travis-ci.org/jessesquires/JSQMessagesViewController.svg)](https://travis-ci.org/jessesquires/JSQMessagesViewController) [![Version Status](https://img.shields.io/cocoapods/v/JSQMessagesViewController.svg)][podLink] [![license MIT](https://img.shields.io/cocoapods/l/JSQMessagesViewController.svg)][mitLink] [![codecov](https://codecov.io/gh/jessesquires/JSQMessagesViewController/branch/develop/graph/badge.svg)](https://codecov.io/gh/jessesquires/JSQMessagesViewController) [![Platform](https://img.shields.io/cocoapods/p/JSQMessagesViewController.svg)][docsLink] + +![Screenshot0][img0]    ![Screenshot1][img1]    + +![Screenshot2][img2]    ![Screenshot3][img3] + +> More screenshots available at [CocoaControls](https://www.cocoacontrols.com/controls/jsqmessagesviewcontroller) + +## Features + +See the [website](http://www.jessesquires.com/JSQMessagesViewController/) for the list of features. + +## Design Goals + +- Closely mimic the [iOS Messages](http://www.apple.com/ios/messages/) style and behavior +- [SOLID](https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)) design +- Easy customization and extension for clients + +## Dependencies + +* [JSQSystemSoundPlayer][playerLink] + +## Requirements + +* iOS 7.0+ +* ARC + +## Installation + +### [CocoaPods](https://cocoapods.org/) (recommended) + +````ruby +# For latest release in cocoapods +pod 'JSQMessagesViewController' + +# Latest on develop +pod 'JSQMessagesViewController', :git => 'https://github.com/jessesquires/JSQMessagesViewController.git', :branch => 'develop' + +# For version 5.3.2 +pod 'JSQMessagesViewController', :git => 'https://github.com/jessesquires/JSQMessagesViewController', :branch => 'version_5.3.2_patch' +```` + +## Getting Started + +See the [Getting Started](https://github.com/jessesquires/JSQMessagesViewController/blob/develop/Documentation/getting_started.md) guide! + +## Questions & Help + +* Review the [FAQ](https://github.com/jessesquires/JSQMessagesViewController/blob/develop/Documentation/faq.md). +* Search issues for previous and current [questions](https://github.com/jessesquires/JSQMessagesViewController/issues?utf8=✓&q=label%3A%22questions+%26+help%22+). *Do not open duplicates.* +* [StackOverflow](http://stackoverflow.com/questions/tagged/jsqmessagesviewcontroller) is often the most appropriate place for questions and help. We have our own tag, `jsqmessagesviewcontroller`. +* See the [Migration Guide](https://github.com/jessesquires/JSQMessagesViewController/blob/develop/Documentation/migration.md) for migrating between major versions of the library. +* **Only ask questions that are _specific_ to this library.** +* **Please avoid emailing questions.** I prefer to keep questions and their answers open-source. + +## Documentation + +Read the docs, [available here][docsLink] via [@CocoaDocs](https://twitter.com/CocoaDocs). + +## Core team + +- Jesse Squires ([**@jesse_squires**](https://twitter.com/jesse_squires)) +- Harlan Haskans ([**@harlanhaskins**](https://github.com/harlanhaskins)) +- Eli Burke ([**@eliburke**](https://github.com/eliburke)) + +## Contributing + +Please follow these sweet [contribution guidelines](https://github.com/jessesquires/JSQMessagesViewController/blob/develop/.github/CONTRIBUTING.md). + +> **Interested in becoming a core contributor with push access? See our [onboarding guide](https://github.com/jessesquires/JSQMessagesViewController/blob/develop/Documentation/contributor_onboarding.md) for details.** + +## Donate + +Support the development of this **free** library! **[Donate](https://cash.me/$jsq)** via [Square Cash](https://cash.me/). + +## Credits + +* Created and maintained by [**@jesse_squires**](https://twitter.com/jesse_squires). +* Many thanks to [**the contributors**](https://github.com/jessesquires/JSQMessagesViewController/graphs/contributors) of this project. +* iOS assets extracted using [**@0xced**](https://github.com/0xced) / [iOS-Artwork-Extractor](https://github.com/0xced/iOS-Artwork-Extractor). + +## Apps using this library + +According to [CocoaPods stats](https://cocoapods.org/pods/JSQMessagesViewController), over **9,000 apps** are using `JSQMessagesViewController`. [Here are the ones](https://github.com/jessesquires/JSQMessagesViewController/blob/develop/Documentation/apps_using_this_library.md) that we know about. Please submit a [pull request](https://github.com/jessesquires/JSQMessagesViewController/compare) to add your app! :smile: + +## License + +`JSQMessagesViewController` is released under an [MIT License][mitLink]. See `LICENSE` for details. + +>**Copyright © 2013-present Jesse Squires.** + +*Please provide attribution, it is greatly appreciated.* + +[docsLink]:http://cocoadocs.org/docsets/JSQMessagesViewController/ +[podLink]:https://cocoapods.org/pods/JSQMessagesViewController +[mitLink]:http://opensource.org/licenses/MIT +[playerLink]:https://github.com/jessesquires/JSQSystemSoundPlayer + +[img0]:https://raw.githubusercontent.com/jessesquires/JSQMessagesViewController/develop/Screenshots/screenshot0.png +[img1]:https://raw.githubusercontent.com/jessesquires/JSQMessagesViewController/develop/Screenshots/screenshot1.png +[img2]:https://raw.githubusercontent.com/jessesquires/JSQMessagesViewController/develop/Screenshots/screenshot2.png +[img3]:https://raw.githubusercontent.com/jessesquires/JSQMessagesViewController/develop/Screenshots/screenshot3.png diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-SIGNAL.md b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-SIGNAL.md new file mode 100644 index 000000000..f9cf9824f --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMVC-SIGNAL.md @@ -0,0 +1,7 @@ +The files in this directory are drawn from JSQMessagesViewController, created by Jesse Squires. These files have been pulled into the Signal-iOS repository with his permission. + +https://github.com/jessesquires/JSQMessagesViewController + +These files are available under the MIT License. See JSQMVC-LICENSE. + + diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessageAvatarImageDataSource.h b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessageAvatarImageDataSource.h new file mode 100644 index 000000000..fc31072b1 --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessageAvatarImageDataSource.h @@ -0,0 +1,63 @@ +// +// Created by Jesse Squires +// http://www.jessesquires.com +// +// +// Documentation +// http://cocoadocs.org/docsets/JSQMessagesViewController +// +// +// GitHub +// https://github.com/jessesquires/JSQMessagesViewController +// +// +// License +// Copyright (c) 2014 Jesse Squires +// Released under an MIT license: http://opensource.org/licenses/MIT +// + +#import +#import + +/** + * The `JSQMessageAvatarImageDataSource` protocol defines the common interface through which + * a `JSQMessagesViewController` and `JSQMessagesCollectionView` interact with avatar image model objects. + * + * It declares the required and optional methods that a class must implement so that instances + * of that class can be display properly within a `JSQMessagesCollectionViewCell`. + * + * A concrete class that conforms to this protocol is provided in the library. See `JSQMessagesAvatarImage`. + * + * @see JSQMessagesAvatarImage. + */ +@protocol JSQMessageAvatarImageDataSource + +@required + +/** + * @return The avatar image for a regular display state. + * + * @discussion You may return `nil` from this method while the image is being downloaded. + */ +- (UIImage *)avatarImage; + +/** + * @return The avatar image for a highlighted display state. + * + * @discussion You may return `nil` from this method if this does not apply. + */ +- (UIImage *)avatarHighlightedImage; + +/** + * @return A placeholder avatar image to be displayed if avatarImage is not yet available, or `nil`. + * For example, if avatarImage needs to be downloaded, this placeholder image + * will be used until avatarImage is not `nil`. + * + * @discussion If you do not need support for a placeholder image, that is, your images + * are stored locally on the device, then you may simply return the same value as avatarImage here. + * + * @warning You must not return `nil` from this method. + */ +- (UIImage *)avatarPlaceholderImage; + +@end diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImage.h b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImage.h new file mode 100644 index 000000000..6d40fb4e8 --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImage.h @@ -0,0 +1,86 @@ +// +// Created by Jesse Squires +// http://www.jessesquires.com +// +// +// Documentation +// http://cocoadocs.org/docsets/JSQMessagesViewController +// +// +// GitHub +// https://github.com/jessesquires/JSQMessagesViewController +// +// +// License +// Copyright (c) 2014 Jesse Squires +// Released under an MIT license: http://opensource.org/licenses/MIT +// + +#import +#import + +#import "JSQMessageAvatarImageDataSource.h" + +/** + * A `JSQMessagesAvatarImage` model object represents an avatar image. + * This is a concrete class that implements the `JSQMessageAvatarImageDataSource` protocol. + * It contains a regular avatar image, a highlighted avatar image, and a placeholder avatar image. + * + * @see JSQMessagesAvatarImageFactory. + */ +@interface JSQMessagesAvatarImage : NSObject + +/** + * The avatar image for a regular display state. + */ +@property (nonatomic, strong) UIImage *avatarImage; + +/** + * The avatar image for a highlighted display state. + */ +@property (nonatomic, strong) UIImage *avatarHighlightedImage; + +/** + * Returns the placeholder image for an avatar to display if avatarImage is `nil`. + */ +@property (nonatomic, strong, readonly) UIImage *avatarPlaceholderImage; + +/** + * Initializes and returns an avatar image object having the specified image. + * + * @param image The image for this avatar image. This image will be used for the all of the following + * properties: avatarImage, avatarHighlightedImage, avatarPlaceholderImage; + * This value must not be `nil`. + * + * @return An initialized `JSQMessagesAvatarImage` object if successful, `nil` otherwise. + */ ++ (instancetype)avatarWithImage:(UIImage *)image; + +/** + * Initializes and returns an avatar image object having the specified placeholder image. + * + * @param placeholderImage The placeholder image for this avatar image. This value must not be `nil`. + * + * @return An initialized `JSQMessagesAvatarImage` object if successful, `nil` otherwise. + */ ++ (instancetype)avatarImageWithPlaceholder:(UIImage *)placeholderImage; + +/** + * Initializes and returns an avatar image object having the specified regular, highlighed, and placeholder images. + * + * @param avatarImage The avatar image for a regular display state. + * @param highlightedImage The avatar image for a highlighted display state. + * @param placeholderImage The placeholder image for this avatar image. This value must not be `nil`. + * + * @return An initialized `JSQMessagesAvatarImage` object if successful, `nil` otherwise. + */ +- (instancetype)initWithAvatarImage:(UIImage *)avatarImage + highlightedImage:(UIImage *)highlightedImage + placeholderImage:(UIImage *)placeholderImage NS_DESIGNATED_INITIALIZER; + +/** + * Not a valid initializer. + */ +- (id)init NS_UNAVAILABLE; + +@end diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImage.m b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImage.m new file mode 100644 index 000000000..20828611a --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImage.m @@ -0,0 +1,78 @@ +// +// Created by Jesse Squires +// http://www.jessesquires.com +// +// +// Documentation +// http://cocoadocs.org/docsets/JSQMessagesViewController +// +// +// GitHub +// https://github.com/jessesquires/JSQMessagesViewController +// +// +// License +// Copyright (c) 2014 Jesse Squires +// Released under an MIT license: http://opensource.org/licenses/MIT +// + +#import "JSQMessagesAvatarImage.h" + +@implementation JSQMessagesAvatarImage + +#pragma mark - Initialization + ++ (instancetype)avatarWithImage:(UIImage *)image +{ + NSParameterAssert(image != nil); + + return [[JSQMessagesAvatarImage alloc] initWithAvatarImage:image + highlightedImage:image + placeholderImage:image]; +} + ++ (instancetype)avatarImageWithPlaceholder:(UIImage *)placeholderImage +{ + return [[JSQMessagesAvatarImage alloc] initWithAvatarImage:nil + highlightedImage:nil + placeholderImage:placeholderImage]; +} + +- (instancetype)initWithAvatarImage:(UIImage *)avatarImage + highlightedImage:(UIImage *)highlightedImage + placeholderImage:(UIImage *)placeholderImage +{ + NSParameterAssert(placeholderImage != nil); + + self = [super init]; + if (self) { + _avatarImage = avatarImage; + _avatarHighlightedImage = highlightedImage; + _avatarPlaceholderImage = placeholderImage; + } + return self; +} + +#pragma mark - NSObject + +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@: avatarImage=%@, avatarHighlightedImage=%@, avatarPlaceholderImage=%@>", + [self class], self.avatarImage, self.avatarHighlightedImage, self.avatarPlaceholderImage]; +} + +- (id)debugQuickLookObject +{ + return [[UIImageView alloc] initWithImage:self.avatarImage ?: self.avatarPlaceholderImage]; +} + +#pragma mark - NSCopying + +- (instancetype)copyWithZone:(NSZone *)zone +{ + return [[[self class] allocWithZone:zone] initWithAvatarImage:[UIImage imageWithCGImage:self.avatarImage.CGImage] + highlightedImage:[UIImage imageWithCGImage:self.avatarHighlightedImage.CGImage] + placeholderImage:[UIImage imageWithCGImage:self.avatarPlaceholderImage.CGImage]]; +} + +@end diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImageFactory.h b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImageFactory.h new file mode 100644 index 000000000..759cd5388 --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImageFactory.h @@ -0,0 +1,99 @@ +// +// Created by Jesse Squires +// http://www.jessesquires.com +// +// +// Documentation +// http://cocoadocs.org/docsets/JSQMessagesViewController +// +// +// GitHub +// https://github.com/jessesquires/JSQMessagesViewController +// +// +// License +// Copyright (c) 2014 Jesse Squires +// Released under an MIT license: http://opensource.org/licenses/MIT +// + +#import +#import + +#import "JSQMessagesAvatarImage.h" + +/** + * `JSQMessagesAvatarImageFactory` is a factory that provides a means for creating and styling + * `JSQMessagesAvatarImage` objects to be displayed in a `JSQMessagesCollectionViewCell` of a `JSQMessagesCollectionView`. + */ +@interface JSQMessagesAvatarImageFactory : NSObject + +/** +* Creates and returns a `JSQMessagesAvatarImage` object with the specified placeholderImage that is +* cropped to a circle of the given diameter. +* +* @param placeholderImage An image object that represents a placeholder avatar image. This value must not be `nil`. +* @param diameter An integer value specifying the diameter size of the avatar in points. This value must be greater than `0`. +* +* @return An initialized `JSQMessagesAvatarImage` object if created successfully, `nil` otherwise. +*/ ++ (JSQMessagesAvatarImage *)avatarImageWithPlaceholder:(UIImage *)placeholderImage diameter:(NSUInteger)diameter; + +/** + * Creates and returns a `JSQMessagesAvatarImage` object with the specified image that is + * cropped to a circle of the given diameter and used for the `avatarImage` and `avatarPlaceholderImage` properties + * of the returned `JSQMessagesAvatarImage` object. This image is then copied and has a transparent black mask applied to it, + * which is used for the `avatarHighlightedImage` property of the returned `JSQMessagesAvatarImage` object. + * + * @param image An image object that represents an avatar image. This value must not be `nil`. + * @param diameter An integer value specifying the diameter size of the avatar in points. This value must be greater than `0`. + * + * @return An initialized `JSQMessagesAvatarImage` object if created successfully, `nil` otherwise. + */ ++ (JSQMessagesAvatarImage *)avatarImageWithImage:(UIImage *)image diameter:(NSUInteger)diameter; + +/** + * Returns a copy of the specified image that is cropped to a circle with the given diameter. + * + * @param image The image to crop. This value must not be `nil`. + * @param diameter An integer value specifying the diameter size of the image in points. This value must be greater than `0`. + * + * @return A new image object if successful, `nil` otherwise. + */ ++ (UIImage *)circularAvatarImage:(UIImage *)image withDiameter:(NSUInteger)diameter; + +/** + * Returns a copy of the specified image that is cropped to a circle with the given diameter. + * Additionally, a transparent overlay is applied to the image to represent a pressed or highlighted state. + * + * @param image The image to crop. This value must not be `nil`. + * @param diameter An integer value specifying the diameter size of the image in points. This value must be greater than `0`. + * + * @return A new image object if successful, `nil` otherwise. + */ ++ (UIImage *)circularAvatarHighlightedImage:(UIImage *)image withDiameter:(NSUInteger)diameter; + +/** + * Creates and returns a `JSQMessagesAvatarImage` object with a circular shape that displays the specified userInitials + * with the given backgroundColor, textColor, font, and diameter. + * + * @param userInitials The user initials to display in the avatar image. This value must not be `nil`. + * @param backgroundColor The background color of the avatar. This value must not be `nil`. + * @param textColor The color of the text of the userInitials. This value must not be `nil`. + * @param font The font applied to userInitials. This value must not be `nil`. + * @param diameter The diameter of the avatar image. This value must be greater than `0`. + * + * @return An initialized `JSQMessagesAvatarImage` object if created successfully, `nil` otherwise. + * + * @discussion This method does not attempt to detect or correct incompatible parameters. + * That is to say, you are responsible for providing a font size and diameter that make sense. + * For example, a font size of `14.0f` and a diameter of `34.0f` will result in an avatar similar to Messages in iOS 7. + * However, a font size `30.0f` and diameter of `10.0f` will not produce a desirable image. + * Further, this method does not check the length of userInitials. It is recommended that you pass a string of length `2` or `3`. + */ ++ (JSQMessagesAvatarImage *)avatarImageWithUserInitials:(NSString *)userInitials + backgroundColor:(UIColor *)backgroundColor + textColor:(UIColor *)textColor + font:(UIFont *)font + diameter:(NSUInteger)diameter; + +@end diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImageFactory.m b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImageFactory.m new file mode 100644 index 000000000..222c2c8f4 --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/JSQMessagesAvatarImageFactory.m @@ -0,0 +1,159 @@ +// +// Created by Jesse Squires +// http://www.jessesquires.com +// +// +// Documentation +// http://cocoadocs.org/docsets/JSQMessagesViewController +// +// +// GitHub +// https://github.com/jessesquires/JSQMessagesViewController +// +// +// License +// Copyright (c) 2014 Jesse Squires +// Released under an MIT license: http://opensource.org/licenses/MIT +// + +#import "JSQMessagesAvatarImageFactory.h" + +#import "UIColor+JSQMessages.h" + + +@implementation JSQMessagesAvatarImageFactory + +#pragma mark - Public + ++ (JSQMessagesAvatarImage *)avatarImageWithPlaceholder:(UIImage *)placeholderImage diameter:(NSUInteger)diameter +{ + UIImage *circlePlaceholderImage = [JSQMessagesAvatarImageFactory jsq_circularImage:placeholderImage + withDiameter:diameter + highlightedColor:nil]; + + return [JSQMessagesAvatarImage avatarImageWithPlaceholder:circlePlaceholderImage]; +} + ++ (JSQMessagesAvatarImage *)avatarImageWithImage:(UIImage *)image diameter:(NSUInteger)diameter +{ + UIImage *avatar = [JSQMessagesAvatarImageFactory circularAvatarImage:image withDiameter:diameter]; + UIImage *highlightedAvatar = [JSQMessagesAvatarImageFactory circularAvatarHighlightedImage:image withDiameter:diameter]; + + return [[JSQMessagesAvatarImage alloc] initWithAvatarImage:avatar + highlightedImage:highlightedAvatar + placeholderImage:avatar]; +} + ++ (UIImage *)circularAvatarImage:(UIImage *)image withDiameter:(NSUInteger)diameter +{ + return [JSQMessagesAvatarImageFactory jsq_circularImage:image + withDiameter:diameter + highlightedColor:nil]; +} + ++ (UIImage *)circularAvatarHighlightedImage:(UIImage *)image withDiameter:(NSUInteger)diameter +{ + return [JSQMessagesAvatarImageFactory jsq_circularImage:image + withDiameter:diameter + highlightedColor:[UIColor colorWithWhite:0.1f alpha:0.3f]]; +} + ++ (JSQMessagesAvatarImage *)avatarImageWithUserInitials:(NSString *)userInitials + backgroundColor:(UIColor *)backgroundColor + textColor:(UIColor *)textColor + font:(UIFont *)font + diameter:(NSUInteger)diameter +{ + UIImage *avatarImage = [JSQMessagesAvatarImageFactory jsq_imageWitInitials:userInitials + backgroundColor:backgroundColor + textColor:textColor + font:font + diameter:diameter]; + + UIImage *avatarHighlightedImage = [JSQMessagesAvatarImageFactory jsq_circularImage:avatarImage + withDiameter:diameter + highlightedColor:[UIColor colorWithWhite:0.1f alpha:0.3f]]; + + return [[JSQMessagesAvatarImage alloc] initWithAvatarImage:avatarImage + highlightedImage:avatarHighlightedImage + placeholderImage:avatarImage]; +} + +#pragma mark - Private + ++ (UIImage *)jsq_imageWitInitials:(NSString *)initials + backgroundColor:(UIColor *)backgroundColor + textColor:(UIColor *)textColor + font:(UIFont *)font + diameter:(NSUInteger)diameter +{ + NSParameterAssert(initials != nil); + NSParameterAssert(backgroundColor != nil); + NSParameterAssert(textColor != nil); + NSParameterAssert(font != nil); + NSParameterAssert(diameter > 0); + + CGRect frame = CGRectMake(0.0f, 0.0f, diameter, diameter); + + NSDictionary *attributes = @{ NSFontAttributeName : font, + NSForegroundColorAttributeName : textColor }; + + CGRect textFrame = [initials boundingRectWithSize:frame.size + options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) + attributes:attributes + context:nil]; + + CGPoint frameMidPoint = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame)); + CGPoint textFrameMidPoint = CGPointMake(CGRectGetMidX(textFrame), CGRectGetMidY(textFrame)); + + CGFloat dx = frameMidPoint.x - textFrameMidPoint.x; + CGFloat dy = frameMidPoint.y - textFrameMidPoint.y; + CGPoint drawPoint = CGPointMake(dx, dy); + UIImage *image = nil; + + UIGraphicsBeginImageContextWithOptions(frame.size, NO, [UIScreen mainScreen].scale); + { + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetFillColorWithColor(context, backgroundColor.CGColor); + CGContextFillRect(context, frame); + [initials drawAtPoint:drawPoint withAttributes:attributes]; + + image = UIGraphicsGetImageFromCurrentImageContext(); + + } + UIGraphicsEndImageContext(); + + return [JSQMessagesAvatarImageFactory jsq_circularImage:image withDiameter:diameter highlightedColor:nil]; +} + ++ (UIImage *)jsq_circularImage:(UIImage *)image withDiameter:(NSUInteger)diameter highlightedColor:(UIColor *)highlightedColor +{ + NSParameterAssert(image != nil); + NSParameterAssert(diameter > 0); + + CGRect frame = CGRectMake(0.0f, 0.0f, diameter, diameter); + UIImage *newImage = nil; + + UIGraphicsBeginImageContextWithOptions(frame.size, NO, [UIScreen mainScreen].scale); + { + CGContextRef context = UIGraphicsGetCurrentContext(); + + UIBezierPath *imgPath = [UIBezierPath bezierPathWithOvalInRect:frame]; + [imgPath addClip]; + [image drawInRect:frame]; + + if (highlightedColor != nil) { + CGContextSetFillColorWithColor(context, highlightedColor.CGColor); + CGContextFillEllipseInRect(context, frame); + } + + newImage = UIGraphicsGetImageFromCurrentImageContext(); + + } + UIGraphicsEndImageContext(); + + return newImage; +} + +@end diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/UIColor+JSQMessages.h b/SignalMessaging/Libraries/JSQMessagesViewController/UIColor+JSQMessages.h new file mode 100644 index 000000000..0dc579817 --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/UIColor+JSQMessages.h @@ -0,0 +1,56 @@ +// +// Created by Jesse Squires +// http://www.jessesquires.com +// +// +// Documentation +// http://cocoadocs.org/docsets/JSQMessagesViewController +// +// +// GitHub +// https://github.com/jessesquires/JSQMessagesViewController +// +// +// License +// Copyright (c) 2014 Jesse Squires +// Released under an MIT license: http://opensource.org/licenses/MIT +// + +#import + +@interface UIColor (JSQMessages) + +#pragma mark - Message bubble colors + +/** + * @return A color object containing HSB values similar to the iOS 7 messages app green bubble color. + */ ++ (UIColor *)jsq_messageBubbleGreenColor; + +/** + * @return A color object containing HSB values similar to the iOS 7 messages app blue bubble color. + */ ++ (UIColor *)jsq_messageBubbleBlueColor; + +/** + * @return A color object containing HSB values similar to the iOS 7 red color. + */ ++ (UIColor *)jsq_messageBubbleRedColor; + +/** + * @return A color object containing HSB values similar to the iOS 7 messages app light gray bubble color. + */ ++ (UIColor *)jsq_messageBubbleLightGrayColor; + +#pragma mark - Utilities + +/** + * Creates and returns a new color object whose brightness component is decreased by the given value, using the initial color values of the receiver. + * + * @param value A floating point value describing the amount by which to decrease the brightness of the receiver. + * + * @return A new color object whose brightness is decreased by the given values. The other color values remain the same as the receiver. + */ +- (UIColor *)jsq_colorByDarkeningColorWithValue:(CGFloat)value; + +@end \ No newline at end of file diff --git a/SignalMessaging/Libraries/JSQMessagesViewController/UIColor+JSQMessages.m b/SignalMessaging/Libraries/JSQMessagesViewController/UIColor+JSQMessages.m new file mode 100644 index 000000000..9e254ac56 --- /dev/null +++ b/SignalMessaging/Libraries/JSQMessagesViewController/UIColor+JSQMessages.m @@ -0,0 +1,90 @@ +// +// Created by Jesse Squires +// http://www.jessesquires.com +// +// +// Documentation +// http://cocoadocs.org/docsets/JSQMessagesViewController +// +// +// GitHub +// https://github.com/jessesquires/JSQMessagesViewController +// +// +// License +// Copyright (c) 2014 Jesse Squires +// Released under an MIT license: http://opensource.org/licenses/MIT +// + +#import "UIColor+JSQMessages.h" + +@implementation UIColor (JSQMessages) + +#pragma mark - Message bubble colors + ++ (UIColor *)jsq_messageBubbleGreenColor +{ + return [UIColor colorWithHue:130.0f / 360.0f + saturation:0.68f + brightness:0.84f + alpha:1.0f]; +} + ++ (UIColor *)jsq_messageBubbleBlueColor +{ + return [UIColor colorWithHue:210.0f / 360.0f + saturation:0.94f + brightness:1.0f + alpha:1.0f]; +} + ++ (UIColor *)jsq_messageBubbleRedColor +{ + return [UIColor colorWithHue:0.0f / 360.0f + saturation:0.79f + brightness:1.0f + alpha:1.0f]; +} + ++ (UIColor *)jsq_messageBubbleLightGrayColor +{ + return [UIColor colorWithHue:240.0f / 360.0f + saturation:0.02f + brightness:0.92f + alpha:1.0f]; +} + +#pragma mark - Utilities + +- (UIColor *)jsq_colorByDarkeningColorWithValue:(CGFloat)value +{ + NSUInteger totalComponents = CGColorGetNumberOfComponents(self.CGColor); + BOOL isGreyscale = (totalComponents == 2) ? YES : NO; + + CGFloat *oldComponents = (CGFloat *)CGColorGetComponents(self.CGColor); + CGFloat newComponents[4]; + + if (isGreyscale) { + newComponents[0] = oldComponents[0] - value < 0.0f ? 0.0f : oldComponents[0] - value; + newComponents[1] = oldComponents[0] - value < 0.0f ? 0.0f : oldComponents[0] - value; + newComponents[2] = oldComponents[0] - value < 0.0f ? 0.0f : oldComponents[0] - value; + newComponents[3] = oldComponents[1]; + } + else { + newComponents[0] = oldComponents[0] - value < 0.0f ? 0.0f : oldComponents[0] - value; + newComponents[1] = oldComponents[1] - value < 0.0f ? 0.0f : oldComponents[1] - value; + newComponents[2] = oldComponents[2] - value < 0.0f ? 0.0f : oldComponents[2] - value; + newComponents[3] = oldComponents[3]; + } + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGColorRef newColor = CGColorCreate(colorSpace, newComponents); + CGColorSpaceRelease(colorSpace); + + UIColor *retColor = [UIColor colorWithCGColor:newColor]; + CGColorRelease(newColor); + + return retColor; +} + +@end \ No newline at end of file diff --git a/SignalMessaging/utils/OWSAvatarBuilder.m b/SignalMessaging/utils/OWSAvatarBuilder.m index 85c8c3598..c5a01120c 100644 --- a/SignalMessaging/utils/OWSAvatarBuilder.m +++ b/SignalMessaging/utils/OWSAvatarBuilder.m @@ -8,10 +8,7 @@ #import "TSContactThread.h" #import "TSGroupThread.h" #import "UIColor+OWS.h" - -// SHARINGEXTENSION FIXME -// intern or reimplement this so that SignalMessaging doesn't depend on JSQ -#import +#import "JSQMessagesAvatarImageFactory.h" NS_ASSUME_NONNULL_BEGIN diff --git a/SignalMessaging/utils/OWSContactAvatarBuilder.m b/SignalMessaging/utils/OWSContactAvatarBuilder.m index 0cf165082..2704c3d67 100644 --- a/SignalMessaging/utils/OWSContactAvatarBuilder.m +++ b/SignalMessaging/utils/OWSContactAvatarBuilder.m @@ -10,10 +10,7 @@ #import "UIColor+OWS.h" #import "UIFont+OWS.h" #import - -// SHARINGEXTENSION FIXME -// intern or reimplement this so that SignalMessaging doesn't depend on JSQ -#import +#import "JSQMessagesAvatarImageFactory.h" NS_ASSUME_NONNULL_BEGIN