@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add an icon+background selector for project images

Summary: Makes it easy to choose distinctive icons for projects.

Test Plan:
{F71018}

{F71020}

{F71019}

{F71021}

Reviewers: btrahan, chad

Reviewed By: chad

CC: chad, aran

Differential Revision: https://secure.phabricator.com/D7333

+973 -287
resources/builtin/project.png

This is a binary file and will not be displayed.

+169 -169
resources/sprite/manifest/projects.json
··· 1 1 { 2 2 "version" : 1, 3 3 "sprites" : { 4 - "projects_8ball" : { 5 - "name" : "projects_8ball", 6 - "rule" : ".projects_8ball", 4 + "projects-8ball" : { 5 + "name" : "projects-8ball", 6 + "rule" : ".projects-8ball", 7 7 "hash" : "1571c4d51926d3af7711b825c5816e2e" 8 8 }, 9 - "projects_alien" : { 10 - "name" : "projects_alien", 11 - "rule" : ".projects_alien", 9 + "projects-alien" : { 10 + "name" : "projects-alien", 11 + "rule" : ".projects-alien", 12 12 "hash" : "384f920ae335dca04edaf29663d3a074" 13 13 }, 14 - "projects_annouce" : { 15 - "name" : "projects_annouce", 16 - "rule" : ".projects_annouce", 17 - "hash" : "38abd2ff32e7c145e44c020ee4e6f2f1" 14 + "projects-announce" : { 15 + "name" : "projects-announce", 16 + "rule" : ".projects-announce", 17 + "hash" : "94329cedd509fc27a6fb577927581118" 18 18 }, 19 - "projects_art" : { 20 - "name" : "projects_art", 21 - "rule" : ".projects_art", 19 + "projects-art" : { 20 + "name" : "projects-art", 21 + "rule" : ".projects-art", 22 22 "hash" : "85c545e5130f00ff1b93c0af0d540974" 23 23 }, 24 - "projects_award" : { 25 - "name" : "projects_award", 26 - "rule" : ".projects_award", 24 + "projects-award" : { 25 + "name" : "projects-award", 26 + "rule" : ".projects-award", 27 27 "hash" : "fad6d89e4938e16f22f3c9db7cf5d696" 28 28 }, 29 - "projects_bacon" : { 30 - "name" : "projects_bacon", 31 - "rule" : ".projects_bacon", 29 + "projects-bacon" : { 30 + "name" : "projects-bacon", 31 + "rule" : ".projects-bacon", 32 32 "hash" : "f6300cdfa5a96a223f53f13dd0d3acc3" 33 33 }, 34 - "projects_bandaid" : { 35 - "name" : "projects_bandaid", 36 - "rule" : ".projects_bandaid", 34 + "projects-bandaid" : { 35 + "name" : "projects-bandaid", 36 + "rule" : ".projects-bandaid", 37 37 "hash" : "c463dffa161997277fc6697155f4085b" 38 38 }, 39 - "projects_beer" : { 40 - "name" : "projects_beer", 41 - "rule" : ".projects_beer", 39 + "projects-beer" : { 40 + "name" : "projects-beer", 41 + "rule" : ".projects-beer", 42 42 "hash" : "81c7580f322d9fb40c77db56cd92d61d" 43 43 }, 44 - "projects_bomb" : { 45 - "name" : "projects_bomb", 46 - "rule" : ".projects_bomb", 44 + "projects-bomb" : { 45 + "name" : "projects-bomb", 46 + "rule" : ".projects-bomb", 47 47 "hash" : "1123da7cc56313891c9979b004cc02f7" 48 48 }, 49 - "projects_briefcase" : { 50 - "name" : "projects_briefcase", 51 - "rule" : ".projects_briefcase", 49 + "projects-briefcase" : { 50 + "name" : "projects-briefcase", 51 + "rule" : ".projects-briefcase", 52 52 "hash" : "9b4b413ddb250ce1d3fbe18a5a5698cd" 53 53 }, 54 - "projects_bug" : { 55 - "name" : "projects_bug", 56 - "rule" : ".projects_bug", 54 + "projects-bug" : { 55 + "name" : "projects-bug", 56 + "rule" : ".projects-bug", 57 57 "hash" : "9678702aed00c4779759ebbdfe97fe48" 58 58 }, 59 - "projects_calendar" : { 60 - "name" : "projects_calendar", 61 - "rule" : ".projects_calendar", 59 + "projects-calendar" : { 60 + "name" : "projects-calendar", 61 + "rule" : ".projects-calendar", 62 62 "hash" : "e7dc5d1b11fc55ed239fcbfe527ed0e7" 63 63 }, 64 - "projects_cloud" : { 65 - "name" : "projects_cloud", 66 - "rule" : ".projects_cloud", 64 + "projects-cloud" : { 65 + "name" : "projects-cloud", 66 + "rule" : ".projects-cloud", 67 67 "hash" : "d38bf58580b3c36fbd3149a13f7d0e5e" 68 68 }, 69 - "projects_coffee" : { 70 - "name" : "projects_coffee", 71 - "rule" : ".projects_coffee", 69 + "projects-coffee" : { 70 + "name" : "projects-coffee", 71 + "rule" : ".projects-coffee", 72 72 "hash" : "a9c10862139d8e7f56c9f892496f9666" 73 73 }, 74 - "projects_creditcard" : { 75 - "name" : "projects_creditcard", 76 - "rule" : ".projects_creditcard", 74 + "projects-creditcard" : { 75 + "name" : "projects-creditcard", 76 + "rule" : ".projects-creditcard", 77 77 "hash" : "db2c179cb4935da8b9950ac30da8c0d1" 78 78 }, 79 - "projects_death" : { 80 - "name" : "projects_death", 81 - "rule" : ".projects_death", 79 + "projects-death" : { 80 + "name" : "projects-death", 81 + "rule" : ".projects-death", 82 82 "hash" : "cdea72dfdcb3fc64873b9fff78addb3c" 83 83 }, 84 - "projects_desktop" : { 85 - "name" : "projects_desktop", 86 - "rule" : ".projects_desktop", 84 + "projects-desktop" : { 85 + "name" : "projects-desktop", 86 + "rule" : ".projects-desktop", 87 87 "hash" : "19d2ef34e3dd53615cdad91eb987d6fe" 88 88 }, 89 - "projects_dropbox" : { 90 - "name" : "projects_dropbox", 91 - "rule" : ".projects_dropbox", 89 + "projects-dropbox" : { 90 + "name" : "projects-dropbox", 91 + "rule" : ".projects-dropbox", 92 92 "hash" : "10231bf468769b96ed40cf983abfa269" 93 93 }, 94 - "projects_education" : { 95 - "name" : "projects_education", 96 - "rule" : ".projects_education", 94 + "projects-education" : { 95 + "name" : "projects-education", 96 + "rule" : ".projects-education", 97 97 "hash" : "ce3d0ca75d519b2ac427a690d30475f8" 98 98 }, 99 - "projects_experimental" : { 100 - "name" : "projects_experimental", 101 - "rule" : ".projects_experimental", 99 + "projects-experimental" : { 100 + "name" : "projects-experimental", 101 + "rule" : ".projects-experimental", 102 102 "hash" : "311ef712f8daca057c20c8fd78fa77ce" 103 103 }, 104 - "projects_facebook" : { 105 - "name" : "projects_facebook", 106 - "rule" : ".projects_facebook", 104 + "projects-facebook" : { 105 + "name" : "projects-facebook", 106 + "rule" : ".projects-facebook", 107 107 "hash" : "16581191e4ce9e0115d447b479c886cb" 108 108 }, 109 - "projects_facility" : { 110 - "name" : "projects_facility", 111 - "rule" : ".projects_facility", 109 + "projects-facility" : { 110 + "name" : "projects-facility", 111 + "rule" : ".projects-facility", 112 112 "hash" : "d8893f9d2b75ec047b6f3898a386055c" 113 113 }, 114 - "projects_film" : { 115 - "name" : "projects_film", 116 - "rule" : ".projects_film", 114 + "projects-film" : { 115 + "name" : "projects-film", 116 + "rule" : ".projects-film", 117 117 "hash" : "57497050fa09ba1533d981a9c1550ba9" 118 118 }, 119 - "projects_forked" : { 120 - "name" : "projects_forked", 121 - "rule" : ".projects_forked", 119 + "projects-forked" : { 120 + "name" : "projects-forked", 121 + "rule" : ".projects-forked", 122 122 "hash" : "f575428e1079981840297bd444e51c43" 123 123 }, 124 - "projects_games" : { 125 - "name" : "projects_games", 126 - "rule" : ".projects_games", 124 + "projects-games" : { 125 + "name" : "projects-games", 126 + "rule" : ".projects-games", 127 127 "hash" : "b802cff3e76051675b37165bd9702088" 128 128 }, 129 - "projects_ghost" : { 130 - "name" : "projects_ghost", 131 - "rule" : ".projects_ghost", 129 + "projects-ghost" : { 130 + "name" : "projects-ghost", 131 + "rule" : ".projects-ghost", 132 132 "hash" : "7c8622cad29bddc5179f6a6d5f15fbe9" 133 133 }, 134 - "projects_gift" : { 135 - "name" : "projects_gift", 136 - "rule" : ".projects_gift", 134 + "projects-gift" : { 135 + "name" : "projects-gift", 136 + "rule" : ".projects-gift", 137 137 "hash" : "f2ca678906a6806f421b60abddaa6cae" 138 138 }, 139 - "projects_globe" : { 140 - "name" : "projects_globe", 141 - "rule" : ".projects_globe", 139 + "projects-globe" : { 140 + "name" : "projects-globe", 141 + "rule" : ".projects-globe", 142 142 "hash" : "87515a83cc0c840804aca594677d1eae" 143 143 }, 144 - "projects_golf" : { 145 - "name" : "projects_golf", 146 - "rule" : ".projects_golf", 144 + "projects-golf" : { 145 + "name" : "projects-golf", 146 + "rule" : ".projects-golf", 147 147 "hash" : "1ee7556fab3d46d925deb00322dad858" 148 148 }, 149 - "projects_heart" : { 150 - "name" : "projects_heart", 151 - "rule" : ".projects_heart", 149 + "projects-heart" : { 150 + "name" : "projects-heart", 151 + "rule" : ".projects-heart", 152 152 "hash" : "3da64839e37ee245333017d0a310cc2e" 153 153 }, 154 - "projects_intergalactic" : { 155 - "name" : "projects_intergalactic", 156 - "rule" : ".projects_intergalactic", 154 + "projects-intergalactic" : { 155 + "name" : "projects-intergalactic", 156 + "rule" : ".projects-intergalactic", 157 157 "hash" : "94dca756cb267bdb4e0ed58467320780" 158 158 }, 159 - "projects_lock" : { 160 - "name" : "projects_lock", 161 - "rule" : ".projects_lock", 159 + "projects-lock" : { 160 + "name" : "projects-lock", 161 + "rule" : ".projects-lock", 162 162 "hash" : "9d4c8ad3a4ac4163f284461da7df2763" 163 163 }, 164 - "projects_mail" : { 165 - "name" : "projects_mail", 166 - "rule" : ".projects_mail", 164 + "projects-mail" : { 165 + "name" : "projects-mail", 166 + "rule" : ".projects-mail", 167 167 "hash" : "963f5ce26c6caf86e72d754f7b6e8865" 168 168 }, 169 - "projects_martini" : { 170 - "name" : "projects_martini", 171 - "rule" : ".projects_martini", 169 + "projects-martini" : { 170 + "name" : "projects-martini", 171 + "rule" : ".projects-martini", 172 172 "hash" : "24d4d5fb5c334621ece4c35a9196471e" 173 173 }, 174 - "projects_medical" : { 175 - "name" : "projects_medical", 176 - "rule" : ".projects_medical", 174 + "projects-medical" : { 175 + "name" : "projects-medical", 176 + "rule" : ".projects-medical", 177 177 "hash" : "e0cb3ef5557321d166e8eb49c10d3599" 178 178 }, 179 - "projects_mobile" : { 180 - "name" : "projects_mobile", 181 - "rule" : ".projects_mobile", 179 + "projects-mobile" : { 180 + "name" : "projects-mobile", 181 + "rule" : ".projects-mobile", 182 182 "hash" : "37dec95d1a4a937743d52acac319c3b6" 183 183 }, 184 - "projects_music" : { 185 - "name" : "projects_music", 186 - "rule" : ".projects_music", 184 + "projects-music" : { 185 + "name" : "projects-music", 186 + "rule" : ".projects-music", 187 187 "hash" : "e7a814194685ac25be0db05b04074607" 188 188 }, 189 - "projects_news" : { 190 - "name" : "projects_news", 191 - "rule" : ".projects_news", 189 + "projects-news" : { 190 + "name" : "projects-news", 191 + "rule" : ".projects-news", 192 192 "hash" : "6861f3ee827d09b0592166514f4941e8" 193 193 }, 194 - "projects_orgchart" : { 195 - "name" : "projects_orgchart", 196 - "rule" : ".projects_orgchart", 194 + "projects-orgchart" : { 195 + "name" : "projects-orgchart", 196 + "rule" : ".projects-orgchart", 197 197 "hash" : "20c51c59788fb2bc8184fdd5687d33dc" 198 198 }, 199 - "projects_peoples" : { 200 - "name" : "projects_peoples", 201 - "rule" : ".projects_peoples", 199 + "projects-peoples" : { 200 + "name" : "projects-peoples", 201 + "rule" : ".projects-peoples", 202 202 "hash" : "c949ba6d09e68317a9a11482e75e5140" 203 203 }, 204 - "projects_piechart" : { 205 - "name" : "projects_piechart", 206 - "rule" : ".projects_piechart", 204 + "projects-piechart" : { 205 + "name" : "projects-piechart", 206 + "rule" : ".projects-piechart", 207 207 "hash" : "051138560e30982a029aa5e4ea87bc17" 208 208 }, 209 - "projects_poison" : { 210 - "name" : "projects_poison", 211 - "rule" : ".projects_poison", 209 + "projects-poison" : { 210 + "name" : "projects-poison", 211 + "rule" : ".projects-poison", 212 212 "hash" : "56ddafd138e421f198b9cb38e5dc7455" 213 213 }, 214 - "projects_putabirdonit" : { 215 - "name" : "projects_putabirdonit", 216 - "rule" : ".projects_putabirdonit", 214 + "projects-putabirdonit" : { 215 + "name" : "projects-putabirdonit", 216 + "rule" : ".projects-putabirdonit", 217 217 "hash" : "ee298fff82c34341b986a3e1b77bea11" 218 218 }, 219 - "projects_radiate" : { 220 - "name" : "projects_radiate", 221 - "rule" : ".projects_radiate", 219 + "projects-radiate" : { 220 + "name" : "projects-radiate", 221 + "rule" : ".projects-radiate", 222 222 "hash" : "9cfb918089b3de8506a5d270a119052c" 223 223 }, 224 - "projects_savings" : { 225 - "name" : "projects_savings", 226 - "rule" : ".projects_savings", 224 + "projects-savings" : { 225 + "name" : "projects-savings", 226 + "rule" : ".projects-savings", 227 227 "hash" : "9e92bc5e64f79d2f4842ac24a8b57fcb" 228 228 }, 229 - "projects_search" : { 230 - "name" : "projects_search", 231 - "rule" : ".projects_search", 229 + "projects-search" : { 230 + "name" : "projects-search", 231 + "rule" : ".projects-search", 232 232 "hash" : "a42c1c31f2929838b0f181f417c0b6a4" 233 233 }, 234 - "projects_shield" : { 235 - "name" : "projects_shield", 236 - "rule" : ".projects_shield", 234 + "projects-shield" : { 235 + "name" : "projects-shield", 236 + "rule" : ".projects-shield", 237 237 "hash" : "40c6e1bec7c07c165668ac45c218847a" 238 238 }, 239 - "projects_speed" : { 240 - "name" : "projects_speed", 241 - "rule" : ".projects_speed", 239 + "projects-speed" : { 240 + "name" : "projects-speed", 241 + "rule" : ".projects-speed", 242 242 "hash" : "2b70c194d07f5a9d95abc51d84fb22ed" 243 243 }, 244 - "projects_sprint" : { 245 - "name" : "projects_sprint", 246 - "rule" : ".projects_sprint", 244 + "projects-sprint" : { 245 + "name" : "projects-sprint", 246 + "rule" : ".projects-sprint", 247 247 "hash" : "655ef9a3043eab23eac1da21baeb36b3" 248 248 }, 249 - "projects_star" : { 250 - "name" : "projects_star", 251 - "rule" : ".projects_star", 249 + "projects-star" : { 250 + "name" : "projects-star", 251 + "rule" : ".projects-star", 252 252 "hash" : "a46e3c18f68bc13a65b410496e27b5d7" 253 253 }, 254 - "projects_storage" : { 255 - "name" : "projects_storage", 256 - "rule" : ".projects_storage", 254 + "projects-storage" : { 255 + "name" : "projects-storage", 256 + "rule" : ".projects-storage", 257 257 "hash" : "bb19baa77bb7596f43f77e5dbbddb006" 258 258 }, 259 - "projects_tablet" : { 260 - "name" : "projects_tablet", 261 - "rule" : ".projects_tablet", 259 + "projects-tablet" : { 260 + "name" : "projects-tablet", 261 + "rule" : ".projects-tablet", 262 262 "hash" : "830dcf6637288ca122c8f5034cae3769" 263 263 }, 264 - "projects_travel" : { 265 - "name" : "projects_travel", 266 - "rule" : ".projects_travel", 264 + "projects-travel" : { 265 + "name" : "projects-travel", 266 + "rule" : ".projects-travel", 267 267 "hash" : "86ec4dcd025879a43435b101fd542a1b" 268 268 }, 269 - "projects_twitter" : { 270 - "name" : "projects_twitter", 271 - "rule" : ".projects_twitter", 269 + "projects-twitter" : { 270 + "name" : "projects-twitter", 271 + "rule" : ".projects-twitter", 272 272 "hash" : "75b8680dd1e4ecce4ca3a39c87e1ed80" 273 273 }, 274 - "projects_warning" : { 275 - "name" : "projects_warning", 276 - "rule" : ".projects_warning", 274 + "projects-warning" : { 275 + "name" : "projects-warning", 276 + "rule" : ".projects-warning", 277 277 "hash" : "3ac48b6f963675e1f4bb4ac75aad936f" 278 278 }, 279 - "projects_whale" : { 280 - "name" : "projects_whale", 281 - "rule" : ".projects_whale", 279 + "projects-whale" : { 280 + "name" : "projects-whale", 281 + "rule" : ".projects-whale", 282 282 "hash" : "569b584c7e80a0a9b965280abd27c723" 283 283 } 284 284 },
resources/sprite/projects_1x/annouce.png resources/sprite/projects_1x/announce.png
resources/sprite/projects_2x/annouce.png resources/sprite/projects_2x/announce.png
+26 -2
src/__celerity_resource_map__.php
··· 1791 1791 ), 1792 1792 'disk' => '/rsrc/js/core/behavior-history-install.js', 1793 1793 ), 1794 + 'javelin-behavior-icon-composer' => 1795 + array( 1796 + 'uri' => '/res/0be5c462/rsrc/js/application/files/behavior-icon-composer.js', 1797 + 'type' => 'js', 1798 + 'requires' => 1799 + array( 1800 + 0 => 'javelin-behavior', 1801 + 1 => 'javelin-dom', 1802 + 2 => 'javelin-stratcom', 1803 + ), 1804 + 'disk' => '/rsrc/js/application/files/behavior-icon-composer.js', 1805 + ), 1794 1806 'javelin-behavior-konami' => 1795 1807 array( 1796 1808 'uri' => '/res/b7bb7c24/rsrc/js/core/behavior-konami.js', ··· 1801 1813 1 => 'javelin-stratcom', 1802 1814 ), 1803 1815 'disk' => '/rsrc/js/core/behavior-konami.js', 1816 + ), 1817 + 'javelin-behavior-launch-icon-composer' => 1818 + array( 1819 + 'uri' => '/res/202488ac/rsrc/js/application/files/behavior-launch-icon-composer.js', 1820 + 'type' => 'js', 1821 + 'requires' => 1822 + array( 1823 + 0 => 'javelin-behavior', 1824 + 1 => 'javelin-dom', 1825 + 2 => 'javelin-workflow', 1826 + ), 1827 + 'disk' => '/rsrc/js/application/files/behavior-launch-icon-composer.js', 1804 1828 ), 1805 1829 'javelin-behavior-lightbox-attachments' => 1806 1830 array( ··· 3062 3086 ), 3063 3087 'people-profile-css' => 3064 3088 array( 3065 - 'uri' => '/res/d50d9502/rsrc/css/application/people/people-profile.css', 3089 + 'uri' => '/res/f1da102e/rsrc/css/application/people/people-profile.css', 3066 3090 'type' => 'css', 3067 3091 'requires' => 3068 3092 array( ··· 4227 4251 ), 4228 4252 'sprite-projects-css' => 4229 4253 array( 4230 - 'uri' => '/res/3ff34b69/rsrc/css/sprite-projects.css', 4254 + 'uri' => '/res/40eacbfb/rsrc/css/sprite-projects.css', 4231 4255 'type' => 'css', 4232 4256 'requires' => 4233 4257 array(
+4
src/__phutil_library_map__.php
··· 1209 1209 'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php', 1210 1210 'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php', 1211 1211 'PhabricatorFileCommentController' => 'applications/files/controller/PhabricatorFileCommentController.php', 1212 + 'PhabricatorFileComposeController' => 'applications/files/controller/PhabricatorFileComposeController.php', 1212 1213 'PhabricatorFileController' => 'applications/files/controller/PhabricatorFileController.php', 1213 1214 'PhabricatorFileDAO' => 'applications/files/storage/PhabricatorFileDAO.php', 1214 1215 'PhabricatorFileDataController' => 'applications/files/controller/PhabricatorFileDataController.php', ··· 1523 1524 'PhabricatorProjectProfile' => 'applications/project/storage/PhabricatorProjectProfile.php', 1524 1525 'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php', 1525 1526 'PhabricatorProjectProfileEditController' => 'applications/project/controller/PhabricatorProjectProfileEditController.php', 1527 + 'PhabricatorProjectProfilePictureController' => 'applications/project/controller/PhabricatorProjectProfilePictureController.php', 1526 1528 'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php', 1527 1529 'PhabricatorProjectSearchEngine' => 'applications/project/query/PhabricatorProjectSearchEngine.php', 1528 1530 'PhabricatorProjectSearchIndexer' => 'applications/project/search/PhabricatorProjectSearchIndexer.php', ··· 3397 3399 3 => 'PhabricatorPolicyInterface', 3398 3400 ), 3399 3401 'PhabricatorFileCommentController' => 'PhabricatorFileController', 3402 + 'PhabricatorFileComposeController' => 'PhabricatorFileController', 3400 3403 'PhabricatorFileController' => 'PhabricatorController', 3401 3404 'PhabricatorFileDAO' => 'PhabricatorLiskDAO', 3402 3405 'PhabricatorFileDataController' => 'PhabricatorFileController', ··· 3739 3742 'PhabricatorProjectProfile' => 'PhabricatorProjectDAO', 3740 3743 'PhabricatorProjectProfileController' => 'PhabricatorProjectController', 3741 3744 'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController', 3745 + 'PhabricatorProjectProfilePictureController' => 'PhabricatorProjectController', 3742 3746 'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3743 3747 'PhabricatorProjectSearchEngine' => 'PhabricatorApplicationSearchEngine', 3744 3748 'PhabricatorProjectSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
+1
src/applications/files/application/PhabricatorApplicationFiles.php
··· 51 51 '(query/(?P<key>[^/]+)/)?' => 'PhabricatorFileListController', 52 52 'upload/' => 'PhabricatorFileUploadController', 53 53 'dropupload/' => 'PhabricatorFileDropUploadController', 54 + 'compose/' => 'PhabricatorFileComposeController', 54 55 'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorFileCommentController', 55 56 'delete/(?P<id>[1-9]\d*)/' => 'PhabricatorFileDeleteController', 56 57 'info/(?P<phid>[^/]+)/' => 'PhabricatorFileInfoController',
+249
src/applications/files/controller/PhabricatorFileComposeController.php
··· 1 + <?php 2 + 3 + final class PhabricatorFileComposeController 4 + extends PhabricatorFileController { 5 + 6 + public function processRequest() { 7 + $request = $this->getRequest(); 8 + $viewer = $request->getUser(); 9 + 10 + $colors = array( 11 + 'red' => pht('Verbillion'), 12 + 'orange' => pht('Navel Orange'), 13 + 'yellow' => pht('Prim Goldenrod'), 14 + 'green' => pht('Lustrous Verdant'), 15 + 'blue' => pht('Tropical Deep'), 16 + 'sky' => pht('Wide Open Sky'), 17 + 'indigo' => pht('Pleated Khaki'), 18 + 'violet' => pht('Aged Merlot'), 19 + 'charcoal' => pht('Gemstone'), 20 + 'backdrop' => pht('Driven Snow'), 21 + ); 22 + 23 + $manifest = PHUIIconView::getSheetManifest(PHUIIconView::SPRITE_PROJECTS); 24 + 25 + if ($request->isFormPost()) { 26 + $icon = $request->getStr('icon'); 27 + $color = $request->getStr('color'); 28 + 29 + if (isset($colors[$color]) && isset($manifest['projects-'.$icon])) { 30 + $root = dirname(phutil_get_library_root('phabricator')); 31 + $icon_file = $root.'/resources/sprite/projects_1x/'.$icon.'.png'; 32 + $icon_data = Filesystem::readFile($icon_file); 33 + 34 + 35 + $data = $this->composeImage($color, $icon_data); 36 + 37 + $file = PhabricatorFile::buildFromFileDataOrHash( 38 + $data, 39 + array( 40 + 'name' => 'project.png', 41 + )); 42 + 43 + $content = array( 44 + 'phid' => $file->getPHID(), 45 + ); 46 + 47 + return id(new AphrontAjaxResponse())->setContent($content); 48 + } 49 + } 50 + 51 + $value_color = head_key($colors); 52 + $value_icon = head_key($manifest); 53 + $value_icon = substr($value_icon, strlen('projects-')); 54 + 55 + require_celerity_resource('people-profile-css'); 56 + 57 + $buttons = array(); 58 + foreach ($colors as $color => $name) { 59 + $buttons[] = javelin_tag( 60 + 'button', 61 + array( 62 + 'class' => 'grey profile-image-button', 63 + 'sigil' => 'has-tooltip compose-select-color', 64 + 'style' => 'margin: 0 8px 8px 0', 65 + 'meta' => array( 66 + 'color' => $color, 67 + 'tip' => $name, 68 + ), 69 + ), 70 + id(new PHUIIconView()) 71 + ->addClass('compose-background-'.$color)); 72 + } 73 + 74 + $icons = array(); 75 + 76 + $icon_quips = array( 77 + '8ball' => pht('Take a Risk'), 78 + 'alien' => pht('Foreign Interface'), 79 + 'announce' => pht('Louder is Better'), 80 + 'art' => pht('Unique Snowflake'), 81 + 'award' => pht('Shooting Star'), 82 + 'bacon' => pht('Healthy Vegetables'), 83 + 'bandaid' => pht('Durable Infrastructure'), 84 + 'beer' => pht('Healthy Vegetable Juice'), 85 + 'bomb' => pht('Imminent Success'), 86 + 'briefcase' => pht('Adventure Pack'), 87 + 'bug' => pht('Costumed Egg'), 88 + 'calendar' => pht('Everyone Loves Meetings'), 89 + 'cloud' => pht('Water Cycle'), 90 + 'coffee' => pht('Half-Whip Nonfat Soy Latte'), 91 + 'creditcard' => pht('Expense It'), 92 + 'death' => pht('Calcium Promotes Bone Health'), 93 + 'desktop' => pht('Magical Portal'), 94 + 'dropbox' => pht('Cardboard Box'), 95 + 'education' => pht('Debt'), 96 + 'experimental' => pht('CAUTION: Dangerous Chemicals'), 97 + 'facebook' => pht('Popular Social Network'), 98 + 'facility' => pht('Pollution Solves Problems'), 99 + 'film' => pht('Actual Physical Film'), 100 + 'forked' => pht('You Can\'t Eat Soup'), 101 + 'games' => pht('Serious Business'), 102 + 'ghost' => pht('Haunted'), 103 + 'gift' => pht('Surprise!'), 104 + 'globe' => pht('Scanner Sweep'), 105 + 'golf' => pht('Business Meeting'), 106 + 'heart' => pht('Undergoing a Major Surgery'), 107 + 'intergalactic' => pht('Jupiter'), 108 + 'lock' => pht('Extremely Secret'), 109 + 'mail' => pht('Oragami'), 110 + 'martini' => pht('Healthy Olive Drink'), 111 + 'medical' => pht('Medic!'), 112 + 'mobile' => pht('Cellular Telephone'), 113 + 'music' => pht("\xE2\x99\xAB"), 114 + 'news' => pht('Actual Physical Newspaper'), 115 + 'orgchart' => pht('It\'s Good to be King'), 116 + 'peoples' => pht('Angel and Devil'), 117 + 'piechart' => pht('Actual Physical Pie'), 118 + 'poison' => pht('Healthy Bone Juice'), 119 + 'putabirdonit' => pht('Put a Bird On It'), 120 + 'radiate' => pht('Radiant Beauty'), 121 + 'savings' => pht('Oink Oink'), 122 + 'search' => pht('Sleuthing'), 123 + 'shield' => pht('Royal Crest'), 124 + 'speed' => pht('Slow and Steady'), 125 + 'sprint' => pht('Fire Exit'), 126 + 'star' => pht('The More You Know'), 127 + 'storage' => pht('Stack of Pancakes'), 128 + 'tablet' => pht('Cellular Telephone For Giants'), 129 + 'travel' => pht('Pretty Clearly an Airplane'), 130 + 'twitter' => pht('Bird Stencil'), 131 + 'warning' => pht('No Caution Required, Everything Looks Safe'), 132 + 'whale' => pht('Friendly Walrus'), 133 + ); 134 + 135 + foreach ($manifest as $icon => $spec) { 136 + $icon = substr($icon, strlen('projects-')); 137 + 138 + $icons[] = javelin_tag( 139 + 'button', 140 + array( 141 + 'class' => 'grey profile-image-button', 142 + 'sigil' => 'has-tooltip compose-select-icon', 143 + 'style' => 'margin: 0 8px 8px 0', 144 + 'meta' => array( 145 + 'icon' => $icon, 146 + 'tip' => idx($icon_quips, $icon, $icon), 147 + ), 148 + ), 149 + id(new PHUIIconView()) 150 + ->setSpriteIcon($icon) 151 + ->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS)); 152 + } 153 + 154 + $dialog_id = celerity_generate_unique_node_id(); 155 + $color_input_id = celerity_generate_unique_node_id();; 156 + $icon_input_id = celerity_generate_unique_node_id(); 157 + $preview_id = celerity_generate_unique_node_id(); 158 + 159 + $preview = id(new PHUIIconView()) 160 + ->setID($preview_id) 161 + ->addClass('compose-background-'.$value_color) 162 + ->setSpriteIcon($value_icon) 163 + ->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS); 164 + 165 + $color_input = javelin_tag( 166 + 'input', 167 + array( 168 + 'type' => 'hidden', 169 + 'name' => 'color', 170 + 'value' => $value_color, 171 + 'id' => $color_input_id, 172 + )); 173 + 174 + $icon_input = javelin_tag( 175 + 'input', 176 + array( 177 + 'type' => 'hidden', 178 + 'name' => 'icon', 179 + 'value' => $value_icon, 180 + 'id' => $icon_input_id, 181 + )); 182 + 183 + Javelin::initBehavior('phabricator-tooltips'); 184 + Javelin::initBehavior( 185 + 'icon-composer', 186 + array( 187 + 'dialogID' => $dialog_id, 188 + 'colorInputID' => $color_input_id, 189 + 'iconInputID' => $icon_input_id, 190 + 'previewID' => $preview_id, 191 + 'defaultColor' => $value_color, 192 + 'defaultIcon' => $value_icon, 193 + )); 194 + 195 + $dialog = id(new AphrontDialogView()) 196 + ->setUser($viewer) 197 + ->setFormID($dialog_id) 198 + ->setClass('compose-dialog') 199 + ->setTitle(pht('Compose Image')) 200 + ->appendChild( 201 + phutil_tag( 202 + 'div', 203 + array( 204 + 'class' => 'compose-header', 205 + ), 206 + pht('Choose Background Color'))) 207 + ->appendChild($buttons) 208 + ->appendChild( 209 + phutil_tag( 210 + 'div', 211 + array( 212 + 'class' => 'compose-header', 213 + ), 214 + pht('Choose Icon'))) 215 + ->appendChild($icons) 216 + ->appendChild( 217 + phutil_tag( 218 + 'div', 219 + array( 220 + 'class' => 'compose-header', 221 + ), 222 + pht('Preview'))) 223 + ->appendChild($preview) 224 + ->appendChild($color_input) 225 + ->appendChild($icon_input) 226 + ->addCancelButton('/') 227 + ->addSubmitButton(pht('Save Image')); 228 + 229 + return id(new AphrontDialogResponse())->setDialog($dialog); 230 + } 231 + 232 + private function composeImage($color, $icon_data) { 233 + $icon_img = imagecreatefromstring($icon_data); 234 + 235 + $map = CelerityResourceTransformer::getCSSVariableMap(); 236 + $color_string = idx($map, $color, '#ff00ff'); 237 + $color_const = hexdec(trim($color_string, '#')); 238 + 239 + $canvas = imagecreatetruecolor(50, 50); 240 + imagefill($canvas, 0, 0, $color_const); 241 + 242 + imagecopy($canvas, $icon_img, 0, 0, 0, 0, 50, 50); 243 + 244 + return PhabricatorImageTransformer::saveImageDataInAnyFormat( 245 + $canvas, 246 + 'image/png'); 247 + } 248 + 249 + }
+2
src/applications/project/application/PhabricatorApplicationProject.php
··· 42 42 => 'PhabricatorProjectMembersEditController', 43 43 'view/(?P<id>[1-9]\d*)/(?:(?P<page>\w+)/)?' 44 44 => 'PhabricatorProjectProfileController', 45 + 'picture/(?P<id>[1-9]\d*)/' => 46 + 'PhabricatorProjectProfilePictureController', 45 47 'create/' => 'PhabricatorProjectCreateController', 46 48 'update/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/' 47 49 => 'PhabricatorProjectUpdateController',
+8
src/applications/project/controller/PhabricatorProjectProfileController.php
··· 216 216 ->setDisabled(!$can_edit) 217 217 ->setWorkflow(!$can_edit)); 218 218 219 + $view->addAction( 220 + id(new PhabricatorActionView()) 221 + ->setName(pht('Edit Picture')) 222 + ->setIcon('image') 223 + ->setHref($this->getApplicationURI("picture/{$id}/")) 224 + ->setDisabled(!$can_edit) 225 + ->setWorkflow(!$can_edit)); 226 + 219 227 220 228 $action = null; 221 229 if (!$project->isUserMember($viewer->getPHID())) {
-53
src/applications/project/controller/PhabricatorProjectProfileEditController.php
··· 29 29 } 30 30 31 31 $profile = $project->getProfile(); 32 - $img_src = $profile->getProfileImageURI(); 33 - 34 32 $options = PhabricatorProjectStatus::getStatusMap(); 35 33 36 - $supported_formats = PhabricatorFile::getTransformableImageFormats(); 37 - 38 34 $e_name = true; 39 - $e_image = null; 40 35 41 36 $errors = array(); 42 37 if ($request->isFormPost()) { ··· 89 84 $e_name = null; 90 85 } 91 86 92 - $default_image = $request->getExists('default_image'); 93 - if ($default_image) { 94 - $profile->setProfileImagePHID(null); 95 - } else if (!empty($_FILES['image'])) { 96 - $err = idx($_FILES['image'], 'error'); 97 - if ($err != UPLOAD_ERR_NO_FILE) { 98 - $file = PhabricatorFile::newFromPHPUpload( 99 - $_FILES['image'], 100 - array( 101 - 'authorPHID' => $user->getPHID(), 102 - )); 103 - $okay = $file->isTransformableImage(); 104 - if ($okay) { 105 - $xformer = new PhabricatorImageTransformer(); 106 - $xformed = $xformer->executeThumbTransform( 107 - $file, 108 - $x = 50, 109 - $y = 50); 110 - 111 - $profile->setProfileImagePHID($xformed->getPHID()); 112 - $xformed->attachToObject($user, $project->getPHID()); 113 - 114 - } else { 115 - $e_image = pht('Not Supported'); 116 - $errors[] = 117 - pht('This server only supports these image formats:').' '. 118 - implode(', ', $supported_formats).'.'; 119 - } 120 - } 121 - } 122 - 123 87 if (!$errors) { 124 88 $project->save(); 125 89 $profile->setProjectPHID($project->getPHID()); ··· 150 114 ->setID('project-edit-form') 151 115 ->setUser($user) 152 116 ->setAction($action) 153 - ->setEncType('multipart/form-data') 154 117 ->appendChild( 155 118 id(new AphrontFormTextControl()) 156 119 ->setLabel(pht('Name')) ··· 198 161 ->setPolicyObject($project) 199 162 ->setPolicies($policies) 200 163 ->setCapability(PhabricatorPolicyCapability::CAN_JOIN)) 201 - ->appendChild( 202 - id(new AphrontFormMarkupControl()) 203 - ->setLabel(pht('Profile Image')) 204 - ->setValue( 205 - phutil_tag( 206 - 'img', 207 - array( 208 - 'src' => $img_src, 209 - )))) 210 - ->appendChild( 211 - id(new AphrontFormImageControl()) 212 - ->setLabel(pht('Change Image')) 213 - ->setName('image') 214 - ->setError($e_image) 215 - ->setCaption( 216 - pht('Supported formats:').' '.implode(', ', $supported_formats))) 217 164 ->appendChild( 218 165 id(new AphrontFormSubmitControl()) 219 166 ->addCancelButton('/project/view/'.$project->getID().'/')
+274
src/applications/project/controller/PhabricatorProjectProfilePictureController.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectProfilePictureController 4 + extends PhabricatorProjectController { 5 + 6 + private $id; 7 + 8 + public function willProcessRequest(array $data) { 9 + $this->id = $data['id']; 10 + } 11 + 12 + public function processRequest() { 13 + $request = $this->getRequest(); 14 + $viewer = $request->getUser(); 15 + 16 + $project = id(new PhabricatorProjectQuery()) 17 + ->setViewer($viewer) 18 + ->withIDs(array($this->id)) 19 + ->needProfiles(true) 20 + ->requireCapabilities( 21 + array( 22 + PhabricatorPolicyCapability::CAN_VIEW, 23 + PhabricatorPolicyCapability::CAN_EDIT, 24 + )) 25 + ->executeOne(); 26 + if (!$project) { 27 + return new Aphront404Response(); 28 + } 29 + 30 + $project_uri = $this->getApplicationURI('view/'.$project->getID().'/'); 31 + 32 + $supported_formats = PhabricatorFile::getTransformableImageFormats(); 33 + $e_file = true; 34 + $errors = array(); 35 + 36 + if ($request->isFormPost()) { 37 + $phid = $request->getStr('phid'); 38 + $is_default = false; 39 + if ($phid == PhabricatorPHIDConstants::PHID_VOID) { 40 + $phid = null; 41 + $is_default = true; 42 + } else if ($phid) { 43 + $file = id(new PhabricatorFileQuery()) 44 + ->setViewer($viewer) 45 + ->withPHIDs(array($phid)) 46 + ->executeOne(); 47 + } else { 48 + if ($request->getFileExists('picture')) { 49 + $file = PhabricatorFile::newFromPHPUpload( 50 + $_FILES['picture'], 51 + array( 52 + 'authorPHID' => $viewer->getPHID(), 53 + )); 54 + } else { 55 + $e_file = pht('Required'); 56 + $errors[] = pht( 57 + 'You must choose a file when uploading a new project picture.'); 58 + } 59 + } 60 + 61 + if (!$errors && !$is_default) { 62 + if (!$file->isTransformableImage()) { 63 + $e_file = pht('Not Supported'); 64 + $errors[] = pht( 65 + 'This server only supports these image formats: %s.', 66 + implode(', ', $supported_formats)); 67 + } else { 68 + $xformer = new PhabricatorImageTransformer(); 69 + $xformed = $xformer->executeProfileTransform( 70 + $file, 71 + $width = 50, 72 + $min_height = 50, 73 + $max_height = 50); 74 + } 75 + } 76 + 77 + if (!$errors) { 78 + $profile = $project->getProfile(); 79 + if ($is_default) { 80 + $profile->setProfileImagePHID(null); 81 + } else { 82 + $profile->setProfileImagePHID($xformed->getPHID()); 83 + $xformed->attachToObject($viewer, $project->getPHID()); 84 + } 85 + $profile->save(); 86 + return id(new AphrontRedirectResponse())->setURI($project_uri); 87 + } 88 + } 89 + 90 + $title = pht('Edit Project Picture'); 91 + $crumbs = $this->buildApplicationCrumbs(); 92 + $crumbs->addCrumb( 93 + id(new PhabricatorCrumbView()) 94 + ->setName($project->getName()) 95 + ->setHref($project_uri)); 96 + $crumbs->addCrumb( 97 + id(new PhabricatorCrumbView()) 98 + ->setName($title)); 99 + 100 + $form = id(new PHUIFormLayoutView()) 101 + ->setUser($viewer); 102 + 103 + $default_image = PhabricatorFile::loadBuiltin($viewer, 'project.png'); 104 + 105 + $images = array(); 106 + 107 + $current = $project->getProfile()->getProfileImagePHID(); 108 + $has_current = false; 109 + if ($current) { 110 + $files = id(new PhabricatorFileQuery()) 111 + ->setViewer($viewer) 112 + ->withPHIDs(array($current)) 113 + ->execute(); 114 + if ($files) { 115 + $file = head($files); 116 + if ($file->isTransformableImage()) { 117 + $has_current = true; 118 + $images[$current] = array( 119 + 'uri' => $file->getBestURI(), 120 + 'tip' => pht('Current Picture'), 121 + ); 122 + } 123 + } 124 + } 125 + 126 + $images[PhabricatorPHIDConstants::PHID_VOID] = array( 127 + 'uri' => $default_image->getBestURI(), 128 + 'tip' => pht('Default Picture'), 129 + ); 130 + 131 + require_celerity_resource('people-profile-css'); 132 + Javelin::initBehavior('phabricator-tooltips', array()); 133 + 134 + $buttons = array(); 135 + foreach ($images as $phid => $spec) { 136 + $button = javelin_tag( 137 + 'button', 138 + array( 139 + 'class' => 'grey profile-image-button', 140 + 'sigil' => 'has-tooltip', 141 + 'meta' => array( 142 + 'tip' => $spec['tip'], 143 + 'size' => 300, 144 + ), 145 + ), 146 + phutil_tag( 147 + 'img', 148 + array( 149 + 'height' => 50, 150 + 'width' => 50, 151 + 'src' => $spec['uri'], 152 + ))); 153 + 154 + $button = array( 155 + phutil_tag( 156 + 'input', 157 + array( 158 + 'type' => 'hidden', 159 + 'name' => 'phid', 160 + 'value' => $phid, 161 + )), 162 + $button); 163 + 164 + $button = phabricator_form( 165 + $viewer, 166 + array( 167 + 'class' => 'profile-image-form', 168 + 'method' => 'POST', 169 + ), 170 + $button); 171 + 172 + $buttons[] = $button; 173 + } 174 + 175 + if ($has_current) { 176 + $form->appendChild( 177 + id(new AphrontFormMarkupControl()) 178 + ->setLabel(pht('Current Picture')) 179 + ->setValue(array_shift($buttons))); 180 + } 181 + 182 + $form->appendChild( 183 + id(new AphrontFormMarkupControl()) 184 + ->setLabel(pht('Use Picture')) 185 + ->setValue($buttons)); 186 + 187 + $launch_id = celerity_generate_unique_node_id(); 188 + $input_id = celerity_generate_unique_node_id(); 189 + 190 + Javelin::initBehavior( 191 + 'launch-icon-composer', 192 + array( 193 + 'launchID' => $launch_id, 194 + 'inputID' => $input_id, 195 + )); 196 + 197 + $compose_button = javelin_tag( 198 + 'button', 199 + array( 200 + 'class' => 'grey', 201 + 'id' => $launch_id, 202 + 'sigil' => 'icon-composer', 203 + ), 204 + pht('Choose Icon and Color...')); 205 + 206 + $compose_input = javelin_tag( 207 + 'input', 208 + array( 209 + 'type' => 'hidden', 210 + 'id' => $input_id, 211 + 'name' => 'phid', 212 + )); 213 + 214 + $compose_form = phabricator_form( 215 + $viewer, 216 + array( 217 + 'class' => 'profile-image-form', 218 + 'method' => 'POST', 219 + ), 220 + array( 221 + $compose_input, 222 + $compose_button, 223 + )); 224 + 225 + $form->appendChild( 226 + id(new AphrontFormMarkupControl()) 227 + ->setLabel(pht('Quick Create')) 228 + ->setValue($compose_form)); 229 + 230 + $form_box = id(new PHUIObjectBoxView()) 231 + ->setHeaderText($title) 232 + ->setFormError($errors) 233 + ->setForm($form); 234 + 235 + $upload_form = id(new AphrontFormView()) 236 + ->setUser($viewer) 237 + ->setEncType('multipart/form-data') 238 + ->appendChild( 239 + id(new AphrontFormFileControl()) 240 + ->setName('picture') 241 + ->setLabel(pht('Upload Picture')) 242 + ->setError($e_file) 243 + ->setCaption( 244 + pht('Supported formats: %s', implode(', ', $supported_formats)))) 245 + ->appendChild( 246 + id(new AphrontFormSubmitControl()) 247 + ->addCancelButton($project_uri) 248 + ->setValue(pht('Upload Picture'))); 249 + 250 + if ($errors) { 251 + $errors = id(new AphrontErrorView())->setErrors($errors); 252 + } 253 + 254 + $form_box = id(new PHUIObjectBoxView()) 255 + ->setHeaderText($title) 256 + ->setFormError($errors) 257 + ->setForm($form); 258 + 259 + $upload_box = id(new PHUIObjectBoxView()) 260 + ->setHeaderText(pht('Upload New Picture')) 261 + ->setForm($upload_form); 262 + 263 + return $this->buildApplicationPage( 264 + array( 265 + $crumbs, 266 + $form_box, 267 + $upload_box, 268 + ), 269 + array( 270 + 'title' => $title, 271 + 'device' => true, 272 + )); 273 + } 274 + }
+2 -2
src/applications/project/query/PhabricatorProjectQuery.php
··· 142 142 if (!$default) { 143 143 $default = PhabricatorFile::loadBuiltin( 144 144 $this->getViewer(), 145 - 'profile.png'); 145 + 'project.png'); 146 146 } 147 147 $file = $default; 148 148 } ··· 156 156 if (!$default) { 157 157 $default = PhabricatorFile::loadBuiltin( 158 158 $this->getViewer(), 159 - 'profile.png'); 159 + 'project.png'); 160 160 } 161 161 $profile = id(new PhabricatorProjectProfile()) 162 162 ->setProjectPHID($project->getPHID())
+11 -2
src/infrastructure/celerity/CelerityResourceTransformer.php
··· 129 129 $data); 130 130 } 131 131 132 - public function replaceCSSVariable($matches) { 133 - static $map = array( 132 + public static function getCSSVariableMap() { 133 + return array( 134 134 // Base Colors 135 135 'red' => '#c0392b', 136 136 'lightred' => '#f4dddb', ··· 148 148 'lightindigo' => '#f5e2ef', 149 149 'violet' => '#8e44ad', 150 150 'lightviolet' => '#ecdff1', 151 + 'charcoal' => '#4b4d51', 152 + 'backdrop' => '#c4cde0', 151 153 152 154 // Base Greys 153 155 'lightgreyborder' => '#C7CCD9', ··· 170 172 'bluetext' => '#6B748C', 171 173 'darkbluetext' => '#464C5C', 172 174 ); 175 + } 176 + 177 + public function replaceCSSVariable($matches) { 178 + static $map; 179 + if (!$map) { 180 + $map = self::getCSSVariableMap(); 181 + } 173 182 174 183 $var_name = $matches[1]; 175 184 if (empty($map[$var_name])) {
+2 -2
src/infrastructure/celerity/CeleritySpriteGenerator.php
··· 347 347 ->setSourceSize(50, 50); 348 348 349 349 $sprites = array(); 350 - $prefix = 'projects_'; 350 + $prefix = 'projects-'; 351 351 foreach ($icons as $icon) { 352 352 $sprite = id(clone $template) 353 353 ->setName($prefix.$icon) 354 354 ->setTargetCSS('.'.$prefix.$icon); 355 355 356 356 foreach ($scales as $scale_key => $scale) { 357 - $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); 357 + $path = $this->getPath('projects_'.$scale_key.'/'.$icon.'.png'); 358 358 $sprite->setSourceFile($path, $scale); 359 359 } 360 360 $sprites[] = $sprite;
+1
src/view/phui/PHUIIconView.php
··· 10 10 const SPRITE_ICONS = 'icons'; 11 11 const SPRITE_LOGIN = 'login'; 12 12 const SPRITE_STATUS = 'status'; 13 + const SPRITE_PROJECTS = 'projects'; 13 14 14 15 const HEAD_SMALL = 'phuihead-small'; 15 16 const HEAD_MEDIUM = 'phuihead-medium';
+66
webroot/rsrc/css/application/people/people-profile.css
··· 11 11 padding: 4px; 12 12 margin: 0; 13 13 } 14 + 15 + .compose-dialog button.profile-image-button-selected { 16 + background-image: none; 17 + background-color: {$lightblue}; 18 + border-color: {$blueborder}; 19 + } 20 + 21 + .compose-header { 22 + color: {$bluetext}; 23 + border-bottom: 1px solid {$lightblueborder}; 24 + padding: 4px 0; 25 + margin: 0 0 8px; 26 + } 27 + 28 + form.compose-dialog { 29 + width: 80%; 30 + } 31 + 32 + .compose-dialog .phui-icon-view { 33 + display: block; 34 + position: relative; 35 + width: 50px; 36 + height: 50px; 37 + background-color: {$darkgreytext}; 38 + } 39 + 40 + .compose-dialog .compose-background-red { 41 + background-color: {$red}; 42 + } 43 + 44 + .compose-dialog .compose-background-orange { 45 + background-color: {$orange}; 46 + } 47 + 48 + .compose-dialog .compose-background-yellow { 49 + background-color: {$yellow}; 50 + } 51 + 52 + .compose-dialog .compose-background-green { 53 + background-color: {$green}; 54 + } 55 + 56 + .compose-dialog .compose-background-blue { 57 + background-color: {$blue}; 58 + } 59 + 60 + .compose-dialog .compose-background-sky { 61 + background-color: {$sky}; 62 + } 63 + 64 + .compose-dialog .compose-background-indigo { 65 + background-color: {$indigo}; 66 + } 67 + 68 + .compose-dialog .compose-background-violet { 69 + background-color: {$violet}; 70 + } 71 + 72 + .compose-dialog .compose-background-charcoal { 73 + background-color: {$charcoal}; 74 + } 75 + 76 + .compose-dialog .compose-background-backdrop { 77 + background-color: {$backdrop}; 78 + } 79 +
+1 -1
webroot/rsrc/css/phui/phui-workpanel-view.css
··· 15 15 } 16 16 17 17 .phui-workpanel-view .phui-workpanel-body { 18 - background: #c4cde0; 18 + background: {$backdrop}; 19 19 padding: 5px 5px 1px 5px; 20 20 border-bottom-left-radius: 5px; 21 21 border-bottom-right-radius: 5px;
+56 -56
webroot/rsrc/css/sprite-projects.css
··· 18 18 } 19 19 20 20 21 - .projects_8ball { 21 + .projects-8ball { 22 22 background-position: 0px 0px; 23 23 } 24 24 25 - .projects_alien { 25 + .projects-alien { 26 26 background-position: -51px 0px; 27 27 } 28 28 29 - .projects_annouce { 29 + .projects-announce { 30 30 background-position: -102px 0px; 31 31 } 32 32 33 - .projects_art { 33 + .projects-art { 34 34 background-position: -153px 0px; 35 35 } 36 36 37 - .projects_award { 37 + .projects-award { 38 38 background-position: -204px 0px; 39 39 } 40 40 41 - .projects_bacon { 41 + .projects-bacon { 42 42 background-position: -255px 0px; 43 43 } 44 44 45 - .projects_bandaid { 45 + .projects-bandaid { 46 46 background-position: -306px 0px; 47 47 } 48 48 49 - .projects_beer { 49 + .projects-beer { 50 50 background-position: 0px -51px; 51 51 } 52 52 53 - .projects_bomb { 53 + .projects-bomb { 54 54 background-position: -51px -51px; 55 55 } 56 56 57 - .projects_briefcase { 57 + .projects-briefcase { 58 58 background-position: -102px -51px; 59 59 } 60 60 61 - .projects_bug { 61 + .projects-bug { 62 62 background-position: -153px -51px; 63 63 } 64 64 65 - .projects_calendar { 65 + .projects-calendar { 66 66 background-position: -204px -51px; 67 67 } 68 68 69 - .projects_cloud { 69 + .projects-cloud { 70 70 background-position: -255px -51px; 71 71 } 72 72 73 - .projects_coffee { 73 + .projects-coffee { 74 74 background-position: -306px -51px; 75 75 } 76 76 77 - .projects_creditcard { 77 + .projects-creditcard { 78 78 background-position: 0px -102px; 79 79 } 80 80 81 - .projects_death { 81 + .projects-death { 82 82 background-position: -51px -102px; 83 83 } 84 84 85 - .projects_desktop { 85 + .projects-desktop { 86 86 background-position: -102px -102px; 87 87 } 88 88 89 - .projects_dropbox { 89 + .projects-dropbox { 90 90 background-position: -153px -102px; 91 91 } 92 92 93 - .projects_education { 93 + .projects-education { 94 94 background-position: -204px -102px; 95 95 } 96 96 97 - .projects_experimental { 97 + .projects-experimental { 98 98 background-position: -255px -102px; 99 99 } 100 100 101 - .projects_facebook { 101 + .projects-facebook { 102 102 background-position: -306px -102px; 103 103 } 104 104 105 - .projects_facility { 105 + .projects-facility { 106 106 background-position: 0px -153px; 107 107 } 108 108 109 - .projects_film { 109 + .projects-film { 110 110 background-position: -51px -153px; 111 111 } 112 112 113 - .projects_forked { 113 + .projects-forked { 114 114 background-position: -102px -153px; 115 115 } 116 116 117 - .projects_games { 117 + .projects-games { 118 118 background-position: -153px -153px; 119 119 } 120 120 121 - .projects_ghost { 121 + .projects-ghost { 122 122 background-position: -204px -153px; 123 123 } 124 124 125 - .projects_gift { 125 + .projects-gift { 126 126 background-position: -255px -153px; 127 127 } 128 128 129 - .projects_globe { 129 + .projects-globe { 130 130 background-position: -306px -153px; 131 131 } 132 132 133 - .projects_golf { 133 + .projects-golf { 134 134 background-position: 0px -204px; 135 135 } 136 136 137 - .projects_heart { 137 + .projects-heart { 138 138 background-position: -51px -204px; 139 139 } 140 140 141 - .projects_intergalactic { 141 + .projects-intergalactic { 142 142 background-position: -102px -204px; 143 143 } 144 144 145 - .projects_lock { 145 + .projects-lock { 146 146 background-position: -153px -204px; 147 147 } 148 148 149 - .projects_mail { 149 + .projects-mail { 150 150 background-position: -204px -204px; 151 151 } 152 152 153 - .projects_martini { 153 + .projects-martini { 154 154 background-position: -255px -204px; 155 155 } 156 156 157 - .projects_medical { 157 + .projects-medical { 158 158 background-position: -306px -204px; 159 159 } 160 160 161 - .projects_mobile { 161 + .projects-mobile { 162 162 background-position: 0px -255px; 163 163 } 164 164 165 - .projects_music { 165 + .projects-music { 166 166 background-position: -51px -255px; 167 167 } 168 168 169 - .projects_news { 169 + .projects-news { 170 170 background-position: -102px -255px; 171 171 } 172 172 173 - .projects_orgchart { 173 + .projects-orgchart { 174 174 background-position: -153px -255px; 175 175 } 176 176 177 - .projects_peoples { 177 + .projects-peoples { 178 178 background-position: -204px -255px; 179 179 } 180 180 181 - .projects_piechart { 181 + .projects-piechart { 182 182 background-position: -255px -255px; 183 183 } 184 184 185 - .projects_poison { 185 + .projects-poison { 186 186 background-position: -306px -255px; 187 187 } 188 188 189 - .projects_putabirdonit { 189 + .projects-putabirdonit { 190 190 background-position: 0px -306px; 191 191 } 192 192 193 - .projects_radiate { 193 + .projects-radiate { 194 194 background-position: -51px -306px; 195 195 } 196 196 197 - .projects_savings { 197 + .projects-savings { 198 198 background-position: -102px -306px; 199 199 } 200 200 201 - .projects_search { 201 + .projects-search { 202 202 background-position: -153px -306px; 203 203 } 204 204 205 - .projects_shield { 205 + .projects-shield { 206 206 background-position: -204px -306px; 207 207 } 208 208 209 - .projects_speed { 209 + .projects-speed { 210 210 background-position: -255px -306px; 211 211 } 212 212 213 - .projects_sprint { 213 + .projects-sprint { 214 214 background-position: -306px -306px; 215 215 } 216 216 217 - .projects_star { 217 + .projects-star { 218 218 background-position: 0px -357px; 219 219 } 220 220 221 - .projects_storage { 221 + .projects-storage { 222 222 background-position: -51px -357px; 223 223 } 224 224 225 - .projects_tablet { 225 + .projects-tablet { 226 226 background-position: -102px -357px; 227 227 } 228 228 229 - .projects_travel { 229 + .projects-travel { 230 230 background-position: -153px -357px; 231 231 } 232 232 233 - .projects_twitter { 233 + .projects-twitter { 234 234 background-position: -204px -357px; 235 235 } 236 236 237 - .projects_warning { 237 + .projects-warning { 238 238 background-position: -255px -357px; 239 239 } 240 240 241 - .projects_whale { 241 + .projects-whale { 242 242 background-position: -306px -357px; 243 243 }
+76
webroot/rsrc/js/application/files/behavior-icon-composer.js
··· 1 + /** 2 + * @provides javelin-behavior-icon-composer 3 + * @requires javelin-behavior 4 + * javelin-dom 5 + * javelin-stratcom 6 + */ 7 + 8 + JX.behavior('icon-composer', function(config) { 9 + 10 + var nodes = { 11 + root: JX.$(config.dialogID), 12 + colorInput: JX.$(config.colorInputID), 13 + iconInput: JX.$(config.iconInputID), 14 + preview: JX.$(config.previewID) 15 + }; 16 + 17 + var selected = { 18 + color: config.defaultColor, 19 + icon: config.defaultIcon 20 + }; 21 + 22 + var redraw = function() { 23 + var ii; 24 + 25 + var colors = JX.DOM.scry(nodes.root, 'button', 'compose-select-color'); 26 + for (ii = 0; ii < colors.length; ii++) { 27 + JX.DOM.alterClass( 28 + colors[ii], 29 + 'profile-image-button-selected', 30 + (JX.Stratcom.getData(colors[ii]).color == selected.color)); 31 + } 32 + 33 + var icons = JX.DOM.scry(nodes.root, 'button', 'compose-select-icon'); 34 + for (ii = 0; ii < icons.length; ii++) { 35 + JX.DOM.alterClass( 36 + icons[ii], 37 + 'profile-image-button-selected', 38 + (JX.Stratcom.getData(icons[ii]).icon == selected.icon)); 39 + } 40 + 41 + nodes.colorInput.value = selected.color; 42 + nodes.iconInput.value = selected.icon; 43 + 44 + var classes = ['phui-icon-view', 'sprite-projects']; 45 + classes.push('compose-background-' + selected.color); 46 + classes.push('projects-' + selected.icon); 47 + 48 + nodes.preview.className = classes.join(' '); 49 + }; 50 + 51 + JX.DOM.listen( 52 + nodes.root, 53 + 'click', 54 + 'compose-select-color', 55 + function (e) { 56 + e.kill(); 57 + 58 + selected.color = e.getNodeData('compose-select-color').color; 59 + redraw(); 60 + }); 61 + 62 + JX.DOM.listen( 63 + nodes.root, 64 + 'click', 65 + 'compose-select-icon', 66 + function (e) { 67 + e.kill(); 68 + 69 + selected.icon = e.getNodeData('compose-select-icon').icon; 70 + redraw(); 71 + }); 72 + 73 + redraw(); 74 + 75 + }); 76 +
+25
webroot/rsrc/js/application/files/behavior-launch-icon-composer.js
··· 1 + /** 2 + * @provides javelin-behavior-launch-icon-composer 3 + * @requires javelin-behavior 4 + * javelin-dom 5 + * javelin-workflow 6 + */ 7 + 8 + JX.behavior('launch-icon-composer', function(config) { 9 + 10 + JX.DOM.listen( 11 + JX.$(config.launchID), 12 + 'click', 13 + null, 14 + function(e) { 15 + e.kill(); 16 + new JX.Workflow('/file/compose/') 17 + .setHandler(function(r) { 18 + JX.$(config.inputID).value = r.phid; 19 + JX.DOM.findAbove(e.getTarget(), 'form').submit(); 20 + }) 21 + .start(); 22 + }); 23 + 24 + }); 25 +