Choose default project image by icon

Summary: Builds out a map for icon->image in Projects, selects the icon's image as the default project image if there is no custom image chosen by the user.

Test Plan: Select various icons, see image change. Test choose picture, pick a new image.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D18174
This commit is contained in:
Chad Little
2017-07-09 11:15:46 -07:00
parent 39e5da7ea7
commit 250aaabd64
6 changed files with 68 additions and 41 deletions

View File

@@ -56,4 +56,20 @@ final class PhabricatorFilesOnDiskBuiltinFile
return $map; return $map;
} }
public function getProjectBuiltinFiles() {
$root = dirname(phutil_get_library_root('phabricator'));
$root = $root.'/resources/builtin/projects/';
$map = array();
$list = id(new FileFinder($root))
->withType('f')
->withFollowSymlinks(true)
->find();
foreach ($list as $file) {
$map[$file] = $root.$file;
}
return $map;
}
} }

View File

@@ -34,6 +34,8 @@ a dictionary, which may contain these keys:
- `key` //Required string.// Internal key identifying the icon. - `key` //Required string.// Internal key identifying the icon.
- `name` //Required string.// Human-readable icon name. - `name` //Required string.// Human-readable icon name.
- `icon` //Required string.// Specifies which actual icon image to use. - `icon` //Required string.// Specifies which actual icon image to use.
- `image` //Optional string.// Selects a default image. Select an image from
`resources/builtins/projects/`.
- `default` //Optional bool.// Selects a default icon. Exactly one icon must - `default` //Optional bool.// Selects a default icon. Exactly one icon must
be selected as the default. be selected as the default.
- `disabled` //Optional bool.// If true, this icon will no longer be - `disabled` //Optional bool.// If true, this icon will no longer be

View File

@@ -98,7 +98,10 @@ final class PhabricatorProjectEditPictureController
$form = id(new PHUIFormLayoutView()) $form = id(new PHUIFormLayoutView())
->setUser($viewer); ->setUser($viewer);
$default_image = PhabricatorFile::loadBuiltin($viewer, 'project.png'); $builtin = PhabricatorProjectIconSet::getIconImage(
$project->getIcon());
$default_image = PhabricatorFile::loadBuiltin($this->getViewer(),
'projects/'.$builtin);
$images = array(); $images = array();

View File

@@ -296,10 +296,6 @@ final class PhabricatorProjectTransactionEditor
} }
} }
if ($this->getIsNewObject()) {
$this->setDefaultProfilePicture($object);
}
// TODO: We should dump an informational transaction onto the parent // TODO: We should dump an informational transaction onto the parent
// project to show that we created the sub-thing. // project to show that we created the sub-thing.
@@ -457,34 +453,6 @@ final class PhabricatorProjectTransactionEditor
return $results; return $results;
} }
private function setDefaultProfilePicture(PhabricatorProject $project) {
if ($project->isMilestone()) {
return;
}
$compose_color = $project->getDisplayIconComposeColor();
$compose_icon = $project->getDisplayIconComposeIcon();
$builtin = id(new PhabricatorFilesComposeIconBuiltinFile())
->setColor($compose_color)
->setIcon($compose_icon);
$data = $builtin->loadBuiltinFileData();
$file = PhabricatorFile::newFromFileData(
$data,
array(
'name' => $builtin->getBuiltinDisplayName(),
'profile' => true,
'canCDN' => true,
));
$project
->setProfileImagePHID($file->getPHID())
->save();
}
protected function shouldApplyHeraldRules( protected function shouldApplyHeraldRules(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
array $xactions) { array $xactions) {

View File

@@ -18,87 +18,104 @@ final class PhabricatorProjectIconSet
'icon' => 'fa-briefcase', 'icon' => 'fa-briefcase',
'name' => pht('Project'), 'name' => pht('Project'),
'default' => true, 'default' => true,
'image' => 'v3/briefcase.png',
), ),
array( array(
'key' => 'tag', 'key' => 'tag',
'icon' => 'fa-tags', 'icon' => 'fa-tags',
'name' => pht('Tag'), 'name' => pht('Tag'),
'image' => 'v3/tag.png',
), ),
array( array(
'key' => 'policy', 'key' => 'policy',
'icon' => 'fa-lock', 'icon' => 'fa-lock',
'name' => pht('Policy'), 'name' => pht('Policy'),
'image' => 'v3/lock.png',
), ),
array( array(
'key' => 'group', 'key' => 'group',
'icon' => 'fa-users', 'icon' => 'fa-users',
'name' => pht('Group'), 'name' => pht('Group'),
'image' => 'v3/people.png',
), ),
array( array(
'key' => 'folder', 'key' => 'folder',
'icon' => 'fa-folder', 'icon' => 'fa-folder',
'name' => pht('Folder'), 'name' => pht('Folder'),
'image' => 'v3/folder.png',
), ),
array( array(
'key' => 'timeline', 'key' => 'timeline',
'icon' => 'fa-calendar', 'icon' => 'fa-calendar',
'name' => pht('Timeline'), 'name' => pht('Timeline'),
'image' => 'v3/calendar.png',
), ),
array( array(
'key' => 'goal', 'key' => 'goal',
'icon' => 'fa-flag-checkered', 'icon' => 'fa-flag-checkered',
'name' => pht('Goal'), 'name' => pht('Goal'),
'image' => 'v3/flag.png',
), ),
array( array(
'key' => 'release', 'key' => 'release',
'icon' => 'fa-truck', 'icon' => 'fa-truck',
'name' => pht('Release'), 'name' => pht('Release'),
'image' => 'v3/truck.png',
), ),
array( array(
'key' => 'bugs', 'key' => 'bugs',
'icon' => 'fa-bug', 'icon' => 'fa-bug',
'name' => pht('Bugs'), 'name' => pht('Bugs'),
'image' => 'v3/bug.png',
), ),
array( array(
'key' => 'cleanup', 'key' => 'cleanup',
'icon' => 'fa-trash-o', 'icon' => 'fa-trash-o',
'name' => pht('Cleanup'), 'name' => pht('Cleanup'),
'image' => 'v3/trash.png',
), ),
array( array(
'key' => 'umbrella', 'key' => 'umbrella',
'icon' => 'fa-umbrella', 'icon' => 'fa-umbrella',
'name' => pht('Umbrella'), 'name' => pht('Umbrella'),
'image' => 'v3/umbrella.png',
), ),
array( array(
'key' => 'communication', 'key' => 'communication',
'icon' => 'fa-envelope', 'icon' => 'fa-envelope',
'name' => pht('Communication'), 'name' => pht('Communication'),
'image' => 'v3/mail.png',
), ),
array( array(
'key' => 'organization', 'key' => 'organization',
'icon' => 'fa-building', 'icon' => 'fa-building',
'name' => pht('Organization'), 'name' => pht('Organization'),
'image' => 'v3/organization.png',
), ),
array( array(
'key' => 'infrastructure', 'key' => 'infrastructure',
'icon' => 'fa-cloud', 'icon' => 'fa-cloud',
'name' => pht('Infrastructure'), 'name' => pht('Infrastructure'),
'image' => 'v3/cloud.png',
), ),
array( array(
'key' => 'account', 'key' => 'account',
'icon' => 'fa-credit-card', 'icon' => 'fa-credit-card',
'name' => pht('Account'), 'name' => pht('Account'),
'image' => 'v3/creditcard.png',
), ),
array( array(
'key' => 'experimental', 'key' => 'experimental',
'icon' => 'fa-flask', 'icon' => 'fa-flask',
'name' => pht('Experimental'), 'name' => pht('Experimental'),
'image' => 'v3/experimental.png',
), ),
array( array(
'key' => 'milestone', 'key' => 'milestone',
'icon' => 'fa-map-marker', 'icon' => 'fa-map-marker',
'name' => pht('Milestone'), 'name' => pht('Milestone'),
'special' => self::SPECIAL_MILESTONE, 'special' => self::SPECIAL_MILESTONE,
'image' => 'v3/marker.png',
), ),
); );
} }
@@ -149,6 +166,11 @@ final class PhabricatorProjectIconSet
return idx($spec, 'name', null); return idx($spec, 'name', null);
} }
public static function getIconImage($key) {
$spec = self::getIconSpec($key);
return idx($spec, 'image', 'v3/briefcase.png');
}
private static function getIconSpec($key) { private static function getIconSpec($key) {
$icons = self::getIconSpecifications(); $icons = self::getIconSpecifications();
foreach ($icons as $icon) { foreach ($icons as $icon) {
@@ -190,6 +212,7 @@ final class PhabricatorProjectIconSet
'key' => 'string', 'key' => 'string',
'name' => 'string', 'name' => 'string',
'icon' => 'string', 'icon' => 'string',
'image' => 'optional string',
'special' => 'optional string', 'special' => 'optional string',
'disabled' => 'optional bool', 'disabled' => 'optional bool',
'default' => 'optional bool', 'default' => 'optional bool',
@@ -239,6 +262,25 @@ final class PhabricatorProjectIconSet
$is_disabled = idx($value, 'disabled'); $is_disabled = idx($value, 'disabled');
if (idx($value, 'image')) {
$builtin = idx($value, 'image');
$builtin_map = id(new PhabricatorFilesOnDiskBuiltinFile())
->getProjectBuiltinFiles();
$builtin_map = array_flip($builtin_map);
$root = dirname(phutil_get_library_root('phabricator'));
$image = $root.'/resources/builtin/projects/'.$builtin;
if (!array_key_exists($image, $builtin_map)) {
throw new Exception(
pht(
'The project image ("%s") specified for ("%s") '.
'was not found in the folder "resources/builtin/projects/".',
$builtin,
$key));
}
}
if (idx($value, 'default')) { if (idx($value, 'default')) {
if ($default === null) { if ($default === null) {
if ($is_disabled) { if ($is_disabled) {

View File

@@ -358,8 +358,6 @@ final class PhabricatorProjectQuery
protected function didFilterPage(array $projects) { protected function didFilterPage(array $projects) {
if ($this->needImages) { if ($this->needImages) {
$default = null;
$file_phids = mpull($projects, 'getProfileImagePHID'); $file_phids = mpull($projects, 'getProfileImagePHID');
$file_phids = array_filter($file_phids); $file_phids = array_filter($file_phids);
if ($file_phids) { if ($file_phids) {
@@ -376,12 +374,10 @@ final class PhabricatorProjectQuery
foreach ($projects as $project) { foreach ($projects as $project) {
$file = idx($files, $project->getProfileImagePHID()); $file = idx($files, $project->getProfileImagePHID());
if (!$file) { if (!$file) {
if (!$default) { $builtin = PhabricatorProjectIconSet::getIconImage(
$default = PhabricatorFile::loadBuiltin( $project->getIcon());
$this->getViewer(), $file = PhabricatorFile::loadBuiltin($this->getViewer(),
'project.png'); 'projects/'.$builtin);
}
$file = $default;
} }
$project->attachProfileImageFile($file); $project->attachProfileImageFile($file);
} }