diff --git a/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php b/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php index ad452d5f0..40159d1cc 100644 --- a/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php +++ b/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php @@ -1,109 +1,111 @@ withPHIDs($phids) ->needProfile(true) ->needProfileImage(true) ->needAvailability(true); } public function loadHandles( PhabricatorHandleQuery $query, array $handles, array $objects) { foreach ($handles as $phid => $handle) { $user = $objects[$phid]; $realname = $user->getRealName(); $handle->setName($user->getUsername()); $handle->setURI('/p/'.$user->getUsername().'/'); $handle->setFullName($user->getFullName()); $handle->setImageURI($user->getProfileImageURI()); if ($user->getIsMailingList()) { $handle->setIcon('fa-envelope-o'); $handle->setSubtitle(pht('Mailing List')); } else { $profile = $user->getUserProfile(); $icon_key = $profile->getIcon(); $icon_icon = PhabricatorPeopleIconSet::getIconIcon($icon_key); $subtitle = $profile->getDisplayTitle(); - $handle->setIcon($icon_icon); - $handle->setSubtitle($subtitle); + $handle + ->setIcon($icon_icon) + ->setSubtitle($subtitle) + ->setTokenIcon('fa-user'); } $availability = null; if (!$user->isUserActivated()) { $availability = PhabricatorObjectHandle::AVAILABILITY_DISABLED; } else { $until = $user->getAwayUntil(); if ($until) { $availability = PhabricatorObjectHandle::AVAILABILITY_NONE; } } if ($availability) { $handle->setAvailability($availability); } } } public function canLoadNamedObject($name) { return preg_match('/^@.+/', $name); } public function loadNamedObjects( PhabricatorObjectQuery $query, array $names) { $id_map = array(); foreach ($names as $name) { $id = substr($name, 1); $id = phutil_utf8_strtolower($id); $id_map[$id][] = $name; } $objects = id(new PhabricatorPeopleQuery()) ->setViewer($query->getViewer()) ->withUsernames(array_keys($id_map)) ->execute(); $results = array(); foreach ($objects as $id => $object) { $user_key = $object->getUsername(); $user_key = phutil_utf8_strtolower($user_key); foreach (idx($id_map, $user_key, array()) as $name) { $results[$name] = $object; } } return $results; } } diff --git a/src/applications/phid/PhabricatorObjectHandle.php b/src/applications/phid/PhabricatorObjectHandle.php index e49094e31..c83100573 100644 --- a/src/applications/phid/PhabricatorObjectHandle.php +++ b/src/applications/phid/PhabricatorObjectHandle.php @@ -1,367 +1,381 @@ icon = $icon; return $this; } public function getIcon() { if ($this->getPolicyFiltered()) { return 'fa-lock'; } if ($this->icon) { return $this->icon; } return $this->getTypeIcon(); } public function setSubtitle($subtitle) { $this->subtitle = $subtitle; return $this; } public function getSubtitle() { return $this->subtitle; } public function setTagColor($color) { static $colors; if (!$colors) { $colors = array_fuse(array_keys(PHUITagView::getShadeMap())); } if (isset($colors[$color])) { $this->tagColor = $color; } return $this; } public function getTagColor() { if ($this->getPolicyFiltered()) { return 'disabled'; } if ($this->tagColor) { return $this->tagColor; } return 'blue'; } public function getIconColor() { if ($this->tagColor) { return $this->tagColor; } return null; } + public function setTokenIcon($icon) { + $this->tokenIcon = $icon; + return $this; + } + + public function getTokenIcon() { + if ($this->tokenIcon !== null) { + return $this->tokenIcon; + } + + return $this->getIcon(); + } + public function getTypeIcon() { if ($this->getPHIDType()) { return $this->getPHIDType()->getTypeIcon(); } return null; } public function setPolicyFiltered($policy_filered) { $this->policyFiltered = $policy_filered; return $this; } public function getPolicyFiltered() { return $this->policyFiltered; } public function setObjectName($object_name) { $this->objectName = $object_name; return $this; } public function getObjectName() { if (!$this->objectName) { return $this->getName(); } return $this->objectName; } public function setURI($uri) { $this->uri = $uri; return $this; } public function getURI() { return $this->uri; } public function setPHID($phid) { $this->phid = $phid; return $this; } public function getPHID() { return $this->phid; } public function setName($name) { $this->name = $name; return $this; } public function getName() { if ($this->name === null) { if ($this->getPolicyFiltered()) { return pht('Restricted %s', $this->getTypeName()); } else { return pht('Unknown Object (%s)', $this->getTypeName()); } } return $this->name; } public function setAvailability($availability) { $this->availability = $availability; return $this; } public function getAvailability() { return $this->availability; } public function isDisabled() { return ($this->getAvailability() == self::AVAILABILITY_DISABLED); } public function setStatus($status) { $this->status = $status; return $this; } public function getStatus() { return $this->status; } public function setFullName($full_name) { $this->fullName = $full_name; return $this; } public function getFullName() { if ($this->fullName !== null) { return $this->fullName; } return $this->getName(); } public function setTitle($title) { $this->title = $title; return $this; } public function getTitle() { return $this->title; } public function setType($type) { $this->type = $type; return $this; } public function getType() { return $this->type; } public function setImageURI($uri) { $this->imageURI = $uri; return $this; } public function getImageURI() { return $this->imageURI; } public function setTimestamp($timestamp) { $this->timestamp = $timestamp; return $this; } public function getTimestamp() { return $this->timestamp; } public function getTypeName() { if ($this->getPHIDType()) { return $this->getPHIDType()->getTypeName(); } return $this->getType(); } /** * Set whether or not the underlying object is complete. See * @{method:isComplete} for an explanation of what it means to be complete. * * @param bool True if the handle represents a complete object. * @return this */ public function setComplete($complete) { $this->complete = $complete; return $this; } /** * Determine if the handle represents an object which was completely loaded * (i.e., the underlying object exists) vs an object which could not be * completely loaded (e.g., the type or data for the PHID could not be * identified or located). * * Basically, @{class:PhabricatorHandleQuery} gives you back a handle for * any PHID you give it, but it gives you a complete handle only for valid * PHIDs. * * @return bool True if the handle represents a complete object. */ public function isComplete() { return $this->complete; } public function renderLink($name = null) { return $this->renderLinkWithAttributes($name, array()); } public function renderHovercardLink($name = null) { Javelin::initBehavior('phabricator-hovercards'); $attributes = array( 'sigil' => 'hovercard', 'meta' => array( 'hoverPHID' => $this->getPHID(), ), ); return $this->renderLinkWithAttributes($name, $attributes); } private function renderLinkWithAttributes($name, array $attributes) { if ($name === null) { $name = $this->getLinkName(); } $classes = array(); $classes[] = 'phui-handle'; $title = $this->title; if ($this->status != self::STATUS_OPEN) { $classes[] = 'handle-status-'.$this->status; } if ($this->availability != self::AVAILABILITY_FULL) { $classes[] = 'handle-availability-'.$this->availability; } if ($this->getType() == PhabricatorPeopleUserPHIDType::TYPECONST) { $classes[] = 'phui-link-person'; } $uri = $this->getURI(); $icon = null; if ($this->getPolicyFiltered()) { $icon = id(new PHUIIconView()) ->setIcon('fa-lock lightgreytext'); } $attributes = $attributes + array( 'href' => $uri, 'class' => implode(' ', $classes), 'title' => $title, ); return javelin_tag( $uri ? 'a' : 'span', $attributes, array($icon, $name)); } public function renderTag() { return id(new PHUITagView()) ->setType(PHUITagView::TYPE_OBJECT) ->setShade($this->getTagColor()) ->setIcon($this->getIcon()) ->setHref($this->getURI()) ->setName($this->getLinkName()); } public function getLinkName() { switch ($this->getType()) { case PhabricatorPeopleUserPHIDType::TYPECONST: $name = $this->getName(); break; default: $name = $this->getFullName(); break; } return $name; } protected function getPHIDType() { $types = PhabricatorPHIDType::getAllTypes(); return idx($types, $this->getType()); } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, ); } public function getPolicy($capability) { return PhabricatorPolicies::POLICY_PUBLIC; } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { // NOTE: Handles are always visible, they just don't get populated with // data if the user can't see the underlying object. return true; } public function describeAutomaticCapability($capability) { return null; } } diff --git a/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php b/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php index 2dacd8402..56867d827 100644 --- a/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php +++ b/src/applications/typeahead/view/PhabricatorTypeaheadTokenView.php @@ -1,167 +1,167 @@ setKey($result->getPHID()) ->setIcon($result->getIcon()) ->setColor($result->getColor()) ->setValue($result->getDisplayName()) ->setTokenType($result->getTokenType()); } public static function newFromHandle( PhabricatorObjectHandle $handle) { $token = id(new PhabricatorTypeaheadTokenView()) ->setKey($handle->getPHID()) ->setValue($handle->getFullName()) - ->setIcon($handle->getIcon()); + ->setIcon($handle->getTokenIcon()); if ($handle->isDisabled() || $handle->getStatus() == PhabricatorObjectHandle::STATUS_CLOSED) { $token->setTokenType(self::TYPE_DISABLED); } else { $token->setColor($handle->getTagColor()); } return $token; } public function isInvalid() { return ($this->getTokenType() == self::TYPE_INVALID); } public function setKey($key) { $this->key = $key; return $this; } public function getKey() { return $this->key; } public function setTokenType($token_type) { $this->tokenType = $token_type; return $this; } public function getTokenType() { return $this->tokenType; } public function setInputName($input_name) { $this->inputName = $input_name; return $this; } public function getInputName() { return $this->inputName; } public function setIcon($icon) { $this->icon = $icon; return $this; } public function getIcon() { return $this->icon; } public function setColor($color) { $this->color = $color; return $this; } public function getColor() { return $this->color; } public function setValue($value) { $this->value = $value; return $this; } public function getValue() { return $this->value; } protected function getTagName() { return 'a'; } protected function getTagAttributes() { $classes = array(); $classes[] = 'jx-tokenizer-token'; switch ($this->getTokenType()) { case self::TYPE_FUNCTION: $classes[] = 'jx-tokenizer-token-function'; break; case self::TYPE_INVALID: $classes[] = 'jx-tokenizer-token-invalid'; break; case self::TYPE_DISABLED: $classes[] = 'jx-tokenizer-token-disabled'; break; case self::TYPE_OBJECT: default: break; } $classes[] = $this->getColor(); return array( 'class' => $classes, ); } protected function getTagContent() { $input_name = $this->getInputName(); if ($input_name) { $input_name .= '[]'; } $value = $this->getValue(); $icon = $this->getIcon(); if ($icon) { $value = array( phutil_tag( 'span', array( 'class' => 'phui-icon-view phui-font-fa '.$icon, )), $value, ); } return array( $value, phutil_tag( 'input', array( 'type' => 'hidden', 'name' => $input_name, 'value' => $this->getKey(), )), phutil_tag('span', array('class' => 'jx-tokenizer-x-placeholder'), ''), ); } }