Intern JSQMessagesViewController.

This commit is contained in:
Matthew Chen 2018-07-23 10:17:35 -04:00
parent 906d0b01a4
commit 25a98554b7
18 changed files with 849 additions and 71 deletions

View File

@ -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

View File

@ -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

View File

@ -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 = "<group>"; };
341F2C0D1F2B8AE700D07D6B /* DebugUIMisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIMisc.h; sourceTree = "<group>"; };
341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIMisc.m; sourceTree = "<group>"; };
342197FF210612F600C57195 /* iRate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iRate.m; sourceTree = "<group>"; };
34219800210612F600C57195 /* iRate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iRate.h; sourceTree = "<group>"; };
3421980521061A0600C57195 /* UIColor+JSQMessages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+JSQMessages.m"; sourceTree = "<group>"; };
3421980621061A0600C57195 /* JSQMessagesAvatarImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSQMessagesAvatarImage.m; sourceTree = "<group>"; };
3421980721061A0600C57195 /* JSQMessagesAvatarImageFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQMessagesAvatarImageFactory.h; sourceTree = "<group>"; };
3421980821061A0600C57195 /* JSQMVC-LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "JSQMVC-LICENSE"; sourceTree = "<group>"; };
3421980921061A0700C57195 /* JSQMessagesAvatarImageFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSQMessagesAvatarImageFactory.m; sourceTree = "<group>"; };
3421980A21061A0700C57195 /* JSQMessagesAvatarImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQMessagesAvatarImage.h; sourceTree = "<group>"; };
3421980B21061A0700C57195 /* UIColor+JSQMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+JSQMessages.h"; sourceTree = "<group>"; };
3421980C21061A0700C57195 /* JSQMVC-README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "JSQMVC-README.md"; sourceTree = "<group>"; };
3421980D21061A0700C57195 /* JSQMVC-SIGNAL.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "JSQMVC-SIGNAL.md"; sourceTree = "<group>"; };
3421980E21061A0700C57195 /* JSQMessageAvatarImageDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQMessageAvatarImageDataSource.h; sourceTree = "<group>"; };
34277A5C20751BDC006049F2 /* OWSQuotedMessageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSQuotedMessageView.m; sourceTree = "<group>"; };
34277A5D20751BDC006049F2 /* OWSQuotedMessageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSQuotedMessageView.h; sourceTree = "<group>"; };
3427C64120F500DE00EEC730 /* OWSMessageTimerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageTimerView.h; sourceTree = "<group>"; };
@ -1074,7 +1096,6 @@
45E5A6981F61E6DD001E4A8A /* MarqueeLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarqueeLabel.swift; sourceTree = "<group>"; };
45E7A6A61E71CA7E00D44FB5 /* DisplayableTextFilterTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayableTextFilterTest.swift; sourceTree = "<group>"; };
45F170AB1E2F0351003FC1F2 /* OWSAudioSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAudioSession.swift; 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>"; };
45F170D51E315310003FC1F2 /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = "<group>"; };
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 = "<group>"; };
B10C9B5E1A7049EC00ECA2BF /* play_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "play_icon@2x.png"; sourceTree = "<group>"; };
B60341CD1AA5469800A01E42 /* ja_JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja_JP; path = translations/ja_JP.lproj/Localizable.strings; sourceTree = "<group>"; };
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 = "<group>"; };
B633C50B1A1D190B0059AC12 /* contact_default_feed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contact_default_feed.png; sourceTree = "<group>"; };
@ -1419,6 +1438,49 @@
path = ThreadSettings;
sourceTree = "<group>";
};
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 = "<group>";
};
34219803210619D300C57195 /* Libraries */ = {
isa = PBXGroup;
children = (
3421980421061A0600C57195 /* JSQMessagesViewController */,
);
path = Libraries;
sourceTree = "<group>";
};
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 = "<group>";
};
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 = "<group>";
};
45F170B01E2F0A35003FC1F2 /* Libraries */ = {
isa = PBXGroup;
children = (
45F170B11E2F0A6A003FC1F2 /* WebRTC */,
);
name = Libraries;
path = Signal;
sourceTree = "<group>";
};
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 = "<group>";
};
B60959791C2C0FA9004E8797 /* rating */ = {
isa = PBXGroup;
children = (
B609597A1C2C0FC6004E8797 /* iRate.h */,
B609597B1C2C0FC6004E8797 /* iRate.m */,
);
name = rating;
sourceTree = "<group>";
};
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 */,

View File

@ -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]) {

View File

@ -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.

View File

@ -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] &nbsp;&nbsp; ![Screenshot1][img1] &nbsp;&nbsp;
![Screenshot2][img2] &nbsp;&nbsp; ![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 &copy; 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

View File

@ -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.

View File

@ -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 <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
/**
* 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 <NSObject>
@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

View File

@ -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 <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#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 <JSQMessageAvatarImageDataSource, NSCopying>
/**
* 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

View File

@ -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

View File

@ -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 <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#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

View File

@ -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

View File

@ -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 <UIKit/UIKit.h>
@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

View File

@ -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

View File

@ -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 <JSQMessagesViewController/JSQMessagesAvatarImageFactory.h>
#import "JSQMessagesAvatarImageFactory.h"
NS_ASSUME_NONNULL_BEGIN

View File

@ -10,10 +10,7 @@
#import "UIColor+OWS.h"
#import "UIFont+OWS.h"
#import <SignalMessaging/SignalMessaging-Swift.h>
// SHARINGEXTENSION FIXME
// intern or reimplement this so that SignalMessaging doesn't depend on JSQ
#import <JSQMessagesViewController/JSQMessagesAvatarImageFactory.h>
#import "JSQMessagesAvatarImageFactory.h"
NS_ASSUME_NONNULL_BEGIN