From 25d56b30c173b8f39d6a3485581146ce506b88e9 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 26 Sep 2018 11:10:28 -0400 Subject: [PATCH 1/4] Rework group avatars to reflect conversation colors. --- .../empty-group-avatar.png | Bin 12034 -> 0 bytes .../Contents.json | 12 - .../group-avi.pdf | 748 ------------------ .../Contents.json | 4 +- .../group-28-white@1x.png | Bin 0 -> 1558 bytes .../group-28-white@2x.png | Bin 0 -> 1994 bytes .../group-28-white@3x.png | Bin 0 -> 2418 bytes .../AppSettings/BlockListViewController.m | 2 +- .../ViewControllers/CallViewController.swift | 2 +- .../Cells/OWSAudioMessageView.m | 2 +- .../Cells/OWSContactShareView.m | 2 +- .../Cells/OWSGenericAttachmentView.m | 2 +- .../ConversationView/Cells/OWSMessageCell.m | 9 +- .../ViewControllers/HomeView/HomeViewCell.m | 6 +- .../ViewControllers/NewGroupViewController.m | 2 +- .../OWSConversationSettingsViewController.m | 3 +- .../UpdateGroupViewController.m | 2 +- Signal/src/views/AvatarTableViewCell.swift | 2 +- Signal/src/views/ContactCell.swift | 3 +- Signal/src/views/GroupTableViewCell.swift | 4 +- .../ViewModels/ContactShareViewModel.swift | 3 +- SignalMessaging/Views/AvatarImageView.swift | 2 +- SignalMessaging/Views/ContactCellView.h | 1 - SignalMessaging/Views/ContactCellView.m | 22 +- SignalMessaging/categories/UIView+OWS.h | 20 + SignalMessaging/utils/OWSAvatarBuilder.h | 8 +- SignalMessaging/utils/OWSAvatarBuilder.m | 47 +- .../utils/OWSContactAvatarBuilder.h | 9 +- .../utils/OWSContactAvatarBuilder.m | 33 +- SignalMessaging/utils/OWSGroupAvatarBuilder.h | 5 +- SignalMessaging/utils/OWSGroupAvatarBuilder.m | 65 +- 31 files changed, 161 insertions(+), 859 deletions(-) delete mode 100644 Signal/Images.xcassets/empty-group-avatar.imageset/empty-group-avatar.png delete mode 100644 Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json delete mode 100644 Signal/Images.xcassets/empty-group-avatar_old.imageset/group-avi.pdf rename Signal/Images.xcassets/{empty-group-avatar.imageset => group-avatar.imageset}/Contents.json (66%) create mode 100644 Signal/Images.xcassets/group-avatar.imageset/group-28-white@1x.png create mode 100644 Signal/Images.xcassets/group-avatar.imageset/group-28-white@2x.png create mode 100644 Signal/Images.xcassets/group-avatar.imageset/group-28-white@3x.png diff --git a/Signal/Images.xcassets/empty-group-avatar.imageset/empty-group-avatar.png b/Signal/Images.xcassets/empty-group-avatar.imageset/empty-group-avatar.png deleted file mode 100644 index c18015bbff8a97b9314842883c9d0914db671cbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12034 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 GzyE)o)_oQL diff --git a/Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json b/Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json deleted file mode 100644 index c8b0525d9..000000000 --- a/Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "group-avi.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Signal/Images.xcassets/empty-group-avatar_old.imageset/group-avi.pdf b/Signal/Images.xcassets/empty-group-avatar_old.imageset/group-avi.pdf deleted file mode 100644 index 1dda2be4d..000000000 --- a/Signal/Images.xcassets/empty-group-avatar_old.imageset/group-avi.pdf +++ /dev/null @@ -1,748 +0,0 @@ -%PDF-1.5 % -1 0 obj <> endobj 2 0 obj <>stream - - - - - application/pdf - - - group-avi - - - - - Adobe Illustrator CS6 (Macintosh) - 2015-02-17T04:15:09-05:00 - 2015-02-17T04:15:09-05:00 - 2015-02-17T04:15:09-05:00 - - - - 256 - 256 - JPEG - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUHqetaTpcXq6jdxWqH7PqMFLf6q9W+jLcWCeQ1EEtWXPDGLkQGFat+dHly2LLp8E1+46NT 0Yz/ALJgX/4TNrh7Eyy+oiP2/j5urzdt4o/SDL7Px8mJaj+dHmeckWcNvZp2IUyuPpc8f+FzZY+x MI+omX2Otydt5T9IEWP3fn7zld19XV7ha9fSb0f+TQTMyHZ+CPKA+/73Dn2hnlzmfu+5KZ9U1Oc1 nu5pT4vI7e3c5kxxQHIAfBxpZZnmT80LljB2KoqDVNTgNYLuaI+KSOvt2OVyxQPMA/BnHLMcifmm 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 uxV2Kv8A/9k= - - - - - - uuid:C1BCCE1871B8DB11993190FCD52B4E9F - xmp.did:5584665610206811822A93E3E51DFDF6 - uuid:eb7c3ca0-3c44-fd4a-95ad-623770cf2596 - proof:pdf - - uuid:6ea8efe9-b23e-1444-ac85-a5f9c9c8cb70 - xmp.did:0180117407206811822AE1909D884414 - uuid:C1BCCE1871B8DB11993190FCD52B4E9F - proof:pdf - - - - - saved - xmp.iid:5584665610206811822A93E3E51DFDF6 - 2015-02-17T04:14:24-05:00 - Adobe Illustrator CS6 (Macintosh) - / - - - - - - - EmbedByReference - - /Users/Tyler/code/Signal-iOS/Signal/Images.xcassets/empty-group-avatar.imageset/circGroup--empty.pdf - - - - - - - Mobile - - - 1 - False - False - - 53.000000 - 53.000000 - Points - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - White - RGB - PROCESS - 255 - 255 - 255 - - - Black - RGB - PROCESS - 0 - 0 - 0 - - - RGB Red - RGB - PROCESS - 255 - 0 - 0 - - - RGB Yellow - RGB - PROCESS - 255 - 255 - 0 - - - RGB Green - RGB - PROCESS - 0 - 255 - 0 - - - RGB Cyan - RGB - PROCESS - 0 - 255 - 255 - - - RGB Blue - RGB - PROCESS - 0 - 0 - 255 - - - RGB Magenta - RGB - PROCESS - 255 - 0 - 255 - - - R=193 G=39 B=45 - RGB - PROCESS - 193 - 39 - 45 - - - R=237 G=28 B=36 - RGB - PROCESS - 237 - 28 - 36 - - - R=241 G=90 B=36 - RGB - PROCESS - 241 - 90 - 36 - - - R=247 G=147 B=30 - RGB - PROCESS - 247 - 147 - 30 - - - R=251 G=176 B=59 - RGB - PROCESS - 251 - 176 - 59 - - - R=252 G=238 B=33 - RGB - PROCESS - 252 - 238 - 33 - - - R=217 G=224 B=33 - RGB - PROCESS - 217 - 224 - 33 - - - R=140 G=198 B=63 - RGB - PROCESS - 140 - 198 - 63 - - - R=57 G=181 B=74 - RGB - PROCESS - 57 - 181 - 74 - - - R=0 G=146 B=69 - RGB - PROCESS - 0 - 146 - 69 - - - R=0 G=104 B=55 - RGB - PROCESS - 0 - 104 - 55 - - - R=34 G=181 B=115 - RGB - PROCESS - 34 - 181 - 115 - - - R=0 G=169 B=157 - RGB - PROCESS - 0 - 169 - 157 - - - R=41 G=171 B=226 - RGB - PROCESS - 41 - 171 - 226 - - - R=0 G=113 B=188 - RGB - PROCESS - 0 - 113 - 188 - - - R=46 G=49 B=146 - RGB - PROCESS - 46 - 49 - 146 - - - R=27 G=20 B=100 - RGB - PROCESS - 27 - 20 - 100 - - - R=102 G=45 B=145 - RGB - PROCESS - 102 - 45 - 145 - - - R=147 G=39 B=143 - RGB - PROCESS - 147 - 39 - 143 - - - R=158 G=0 B=93 - RGB - PROCESS - 158 - 0 - 93 - - - R=212 G=20 B=90 - RGB - PROCESS - 212 - 20 - 90 - - - R=237 G=30 B=121 - RGB - PROCESS - 237 - 30 - 121 - - - R=199 G=178 B=153 - RGB - PROCESS - 199 - 178 - 153 - - - R=153 G=134 B=117 - RGB - PROCESS - 153 - 134 - 117 - - - R=115 G=99 B=87 - RGB - PROCESS - 115 - 99 - 87 - - - R=83 G=71 B=65 - RGB - PROCESS - 83 - 71 - 65 - - - R=198 G=156 B=109 - RGB - PROCESS - 198 - 156 - 109 - - - R=166 G=124 B=82 - RGB - PROCESS - 166 - 124 - 82 - - - R=140 G=98 B=57 - RGB - PROCESS - 140 - 98 - 57 - - - R=117 G=76 B=36 - RGB - PROCESS - 117 - 76 - 36 - - - R=96 G=56 B=19 - RGB - PROCESS - 96 - 56 - 19 - - - R=66 G=33 B=11 - RGB - PROCESS - 66 - 33 - 11 - - - - - - Grays - 1 - - - - R=0 G=0 B=0 - RGB - PROCESS - 0 - 0 - 0 - - - R=26 G=26 B=26 - RGB - PROCESS - 26 - 26 - 26 - - - R=51 G=51 B=51 - RGB - PROCESS - 51 - 51 - 51 - - - R=77 G=77 B=77 - RGB - PROCESS - 77 - 77 - 77 - - - R=102 G=102 B=102 - RGB - PROCESS - 102 - 102 - 102 - - - R=128 G=128 B=128 - RGB - PROCESS - 128 - 128 - 128 - - - R=153 G=153 B=153 - RGB - PROCESS - 153 - 153 - 153 - - - R=179 G=179 B=179 - RGB - PROCESS - 179 - 179 - 179 - - - R=204 G=204 B=204 - RGB - PROCESS - 204 - 204 - 204 - - - R=230 G=230 B=230 - RGB - PROCESS - 230 - 230 - 230 - - - R=242 G=242 B=242 - RGB - PROCESS - 242 - 242 - 242 - - - - - - Mobile Color Group - 1 - - - - R=136 G=168 B=13 - RGB - PROCESS - 136 - 168 - 13 - - - R=127 G=71 B=221 - RGB - PROCESS - 127 - 71 - 221 - - - R=251 G=174 B=23 - RGB - PROCESS - 251 - 174 - 23 - - - - - - - - - Adobe PDF library 10.01 - - - - - - - - - - - - - - - - - - - - - - - - - endstream endobj 3 0 obj <> endobj 5 0 obj <>/Properties<>/XObject<>>>/TrimBox[0.0 0.0 53.0 53.0]/Type/Page>> endobj 6 0 obj <>stream -H|Ur1+FHp" \G3=}ܕε^K==?wz [ޖ+ )N{9}z (?ME..Pxo.:01W*U3czΫ)댴yN`9׭x>hrHJq~%(|bkZ3Fub1GcSLp(zUGA#q*)HٔsC9pUY&_H,}45 4@ d 9JK)MLre(ـC]MjáՌyqȰI}r'F|"xzX8@r[dž<'liDŽnތ%vS*Gq´8W#M4kTW|֦B-j!P&|âuNQ'0jtMrSۺNsTgW2MVvV}ŰB`z@E'@qTa:!.c Sx5҄|ft*,]1 "QA6|GdR -lby+"@~m1R>টl<֬j,[Eg_ l=W򁛏q+OC endstream endobj 10 0 obj <>/XObject<>>>/Subtype/Form>>stream -q -0 0 53 53 re -W n -0.125 0.565 0.918 RG -0.5 w 10 M 0 j 0 J [3 2]0 d -/GS0 gs -q 1 0 0 1 26.5 0.5 cm -0 0 m -14.359 0 26 11.641 26 26 c -26 40.359 14.359 52 0 52 c --14.359 52 -26 40.359 -26 26 c --26 11.641 -14.359 0 0 0 c -h -S -Q -Q -q -29 36.5 m -30.266 33.971 30.399 32.707 v -30.399 32.707 l -30.549 31.285 29.623 29.463 29.651 27.578 c -29.651 27.578 l -29.683 25.482 32.753 22.308 32.821 20.518 c -32.821 20.518 l -32.911 18.182 32.5 16.5 y -32.5 16.5 l -38 17.5 l -38 36.5 l -h -W n -q -/GS0 gs -0 Tc 0 Tw 0 Ts 100 Tz 0 Tr /Fm0 Do -Q -Q -q -18.05 32.5 m -18.05 30.242 19.424 28.304 21.381 27.478 c -21.381 27.478 l -18.433 26.229 15.55 22.717 15.55 19.5 c -15.55 19.5 l -15.55 17.58 16.065 16.531 17.339 16.015 c -17.339 16.015 l -18.343 15.608 19.363 15.547 22.902 15.549 c -22.902 15.549 l -23.187 15.55 23.329 15.55 23.5 15.55 c -23.5 15.55 l -23.671 15.55 23.812 15.55 24.097 15.549 c -24.097 15.549 l -27.637 15.547 28.657 15.608 29.66 16.015 c -29.66 16.015 l -30.935 16.531 31.45 17.58 31.45 19.5 c -31.45 19.5 l -31.45 22.717 28.567 26.229 25.618 27.478 c -25.618 27.478 l -27.576 28.304 28.95 30.242 28.95 32.5 c -28.95 32.5 l -28.95 35.51 26.51 37.95 23.5 37.95 c -23.5 37.95 l -20.49 37.95 18.05 35.51 18.05 32.5 c -18.95 32.5 m -18.95 35.013 20.987 37.05 23.5 37.05 c -23.5 37.05 l -26.013 37.05 28.05 35.013 28.05 32.5 c -28.05 32.5 l -28.05 29.987 26.013 27.95 23.5 27.95 c -23.5 27.95 l -20.987 27.95 18.95 29.987 18.95 32.5 c -17.678 16.849 m -16.796 17.206 16.45 17.91 16.45 19.5 c -16.45 19.5 l -16.45 23.001 20.498 27.05 23.5 27.05 c -23.5 27.05 l -26.501 27.05 30.55 23.001 30.55 19.5 c -30.55 19.5 l -30.55 17.91 30.204 17.206 29.322 16.849 c -29.322 16.849 l -28.479 16.507 27.477 16.447 24.098 16.449 c -24.098 16.449 l -23.813 16.45 23.671 16.45 23.5 16.45 c -23.5 16.45 l -23.329 16.45 23.187 16.45 22.901 16.449 c -22.901 16.449 l -22.832 16.449 22.762 16.449 22.695 16.449 c -22.695 16.449 l -19.48 16.449 18.504 16.514 17.678 16.849 c -W n -0.125 0.565 0.918 rg -/GS0 gs -13.05 40.45 20.9 -27.4 re -f -Q - endstream endobj 11 0 obj <> endobj 12 0 obj <>>>/Subtype/Form>>stream -q -29 35.242 m -29 33.95 l -29.635 34.598 30.521 35 31.5 35 c -31.5 35 l -33.433 35 35 33.433 35 31.5 c -35 31.5 l -35 29.567 33.433 28 31.5 28 c -31.5 28 l -30.521 28 29.635 28.402 29 29.05 c -29 29.05 l -29 27.758 l -29.15 27.657 29.308 27.565 29.471 27.483 c -29.471 27.483 l -29.312 27.407 29.156 27.323 29 27.232 c -29 27.232 l -29 26.046 l -29.827 26.635 30.712 27 31.5 27 c -31.5 27 l -33.824 27 37 23.824 37 21.1 c -37 21.1 l -37 19.879 36.75 19.37 36.105 19.109 c -36.105 19.109 l -35.456 18.845 34.657 18.797 31.979 18.8 c -31.979 18.8 l -31.743 18.8 31.637 18.8 31.5 18.8 c -31.5 18.8 l -31.363 18.8 31.256 18.8 31.021 18.8 c -31.021 18.8 l -30.18 18.799 29.524 18.804 29 18.817 c -29 18.817 l -29 17.816 l -29.535 17.802 30.193 17.798 31.022 17.799 c -31.022 17.799 l -31.257 17.8 31.363 17.8 31.5 17.8 c -31.5 17.8 l -31.637 17.8 31.742 17.8 31.978 17.799 c -31.978 17.799 l -34.835 17.797 35.653 17.846 36.481 18.182 c -36.481 18.182 l -37.562 18.62 38 19.512 38 21.1 c -38 21.1 l -38 23.63 35.839 26.367 33.529 27.483 c -33.529 27.483 l -34.996 28.225 36 29.745 36 31.5 c -36 31.5 l -36 33.985 33.985 36 31.5 36 c -31.5 36 l -30.575 36 29.715 35.721 29 35.242 c -W n -0.125 0.565 0.918 rg -/GS0 gs -22.5 38.5 18 -23.2 re -f -Q - endstream endobj 13 0 obj <> endobj 7 0 obj <> endobj 9 0 obj <> endobj 8 0 obj <> endobj 14 0 obj <> endobj xref 0 15 0000000000 65535 f -0000000016 00000 n -0000000076 00000 n -0000046447 00000 n -0000000000 00000 f -0000046498 00000 n -0000046761 00000 n -0000051153 00000 n -0000051391 00000 n -0000051265 00000 n -0000047494 00000 n -0000049642 00000 n -0000049717 00000 n -0000051078 00000 n -0000051503 00000 n -trailer <]>> startxref 51691 %%EOF \ No newline at end of file diff --git a/Signal/Images.xcassets/empty-group-avatar.imageset/Contents.json b/Signal/Images.xcassets/group-avatar.imageset/Contents.json similarity index 66% rename from Signal/Images.xcassets/empty-group-avatar.imageset/Contents.json rename to Signal/Images.xcassets/group-avatar.imageset/Contents.json index 00c7b2c36..4c8a8ab98 100644 --- a/Signal/Images.xcassets/empty-group-avatar.imageset/Contents.json +++ b/Signal/Images.xcassets/group-avatar.imageset/Contents.json @@ -2,15 +2,17 @@ "images" : [ { "idiom" : "universal", - "filename" : "empty-group-avatar.png", + "filename" : "group-28-white@1x.png", "scale" : "1x" }, { "idiom" : "universal", + "filename" : "group-28-white@2x.png", "scale" : "2x" }, { "idiom" : "universal", + "filename" : "group-28-white@3x.png", "scale" : "3x" } ], diff --git a/Signal/Images.xcassets/group-avatar.imageset/group-28-white@1x.png b/Signal/Images.xcassets/group-avatar.imageset/group-28-white@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..55a8d0c674722a695cad25ddde88e31f1436fb97 GIT binary patch literal 1558 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 awb6fCxcSVzSM$$+T0x$!elF{r5}E+LKCpZM literal 0 HcmV?d00001 diff --git a/Signal/src/ViewControllers/AppSettings/BlockListViewController.m b/Signal/src/ViewControllers/AppSettings/BlockListViewController.m index ba8d4be58..5b18d3eb9 100644 --- a/Signal/src/ViewControllers/AppSettings/BlockListViewController.m +++ b/Signal/src/ViewControllers/AppSettings/BlockListViewController.m @@ -117,7 +117,7 @@ NS_ASSUME_NONNULL_BEGIN @"BLOCK_LIST_BLOCKED_GROUPS_SECTION", @"Section header for groups that have been blocked"); for (TSGroupModel *blockedGroup in blockedGroups) { - UIImage *image = blockedGroup.groupImage ?: OWSGroupAvatarBuilder.defaultGroupImage; + UIImage *image = blockedGroup.groupImage ?: OWSGroupAvatarBuilder.defaultGroupAvatarImage; NSString *groupName = blockedGroup.groupName.length > 0 ? blockedGroup.groupName : TSGroupThread.defaultGroupName; diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index ee77f706c..c9ca747f8 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -449,7 +449,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } func updateAvatarImage() { - contactAvatarView.image = OWSAvatarBuilder.buildImage(thread: thread, diameter: 400, contactsManager: contactsManager) + contactAvatarView.image = OWSAvatarBuilder.buildImage(thread: thread, diameter: 400) } func createIncomingCallControls() { diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m index e4f6c18ec..e380c4acd 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m @@ -164,7 +164,7 @@ NS_ASSUME_NONNULL_BEGIN + (CGFloat)iconSize { - return 48.f; + return kStandardAvatarSize; } - (CGFloat)iconSize diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m index de3294124..7a77d1647 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m @@ -77,7 +77,7 @@ NS_ASSUME_NONNULL_BEGIN + (CGFloat)iconSize { - return 48.f; + return kStandardAvatarSize; } - (CGFloat)iconSize diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m index 2be73de8e..7307e6ea0 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m @@ -82,7 +82,7 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)iconHeight { - return 48.f; + return kStandardAvatarSize; } - (void)createContentsWithConversationStyle:(ConversationStyle *)conversationStyle diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index 4296629bb..185349db6 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -262,18 +262,11 @@ NS_ASSUME_NONNULL_BEGIN return NO; } - OWSContactsManager *contactsManager = self.delegate.contactsManager; - if (contactsManager == nil) { - OWSFailDebug(@"contactsManager should not be nil"); - return NO; - } - TSIncomingMessage *incomingMessage = (TSIncomingMessage *)self.viewItem.interaction; UIImage *_Nullable authorAvatarImage = [[[OWSContactAvatarBuilder alloc] initWithSignalId:incomingMessage.authorId colorName:self.viewItem.authorConversationColorName - diameter:self.avatarSize - contactsManager:contactsManager] build]; + diameter:self.avatarSize] build]; self.avatarView.image = authorAvatarImage; [self.contentView addSubview:self.avatarView]; diff --git a/Signal/src/ViewControllers/HomeView/HomeViewCell.m b/Signal/src/ViewControllers/HomeView/HomeViewCell.m index c24cd37cb..a81163727 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewCell.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewCell.m @@ -334,9 +334,7 @@ NS_ASSUME_NONNULL_BEGIN return; } - self.avatarView.image = [OWSAvatarBuilder buildImageForThread:thread.threadRecord - diameter:self.avatarSize - contactsManager:contactsManager]; + self.avatarView.image = [OWSAvatarBuilder buildImageForThread:thread.threadRecord diameter:self.avatarSize]; } - (NSAttributedString *)attributedSnippetForThread:(ThreadViewModel *)thread isBlocked:(BOOL)isBlocked @@ -427,7 +425,7 @@ NS_ASSUME_NONNULL_BEGIN - (NSUInteger)avatarSize { - return 48.f; + return kStandardAvatarSize; } - (NSUInteger)avatarHSpacing diff --git a/Signal/src/ViewControllers/NewGroupViewController.m b/Signal/src/ViewControllers/NewGroupViewController.m index 59d352cf7..c0a6a4990 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.m +++ b/Signal/src/ViewControllers/NewGroupViewController.m @@ -529,7 +529,7 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; - (void)updateAvatarView { - self.avatarView.image = (self.groupAvatar ?: [UIImage imageNamed:@"empty-group-avatar"]); + self.avatarView.image = (self.groupAvatar ?: [OWSGroupAvatarBuilder defaultGroupAvatarImage]); } #pragma mark - Event Handling diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index bafb30ed5..f9759a59c 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -759,8 +759,7 @@ const CGFloat kIconViewLength = 24; [threadInfoView autoPinHeightToSuperviewWithMargin:16.f]; const NSUInteger kAvatarSize = 68; - UIImage *avatarImage = - [OWSAvatarBuilder buildImageForThread:self.thread diameter:kAvatarSize contactsManager:self.contactsManager]; + UIImage *avatarImage = [OWSAvatarBuilder buildImageForThread:self.thread diameter:kAvatarSize]; OWSAssertDebug(avatarImage); AvatarImageView *avatarView = [[AvatarImageView alloc] initWithImage:avatarImage]; diff --git a/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m b/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m index 0cdca4f3d..ed73e42e3 100644 --- a/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m @@ -397,7 +397,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateAvatarView { - self.avatarView.image = (self.groupAvatar ?: [UIImage imageNamed:@"empty-group-avatar"]); + self.avatarView.image = (self.groupAvatar ?: [OWSGroupAvatarBuilder defaultGroupAvatarImage]); } #pragma mark - Event Handling diff --git a/Signal/src/views/AvatarTableViewCell.swift b/Signal/src/views/AvatarTableViewCell.swift index e093a7501..18981bd16 100644 --- a/Signal/src/views/AvatarTableViewCell.swift +++ b/Signal/src/views/AvatarTableViewCell.swift @@ -28,7 +28,7 @@ public class AvatarTableViewCell: UITableViewCell { @objc public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { self.avatarView = AvatarImageView() - avatarView.autoSetDimensions(to: CGSize(width: CGFloat(kContactCellAvatarSize), height: CGFloat(kContactCellAvatarSize))) + avatarView.autoSetDimensions(to: CGSize(width: CGFloat(kStandardAvatarSize), height: CGFloat(kStandardAvatarSize))) self._textLabel = UILabel() self._detailTextLabel = UILabel() diff --git a/Signal/src/views/ContactCell.swift b/Signal/src/views/ContactCell.swift index a977a7c84..d738fb94d 100644 --- a/Signal/src/views/ContactCell.swift +++ b/Signal/src/views/ContactCell.swift @@ -96,8 +96,7 @@ class ContactCell: UITableViewCell { let avatarBuilder = OWSContactAvatarBuilder(nonSignalName: contact.fullName, colorSeed: contactIdForDeterminingBackgroundColor, - diameter: ContactCell.kAvatarDiameter, - contactsManager: contactsManager) + diameter: ContactCell.kAvatarDiameter) contactImageView.image = avatarBuilder.build() } diff --git a/Signal/src/views/GroupTableViewCell.swift b/Signal/src/views/GroupTableViewCell.swift index 656a1d5aa..810be8b34 100644 --- a/Signal/src/views/GroupTableViewCell.swift +++ b/Signal/src/views/GroupTableViewCell.swift @@ -22,7 +22,7 @@ import SignalServiceKit // Layout - avatarView.autoSetDimension(.width, toSize: CGFloat(kContactCellAvatarSize)) + avatarView.autoSetDimension(.width, toSize: CGFloat(kStandardAvatarSize)) avatarView.autoPinToSquareAspectRatio() let textRows = UIStackView(arrangedSubviews: [nameLabel, subtitleLabel]) @@ -58,7 +58,7 @@ import SignalServiceKit }.joined(separator: ", ") self.subtitleLabel.text = groupMemberNames - self.avatarView.image = OWSAvatarBuilder.buildImage(thread: thread, diameter: kContactCellAvatarSize, contactsManager: contactsManager) + self.avatarView.image = OWSAvatarBuilder.buildImage(thread: thread, diameter: kStandardAvatarSize) } } diff --git a/SignalMessaging/ViewModels/ContactShareViewModel.swift b/SignalMessaging/ViewModels/ContactShareViewModel.swift index e75f1720b..4397f0045 100644 --- a/SignalMessaging/ViewModels/ContactShareViewModel.swift +++ b/SignalMessaging/ViewModels/ContactShareViewModel.swift @@ -65,8 +65,7 @@ public class ContactShareViewModel: NSObject { let avatarBuilder = OWSContactAvatarBuilder(nonSignalName: displayName, colorSeed: colorSeed, - diameter: UInt(diameter), - contactsManager: contactsManager) + diameter: UInt(diameter)) // Note: we use buildDefaultImage() and not build() so that contact // share views always reflect the contents of the contact share. // build() might return an avatar from a corresponding system diff --git a/SignalMessaging/Views/AvatarImageView.swift b/SignalMessaging/Views/AvatarImageView.swift index 20ec9dc30..b2481f7ab 100644 --- a/SignalMessaging/Views/AvatarImageView.swift +++ b/SignalMessaging/Views/AvatarImageView.swift @@ -153,6 +153,6 @@ public class ConversationAvatarImageView: AvatarImageView { public func updateImage() { Logger.debug("updateImage") - self.image = OWSAvatarBuilder.buildImage(thread: thread, diameter: diameter, contactsManager: contactsManager) + self.image = OWSAvatarBuilder.buildImage(thread: thread, diameter: diameter) } } diff --git a/SignalMessaging/Views/ContactCellView.h b/SignalMessaging/Views/ContactCellView.h index 86ede9d9b..08e9fdef1 100644 --- a/SignalMessaging/Views/ContactCellView.h +++ b/SignalMessaging/Views/ContactCellView.h @@ -4,7 +4,6 @@ NS_ASSUME_NONNULL_BEGIN -extern const NSUInteger kContactCellAvatarSize; extern const CGFloat kContactCellAvatarTextMargin; @class OWSContactsManager; diff --git a/SignalMessaging/Views/ContactCellView.m b/SignalMessaging/Views/ContactCellView.m index 86e4fcc89..6e44c049b 100644 --- a/SignalMessaging/Views/ContactCellView.m +++ b/SignalMessaging/Views/ContactCellView.m @@ -15,7 +15,6 @@ NS_ASSUME_NONNULL_BEGIN -const NSUInteger kContactCellAvatarSize = 48; const CGFloat kContactCellAvatarTextMargin = 12; @interface ContactCellView () @@ -53,8 +52,8 @@ const CGFloat kContactCellAvatarTextMargin = 12; self.layoutMargins = UIEdgeInsetsZero; _avatarView = [AvatarImageView new]; - [_avatarView autoSetDimension:ALDimensionWidth toSize:kContactCellAvatarSize]; - [_avatarView autoSetDimension:ALDimensionHeight toSize:kContactCellAvatarSize]; + [_avatarView autoSetDimension:ALDimensionWidth toSize:kStandardAvatarSize]; + [_avatarView autoSetDimension:ALDimensionHeight toSize:kStandardAvatarSize]; self.nameLabel = [UILabel new]; self.nameLabel.lineBreakMode = NSLineBreakByTruncatingTail; @@ -164,8 +163,7 @@ const CGFloat kContactCellAvatarTextMargin = 12; object:nil]; [self updateProfileName]; } - self.avatarView.image = - [OWSAvatarBuilder buildImageForThread:thread diameter:kContactCellAvatarSize contactsManager:contactsManager]; + self.avatarView.image = [OWSAvatarBuilder buildImageForThread:thread diameter:kStandardAvatarSize]; if (self.accessoryMessage) { self.accessoryLabel.text = self.accessoryMessage; @@ -178,13 +176,6 @@ const CGFloat kContactCellAvatarTextMargin = 12; - (void)updateAvatar { - OWSContactsManager *contactsManager = self.contactsManager; - if (contactsManager == nil) { - OWSFailDebug(@"contactsManager should not be nil"); - self.avatarView.image = nil; - return; - } - NSString *recipientId = self.recipientId; if (recipientId.length == 0) { OWSFailDebug(@"recipientId should not be nil"); @@ -201,10 +192,9 @@ const CGFloat kContactCellAvatarTextMargin = 12; } }(); - self.avatarView.image = [[[OWSContactAvatarBuilder alloc] initWithSignalId:recipientId - colorName:colorName - diameter:kContactCellAvatarSize - contactsManager:contactsManager] build]; + self.avatarView.image = + [[[OWSContactAvatarBuilder alloc] initWithSignalId:recipientId colorName:colorName diameter:kStandardAvatarSize] + build]; } - (void)updateProfileName diff --git a/SignalMessaging/categories/UIView+OWS.h b/SignalMessaging/categories/UIView+OWS.h index 31b501f31..3e1de19c2 100644 --- a/SignalMessaging/categories/UIView+OWS.h +++ b/SignalMessaging/categories/UIView+OWS.h @@ -173,6 +173,26 @@ CG_INLINE CGSize CGSizeMax(CGSize size1, CGSize size2) return CGSizeMake(MAX(size1.width, size2.width), MAX(size1.height, size2.height)); } +CG_INLINE CGPoint CGPointAdd(CGPoint left, CGPoint right) +{ + return CGPointMake(left.x + right.x, left.y + right.y); +} + +CG_INLINE CGPoint CGPointSubtract(CGPoint left, CGPoint right) +{ + return CGPointMake(left.x - right.x, left.y - right.y); +} + +CG_INLINE CGPoint CGPointScale(CGPoint point, CGFloat factor) +{ + return CGPointMake(point.x * factor, point.y * factor); +} + +CG_INLINE CGSize CGSizeScale(CGSize size, CGFloat factor) +{ + return CGSizeMake(size.width * factor, size.height * factor); +} + CGFloat CGHairlineWidth(void); NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/utils/OWSAvatarBuilder.h b/SignalMessaging/utils/OWSAvatarBuilder.h index ec3003730..36926c423 100644 --- a/SignalMessaging/utils/OWSAvatarBuilder.h +++ b/SignalMessaging/utils/OWSAvatarBuilder.h @@ -4,16 +4,15 @@ NS_ASSUME_NONNULL_BEGIN -@class OWSContactsManager; +extern const NSUInteger kStandardAvatarSize; + @class TSThread; @class UIImage; @interface OWSAvatarBuilder : NSObject + (nullable UIImage *)buildImageForThread:(TSThread *)thread - diameter:(NSUInteger)diameter - contactsManager:(OWSContactsManager *)contactsManager - NS_SWIFT_NAME(buildImage(thread:diameter:contactsManager:)); + diameter:(NSUInteger)diameter NS_SWIFT_NAME(buildImage(thread:diameter:)); + (nullable UIImage *)buildRandomAvatarWithDiameter:(NSUInteger)diameter; @@ -26,6 +25,7 @@ NS_ASSUME_NONNULL_BEGIN diameter:(NSUInteger)diameter; + (nullable UIImage *)avatarImageWithIcon:(UIImage *)icon + iconSize:(CGSize)iconSize backgroundColor:(UIColor *)backgroundColor diameter:(NSUInteger)diameter; diff --git a/SignalMessaging/utils/OWSAvatarBuilder.m b/SignalMessaging/utils/OWSAvatarBuilder.m index 3d66671b4..3082012bf 100644 --- a/SignalMessaging/utils/OWSAvatarBuilder.m +++ b/SignalMessaging/utils/OWSAvatarBuilder.m @@ -9,19 +9,20 @@ #import "TSGroupThread.h" #import "UIColor+OWS.h" #import "UIFont+OWS.h" +#import "UIView+OWS.h" NS_ASSUME_NONNULL_BEGIN +const NSUInteger kStandardAvatarSize = 48; + typedef void (^OWSAvatarDrawBlock)(CGContextRef context); @implementation OWSAvatarBuilder + (nullable UIImage *)buildImageForThread:(TSThread *)thread diameter:(NSUInteger)diameter - contactsManager:(OWSContactsManager *)contactsManager { OWSAssertDebug(thread); - OWSAssertDebug(contactsManager); OWSAvatarBuilder *avatarBuilder; if ([thread isKindOfClass:[TSContactThread class]]) { @@ -29,10 +30,9 @@ typedef void (^OWSAvatarDrawBlock)(CGContextRef context); NSString *colorName = thread.conversationColorName; avatarBuilder = [[OWSContactAvatarBuilder alloc] initWithSignalId:contactThread.contactIdentifier colorName:colorName - diameter:diameter - contactsManager:contactsManager]; + diameter:diameter]; } else if ([thread isKindOfClass:[TSGroupThread class]]) { - avatarBuilder = [[OWSGroupAvatarBuilder alloc] initWithThread:(TSGroupThread *)thread]; + avatarBuilder = [[OWSGroupAvatarBuilder alloc] initWithThread:(TSGroupThread *)thread diameter:diameter]; } else { OWSLogError(@"called with unsupported thread: %@", thread); } @@ -106,16 +106,19 @@ typedef void (^OWSAvatarDrawBlock)(CGContextRef context); } + (nullable UIImage *)avatarImageWithIcon:(UIImage *)icon + iconSize:(CGSize)iconSize backgroundColor:(UIColor *)backgroundColor diameter:(NSUInteger)diameter { return [self avatarImageWithIcon:icon + iconSize:iconSize iconColor:self.avatarForegroundColor backgroundColor:backgroundColor diameter:diameter]; } + (nullable UIImage *)avatarImageWithIcon:(UIImage *)icon + iconSize:(CGSize)iconSize iconColor:(UIColor *)iconColor backgroundColor:(UIColor *)backgroundColor diameter:(NSUInteger)diameter @@ -126,7 +129,11 @@ typedef void (^OWSAvatarDrawBlock)(CGContextRef context); return [self avatarImageWithDiameter:diameter backgroundColor:backgroundColor drawBlock:^(CGContextRef context) { - [self drawIconInAvatar:icon iconColor:iconColor diameter:diameter]; + [self drawIconInAvatar:icon + iconSize:iconSize + iconColor:iconColor + diameter:diameter + context:context]; }]; } @@ -230,14 +237,34 @@ typedef void (^OWSAvatarDrawBlock)(CGContextRef context); [initials drawAtPoint:drawPoint withAttributes:textAttributes]; } -+ (void)drawIconInAvatar:(UIImage *)icon iconColor:(UIColor *)iconColor diameter:(NSUInteger)diameter ++ (void)drawIconInAvatar:(UIImage *)icon + iconSize:(CGSize)iconSize + iconColor:(UIColor *)iconColor + diameter:(NSUInteger)diameter + context:(CGContextRef)context { OWSAssertDebug(icon); OWSAssertDebug(iconColor); OWSAssertDebug(diameter > 0); - - CGPoint drawPoint = CGPointMake((diameter - icon.size.width) * 0.5f, (diameter - icon.size.height) * 0.5f); - [icon drawAtPoint:drawPoint]; + OWSAssertDebug(context); + + // UIKit uses an ULO coordinate system (upper-left-origin). + // Core Graphics uses an LLO coordinate system (lower-left-origin). + CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, diameter); + CGContextConcatCTM(context, flipVertical); + + CGRect imageRect = CGRectZero; + imageRect.size = CGSizeMake(diameter, diameter); + + // The programmatic equivalent of UIImageRenderingModeAlwaysTemplate/tintColor. + CGContextSetBlendMode(context, kCGBlendModeNormal); + CGRect maskRect = CGRectZero; + maskRect.origin = CGPointScale( + CGPointSubtract(CGPointMake(diameter, diameter), CGPointMake(iconSize.width, iconSize.height)), 0.5f); + maskRect.size = iconSize; + CGContextClipToMask(context, maskRect, icon.CGImage); + CGContextSetFillColor(context, CGColorGetComponents(iconColor.CGColor)); + CGContextFillRect(context, imageRect); } - (nullable UIImage *)build diff --git a/SignalMessaging/utils/OWSContactAvatarBuilder.h b/SignalMessaging/utils/OWSContactAvatarBuilder.h index 12bf6b61c..fa621f21a 100644 --- a/SignalMessaging/utils/OWSContactAvatarBuilder.h +++ b/SignalMessaging/utils/OWSContactAvatarBuilder.h @@ -6,7 +6,6 @@ NS_ASSUME_NONNULL_BEGIN -@class OWSContactsManager; @class TSContactThread; @interface OWSContactAvatarBuilder : OWSAvatarBuilder @@ -15,18 +14,14 @@ NS_ASSUME_NONNULL_BEGIN * Build an avatar for a Signal recipient */ -- (instancetype)initWithSignalId:(NSString *)signalId - colorName:(NSString *)colorName - diameter:(NSUInteger)diameter - contactsManager:(OWSContactsManager *)contactsManager; +- (instancetype)initWithSignalId:(NSString *)signalId colorName:(NSString *)colorName diameter:(NSUInteger)diameter; /** * Build an avatar for a non-Signal recipient */ - (instancetype)initWithNonSignalName:(NSString *)nonSignalName colorSeed:(NSString *)colorSeed - diameter:(NSUInteger)diameter - contactsManager:(OWSContactsManager *)contactsManager; + diameter:(NSUInteger)diameter; @end diff --git a/SignalMessaging/utils/OWSContactAvatarBuilder.m b/SignalMessaging/utils/OWSContactAvatarBuilder.m index a440fd12d..cb80d9f0b 100644 --- a/SignalMessaging/utils/OWSContactAvatarBuilder.m +++ b/SignalMessaging/utils/OWSContactAvatarBuilder.m @@ -10,12 +10,12 @@ #import "UIColor+OWS.h" #import "UIFont+OWS.h" #import +#import NS_ASSUME_NONNULL_BEGIN @interface OWSContactAvatarBuilder () -@property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) NSString *signalId; @property (nonatomic, readonly) NSString *contactName; @property (nonatomic, readonly) NSString *colorName; @@ -31,7 +31,6 @@ NS_ASSUME_NONNULL_BEGIN name:(NSString *)name colorName:(NSString *)colorName diameter:(NSUInteger)diameter - contactsManager:(OWSContactsManager *)contactsManager { self = [super init]; if (!self) { @@ -44,7 +43,6 @@ NS_ASSUME_NONNULL_BEGIN _contactName = name; _colorName = colorName; _diameter = diameter; - _contactsManager = contactsManager; return self; } @@ -52,42 +50,37 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithSignalId:(NSString *)signalId colorName:(NSString *)colorName diameter:(NSUInteger)diameter - contactsManager:(OWSContactsManager *)contactsManager { // Name for avatar initials. - NSString *_Nullable name = [contactsManager nameFromSystemContactsForRecipientId:signalId]; + NSString *_Nullable name = [OWSContactAvatarBuilder.contactsManager nameFromSystemContactsForRecipientId:signalId]; if (name.length == 0) { - name = [contactsManager profileNameForRecipientId:signalId]; + name = [OWSContactAvatarBuilder.contactsManager profileNameForRecipientId:signalId]; } if (name.length == 0) { name = signalId; } - return [self initWithContactId:signalId - name:name - colorName:colorName - diameter:diameter - contactsManager:contactsManager]; + return [self initWithContactId:signalId name:name colorName:colorName diameter:diameter]; } - (instancetype)initWithNonSignalName:(NSString *)nonSignalName colorSeed:(NSString *)colorSeed diameter:(NSUInteger)diameter - contactsManager:(OWSContactsManager *)contactsManager { NSString *colorName = [TSThread stableConversationColorNameForString:colorSeed]; - return [self initWithContactId:colorSeed - name:nonSignalName - colorName:(NSString *)colorName - diameter:diameter - contactsManager:contactsManager]; + return [self initWithContactId:colorSeed name:nonSignalName colorName:(NSString *)colorName diameter:diameter]; +} + ++ (OWSContactsManager *)contactsManager +{ + return (OWSContactsManager *)SSKEnvironment.shared.contactsManager; } #pragma mark - Instance methods - (nullable UIImage *)buildSavedImage { - return [self.contactsManager imageForPhoneIdentifier:self.signalId]; + return [OWSContactAvatarBuilder.contactsManager imageForPhoneIdentifier:self.signalId]; } - (id)cacheKey @@ -98,7 +91,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable UIImage *)buildDefaultImage { UIImage *cachedAvatar = - [self.contactsManager.avatarCache imageForKey:self.cacheKey diameter:(CGFloat)self.diameter]; + [OWSContactAvatarBuilder.contactsManager.avatarCache imageForKey:self.cacheKey diameter:(CGFloat)self.diameter]; if (cachedAvatar) { return cachedAvatar; } @@ -139,7 +132,7 @@ NS_ASSUME_NONNULL_BEGIN return nil; } - [self.contactsManager.avatarCache setImage:image forKey:self.cacheKey diameter:self.diameter]; + [OWSContactAvatarBuilder.contactsManager.avatarCache setImage:image forKey:self.cacheKey diameter:self.diameter]; return image; } diff --git a/SignalMessaging/utils/OWSGroupAvatarBuilder.h b/SignalMessaging/utils/OWSGroupAvatarBuilder.h index 36a9eeebb..19e3f3143 100644 --- a/SignalMessaging/utils/OWSGroupAvatarBuilder.h +++ b/SignalMessaging/utils/OWSGroupAvatarBuilder.h @@ -10,8 +10,9 @@ NS_ASSUME_NONNULL_BEGIN @interface OWSGroupAvatarBuilder : OWSAvatarBuilder -- (instancetype)initWithThread:(TSGroupThread *)thread; -+ (UIImage *)defaultGroupImage; +- (instancetype)initWithThread:(TSGroupThread *)thread diameter:(NSUInteger)diameter; + ++ (nullable UIImage *)defaultGroupAvatarImage; @end diff --git a/SignalMessaging/utils/OWSGroupAvatarBuilder.m b/SignalMessaging/utils/OWSGroupAvatarBuilder.m index 30fd02bdc..e48dcb9a4 100644 --- a/SignalMessaging/utils/OWSGroupAvatarBuilder.m +++ b/SignalMessaging/utils/OWSGroupAvatarBuilder.m @@ -3,19 +3,24 @@ // #import "OWSGroupAvatarBuilder.h" +#import "OWSContactsManager.h" #import "TSGroupThread.h" +#import "UIColor+OWS.h" +#import +#import NS_ASSUME_NONNULL_BEGIN @interface OWSGroupAvatarBuilder () @property (nonatomic, readonly) TSGroupThread *thread; +@property (nonatomic, readonly) NSUInteger diameter; @end @implementation OWSGroupAvatarBuilder -- (instancetype)initWithThread:(TSGroupThread *)thread +- (instancetype)initWithThread:(TSGroupThread *)thread diameter:(NSUInteger)diameter { self = [super init]; if (!self) { @@ -23,6 +28,7 @@ NS_ASSUME_NONNULL_BEGIN } _thread = thread; + _diameter = diameter; return self; } @@ -32,19 +38,60 @@ NS_ASSUME_NONNULL_BEGIN return self.thread.groupModel.groupImage; } ++ (OWSContactsManager *)contactsManager +{ + return (OWSContactsManager *)SSKEnvironment.shared.contactsManager; +} + - (nullable UIImage *)buildDefaultImage { - return self.class.defaultGroupImage; + NSString *cacheKey = self.thread.uniqueId; + + UIImage *cachedAvatar = + [OWSGroupAvatarBuilder.contactsManager.avatarCache imageForKey:cacheKey diameter:(CGFloat)self.diameter]; + if (cachedAvatar) { + return cachedAvatar; + } + + UIColor *backgroundColor = + [UIColor ows_conversationColorForColorName:self.thread.conversationColorName isShaded:Theme.isDarkThemeEnabled]; + UIImage *_Nullable image = + [OWSGroupAvatarBuilder groupAvatarImageWithBackgroundColor:backgroundColor diameter:self.diameter]; + if (!image) { + return nil; + } + + [OWSGroupAvatarBuilder.contactsManager.avatarCache setImage:image forKey:cacheKey diameter:self.diameter]; + return image; +} + ++ (nullable UIImage *)defaultGroupAvatarImage +{ + NSUInteger diameter = 200; + NSString *cacheKey = @"default-group-avatar"; + + UIImage *cachedAvatar = [self.contactsManager.avatarCache imageForKey:cacheKey diameter:(CGFloat)diameter]; + if (cachedAvatar) { + return cachedAvatar; + } + + // TODO: Verify with Myles. + UIColor *backgroundColor = UIColor.ows_signalBlueColor; + UIImage *_Nullable image = [self groupAvatarImageWithBackgroundColor:backgroundColor diameter:diameter]; + if (!image) { + return nil; + } + + [self.contactsManager.avatarCache setImage:image forKey:cacheKey diameter:diameter]; + return image; } -+ (UIImage *)defaultGroupImage ++ (nullable UIImage *)groupAvatarImageWithBackgroundColor:(UIColor *)backgroundColor diameter:(NSUInteger)diameter { - static UIImage *defaultGroupImage; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - defaultGroupImage = [UIImage imageNamed:@"empty-group-avatar"]; - }); - return defaultGroupImage; + UIImage *icon = [UIImage imageNamed:@"group-avatar"]; + CGSize iconSize = CGSizeScale(icon.size, diameter / kStandardAvatarSize); + return + [OWSAvatarBuilder avatarImageWithIcon:icon iconSize:iconSize backgroundColor:backgroundColor diameter:diameter]; } @end From 1c920c6be6f1d4da8ae8dc3d56e7d58dc7fe0352 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 26 Sep 2018 11:13:13 -0400 Subject: [PATCH 2/4] Rework group avatars to reflect conversation colors. --- SignalMessaging/utils/OWSGroupAvatarBuilder.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SignalMessaging/utils/OWSGroupAvatarBuilder.m b/SignalMessaging/utils/OWSGroupAvatarBuilder.m index e48dcb9a4..ecf497d75 100644 --- a/SignalMessaging/utils/OWSGroupAvatarBuilder.m +++ b/SignalMessaging/utils/OWSGroupAvatarBuilder.m @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable UIImage *)buildDefaultImage { - NSString *cacheKey = self.thread.uniqueId; + NSString *cacheKey = [NSString stringWithFormat:@"%@-%d", self.thread.uniqueId, Theme.isDarkThemeEnabled]; UIImage *cachedAvatar = [OWSGroupAvatarBuilder.contactsManager.avatarCache imageForKey:cacheKey diameter:(CGFloat)self.diameter]; @@ -68,7 +68,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable UIImage *)defaultGroupAvatarImage { NSUInteger diameter = 200; - NSString *cacheKey = @"default-group-avatar"; + NSString *cacheKey = [NSString stringWithFormat:@"default-group-avatar-%d", Theme.isDarkThemeEnabled]; UIImage *cachedAvatar = [self.contactsManager.avatarCache imageForKey:cacheKey diameter:(CGFloat)diameter]; if (cachedAvatar) { From 8db4595bdcdf5c74f86945c1c00b44bb92229c2f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 26 Sep 2018 12:02:17 -0400 Subject: [PATCH 3/4] Rework group avatars to reflect conversation colors. --- .../AppSettings/AppSettingsViewController.m | 5 +-- .../AppSettings/BlockListViewController.m | 9 +++- .../ViewControllers/NewGroupViewController.m | 25 ++++++++--- .../OWSConversationSettingsViewController.m | 7 ++- .../UpdateGroupViewController.m | 11 +++-- SignalMessaging/utils/OWSAvatarBuilder.h | 1 + SignalMessaging/utils/OWSAvatarBuilder.m | 1 + .../utils/OWSContactAvatarBuilder.m | 2 +- SignalMessaging/utils/OWSGroupAvatarBuilder.h | 4 +- SignalMessaging/utils/OWSGroupAvatarBuilder.m | 45 ++++++++----------- .../src/Contacts/Threads/TSGroupThread.h | 2 + .../src/Contacts/Threads/TSGroupThread.m | 7 +++ 12 files changed, 71 insertions(+), 48 deletions(-) diff --git a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m index b9698efe9..40d8b7631 100644 --- a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m @@ -280,7 +280,6 @@ cell.contentView.preservesSuperviewLayoutMargins = YES; cell.selectionStyle = UITableViewCellSelectionStyleNone; - const NSUInteger kAvatarSize = 68; // TODO: Replace this icon. UIImage *_Nullable localProfileAvatarImage = [OWSProfileManager.sharedManager localProfileAvatarImage]; UIImage *avatarImage = (localProfileAvatarImage @@ -295,8 +294,8 @@ [cell.contentView addSubview:avatarView]; [avatarView autoVCenterInSuperview]; [avatarView autoPinLeadingToSuperviewMargin]; - [avatarView autoSetDimension:ALDimensionWidth toSize:kAvatarSize]; - [avatarView autoSetDimension:ALDimensionHeight toSize:kAvatarSize]; + [avatarView autoSetDimension:ALDimensionWidth toSize:kLargeAvatarSize]; + [avatarView autoSetDimension:ALDimensionHeight toSize:kLargeAvatarSize]; if (!localProfileAvatarImage) { UIImage *cameraImage = [UIImage imageNamed:@"settings-avatar-camera"]; diff --git a/Signal/src/ViewControllers/AppSettings/BlockListViewController.m b/Signal/src/ViewControllers/AppSettings/BlockListViewController.m index 5b18d3eb9..601276b87 100644 --- a/Signal/src/ViewControllers/AppSettings/BlockListViewController.m +++ b/Signal/src/ViewControllers/AppSettings/BlockListViewController.m @@ -117,7 +117,14 @@ NS_ASSUME_NONNULL_BEGIN @"BLOCK_LIST_BLOCKED_GROUPS_SECTION", @"Section header for groups that have been blocked"); for (TSGroupModel *blockedGroup in blockedGroups) { - UIImage *image = blockedGroup.groupImage ?: OWSGroupAvatarBuilder.defaultGroupAvatarImage; + UIImage *_Nullable image = blockedGroup.groupImage; + if (!image) { + NSString *conversationColorName = + [TSGroupThread defaultConversationColorNameForGroupId:blockedGroup.groupId]; + image = [OWSGroupAvatarBuilder defaultAvatarForGroupId:blockedGroup.groupId + conversationColorName:conversationColorName + diameter:kStandardAvatarSize]; + } NSString *groupName = blockedGroup.groupName.length > 0 ? blockedGroup.groupName : TSGroupThread.defaultGroupName; diff --git a/Signal/src/ViewControllers/NewGroupViewController.m b/Signal/src/ViewControllers/NewGroupViewController.m index c0a6a4990..ca3a7c22a 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.m +++ b/Signal/src/ViewControllers/NewGroupViewController.m @@ -29,8 +29,6 @@ NS_ASSUME_NONNULL_BEGIN -const NSUInteger kNewGroupViewControllerAvatarWidth = 68; - @interface NewGroupViewController () *memberRecipientIds; @@ -86,6 +86,8 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; - (void)commonInit { + self.groupId = [Randomness generateRandomBytes:16]; + _messageSender = SSKEnvironment.shared.messageSender; _contactsViewHelper = [[ContactsViewHelper alloc] initWithDelegate:self]; _avatarViewHelper = [AvatarViewHelper new]; @@ -151,8 +153,8 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; [threadInfoView addSubview:avatarView]; [avatarView autoVCenterInSuperview]; [avatarView autoPinLeadingToSuperviewMargin]; - [avatarView autoSetDimension:ALDimensionWidth toSize:kNewGroupViewControllerAvatarWidth]; - [avatarView autoSetDimension:ALDimensionHeight toSize:kNewGroupViewControllerAvatarWidth]; + [avatarView autoSetDimension:ALDimensionWidth toSize:kLargeAvatarSize]; + [avatarView autoSetDimension:ALDimensionHeight toSize:kLargeAvatarSize]; [self updateAvatarView]; UITextField *groupNameTextField = [OWSTextField new]; @@ -505,8 +507,10 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; NSString *groupName = [self.groupNameTextField.text ows_stripped]; NSMutableArray *recipientIds = [self.memberRecipientIds.allObjects mutableCopy]; [recipientIds addObject:[self.contactsViewHelper localNumber]]; - NSData *groupId = [Randomness generateRandomBytes:16]; - return [[TSGroupModel alloc] initWithTitle:groupName memberIds:recipientIds image:self.groupAvatar groupId:groupId]; + return [[TSGroupModel alloc] initWithTitle:groupName + memberIds:recipientIds + image:self.groupAvatar + groupId:self.groupId]; } #pragma mark - Group Avatar @@ -529,7 +533,14 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; - (void)updateAvatarView { - self.avatarView.image = (self.groupAvatar ?: [OWSGroupAvatarBuilder defaultGroupAvatarImage]); + UIImage *_Nullable groupAvatar = self.groupAvatar; + if (!groupAvatar) { + NSString *conversationColorName = [TSGroupThread defaultConversationColorNameForGroupId:self.groupId]; + groupAvatar = [OWSGroupAvatarBuilder defaultAvatarForGroupId:self.groupId + conversationColorName:conversationColorName + diameter:kLargeAvatarSize]; + } + self.avatarView.image = groupAvatar; } #pragma mark - Event Handling diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index f9759a59c..2715b0dd0 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -758,8 +758,7 @@ const CGFloat kIconViewLength = 24; [threadInfoView autoPinWidthToSuperviewWithMargin:16.f]; [threadInfoView autoPinHeightToSuperviewWithMargin:16.f]; - const NSUInteger kAvatarSize = 68; - UIImage *avatarImage = [OWSAvatarBuilder buildImageForThread:self.thread diameter:kAvatarSize]; + UIImage *avatarImage = [OWSAvatarBuilder buildImageForThread:self.thread diameter:kLargeAvatarSize]; OWSAssertDebug(avatarImage); AvatarImageView *avatarView = [[AvatarImageView alloc] initWithImage:avatarImage]; @@ -767,8 +766,8 @@ const CGFloat kIconViewLength = 24; [threadInfoView addSubview:avatarView]; [avatarView autoVCenterInSuperview]; [avatarView autoPinLeadingToSuperviewMargin]; - [avatarView autoSetDimension:ALDimensionWidth toSize:kAvatarSize]; - [avatarView autoSetDimension:ALDimensionHeight toSize:kAvatarSize]; + [avatarView autoSetDimension:ALDimensionWidth toSize:kLargeAvatarSize]; + [avatarView autoSetDimension:ALDimensionHeight toSize:kLargeAvatarSize]; UIView *threadNameView = [UIView containerView]; [threadInfoView addSubview:threadNameView]; diff --git a/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m b/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m index ed73e42e3..00923f0f3 100644 --- a/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/UpdateGroupViewController.m @@ -179,15 +179,14 @@ NS_ASSUME_NONNULL_BEGIN [threadInfoView autoPinWidthToSuperviewWithMargin:16.f]; [threadInfoView autoPinHeightToSuperviewWithMargin:16.f]; - const CGFloat kAvatarSize = 68.f; AvatarImageView *avatarView = [AvatarImageView new]; _avatarView = avatarView; [threadInfoView addSubview:avatarView]; [avatarView autoVCenterInSuperview]; [avatarView autoPinLeadingToSuperviewMargin]; - [avatarView autoSetDimension:ALDimensionWidth toSize:kAvatarSize]; - [avatarView autoSetDimension:ALDimensionHeight toSize:kAvatarSize]; + [avatarView autoSetDimension:ALDimensionWidth toSize:kLargeAvatarSize]; + [avatarView autoSetDimension:ALDimensionHeight toSize:kLargeAvatarSize]; _groupAvatar = self.thread.groupModel.groupImage; [self updateAvatarView]; @@ -397,7 +396,11 @@ NS_ASSUME_NONNULL_BEGIN - (void)updateAvatarView { - self.avatarView.image = (self.groupAvatar ?: [OWSGroupAvatarBuilder defaultGroupAvatarImage]); + UIImage *_Nullable groupAvatar = self.groupAvatar; + if (!groupAvatar) { + groupAvatar = [[[OWSGroupAvatarBuilder alloc] initWithThread:self.thread diameter:kLargeAvatarSize] build]; + } + self.avatarView.image = groupAvatar; } #pragma mark - Event Handling diff --git a/SignalMessaging/utils/OWSAvatarBuilder.h b/SignalMessaging/utils/OWSAvatarBuilder.h index 36926c423..81e7bd785 100644 --- a/SignalMessaging/utils/OWSAvatarBuilder.h +++ b/SignalMessaging/utils/OWSAvatarBuilder.h @@ -5,6 +5,7 @@ NS_ASSUME_NONNULL_BEGIN extern const NSUInteger kStandardAvatarSize; +extern const NSUInteger kLargeAvatarSize; @class TSThread; @class UIImage; diff --git a/SignalMessaging/utils/OWSAvatarBuilder.m b/SignalMessaging/utils/OWSAvatarBuilder.m index 3082012bf..2e597948a 100644 --- a/SignalMessaging/utils/OWSAvatarBuilder.m +++ b/SignalMessaging/utils/OWSAvatarBuilder.m @@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN const NSUInteger kStandardAvatarSize = 48; +const NSUInteger kLargeAvatarSize = 68; typedef void (^OWSAvatarDrawBlock)(CGContextRef context); diff --git a/SignalMessaging/utils/OWSContactAvatarBuilder.m b/SignalMessaging/utils/OWSContactAvatarBuilder.m index cb80d9f0b..b59d6d3a3 100644 --- a/SignalMessaging/utils/OWSContactAvatarBuilder.m +++ b/SignalMessaging/utils/OWSContactAvatarBuilder.m @@ -90,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable UIImage *)buildDefaultImage { - UIImage *cachedAvatar = + UIImage *_Nullable cachedAvatar = [OWSContactAvatarBuilder.contactsManager.avatarCache imageForKey:self.cacheKey diameter:(CGFloat)self.diameter]; if (cachedAvatar) { return cachedAvatar; diff --git a/SignalMessaging/utils/OWSGroupAvatarBuilder.h b/SignalMessaging/utils/OWSGroupAvatarBuilder.h index 19e3f3143..2662310e0 100644 --- a/SignalMessaging/utils/OWSGroupAvatarBuilder.h +++ b/SignalMessaging/utils/OWSGroupAvatarBuilder.h @@ -12,7 +12,9 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithThread:(TSGroupThread *)thread diameter:(NSUInteger)diameter; -+ (nullable UIImage *)defaultGroupAvatarImage; ++ (nullable UIImage *)defaultAvatarForGroupId:(NSData *)groupId + conversationColorName:(NSString *)conversationColorName + diameter:(NSUInteger)diameter; @end diff --git a/SignalMessaging/utils/OWSGroupAvatarBuilder.m b/SignalMessaging/utils/OWSGroupAvatarBuilder.m index ecf497d75..08e420a1d 100644 --- a/SignalMessaging/utils/OWSGroupAvatarBuilder.m +++ b/SignalMessaging/utils/OWSGroupAvatarBuilder.m @@ -45,51 +45,42 @@ NS_ASSUME_NONNULL_BEGIN - (nullable UIImage *)buildDefaultImage { - NSString *cacheKey = [NSString stringWithFormat:@"%@-%d", self.thread.uniqueId, Theme.isDarkThemeEnabled]; - - UIImage *cachedAvatar = - [OWSGroupAvatarBuilder.contactsManager.avatarCache imageForKey:cacheKey diameter:(CGFloat)self.diameter]; - if (cachedAvatar) { - return cachedAvatar; - } - - UIColor *backgroundColor = - [UIColor ows_conversationColorForColorName:self.thread.conversationColorName isShaded:Theme.isDarkThemeEnabled]; - UIImage *_Nullable image = - [OWSGroupAvatarBuilder groupAvatarImageWithBackgroundColor:backgroundColor diameter:self.diameter]; - if (!image) { - return nil; - } - - [OWSGroupAvatarBuilder.contactsManager.avatarCache setImage:image forKey:cacheKey diameter:self.diameter]; - return image; + return [self.class defaultAvatarForGroupId:self.thread.groupModel.groupId + conversationColorName:self.thread.conversationColorName + diameter:self.diameter]; } -+ (nullable UIImage *)defaultGroupAvatarImage ++ (nullable UIImage *)defaultAvatarForGroupId:(NSData *)groupId + conversationColorName:(NSString *)conversationColorName + diameter:(NSUInteger)diameter { - NSUInteger diameter = 200; - NSString *cacheKey = [NSString stringWithFormat:@"default-group-avatar-%d", Theme.isDarkThemeEnabled]; + NSString *cacheKey = [NSString stringWithFormat:@"%@-%d", groupId.hexadecimalString, Theme.isDarkThemeEnabled]; - UIImage *cachedAvatar = [self.contactsManager.avatarCache imageForKey:cacheKey diameter:(CGFloat)diameter]; + UIImage *_Nullable cachedAvatar = + [OWSGroupAvatarBuilder.contactsManager.avatarCache imageForKey:cacheKey diameter:(CGFloat)diameter]; if (cachedAvatar) { return cachedAvatar; } - // TODO: Verify with Myles. - UIColor *backgroundColor = UIColor.ows_signalBlueColor; - UIImage *_Nullable image = [self groupAvatarImageWithBackgroundColor:backgroundColor diameter:diameter]; + UIColor *backgroundColor = + [UIColor ows_conversationColorForColorName:conversationColorName isShaded:Theme.isDarkThemeEnabled]; + UIImage *_Nullable image = + [OWSGroupAvatarBuilder groupAvatarImageWithBackgroundColor:backgroundColor diameter:diameter]; if (!image) { return nil; } - [self.contactsManager.avatarCache setImage:image forKey:cacheKey diameter:diameter]; + [OWSGroupAvatarBuilder.contactsManager.avatarCache setImage:image forKey:cacheKey diameter:diameter]; return image; } + (nullable UIImage *)groupAvatarImageWithBackgroundColor:(UIColor *)backgroundColor diameter:(NSUInteger)diameter { UIImage *icon = [UIImage imageNamed:@"group-avatar"]; - CGSize iconSize = CGSizeScale(icon.size, diameter / kStandardAvatarSize); + // The group-avatar asset is designed for the kStandardAvatarSize. + // Adjust its size to reflect the actual output diameter. + CGFloat scaling = diameter / (CGFloat)kStandardAvatarSize; + CGSize iconSize = CGSizeScale(icon.size, scaling); return [OWSAvatarBuilder avatarImageWithIcon:icon iconSize:iconSize backgroundColor:backgroundColor diameter:diameter]; } diff --git a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.h b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.h index 5a937f509..2f9445089 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.h +++ b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.h @@ -44,6 +44,8 @@ extern NSString *const TSGroupThread_NotificationKey_UniqueId; - (void)fireAvatarChangedNotification; ++ (NSString *)defaultConversationColorNameForGroupId:(NSData *)groupId; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m index 255e7def4..248a5ae22 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m +++ b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m @@ -242,6 +242,13 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific userInfo:userInfo]; } ++ (NSString *)defaultConversationColorNameForGroupId:(NSData *)groupId +{ + OWSAssertDebug(groupId.length > 0); + + return [self.class stableConversationColorNameForString:[self threadIdFromGroupId:groupId]]; +} + @end NS_ASSUME_NONNULL_END From da637314475e2771b28eabdad7b2e5824629d1eb Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 27 Sep 2018 09:07:03 -0400 Subject: [PATCH 4/4] Respond to CR. --- Signal/src/ViewControllers/NewGroupViewController.m | 4 ++-- SignalMessaging/utils/OWSContactAvatarBuilder.m | 2 ++ SignalMessaging/utils/OWSGroupAvatarBuilder.m | 13 +++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Signal/src/ViewControllers/NewGroupViewController.m b/Signal/src/ViewControllers/NewGroupViewController.m index ca3a7c22a..3e988389d 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.m +++ b/Signal/src/ViewControllers/NewGroupViewController.m @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) AvatarImageView *avatarView; @property (nonatomic, readonly) UITextField *groupNameTextField; -@property (nonatomic) NSData *groupId; +@property (nonatomic, readonly) NSData *groupId; @property (nonatomic, nullable) UIImage *groupAvatar; @property (nonatomic) NSMutableSet *memberRecipientIds; @@ -86,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)commonInit { - self.groupId = [Randomness generateRandomBytes:16]; + _groupId = [Randomness generateRandomBytes:16]; _messageSender = SSKEnvironment.shared.messageSender; _contactsViewHelper = [[ContactsViewHelper alloc] initWithDelegate:self]; diff --git a/SignalMessaging/utils/OWSContactAvatarBuilder.m b/SignalMessaging/utils/OWSContactAvatarBuilder.m index b59d6d3a3..357faf055 100644 --- a/SignalMessaging/utils/OWSContactAvatarBuilder.m +++ b/SignalMessaging/utils/OWSContactAvatarBuilder.m @@ -71,6 +71,8 @@ NS_ASSUME_NONNULL_BEGIN return [self initWithContactId:colorSeed name:nonSignalName colorName:(NSString *)colorName diameter:diameter]; } +#pragma mark - Dependencies + + (OWSContactsManager *)contactsManager { return (OWSContactsManager *)SSKEnvironment.shared.contactsManager; diff --git a/SignalMessaging/utils/OWSGroupAvatarBuilder.m b/SignalMessaging/utils/OWSGroupAvatarBuilder.m index 08e420a1d..1c8c8b025 100644 --- a/SignalMessaging/utils/OWSGroupAvatarBuilder.m +++ b/SignalMessaging/utils/OWSGroupAvatarBuilder.m @@ -33,16 +33,20 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (nullable UIImage *)buildSavedImage -{ - return self.thread.groupModel.groupImage; -} +#pragma mark - Dependencies + (OWSContactsManager *)contactsManager { return (OWSContactsManager *)SSKEnvironment.shared.contactsManager; } +#pragma mark - + +- (nullable UIImage *)buildSavedImage +{ + return self.thread.groupModel.groupImage; +} + - (nullable UIImage *)buildDefaultImage { return [self.class defaultAvatarForGroupId:self.thread.groupModel.groupId @@ -67,6 +71,7 @@ NS_ASSUME_NONNULL_BEGIN UIImage *_Nullable image = [OWSGroupAvatarBuilder groupAvatarImageWithBackgroundColor:backgroundColor diameter:diameter]; if (!image) { + OWSFailDebug(@"Could not create group avatar."); return nil; }